@@ -190,15 +190,28 @@ typedef struct
190
190
/* Mask for tracking event handler entries allocation. */
191
191
nrfx_atomic_t available_evt_handlers ;
192
192
193
- /* Mask of available ports for GPIOTE instance. */
194
- uint32_t available_gpio_ports ;
195
-
193
+ uint8_t ch_pin [GPIOTE_CH_NUM ];
196
194
#if !defined(NRF_GPIO_LATCH_PRESENT )
197
195
uint32_t port_pins [GPIO_COUNT ];
198
196
#endif
199
197
nrfx_drv_state_t state ;
200
198
} gpiote_control_block_t ;
201
199
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
+
202
215
#if !defined(__NRFX_DOXYGEN__ )
203
216
#if (defined(NRF_GPIOTE ) || defined(NRF_GPIOTE0 )) && !defined(NRFX_GPIOTE0_CHANNELS_USED )
204
217
/* Bitmask that defines GPIOTE0 channels that are reserved for use outside of the nrfx library. */
@@ -231,16 +244,34 @@ typedef struct
231
244
#endif
232
245
#endif // !defined(__NRFX_DOXYGEN__)
233
246
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 , _ ) \
235
257
[NRFX_CONCAT(NRFX_, periph_name, idx, _INST_IDX)] = { \
236
258
.channels_number = NRFX_CONCAT_3(periph_name, idx, _CH_NUM), \
237
- .available_channels_mask = (nrfx_atomic_t)NRFX_GPIOTE_APP_CHANNELS_MASK(idx), \
238
259
.available_gpio_ports = NRFX_CONCAT_3(periph_name, idx, _AVAILABLE_GPIO_PORTS), \
260
+ GPIOTE_VAR_INIT(prefix, idx) \
239
261
},
240
262
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 , ( ), ( ))
243
270
};
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 ];
244
275
245
276
#if defined(NRF_GPIO_LATCH_PRESENT ) || (!FULL_PORTS_PRESENT )
246
277
static const uint8_t ports [GPIO_COUNT ] = GPIO_PORT_NUM_LIST ;
@@ -301,6 +332,26 @@ static gpiote_control_block_t * get_cb(uint32_t idx)
301
332
}
302
333
}
303
334
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
+
304
355
/** @brief Checks if pin is in use by a given GPIOTE instance.
305
356
*
306
357
* @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
471
522
{
472
523
uint8_t ch = pin_te_get (p_instance , pin );
473
524
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
475
532
nrfy_gpiote_event_disable (p_instance -> p_reg , ch );
476
533
}
477
534
else
@@ -677,7 +734,7 @@ static nrfx_err_t gpiote_input_configure(nrfx_gpiote_t const *
677
734
678
735
nrfy_gpiote_event_disable (p_instance -> p_reg , ch );
679
736
nrfy_gpiote_event_configure (p_instance -> p_reg , ch , pin , polarity );
680
-
737
+ get_cb ( p_instance -> drv_inst_idx ) -> ch_pin [ ch ] = pin ;
681
738
get_cb (p_instance -> drv_inst_idx )-> pin_flags [idx ] |= (uint16_t )PIN_FLAG_TE_ID (ch );
682
739
}
683
740
}
@@ -689,6 +746,12 @@ static nrfx_err_t gpiote_input_configure(nrfx_gpiote_t const *
689
746
}
690
747
else
691
748
{
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
692
755
nrf_bitmask_bit_set (pin , (uint8_t * )get_cb (p_instance -> drv_inst_idx )-> port_pins );
693
756
}
694
757
#endif
@@ -805,7 +868,8 @@ static nrfx_err_t gpiote_init(nrfx_gpiote_t const * p_instance, uint8_t interrup
805
868
nrfx_err_t err_code = NRFX_SUCCESS ;
806
869
807
870
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 ]);
809
873
810
874
if (p_cb -> state != NRFX_DRV_STATE_UNINITIALIZED )
811
875
{
@@ -822,11 +886,18 @@ static nrfx_err_t gpiote_init(nrfx_gpiote_t const * p_instance, uint8_t interrup
822
886
823
887
memset (p_cb -> pin_flags , 0 , sizeof (p_cb -> pin_flags ));
824
888
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
+
825
896
nrfy_gpiote_int_init (p_instance -> p_reg ,
826
- ( uint32_t ) NRF_GPIOTE_INT_PORT_MASK ,
897
+ int_mask ,
827
898
interrupt_priority ,
828
899
false,
829
- p_cb -> channels_number );
900
+ get_config ( p_instance -> drv_inst_idx ) -> channels_number );
830
901
831
902
p_cb -> state = NRFX_DRV_STATE_INITIALIZED ;
832
903
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)
875
946
876
947
static nrfx_err_t pin_channel_free (nrfx_gpiote_t const * p_instance , uint8_t channel )
877
948
{
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 );
879
958
}
880
959
881
960
static nrfx_err_t pin_channel_alloc (nrfx_gpiote_t const * p_instance , uint8_t * p_channel )
882
961
{
883
962
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 );
886
974
}
887
975
888
976
static 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,
1017
1105
{
1018
1106
NRFX_ASSERT (pin_has_trigger (p_instance , pin ));
1019
1107
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
-
1025
1108
if (pin_in_use_by_te (p_instance , pin ) && pin_is_input (p_instance , pin ))
1026
1109
{
1027
1110
uint8_t ch = pin_te_get (p_instance , pin );
@@ -1030,11 +1113,22 @@ static void pin_trigger_enable(nrfx_gpiote_t const * p_instance,
1030
1113
nrfy_gpiote_event_enable (p_instance -> p_reg , ch );
1031
1114
if (int_enable )
1032
1115
{
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
1033
1121
nrfy_gpiote_int_enable (p_instance -> p_reg , NRFX_BIT (ch ));
1122
+ #endif
1034
1123
}
1035
1124
}
1036
1125
else
1037
1126
{
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
+
1038
1132
NRFX_ASSERT (int_enable );
1039
1133
nrfy_gpio_cfg_sense_set (pin , get_initial_sense (p_instance , pin ));
1040
1134
}
@@ -1079,9 +1173,7 @@ nrfx_err_t nrfx_gpiote_channel_get(nrfx_gpiote_t const * p_instance,
1079
1173
1080
1174
uint32_t nrfx_gpiote_channels_number_get (nrfx_gpiote_t const * p_instance )
1081
1175
{
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 ;
1085
1177
}
1086
1178
1087
1179
nrfx_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
1479
1571
return false;
1480
1572
}
1481
1573
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 )
1483
1576
{
1484
1577
uint32_t latch [GPIO_COUNT ] = {0 };
1485
1578
1486
- latch_pending_read_and_check (latch , p_cb -> available_gpio_ports );
1579
+ latch_pending_read_and_check (latch , p_config -> available_gpio_ports );
1487
1580
1488
1581
do {
1489
1582
for (uint32_t i = 0 ; i < GPIO_COUNT ; i ++ )
1490
1583
{
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 ))
1492
1585
{
1493
1586
while (latch [i ])
1494
1587
{
@@ -1516,7 +1609,7 @@ static void port_event_handle(NRF_GPIOTE_Type * p_gpiote, gpiote_control_block_t
1516
1609
/* All pins have been handled, clear PORT, check latch again in case
1517
1610
* something came between deciding to exit and clearing PORT event. */
1518
1611
(void )nrfy_gpiote_events_process (p_gpiote , (uint32_t )NRF_GPIOTE_INT_PORT_MASK , 0 );
1519
- } while (latch_pending_read_and_check (latch , p_cb -> available_gpio_ports ));
1612
+ } while (latch_pending_read_and_check (latch , p_config -> available_gpio_ports ));
1520
1613
}
1521
1614
1522
1615
#else
@@ -1554,7 +1647,8 @@ static bool input_read_and_check(uint32_t * input,
1554
1647
return process_inputs_again ;
1555
1648
}
1556
1649
1557
- 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 )
1558
1652
{
1559
1653
uint32_t pins_to_check [GPIO_COUNT ] = {0 };
1560
1654
uint32_t input [GPIO_COUNT ] = {0 };
@@ -1564,7 +1658,7 @@ static void port_event_handle(NRF_GPIOTE_Type * p_gpiote, gpiote_control_block_t
1564
1658
1565
1659
for (uint32_t port_idx = 0 ; port_idx < GPIO_COUNT ; port_idx ++ )
1566
1660
{
1567
- 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 ))
1568
1662
{
1569
1663
nrfy_gpio_ports_read (port_idx , 1 , & input [port_idx ]);
1570
1664
pins_to_check [port_idx ] = p_cb -> port_pins [port_idx ];
@@ -1599,7 +1693,7 @@ static void port_event_handle(NRF_GPIOTE_Type * p_gpiote, gpiote_control_block_t
1599
1693
1600
1694
for (uint32_t port_idx = 0 ; port_idx < GPIO_COUNT ; port_idx ++ )
1601
1695
{
1602
- 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 ))
1603
1697
{
1604
1698
/* All pins used with PORT must be rechecked because it's content and
1605
1699
* number of port pins may have changed during handler execution. */
@@ -1633,7 +1727,7 @@ static void port_event_handle(NRF_GPIOTE_Type * p_gpiote, gpiote_control_block_t
1633
1727
}
1634
1728
1635
1729
(void )nrfy_gpiote_events_process (p_gpiote , (uint32_t )NRF_GPIOTE_INT_PORT_MASK , 0 );
1636
- } while (input_read_and_check (input , pins_to_check , p_cb -> available_gpio_ports ));
1730
+ } while (input_read_and_check (input , pins_to_check , p_config -> available_gpio_ports ));
1637
1731
}
1638
1732
#endif // defined(NRF_GPIO_LATCH_PRESENT)
1639
1733
@@ -1645,7 +1739,7 @@ static void gpiote_evt_handle(NRF_GPIOTE_Type * p_gpiote,
1645
1739
{
1646
1740
uint32_t ch = NRF_CTZ (mask );
1647
1741
mask &= ~NRFX_BIT (ch );
1648
- nrfx_gpiote_pin_t pin = nrfy_gpiote_event_pin_get ( p_gpiote , ch ) ;
1742
+ nrfx_gpiote_pin_t pin = p_cb -> ch_pin [ ch ] ;
1649
1743
nrf_gpiote_polarity_t polarity = nrfy_gpiote_event_polarity_get (p_gpiote , ch );
1650
1744
1651
1745
call_handler (p_cb , pin , gpiote_polarity_to_trigger (polarity ));
@@ -1654,17 +1748,27 @@ static void gpiote_evt_handle(NRF_GPIOTE_Type * p_gpiote,
1654
1748
1655
1749
static void irq_handler (NRF_GPIOTE_Type * p_gpiote , gpiote_control_block_t * p_cb )
1656
1750
{
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 );
1657
1753
/* Collect status of all GPIOTE pin events. Processing is done once all are collected and cleared.*/
1658
- 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
1659
1764
uint32_t evt_mask = nrfy_gpiote_events_process (p_gpiote ,
1660
- enabled_in_events |
1661
- (uint32_t )NRF_GPIOTE_INT_PORT_MASK ,
1662
- p_cb -> channels_number );
1765
+ enabled_events ,
1766
+ p_config -> channels_number );
1663
1767
1664
1768
/* Handle PORT event. */
1665
1769
if (evt_mask & (uint32_t )NRF_GPIOTE_INT_PORT_MASK )
1666
1770
{
1667
- port_event_handle (p_gpiote , p_cb );
1771
+ port_event_handle (p_gpiote , p_cb , p_config );
1668
1772
evt_mask &= ~(uint32_t )NRF_GPIOTE_INT_PORT_MASK ;
1669
1773
}
1670
1774
0 commit comments