libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
ppi.c
Go to the documentation of this file.
1/** @addtogroup ppi_file PPI peripheral API
2 *
3 * @brief <b>Access functions for the Programmable Peripheral Interconnect </b>
4 *
5 * @ingroup peripheral_apis
6 * LGPL License Terms @ref lgpl_license
7 * @author @htmlonly &copy; @endhtmlonly 2016
8 * Maxim Sloyko <maxims@google.com>
9 *
10 */
11
12/*
13 * This file is part of the libopencm3 project.
14 *
15 * Copyright (C) 2017-2018 Unicore MX project<dev(at)lists(dot)unicore-mx(dot)org>
16 * Copyright (C) 2021 Eduard Drusa <ventyl86(at)netkosice(dot)sk>
17 *
18 * This library is free software: you can redistribute it and/or modify
19 * it under the terms of the GNU Lesser General Public License as published by
20 * the Free Software Foundation, either version 3 of the License, or
21 * (at your option) any later version.
22 *
23 * This library is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU Lesser General Public License for more details.
27 *
28 * You should have received a copy of the GNU Lesser General Public License
29 * along with this library. If not, see <http://www.gnu.org/licenses/>.
30 */
31
32#include <stdint.h>
33
34#include <libopencm3/nrf/ppi.h>
35/**@{*/
36
37/** @brief Configure PPI Channel.
38 *
39 * @param[in] chan_num uint8_t Channel number (0-15).
40 * @param[in] eep uint32_t Event endpoint. Memory address of the event endpoint.
41 * @param[in] tep uint32_t Task endpoint. Memory address of the task endpoint.
42 */
43void ppi_configure_channel(uint8_t chan_num, uint32_t eep, uint32_t tep)
44{
45 PPI_CH_EEP(chan_num) = eep;
46 PPI_CH_TEP(chan_num) = tep;
47}
48
49/** @brief Enable PPI channels, given the channels mask.
50 *
51 * @param[in] channels uint32_t mask of the channels to enable.
52 */
53void ppi_enable_channels(uint32_t channels)
54{
55 PPI_CHENSET = channels;
56}
57
58/** @brief Disable PPI channels, given the channels mask.
59 *
60 * @param[in] channels uint32_t mask of the channels to disable.
61 */
62void ppi_disable_channels(uint32_t channels)
63{
64 PPI_CHENCLR = channels;
65}
66
67/** @brief Set channels group, given channels mask.
68 *
69 * @param[in] group uint8_t group number (0-3)
70 * @param[in] channels uint32_t mask of the channels to group together.
71 */
72void ppi_set_group(uint8_t group, uint32_t channels)
73{
74 PPI_CHG(group) = channels;
75}
76
77/** @brief Enable previously configured group of channels.
78 *
79 * @param[in] group uint8_t group number (0-3)
80 */
81void ppi_enable_group(uint8_t group)
82{
83 PPI_TASK_CHG_EN(group) = 1;
84}
85
86/** @brief Disable previously configured group of channels.
87 *
88 * @param[in] group uint8_t group number (0-3)
89 */
90void ppi_disable_group(uint8_t group)
91{
92 PPI_TASK_CHG_DIS(group) = 1;
93}
94
95/** @brief Configure new channel.
96 *
97 * This is the alternative API, which requires the caller to store the mask of used channels.
98 *
99 * @param chan_map uint32_t* The mask of channels that are already in use.
100 * For the first call initialize with zero and pass in.
101 * @param[in] eep uint32_t Event endpoint.
102 * @param[in] tep uint32_t Task endpoint.
103 * @param enable bool If true, enable the channel immediately.
104 * @return The number of the new channel. If there are no channels available, returns 0xff.
105 */
106uint8_t ppi_add_channel(uint32_t *chan_map, uint32_t eep, uint32_t tep, bool enable)
107{
108 /* Find a free channel */
109 uint8_t i;
110 uint32_t chan_bit;
111 for (i = 0, chan_bit = 1; i <= PPI_MAX_PROG_CHANNEL; ++i, chan_bit <<= 1) {
112 if (!(chan_bit & *chan_map)) {
113 *chan_map |= chan_bit;
114 break;
115 }
116 }
117
118 /* If all channels are taken, return error. */
119 if (i > PPI_MAX_PROG_CHANNEL) {
120 return 0xff;
121 }
122
123 ppi_configure_channel(i, eep, tep);
124 if (enable) {
125 ppi_enable_channels(chan_bit);
126 }
127
128 return i;
129}
130
131/** @brief Disable channel and remove it from the map of used channels.
132 *
133 * This is the alternative API, which requires the caller to store the mask of used channels.
134 *
135 * @param chan_map uint32_t* The mask of channels that are already in use.
136 * For the first call initialize with zero and pass in.
137 * @param[in] chan_num uint8_t the number of the channel to remove from the map.
138 */
139void ppi_remove_channel(uint32_t *chan_map, uint8_t chan_num)
140{
141 ppi_disable_channels(PPI_CH(chan_num));
142 *chan_map &= ~(PPI_CH(chan_num));
143}
144/**@}*/
145
#define PPI_CHENCLR
Definition: common/ppi.h:45
#define PPI_CHENSET
Definition: common/ppi.h:44
#define PPI_MAX_PROG_CHANNEL
Definition: common/ppi.h:91
#define PPI_CH_EEP(n)
Definition: common/ppi.h:48
#define PPI_CH(n)
Definition: common/ppi.h:55
#define PPI_TASK_CHG_DIS(n)
Definition: common/ppi.h:39
#define PPI_CH_TEP(n)
Definition: common/ppi.h:50
#define PPI_TASK_CHG_EN(n)
Definition: common/ppi.h:38
#define PPI_CHG(n)
Definition: common/ppi.h:53
void ppi_configure_channel(uint8_t chan_num, uint32_t eep, uint32_t tep)
Configure PPI Channel.
Definition: ppi.c:43
void ppi_enable_group(uint8_t group)
Enable previously configured group of channels.
Definition: ppi.c:81
void ppi_enable_channels(uint32_t channels)
Enable PPI channels, given the channels mask.
Definition: ppi.c:53
void ppi_remove_channel(uint32_t *chan_map, uint8_t chan_num)
Disable channel and remove it from the map of used channels.
Definition: ppi.c:139
void ppi_disable_channels(uint32_t channels)
Disable PPI channels, given the channels mask.
Definition: ppi.c:62
void ppi_set_group(uint8_t group, uint32_t channels)
Set channels group, given channels mask.
Definition: ppi.c:72
void ppi_disable_group(uint8_t group)
Disable previously configured group of channels.
Definition: ppi.c:90
uint8_t ppi_add_channel(uint32_t *chan_map, uint32_t eep, uint32_t tep, bool enable)
Configure new channel.
Definition: ppi.c:106