I am using Timer0 and Timer with GPIOTE and PPI to output 2 clocks on 2 pins.
Both timer settings are identical (for troubleshooting). Only timer-0 can be generated at the output pins (pin-1 and pin-2). While timer-1 does not produce any output.
(after spending 10+ hours of testing, and missing a deadline, and checking that both timers are enabled in the sdk_config.h)
any clue what can be the reason ?
/* Use Timer with PPI and GPIOTE Generates 4MHz timer on output pin Timer1 is not outputting */ #include <stdbool.h> #include <stdint.h> #include "nrf.h" #include "app_error.h" #include "nrfx_gpiote.h" #include "nrf_gpiote.h" #include "nrf_gpio.h" #include "nrf_drv_gpiote.h" #include "nrf_ppi.h" #include "nrf_drv_ppi.h" #include "nrf_drv_timer.h" #include "boards.h" #include "nrf_drv_gpiote.h" #define I2S_SCK NRF_GPIO_PIN_MAP(0,13) #define I2S_LRCLK NRF_GPIO_PIN_MAP(0,3) #define LED_Power NRF_GPIO_PIN_MAP(1,9) // Create variable to hold error values ret_code_t err_code; // Create timer instance const nrf_drv_timer_t Timer_0 = NRF_DRV_TIMER_INSTANCE(0); const nrf_drv_timer_t Timer_1 = NRF_DRV_TIMER_INSTANCE(1); // Create Timer ISR handler void Timer_0_handler(nrf_timer_event_t event_type, void* p_context) { } void Timer_1_handler(nrf_timer_event_t event_type, void* p_context) { } // A function to initialize and set everything for the timers with PPI and GPIOTE static void Initialize_Timer_PPI_GPIOTE(void) { //NRF_CLOCK->TASKS_HFCLKSTART = 1; // while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) // { // // Wait for clock to start // } // Configure timer as counter, 64 counts at 4MHz nrf_drv_timer_config_t Timer_0_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; Timer_0_cfg.frequency = NRF_TIMER_FREQ_8MHz; //Timer_0_cfg.mode = NRF_TIMER_MODE_COUNTER; //Timer_0_cfg.bit_width = TIMER_BITMODE_BITMODE_32Bit; // Set up timer NRF_TIMER0->PRESCALER = 1; NRF_TIMER0->CC[0] = 1; // Adjust the output frequency by adjusting the CC. //NRF_TIMER0->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; NRF_TIMER0->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled; //NRF_TIMER0->TASKS_START = 1; // Configure timer as counter, 2 counts at 62.5KHz nrf_drv_timer_config_t Timer_1_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; Timer_1_cfg.frequency = NRF_TIMER_FREQ_4MHz; //Timer_1_cfg.mode = NRF_TIMER_MODE_COUNTER; //Timer_1_cfg.bit_width = TIMER_BITMODE_BITMODE_32Bit; // Set up timer NRF_TIMER1->PRESCALER = 0; NRF_TIMER1->CC[1] = 1; // Adjust the output frequency by adjusting the CC. //NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE1_CLEAR_Enabled << TIMER_SHORTS_COMPARE1_CLEAR_Pos; NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE1_CLEAR_Enabled; //NRF_TIMER1->TASKS_START = 1; // Initialize timers err_code = nrf_drv_timer_init(&Timer_0, &Timer_0_cfg, Timer_0_handler); APP_ERROR_CHECK(err_code); err_code = nrf_drv_timer_init(&Timer_1, &Timer_1_cfg, Timer_1_handler); APP_ERROR_CHECK(err_code); // Create variables to hold event and task addresses. They will connect with PPI TEP (Task End Point) and PPI EEP (Event End Point) uint32_t compare_event_addr_1; uint32_t compare_event_addr_2; uint32_t gpiote_task_addr_1; uint32_t gpiote_task_addr_2; // Create structure to hold PPI channel values nrf_ppi_channel_t ppi_channel_1; nrf_ppi_channel_t ppi_channel_2; // Initialize GPTIOTE module if(!nrf_drv_gpiote_is_init()) { err_code = nrf_drv_gpiote_init(); APP_ERROR_CHECK(err_code); } // Initialize PPI module, make sure it is only enabled once in the code err_code = nrf_drv_ppi_init(); APP_ERROR_CHECK(err_code); // Allocate a channel from available PPI channels err_code = nrf_drv_ppi_channel_alloc(&ppi_channel_1); APP_ERROR_CHECK(err_code); err_code = nrf_drv_ppi_channel_alloc(&ppi_channel_2); APP_ERROR_CHECK(err_code); // Enable and configure the pin (high/low/toggle). True ? Initial high state, False ? Initial low state nrf_drv_gpiote_out_config_t out_config_1 = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false); err_code = nrf_drv_gpiote_out_init(I2S_SCK, &out_config_1); APP_ERROR_CHECK(err_code); nrf_drv_gpiote_out_config_t out_config_2 = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false); err_code = nrf_drv_gpiote_out_init(I2S_LRCLK, &out_config_2); APP_ERROR_CHECK(err_code); // Get address of respective event and tasks from the respective peripherals compare_event_addr_1 = nrf_drv_timer_event_address_get(&Timer_0, NRF_TIMER_EVENT_COMPARE0); gpiote_task_addr_1 = nrf_drv_gpiote_out_task_addr_get(I2S_SCK); compare_event_addr_2 = nrf_drv_timer_event_address_get(&Timer_1, NRF_TIMER_EVENT_COMPARE1); gpiote_task_addr_2 = nrf_drv_gpiote_out_task_addr_get(I2S_LRCLK); // Connect EEP & TEP with Peripheral Events and Tasks using their addresses and assign them to an allocated channel err_code = nrf_drv_ppi_channel_assign(ppi_channel_1, compare_event_addr_1, gpiote_task_addr_1); APP_ERROR_CHECK(err_code); err_code = nrf_drv_ppi_channel_assign(ppi_channel_2, compare_event_addr_2, gpiote_task_addr_2); APP_ERROR_CHECK(err_code); // Enable channel to start receiving events and route them to tasks err_code = nrf_drv_ppi_channel_enable(ppi_channel_1); APP_ERROR_CHECK(err_code); err_code = nrf_drv_ppi_channel_enable(ppi_channel_2); APP_ERROR_CHECK(err_code); // Enable pin task to be executed when called by any event via PPI nrf_drv_gpiote_out_task_enable(I2S_SCK); nrf_drv_gpiote_out_task_enable(I2S_LRCLK); } int main(void) { nrf_gpio_cfg_output(I2S_SCK); nrf_gpio_cfg_output(I2S_LRCLK); nrf_gpio_cfg_output(LED_Power); nrf_gpio_pin_clear(I2S_SCK); nrf_gpio_pin_clear(I2S_LRCLK); nrf_gpio_pin_set(LED_Power); Initialize_Timer_PPI_GPIOTE(); // Start timer nrf_drv_timer_enable(&Timer_0); nrf_drv_timer_enable(&Timer_1); while (1) { // __WFI(); } }