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: not writing to flash during received too much data via uart

Part Number: CC1312R

Hello, I have a CC1312 connected to BeagleBone. BeagleBone sends command to the CC1312 via UART. Everything works fine, but in case of sending too much commands (in short time) which writes to flash of the CC1312, the CC1312 resets and in its flash are wrong data. It happens when CC1312 is on the radio receiving. Unfortunately I cannot you send the whole program, but it looks like following:

// I use UART2_Mode_CALLBACK;
    void readCallbackUart(UART2_Handle handle, void *buf, size_t count,
                          void *userArg, int_fast16_t status)
    {
        device.isUartRead = status == UART2_STATUS_SUCCESS ? 1 : 0;
        // I tried to add following but it did not help
        if (status != UART2_STATUS_SUCCESS)
        {
            UART2_flushRx(uartHandle);
        }
    }

    // radio receiving and uart processing
    RF_postCmd(rfHandle, (RF_Op *)&RF_cmdPropRx, RF_PriorityNormal,
               radioCallback,
               RF_EventRxEntryDone);
    while (((volatile RF_Op *)&RF_cmdPropRx)->status < 4)
    {
        if (device.isUartRead)
        {

            // here is called a function performing writing to flash
            // it uses two region, one si a mirror to allow change only some without
            // having the whole region in ram hence there are commands NVS_erase
            // and NVS_write
            // after processing the command ACK via uart is sent
            
            device.isUartRead = 0;
            UART2_read(uartHandle, &uartBuffer, sizeof(uartBuffer), NULL);
        }
    }
    
    // radio callback
    void radioCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
        if (e & RF_EventRxEntryDone)
        {
            memcpy(rxPacket, (uint8_t *)&currentDataEntry->data,
                   (*(uint8_t *)(&(currentDataEntry->data))) + NUM_APPENDED_BYTES);

            RFQueue_nextEntry();
            // I added following, it helped but only a bit
            if (device.isUartRead)
            {
                return;
            }
            
            processData();// processing the received data
        }
    }

I guess it happens due to the uart input buffer is full and it causes reset of device (at that time probably a flash erase/write is performing) but I am not sure. Anyway how should I easily avoid to receive any other data to uart input buffer till I process the current uart data?

  • Hi user,

    I think this is where hardware flow control would be useful, if it is not already done!

    Do you have a way to enable it on both sides? That way, your CC1312R would let the Beaglebone know when it is actually ready to handle more data.

    Regards,

    Arthur

  • unfortunately the HW design is done. I use only tx and rx signals. Except this, everything works reliable. This case (sending too many commands) would never happen, it would happen only if the BeagleBone is in a paricular fault loop. but even that I would be glad to fix it... are there any other possibilities?

  • which writes to flash of the CC1312, the CC1312 resets

    - Why does CC1312R reset? Do you have a watchdog enabled that cause the reset?

    - Since you see this when you get "too much data" I would suspect that the program timing prevent the incoming data to be processed in timely manner and you start to write data outside the area you have allocated which will cause flash data to be corrupted. 

  • Yes, I have enabled the watchdog and the reset is probably caused by watchdog.

    Which data do you mean "start to write data outside"? I write to flash always to the same parts there is not a problem, there are used constants so there cannot be a problem. But if you mean the uart data, it is very possible that data are written after previous uart data and there is an overflow.. But the question is how to avoid saving other uart data after I receive the first uart data...

  • "start to write data outside"

    Bad wording from my side. What I was thinking about is memory allocation etc. Simplified, if you have set the memory to store 5 bytes and you get 8, then you can risk that the last 3 end up a random place or in worst case where the next instruction is collected from which will cause a crash. 

    But I would start looking for the cause of the reset. Is it the watchdog and if that is the case, which thread hangs and causing a reset? I would assume that it's possible to rewrite the code some to better handle the incoming data. 

  • Thank you for the explanation. But I do not think so there is a problem with memory allocation. I use all the time the same buffers. And if there is "normal" uart communication, there is no any problem. U use NORTOS, so I have only 1 thread. How can I find out the reason of the reset? And the main problem is not the reset of device, but that my configuration data in flash are erased. The program probably stop working between flash erase and flash write. Please could you answer this question: Is it possible somehow recognize if the uart input buffer is full, and what is a behaviour if it is full? Is it possible to ignore other incoming data till I process the current data?

  • Hi user,

    To answer your question. It is indeed possible to do in hardware, using the "OE" flag (section 21.7.1.1 of the Technical Reference manual).

    What you want to do is to subscribe to the UART2_EVENT_OVERRUN event , and disable RX when such an event occurs, at least temporarly.

    In order to do so, configure your UART2_Params instance with the following settings:

    • uartParams.eventCallback = <your callback function, where you will disable RX using UART2_rxDisable>
    • uartParams.eventMask = UART2_EVENT_OVERRUN

    Regards,

    Arthur

  • Thank you,

    actually I did what you mention several minutes ago :-) except I call the flushUart function in the callback. How to temporarily disable uart and later enable it?

  • What you want to do is to use UART2_rxDisable in conjunction with flushUart, and reenable it using UART2_txEnable some time in the future, with a timer callback, for instance.

    Let me know how that worked,

    Regards,

    Arthur

  • Unfortunately, it has not helped.

  • Hi,

    Can you be more specific, you mean that you are still loosing your flash data although UART is disabled? Or is the chip still resetting when receiving lots of data?

    Do you ever get to the callback of the UART overrun event?

    Regards,

    Arthur

  • Hi,

    I mean exact the same behaviour. It is reseted by watch dog and after that the flash data(only in region which I edit via NVS functions) has default (0xFF) values, but sometimes it is not fully erased and amount is also changing I guess it depends when the freeze occurs.

    Do you ever get to the callback of the UART overrun event?

    Yes, I tried to put there breakpoint and it goes in there...