This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Stuck waiting for UART event (pstorage)

I am developing firmware using S132 (SDK 11) for a custom board.

After performing Pstorage Update, if I do not wait for the callback from pstorage before continuing execution of firmware, then the firmware seems to stop executing for some reason which I did not manage to investigate yet. Pstorage has a queue of 50 operations. However I just use no more than 2 in sequence.

Do you have any suggestion on what the cause could be?

Thank you, Marco

ADDITIONAL INFO:

Erase/Load/Store operations work fine even without waiting for the callback function to be called.

When I use "Update", the code execution stops after the System Event callback execution:

acs.c:acs_update_flash:405: updating Flash with latest Accelerometer parameters...
acs.c:[UART message cut here by following line]
main.c:sys_evt_dispatch:278: SYSTEM EVENT #2
main.c:sys_evt_dispatch:287: count 1
main.c:sys_evt_dispatch:289: pstorage_sys_event_handler returned!
main.c:sys_evt_dispatch:278: SYSTEM EVENT #2
main.c:sys_evt_dispatch:287: count 1
main.c:sys_evt_dispatch:289: pstorage_sys_event_handler returned!
main.c:sys_evt_dispatch:278: SYSTEM EVENT #2
main.c:sys_evt_dispatch:287: count 1
main.c:sys_evt_dispatch:289: pstorage_sys_event_handler returned!
main.c:sys_evt_dispatch:278: SYSTEM EVENT #2
main.c:sys_evt_dispatch:287: count 1
main.c:sys_evt_dispatch:289: pstorage_sys_event_handler returned!
main.c:sys_evt_dispatch:278: SYSTEM EVENT #2
main.c:sys_evt_dispatch:287: count 1
acs.c:pstorage_ntf_cb:392: FLASH OPERATION DONE(Handle ID 0, Result 0, Data Size 8 B)! flash_op_cnt 0
main.c:sys_evt_dispatch:289: pstorage_sys_event_handler returned!

Function sys_evt_dispatch() has been registered with softdevice_sys_evt_handler_set(), and is defined as follow:

static void sys_evt_dispatch(uint32_t sys_evt)
{
    uint32_t err_code;
    uint32_t count;
    
    RMLOG("SYSTEM EVENT #%d", sys_evt);

    if ((sys_evt == NRF_EVT_FLASH_OPERATION_SUCCESS) || (sys_evt == NRF_EVT_FLASH_OPERATION_ERROR))
    {
		err_code = pstorage_access_status_get(&count);
		APP_ERROR_CHECK(err_code);

		if ((err_code == NRF_SUCCESS) && count) {
			RMLOG("count %u", count);
			pstorage_sys_event_handler(sys_evt);
			RMLOG("pstorage_sys_event_handler returned!");
		}    			     
    }
}

In theory, the system should then enter System Off mode and be woken up by detecting motion. But after the last UART message, nothing happens if I move the device. Thus, I guess it is stuck somewhere.

There is no Read-back lock/protection set.

UPDATES:

I have tried debugging the application, and what I can see is that the firmware gets stuck in following line in function simple_uart_put() (in simple_uart.c):

while (NRF_UART0->EVENTS_TXDRDY != 1) { // Wait for TXD data to be sent. }

Apparently I have been able to fix the issue. It seems that I was using too much the UART peripheral, while the nature of PStorage operations is asynchronous and the UART functions might be called on top of each other by main state machine and callback functions (I should probably remove UART communication in such functions). However by using the debugger I found out that the firmware was getting stuck waiting for the NRF_UART0->EVENTS_TXDRDY to switch to 0x1 in simple_uart_put(). This function was interrupted just after setting the char to transmit:

NRF_UART0->TXD = (uint8_t)cr;

The interrupt-handler/callback-function by using the UART themselves, have probably stopped all transmission (triggering STOPTX task). Thus, as a workaround I have modified the function as follow:

void simple_uart_put(uint8_t cr)
{
    NRF_UART0->TXD = (uint8_t)cr;

    while (NRF_UART0->EVENTS_TXDRDY != 1)
    {
        // Wait for TXD data to be sent.
    	if (NRF_UART0->TASKS_STARTTX != 1)
    	{
    		NRF_UART0->TASKS_STARTTX = 1;
    		NRF_UART0->TXD = (uint8_t)cr;
    	}
    }

    NRF_UART0->EVENTS_TXDRDY = 0;
}

Can anyone advise me if for any reason this solution might generate other side effects? In my case, it solve the issue and does not seem to generate problems.

Cheers, Marco

  • Actually the previous solution generated the issue that often some letters were repeated twice in a row (even in situations when there was no problem in transmitting before). By doing additional tests, I came up with the following updated code:

    void simple_uart_put(uint8_t cr)
    {
    	int loop_cnt = 0;
        NRF_UART0->TXD = (uint8_t)cr;
    
        while (NRF_UART0->EVENTS_TXDRDY != 1)
        {
            // Wait for TXD data to be sent.
    
        	if (loop_cnt++ > 1000)
    		{
    			if(NRF_UART0->EVENTS_ERROR)
    			{
    				if ((NRF_UART0->TASKS_STARTTX != 1) && (NRF_UART0->TASKS_SUSPEND != 1))
    				{
    					NRF_UART0->TASKS_STARTTX = 1;
    					return;
    				}
    			}    
    			loop_cnt = 0;
    		}
        }
    
        NRF_UART0->EVENTS_TXDRDY = 0;
    }
    
Related