This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Using DMA with SPI functionality for CC2640

Other Parts Discussed in Thread: CC2640, ADS1292R

Hi,

We want to use the spi with dma functionality for our project.  Is there any example in stack using dma with SPI feature? The SPICC26XXDMA.c & SPICC26XXDMA.h do not provide much information about initializing the dma with SPI. Could anyone please provide more details how to use dma with SPI.?

  • You should just use the SPI API from SPI.h which again will use our driver SPICC26XXDMA. We do only have a DMA version of the SPI driver available.
    This is fairly well documented in the TI RTOS documentation, typically found at C:/ti/tirtos_simplelink_2_11_01_09/docs/doxygen/html/index.html

    Regards,
    Svend
  • Hi, 

    Thank you for your reply. We have interface 24 bit ADC device to CC2640 with interrupt from ADC. We want to configure the dma based on ADC interrupt. We have configured the GPIO interrupt & called the SPI_tranfer() & it reads the ADC samples from ADC upon interrupt continuously. But we would like to How to assign the GPIO interrupt to dma so that the dma transfer should begin automatically?

    Thanks  & regards,

    Ankit Channa

  • Ankit,

    Do I understand you correctly if you want to make the IO interrupt start a SPI transaction automatically when the IO gets set high?
    That would not be possible as the SPI driver needs to configure the SPI module and keep track of the data buffers.

    What could be possible is to modify the SPICC26XXDMA_transfer function to not enable the SPI (SSIEnable). Then the DMA would write the SSI Enable bit and start the transaction. I don't see how you gain anything doing this though compared to just starting the transfer directly with the M3.

    Regards,
    Svend
  • Hi svendbt,
    What if i configure the one of MCU GPIO as interrupt & upon interrupt from adc i call the SPI_transfer function for reading the ADC samples. The ADC device that we have used gives interrupt for every 4 ms. Due to this the MCU wakes up for every 4 ms & consuming a lot of power. Would u please tell us that starting spi transaction upon interrupt causes M3 to consume lots of power?

    Regards,
    Ankit Channa
  • Ankit,

    The M3 will wake up and draw a total system current of a little above 3mA while starting the transfer. Once the SPI transfer starts using DMA you will have around 1mA until the transfer is done and you go back to standby with ~1uA.

    If you want to reduce this you can potentially use the Sensor Controller instead to do the SPI transfer which will reduce current to ~7-800uA while reading the data from the ADC and 1uA otherwise.
    You can also then buffer up ADC samples in the Sensor Controller RAM and wake up the M3 once your buffer is near full.

    Currently we do not have SW support for waking up on a IO (we will have in next release of Sensor Controller Studio) but if the sample rate is fixed than you can simply wake up every 4ms to read out the ADC value.

    Regards,
    Svend
  • Hi Svendbt, 

    Thank you so much for your support.  We are using  ADS1292R device interfaced to CC2640 externally which gives interrupt every 4 ms. We have configured  a gpio interrupt to read samples from the ADS1292R device using SPI_transfer(). The CC2640 device consumes around 6 mA for every read that we perform on the ADS1292R device. The battery would drain fast. Can you please tell me way to reduce the power consumption? Please suggest solution. Also tell me which API's are provided  to use the sensor controller?

    Thank you!

    Regards,

    Ankit Channa

  • The CC2640 typically does not use 6mA while active unless the radio is transmitting/receiving at the same time and you are using the DC/DC.
    Are you powering external devices through IO's?

    To reduce current you can try using the Sensor Controller which is can be downloaded here:
    www.ti.com/tool/sensor-controller-studio

    Regards,
    Svend

  • Hi,
    The SPI & interrupt configuration that we followed for reading samples from ADS1292R is given below:
    Interrupt configuration that we followed procedure in thermometer application provided in BLE stack.
    Board_initKeys(Thermometer_keyPressHandler); //Modified this for our application as below

    Board_InitInt( interruptHandler); // Called in the init function once

    void Board_InitInt(InterruptCB_t appEcgCB)
    {
    // Initialize KEY pins. Enable int after callback registered
    hPins = PIN_open(&Pins, PinsCfg);
    PIN_registerIntCb(hPins, Board_Callback); // Here the pin interrupt callback is registered &
    //This callback function will be called after a key press event

    PIN_setConfig(hPins, PIN_BM_IRQ, Board_ADS1292R_DRDY | PIN_IRQ_NEGEDGE);
    PIN_setConfig(hPins, PINCC26XX_BM_WAKEUP, Board_ADS1292R_DRDY | PINCC26XX_WAKEUP_NEGEDGE);

    // Setup keycallback for keys
    Util_constructClock(&ChangeClock, Board_ChangeHandler,
    DEBOUNCE_TIMEOUT, 0, false, 0);

    // Set the application callback
    appChangeHandler = appCB;
    }
    The DEBOUNCE_TIMEOUT is 0.

    The SPI clock is 1 MHz.
    We have configured one gpio as interrupt from ADS1292R & upon interrupt we tried to read the samples using SPI transfer function.
    But upon interrupt the application, the callback provided starts clock & gives a callback to application & puts it in the application queue.
    After application wakes up then it calls the SPI_transfer function to read from ADS1292R & this whole process takes around 2 ms consuming more current.

    The actual time required to wake up application & start SPI dma transfer is around 1.2 ms. This method works though it takes much time to wake up application. Is there any other way to service the interrupt in microseconds?
    And If we also read the GPIO using GPIO_pinRead function continuously for the interrupt in a while loop it takes less than 20 micro seconds to read samples from ADS1292R to service the interrupt.

    The other possible way that we tried is :
    IOCIOIntSet(IOID_11, IOC_INT_ENABLE, IOC_RISING_EDGE);
    IOCIntEnable(IOID_11);
    IntEnable(INT_EDGE_DETECT);
    IntMasterEnable();
    IOCIntRegister(&samplesCB);

    And in the samplesCB callback function we tried to read the samples using SPI_transfer function but this method fails read.
    How to configure the GPIO as interrupt exactly for faster interrupt service routine?
    Is it needed that application to wake up for SPI dma tranfer ? If then how to minimize the interrupt timing ?
    Please suggest possible ways to reduce the timing for the interrupt for faster interrupt service routine.

    Thanks & Regards,
    Ankit Channa