Zephyre BLE UART example reads wrong bytes ( Adafuit Feather nRF52840 )

I am receiving bytes from a GPS module and passing them to BLE UART example app configured to use UARTE1 and asynchronous API.

After few minutes of running it starts leaking memory by not releasing RX buffers. Using RTT messages I identified it correspond to non-standard bytes. Especially often to 0x0092 and few others.

The uart_cb function in main.c was modified for debugging:

case UART_RX_RDY:
		LOG_INF("UART_RX_RDY");
		buf = CONTAINER_OF(evt->data.rx.buf, struct uart_data_t, data[0]);
		buf->len += evt->data.rx.len;
		LOG_INF("UART buf len %u", buf->len);
		LOG_INF("UART evt->data.rx.len %u", evt->data.rx.len);
		if (disable_req) {
			return;
		}
		//DEBUG stuff
		#ifdef DEBUGCOMP
		if (buf->len < (DEBUG_CHAR_LEN -1)){
			memcpy(debugchars, evt->data.rx.buf, buf->len);
			debugchars[buf->len]=0;
			LOG_INF("data.rx.buf: %s \n^^", debugchars);
		}
		#endif

		if ((evt->data.rx.buf[buf->len - 1] == '\n') ||
		    (evt->data.rx.buf[buf->len - 1] == '\r') ||
			(evt->data.rx.buf[buf->len - 1] == 0x0a)) {
				#ifdef DEBUGCOMP
					LOG_INF("running uart_rx_disable(uarte);");
				#endif
			disable_req = true;
			uart_rx_disable(uarte);
		}
		#ifdef DEBUGCOMP
			if (evt->data.rx.buf[buf->len - 1] == 0x0a) {
				LOG_INF("UART_RX last symbol LF");
			}
		#endif

		break;

To rule out noise issues I recorded the signal with an oscilloscope

As you can see, there is no non-display symbols. And there is no noise.

Where should I focus on?

Parents Reply Children
  • Hello,
    HWFC was disabled.

    UART1 related nodes:

      uart1: uart@40028000 {
       compatible = "nordic,nrf-uarte";
       reg = <0x40028000 0x1000>;
       interrupts = <40 1>;
       status = "disabled";
      };
    
    uart1_default: uart1_default {
        group1 {
        psels = <((((((0) * 32U) + (2)) & 0x1FFU) << 0U) | ((0U & 0x7FFFU) << 17U))>,
        <((((((0) * 32U) + (3)) & 0x1FFU) << 0U) | ((1U & 0x7FFFU) << 17U))>;
        };
    };
    
    uart1_sleep: uart1_sleep {
     group1 {
     psels = <((((((0) * 32U) + (2)) & 0x1FFU) << 0U) | ((0U & 0x7FFFU) << 17U))>,
     <((((((0) * 32U) + (3)) & 0x1FFU) << 0U) | ((1U & 0x7FFFU) << 17U))>;
     low-power-enable;
     };
    };
    
    &uart1 {
            compatible = "nordic,nrf-uarte";
            current-speed = <115200>;
            status = "okay";
            pinctrl-0 = <&uart1_default>;
            pinctrl-1 = <&uart1_sleep>;
            pinctrl-names = "default", "sleep";
    };
    
    chosen {
      nordic,nus-uarte = &uart1;
    };
    
    

    The device:

    static const struct device *uarte = DEVICE_DT_GET(DT_CHOSEN(nordic_nus_uarte));

    I suspect it is a memory leak as I track number of calls for

    k_malloc(sizeof(*buf)); // if (buf)

    k_free(buf); // appears twice in the code

    Difference between them should be number of buffers in use. The number of buffers in use rises to about 30 and after that the MCU starts calling: LOG_WRN("Not able to allocate UART receive buffer");

  • Looks like it is a hardware problem on the GPS module side

    Will try to figure out how to handle it

  • A couple suggestions:

    • As Susheel alreadt suggested, enable HWFC
    • Check the supply voltage of the GPS module and make sure it matches the operating conditions of the module's specifications.

    Best regards,

    Simon

Related