/** @addtogroup ppi_file PPI peripheral API * * @brief Access functions for the Programmable Peripheral Interconnect * * @ingroup peripheral_apis * LGPL License Terms @ref lgpl_license * @author @htmlonly © @endhtmlonly 2016 * Maxim Sloyko * */ /* * This file is part of the libopencm3 project. * * Copyright (C) 2017-2018 Unicore MX project * Copyright (C) 2021 Eduard Drusa * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ #include #include /**@{*/ /** @brief Configure PPI Channel. * * @param[in] chan_num uint8_t Channel number (0-15). * @param[in] eep uint32_t Event endpoint. Memory address of the event endpoint. * @param[in] tep uint32_t Task endpoint. Memory address of the task endpoint. */ void ppi_configure_channel(uint8_t chan_num, uint32_t eep, uint32_t tep) { PPI_CH_EEP(chan_num) = eep; PPI_CH_TEP(chan_num) = tep; } /** @brief Enable PPI channels, given the channels mask. * * @param[in] channels uint32_t mask of the channels to enable. */ void ppi_enable_channels(uint32_t channels) { PPI_CHENSET = channels; } /** @brief Disable PPI channels, given the channels mask. * * @param[in] channels uint32_t mask of the channels to disable. */ void ppi_disable_channels(uint32_t channels) { PPI_CHENCLR = channels; } /** @brief Set channels group, given channels mask. * * @param[in] group uint8_t group number (0-3) * @param[in] channels uint32_t mask of the channels to group together. */ void ppi_set_group(uint8_t group, uint32_t channels) { PPI_CHG(group) = channels; } /** @brief Enable previously configured group of channels. * * @param[in] group uint8_t group number (0-3) */ void ppi_enable_group(uint8_t group) { PPI_TASK_CHG_EN(group) = 1; } /** @brief Disable previously configured group of channels. * * @param[in] group uint8_t group number (0-3) */ void ppi_disable_group(uint8_t group) { PPI_TASK_CHG_DIS(group) = 1; } /** @brief Configure new channel. * * This is the alternative API, which requires the caller to store the mask of used channels. * * @param chan_map uint32_t* The mask of channels that are already in use. * For the first call initialize with zero and pass in. * @param[in] eep uint32_t Event endpoint. * @param[in] tep uint32_t Task endpoint. * @param enable bool If true, enable the channel immediately. * @return The number of the new channel. If there are no channels available, returns 0xff. */ uint8_t ppi_add_channel(uint32_t *chan_map, uint32_t eep, uint32_t tep, bool enable) { /* Find a free channel */ uint8_t i; uint32_t chan_bit; for (i = 0, chan_bit = 1; i <= PPI_MAX_PROG_CHANNEL; ++i, chan_bit <<= 1) { if (!(chan_bit & *chan_map)) { *chan_map |= chan_bit; break; } } /* If all channels are taken, return error. */ if (i > PPI_MAX_PROG_CHANNEL) { return 0xff; } ppi_configure_channel(i, eep, tep); if (enable) { ppi_enable_channels(chan_bit); } return i; } /** @brief Disable channel and remove it from the map of used channels. * * This is the alternative API, which requires the caller to store the mask of used channels. * * @param chan_map uint32_t* The mask of channels that are already in use. * For the first call initialize with zero and pass in. * @param[in] chan_num uint8_t the number of the channel to remove from the map. */ void ppi_remove_channel(uint32_t *chan_map, uint8_t chan_num) { ppi_disable_channels(PPI_CH(chan_num)); *chan_map &= ~(PPI_CH(chan_num)); } /**@}*/