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.

LP-EM-CC2340R5: Debugging tips + SPI causing exception

Part Number: LP-EM-CC2340R5
Other Parts Discussed in Thread: CC2340R5, , SYSCONFIG

Tool/software:

Hey folks! I'm sure there's a more productive way to debug this, and I'm struggling to find it. 

I've been following: Debugging — SimpleLinkTm CC23xx SDK BLE5-Stack User's Guide 3.02.04.00 documentation



Here's what I know so far:

- SPI transfers are successful and work (healthy transactions, what I expect, data is read back successfully too)

- Consistently, the next SPI transfer puts me into ExceptionArmV6M.c 's Exception_handlerSpin. Identical to the image above. 

- Looking at tasks, none exceed stack size

-Heap seems fine


- Looking at PC program counter, 0x000124CE, which points me to this exception_handlerSpin, makes sense

- xPSR confirms yes, this is a hard fault via 0x3

- MSP / SP are the same 0x20008F70 value. Looking at this address in disassembly doesn't lead me to anything fruitful. No functions nearby /above to give me hints. 

- Logging, my code is essentially, where the last log is immediately after spi_transfer:

log (start SPI transfer) //this prints to log
spi_transfer(stuff) //SPI trasnfer completes via Saleae reading
log (end SPI transfer) //never prints

So I'm not sure how to debug from here... Looking at the SPI and DMA registers, 

DMA -> ERROR: 0x00000000

SPI0 -> raw interrupt status: IDLE and TX 0x1

SPI0 -> STA: RX FIFO not full, it's empty. TX FIFO not full, it's empty

