nRF52832 Bluetooth peripheral_uart sample: use RX data and not sent to BLE

I want to intercept some data in the RX (in section UART_RX_READY in uart_cb() as a command with arguments.  And I do not want this data to be sent on the the BLE.

After I get the data that I want, what should I do with the buf, so the process continues getting new data from the UART RX?

Do I just k_free(buf)?  Or something else?

  • Hello again,

    BradEA said:
    Is this how the Rx works?

    Almost, with a few amendments:

    BradEA said:
    uart causes interrupt for every byte it receives

    Not quite - it causes an interrupt for every tranfer it received. The transfer might be longer than 1 byte.
    You can test this by sending multiple characters from your serial terminal at once.

    BradEA said:
    data is in evt->data.rx.buf, len is in evt->rx.len (always 1?)

    No, because the length of the transfer could be longer than 1.

    BradEA said:
    interrupt causes evt of type UART_RX_RDY via notify_rx_buffer()?

    This depends on whether the UART driver is operating in asynchronous mode or not, but yes.

    BradEA said:
    not sure what all goes on, but I presume we end up in uart_cb() again at UART_RX_BUF_RELEASED

    The new buffer is actually set as part of the handling for the UART_RX_DISABLED event, which is generated at the end of the UART_RX_RDY event.
    A new buffer can also be made as part of the UART_RX_BUF_REQUEST event handling, if required.

    BradEA said:
    here the len can be no longer than what bt_nus_get_mtu() returns

    The len can be longer than the MTU size - this will make the data be split and transferred over multiple packets. The SoftDevice Controller will handle this for you. The UART buffer is however set to be the same as the NUS buffer - UART_BUF_SIZE, so you can not exceed that.

    BradEA said:
    UART_RX_DISABLED 
    UART_RX_BUF_REQUEST

    UART_RX_DISABLED is raised at the end of the UART_RX_RDY event handling.
    UART_RX_BUF_REQUEST is used to request a new buffer, you can see how it is used by going into the uart_nrfx_uart.c source code's rx_isr function.

    BradEA said:
    Where is the size of these buffers determined?

    They are defined at the beginning of main.c in this case.

    BradEA said:
    What process controls the RTS line for the uart's rx buffer?

    If enabled then the UART peripheral itself will control this. It is the CTS (clear to send) that is related to the RX buffer on the receiving device.

    Best regards,
    Karl

  • RTS line control:  Is this not the uart's output line that when high signals the sender that the uart cannot receive any more characters on its RX line?

    CTS line: uart input indicating the uart may send characters out TX line when low?  All the code I've looked at has the CTS line as an input with an optional pullup.

    So my question regarding the RTS line: what actually controls the state of the RTS line?

    You indicated that this sample uses "uart_nrfx_uart.c", How should the uart be defined in prj.conf:

    CONFIG_NRFX_UART0=y  or

    CONFIG_NRFX_UARTE0=y?

    AND  CONFIG_BT_NUS_UART_ASYNC_ADAPTER=y?

    Would it be appropriate to send the project so you can see what I may have messed up?  When I send a long string of characters (54 long), I get this: (I added the BufLen and Ble_Mtu_size printouts)

    It dropped some chars and nothing shows up on the tablet.

    12345678901234567890123456789012345678901234567890FEFF[00:04:27.464,508] <inf> peripheral_uart: BufLen: 1, Ble_Mtu_size: 20
    --- 4 messages dropped ---
    [00:04:27.465,179] <inf> peripheral_uart: BufLen: 8, Ble_Mtu_size: 20
    [00:04:27.465,301] <inf> peripheral_uart: BufLen: 10, Ble_Mtu_size: 20
    [00:04:27.465,423] <inf> peripheral_uart: BufLen: 11, Ble_Mtu_size: 20
    [00:04:27.465,545] <inf> peripheral_uart: BufLen: 13, Ble_Mtu_size: 20
    [00:04:27.465,667] <inf> peripheral_uart: BufLen: 14, Ble_Mtu_size: 20
    [00:04:27.465,789] <inf> peripheral_uart: BufLen: 15, Ble_Mtu_size: 20
    [00:04:27.465,911] <inf> peripheral_uart: BufLen: 16, Ble_Mtu_size: 20
    [00:04:27.466,033] <inf> peripheral_uart: BufLen: 17, Ble_Mtu_size: 20
    [00:04:27.466,156] <inf> peripheral_uart: BufLen: 19, Ble_Mtu_size: 20
    [00:04:27.466,278] <inf> peripheral_uart: BufLen: 20, Ble_Mtu_size: 20
    [00:04:27.466,949] <wrn> bt_att: No ATT channel for MTU 31
    [00:04:27.466,979] <wrn> bt_gatt: No buffer available to send notification
    [00:04:27.467,041] <wrn> peripheral_uart: Failed to send data over BLE connection
    [00:04:27.467,163] <inf> peripheral_uart: BufLen: 2, Ble_Mtu_size: 20
    [00:04:27.467,285] <inf> peripheral_uart: BufLen: 3, Ble_Mtu_size: 20
    [00:04:27.467,437] <inf> peripheral_uart: BufLen: 5, Ble_Mtu_size: 20
    [00:04:27.467,559] <inf> peripheral_uart: BufLen: 6, Ble_Mtu_size: 20
    [00:04:27.467,681] <inf> peripheral_uart: BufLen: 7, Ble_Mtu_size: 20
    [00:04:27.467,803] <inf> peripheral_uart: BufLen: 9, Ble_Mtu_size: 20
    [00:04:27.467,926] <inf> peripheral_uart: BufLen: 10, Ble_Mtu_size: 20
    [00:04:27.468,048] <inf> peripheral_uart: BufLen: 12, Ble_Mtu_size: 20
    [00:04:27.468,170] <inf> peripheral_uart: BufLen: 13, Ble_Mtu_size: 20
    [00:04:27.468,292] <inf> peripheral_uart: BufLen: 14, Ble_Mtu_size: 20
    [00:04:27.468,414] <inf> peripheral_uart: BufLen: 16, Ble_Mtu_size: 20
    [00:04:27.468,536] <inf> peripheral_uart: BufLen: 17, Ble_Mtu_size: 20
    [00:04:27.468,658] <inf> peripheral_uart: BufLen: 19, Ble_Mtu_size: 20
    [00:04:27.468,780] <inf> peripheral_uart: BufLen: 20, Ble_Mtu_size: 20
    [00:04:27.469,482] <wrn> bt_att: No ATT channel for MTU 28
    [00:04:27.469,482] <wrn> bt_gatt: No buffer available to send notification
    [00:04:27.469,512] <wrn> peripheral_uart: Failed to send data over BLE connection

  • BradEA said:
    here the len can be no longer than what bt_nus_get_mtu() returns

    Karl said:

    The len can be longer than the MTU size - this will make the data be split and transferred over multiple packets. The SoftDevice Controller will handle this for you. The UART buffer is however set to be the same as the NUS buffer - UART_BUF_SIZE, so you can not exceed that.

    Brad discovered:

    With the UART_BUF_SIZE = 40, I get a message for a string of 21 characters while the MTU = 20:

    [04:49:58.773,773] <wrn> bt_att: No ATT channel for MTU 24
    [04:49:58.773,803] <wrn> bt_gatt: No buffer available to send notification
    [04:49:58.773,864] <wrn> peripheral_uart: Failed to send data over BLE connection

    And nothing goes to the receiving tablet.  So it appears that this sample "peripheral_uart" will not handle long strings, even when less than the buffer size.

  • Hello again,

    BradEA said:

    RTS line control:  Is this not the uart's output line that when high signals the sender that the uart cannot receive any more characters on its RX line?

    CTS line: uart input indicating the uart may send characters out TX line when low?

    They will be cross connected between the two UARTs, so one side's RTS (Request to send) is connected to the other device's CTS (Cleared to send).

    BradEA said:
    So my question regarding the RTS line: what actually controls the state of the RTS line?

    If you have enabled hardware flow control then you will not have to manually control this, the peripheral will take handle this for you, please see the transmission and reception sections of the UART documentation for more information about this.

    BradEA said:

    You indicated that this sample uses "uart_nrfx_uart.c", How should the uart be defined in prj.conf:

    CONFIG_NRFX_UART0=y  or

    CONFIG_NRFX_UARTE0=y?

    This depends on how you intend to use it - the difference between UART and UARTE is that the UARTE uses easyDMA, you can read more about this here. The BLE NUS example uses easyDMA for its uart, which is why it uses the UARTE, as you can see in its prj.conf.

    BradEA said:
    With the UART_BUF_SIZE = 40, I get a message for a string of 21 characters while the MTU = 20:

    What do you mean when you say that you get a message for a string of 21 characters while the MTU size is 20? I am not sure that I understand what you mean by this.

    Best regards,
    Karl

  • For the Peripheral_Uart sample with no changes, UART_BUF_SIZE = 40, and the MTU size = 20 (value returned by bt_nus_get_mtu() when connected to a BT device, the Tablet).  If I send a string of 20 characters ("1234567890123456789\r") from the terminal connected to the nRF52832's uart, this string is sent to the connected Bluetooth device (e.g., a Tablet running nRF Connect), and no problem.

    If I send a string with 21 characters ("12345678901234567890\r"), I get the warning messages on the terminal:

    [04:49:58.773,773] <wrn> bt_att: No ATT channel for MTU 24
    [04:49:58.773,803] <wrn> bt_gatt: No buffer available to send notification
    [04:49:58.773,864] <wrn> peripheral_uart: Failed to send data over BLE connection

    and no data is sent to the tablet.

Related