Created
July 15, 2024 21:45
-
-
Save hieuv/06fb6b9609c59e3a57bb62340ccaf242 to your computer and use it in GitHub Desktop.
nRF52x - Two ways to connect RADIO events to GPIOTE with PPI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Pro: The nrfx drivers keep track of which PPI and GPIOTE channels are in used. | |
static void alloc_assign_enable_nrfx_ppi(nrf_ppi_channel_t* p_channel, | |
uint32_t event_end_point, | |
uint32_t task_end_point) | |
{ | |
#if (!NRFX_PPI_ENABLED) | |
#error "Require enabling NRFX_PPI_ENABLED in sdk_config.h. In nRF5 SDK, also check PPI_ENABLED (refer to apply_old_config.h)" | |
#endif | |
nrfx_err_t err; | |
if (!nrfx_gpiote_is_init()) | |
{ | |
APP_ERROR_CHECK(NRFX_ERROR_INVALID_STATE); | |
} | |
err = nrfx_ppi_channel_alloc(p_channel); | |
APP_ERROR_CHECK(err); | |
err = nrfx_ppi_channel_assign(*p_channel, | |
event_end_point, | |
task_end_point | |
); | |
APP_ERROR_CHECK(err); | |
err = nrfx_ppi_channel_enable(*p_channel); | |
APP_ERROR_CHECK(err); | |
} | |
static void config_then_enable_gpiote_via_nrfx(uint8_t port, uint8_t pin) | |
{ | |
#if (!NRFX_GPIOTE_ENABLED) | |
#error "Require enabling NRFX_GPIOTE_ENABLED in sdk_config.h. In nRF5 SDK, also check GPIOTE_ENABLED (refer to apply_old_config.h)" | |
#endif | |
nrfx_err_t err; | |
nrfx_gpiote_out_config_t nrfx_gpiote_out_config_led_common = { | |
.action = NRF_GPIOTE_POLARITY_TOGGLE, | |
.init_state = NRF_GPIOTE_INITIAL_VALUE_LOW, | |
.task_pin = true | |
}; | |
err = nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(port, pin), &nrfx_gpiote_out_config_led_common); | |
APP_ERROR_CHECK(err); | |
nrfx_gpiote_out_task_enable(NRF_GPIO_PIN_MAP(port, pin)); | |
} | |
static void radio_ppi_gpiote_setup_nrfx(void) | |
{ | |
nrfx_err_t err; | |
err = nrfx_gpiote_init(); | |
APP_ERROR_CHECK(err); | |
config_then_enable_gpiote_via_nrfx(LED_PORT, LED1_PIN); | |
config_then_enable_gpiote_via_nrfx(LED_PORT, LED2_PIN); | |
nrf_ppi_channel_t nrf_ppi_channel_set_led1; | |
nrf_ppi_channel_t nrf_ppi_channel_clr_led1; | |
nrf_ppi_channel_t nrf_ppi_channel_set_led2; | |
nrf_ppi_channel_t nrf_ppi_channel_clr_led2; | |
alloc_assign_enable_nrfx_ppi( | |
&nrf_ppi_channel_clr_led1, | |
nrf_radio_event_address_get(NRF_RADIO_EVENT_TXREADY), | |
nrfx_gpiote_clr_task_addr_get(NRF_GPIO_PIN_MAP(LED_PORT, LED1_PIN)) | |
); | |
alloc_assign_enable_nrfx_ppi( | |
&nrf_ppi_channel_set_led1, | |
nrf_radio_event_address_get(NRF_RADIO_EVENT_END), | |
nrfx_gpiote_set_task_addr_get(NRF_GPIO_PIN_MAP(LED_PORT, LED1_PIN)) | |
); | |
alloc_assign_enable_nrfx_ppi( | |
&nrf_ppi_channel_clr_led2, | |
nrf_radio_event_address_get(NRF_RADIO_EVENT_RXREADY), | |
nrfx_gpiote_clr_task_addr_get(NRF_GPIO_PIN_MAP(LED_PORT, LED2_PIN)) | |
); | |
alloc_assign_enable_nrfx_ppi( | |
&nrf_ppi_channel_set_led2, | |
nrf_radio_event_address_get(NRF_RADIO_EVENT_END), | |
nrfx_gpiote_set_task_addr_get(NRF_GPIO_PIN_MAP(LED_PORT, LED2_PIN)) | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Con: need to keep track of which PPI and GPIOTE channels are in used. | |
static void radio_ppi_gpiote_setup_direct_register_macro(void) | |
{ | |
#define LED_PORT 0 | |
#define LED1_PIN 13 | |
#define LED2_PIN 14 | |
#define GPIOTE_CHANNEL_FOR_LED1 0 /* 0..7, can't reuse */ | |
#define GPIOTE_CHANNEL_FOR_LED2 1 /* 0..7, can't reuse */ | |
#define PPI_CHANNEL_FOR_LED1_SET 0 /* 0..19 for nRF52840, can't reuse */ | |
#define PPI_CHANNEL_FOR_LED2_SET 1 /* 0..19 for nRF52840, can't reuse */ | |
#define PPI_CHANNEL_FOR_LED1_CLR 2 /* 0..19 for nRF52840, can't reuse */ | |
#define PPI_CHANNEL_FOR_LED2_CLR 3 /* 0..19 for nRF52840, can't reuse */ | |
NRF_GPIOTE->CONFIG[GPIOTE_CHANNEL_FOR_LED1] = (uint32_t) | |
( GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos ) | | |
( LED_PORT << GPIOTE_CONFIG_PORT_Pos ) | | |
( LED1_PIN << GPIOTE_CONFIG_PSEL_Pos ) | | |
//( GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos ) | | |
( GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos ); | |
NRF_GPIOTE->CONFIG[GPIOTE_CHANNEL_FOR_LED2] = (uint32_t) | |
( GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos ) | | |
( LED_PORT << GPIOTE_CONFIG_PORT_Pos ) | | |
( LED2_PIN << GPIOTE_CONFIG_PSEL_Pos ) | | |
//( GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos ) | | |
( GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos ); | |
NRF_PPI->CH[PPI_CHANNEL_FOR_LED1_CLR].EEP = | |
(uint32_t) (&NRF_RADIO->EVENTS_TXREADY); | |
NRF_PPI->CH[PPI_CHANNEL_FOR_LED1_CLR].TEP = | |
(uint32_t) (&NRF_GPIOTE->TASKS_CLR[GPIOTE_CHANNEL_FOR_LED1]); | |
NRF_PPI->CH[PPI_CHANNEL_FOR_LED1_SET].EEP = | |
(uint32_t) (&NRF_RADIO->EVENTS_END); | |
NRF_PPI->CH[PPI_CHANNEL_FOR_LED1_SET].TEP = | |
(uint32_t) (&NRF_GPIOTE->TASKS_SET[GPIOTE_CHANNEL_FOR_LED1]); | |
NRF_PPI->CH[PPI_CHANNEL_FOR_LED2_CLR].EEP = | |
(uint32_t) (&NRF_RADIO->EVENTS_RXREADY); | |
NRF_PPI->CH[PPI_CHANNEL_FOR_LED2_CLR].TEP = | |
(uint32_t) (&NRF_GPIOTE->TASKS_CLR[GPIOTE_CHANNEL_FOR_LED2]); | |
NRF_PPI->CH[PPI_CHANNEL_FOR_LED2_SET].EEP = | |
(uint32_t) (&NRF_RADIO->EVENTS_END); | |
NRF_PPI->CH[PPI_CHANNEL_FOR_LED2_SET].TEP = | |
(uint32_t) (&NRF_GPIOTE->TASKS_SET[GPIOTE_CHANNEL_FOR_LED2]); | |
NRF_PPI->CHENSET = (0x1 << PPI_CHANNEL_FOR_LED1_CLR) | | |
(0x1 << PPI_CHANNEL_FOR_LED1_SET) | | |
(0x1 << PPI_CHANNEL_FOR_LED2_CLR) | | |
(0x1 << PPI_CHANNEL_FOR_LED2_SET); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment