nRF52 UART Lock Up in NCS Connect

We are seeing an issue where we are connecting to an LTE/GPS chip via interrupt UART. Things work great until have an irregular amount of time, communication to the LTE chip is no longer possible. If we remove power from the LTE chip and then power it back up, we still are unable to communicate. The only thing that resolves the issue is to restart the nRF52.

Any thoughts on what we can do to reset the UART?

  • From what I can see, it is RX that is the problem, not TX. 

  • Hello!

    Things work great until have an irregular amount of time

    Can you please expand on what you mean by this?

    NautDesigner said:
    From what I can see, it is RX that is the problem, not TX

    Can you also explain how you came to this conclusion?

    Best regards,

    Einar

  • Ongoing communication with the modem is fine for 30 minutes to several hours of constant communication. And it is just repeating the same sequence over and over.

    Based on the lights, we thought it may have been received TX commands, but that may not be the case. It could just be that we are turning if off, turning it back on again to try and get the UART to sync up again.

  • Sounds like it would be a good idea to activate more logging to investigate what goes wrong.

    It would be easier to debug this if you had a specific error message to work with.

    Also, what UART driver/API are you using?

    -Einar

  • Interrupt driven UARTE. Nothing to log. Just send data and nothing returns.

    static void uart_irq_handler(const struct device *dev)
    {
    int read = 0;
    
    	uart_irq_update(dev);
    
    	if (uart_irq_rx_ready(dev)) {
          struct rx_uart_data_t *buf = k_malloc(sizeof(struct rx_uart_data_t));
    		read = uart_fifo_read(dev, buf->data, RX_BUF_SIZE);
    
    	   k_fifo_put(&rx_fifo, buf);
    
    	}
    
    	if (uart_irq_tx_ready(dev)) {
    		struct tx_uart_data_t *buf = k_fifo_get(&tx_fifo, K_NO_WAIT);
          if (!buf) {
             uart_irq_tx_disable(dev);
             return;
          }
    
    	   uart_fifo_fill(dev, buf->data, buf->len);
    
          while (!uart_irq_tx_complete(dev)) {
    			/* Wait for the last byte to get
    			 * shifted out of the module
    			 */
    		}
          if (k_fifo_is_empty(&tx_fifo)) 
    		   uart_irq_tx_disable(dev);
          k_free(buf);
    
    	}
    }
    
    static void interrupt_driven(const struct device *dev)
    {
    	uart_irq_callback_set(dev, uart_irq_handler);
    	uart_irq_rx_enable(dev);
    }
    
    void initUart() {
       uart = device_get_binding("UART_1");
        //uart = device_get_binding("LPUART");
    	__ASSERT(uart, "Failed to get UART device");
    	interrupt_driven(uart);
    }
    
    void enableUART() {
       pm_device_action_run(uart, PM_DEVICE_ACTION_RESUME);
    }
    
    void disableUART() {
       if (!device_is_ready(uart)) {
    		return;
    	}
    
       pm_device_action_run(uart, PM_DEVICE_ACTION_SUSPEND);
    }

Related