@@ -190,15 +190,28 @@ typedef struct
190190 /* Mask for tracking event handler entries allocation. */
191191 nrfx_atomic_t available_evt_handlers ;
192192
193- /* Mask of available ports for GPIOTE instance. */
194- uint32_t available_gpio_ports ;
195-
193+ uint8_t ch_pin [GPIOTE_CH_NUM ];
196194#if !defined(NRF_GPIO_LATCH_PRESENT )
197195 uint32_t port_pins [GPIO_COUNT ];
198196#endif
199197 nrfx_drv_state_t state ;
200198} gpiote_control_block_t ;
201199
200+ typedef struct
201+ {
202+ /* Number of GPIOTE channels. */
203+ uint32_t channels_number ;
204+
205+ /* Mask of available ports for GPIOTE instance. */
206+ uint32_t available_gpio_ports ;
207+
208+ #if NRFX_GPIOTE_VAR_FEATURE_SUPPORT
209+ uint32_t group_idx ;
210+ bool port_supported ;
211+ bool dynamic_chan_supported ;
212+ #endif
213+ } gpiote_config_t ;
214+
202215#if !defined(__NRFX_DOXYGEN__ )
203216#if (defined(NRF_GPIOTE ) || defined(NRF_GPIOTE0 )) && !defined(NRFX_GPIOTE0_CHANNELS_USED )
204217/* Bitmask that defines GPIOTE0 channels that are reserved for use outside of the nrfx library. */
@@ -231,16 +244,34 @@ typedef struct
231244#endif
232245#endif // !defined(__NRFX_DOXYGEN__)
233246
234- #define _NRFX_GPIOTE_CB_INITIALIZER (periph_name , prefix , idx , _ ) \
247+ #ifdef NRFX_GPIOTE_VAR_FEATURE_SUPPORT
248+ #define GPIOTE_VAR_INIT (prefix , idx ) \
249+ .group_idx = idx == 0 ? 0 : NRF_GPIOTE_IRQ_GROUP, \
250+ .port_supported = idx != 0, \
251+ .dynamic_chan_supported = idx != 0,
252+ #else
253+ #define GPIOTE_VAR_INIT (prefix , idx )
254+ #endif
255+
256+ #define _NRFX_GPIOTE_CONFIG_INITIALIZER (periph_name , prefix , idx , _ ) \
235257 [NRFX_CONCAT(NRFX_, periph_name, idx, _INST_IDX)] = { \
236258 .channels_number = NRFX_CONCAT_3(periph_name, idx, _CH_NUM), \
237- .available_channels_mask = (nrfx_atomic_t)NRFX_GPIOTE_APP_CHANNELS_MASK(idx), \
238259 .available_gpio_ports = NRFX_CONCAT_3(periph_name, idx, _AVAILABLE_GPIO_PORTS), \
260+ GPIOTE_VAR_INIT(prefix, idx) \
239261 },
240262
241- static gpiote_control_block_t m_cb [NRFX_GPIOTE_ENABLED_COUNT ] = {
242- NRFX_FOREACH_ENABLED (GPIOTE , _NRFX_GPIOTE_CB_INITIALIZER , ( ), ( ))
263+ #define _NRFX_GPIOTE_CHANNEL_INITIALIZER (periph_name , prefix , idx , _ ) \
264+ [NRFX_CONCAT(NRFX_, periph_name, idx, _INST_IDX)] = \
265+ (nrfx_atomic_t)NRFX_GPIOTE_APP_CHANNELS_MASK(idx),
266+
267+ /* Mask for tracking GPIOTE channel allocation. */
268+ static nrfx_atomic_t available_channels_mask [NRFX_GPIOTE_ENABLED_COUNT ] = {
269+ NRFX_FOREACH_ENABLED (GPIOTE , _NRFX_GPIOTE_CHANNEL_INITIALIZER , ( ), ( ))
243270};
271+ static const gpiote_config_t m_config [NRFX_GPIOTE_ENABLED_COUNT ] = {
272+ NRFX_FOREACH_ENABLED (GPIOTE , _NRFX_GPIOTE_CONFIG_INITIALIZER , ( ), ( ))
273+ };
274+ static gpiote_control_block_t m_cb [NRFX_GPIOTE_ENABLED_COUNT ];
244275
245276#if defined(NRF_GPIO_LATCH_PRESENT ) || (!FULL_PORTS_PRESENT )
246277static const uint8_t ports [GPIO_COUNT ] = GPIO_PORT_NUM_LIST ;
@@ -301,6 +332,26 @@ static gpiote_control_block_t * get_cb(uint32_t idx)
301332 }
302333}
303334
335+ /** @brief Function for getting instance configuration structure.
336+ *
337+ * Function is optimized for case when there is only one GPIOTE instance.
338+ *
339+ * @param[in] idx Instance index.
340+ *
341+ * @return Configure structure.
342+ */
343+ static const gpiote_config_t * get_config (uint32_t idx )
344+ {
345+ if (NRFX_GPIOTE_ENABLED_COUNT == 1 )
346+ {
347+ return & m_config [0 ];
348+ }
349+ else
350+ {
351+ return & m_config [idx ];
352+ }
353+ }
354+
304355/** @brief Checks if pin is in use by a given GPIOTE instance.
305356 *
306357 * @param[in] p_instance Pointer to the driver instance structure.
@@ -471,7 +522,13 @@ static void pin_trigger_disable(nrfx_gpiote_t const * p_instance, nrfx_gpiote_pi
471522 {
472523 uint8_t ch = pin_te_get (p_instance , pin );
473524
474- nrfy_gpiote_int_disable (p_instance -> p_reg , NRFX_BIT (ch ));
525+ #ifdef NRFX_GPIOTE_VAR_FEATURE_SUPPORT
526+ nrf_gpiote_int_group_disable (p_instance -> p_reg ,
527+ get_config (p_instance -> drv_inst_idx )-> group_idx ,
528+ NRFX_BIT (ch ));
529+ #else
530+ nrfy_gpiote_int_disable (p_instance -> p_reg , NRFX_BIT (ch ));
531+ #endif
475532 nrfy_gpiote_event_disable (p_instance -> p_reg , ch );
476533 }
477534 else
@@ -677,7 +734,7 @@ static nrfx_err_t gpiote_input_configure(nrfx_gpiote_t const *
677734
678735 nrfy_gpiote_event_disable (p_instance -> p_reg , ch );
679736 nrfy_gpiote_event_configure (p_instance -> p_reg , ch , pin , polarity );
680-
737+ get_cb ( p_instance -> drv_inst_idx ) -> ch_pin [ ch ] = pin ;
681738 get_cb (p_instance -> drv_inst_idx )-> pin_flags [idx ] |= (uint16_t )PIN_FLAG_TE_ID (ch );
682739 }
683740 }
@@ -689,6 +746,12 @@ static nrfx_err_t gpiote_input_configure(nrfx_gpiote_t const *
689746 }
690747 else
691748 {
749+ #if NRFX_GPIOTE_VAR_FEATURE_SUPPORT
750+ if (!get_config (p_instance -> drv_inst_idx )-> port_supported )
751+ {
752+ return NRFX_ERROR_INVALID_PARAM ;
753+ }
754+ #endif
692755 nrf_bitmask_bit_set (pin , (uint8_t * )get_cb (p_instance -> drv_inst_idx )-> port_pins );
693756 }
694757#endif
@@ -805,7 +868,8 @@ static nrfx_err_t gpiote_init(nrfx_gpiote_t const * p_instance, uint8_t interrup
805868 nrfx_err_t err_code = NRFX_SUCCESS ;
806869
807870 NRFX_LOG_INFO ("channels_number: %d, available_channels_mask: 0x%x" ,
808- (int )p_cb -> channels_number , (int )p_cb -> available_channels_mask );
871+ (int )get_config (p_instance -> drv_inst_idx )-> channels_number ,
872+ (int )available_channels_mask [p_instance -> drv_inst_idx ]);
809873
810874 if (p_cb -> state != NRFX_DRV_STATE_UNINITIALIZED )
811875 {
@@ -822,11 +886,18 @@ static nrfx_err_t gpiote_init(nrfx_gpiote_t const * p_instance, uint8_t interrup
822886
823887 memset (p_cb -> pin_flags , 0 , sizeof (p_cb -> pin_flags ));
824888
889+ #if NRFX_GPIOTE_VAR_FEATURE_SUPPORT
890+ uint32_t int_mask = get_config (p_instance -> drv_inst_idx )-> port_supported ?
891+ NRF_GPIOTE_INT_PORT_MASK : 0 ;
892+ #else
893+ uint32_t int_mask = NRF_GPIOTE_INT_PORT_MASK ;
894+ #endif
895+
825896 nrfy_gpiote_int_init (p_instance -> p_reg ,
826- ( uint32_t ) NRF_GPIOTE_INT_PORT_MASK ,
897+ int_mask ,
827898 interrupt_priority ,
828899 false,
829- p_cb -> channels_number );
900+ get_config ( p_instance -> drv_inst_idx ) -> channels_number );
830901
831902 p_cb -> state = NRFX_DRV_STATE_INITIALIZED ;
832903 p_cb -> available_evt_handlers = NRFX_BIT_MASK (NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS );
@@ -875,14 +946,31 @@ static void gpiote_uninit(nrfx_gpiote_t const * p_instance)
875946
876947static nrfx_err_t pin_channel_free (nrfx_gpiote_t const * p_instance , uint8_t channel )
877948{
878- return nrfx_flag32_free (& get_cb (p_instance -> drv_inst_idx )-> available_channels_mask , channel );
949+ #if NRFX_GPIOTE_VAR_FEATURE_SUPPORT
950+ const gpiote_config_t * p_config = get_config (p_instance -> drv_inst_idx );
951+
952+ if (!p_config -> dynamic_chan_supported )
953+ {
954+ return NRFX_ERROR_NOT_SUPPORTED ;
955+ }
956+ #endif
957+ return nrfx_flag32_free (& available_channels_mask [p_instance -> drv_inst_idx ], channel );
879958}
880959
881960static nrfx_err_t pin_channel_alloc (nrfx_gpiote_t const * p_instance , uint8_t * p_channel )
882961{
883962 NRFX_LOG_INFO ("available_channels_mask = %d" ,
884- (int )get_cb (p_instance -> drv_inst_idx )-> available_channels_mask );
885- return nrfx_flag32_alloc (& get_cb (p_instance -> drv_inst_idx )-> available_channels_mask , p_channel );
963+ (int )& available_channels_mask [p_instance -> drv_inst_idx ]);
964+ #if NRFX_GPIOTE_VAR_FEATURE_SUPPORT
965+ const gpiote_config_t * p_config = get_config (p_instance -> drv_inst_idx );
966+
967+ if (!p_config -> dynamic_chan_supported )
968+ {
969+ return NRFX_ERROR_NOT_SUPPORTED ;
970+ }
971+ #endif
972+
973+ return nrfx_flag32_alloc (& available_channels_mask [p_instance -> drv_inst_idx ], p_channel );
886974}
887975
888976static void pin_out_set (nrfx_gpiote_t const * p_instance , nrfx_gpiote_pin_t pin )
@@ -1017,11 +1105,6 @@ static void pin_trigger_enable(nrfx_gpiote_t const * p_instance,
10171105{
10181106 NRFX_ASSERT (pin_has_trigger (p_instance , pin ));
10191107
1020- if (!nrfy_gpiote_int_enable_check (p_instance -> p_reg , (uint32_t )NRF_GPIOTE_INT_PORT_MASK ))
1021- {
1022- nrfy_gpiote_int_enable (p_instance -> p_reg , (uint32_t )NRF_GPIOTE_INT_PORT_MASK );
1023- }
1024-
10251108 if (pin_in_use_by_te (p_instance , pin ) && pin_is_input (p_instance , pin ))
10261109 {
10271110 uint8_t ch = pin_te_get (p_instance , pin );
@@ -1030,11 +1113,22 @@ static void pin_trigger_enable(nrfx_gpiote_t const * p_instance,
10301113 nrfy_gpiote_event_enable (p_instance -> p_reg , ch );
10311114 if (int_enable )
10321115 {
1116+ #if NRFX_GPIOTE_VAR_FEATURE_SUPPORT
1117+ nrf_gpiote_int_group_enable (p_instance -> p_reg ,
1118+ get_config (p_instance -> drv_inst_idx )-> group_idx ,
1119+ NRFX_BIT (ch ));
1120+ #else
10331121 nrfy_gpiote_int_enable (p_instance -> p_reg , NRFX_BIT (ch ));
1122+ #endif
10341123 }
10351124 }
10361125 else
10371126 {
1127+ if (!nrfy_gpiote_int_enable_check (p_instance -> p_reg , (uint32_t )NRF_GPIOTE_INT_PORT_MASK ))
1128+ {
1129+ nrfy_gpiote_int_enable (p_instance -> p_reg , (uint32_t )NRF_GPIOTE_INT_PORT_MASK );
1130+ }
1131+
10381132 NRFX_ASSERT (int_enable );
10391133 nrfy_gpio_cfg_sense_set (pin , get_initial_sense (p_instance , pin ));
10401134 }
@@ -1079,9 +1173,7 @@ nrfx_err_t nrfx_gpiote_channel_get(nrfx_gpiote_t const * p_instance,
10791173
10801174uint32_t nrfx_gpiote_channels_number_get (nrfx_gpiote_t const * p_instance )
10811175{
1082- gpiote_control_block_t * p_cb = get_cb (p_instance -> drv_inst_idx );
1083-
1084- return p_cb -> channels_number ;
1176+ return get_config (p_instance -> drv_inst_idx )-> channels_number ;
10851177}
10861178
10871179nrfx_err_t nrfx_gpiote_init (nrfx_gpiote_t const * p_instance , uint8_t interrupt_priority )
@@ -1479,16 +1571,17 @@ static bool latch_pending_read_and_check(uint32_t * latch, uint32_t available_gp
14791571 return false;
14801572}
14811573
1482- static void port_event_handle (NRF_GPIOTE_Type * p_gpiote , gpiote_control_block_t * p_cb )
1574+ static void port_event_handle (NRF_GPIOTE_Type * p_gpiote , gpiote_control_block_t * p_cb ,
1575+ const gpiote_config_t * p_config )
14831576{
14841577 uint32_t latch [GPIO_COUNT ] = {0 };
14851578
1486- latch_pending_read_and_check (latch , p_cb -> available_gpio_ports );
1579+ latch_pending_read_and_check (latch , p_config -> available_gpio_ports );
14871580
14881581 do {
14891582 for (uint32_t i = 0 ; i < GPIO_COUNT ; i ++ )
14901583 {
1491- if (nrf_bitmask_bit_is_set (port_index [i ], & p_cb -> available_gpio_ports ))
1584+ if (nrf_bitmask_bit_is_set (port_index [i ], & p_config -> available_gpio_ports ))
14921585 {
14931586 while (latch [i ])
14941587 {
@@ -1515,10 +1608,8 @@ static void port_event_handle(NRF_GPIOTE_Type * p_gpiote, gpiote_control_block_t
15151608
15161609 /* All pins have been handled, clear PORT, check latch again in case
15171610 * something came between deciding to exit and clearing PORT event. */
1518- (void )nrfy_gpiote_events_process (p_gpiote ,
1519- (uint32_t )NRF_GPIOTE_INT_PORT_MASK ,
1520- p_cb -> channels_number );
1521- } while (latch_pending_read_and_check (latch , p_cb -> available_gpio_ports ));
1611+ (void )nrfy_gpiote_events_process (p_gpiote , (uint32_t )NRF_GPIOTE_INT_PORT_MASK , 0 );
1612+ } while (latch_pending_read_and_check (latch , p_config -> available_gpio_ports ));
15221613}
15231614
15241615#else
@@ -1556,7 +1647,8 @@ static bool input_read_and_check(uint32_t * input,
15561647 return process_inputs_again ;
15571648}
15581649
1559- static void port_event_handle (NRF_GPIOTE_Type * p_gpiote , gpiote_control_block_t * p_cb )
1650+ static void port_event_handle (NRF_GPIOTE_Type * p_gpiote , gpiote_control_block_t * p_cb ,
1651+ const gpiote_config_t * p_config )
15601652{
15611653 uint32_t pins_to_check [GPIO_COUNT ] = {0 };
15621654 uint32_t input [GPIO_COUNT ] = {0 };
@@ -1566,7 +1658,7 @@ static void port_event_handle(NRF_GPIOTE_Type * p_gpiote, gpiote_control_block_t
15661658
15671659 for (uint32_t port_idx = 0 ; port_idx < GPIO_COUNT ; port_idx ++ )
15681660 {
1569- if (nrf_bitmask_bit_is_set (port_index [port_idx ], & p_cb -> available_gpio_ports ))
1661+ if (nrf_bitmask_bit_is_set (port_index [port_idx ], & p_config -> available_gpio_ports ))
15701662 {
15711663 nrfy_gpio_ports_read (port_idx , 1 , & input [port_idx ]);
15721664 pins_to_check [port_idx ] = p_cb -> port_pins [port_idx ];
@@ -1601,7 +1693,7 @@ static void port_event_handle(NRF_GPIOTE_Type * p_gpiote, gpiote_control_block_t
16011693
16021694 for (uint32_t port_idx = 0 ; port_idx < GPIO_COUNT ; port_idx ++ )
16031695 {
1604- if (nrf_bitmask_bit_is_set (port_index [port_idx ], & p_cb -> available_gpio_ports ))
1696+ if (nrf_bitmask_bit_is_set (port_index [port_idx ], & p_config -> available_gpio_ports ))
16051697 {
16061698 /* All pins used with PORT must be rechecked because it's content and
16071699 * number of port pins may have changed during handler execution. */
@@ -1634,10 +1726,8 @@ static void port_event_handle(NRF_GPIOTE_Type * p_gpiote, gpiote_control_block_t
16341726 }
16351727 }
16361728
1637- (void )nrfy_gpiote_events_process (p_gpiote ,
1638- (uint32_t )NRF_GPIOTE_INT_PORT_MASK ,
1639- p_cb -> channels_number );
1640- } while (input_read_and_check (input , pins_to_check , p_cb -> available_gpio_ports ));
1729+ (void )nrfy_gpiote_events_process (p_gpiote , (uint32_t )NRF_GPIOTE_INT_PORT_MASK , 0 );
1730+ } while (input_read_and_check (input , pins_to_check , p_config -> available_gpio_ports ));
16411731}
16421732#endif // defined(NRF_GPIO_LATCH_PRESENT)
16431733
@@ -1649,7 +1739,7 @@ static void gpiote_evt_handle(NRF_GPIOTE_Type * p_gpiote,
16491739 {
16501740 uint32_t ch = NRF_CTZ (mask );
16511741 mask &= ~NRFX_BIT (ch );
1652- nrfx_gpiote_pin_t pin = nrfy_gpiote_event_pin_get ( p_gpiote , ch ) ;
1742+ nrfx_gpiote_pin_t pin = p_cb -> ch_pin [ ch ] ;
16531743 nrf_gpiote_polarity_t polarity = nrfy_gpiote_event_polarity_get (p_gpiote , ch );
16541744
16551745 call_handler (p_cb , pin , gpiote_polarity_to_trigger (polarity ));
@@ -1658,17 +1748,27 @@ static void gpiote_evt_handle(NRF_GPIOTE_Type * p_gpiote,
16581748
16591749static void irq_handler (NRF_GPIOTE_Type * p_gpiote , gpiote_control_block_t * p_cb )
16601750{
1751+ uint32_t instance_idx = ((uintptr_t )p_cb - (uintptr_t )m_cb ) / sizeof (gpiote_control_block_t );
1752+ const gpiote_config_t * p_config = get_config (instance_idx );
16611753 /* Collect status of all GPIOTE pin events. Processing is done once all are collected and cleared.*/
1662- uint32_t enabled_in_events = nrf_gpiote_int_enable_check (p_gpiote , NRF_GPIOTE_INT_IN_MASK );
1754+ #if NRFX_GPIOTE_VAR_FEATURE_SUPPORT
1755+ uint32_t enabled_in_events = nrf_gpiote_int_group_enable_check (p_gpiote ,
1756+ p_config -> group_idx ,
1757+ NRF_GPIOTE_INT_IN_MASK );
1758+ uint32_t enabled_events = enabled_in_events |
1759+ (p_config -> port_supported ? NRF_GPIOTE_INT_PORT_MASK : 0 );
1760+ #else
1761+ uint32_t enabled_events = nrf_gpiote_int_enable_check (p_gpiote , NRF_GPIOTE_INT_IN_MASK ) |
1762+ NRF_GPIOTE_INT_PORT_MASK ;
1763+ #endif
16631764 uint32_t evt_mask = nrfy_gpiote_events_process (p_gpiote ,
1664- enabled_in_events |
1665- (uint32_t )NRF_GPIOTE_INT_PORT_MASK ,
1666- p_cb -> channels_number );
1765+ enabled_events ,
1766+ p_config -> channels_number );
16671767
16681768 /* Handle PORT event. */
16691769 if (evt_mask & (uint32_t )NRF_GPIOTE_INT_PORT_MASK )
16701770 {
1671- port_event_handle (p_gpiote , p_cb );
1771+ port_event_handle (p_gpiote , p_cb , p_config );
16721772 evt_mask &= ~(uint32_t )NRF_GPIOTE_INT_PORT_MASK ;
16731773 }
16741774
0 commit comments