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.

CC1312R: SPI transfer using DMA asserts

Part Number: CC1312R
Other Parts Discussed in Thread: SYSBIOS

Hello,

using SimpleLink SDK 4.20, my code is based on the TI 15.4 sensor project.

I spin a new TIRTOS tasks which, among other things, initiates SPI transfers on a regular basis. Everything seems to be working well, except if I enable DMA for the SPI transfers (DMA is needed for more predictable timing).

With DMA enabled, the app asserts here at line 798 (the semaphore_pend function actually returns SemaphoreP_OK), but stepping over that line doesn't work, and if I pause the debugger, I am in the main app exception handler from main.

 :

Any pointers in troubleshooting this are appreciated!

  • After enabling more debugging in my cfg, I see that the assert is at line 203 of Semaphore.c in sysbios/knl:

    What should I be doing differently to make this work?

  • Can you please provide information regarding what driver function calls you use and where you put them, both for the case that works and the one that does not work.

    The best thing would be if you could generate a small demo project that triggers the same error so that we can try to reproduce any issues here.

    BR

    Siri

  • Hi Siri,

    well, in both instances, I'm doing a SPI_transfer(). One just doesn't work if DMA is used, the other works OK. It's a small class used in the context of a tirtos task. Relevant bits, maybe something will seem obviously wrong to you. I am working on creating as simple a use case as I can to reproduce the issue.

    private:
        SPI_Transaction transaction;
        SPI_Params      spiParams;
        uint8_t         spiIndex;

    RGBLED::RGBLED(uint8_t index, uint16_t count) {
        ledCount = count;
        spiIndex = index;
    
        SPI_init();
    
        SPI_Params_init(&spiParams);
        spiParams.bitRate     = 2400000;
        spiParams.dataSize    = 8;
        spiParams.frameFormat = SPI_POL0_PHA1;
        transaction.rxBuf = NULL;
        outputBuffer = new uint8_t[ledCount*9 + 480]();
        transaction.txBuf = (void *) outputBuffer;
        transaction.count = ledCount*9 + 480;
    }
    

    void RGBLED::output() {
        SPI_Handle spi = SPI_open(spiIndex, &spiParams);
        SPI_transfer(spi, &transaction);
        SPI_close(spi);
    }
    

  • Not sure I understand.

    I think minDmaTransferSize = 10 by default, meaning that you are always using the DMA, since you transaction.count always is greater than 10.

    It that correct, or are you testing with different transactions.counts and different minDmaTransferSize?

    Also, how big is count?

    The UDMA controller only supports data transfers of up to 1024 data frames. A transfer with more than 1024 frames will be transmitted/received in multiple 1024 sized portions until all data has been transmitted/received

    Are you getting problems with all transaction.count > minDmaTransferSize

    Siri

  • Hi Siri, yes, I was using minDmaTransferSize to enable/disable DMA transfers. The count is around 620 bytes. And yes, the problem occurs when count > minDmaTransferSize. 

    I have reworked some logic in the app. In the end, I _think_ the transfers occured outside the context of the task (due to using C++ and C wrapper functions for callbacks), causing problems.

    While I am not entirely sure that is the case, I guess this can be considered resolved.

    Thanks.