Good evening,
From testing my Nano 33 BLE, I've discovered that the following settings are reversed with respect to "High" and "Low", i.e., LEDs light up for Low, and turn off for High
For testing purposes I'm running the following program compiled using Arduino's IDE and source files... PPI Toggle Test (I've also included it just below; virtually exactly the same as via the link).
For the following program it becomes apparent when GPIOTE_CONFIG_OUTINIT_Low is changed to GPIOTE_CONFIG_OUTINIT_High, but it's the same for NRF_GPIOTE->TASKS_CLR and NRF_GPIOTE->TASKS_SET for which CLR turns the LED on and SET turns it off.
I can work like this if I need to, but I'm hoping that I've just missed something silly. Therefore please can someone help?
This is my test program via the above link...
#include <nrf.h> #define PPI_CHANNEL (0) // #define PIN_GPIO (11) #define PIN_GPIO (16) // Green LED on Nano 33 BLE void setup() { // Configure PIN_GPIO as output // ---------------------------- NRF_GPIO->DIRSET = (1UL << PIN_GPIO); // Configure GPIOTE->TASKS_OUT[0] to toggle PIN_GPIO // ------------------------------------------------- NRF_GPIOTE->CONFIG[0] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | (GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos) | (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) | (PIN_GPIO << GPIOTE_CONFIG_PSEL_Pos); // Configure TIMER0 to generate EVENTS_COMPARE[0] every 2000000us // ----------------------------------------------------------- NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos; NRF_TIMER0->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; NRF_TIMER0->PRESCALER = 4; NRF_TIMER0->CC[0] = 2000000; NRF_TIMER0->TASKS_START = 1; // Configure PPI channel with connection between TIMER->EVENTS_COMPARE[0] and GPIOTE->TASKS_OUT[0] // ----------------------------------------------------------------------------------------------- NRF_PPI->CH[PPI_CHANNEL].EEP = (uint32_t)&NRF_TIMER0->EVENTS_COMPARE[0]; NRF_PPI->CH[PPI_CHANNEL].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0]; // Enable PPI channel // ------------------ NRF_PPI->CHENSET = (1UL << PPI_CHANNEL); } void loop() { while (1) { __WFE(); } }
Thank you, Gary.
EDIT... Here's my NRF_GPIOTE->TASKS_SET and NRF_GPIOTE->TASKS_CLR test program.
Each time the LED should turn on it starts timer 3, which then should turn the LED off after 0.5 seconds. But instead what actually happens is, each time the LED turns on, 1.5 seconds (because timer 0 has already been running for 0.5 seconds) later GPIOTE->TASKS_SET turns it off. But that means SET and CLR are each doing the opposite to what they're suppose to do...
When I change _SET to _CLR and _CLR to _SET it then works as expected.
Here's the program...
#include <nrf.h> #define PPI_CHANNEL_0 (0) #define PPI_CHANNEL_1 (1) // #define PIN_GPIO (11) #define PIN_GPIO (16) // Green LED on Nano 33 BLE /* Using Timer 1 crashes the board... so don't use it */ void setup() { // Configure PIN_GPIO as output // ---------------------------- NRF_GPIO->DIRSET = (1UL << PIN_GPIO); // Configure GPIOTE // ---------------- NRF_GPIOTE->CONFIG[0] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | (PIN_GPIO << GPIOTE_CONFIG_PSEL_Pos); // Configure TIMER0 & TIMER3 to generate EVENTS_COMPARE[0] every 2000000us and 500000us respectively // ------------------------------------------------------------------------------------------------- NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos; NRF_TIMER0->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; NRF_TIMER0->PRESCALER = 4; NRF_TIMER0->CC[0] = 2000000; NRF_TIMER0->TASKS_START = 1; NRF_TIMER3->BITMODE = TIMER_BITMODE_BITMODE_32Bit; NRF_TIMER3->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; NRF_TIMER3->PRESCALER = 4; NRF_TIMER3->CC[0] = 500000; // Configure PPI channels with connection between TIMER->EVENTS_COMPARE[0] and GPIOTE->TASKS_SET[0] and GPIOTE->TASKS_CLR[0] // ------------------------------------------------------------------------------------------------------------------------- NRF_PPI->CH[PPI_CHANNEL_0].EEP = (uint32_t) & NRF_TIMER0->EVENTS_COMPARE[0]; NRF_PPI->CH[PPI_CHANNEL_0].TEP = (uint32_t) & NRF_GPIOTE->TASKS_SET[0]; NRF_PPI->FORK[PPI_CHANNEL_0].TEP = (uint32_t) & NRF_TIMER3->TASKS_START; NRF_PPI->CH[PPI_CHANNEL_1].EEP = (uint32_t) & NRF_TIMER3->EVENTS_COMPARE[0]; NRF_PPI->CH[PPI_CHANNEL_1].TEP = (uint32_t) & NRF_GPIOTE->TASKS_CLR[0]; NRF_PPI->FORK[PPI_CHANNEL_1].TEP = (uint32_t) & NRF_TIMER3->TASKS_STOP; // Enable PPI channel // ------------------ NRF_PPI->CHENSET = (1UL << PPI_CHANNEL_0); NRF_PPI->CHENSET = (1UL << PPI_CHANNEL_1); } void loop() { while (1) { __WFE(); } }