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

SPI inter-byte duration

Hello, I've been working on porting a bit-banged control of a peripheral to use nRF51 SPI--which is just SPI rather than SPIM (therefore no DMA). Observe the SPICLK waveform when I choose 4 MHz: image description

The byte itself is emitted at 4 MHz. But the huge inter-byte distance remains constant down to about 1 MHz CLK speed. I guess that's just how it is with SPI (not SPIM). In the waveform above, one can see that the maximum effective SPI speed is roughly 14 us / 1 B => 570 KHz, which is only slightly faster than the maximum effective SPI speed when I bit-bang using GPIO on an STM32L1 (Cortex M3) ~ 400 KHz. It nearly negates the arguments for using the SPI peripheral over bit-bang (except for some battery savings by using WFE).

I doubt there is anything I can do to improve the situation, but thought I'd check with experts just in case. Thanks for reading.

Parents
  • Thank you for the reply Wojtek and Hung, you were right: I was taking much too long in my checking for the nrf_spi_event_check(p_spi, NRF_SPI_EVENT_READY). There is still some ~4 us until I see the EVENT_READY flag in the register, but the effective BW is now up to 1.23 MHz (when using the 4 MHz SPI speed). BTW, why can't I call sd_app_evt_wait() (which just calls WFE) while waiting for NRF_SPI_EVENT_READY? I find this to be true even while waiting for NRF_UART0->EVENTS_TXDRDY (in another context) as well. Shouldn't these events wake up the nRF that is sleeping on WFE?

  • @Henry Choi: I see, but from my understanding you should still enable the interrupt on READY event (with INTENSET register), if you want to wake CPU up when in WFE.

    Still from my understanding, what ARM described as "events from peripheral" actually are the events that are enabled as interrupts from the peripheral. Without enabling interrupt, the peripheral has no way to tell the CPU about its events.

    Also you need to enable SEVONPEND with SCB->SCR |= SCB_SCR_SEVONPEND_Msk; to wake the chip up from pended event.

    So, NVIC_EnableIRQ() is not needed if you don't want to handle the interrupt, but INTENSET should be set, and also you should clear the interrupt pending flag NVIC_ClearPendingIRQ(XXX_IRQn); after it wake the chip up.

Reply
  • @Henry Choi: I see, but from my understanding you should still enable the interrupt on READY event (with INTENSET register), if you want to wake CPU up when in WFE.

    Still from my understanding, what ARM described as "events from peripheral" actually are the events that are enabled as interrupts from the peripheral. Without enabling interrupt, the peripheral has no way to tell the CPU about its events.

    Also you need to enable SEVONPEND with SCB->SCR |= SCB_SCR_SEVONPEND_Msk; to wake the chip up from pended event.

    So, NVIC_EnableIRQ() is not needed if you don't want to handle the interrupt, but INTENSET should be set, and also you should clear the interrupt pending flag NVIC_ClearPendingIRQ(XXX_IRQn); after it wake the chip up.

Children
No Data
Related