Hey all, I'm new here. So far things have been going pretty well, I am just having an issue with PPI that I can't quite figure out, but I think I'm close. I currently have an nRF52840 DK hooked up to a 6 axis sensor with a FIFO buffer. I get the number of records in FIFO from the device, then try to use PPI to send a STOP to SPIM once I have read that many records. To accomplish this I have Timer1 in compare mode and tied the SPIM END event to the Timer1 COUNT task with PPI, then I have the Timer1 COMPARE event hooked to the SPIM STOP task.
The problem is that I see the SPIM STOPPED register set to 1 in the debugger, but the SPIM is still reading on my scope.
Here are some snippets:
const nrfx_timer_t m_timer1 = NRFX_TIMER_INSTANCE(1); const nrfx_spim_t m_spim3 = NRFX_SPIM_INSTANCE(3); ... nrfx_spim_config_t spim_cfg = NRFX_SPIM_DEFAULT_CONFIG; spim_cfg.frequency = NRF_SPIM_FREQ_8M; spim_cfg.ss_pin = SPIM_CS; spim_cfg.sck_pin = SPIM_SCK; spim_cfg.mosi_pin = SPIM_MOSI; spim_cfg.miso_pin = SPIM_MISO; spim_cfg.orc = SPIM_ORC; spim_cfg.mode = NRF_SPIM_MODE_0; spim_cfg.use_hw_ss = true; APP_ERROR_CHECK(nrfx_spim_init(&m_spim3, &spim_cfg, spim_event_handler, NULL)); ... nrfx_timer_config_t timer_config = NRFX_TIMER_DEFAULT_CONFIG; timer_config.mode = (nrf_timer_mode_t)NRF_TIMER_MODE_COUNTER; err_code = nrfx_timer_init(p_timer1, &timer_config, timer_handler); APP_ERROR_CHECK(err_code); nrfx_timer_compare(p_timer1, NRF_TIMER_CC_CHANNEL5, 0xFFFF, true); nrfx_timer_enable(p_timer1); /* PPI Configuration - NOTE that we DO NOT enable PPI here, but in the SPIM FIFO read * Configure PPI channel 0 to increment TIMER1 counter on SPIM END event. */ NRF_PPI->CH[0].EEP = (uint32_t)((uint32_t)NRF_SPIM3_BASE + (uint32_t)NRF_SPIM_EVENT_END); // EVENTS_END NRF_PPI->CH[0].TEP = (uint32_t)((uint32_t)NRF_TIMER1_BASE + (uint32_t)NRF_TIMER_TASK_COUNT); // TASKS_COUNT /* Configure PPI channel 2 to initiate a SPIM STOP task on TIMER1 COMPARE event. */ NRF_PPI->CH[2].EEP = (uint32_t)((uint32_t)NRF_TIMER1_BASE + (uint32_t)NRF_TIMER_EVENT_COMPARE0); // EVENTS_COMPARE NRF_PPI->CH[2].TEP = (uint32_t)((uint32_t)NRF_SPIM3_BASE + (uint32_t)NRF_SPIM_TASK_STOP); // TASKS_STOP ... /* Get buffer cardinality from FIFO_STATUS1 and 2 */ nrfx_timer_compare(&p_timer1, NRF_TIMER_CC_CHANNEL5, (((rx_buff[2] & 0x0F) << 8 ) | rx_buff[1]), true); /* Reset TIMER1 counter. */ nrfx_timer_clear(&p_timer1); /* Set up buffers */ p_instance.p_reg->TXD.PTR = (uint32_t)tx_buff; p_instance.p_reg->TXD.MAXCNT = 1; p_instance.p_reg->RXD.PTR = (uint32_t)fifo_buff; p_instance.p_reg->RXD.MAXCNT = 3; p_instance.p_reg->RXD.LIST = (SPIM_RXD_LIST_LIST_ArrayList << SPIM_RXD_LIST_LIST_Pos); // Array List mode p_instance.p_reg->SHORTS = (SPIM_SHORTS_END_START_Enabled << SPIM_SHORTS_END_START_Pos); //Short END to START /* ENABLE PPI connections * SPIM END event is connected to START task by SHORTS. * SPIM END event is connected to TIMER1 COUNT task in PPI0, * then TIMER1 COMPARE event is connected to SPIM STOP task for = fifo size in PPI2 */ NRF_PPI->CHENSET = (PPI_CHENSET_CH0_Enabled << PPI_CHENSET_CH0_Pos); NRF_PPI->CHENSET = (PPI_CHENSET_CH2_Enabled << PPI_CHENSET_CH2_Pos); p_instance.p_reg->INTENCLR = 0xFFFFFFFFUL; /* Kick off SPIM START Task */ p_instance.p_reg->TASKS_START = 1;
And yes, I am aware that I am mixing nrfx driver and registers, but there are no nrfx functions that I see for SHORTS or LIST mode (and I don't see them in the xfer_desc structure) so I am guessing that you are intended to use the buffers. And besides, without PPI it works great as it is. As for PPI, I only use the registers so I am guessing that is fine. (<rant>Also, why are there so many different options for drivers? I see so many questions where the answer is "You should use XXX driver instead" that it is almost as if they were invented to prevent the need of answering questions.</rant>)