Any thoughts or wisdoms appreciated!

  • Hey Cameron,

    This is a fine debugging process.  You've ruled out stack and heap overflows and isolated the issue to a hardware exception.  Some code analysis and line-by-line debugging could help further isolate the issue.  Is the CC2340R5 acting as the SPI controller or peripheral?  Have any radio protocols been enabled?  Are you using the SPI TI Driver or driverlib functions?  Is the transfer mode blocking or callback?  Can the behavior be replicated from example code?  Please provide code snippets of your SPI initialization and usage if possible.

    Regards,
    Ryan

  • Side note- I'm a huge fan of yours... I've read countless of your E2E posts. Thank you for everything you've contributed Slight smile

    • CC2340R5 is the controller
    • No radio protocols enabled
    • I am using TI's C:\ti\simplelink_lowpower_f3_sdk_8_40_02_01\source\ti\drivers\SPI.h & SPI.c file
    • I am using blocking mode
    • Sanity checking- SPI example code works well. My implementation is the issue 

    Initializing SPI: I use defaults: 

        SPI_Params spiParams;
        spiParams.bitRate = 1000000;
        spiParams.transferMode = SPI_MODE_BLOCKING;
        SPI_Params_init(&spiParams);
        spiFlashHandle = SPI_open(0, &spiParams);

    So you don't have to go digging, here are the defaults:

    Defaults values are:
    * SPI_Params.transferMode = #SPI_MODE_BLOCKING
    * SPI_Params.transferTimeout = #SPI_WAIT_FOREVER
    * SPI_Params.transferCallbackFxn = NULL
    * SPI_Params.mode = #SPI_CONTROLLER
    * SPI_Params.bitRate = 1000000 (Hz)
    * SPI_Params.dataSize = 8 (bits)
    * SPI_Params.frameFormat = #SPI_POL0_PHA0

    Calling SPI_ transfer: I am using a wrapper I call flash_spi_transfer. It's bogged down with a lot of safety checks and logging I've used to help debug this issue

    static int flash_spi_transfer(SPI_Transaction *t) {
        // 1) Basic protection
        if (!t || t->count == 0 || (!t->txBuf && !t->rxBuf) || t->count > FLASH_READ_STATIC_BUF_SZ) {
            Log_printf(LogModule0, Log_ERROR,
                       "flash_spi_transfer: bad params tx=0x%08X rx=0x%08X cnt=%u",
                       (uintptr_t)(t? t->txBuf:0),
                       (uintptr_t)(t? t->rxBuf:0),
                       t? t->count:0);
            LogSinkUART_flush();
            return -1;
        }
    
        Log_printf(LogModule0, Log_DEBUG,
                   "flash_spi_transfer: START tx=0x%08X rx=0x%08X cnt=%u",
                   (uintptr_t)t->txBuf, (uintptr_t)t->rxBuf, t->count);
        LogSinkUART_flush();
    
        // 2) Assert CS low entirety of transfer
        SPI_control(spiFlashHandle, SPILPF3DMA_CMD_CLEAR_CSN_PIN, NULL);
        flash_select(); //GPIO writes CS low
    
        // 3) Blocking transfer
        bool ok = SPI_transfer(spiFlashHandle, t);
        Log_printf(LogModule0, Log_DEBUG, "flash_spi_transfer: SPI_transfer done");
        
        // 4) Poll BUSY bit with timeout, yield to other tasks
        const TickType_t start = xTaskGetTickCount();
        while (SPIStatus(SPI0_BASE) & SPI_BUSY) {
            if ((xTaskGetTickCount() - start) > pdMS_TO_TICKS(1000)) {
                Log_printf(LogModule0, Log_ERROR, "flash_spi_transfer: BUSY timeout");
                LogSinkUART_flush();
                break;
            }
            taskYIELD();
        }
    
        // 5) De-assert CS
        flash_deselect();
    
        Log_printf(LogModule0, Log_DEBUG, "flash_spi_transfer: END success=%d", ok); LogSinkUART_flush();
    
        return ok ? 0 : -1;
    }

    And here's how I ultimately call the wrapper which calls SPI_trasnfer ultimately:

    bool flash_read(uint32_t address, uint8_t *data, uint32_t length) {
        Log_printf(LogModule0, Log_DEBUG, "flash_read: START - addr=0x%08X len=%u", address, length); LogSinkUART_flush();
        // Sanity check
        if (!spiFlashHandle || data == NULL || length == 0 || length > FLASH_READ_MAX) {
            Log_printf(LogModule0, Log_ERROR,
                       "flash_read: Invalid args (len=%u)", length);
            LogSinkUART_flush();
            return false;
        }
    
        // These live in DMA-capable RAM and are 4-byte aligned
        static __attribute__((aligned(4)))
        uint8_t txBuf[FLASH_READ_STATIC_BUF_SZ];
        static __attribute__((aligned(4)))
        uint8_t rxBuf[FLASH_READ_STATIC_BUF_SZ];
    
        // Build the 4-byte Read-command header
        txBuf[0] = FLASH_CMD_READ;
        txBuf[1] = (address >> 16) & 0xFF;
        txBuf[2] = (address >>  8) & 0xFF;
        txBuf[3] =  address        & 0xFF;
    
        // Dummy clocks for the data phase
        memset(txBuf + 4, 0xFF, length);
    
        // Clear RX buffer (optional, but helps with debugging)
        memset(rxBuf, 0x00, length + 4);
    
        // Set up the SPI transfer
        SPI_Transaction t = {
            .count = length + 4,
            .txBuf = txBuf,
            .rxBuf = rxBuf,
        };
    
        GPIO_write(CONFIG_GPIO_LED_GREEN, CONFIG_LED_ON);
    
        if (flash_spi_transfer(&t) < 0) {
            Log_printf(LogModule0, Log_ERROR,
                       "flash_read: SPI transfer failed");
            LogSinkUART_flush(); //This is never printed
            return false;
        }
        Log_printf(LogModule0, Log_DEBUG,
                   "flash_read: SUCCESS addr=0x%06X len=%u",
                   address, length); LogSinkUART_flush(); //This is never printed
        GPIO_write(CONFIG_GPIO_LED_GREEN, CONFIG_LED_OFF);
    
    
        // Copy out just the data payload
        memcpy(data, rxBuf + 4, length);
    
        
        
        return true;
    }

    Thanks!!

  • I truly appreciate your kind words.  I cannot take all of the credit for my E2E prominence as many times my E2E responses are based off feedback/thoughts from other TI colleagues and experts.  I do try to give credit where it is due, and certainly intend to take leadership on the majority of threads I answer, but as a whole my E2E presence is a team effort. 

    Here are some of my observations when reviewing the code provided:

    • SPI_control is used once for SPILPF3DMA_CMD_CLEAR_CSN_PIN before the SPI transfer, but not SPILPF3DMA_CMD_SET_CSN_PIN after the transfer.  Also flash_select/flash_deselect should achieve this anyway so I would recommend removing SPI_control.
    • Step 4 (Poll BUSY bit with timeout, yield to other tasks) is unnecessary in blocking mode and can be removed.  
    • static __attribute__((aligned(4))) should not be necessary for the tx and rx buffers with a data size of 8 bits.

    Please explain your reasoning if you disagree with any of the above points, but note that I don't suspect any of causing the issue.

    How many calls to flash_spi_transfer complete successfully?  Are you able to provide a full UART log?  Can the issue be reduced to a a single application file which you can share (assuming the issue can be replicated with the MISO and MOSI lines tied together)?  I would also recommend that you add SPILPF3DMA.c directly to your project workspace to add logs and further debug SPILPF3DMA_transfer.  You can view the SPI and DMA registers in the CCS debugger to see if there is a difference in setup between the last working transfer and the broken instance.

    Regards,
    Ryan

  • Implemented your recommendations, code looks healthy. Transfer wise, ~5 SPI transfers, long ones where I attempt to read back an entire page of flash. 256 bytes + 4 = 260 total. All 260 transfer the first 4x, and all 260 the final problem child.

    A's are identical, B's are identical

    I would also recommend that you add SPILPF3DMA.c directly to your project workspace to add logs and further debug SPILPF3DMA_transfer


    genius! I added many logging lines, within SPILPF3DMA_transfer,

    the final transfer hangs on "waiting for semaphore"

            if (object->transferMode == SPI_MODE_BLOCKING) {
                Log_printf(LogModule0, Log_DEBUG, "SPILPF3DMA_transfer: waiting on semaphore"); LogSinkUART_flush(); // the last print of this function
                if (SemaphoreP_OK != SemaphoreP_pend(&(object->transferComplete), object->transferTimeout)) {
                    object->headPtr->status = SPI_TRANSFER_FAILED;
                    Log_printf(LogModule0, Log_ERROR, "SPILPF3DMA_transfer: semaphore timeout, cancelling"); LogSinkUART_flush(); //no print
                    SPILPF3DMA_transferCancel(handle);
                    SemaphoreP_pend(&(object->transferComplete), SemaphoreP_NO_WAIT);
                    return false;
                }
                Log_printf(LogModule0, Log_DEBUG, "SPILPF3DMA_transfer: semaphore acquired"); LogSinkUART_flush(); //no print
            }

    So, I continued deeper down the logging rabbit hole, now logging verbosely SPI3LPF3DMA_hwiFxn. 


    The final log printed is "TX channel idle & no queue: disabling DMA TX" corresponding to this code within SPI3LPF3DMA_hwiFxn:



    I attempted to add a breakpoint within SPI3LPF3DMA_hwiFxn to read values in debugger, but the breakpoint causes me to fail first SPI transfer. I get stuck in dataGet() forever when breakpoint. 


    Anyways, here's a log dump. It's cruel and unusual punishment to ask you to read this bloated log... Final lines are probably most fruitful, hinting to where exception happens 

    COM3 |  0.003808000 | LogMod_LogModule0 | Log_INFO    | ../source/tests_tasks/LittleFS_test_task.c:32 | >>>>> LittleFS Test Task Starting
    COM3 |  0.003928000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:66                      | flash_spi_transfer: START tx=0x2000278C rx=0x20002788 cnt=4
    COM3 |  0.004024000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:74                      | flash_spi_transfer: SPI_transfer START
    COM3 |  0.004056000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:753                    | SPILPF3DMA_transfer: START count=4 tx=0x2000278c rx=0x20002788
    COM3 |  0.004144000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:767                    | SPILPF3DMA_transfer: interrupts disabled
    COM3 |  0.004208000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:778                    | SPILPF3DMA_transfer: buffersAligned=1
    COM3 |  0.004264000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:802                    | SPILPF3DMA_transfer: new headPtr set, count=4
    COM3 |  0.004360000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:806                    | SPILPF3DMA_transfer: constraint set for txBuf=0x2000278c
    COM3 |  0.004416000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:823                    | SPILPF3DMA_transfer: DMA priming
    COM3 |  0.004512000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:825                    | SPILPF3DMA_transfer: DMA primeTransfer done
    COM3 |  0.004568000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.004632000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x000001a0
    COM3 |  0.004632000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:353                    | SPI baseAddr: 0x40030000
    COM3 |  0.004696000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:356                    | MIS cleared
    COM3 |  0.004752000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:407                    | No RX overflow, proceeding with DMA handling
    COM3 |  0.004784000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:411                    | UDMA RX interrupt cleared
    COM3 |  0.004848000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 0
    COM3 |  0.004904000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:433                    | Using primary DMA channel
    COM3 |  0.004968000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:450                    | TX channel idle & no queue: disabling DMA TX
    COM3 |  0.005000000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:454                    | DMA TX disabled and interrupt cleared
    COM3 |  0.005056000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:461                    | RX DMA STOP & transferSize=4
    COM3 |  0.005120000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:465                    | framesTransferred=4
    COM3 |  0.005152000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:472                    | Switched activeChannel to 8
    COM3 |  0.005208000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:477                    | Cleared transferSize
    COM3 |  0.005272000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:498                    | Interrupts disabled (key=0)
    COM3 |  0.005336000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:502                    | Marked transfer completed
    COM3 |  0.005368000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:509                    | Initialized completedTransfers list
    COM3 |  0.005424000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:531                    | Prepared for next transaction
    COM3 |  0.005488000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:535                    | Interrupts restored
    COM3 |  0.005520000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:549                    | All transfers done: DMA disabled
    COM3 |  0.005576000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:554                    | Driver SWI posted
    COM3 |  0.005640000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:559                    | End of iteration 0
    COM3 |  0.005696000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 1
    COM3 |  0.005728000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:422                    | No more transfers (headPtr NULL), breaking
    COM3 |  0.005792000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:565                    | SPILPF3DMA_hwiFxn: END
    COM3 |  0.005912000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:828                    | SPILPF3DMA_transfer: interrupts restored
    COM3 |  0.006008000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:831                    | SPILPF3DMA_transfer: waiting on semaphore
    COM3 |  0.006160000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:839                    | SPILPF3DMA_transfer: semaphore acquired
    COM3 |  0.006248000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:843                    | SPILPF3DMA_transfer: END status=0
    COM3 |  0.006368000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:76                      | flash_spi_transfer: SPI_transfer done
    COM3 |  0.006368000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:81                      | flash_spi_transfer: END success=1
    COM3 |  0.006496000 | LogMod_LogModule0 | Log_DEBUG   | ../source/LittleFS.c:128                      | littlefs_mount: BEGIN
    COM3 |  0.006584000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:89                      | flash_read_status: START
    COM3 |  0.006704000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:66                      | flash_spi_transfer: START tx=0x20002764 rx=0x20002760 cnt=2
    COM3 |  0.006800000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:74                      | flash_spi_transfer: SPI_transfer START
    COM3 |  0.006832000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:753                    | SPILPF3DMA_transfer: START count=2 tx=0x20002764 rx=0x20002760
    COM3 |  0.006920000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:767                    | SPILPF3DMA_transfer: interrupts disabled
    COM3 |  0.006984000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:778                    | SPILPF3DMA_transfer: buffersAligned=1
    COM3 |  0.007040000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:802                    | SPILPF3DMA_transfer: new headPtr set, count=2
    COM3 |  0.007136000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:806                    | SPILPF3DMA_transfer: constraint set for txBuf=0x20002764
    COM3 |  0.007192000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:823                    | SPILPF3DMA_transfer: DMA priming
    COM3 |  0.007288000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:825                    | SPILPF3DMA_transfer: DMA primeTransfer done
    COM3 |  0.007344000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.007408000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x000001a0
    COM3 |  0.007408000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:353                    | SPI baseAddr: 0x40030000
    COM3 |  0.007472000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:356                    | MIS cleared
    COM3 |  0.007528000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:407                    | No RX overflow, proceeding with DMA handling
    COM3 |  0.007560000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:411                    | UDMA RX interrupt cleared
    COM3 |  0.007624000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 0
    COM3 |  0.007680000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:433                    | Using primary DMA channel
    COM3 |  0.007712000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:450                    | TX channel idle & no queue: disabling DMA TX
    COM3 |  0.007776000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:454                    | DMA TX disabled and interrupt cleared
    COM3 |  0.007832000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:461                    | RX DMA STOP & transferSize=2
    COM3 |  0.007896000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:465                    | framesTransferred=2
    COM3 |  0.007928000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:472                    | Switched activeChannel to 8
    COM3 |  0.007984000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:477                    | Cleared transferSize
    COM3 |  0.008048000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:498                    | Interrupts disabled (key=0)
    COM3 |  0.008080000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:502                    | Marked transfer completed
    COM3 |  0.008136000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:509                    | Initialized completedTransfers list
    COM3 |  0.008200000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:531                    | Prepared for next transaction
    COM3 |  0.008264000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:535                    | Interrupts restored
    COM3 |  0.008296000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:549                    | All transfers done: DMA disabled
    COM3 |  0.008352000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:554                    | Driver SWI posted
    COM3 |  0.008416000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:559                    | End of iteration 0
    COM3 |  0.008472000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 1
    COM3 |  0.008504000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:422                    | No more transfers (headPtr NULL), breaking
    COM3 |  0.008568000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:565                    | SPILPF3DMA_hwiFxn: END
    COM3 |  0.008688000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:828                    | SPILPF3DMA_transfer: interrupts restored
    COM3 |  0.008784000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:831                    | SPILPF3DMA_transfer: waiting on semaphore
    COM3 |  0.008936000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:839                    | SPILPF3DMA_transfer: semaphore acquired
    COM3 |  0.009024000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:843                    | SPILPF3DMA_transfer: END status=0
    COM3 |  0.009144000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:76                      | flash_spi_transfer: SPI_transfer done
    COM3 |  0.009144000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:81                      | flash_spi_transfer: END success=1
    COM3 |  0.009272000 | LogMod_LogModule0 | Log_INFO    | ../source/LittleFS.c:135                      | Flash Status Register: 0x00 (WIP=0, WEL=0, BP=0)
    COM3 |  0.009360000 | LogMod_LogModule0 | Log_INFO    | ../source/SPI_flash.c:420                     | flash_init: SPI already opened, sent wake command via flash_write
    COM3 |  0.009480000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:66                      | flash_spi_transfer: START tx=0x20002730 rx=0x00000000 cnt=1
    COM3 |  0.009576000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:74                      | flash_spi_transfer: SPI_transfer START
    COM3 |  0.009600000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:753                    | SPILPF3DMA_transfer: START count=1 tx=0x20002730 rx=0x00000000
    COM3 |  0.009696000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:767                    | SPILPF3DMA_transfer: interrupts disabled
    COM3 |  0.009784000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:778                    | SPILPF3DMA_transfer: buffersAligned=1
    COM3 |  0.009848000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:802                    | SPILPF3DMA_transfer: new headPtr set, count=1
    COM3 |  0.009912000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:806                    | SPILPF3DMA_transfer: constraint set for txBuf=0x20002730
    COM3 |  0.009968000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:812                    | SPILPF3DMA_transfer: using polling mode
    COM3 |  0.010064000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.010152000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x00000020
    COM3 |  0.010184000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:353                    | SPI baseAddr: 0x40030000
    COM3 |  0.010248000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:356                    | MIS cleared
    COM3 |  0.010272000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:407                    | No RX overflow, proceeding with DMA handling
    COM3 |  0.010336000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:411                    | UDMA RX interrupt cleared
    COM3 |  0.010400000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 0
    COM3 |  0.010424000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:440                    | Using alternate DMA channel
    COM3 |  0.010488000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:559                    | End of iteration 0
    COM3 |  0.010552000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 1
    COM3 |  0.010608000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:440                    | Using alternate DMA channel
    COM3 |  0.010640000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:559                    | End of iteration 1
    COM3 |  0.010704000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:565                    | SPILPF3DMA_hwiFxn: END
    COM3 |  0.010760000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.010792000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x00000000
    COM3 |  0.010824000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:353                    | SPI baseAddr: 0x40030000
    COM3 |  0.010888000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:356                    | MIS cleared
    COM3 |  0.010944000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:407                    | No RX overflow, proceeding with DMA handling
    COM3 |  0.010976000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:411                    | UDMA RX interrupt cleared
    COM3 |  0.011040000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 0
    COM3 |  0.011096000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:440                    | Using alternate DMA channel
    COM3 |  0.011128000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:559                    | End of iteration 0
    COM3 |  0.011192000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 1
    COM3 |  0.011248000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:440                    | Using alternate DMA channel
    COM3 |  0.011312000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:559                    | End of iteration 1
    COM3 |  0.011344000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:565                    | SPILPF3DMA_hwiFxn: END
    COM3 |  0.011552000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:843                    | SPILPF3DMA_transfer: END status=0
    COM3 |  0.011648000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:76                      | flash_spi_transfer: SPI_transfer done
    COM3 |  0.011984000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:1136                          | lfs_dir_fetchmatch: ENTER
    COM3 |  0.012072000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:52                            | lfs_bd_read: ENTER block=0 off=0 size=4
    COM3 |  0.012200000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:116                           | lfs_bd_read: loading to rcache
    COM3 |  0.012288000 | LogMod_LogModule0 | Log_DEBUG   | ../source/LittleFS.c:42                       | start lfs_flash_read
    COM3 |  0.012408000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:224                     | flash_read: START - addr=0x00000000 len=256
    COM3 |  0.012624000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:66                      | flash_spi_transfer: START tx=0x2000244C rx=0x20002348 cnt=260
    COM3 |  0.012744000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:74                      | flash_spi_transfer: SPI_transfer START
    COM3 |  0.012744000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:753                    | SPILPF3DMA_transfer: START count=260 tx=0x2000244c rx=0x20002348
    COM3 |  0.012896000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:767                    | SPILPF3DMA_transfer: interrupts disabled
    COM3 |  0.012960000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:778                    | SPILPF3DMA_transfer: buffersAligned=1
    COM3 |  0.013016000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:802                    | SPILPF3DMA_transfer: new headPtr set, count=260
    COM3 |  0.013080000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:806                    | SPILPF3DMA_transfer: constraint set for txBuf=0x2000244c
    COM3 |  0.013144000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:823                    | SPILPF3DMA_transfer: DMA priming
    COM3 |  0.013232000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:825                    | SPILPF3DMA_transfer: DMA primeTransfer done
    COM3 |  0.013296000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.013352000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x00000100
    COM3 |  0.013968000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:831                    | SPILPF3DMA_transfer: waiting on semaphore
    COM3 |  0.015552000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.015616000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x00000100
    COM3 |  0.015616000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:353                    | SPI baseAddr: 0x40030000
    COM3 |  0.015672000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:356                    | MIS cleared
    COM3 |  0.015736000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:407                    | No RX overflow, proceeding with DMA handling
    COM3 |  0.015792000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:411                    | UDMA RX interrupt cleared
    COM3 |  0.015824000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 0
    COM3 |  0.015888000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:433                    | Using primary DMA channel
    COM3 |  0.015944000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:450                    | TX channel idle & no queue: disabling DMA TX
    COM3 |  0.015976000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:454                    | DMA TX disabled and interrupt cleared
    COM3 |  0.016040000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:461                    | RX DMA STOP & transferSize=260
    COM3 |  0.016104000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:465                    | framesTransferred=260
    COM3 |  0.016128000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:472                    | Switched activeChannel to 8
    COM3 |  0.016192000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:477                    | Cleared transferSize
    COM3 |  0.016224000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:498                    | Interrupts disabled (key=0)
    COM3 |  0.016280000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:502                    | Marked transfer completed
    COM3 |  0.016344000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:509                    | Initialized completedTransfers list
    COM3 |  0.016376000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:531                    | Prepared for next transaction
    COM3 |  0.016432000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:535                    | Interrupts restored
    COM3 |  0.016496000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:549                    | All transfers done: DMA disabled
    COM3 |  0.016560000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:554                    | Driver SWI posted
    COM3 |  0.016616000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:559                    | End of iteration 0
    COM3 |  0.016648000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 1
    COM3 |  0.016712000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:422                    | No more transfers (headPtr NULL), breaking
    COM3 |  0.016768000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:565                    | SPILPF3DMA_hwiFxn: END
    COM3 |  0.016800000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.016864000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x000000a0
    COM3 |  0.016896000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:353                    | SPI baseAddr: 0x40030000
    COM3 |  0.016920000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:356                    | MIS cleared
    COM3 |  0.017384000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:843                    | SPILPF3DMA_transfer: END status=0
    COM3 |  0.017472000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:76                      | flash_spi_transfer: SPI_transfer done
    COM3 |  0.017568000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:266                     | flash_read: SUCCESS addr=0x000000 len=256
    COM3 |  0.017720000 | LogMod_LogModule0 | Log_DEBUG   | ../source/LittleFS.c:45                       | lfs_flash_read: Read block 0 offset 0 size 256
    COM3 |  0.017840000 | LogMod_LogModule0 | Log_DEBUG   | ../source/LittleFS.c:46                       | lfs_flash_read:  1 (1=good)
    COM3 |  0.017928000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:84                            | lfs_bd_read: hit rcache
    COM3 |  0.018056000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:135                           | lfs_bd_read: EXIT
    COM3 |  0.018144000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:52                            | lfs_bd_read: ENTER block=1 off=0 size=4
    COM3 |  0.018264000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:116                           | lfs_bd_read: loading to rcache
    COM3 |  0.018360000 | LogMod_LogModule0 | Log_DEBUG   | ../source/LittleFS.c:42                       | start lfs_flash_read
    COM3 |  0.018480000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:224                     | flash_read: START - addr=0x00001000 len=256
    COM3 |  0.018664000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:66                      | flash_spi_transfer: START tx=0x2000244C rx=0x20002348 cnt=260
    COM3 |  0.018784000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:74                      | flash_spi_transfer: SPI_transfer START
    COM3 |  0.018784000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:753                    | SPILPF3DMA_transfer: START count=260 tx=0x2000244c rx=0x20002348
    COM3 |  0.018936000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:767                    | SPILPF3DMA_transfer: interrupts disabled
    COM3 |  0.019000000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:778                    | SPILPF3DMA_transfer: buffersAligned=1
    COM3 |  0.019056000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:802                    | SPILPF3DMA_transfer: new headPtr set, count=260
    COM3 |  0.019120000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:806                    | SPILPF3DMA_transfer: constraint set for txBuf=0x2000244c
    COM3 |  0.019184000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:823                    | SPILPF3DMA_transfer: DMA priming
    COM3 |  0.019272000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:825                    | SPILPF3DMA_transfer: DMA primeTransfer done
    COM3 |  0.019976000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:831                    | SPILPF3DMA_transfer: waiting on semaphore
    COM3 |  0.021592000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.021648000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x00000100
    COM3 |  0.021680000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:353                    | SPI baseAddr: 0x40030000
    COM3 |  0.021712000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:356                    | MIS cleared
    COM3 |  0.021776000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:407                    | No RX overflow, proceeding with DMA handling
    COM3 |  0.021832000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:411                    | UDMA RX interrupt cleared
    COM3 |  0.021864000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 0
    COM3 |  0.021928000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:433                    | Using primary DMA channel
    COM3 |  0.021984000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:450                    | TX channel idle & no queue: disabling DMA TX
    COM3 |  0.022048000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:454                    | DMA TX disabled and interrupt cleared
    COM3 |  0.022080000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:461                    | RX DMA STOP & transferSize=260
    COM3 |  0.022136000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:465                    | framesTransferred=260
    COM3 |  0.023208000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:843                    | SPILPF3DMA_transfer: END status=0
    COM3 |  0.023328000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:76                      | flash_spi_transfer: SPI_transfer done
    COM3 |  0.023448000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:266                     | flash_read: SUCCESS addr=0x001000 len=256
    COM3 |  0.023600000 | LogMod_LogModule0 | Log_DEBUG   | ../source/LittleFS.c:45                       | lfs_flash_read: Read block 1 offset 0 size 256
    COM3 |  0.023696000 | LogMod_LogModule0 | Log_DEBUG   | ../source/LittleFS.c:46                       | lfs_flash_read:  1 (1=good)
    COM3 |  0.023816000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:84                            | lfs_bd_read: hit rcache
    COM3 |  0.023912000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:135                           | lfs_bd_read: EXIT
    COM3 |  0.024032000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:52                            | lfs_bd_read: ENTER block=0 off=4 size=4
    COM3 |  0.024120000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:116                           | lfs_bd_read: loading to rcache
    COM3 |  0.024240000 | LogMod_LogModule0 | Log_DEBUG   | ../source/LittleFS.c:42                       | start lfs_flash_read
    COM3 |  0.024336000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:224                     | flash_read: START - addr=0x00000000 len=256
    COM3 |  0.024552000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:66                      | flash_spi_transfer: START tx=0x2000244C rx=0x20002348 cnt=260
    COM3 |  0.024640000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:74                      | flash_spi_transfer: SPI_transfer START
    COM3 |  0.024672000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:753                    | SPILPF3DMA_transfer: START count=260 tx=0x2000244c rx=0x20002348
    COM3 |  0.024792000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:767                    | SPILPF3DMA_transfer: interrupts disabled
    COM3 |  0.024856000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:778                    | SPILPF3DMA_transfer: buffersAligned=1
    COM3 |  0.024944000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:802                    | SPILPF3DMA_transfer: new headPtr set, count=260
    COM3 |  0.025008000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:806                    | SPILPF3DMA_transfer: constraint set for txBuf=0x2000244c
    COM3 |  0.025064000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:823                    | SPILPF3DMA_transfer: DMA priming
    COM3 |  0.025160000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:825                    | SPILPF3DMA_transfer: DMA primeTransfer done
    COM3 |  0.025864000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:831                    | SPILPF3DMA_transfer: waiting on semaphore
    COM3 |  0.027480000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.027536000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x00000100
    COM3 |  0.027568000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:353                    | SPI baseAddr: 0x40030000
    COM3 |  0.027632000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:356                    | MIS cleared
    COM3 |  0.027688000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:407                    | No RX overflow, proceeding with DMA handling
    COM3 |  0.027720000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:411                    | UDMA RX interrupt cleared
    COM3 |  0.027784000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 0
    COM3 |  0.027840000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:433                    | Using primary DMA channel
    COM3 |  0.027872000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:450                    | TX channel idle & no queue: disabling DMA TX
    COM3 |  0.027936000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:454                    | DMA TX disabled and interrupt cleared
    COM3 |  0.027992000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:461                    | RX DMA STOP & transferSize=260
    COM3 |  0.028056000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:465                    | framesTransferred=260
    COM3 |  0.028088000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:472                    | Switched activeChannel to 8
    COM3 |  0.028144000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:477                    | Cleared transferSize
    COM3 |  0.028208000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:498                    | Interrupts disabled (key=0)
    COM3 |  0.028240000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:502                    | Marked transfer completed
    COM3 |  0.028304000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:509                    | Initialized completedTransfers list
    COM3 |  0.028360000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:531                    | Prepared for next transaction
    COM3 |  0.028392000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:535                    | Interrupts restored
    COM3 |  0.028456000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:549                    | All transfers done: DMA disabled
    COM3 |  0.028512000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:554                    | Driver SWI posted
    COM3 |  0.028576000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:559                    | End of iteration 0
    COM3 |  0.028632000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 1
    COM3 |  0.028664000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:422                    | No more transfers (headPtr NULL), breaking
    COM3 |  0.028728000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:565                    | SPILPF3DMA_hwiFxn: END
    COM3 |  0.028792000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.028816000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x000000a0
    COM3 |  0.028848000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:353                    | SPI baseAddr: 0x40030000
    COM3 |  0.028912000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:356                    | MIS cleared
    COM3 |  0.029336000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:843                    | SPILPF3DMA_transfer: END status=0
    COM3 |  0.029456000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:76                      | flash_spi_transfer: SPI_transfer done
    COM3 |  0.029584000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:266                     | flash_read: SUCCESS addr=0x000000 len=256
    COM3 |  0.029736000 | LogMod_LogModule0 | Log_DEBUG   | ../source/LittleFS.c:45                       | lfs_flash_read: Read block 0 offset 0 size 256
    COM3 |  0.029824000 | LogMod_LogModule0 | Log_DEBUG   | ../source/LittleFS.c:46                       | lfs_flash_read:  1 (1=good)
    COM3 |  0.029920000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:84                            | lfs_bd_read: hit rcache
    COM3 |  0.030040000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:135                           | lfs_bd_read: EXIT
    COM3 |  0.030160000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:52                            | lfs_bd_read: ENTER block=0 off=8 size=4
    COM3 |  0.030256000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:84                            | lfs_bd_read: hit rcache
    COM3 |  0.030344000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:135                           | lfs_bd_read: EXIT
    COM3 |  0.030464000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:52                            | lfs_bd_read: ENTER block=1 off=4 size=4
    COM3 |  0.030616000 | LogMod_LogModule0 | Log_DEBUG   | ../source/lfs.c:116                           | lfs_bd_read: loading to rcache
    COM3 |  0.030712000 | LogMod_LogModule0 | Log_DEBUG   | ../source/LittleFS.c:42                       | start lfs_flash_read
    COM3 |  0.030832000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:224                     | flash_read: START - addr=0x00001000 len=256
    COM3 |  0.031016000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:66                      | flash_spi_transfer: START tx=0x2000244C rx=0x20002348 cnt=260
    COM3 |  0.031136000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPI_flash.c:74                      | flash_spi_transfer: SPI_transfer START
    COM3 |  0.031168000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:753                    | SPILPF3DMA_transfer: START count=260 tx=0x2000244c rx=0x20002348
    COM3 |  0.031288000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:767                    | SPILPF3DMA_transfer: interrupts disabled
    COM3 |  0.031352000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:778                    | SPILPF3DMA_transfer: buffersAligned=1
    COM3 |  0.031440000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:802                    | SPILPF3DMA_transfer: new headPtr set, count=260
    COM3 |  0.031504000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:806                    | SPILPF3DMA_transfer: constraint set for txBuf=0x2000244c
    COM3 |  0.031560000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:823                    | SPILPF3DMA_transfer: DMA priming
    COM3 |  0.031656000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:825                    | SPILPF3DMA_transfer: DMA primeTransfer done
    COM3 |  0.031720000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.031776000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x00000100
    COM3 |  0.031776000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:353                    | SPI baseAddr: 0x40030000
    COM3 |  0.032384000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:831                    | SPILPF3DMA_transfer: waiting on semaphore
    COM3 |  0.033824000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:336                    | SPILPF3DMA_hwiFxn: entered
    COM3 |  0.033848000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:352                    | MIS read: 0x00000100
    COM3 |  0.033880000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:353                    | SPI baseAddr: 0x40030000
    COM3 |  0.033944000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:356                    | MIS cleared
    COM3 |  0.033976000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:407                    | No RX overflow, proceeding with DMA handling
    COM3 |  0.034000000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:411                    | UDMA RX interrupt cleared
    
    ==== Often, this is where log ends ====
    
    COM3 |  0.034064000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:417                    | Loop iteration 0
    COM3 |  0.034128000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:433                    | Using primary DMA channel
    COM3 |  0.034160000 | LogMod_LogModule0 | Log_DEBUG   | ../source/SPILPF3DMA.c:450                    | TX channel idle & no queue: disabling DMA TX
    ==== Log never goes beyond here ====

    The code in question which prints these final log lines is:

    SPILPF3DMA_hwiFxn(){
    ...
        if( intStatus & SPI_MIS_RXOFV_SET) {
        ...
        }
        else {
            Log_printf(LogModule0, Log_DEBUG, "No RX overflow, proceeding with DMA handling");
            LogSinkUART_flush();
        
            UDMALPF3_clearInterrupt(hwAttrs->rxChannelBitMask | hwAttrs->txChannelBitMask);
            Log_printf(LogModule0, Log_DEBUG, "UDMA RX interrupt cleared"); //final print
            LogSinkUART_flush();
        
            /* Check both primary and alternate channels */
            for (i = 0; i < 2; i++)
            {
                Log_printf(LogModule0, Log_DEBUG, "Loop iteration %u", i); //sometimes prints, usually not
                LogSinkUART_flush();
                ...
            }
        }
    }

  • Thank you for the additional debugging.  Do you know the reason for the abnormal time delay between the fourth and fifth transfers?  Also, does the issue occur with a loopback test (i.e. the SPI controller communicating with itself by tying the MISO and MOSI lines, CLK and CS are not connected to a peripheral)?  I'm not having any issues when replicating your SPI setup using the spicontroller example.  I am using a LP-EM-CC2340R5 with Rev B silicon, SDK v8.40.02.01, and minor changes to the spicontroller.syscfg configuration for three-pin SPI mode with software control of a CS GPIO pin.

    If you could review and run the following spicontroller.c code and confirm the minimal changes necessary to break the SPI TI Driver, this would help in further debugging your setup.  CONFIG_GPIO_SPI_CS is configured as a GPIO on pin DIO11 in my SysConfig.

    /*
     * Copyright (c) 2018-2024, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *     notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *     notice, this list of conditions and the following disclaimer in the
     *     documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *     its contributors may be used to endorse or promote products derived
     *     from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== spicontroller.c ========
     */
    #include <stddef.h>
    #include <stdint.h>
    #include <string.h>
    
    /* POSIX Header files */
    #include <pthread.h>
    #include <semaphore.h>
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/SPI.h>
    #include <ti/display/Display.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    #define THREADSTACKSIZE (1024)
    
    #define SPI_MSG_LENGTH (260)
    #define CONTROLLER_MSG ("Hello from controller, msg#: ")
    
    #define MAX_LOOP (20)
    
    #ifdef DeviceFamily_CC35XX
        #define CONFIG_GPIO_LED_0 GPIO_INVALID_INDEX
        #define CONFIG_GPIO_LED_1 GPIO_INVALID_INDEX
    #endif
    
    static Display_Handle display;
    
    unsigned char controllerRxBuffer[SPI_MSG_LENGTH];
    unsigned char controllerTxBuffer[SPI_MSG_LENGTH];
    
    /*
     *  ======== controllerThread ========
     *  Controller SPI sends a message to peripheral while simultaneously receiving a
     *  message from the peripheral.
     */
    void *controllerThread(void *arg0)
    {
        SPI_Handle controllerSpi;
        SPI_Params spiParams;
        SPI_Transaction transaction;
        uint32_t i;
        bool transferOK;
        int32_t status;
    
        /* Open SPI as controller (default) */
        SPI_Params_init(&spiParams);
        spiParams.frameFormat = SPI_POL0_PHA1;
        /* See device-specific technical reference manual for supported speeds */
        spiParams.bitRate     = 1000000;
        controllerSpi         = SPI_open(CONFIG_SPI_CONTROLLER, &spiParams);
        if (controllerSpi == NULL)
        {
            Display_printf(display, 0, 0, "Error initializing controller SPI\n");
            while (1) {}
        }
        else
        {
            Display_printf(display, 0, 0, "Controller SPI initialized\n");
        }
    
        /* Copy message to transmit buffer */
        strncpy((char *)controllerTxBuffer, CONTROLLER_MSG, SPI_MSG_LENGTH);
    
        for (i = 0; i < MAX_LOOP; i++)
        {
            /* Initialize controller SPI transaction structure */
            controllerTxBuffer[sizeof(CONTROLLER_MSG) - 1] = (i % 10) + '0';
            memset((void *)controllerRxBuffer, 0, SPI_MSG_LENGTH);
            transaction.count = SPI_MSG_LENGTH;
            transaction.txBuf = (void *)controllerTxBuffer;
            transaction.rxBuf = (void *)controllerRxBuffer;
    
            /* Toggle user LED, indicating a SPI transfer is in progress */
            GPIO_toggle(CONFIG_GPIO_LED_1);
    
            /* Perform SPI transfer */
            GPIO_write(CONFIG_GPIO_SPI_CS, 0);
            transferOK = SPI_transfer(controllerSpi, &transaction);
            if (transferOK)
            {
                Display_printf(display, 0, 0, "Controller received: %s", controllerRxBuffer);
            }
            else
            {
                Display_printf(display, 0, 0, "Unsuccessful controller SPI transfer");
            }
            GPIO_write(CONFIG_GPIO_SPI_CS, 1);
    
            /* Sleep for a bit before starting the next SPI transfer  */
    //        sleep(3);
        }
    
        SPI_close(controllerSpi);
    
        Display_printf(display, 0, 0, "\nDone");
    
        return (NULL);
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        pthread_t thread0;
        pthread_attr_t attrs;
        struct sched_param priParam;
        int retc;
        int detachState;
    
        /* Call driver init functions. */
        Display_init();
        GPIO_init();
        SPI_init();
    
        /* Configure the LED pins */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        GPIO_setConfig(CONFIG_GPIO_SPI_CS, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_write(CONFIG_GPIO_SPI_CS, 1);
    
        /* Open the display for output */
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL)
        {
            /* Failed to open display driver */
            while (1) {}
        }
    
        /* Turn on user LED */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    
        Display_printf(display, 0, 0, "Starting the SPI controller example");
        Display_printf(display,
                       0,
                       0,
                       "This example requires external wires to be "
                       "connected to the header pins. Please see the Readme.html and Board.html for details.\n");
    
        /* Create application threads */
        pthread_attr_init(&attrs);
    
        detachState = PTHREAD_CREATE_DETACHED;
        /* Set priority and stack size attributes */
        retc        = pthread_attr_setdetachstate(&attrs, detachState);
        if (retc != 0)
        {
            /* pthread_attr_setdetachstate() failed */
            while (1) {}
        }
    
        retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
        if (retc != 0)
        {
            /* pthread_attr_setstacksize() failed */
            while (1) {}
        }
    
        /* Create controller thread */
        priParam.sched_priority = 1;
        pthread_attr_setschedparam(&attrs, &priParam);
    
        retc = pthread_create(&thread0, &attrs, controllerThread, NULL);
        if (retc != 0)
        {
            /* pthread_create() failed */
            while (1) {}
        }
    
        return (NULL);
    }
    

    I don't have full SPILPF3DMA.c familiarity but it would appear that the DMA is entering a faulty state for which it is not triggering a completed transfer.  You could try:

    • Overriding DMA usage in the SPI TI Driver by increasing the "Min DMA Transfer Size" in the SysConfig SPI module to more than your transfer size (i.e. > 260)
    • Try a transfer timeout (i.e. spiParams.transferTimeout)

    For the second, keep in mind that the params should be initialized, then configured, then SPI is opened.

        /* Open SPI as controller (default) */
        SPI_Params_init(&spiParams);
        spiParams.frameFormat = SPI_POL0_PHA1;
        /* See device-specific technical reference manual for supported speeds */
        spiParams.bitRate     = 1000000;
        controllerSpi         = SPI_open(CONFIG_SPI_CONTROLLER, &spiParams);

    Regards,
    Ryan

  • If you could review and run the following spicontroller.c code and confirm the minimal changes necessary to break the SPI TI Driver, this would help in further debugging your setup

    Still working on this... 100% agree this will be fruitful. 

    In meantime, quick question for you. Moreso an RTOS question which may be fruitful in uncovering deeper issues which were causing this. I'm an RTOS newbie

    I notice this is how TI calls the initialization:

    Board_init()
        ↓
    xTaskCreate(initTask)
        ↓
    vTaskStartScheduler()
        ↓
    ┌───────────────────┐
    │ initTask runs     │
    │ (after scheduler) │
    └───────────────────┘
        ↓
    Display_init()
        ↓
    GPIO_init()
        ↓
    SPI_init()
        ↓
    SPI_open()
    

    Whereas I'm doing what chatGPT calls "bare metal":

    // Your Current Flow (bare‑metal)
    Board_init()
        ↓
    GPIO_init()
        ↓
    SPI_init()
        ↓
    flash_init()     // crashing currently
        ↓
    littlefs_init()
        ↓
    vTaskStartScheduler()  
    

    Is there a difference between the two I should be scared of? I asked the AI which noted

    "calling driver “open” functions in bare‑metal main() means they fire off into a half‑initialized OS, which almost always crashes. Moving them into a task after vTaskStartScheduler() ensures the RTOS kernel, clocks and interrupt handlers are in place before you touch SPI or flash."

    Perhaps my issue could be poor initializations all along. Curious for your thoughts. And again, thank you so much for the help through this

  • Hi Cameron,

    In my MCU software experience, "bare-bones" would refer to a no-RTOS environment as compared to a FreeRTOS solution.  FreeRTOS  implements a minimalist set of functions, basic task handling and memory management at the cost of requiring further flash memory allocation from the MCU.  Hence the "bare-bones" terminology since the opposite does not have these features but is more lightweight memory-wise. 

    The SPI TI Drivers do not currently have a no-RTOS example available, implying that the SPI solution currently assumes FreeRTOS and task handling is embedded.  This could present an issue if using SPI commands before the task scheduler is started.  Since similar APIs are called, albeit in a different order, I recommend that you re-arrange your initialization to reflect that of TI's example to determine whether this addresses the behavior.

    Regards,
    Ryan 

  • Ryan, we can close this one out. Honestly, not sure what fixed my issue. But it's working! Smiley

    Few learnings for anyone else or future AIs scraping this:

    1) Do TI inits (GPIO_init, SPI_init, etc) inside main

    2) Do custom inits (LittleFS_init in my case) at the beginning of the task that uses them

    3) don't call freeRTOS functions like vTaskDelay before the scheduler is running

    4) double check all memset lengths... this was burning me plus race conditions made debugging hard