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

SPI master driver for nRF52832

Hello,

Question regarding using the SPI master peripheral with DMA to communicate from the nRF52832 to the ads1296 device .

In order to use this device in the mode and sampling rate I need, with the number of channels, I have to use an SPI clock frequency of 8 MHz which is supported by the nRF52832. Unfortunately, the ads1296 device (on pg 63 of datasheet, section 9.5.2.9) says that if an SPI clock frequency higher than 4 MHz is used, "a delay must be inserted so that the end of the second byte arrives 1.46us later". This basically means if I'm using 8 MHz, I have to add a delay between the OPCODE (first byte) and the second byte, and all bytes that follow do not require a delay.

So...I think I have two options :

  1. Use the SPI in 4 MHz mode when I am configuring the ads1296 device, then change to 8 MHz clock when I am ready to start receiving data.

  2. Modify the SPI driver to introduce a delay from the first byte to the second byte and stay using the 8 MHz clock.

Option 1 obviously seems easier but is there a way to do option 2 with minimal modifications to the SPI driver. Or does the driver provide some functionality that already allows this?

Thanks for reading - E

  • I don't think there are any specific functions in the driver for adding delays between transfers. You say you are using DMA, how do you setup the transfer(s)? Do you need both bytes to be transferred in one transfer, or could you split it into two transfers with a "software delay" between?

  • Hello Jorgen and thanks for responding to my question.

    1. Let me describe how I am setting up my spi transfers with more detail. I am using an SPI clk frequency of 8MHz. The DRDY signal from the ads1296 is active low and it occurs at the selected adc sampling rate 32ksps(31.25us). I have a GPIOTE "in event" that is setup to occur when hi-to-low transition occurs on this pin. This GPIOTE was initialized with an "in_pin_handler". Inside the pin handler, I change a variable named "m_drdy" to true. In main, I have the following:

      for (;;) { if(m_drdy) { m_drdy = false; get_eeg_voltage_samples(&eeg1, &eeg2, &eeg3, &eeg4); } }

      void get_eeg_voltage_samples (int32_t *eeg1, int32_t *eeg2, int32_t *eeg3, int32_t *eeg4) { uint8_t tx_rx_data[15] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; nrf_drv_spi_transfer(&spi, tx_rx_data, 15, tx_rx_data, 15); uint8_t cnt = 0; do { if(tx_rx_data[0]==0xC0){ *eeg1 = ( (tx_rx_data[3] << 16) | (tx_rx_data[4] << 8) | (tx_rx_data[5]) ); *eeg2 = ( (tx_rx_data[6] << 16) | (tx_rx_data[7] << 8) | (tx_rx_data[8]) ); *eeg3 = ( (tx_rx_data[9] << 16) | (tx_rx_data[10] << 8) | (tx_rx_data[11]) ); *eeg4 = ( (tx_rx_data[12] << 16) | (tx_rx_data[13] << 8) | (tx_rx_data[14]) ); break; } cnt++; nrf_delay_us(1); } while(cnt<255); }

    2. I actually do need both bytes to be transferred in one transfer since the write and read commands for ads1296 require 2 byte transfers: byte1 contains: (opcode|start_addr),and byte2 contains: number of bytes to be read or written minus one. So, as I pointed out in original question, pgs 63 section 9.5.2.9 of datasheet says if spi clock frequency > 4MHz is used, an additional 1.5us delay must be inserted between bytes to meet timing requirements. So, I dont think the software delay approach between bytes will work, please confirm my reasoning makes sense.

    3. How do you setup interrupts (to handle event) on spi after each byte on a multi-byte spi transaction as opposed to interrupting when all bytes are transferred?

  • You might be able to setup PPI, GPIOTE, and a TIMER to create the delay between the transfers. Unfortunately, this is not supported by the driver, and it would make more sense to setup this using the registers directly,

Related