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

SPI high-speed reading

Hello,

We use NRF52 and the SPI protocol to read the ADS7866. But we are facing a problem when reading at high speed, we want to make one read transaction of 2 Bytes every 5µs ( to achieve a 200KHz ADC )

Before explaining which method was used, there is the SPI configuration that we use:

#define NRF_DRV_SPI_CUSTOM_CONFIG                            \
{                                                            \
    .sck_pin      = SPI_SCK_PIN,                             \
    .mosi_pin     = SPI_MOSI_PIN,                            \
    .miso_pin     = SPI_MISO_PIN,                            \
    .ss_pin       = SPI_ADC7866_PIN,                         \
    .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY,         \
    .orc          = 0xFF,                                    \
    .frequency    = NRF_DRV_SPI_FREQ_4M,                     \
    .mode         = NRF_DRV_SPI_MODE_0,                      \
    .bit_order    = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST,         \
}

We have tried 3 different ways:

1: Make on bulk read of 100 Bytes using the SPI driver  (`nrf_drv_spi_transfer()`). But it's does not work because, as you can see on the ADS7866 documentation, the CS signal should have a falling edge every 5µs to trigger the ADC acquisition.

2: Try to read 2 bytes per 2 bytes using the same driver  but the best performance we can get is 7.3µs between each transaction ; this is too slow as we need 5µs.

3: Try to use an external clock as a CS to force the CS to fall edge every 5µs. But we failed to synchronize the SPI driver and this external clock.

What do you think about our problem ?  In your opinion, what is the best way to do the job ?

Parents
  • You might try a creative solution by spoofing the /CS signal instead of using the real CS which is (usually) provided by the .ss_pin. I'd be inclined to keep the .ss_pin as you have it, but don't actually connect it to anything, just use it as a 'scope trigger while you tune the spoofed /CS. So where does the /CS connection to the ADS7866 come from? The answer is to use the .mosi_pin. The shape of this waveform is now controlled by using (say) a 3-byte Tx buffer which could have the values {0x00, 0x00, 0xFF} for the 16-bit active-low /CS. Use a 2-byte buffer {0x00, 0x0F} for the 12-bit version (assuming MSB first) which only requires 2 bytes. Set .orc to 0xFF. This may work as the .sck_pin can run indefinitely provided /CS remains high (the .mosi pin in your case) and only on the next falling edge will the new conversion start.

    I haven't tried this, so it may require a little experimentation, let us know if it works :-)

Reply
  • You might try a creative solution by spoofing the /CS signal instead of using the real CS which is (usually) provided by the .ss_pin. I'd be inclined to keep the .ss_pin as you have it, but don't actually connect it to anything, just use it as a 'scope trigger while you tune the spoofed /CS. So where does the /CS connection to the ADS7866 come from? The answer is to use the .mosi_pin. The shape of this waveform is now controlled by using (say) a 3-byte Tx buffer which could have the values {0x00, 0x00, 0xFF} for the 16-bit active-low /CS. Use a 2-byte buffer {0x00, 0x0F} for the 12-bit version (assuming MSB first) which only requires 2 bytes. Set .orc to 0xFF. This may work as the .sck_pin can run indefinitely provided /CS remains high (the .mosi pin in your case) and only on the next falling edge will the new conversion start.

    I haven't tried this, so it may require a little experimentation, let us know if it works :-)

Children
No Data
Related