xref: /nrf52832-nimble/nordic/nrfx/drivers/src/nrfx_ppi.c (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
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