1*150812a8SEvalZero /*
2*150812a8SEvalZero * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
3*150812a8SEvalZero * All rights reserved.
4*150812a8SEvalZero *
5*150812a8SEvalZero * Redistribution and use in source and binary forms, with or without
6*150812a8SEvalZero * modification, are permitted provided that the following conditions are met:
7*150812a8SEvalZero *
8*150812a8SEvalZero * 1. Redistributions of source code must retain the above copyright notice, this
9*150812a8SEvalZero * list of conditions and the following disclaimer.
10*150812a8SEvalZero *
11*150812a8SEvalZero * 2. Redistributions in binary form must reproduce the above copyright
12*150812a8SEvalZero * notice, this list of conditions and the following disclaimer in the
13*150812a8SEvalZero * documentation and/or other materials provided with the distribution.
14*150812a8SEvalZero *
15*150812a8SEvalZero * 3. Neither the name of the copyright holder nor the names of its
16*150812a8SEvalZero * contributors may be used to endorse or promote products derived from this
17*150812a8SEvalZero * software without specific prior written permission.
18*150812a8SEvalZero *
19*150812a8SEvalZero * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*150812a8SEvalZero * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*150812a8SEvalZero * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*150812a8SEvalZero * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23*150812a8SEvalZero * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*150812a8SEvalZero * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*150812a8SEvalZero * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*150812a8SEvalZero * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*150812a8SEvalZero * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*150812a8SEvalZero * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*150812a8SEvalZero * POSSIBILITY OF SUCH DAMAGE.
30*150812a8SEvalZero */
31*150812a8SEvalZero
32*150812a8SEvalZero #include <nrfx.h>
33*150812a8SEvalZero
34*150812a8SEvalZero #if NRFX_CHECK(NRFX_PPI_ENABLED)
35*150812a8SEvalZero
36*150812a8SEvalZero #include <nrfx_ppi.h>
37*150812a8SEvalZero
38*150812a8SEvalZero #define NRFX_LOG_MODULE PPI
39*150812a8SEvalZero #include <nrfx_log.h>
40*150812a8SEvalZero
41*150812a8SEvalZero
42*150812a8SEvalZero static uint32_t m_channels_allocated; /**< Bitmap representing channels availability. 1 when a channel is allocated, 0 otherwise. */
43*150812a8SEvalZero static uint8_t m_groups_allocated; /**< Bitmap representing groups availability. 1 when a group is allocated, 0 otherwise.*/
44*150812a8SEvalZero
45*150812a8SEvalZero
46*150812a8SEvalZero /**
47*150812a8SEvalZero * @brief Compute a group mask (needed for driver internals, not used for NRF_PPI registers).
48*150812a8SEvalZero *
49*150812a8SEvalZero * @param[in] group Group number to transform to a mask.
50*150812a8SEvalZero *
51*150812a8SEvalZero * @retval Group mask.
52*150812a8SEvalZero */
group_to_mask(nrf_ppi_channel_group_t group)53*150812a8SEvalZero __STATIC_INLINE uint32_t group_to_mask(nrf_ppi_channel_group_t group)
54*150812a8SEvalZero {
55*150812a8SEvalZero return (1uL << (uint32_t) group);
56*150812a8SEvalZero }
57*150812a8SEvalZero
58*150812a8SEvalZero
59*150812a8SEvalZero /**
60*150812a8SEvalZero * @brief Check whether a channel is a programmable channel and can be used by an application.
61*150812a8SEvalZero *
62*150812a8SEvalZero * @param[in] channel Channel to check.
63*150812a8SEvalZero *
64*150812a8SEvalZero * @retval true The channel is a programmable application channel.
65*150812a8SEvalZero * @retval false The channel is used by a stack (for example SoftDevice) or is preprogrammed.
66*150812a8SEvalZero */
is_programmable_app_channel(nrf_ppi_channel_t channel)67*150812a8SEvalZero __STATIC_INLINE bool is_programmable_app_channel(nrf_ppi_channel_t channel)
68*150812a8SEvalZero {
69*150812a8SEvalZero return ((NRFX_PPI_PROG_APP_CHANNELS_MASK & nrfx_ppi_channel_to_mask(channel)) != 0);
70*150812a8SEvalZero }
71*150812a8SEvalZero
72*150812a8SEvalZero
73*150812a8SEvalZero /**
74*150812a8SEvalZero * @brief Check whether channels can be used by an application.
75*150812a8SEvalZero *
76*150812a8SEvalZero * @param[in] channel_mask Channel mask to check.
77*150812a8SEvalZero *
78*150812a8SEvalZero * @retval true All specified channels can be used by an application.
79*150812a8SEvalZero * @retval false At least one specified channel is used by a stack (for example SoftDevice).
80*150812a8SEvalZero */
are_app_channels(uint32_t channel_mask)81*150812a8SEvalZero __STATIC_INLINE bool are_app_channels(uint32_t channel_mask)
82*150812a8SEvalZero {
83*150812a8SEvalZero //lint -e(587)
84*150812a8SEvalZero return ((~(NRFX_PPI_ALL_APP_CHANNELS_MASK) & channel_mask) == 0);
85*150812a8SEvalZero }
86*150812a8SEvalZero
87*150812a8SEvalZero
88*150812a8SEvalZero /**
89*150812a8SEvalZero * @brief Check whether a channel can be used by an application.
90*150812a8SEvalZero *
91*150812a8SEvalZero * @param[in] channel Channel to check.
92*150812a8SEvalZero *
93*150812a8SEvalZero * @retval true The channel can be used by an application.
94*150812a8SEvalZero * @retval false The channel is used by a stack (for example SoftDevice).
95*150812a8SEvalZero */
is_app_channel(nrf_ppi_channel_t channel)96*150812a8SEvalZero __STATIC_INLINE bool is_app_channel(nrf_ppi_channel_t channel)
97*150812a8SEvalZero {
98*150812a8SEvalZero return are_app_channels(nrfx_ppi_channel_to_mask(channel));
99*150812a8SEvalZero }
100*150812a8SEvalZero
101*150812a8SEvalZero
102*150812a8SEvalZero /**
103*150812a8SEvalZero * @brief Check whether a channel group can be used by an application.
104*150812a8SEvalZero *
105*150812a8SEvalZero * @param[in] group Group to check.
106*150812a8SEvalZero *
107*150812a8SEvalZero * @retval true The group is an application group.
108*150812a8SEvalZero * @retval false The group is not an application group (this group either does not exist or
109*150812a8SEvalZero * it is used by a stack (for example SoftDevice)).
110*150812a8SEvalZero */
is_app_group(nrf_ppi_channel_group_t group)111*150812a8SEvalZero __STATIC_INLINE bool is_app_group(nrf_ppi_channel_group_t group)
112*150812a8SEvalZero {
113*150812a8SEvalZero return ((NRFX_PPI_ALL_APP_GROUPS_MASK & group_to_mask(group)) != 0);
114*150812a8SEvalZero }
115*150812a8SEvalZero
116*150812a8SEvalZero
117*150812a8SEvalZero /**
118*150812a8SEvalZero * @brief Check whether a channel is allocated.
119*150812a8SEvalZero *
120*150812a8SEvalZero * @param[in] channel_num Channel number to check.
121*150812a8SEvalZero *
122*150812a8SEvalZero * @retval true The channel is allocated.
123*150812a8SEvalZero * @retval false The channel is not allocated.
124*150812a8SEvalZero */
is_allocated_channel(nrf_ppi_channel_t channel)125*150812a8SEvalZero __STATIC_INLINE bool is_allocated_channel(nrf_ppi_channel_t channel)
126*150812a8SEvalZero {
127*150812a8SEvalZero return ((m_channels_allocated & nrfx_ppi_channel_to_mask(channel)) != 0);
128*150812a8SEvalZero }
129*150812a8SEvalZero
130*150812a8SEvalZero
131*150812a8SEvalZero /**
132*150812a8SEvalZero * @brief Set channel allocated indication.
133*150812a8SEvalZero *
134*150812a8SEvalZero * @param[in] channel_num Specifies the channel to set the "allocated" indication.
135*150812a8SEvalZero */
channel_allocated_set(nrf_ppi_channel_t channel)136*150812a8SEvalZero __STATIC_INLINE void channel_allocated_set(nrf_ppi_channel_t channel)
137*150812a8SEvalZero {
138*150812a8SEvalZero m_channels_allocated |= nrfx_ppi_channel_to_mask(channel);
139*150812a8SEvalZero }
140*150812a8SEvalZero
141*150812a8SEvalZero
142*150812a8SEvalZero /**
143*150812a8SEvalZero * @brief Clear channel allocated indication.
144*150812a8SEvalZero *
145*150812a8SEvalZero * @param[in] channel_num Specifies the channel to clear the "allocated" indication.
146*150812a8SEvalZero */
channel_allocated_clr(nrf_ppi_channel_t channel)147*150812a8SEvalZero __STATIC_INLINE void channel_allocated_clr(nrf_ppi_channel_t channel)
148*150812a8SEvalZero {
149*150812a8SEvalZero m_channels_allocated &= ~nrfx_ppi_channel_to_mask(channel);
150*150812a8SEvalZero }
151*150812a8SEvalZero
152*150812a8SEvalZero
153*150812a8SEvalZero /**
154*150812a8SEvalZero * @brief Clear all allocated channels.
155*150812a8SEvalZero */
channel_allocated_clr_all(void)156*150812a8SEvalZero __STATIC_INLINE void channel_allocated_clr_all(void)
157*150812a8SEvalZero {
158*150812a8SEvalZero m_channels_allocated &= ~NRFX_PPI_ALL_APP_CHANNELS_MASK;
159*150812a8SEvalZero }
160*150812a8SEvalZero
161*150812a8SEvalZero
162*150812a8SEvalZero /**
163*150812a8SEvalZero * @brief Check whether a group is allocated.
164*150812a8SEvalZero *
165*150812a8SEvalZero * @param[in] group_num Group number to check.
166*150812a8SEvalZero *
167*150812a8SEvalZero * @retval true The group is allocated.
168*150812a8SEvalZero * false The group is not allocated.
169*150812a8SEvalZero */
is_allocated_group(nrf_ppi_channel_group_t group)170*150812a8SEvalZero __STATIC_INLINE bool is_allocated_group(nrf_ppi_channel_group_t group)
171*150812a8SEvalZero {
172*150812a8SEvalZero return ((m_groups_allocated & group_to_mask(group)) != 0);
173*150812a8SEvalZero }
174*150812a8SEvalZero
175*150812a8SEvalZero
176*150812a8SEvalZero /**
177*150812a8SEvalZero * @brief Set group allocated indication.
178*150812a8SEvalZero *
179*150812a8SEvalZero * @param[in] group_num Specifies the group to set the "allocated" indication.
180*150812a8SEvalZero */
group_allocated_set(nrf_ppi_channel_group_t group)181*150812a8SEvalZero __STATIC_INLINE void group_allocated_set(nrf_ppi_channel_group_t group)
182*150812a8SEvalZero {
183*150812a8SEvalZero m_groups_allocated |= group_to_mask(group);
184*150812a8SEvalZero }
185*150812a8SEvalZero
186*150812a8SEvalZero
187*150812a8SEvalZero /**
188*150812a8SEvalZero * @brief Clear group allocated indication.
189*150812a8SEvalZero *
190*150812a8SEvalZero * @param[in] group_num Specifies the group to clear the "allocated" indication.
191*150812a8SEvalZero */
group_allocated_clr(nrf_ppi_channel_group_t group)192*150812a8SEvalZero __STATIC_INLINE void group_allocated_clr(nrf_ppi_channel_group_t group)
193*150812a8SEvalZero {
194*150812a8SEvalZero m_groups_allocated &= ~group_to_mask(group);
195*150812a8SEvalZero }
196*150812a8SEvalZero
197*150812a8SEvalZero
198*150812a8SEvalZero /**
199*150812a8SEvalZero * @brief Clear all allocated groups.
200*150812a8SEvalZero */
group_allocated_clr_all()201*150812a8SEvalZero __STATIC_INLINE void group_allocated_clr_all()
202*150812a8SEvalZero {
203*150812a8SEvalZero m_groups_allocated &= ~NRFX_PPI_ALL_APP_GROUPS_MASK;
204*150812a8SEvalZero }
205*150812a8SEvalZero
206*150812a8SEvalZero
nrfx_ppi_free_all(void)207*150812a8SEvalZero void nrfx_ppi_free_all(void)
208*150812a8SEvalZero {
209*150812a8SEvalZero uint32_t mask = NRFX_PPI_ALL_APP_GROUPS_MASK;
210*150812a8SEvalZero nrf_ppi_channel_group_t group;
211*150812a8SEvalZero
212*150812a8SEvalZero // Disable all channels and groups
213*150812a8SEvalZero nrf_ppi_channels_disable(NRFX_PPI_ALL_APP_CHANNELS_MASK);
214*150812a8SEvalZero
215*150812a8SEvalZero for (group = NRF_PPI_CHANNEL_GROUP0; mask != 0; mask &= ~group_to_mask(group), group++)
216*150812a8SEvalZero {
217*150812a8SEvalZero if (mask & group_to_mask(group))
218*150812a8SEvalZero {
219*150812a8SEvalZero nrf_ppi_channel_group_clear(group);
220*150812a8SEvalZero }
221*150812a8SEvalZero }
222*150812a8SEvalZero channel_allocated_clr_all();
223*150812a8SEvalZero group_allocated_clr_all();
224*150812a8SEvalZero }
225*150812a8SEvalZero
226*150812a8SEvalZero
nrfx_ppi_channel_alloc(nrf_ppi_channel_t * p_channel)227*150812a8SEvalZero nrfx_err_t nrfx_ppi_channel_alloc(nrf_ppi_channel_t * p_channel)
228*150812a8SEvalZero {
229*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
230*150812a8SEvalZero nrf_ppi_channel_t channel;
231*150812a8SEvalZero uint32_t mask = 0;
232*150812a8SEvalZero err_code = NRFX_ERROR_NO_MEM;
233*150812a8SEvalZero
234*150812a8SEvalZero mask = NRFX_PPI_PROG_APP_CHANNELS_MASK;
235*150812a8SEvalZero for (channel = NRF_PPI_CHANNEL0;
236*150812a8SEvalZero mask != 0;
237*150812a8SEvalZero mask &= ~nrfx_ppi_channel_to_mask(channel), channel++)
238*150812a8SEvalZero {
239*150812a8SEvalZero NRFX_CRITICAL_SECTION_ENTER();
240*150812a8SEvalZero if ((mask & nrfx_ppi_channel_to_mask(channel)) && (!is_allocated_channel(channel)))
241*150812a8SEvalZero {
242*150812a8SEvalZero channel_allocated_set(channel);
243*150812a8SEvalZero *p_channel = channel;
244*150812a8SEvalZero err_code = NRFX_SUCCESS;
245*150812a8SEvalZero }
246*150812a8SEvalZero NRFX_CRITICAL_SECTION_EXIT();
247*150812a8SEvalZero if (err_code == NRFX_SUCCESS)
248*150812a8SEvalZero {
249*150812a8SEvalZero NRFX_LOG_INFO("Allocated channel: %d.", channel);
250*150812a8SEvalZero break;
251*150812a8SEvalZero }
252*150812a8SEvalZero }
253*150812a8SEvalZero
254*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
255*150812a8SEvalZero return err_code;
256*150812a8SEvalZero }
257*150812a8SEvalZero
258*150812a8SEvalZero
nrfx_ppi_channel_free(nrf_ppi_channel_t channel)259*150812a8SEvalZero nrfx_err_t nrfx_ppi_channel_free(nrf_ppi_channel_t channel)
260*150812a8SEvalZero {
261*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
262*150812a8SEvalZero
263*150812a8SEvalZero if (!is_programmable_app_channel(channel))
264*150812a8SEvalZero {
265*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
266*150812a8SEvalZero }
267*150812a8SEvalZero else
268*150812a8SEvalZero {
269*150812a8SEvalZero // First disable this channel
270*150812a8SEvalZero nrf_ppi_channel_disable(channel);
271*150812a8SEvalZero NRFX_CRITICAL_SECTION_ENTER();
272*150812a8SEvalZero channel_allocated_clr(channel);
273*150812a8SEvalZero NRFX_CRITICAL_SECTION_EXIT();
274*150812a8SEvalZero }
275*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
276*150812a8SEvalZero return err_code;
277*150812a8SEvalZero }
278*150812a8SEvalZero
279*150812a8SEvalZero
nrfx_ppi_channel_assign(nrf_ppi_channel_t channel,uint32_t eep,uint32_t tep)280*150812a8SEvalZero nrfx_err_t nrfx_ppi_channel_assign(nrf_ppi_channel_t channel, uint32_t eep, uint32_t tep)
281*150812a8SEvalZero {
282*150812a8SEvalZero if ((uint32_t *)eep == NULL || (uint32_t *)tep == NULL)
283*150812a8SEvalZero {
284*150812a8SEvalZero return NRFX_ERROR_NULL;
285*150812a8SEvalZero }
286*150812a8SEvalZero
287*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
288*150812a8SEvalZero
289*150812a8SEvalZero if (!is_programmable_app_channel(channel))
290*150812a8SEvalZero {
291*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
292*150812a8SEvalZero }
293*150812a8SEvalZero else if (!is_allocated_channel(channel))
294*150812a8SEvalZero {
295*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
296*150812a8SEvalZero }
297*150812a8SEvalZero else
298*150812a8SEvalZero {
299*150812a8SEvalZero nrf_ppi_channel_endpoint_setup(channel, eep, tep);
300*150812a8SEvalZero NRFX_LOG_INFO("Assigned channel: %d, event end point: %x, task end point: %x.",
301*150812a8SEvalZero channel,
302*150812a8SEvalZero eep,
303*150812a8SEvalZero tep);
304*150812a8SEvalZero }
305*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
306*150812a8SEvalZero return err_code;
307*150812a8SEvalZero }
308*150812a8SEvalZero
nrfx_ppi_channel_fork_assign(nrf_ppi_channel_t channel,uint32_t fork_tep)309*150812a8SEvalZero nrfx_err_t nrfx_ppi_channel_fork_assign(nrf_ppi_channel_t channel, uint32_t fork_tep)
310*150812a8SEvalZero {
311*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
312*150812a8SEvalZero #ifdef PPI_FEATURE_FORKS_PRESENT
313*150812a8SEvalZero if (!is_allocated_channel(channel))
314*150812a8SEvalZero {
315*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
316*150812a8SEvalZero }
317*150812a8SEvalZero else
318*150812a8SEvalZero {
319*150812a8SEvalZero nrf_ppi_fork_endpoint_setup(channel, fork_tep);
320*150812a8SEvalZero NRFX_LOG_INFO("Fork assigned channel: %d, task end point: %d.", channel, fork_tep);
321*150812a8SEvalZero }
322*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
323*150812a8SEvalZero return err_code;
324*150812a8SEvalZero #else
325*150812a8SEvalZero err_code = NRFX_ERROR_NOT_SUPPORTED;
326*150812a8SEvalZero NRFX_LOG_WARNING("Function: %s, error code: %s.",
327*150812a8SEvalZero __func__,
328*150812a8SEvalZero NRFX_LOG_ERROR_STRING_GET(err_code));
329*150812a8SEvalZero return err_code;
330*150812a8SEvalZero #endif
331*150812a8SEvalZero }
332*150812a8SEvalZero
nrfx_ppi_channel_enable(nrf_ppi_channel_t channel)333*150812a8SEvalZero nrfx_err_t nrfx_ppi_channel_enable(nrf_ppi_channel_t channel)
334*150812a8SEvalZero {
335*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
336*150812a8SEvalZero
337*150812a8SEvalZero if (!is_app_channel(channel))
338*150812a8SEvalZero {
339*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
340*150812a8SEvalZero }
341*150812a8SEvalZero else if (is_programmable_app_channel(channel) && !is_allocated_channel(channel))
342*150812a8SEvalZero {
343*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
344*150812a8SEvalZero }
345*150812a8SEvalZero else
346*150812a8SEvalZero {
347*150812a8SEvalZero nrf_ppi_channel_enable(channel);
348*150812a8SEvalZero }
349*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
350*150812a8SEvalZero return err_code;
351*150812a8SEvalZero }
352*150812a8SEvalZero
353*150812a8SEvalZero
nrfx_ppi_channel_disable(nrf_ppi_channel_t channel)354*150812a8SEvalZero nrfx_err_t nrfx_ppi_channel_disable(nrf_ppi_channel_t channel)
355*150812a8SEvalZero {
356*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
357*150812a8SEvalZero
358*150812a8SEvalZero if (!is_app_channel(channel))
359*150812a8SEvalZero {
360*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
361*150812a8SEvalZero }
362*150812a8SEvalZero else if (is_programmable_app_channel(channel) && !is_allocated_channel(channel))
363*150812a8SEvalZero {
364*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
365*150812a8SEvalZero }
366*150812a8SEvalZero else
367*150812a8SEvalZero {
368*150812a8SEvalZero nrf_ppi_channel_disable(channel);
369*150812a8SEvalZero err_code = NRFX_SUCCESS;
370*150812a8SEvalZero }
371*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
372*150812a8SEvalZero return err_code;
373*150812a8SEvalZero }
374*150812a8SEvalZero
375*150812a8SEvalZero
nrfx_ppi_group_alloc(nrf_ppi_channel_group_t * p_group)376*150812a8SEvalZero nrfx_err_t nrfx_ppi_group_alloc(nrf_ppi_channel_group_t * p_group)
377*150812a8SEvalZero {
378*150812a8SEvalZero nrfx_err_t err_code;
379*150812a8SEvalZero uint32_t mask = 0;
380*150812a8SEvalZero nrf_ppi_channel_group_t group;
381*150812a8SEvalZero
382*150812a8SEvalZero err_code = NRFX_ERROR_NO_MEM;
383*150812a8SEvalZero
384*150812a8SEvalZero mask = NRFX_PPI_ALL_APP_GROUPS_MASK;
385*150812a8SEvalZero for (group = NRF_PPI_CHANNEL_GROUP0; mask != 0; mask &= ~group_to_mask(group), group++)
386*150812a8SEvalZero {
387*150812a8SEvalZero NRFX_CRITICAL_SECTION_ENTER();
388*150812a8SEvalZero if ((mask & group_to_mask(group)) && (!is_allocated_group(group)))
389*150812a8SEvalZero {
390*150812a8SEvalZero group_allocated_set(group);
391*150812a8SEvalZero *p_group = group;
392*150812a8SEvalZero err_code = NRFX_SUCCESS;
393*150812a8SEvalZero }
394*150812a8SEvalZero NRFX_CRITICAL_SECTION_EXIT();
395*150812a8SEvalZero if (err_code == NRFX_SUCCESS)
396*150812a8SEvalZero {
397*150812a8SEvalZero NRFX_LOG_INFO("Allocated group: %d.", group);
398*150812a8SEvalZero break;
399*150812a8SEvalZero }
400*150812a8SEvalZero }
401*150812a8SEvalZero
402*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
403*150812a8SEvalZero return err_code;
404*150812a8SEvalZero }
405*150812a8SEvalZero
406*150812a8SEvalZero
nrfx_ppi_group_free(nrf_ppi_channel_group_t group)407*150812a8SEvalZero nrfx_err_t nrfx_ppi_group_free(nrf_ppi_channel_group_t group)
408*150812a8SEvalZero {
409*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
410*150812a8SEvalZero
411*150812a8SEvalZero if (!is_app_group(group))
412*150812a8SEvalZero {
413*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
414*150812a8SEvalZero }
415*150812a8SEvalZero if (!is_allocated_group(group))
416*150812a8SEvalZero {
417*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
418*150812a8SEvalZero }
419*150812a8SEvalZero else
420*150812a8SEvalZero {
421*150812a8SEvalZero nrf_ppi_group_disable(group);
422*150812a8SEvalZero NRFX_CRITICAL_SECTION_ENTER();
423*150812a8SEvalZero group_allocated_clr(group);
424*150812a8SEvalZero NRFX_CRITICAL_SECTION_EXIT();
425*150812a8SEvalZero }
426*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
427*150812a8SEvalZero return err_code;
428*150812a8SEvalZero }
429*150812a8SEvalZero
430*150812a8SEvalZero
nrfx_ppi_group_enable(nrf_ppi_channel_group_t group)431*150812a8SEvalZero nrfx_err_t nrfx_ppi_group_enable(nrf_ppi_channel_group_t group)
432*150812a8SEvalZero {
433*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
434*150812a8SEvalZero
435*150812a8SEvalZero if (!is_app_group(group))
436*150812a8SEvalZero {
437*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
438*150812a8SEvalZero }
439*150812a8SEvalZero else if (!is_allocated_group(group))
440*150812a8SEvalZero {
441*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
442*150812a8SEvalZero }
443*150812a8SEvalZero else
444*150812a8SEvalZero {
445*150812a8SEvalZero nrf_ppi_group_enable(group);
446*150812a8SEvalZero }
447*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
448*150812a8SEvalZero return err_code;
449*150812a8SEvalZero }
450*150812a8SEvalZero
451*150812a8SEvalZero
nrfx_ppi_group_disable(nrf_ppi_channel_group_t group)452*150812a8SEvalZero nrfx_err_t nrfx_ppi_group_disable(nrf_ppi_channel_group_t group)
453*150812a8SEvalZero {
454*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
455*150812a8SEvalZero
456*150812a8SEvalZero if (!is_app_group(group))
457*150812a8SEvalZero {
458*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
459*150812a8SEvalZero }
460*150812a8SEvalZero else
461*150812a8SEvalZero {
462*150812a8SEvalZero nrf_ppi_group_disable(group);
463*150812a8SEvalZero }
464*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
465*150812a8SEvalZero return err_code;
466*150812a8SEvalZero }
467*150812a8SEvalZero
nrfx_ppi_channels_remove_from_group(uint32_t channel_mask,nrf_ppi_channel_group_t group)468*150812a8SEvalZero nrfx_err_t nrfx_ppi_channels_remove_from_group(uint32_t channel_mask,
469*150812a8SEvalZero nrf_ppi_channel_group_t group)
470*150812a8SEvalZero {
471*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
472*150812a8SEvalZero
473*150812a8SEvalZero if (!is_app_group(group))
474*150812a8SEvalZero {
475*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
476*150812a8SEvalZero }
477*150812a8SEvalZero else if (!is_allocated_group(group))
478*150812a8SEvalZero {
479*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
480*150812a8SEvalZero }
481*150812a8SEvalZero else if (!are_app_channels(channel_mask))
482*150812a8SEvalZero {
483*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
484*150812a8SEvalZero }
485*150812a8SEvalZero else
486*150812a8SEvalZero {
487*150812a8SEvalZero NRFX_CRITICAL_SECTION_ENTER();
488*150812a8SEvalZero nrf_ppi_channels_remove_from_group(channel_mask, group);
489*150812a8SEvalZero NRFX_CRITICAL_SECTION_EXIT();
490*150812a8SEvalZero }
491*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
492*150812a8SEvalZero return err_code;
493*150812a8SEvalZero }
494*150812a8SEvalZero
nrfx_ppi_channels_include_in_group(uint32_t channel_mask,nrf_ppi_channel_group_t group)495*150812a8SEvalZero nrfx_err_t nrfx_ppi_channels_include_in_group(uint32_t channel_mask,
496*150812a8SEvalZero nrf_ppi_channel_group_t group)
497*150812a8SEvalZero {
498*150812a8SEvalZero nrfx_err_t err_code = NRFX_SUCCESS;
499*150812a8SEvalZero
500*150812a8SEvalZero if (!is_app_group(group))
501*150812a8SEvalZero {
502*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
503*150812a8SEvalZero }
504*150812a8SEvalZero else if (!is_allocated_group(group))
505*150812a8SEvalZero {
506*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_STATE;
507*150812a8SEvalZero }
508*150812a8SEvalZero else if (!are_app_channels(channel_mask))
509*150812a8SEvalZero {
510*150812a8SEvalZero err_code = NRFX_ERROR_INVALID_PARAM;
511*150812a8SEvalZero }
512*150812a8SEvalZero else
513*150812a8SEvalZero {
514*150812a8SEvalZero NRFX_CRITICAL_SECTION_ENTER();
515*150812a8SEvalZero nrf_ppi_channels_include_in_group(channel_mask, group);
516*150812a8SEvalZero NRFX_CRITICAL_SECTION_EXIT();
517*150812a8SEvalZero }
518*150812a8SEvalZero NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
519*150812a8SEvalZero return err_code;
520*150812a8SEvalZero }
521*150812a8SEvalZero #endif // NRFX_CHECK(NRFX_PPI_ENABLED)
522