This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Zephyr UART on Fanstel BLG840F

I am using UART on the Fanstel BLG840F to communicate from the 9160 to the 52840.  So far I have successfully been able to communicate from the 52840 to the 9160 but have not been able to send UART messages back from the 9160 to the 52840.  I am using shared UART functions between the boards with a single function to handle sending:

int uart_send(struct uart_data_t *uart_data)
{
    int status = uart_tx(device_uart, uart_data->data, uart_data->length, SYS_FOREVER_MS);

    if (status != 0)
    {
        printk("uart_tx ( error: %d )\n", status);

        // Add to tx queue to try and process / send later ...
        k_fifo_put(&fifo_uart_tx_data, uart_data);
    }
    printk("data sent: %s \n", uart_data);

    return status;
}

and a registered event handler:

static void on_uart_event(const struct device *dev, struct uart_event *evt, void *user_data)
{
    struct uart_data_t *uart_data;
    static uint8_t *aborted_buf;
    static size_t aborted_len;

    switch (evt->type)
    {
    //put this in ifdef block
    
    case UART_RX_RDY:
    {
        printk("UART_RX_RDY\n");

        uart_data = CONTAINER_OF(evt->data.rx.buf, struct uart_data_t, data); // where does third parameter data come from?

        printk("uart_rx called with data: %s", uart_data->data);
       

        hive_uart_queue_rx_data_buffer(uart_data);

        uart_rx_disable(device_uart); 

        break;
    }
    
    case UART_RX_DISABLED:
    {
        printk("UART_RX_DISABLED\n");

        start_receiving();

        break;
    }
    case UART_RX_BUF_REQUEST:
    {
        printk("UART_RX_BUF_REQUEST\n");

        struct uart_data_t *uart_data = hive_uart_allocate_data_buffer();

        if (uart_data == NULL)
        {
            break;
        }

        uart_rx_buf_rsp(device_uart, uart_data->data, sizeof(uart_data->data));

        break;
    }
    case UART_RX_BUF_RELEASED:
    {
        printk("UART_RX_BUF_RELEASED\n");

        uart_data = CONTAINER_OF(evt->data.rx_buf.buf, struct uart_data_t, data);

        k_free(uart_data);

        break;
    }
    case UART_TX_DONE:
    {
        printk("UART_TX_DONE\n");

        if ((evt->data.tx.len == 0) || (!evt->data.tx.buf))
        {
            return;
        }

        if (aborted_buf)
        {
            uart_data = CONTAINER_OF(aborted_buf, struct uart_data_t, data);
            aborted_buf = NULL;
            aborted_len = 0;
        }
        else
        {
            uart_data = CONTAINER_OF(evt->data.tx.buf, struct uart_data_t, data);
        }

        k_free(uart_data);

        // See if there's anything waiting in the queue ...
        uart_data = k_fifo_get(&fifo_uart_tx_data, K_NO_WAIT);

        if (!uart_data)
        {
            return;
        }

        if (uart_tx(device_uart, uart_data->data, uart_data->length, SYS_FOREVER_MS))
        {
            printk("(UART_TX_DONE) Failed to send data over UART\n");

            // Add back to queue to try again ...
            k_fifo_put(&fifo_uart_tx_data, uart_data);
        }

        break;
    }
    case UART_TX_ABORTED:
    {
        if (!aborted_buf)
        {
            aborted_buf = (uint8_t *)evt->data.tx.buf;
        }

        aborted_len += evt->data.tx.len;

        uart_data = CONTAINER_OF(aborted_buf, struct uart_data_t, data);

        if (uart_tx(device_uart, &uart_data->data[aborted_len], uart_data->length - aborted_len, SYS_FOREVER_MS))
        {
            printk("(UART_TX_ABORTED) Failed to send data over UART\n");

            // Add to queue to try again later ...
            k_fifo_put(&fifo_uart_tx_data, uart_data);
        }

        break;
    }
    default:
    {
        printk("UART event received: %d\n", evt->type);
        break;
    }
    }
}

Calling the UART send function on the 52840 triggers the UART_RX_RDY case correctly on the 9160, but calling the UART send function on the 9160 does not trigger the UART_RX_RDY on the 52840.  Does each board need a separate event handler and separate UART function or can they be shared in this way and I have setup something on the 9160 side incorrectly?

Thanks

  • Hi Jake,

    Thank you for the request. Just letting you know I have starting to look into this. I will get back to you tomorrow or the day after.

    Best regards,

    Håkon

  • Just wanted to update with some tests I ran.  I also realized I didn't post the entire uart event handler in the first post and have since updated it (the second code block in the original post):

    I verified that on the 9160 the data and length are being read correctly and the uart_tx function is returning 0, so the send seems to be functioning correctly.

    On the 52840 side it seems that the event handler registered using uart_callback_set is not being called even tho the uart_tx is sending without error.  I know the pins are configured correctly too since it works as expected sending from the 52840 to the 9160.

  • Hi Jake

    Håkon is currently unavailable, and I will handle the case instead. 

    Have you checked with a scope or logic analyzer whether or not the data is actually sent over the bus, from the 9160 to the 52840?

    Do you know if flow control is used or not?

    Best regards
    Torbjørn

  • I'm using the Fanstel BLG840X and I don't think I can access the UART pins for communicating between the boards can I?  I don't see anything on the board that I could easily probe unless there is another way.

  • Hi Jake

    I guess you are right, if the module is encased it would be hard to get access to these pins, unless you break it apart. 

    Would you happen to have a nRF9160DK available that you can test with, or the DK from Fanstel shown in their user guide?

    Best regards
    Torbjørn

Related