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.

CC3220SF: I use cc3220sf chip. After modifying the SPI program, the program stops running and returns to the ti.driver.config File DMA error handling function, abnormal interrupt, what is the reason

Part Number: CC3220SF

It is worth noting that: 1. When a program is interrupted abnormally, the next time to re run the program is normal operation and will not be interrupted. 2. If I reset the device hardware before running the program every time, there will be no abnormal interruption.

Program abnormal interrupt, interrupt to the following function position

* =============================== DMA ===============================
*/

#include <ti/drivers/dma/UDMACC32XX.h>
#include <ti/devices/cc32xx/inc/hw_ints.h>
#include <ti/devices/cc32xx/inc/hw_types.h>
#include <ti/devices/cc32xx/driverlib/rom_map.h>
#include <ti/devices/cc32xx/driverlib/udma.h>

/* Ensure DMA control table is aligned as required by the uDMA Hardware */
static tDMAControlTable dmaControlTable[64] __attribute__ ((aligned (1024)));

/* This is the handler for the uDMA error interrupt. */
static void dmaErrorFxn(uintptr_t arg)
{
int status = MAP_uDMAErrorStatusGet();
MAP_uDMAErrorStatusClear();

/* Suppress unused variable warning */
(void)status;

while (1);
}

  • Hello,

    What did you modify in the SPI demo?

    Also keep in mind that if you are loading the application over the JTAG debugger, it is not retained on reset. You would need to flash the application to the serial flash. See the Device Overview in the CC3220 Out of Box Experience for more explanation: link

    Best regards,

    Sarah

  • I modified the data part of the transmission to communicate with the ADC chip, write the control instructions to the ADC, and receive the data.

    I don't think serial download has any effect, because I'm still in the debugging stage, loading the program through debug every time.

    What role does DMA play in SPI transmission mileage? What are the common mistakes? I hope you can give me some suggestions, because I don't know much about the use of DMA.

    This is how I write data and write data functions, and call them in threads.

    unsigned char AD7124_SPI_Read(unsigned char slaveDeviceId,
    unsigned char* data,
    unsigned char bytesNumber,
    SPI_Handle masterSpi)
    {

    uint8_t i=0;
    // SPI_Handle masterSpi;
    SPI_Transaction transaction;
    transaction.count = SPI_MSG_LENGTH;
    masterTxBuffer[0] =data[0];
    transaction.txBuf = (void *) masterTxBuffer;
    SPI_transfer(masterSpi, &transaction);
    memset((void *) masterRxBuffer, 0, SPI_MSG_LENGTH);
    for(i=1; i<bytesNumber; i++)
    {
    data[i] = masterRxBuffer[i];
    }

    transaction.rxBuf = (void *) masterRxBuffer;
    SPI_transfer(masterSpi, &transaction);

    return 0;
    }

    unsigned char AD7124_SPI_Write(unsigned char slaveDeviceId,
    unsigned char* data,
    unsigned char bytesNumber,
    SPI_Handle masterSpi)

    {
    uint8_t i=0;
    // SPI_Handle masterSpi;
    SPI_Transaction transaction;
    // bool transferOK;

    for(i=0; i<bytesNumber; i++)
    {

    masterTxBuffer[i] =data[i];

    }
    transaction.count = bytesNumber;
    transaction.txBuf = (void *) masterTxBuffer;
    SPI_transfer(masterSpi, &transaction);

    return 0;
    }

  • Hello,

    The SPI driver uses DMA to transfer data to/from data buffers. This is built into the driver. You can find the documentation in the SDK at docs/drivers/tidriversAPIs.html.

    DMA errors are typically because you are passing an incorrect pointer to the SPI driver (so the memory location is not accessible), or you are editing a data buffer while it is still being used by the DMA. I can't tell from your code snippet, but verify how your TX and RX buffers are defined. If these are global, be sure you are not calling your read and write functions at the same time.

    Best regards,

    Sarah

  • What is the case of calling read and write functions at the same time? I did call my read and write functions in the same function in order. It should be OK.

    Also, please help me see, in the routines given by TI, it is not a loop, put the data in the read and write buffer first, then call the SPI-transfer function to transmit

    for (i = 0; i < MAX_LOOP; i++) {
    /*
    * Wait until slave is ready for transfer; slave will pull
    * CONFIG_SPI_SLAVE_READY low.
    */
    sem_wait(&masterSem);

    /* Initialize master SPI transaction structure */
    masterTxBuffer[sizeof(MASTER_MSG) - 1] = (i % 10) + '0';
    memset((void *) masterRxBuffer, 0, SPI_MSG_LENGTH);
    transaction.count = SPI_MSG_LENGTH;
    transaction.txBuf = (void *) masterTxBuffer;
    transaction.rxBuf = (void *) masterRxBuffer;

    /* Toggle user LED, indicating a SPI transfer is in progress */
    GPIO_toggle(CONFIG_GPIO_LED_1);

    /* Perform SPI transfer */
    transferOK = SPI_transfer(masterSpi, &transaction);
    if (transferOK) {
    Display_printf(display, 0, 0, "Master received: %s", masterRxBuffer);
    }
    else {
    Display_printf(display, 0, 0, "Unsuccessful master SPI transfer");
    }

    /* Sleep for a bit before starting the next SPI transfer */
    sleep(3);
    }

    SPI_close(masterSpi);

    Another question is, whenever I call the SPI transfer function, is the handle I use a pointer variable masterspi? Whenever I call the read-write function, I pass this handle. What's the impact

  • Hello,

    If your application may call SPI_transfer() before another SPI_transfer() is complete, then you should be using separate transaction structures and separate data buffers.

    Do you also see the DMA error on the above loop?

    Best regards,

    Sarah

  • The above loop is obtained in the official routine, there will be no DMA error. In the process of using it, I also set two buffers, mastertxbuffer and masterrxbuffer, to read and write. It should not be a separate buffer. As for the separate transaction structure,

    SPI_transfer(masterSpi, &transaction);

    Is a separate transaction structure the second variable of the above program statement? I use this (& Transaction) variable in all SPI transfer function calls.

    Another problem is that I can't judge when my last SPI transfer will be completed, because my program is called one by one as follows

    int32_t AD7124_Setup(ad7124_device *device, int slave_select,
    ad7124_st_reg *regs, SPI_Handle a)
    {
    int32_t ret;
    unsigned char i=0;
    enum ad7124_registers regNr;
    if(!device || !regs)
    return INVALID_VAL;
    device->regs = regs;
    device->slave_select_id = slave_select;
    device->spi_rdy_poll_cnt = 25000;
    ret = AD7124_Reset(device, a); 

    ---------(int32_t AD7124_Reset(ad7124_device *device, SPI_Handle b)
    {
    int32_t ret = 0;
    uint8_t wrBuf[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    if(!device)
    return INVALID_VAL;
    ret = AD7124_SPI_Write(device->slave_select_id, wrBuf, 8, b);
    ret = AD7124_WaitToPowerOn(device, device->spi_rdy_poll_cnt, b);
    return ret;
    }

    )-----------

    if (ret < 0)
    return ret;
    ret = AD7124_ReadRegister(device, &regs[AD7124_ID], a);------(Similarly, this function calls the SPI read function.)-----

    There are more function calls below, calling the SPI read function and SPI write function sent to you above.All functions are called in order, so I don't know how to determine if preemption occurs while the program is executing.

    Thank you for your patient guidance.

  • Hi,

    Do you call SPI_Params_init() to initialize the transaction? Are you setting the transfer mode anywhere? See the documentation for SPI_transfer() in the docs/drivers/tidriversAPI.html.

    If you are only calling SPI_transfer() from one thread and they are in the default blocking mode, then it should be okay. If you are calling your read/write functions from multiple threads, you should use different transaction structs.

    Best regards,

    Sarah

  • Yes, I call the function in a thread. The initialization settings in the thread are the same as the given example. As shown below, SPI params init is performed without changing the transfer mode.

    void *threadFxn0(void *arg0)
    {

    SPI_Handle masterSpi;
    SPI_Params spiParams;
    struct ad7124_device ad7124;
    status = sem_init(&masterSem, 0, 0);
    SPI_Params_init(&spiParams);
    spiParams.frameFormat = SPI_POL1_PHA1;
    spiParams.bitRate = 1000000;
    masterSpi = SPI_open(CONFIG_SPI_MASTER, &spiParams);
    if (masterSpi == NULL) {
    Display_printf(display, 0, 0, "Error initializing master SPI\n");

    while (1);
    }
    else {
    Display_printf(display, 0, 0, "Master SPI initialized\n");
    }
    AD7124_Setup(&ad7124, AD7124_SLAVE_ID, (ad7124_st_reg *)&ad7124_regs, masterSpi);

    There are other threads in all my programs, but I didn't call the relevant SPI function. I only called the functions mentioned above in the thread above.

    There is another problem. I pass the masterspi variable required by SPI transfer from the main program to the read-write function through the function variable, but I don't pass another variable, transaction, which is defined and used in the read-write function. Will it have an impact

  • When I write a program in SPI read function, the program may jump into stsrtup as well as DMA interrupt cycle_ In the error loop in the cc32xx file, the following

    static void
    faultISR(void)
    {
    /* Enter an infinite loop. */
    while(1)
    {
    }
    }

    In addition, when I write a program in the SPI read function,I found that whether my P05 pin, SCLK signal line, is connected or not has no effect on my program operation, and the waveform can not be measured by using the oscilloscope.If SPI read does not write any program, SCLK has waveform

  • Hello,

    I think you need to set a breakpoint at SPI_transfer() and compare your parameters to your working for-loop or the SDK example. I think it is likely you have an issue with a pointer somewhere.

    Best regards,

    Sarah

  • Does it mean that I need to set a breakpoint to test whether the addresses pointed to by the master and transfer pointers in the SPI transfer function are consistent with the addresses of the running SDK?

  • I found the problem. I used two identical cc3220sf launchxl for SPI communication test. I found that the SPI transmission process must ensure that the sending data and the receiving data exist at the same time, otherwise an error will be reported. For example, delete the sending part of the program from the device, and modify the program as follows:

    for (i = 0; i < MAX_LOOP; i++) {
    sem_wait(&masterSem);
    memset((void *) masterRxBuffer, 0, SPI_MSG_LENGTH);
    transaction.count = SPI_MSG_LENGTH;
    transaction.rxBuf = (void *) masterRxBuffer;
    GPIO_toggle(CONFIG_GPIO_LED_1);
    transferOK = SPI_transfer(masterSpi, &transaction);

    The program doesn't work properly, and when I rewrite the program, I use it alone transation.rx or transation.rx Together with SPI transfer, when I send data to the chip, I don't need to receive the data returned by ADC. I'm not sure whether I will return the data to the host. How can I solve this problem? Because I don't know very well, is all DMA communication bidirectional, or is this the special setting of TI company in writing the example.

    Best wishes.

  • Hello,

    If you only need to send data, you can set the rxBuf for the transaction to NULL.

    Best regards,

    Sarah