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

Drive SS(CS) in SPI manually with easyDMA

Hello I am using nRF52832, sdk v14.1, pca10040.

With regard to SPI, I am using the spi master in nrf_drv_spi.c to handle multi-byte spi transactions. I am able to do this successfully and the driver sets the SS pin low during the transaction and then back high after it has completed.

After I complete these multi-byte transactions, I want to enable easyDMA so that spi read transactions subsequently occur without CPU involvement. The start of the transaction will be initiated by a hi-to-low transition on a GPIO pin called /DRDY. I have setup GPIOTE in "in_event" mode and PPI to automatically start the spi transaction by calling nrf_drv_spi_xfer() with NRF_DRV_SPI_FLAG_HOLD_XFER and NRF_DRV_SPI_FLAG_REPEATED_XFER flags to setup the spi transfer but hold the actual transfer until triggered by PPI and since its a continuous stream of data also use the other flag.

I have setup the easyDMA as follows:

//easy DMA stuff
#define BUFFER_SIZE 3

typedef struct ArrayList
{
    uint8_t buffer[BUFFER_SIZE];
} ArrayList_type;

ArrayList_type afeStreamArrayList[4];
ArrayList_type bufTx[4];

NRF_SPIM0->RXD.MAXCNT = sizeof(afeStreamArrayList);
NRF_SPIM0->RXD.PTR = (int32_t) &afeStreamArrayList;
NRF_SPIM0->RXD.LIST = SPIM_RXD_LIST_LIST_ArrayList;

NRF_SPIM0->TXD.MAXCNT = sizeof(bufTx);
NRF_SPIM0->TXD.PTR = (int32_t) bufTx;
NRF_SPIM0->TXD.LIST = SPIM_RXD_LIST_LIST_Disabled;

nrf_drv_spi_xfer_desc_t xfer_desc;
//xfer_desc.p_tx_buffer = &bufTx;
//xfer_desc.p_rx_buffer = &afeStreamArrayList;
xfer_desc.tx_length   = sizeof(bufTx);
xfer_desc.rx_length   = sizeof(afeStreamArrayList);

nrf_drv_spi_xfer(&spi, &xfer_desc,
             NRF_DRV_SPI_FLAG_HOLD_XFER
            |NRF_DRV_SPI_FLAG_REPEATED_XFER
            );

question1: Is easyDMA setup the correct way? I have a total of 12 bytes(96 bits) I need to clock out during the spi transaction so I would like to organize into 3-32byte buffers (pointers) I can later access.

question 2: I am reading these 96 bits from a device external to the nRF52832. I would like to read these 96 bits and write directly to RAM via easyDMA to the array called "afeStreamArrayList". Then from some other point in the code (like main()), I would read from that array and perform some calculations on the data, so I have my buffers setup correctly?

question 3: argument 2 in nrf_drv_spi_xfer() is the transfer descriptor, which is commented out as you can see, all I did was declare the variable, do I need to configure the transfer descriptor any further or does my easyDMA setup take care of that?

question 4: With the code above, I am able to see the 96 clocks being issued by the SPI driver when the hi-to-low transition occurs on /DRDY consistently but no data is being clocked out because SS is not being driven when in easyDMA mode, it is permanently high. So..I want to manually drive SS but when I try to issue a command like:

//permanently hold CS low
nrf_gpio_cfg_output(ADS129x_SPI_CS_PIN);
nrf_gpio_pin_clear(ADS129x_SPI_CS_PIN);

nothing happens with the pin, it stays high. It seems it is locked by SPI driver and I cannot drive SS manually. How do I modify the spi configuration so that I am able to drive this pin directly? Do I use a fork to the original spi start event that also drives SS low and another fork to the original end event that takes it back high?

thank you for reading

Related