This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SPIM STOP task isn't getting triggered by PPI

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>)

Parents
  • In line 35 you are connecting to event COMPARE0, however in the code you provide nothing us setting CC[0] to 6; by default it will be 0, i.e. effectively 65536.  And in line 24 you setting CC[5] to 0xffff but it (COMPARE5) seems unused?

    (BTW a lot of sympathy for your rant.  And I think timer SHORTS can be accessed through the SDK function "...extended_compare...", which is not an immediately intuitive naming choice!)

Reply
  • In line 35 you are connecting to event COMPARE0, however in the code you provide nothing us setting CC[0] to 6; by default it will be 0, i.e. effectively 65536.  And in line 24 you setting CC[5] to 0xffff but it (COMPARE5) seems unused?

    (BTW a lot of sympathy for your rant.  And I think timer SHORTS can be accessed through the SDK function "...extended_compare...", which is not an immediately intuitive naming choice!)

Children
Related