zhangbo
2024-11-01 f8013e4f432b323dfc3e3725a62858e73176742a
keil/include/components/app/src/uwb_data_transfer.c
@@ -43,10 +43,44 @@
#include "mk_aes.h"
#include "mk_power.h"
#include "wsf_buf.h"
#include "lib_aoa.h"
#include "lib_ranging.h"
#include "uwb_data_transfer.h"
#include "uwb_data.h"
#if ((UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0) || (UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_1) || \
     (UWB_DATA_TRANSFER_MODE == DATA_TRANSFER_TEST_MODE))
#if UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0
// Serial port receives characters.
static uint8_t ch;
#endif
#if ((UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0) || (UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_1))
#define SERIAL_NUM UART_ID0
// Serial TX Data Buffer
static uint8_t serial_tx_msg[MDSDU_MTU_MAX * UWB_SERIAL_DATA_POOL_SIZE];
// Serial RX Data Buffer
static uint8_t serial_rx_msg[MDSDU_MTU_MAX * UWB_SERIAL_DATA_POOL_SIZE];
#endif
// Serial TX/RX Data Buffer Memory management functions
static void initMemoryPool(MemoryPool *pool, uint8_t *data);
static void updateMemory_allocate_block(MemoryPool *pool, MemoryBlock *block);
static void *allocateMemory(MemoryPool *pool, uint16_t size);
static bool mergeFreeBlocks(MemoryPool *pool, uint8_t *prt, uint16_t length);
static bool freeMemoryPool(MemoryPool *pool, MemoryBlock *block);
static MemoryPool g_tx_pool;
static MemoryPool g_rx_pool;
static bool block_send_flag = false;
#endif // UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0 or SERIAL_DATA_TRANSFER_MODE_1 or DATA_TRANSFER_TEST_MODE
struct RANGING_ENV_T ranging_env;
uint8_t fira_uwb_tx_buf[PHY_PAYLOAD_LEN_MAX];
@@ -63,6 +97,8 @@
    .session_responder_list_clr = ranging_responder_list_clr,
    .session_responder_num_get = ranging_responder_num_get,
    .session_responder_addr_get = ranging_responder_addr_get,
    .session_initiator_addr_set = ranging_initiator_addr_set,
    .session_controller_addr_set = ranging_controller_addr_set,
    .session_dynamic_update_responder_list = NULL,
    .session_set_ccc_ursk = NULL,
    .vendor_session_configure = NULL,
@@ -188,7 +224,20 @@
    LOG_INFO(TRACE_MODULE_FIRA, "Ranging stop\r\n");
}
#if 0
uint16_t data_transfer_send(uint8_t *data, uint16_t length)
{
    struct DM_MDSDU_T mdsdu_tx;
    uint16_t status = 0;
    mdsdu_tx.mac_addr = ranging_responder_addr_get(0);
    mdsdu_tx.len = length;
    mdsdu_tx.data = data;
    mdsdu_tx.ready = 1;
    status = uwb_dm_tx_pkt(&mdsdu_tx);
    return status;
}
#if 1
/*
bitmap for 1 responder
slot idx:  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 ...
@@ -287,34 +336,32 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-qual"
#endif
uint16_t uwb_pkt_rx_done_ind(const struct MAC_HW_REPORT_T *rx, enum RANGING_STAGE_T stage, uint8_t slot_idx)
{
    // send an indication to application
#if DM_PRINT_PAYLOAD_EN
    struct UWB_PKT_RX_DONE_IND_T *ind = WsfMsgAlloc(sizeof(struct UWB_PKT_RX_DONE_IND_T) + rx->pkt_len);
#else
    struct UWB_PKT_RX_DONE_IND_T *ind = WsfMsgAlloc(sizeof(struct UWB_PKT_RX_DONE_IND_T));
#endif
    if (ind != NULL)
    {
        ind->hdr.event = UWB_PKT_RX_DONE_MSG;
        ind->ranging_stage = (uint8_t)stage;
        ind->slot_idx = slot_idx;
        ind->status = rx->err_code;
        ind->rssi = rx->rssi;
        ind->snr = rx->snr;
        // ind->rssi = rx->rssi;
        ind->rssi = correct_rssi(rx->rssi);
        ind->snr = correct_snr(rx->snr);
        if (rx->err_code == UWB_RX_OK)
        {
#if 1
            ind->rx_len = rx->pkt_len;
#if DM_PRINT_PAYLOAD_EN
            if ((ind->rx_len) && (rx->pkt_data != NULL))
            {
                memcpy(ind->rx_data, rx->pkt_data, rx->pkt_len);
            }
#endif
#else
            // Decrypt packet
            ind->rx_len = fira_packet_decrypt(rx->pkt_data, ind->rx_data, rx->pkt_len, slot_idx);
@@ -374,154 +421,532 @@
    session_fsm(rx_report);
}
#if UWB_SERIAL_DATA_TRANSFER_EN
#if ((UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0) || (UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_1) || \
     (UWB_DATA_TRANSFER_MODE == DATA_TRANSFER_TEST_MODE))
#if UWB_DATA_TRANSFER_MODE == 1
static uint8_t pkt_header_buff[2];
static uint8_t data_buff[SERIAL_MESSAGE_MAX_LEN];
#endif
static struct RING_BUFFER_T tx_cb;
static struct RING_BUFFER_T rx_cb;
/****************************************************************************
 * Private Functions
 ****************************************************************************/
static void uwb_serial_cb_init(struct RING_BUFFER_T *tx, struct RING_BUFFER_T *rx)
/*****************************************************************************/
#ifdef MEMORY_DEBUG
void memory_check(void)
{
    for (int i = 0; i < UWB_SERIAL_DATA_POOL_SIZE; i++)
#if 0
   MemoryBlock *current_free = g_tx_pool.free;
   int i = 0;
   while(current_free != NULL)
   {
      LOG_INFO(TRACE_MODULE_APP, "free block[%d] start%p, end %p size %d\r\n", i, (void*)current_free->start,(void*)(current_free->start+current_free->size), current_free->size);
      i++;
      current_free = current_free->next;
   }
   i = 0;
   MemoryBlock *current_allocate = g_tx_pool.allocated;
   while(current_allocate != NULL)
   {
      LOG_INFO(TRACE_MODULE_APP, "allocate block[%d] start %p, end %p size %d free %d\r\n", i, (void*)current_allocate->start,(void*)(current_allocate->start+current_allocate->size), current_allocate->size, current_allocate->is_free);
      i++;
      current_allocate = current_allocate->next;
   }
#endif
    MemoryBlock *current_free = g_tx_pool.free;
    int i = 0;
    while (current_free != NULL)
    {
        tx->buffer[i].flag = true;
        rx->buffer[i].flag = true;
        i++;
        current_free = current_free->next;
    }
    tx->head = 0;
    tx->tail = 0;
    tx->check = 0;
    LOG_INFO(TRACE_MODULE_APP, "free block[%d]\r\n", i);
    rx->head = 0;
    rx->tail = 0;
    rx->check = 0;
    i = 0;
    MemoryBlock *current_allocate = g_tx_pool.allocated;
    MemoryBlock *tail = NULL;
    while (current_allocate != NULL)
    {
        i++;
        tail = current_allocate;
        current_allocate = current_allocate->next;
    }
    if (tail != g_tx_pool.allocated->tail)
    {
        LOG_INFO(TRACE_MODULE_APP, "tail != g_tx_pool.allocated->tail\r\n");
    }
    LOG_INFO(TRACE_MODULE_APP, "allocate block[%d]\r\n", i);
    return;
}
#endif
#if ((UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0) || (UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_1) || \
     (UWB_DATA_TRANSFER_MODE == DATA_TRANSFER_TEST_MODE))
/****************************************************************************
 * Name: initMemoryPool
 *
 * Description: Initialize the UWB receive/transmit Circular Buffer.
 *
 * Input Parameters:
 *    pool -
 *    data -
 *
 * Returned Value:
 *    NULL
 *
 ****************************************************************************/
static void initMemoryPool(MemoryPool *pool, uint8_t *data)
{
    if (data == NULL || pool == NULL)
    {
        return;
    }
    LOG_INFO(TRACE_MODULE_APP, "Init Memory POOL 0x%p\r\n", (void *)data);
    pool->memoryPool = data;
    pool->allocated = NULL;
    pool->free = (MemoryBlock *)WsfBufAlloc(sizeof(MemoryBlock));
    if (pool->free == NULL)
    {
        WsfBufFree(pool);
        pool = NULL;
        return;
    }
    pool->free->start = pool->memoryPool;
    pool->free->size = MDSDU_MTU_MAX * UWB_SERIAL_DATA_POOL_SIZE;
    pool->free->is_free = 1;
    pool->free->next = NULL;
    pool->free->prev = NULL;
    pool->free->tail = pool->free;
    return;
}
static bool uwb_serial_cb_is_full(struct RING_BUFFER_T *cb)
/****************************************************************************
 * Name: updateMemory_allocate_block
 *
 * Description: Add allocated memory to the memory management chain table
 *
 * Input Parameters:
 *    pool  -
 *    block -
 *
 * Returned Value:
 *    NULL
 *
 ****************************************************************************/
static void updateMemory_allocate_block(MemoryPool *pool, MemoryBlock *block)
{
    if (cb->buffer[cb->tail].flag == false && ((cb->tail + 1) % (UWB_SERIAL_DATA_POOL_SIZE) == cb->head))
    if (pool == NULL || block == NULL)
    {
        LOG_WARNING(TRACE_NO_OPTION | TRACE_MODULE_APP, "tx_cb_is_full\r\n");
        return true;
    }
    return false;
}
static struct UWB_TX_MSG_t *uwb_serial_cb_read(struct RING_BUFFER_T *cb)
{
    if (cb->buffer[cb->check].flag == false)
    {
        return &cb->buffer[cb->check];
    }
    return NULL;
}
static void uwb_serial_cb_write(struct RING_BUFFER_T *cb, uint8_t *value, uint16_t length)
{
    if (uwb_serial_cb_is_full(cb))
    {
        LOG_INFO(TRACE_MODULE_APP, "uwb serial data fifo full\r\n");
        LOG_INFO(TRACE_MODULE_APP, "%s Input parameter error\r\n", __func__);
        return;
    }
    if (cb->buffer[cb->tail].flag == true)
    if (pool->allocated == NULL)
    {
        cb->buffer[cb->tail].flag = false;
        cb->buffer[cb->tail].length = length;
        memcpy(&cb->buffer[cb->tail].msg, value, cb->buffer[cb->tail].length);
#if 0
        LOG_INFO(TRACE_NO_OPTION | TRACE_MODULE_APP, "serial write FIFO[%d] MSG\r\n", cb->tail);
        for (uint8_t i = 0; i < cb->buffer[cb->tail].length; i++)
        {
            LOG_INFO(TRACE_NO_OPTION | TRACE_MODULE_APP, "%02x ", cb->buffer[cb->tail].msg[i]);
        }
        LOG_INFO(TRACE_NO_OPTION | TRACE_MODULE_APP, "\r\n");
#endif
        block->next = NULL;
        block->prev = NULL;
        block->tail = block;
        pool->allocated = block;
    }
    else
    {
        LOG_INFO(TRACE_MODULE_APP, "uwb fifo block number %d\r\n", cb->tail);
        MemoryBlock *tail = pool->allocated->tail;
        tail->next = block;
        block->next = NULL;
        block->prev = tail;
        pool->allocated->tail = block;
    }
    cb->tail = (cb->tail + 1) % UWB_SERIAL_DATA_POOL_SIZE;
}
void uwb_serial_tx_msg_check(void)
{
    struct UWB_TX_MSG_t *uwb_tx_msg = uwb_serial_cb_read(&tx_cb);
    if (uwb_tx_msg == NULL)
    {
        return;
    }
    if (uwb_dm_tx_is_busy() == 1)
    {
        return;
    }
    if (uwb_tx_msg->flag == false)
    {
        struct DM_MDSDU_T mdsdu_tx;
        mdsdu_tx.mac_addr = ranging_responder_addr_get(0);
        mdsdu_tx.len = uwb_tx_msg->length;
        mdsdu_tx.data = uwb_tx_msg->msg;
        mdsdu_tx.ready = 1;
        uwb_dm_tx_pkt(&mdsdu_tx);
        tx_cb.buffer[tx_cb.check].flag = true;
        tx_cb.check = (tx_cb.check + 1) % UWB_SERIAL_DATA_POOL_SIZE;
        return;
    }
    return;
}
void uwb_serial_rx_msg_update(struct DM_MDSDU_T *rx)
/****************************************************************************
 * Name: allocateMemory
 *
 * Description: Allocation of memory
 *
 * Input Parameters:
 *    pool  -
 *    size -
 *
 * Returned Value:
 *    NULL
 *
 ****************************************************************************/
static void *allocateMemory(MemoryPool *pool, uint16_t size)
{
    rx_cb.buffer[rx_cb.check].length = rx->len;
    rx_cb.buffer[rx_cb.check].flag = false;
    uint32_t lock = int_lock();
    rx_cb.check = (rx_cb.check + 1) % UWB_SERIAL_DATA_POOL_SIZE;
    void *prt = NULL;
    MemoryBlock *current = pool->free;
    uwb_dm_rx_config(rx_cb.buffer[rx_cb.check].msg);
    return;
}
void uwb_serial_rx_msg_check(void)
{
    if (rx_cb.buffer[rx_cb.tail].flag == false)
    while (current != NULL)
    {
#if 0
        LOG_INFO(TRACE_NO_OPTION | TRACE_MODULE_APP, "serial read FIFO[%d] MSG\r\n", rx_cb.tail);
        for (uint8_t i = 0; i < rx_cb.buffer[rx_cb.tail].length; i++)
        if (current->is_free && current->size >= size)
        {
            LOG_INFO(TRACE_NO_OPTION | TRACE_MODULE_APP, "%02x ", rx_cb.buffer[rx_cb.tail].msg[i]);
            MemoryBlock *allocateblock = (MemoryBlock *)WsfBufAlloc(sizeof(MemoryBlock));
            if (allocateblock == NULL)
            {
                return NULL;
            }
            allocateblock->is_free = 0;
            allocateblock->size = size;
            allocateblock->start = current->start;
            updateMemory_allocate_block(pool, allocateblock);
            uint16_t free_size = current->size - size;
            current->start = current->start + size * sizeof(uint8_t);
            current->size = free_size;
            current->is_free = 1;
            prt = (void *)allocateblock->start;
            break;
        }
        LOG_INFO(TRACE_NO_OPTION | TRACE_MODULE_APP, "\r\n");
#endif
        int ret = DRV_OK;
        ret = uart_send(UART_ID1, rx_cb.buffer[rx_cb.tail].msg, rx_cb.buffer[rx_cb.tail].length, 0);
        current = current->next;
    }
        if (ret != DRV_OK)
    int_unlock(lock);
    return prt;
}
/****************************************************************************
 * Name: mergeFreeBlocks
 *
 * Description: Merge neighboring memory blocks.
 *
 * Input Parameters:
 *    pool   -
 *    prt    -
 *    length -
 *
 * Returned Value:
 *    NULL
 *
 ****************************************************************************/
static bool mergeFreeBlocks(MemoryPool *pool, uint8_t *prt, uint16_t length)
{
    MemoryBlock *current = pool->free;
    uint8_t *start_addr = prt;
    uint8_t *end_addr = prt + length;
    bool ret = false;
    while (current != NULL)
    {
        if (current->start == (end_addr))
        {
            LOG_INFO(TRACE_MODULE_APP, "UART ERROR 0x%02x\r\n", ret);
            current->start = start_addr;
            current->size = length + current->size;
            current->is_free = 1;
            ret = true;
            break;
        }
        else if (start_addr == (current->start + current->size))
        {
            current->size = length + current->size;
            current->is_free = 1;
            ret = true;
            break;
        }
        current = current->next;
    }
    if (current != NULL && current->prev != NULL)
    {
        if ((current->prev->start + current->prev->size) == current->start)
        {
            current->prev->size = current->prev->size + current->size;
            current->prev->is_free = 1;
            current->prev->next = current->next;
            current->next->prev = current->prev;
            if (pool->free->tail == current)
            {
                pool->free->tail = current->prev;
            }
            WsfBufFree(current);
            current = NULL;
        }
        if ((current->start + current->size) == current->prev->start)
        {
            current->prev->start = current->start;
            current->prev->size = current->prev->size + current->size;
            current->prev->is_free = 1;
            current->prev->next = current->next;
            current->next->prev = current->prev;
            if (pool->free->tail == current)
            {
                pool->free->tail = current->prev;
            }
            WsfBufFree(current);
            current = NULL;
        }
    }
    if (current != NULL && current->next != NULL)
    {
        if (((current->start + current->size) == current->next->start))
        {
            current->size = current->size + current->next->size;
            current->is_free = 1;
            if (pool->free->tail == current->next)
            {
                pool->free->tail = current;
            }
            current->next = current->next->next;
            current->next->next->prev = current;
            WsfBufFree(current->next);
            current->next = NULL;
        }
        if ((current->next->start + current->next->size) == current->start)
        {
            current->start = current->next->start;
            current->size = current->size + current->next->size;
            current->is_free = 1;
            if (pool->free->tail == current->next)
            {
                pool->free->tail = current;
            }
            current->next = current->next->next;
            current->next->next->prev = current;
            WsfBufFree(current->next);
            current->next = NULL;
        }
    }
    return ret;
}
/****************************************************************************
 * Name: freeMemoryPool
 *
 * Description: free memory blocks.
 *
 * Input Parameters:
 *    pool   -
 *    prt    -
 *    length -
 *
 * Returned Value:
 *    NULL
 *
 ****************************************************************************/
static bool freeMemoryPool(MemoryPool *pool, MemoryBlock *block)
{
    uint32_t lock = int_lock();
    if (pool == NULL || block == NULL)
    {
        LOG_INFO(TRACE_MODULE_APP, "%s Input parameter error\r\n", __func__);
        return false;
    }
    MemoryBlock *current_allocate = block;
    MemoryBlock *next = current_allocate->next;
    MemoryBlock *prev = current_allocate->prev;
    uint16_t block_len = current_allocate->size;
    uint8_t *prt = current_allocate->start;
    if (next == NULL && prev == NULL)
    {
        pool->allocated = NULL;
    }
    else if (prev == NULL)
    {
        next->tail = pool->allocated->tail;
        pool->allocated = next;
        pool->allocated->prev = NULL;
    }
    else
    {
        prev->next = next;
        next->prev = prev;
        if (pool->allocated->tail == current_allocate)
        {
            pool->allocated->tail = prev;
        }
        else if (pool->allocated->tail == pool->allocated)
        {
            pool->allocated->tail = NULL;
        }
    }
    WsfBufFree(current_allocate);
    current_allocate = NULL;
    bool flag = mergeFreeBlocks(pool, prt, block_len);
    if (flag == false)
    {
        MemoryBlock *newfreeblock = (MemoryBlock *)WsfBufAlloc(sizeof(MemoryBlock));
        if (newfreeblock == NULL)
        {
            return false;
        }
        newfreeblock->start = prt;
        newfreeblock->size = block_len;
        newfreeblock->is_free = 1;
        newfreeblock->next = NULL;
        newfreeblock->prev = pool->free->tail;
        pool->free->tail->next = newfreeblock;
        pool->free->tail = newfreeblock;
    }
    int_unlock(lock);
    return true;
}
/*****************************************************************************/
/****************************************************************************
 * Name: uwb_serial_cb_init
 *
 * Description:
 *    Initialize UWB transmit/receive Circular Buffer.
 ****************************************************************************/
void uwb_cb_init(uint8_t *tx_cb, uint8_t *rx_cb)
{
    if (tx_cb == NULL || rx_cb == NULL)
    {
        LOG_INFO(TRACE_MODULE_APP, "\r\n Initialize UWB transmit/receive Circular Buffer Error\r\n");
        return;
    }
    initMemoryPool(&g_tx_pool, tx_cb);
    initMemoryPool(&g_rx_pool, rx_cb);
    return;
}
/****************************************************************************
 * Name: uwb_serial_cb_read
 *
 * Description: Accessing the UWB receive/transmit Circular Buffer.
 *
 * Input Parameters:
 *    cb - UWB transmit/receive Circular Buffers
 *
 * Returned Value:
 *    Returns the first valid data segment of the UWB receive/transmit Circular Buffer.
 *
 ****************************************************************************/
struct MemoryBlock *uwb_transmit_cb_read(void)
{
    MemoryBlock *current_allocate = g_tx_pool.allocated;
    MemoryBlock *next = NULL;
    if (current_allocate == NULL)
    {
        return NULL;
    }
    while (current_allocate != NULL)
    {
        if (current_allocate->is_free == 1)
        {
            next = current_allocate->next;
            bool ret = freeMemoryPool(&g_tx_pool, current_allocate);
            if (ret == false)
            {
                LOG_INFO(TRACE_MODULE_APP, "free Memory address %p fail\r\n", (void *)current_allocate->start);
            }
            current_allocate = next;
        }
        else
        {
            rx_cb.buffer[rx_cb.tail].flag = true;
            rx_cb.tail = (rx_cb.tail + 1) % UWB_SERIAL_DATA_POOL_SIZE;
            break;
        }
    }
    return current_allocate;
}
struct MemoryBlock *uwb_receive_cb_read(void)
{
    MemoryBlock *current_allocate = g_rx_pool.allocated;
    if (current_allocate == NULL)
    {
        return NULL;
    }
    if (current_allocate->is_free == 1)
    {
        return NULL;
    }
    if (current_allocate->next != NULL)
    {
        LOG_INFO(TRACE_MODULE_APP, "Next full\r\n");
    }
    return current_allocate;
}
/****************************************************************************
 * Name: uwb_serial_cb_write
 *
 * Description: Write the data received from the serial port to the UWB buffer
 * and wait for UWB transmission.
 *
 * Input Parameters:
 *    cb - UWB transmit/receive Circular Buffers
 *    value - Waiting for data to be sent from UWB
 *    length - Length of data waiting to be sent by the UWB
 *
 * Returned Value:
 *    NULL
 *
 ****************************************************************************/
void uwb_transmit_cb_write(uint16_t length)
{
    uint8_t *ptr = (uint8_t *)allocateMemory(&g_tx_pool, length);
    if (ptr == NULL)
    {
        LOG_INFO(TRACE_MODULE_APP, "uwb transmit Cache full\r\n");
        return;
    };
    return;
}
void uwb_receive_cb_write(const uint8_t *value, uint16_t length)
{
    uint8_t *ptr = (uint8_t *)allocateMemory(&g_rx_pool, length);
    if (ptr == NULL)
    {
        LOG_INFO(TRACE_MODULE_APP, "uw breceive Cache full\r\n");
        return;
    }
    memcpy(ptr, value, length);
    return;
}
#if UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_1
/****************************************************************************
 * Name: serial_receive_callback
 *
 * Description:
 *    Serial port receive data callback function
 ****************************************************************************/
static void serial_receive_callback(void *dev, uint32_t err_code)
{
@@ -568,13 +993,164 @@
    if (tmp_read_idx == 0)
    {
        uart_receive(UART_ID1, pkt_header_buff, sizeof(pkt_header_buff), serial_receive_callback);
        uart_receive(SERIAL_NUM, pkt_header_buff, sizeof(pkt_header_buff), serial_receive_callback);
    }
    int_unlock(lock);
}
#elif UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0
/****************************************************************************
 * Name: serial_receive_callback
 *
 * Description:
 *    Serial port receive data callback function
 *    This function will receive a single character from the uart module and
 *    append it to a string. The string will be be sent over UWB when the
 *    last character received was a 'new line' '\n' (hex 0x0A) or if the
 *    string has reached the maximum data length.
 ****************************************************************************/
static void serial_receive_callback(void *dev, uint32_t err_code)
{
    uint32_t lock = int_lock();
    static uint16_t index = 0;
    g_tx_pool.free->start[index] = ch;
    index++;
    if ((g_tx_pool.free->start[index - 1] == '\n') || (g_tx_pool.free->start[index - 1] == '\r'))
    {
        // When the last character received is 'new line' '\n' (hex 0x0A)
        // then it is not transmitted
        if (index > 1)
        {
            // Write complete string to UWB transmit buffer
            uwb_transmit_cb_write(index);
        }
        index = 0;
    }
    else if (index == MDSDU_MTU_MAX)
    {
        // Write complete string to UWB transmit buffer
        uwb_transmit_cb_write(index);
        index = 0;
    }
    uart_receive(SERIAL_NUM, &ch, 1, serial_receive_callback);
    int_unlock(lock);
    return;
}
#endif //#if UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_1
/****************************************************************************
 * Public Functions
 ****************************************************************************/
#if (UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0 || UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_1)
/****************************************************************************
 * Name: uwb_serial_tx_msg_check
 *
 * Description:
 *    Check if there is data to be sent in the UWB transmit buffer,
 *    if so, send it.
 ****************************************************************************/
void uwb_serial_tx_msg_check(void)
{
    if (block_send_flag == true)
    {
        return;
    }
    MemoryBlock *current_send_block = uwb_transmit_cb_read();
    if (current_send_block == NULL)
    {
        return;
    }
    if (uwb_dm_tx_is_busy() == 1)
    {
        return;
    }
    current_send_block->is_free = 1;
    struct DM_MDSDU_T mdsdu_tx;
    mdsdu_tx.mac_addr = ranging_responder_addr_get(0);
    mdsdu_tx.len = current_send_block->size;
    mdsdu_tx.data = current_send_block->start;
    mdsdu_tx.ready = 1;
    uwb_dm_tx_pkt(&mdsdu_tx);
    block_send_flag = true;
    return;
}
/****************************************************************************
 * Name: uwb_serial_rx_msg_check
 *
 * Description:
 *    Check if there is data in the UWB receive data buffer and send it
 *    through the serial port if there is.
 ****************************************************************************/
void uwb_serial_rx_msg_check(void)
{
    int ret = DRV_OK;
    MemoryBlock *block = uwb_receive_cb_read();
    if (block == NULL)
    {
        return;
    }
    ret = uart_send(SERIAL_NUM, block->start, block->size, 0);
    if (ret == DRV_OK)
    {
        freeMemoryPool(&g_rx_pool, block);
    }
    return;
}
void uwb_serial_data_transfer_tx_done(void)
{
    block_send_flag = false;
    // LOG_INFO(TRACE_MODULE_APP, "block_send_flag %d \r\n",block_send_flag);
}
#endif //(UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0 || UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_1)
#endif // UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0 or SERIAL_DATA_TRANSFER_MODE_1 or DATA_TRANSFER_TEST_MODE
/****************************************************************************
 * Name: uwb_serial_data_transfer_init
 *
 * Description:
 *   UWB Serial Data Transfer passthrough initialization
 *   Mode 0, packet has no data format, serial data is terminated by '\r\n'.
 *   Mode 1, packet has packet format 2 bytes data length and payload.
 *
 * Input Parameters:
 *   NULL
 *
 * Returned Value:
 *   NULL
 *
 ****************************************************************************/
void uwb_serial_data_transfer_init(void)
{
#if UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_1
    LOG_INFO(TRACE_MODULE_APP, "UART input data format: Length(2B) + Data \r\n");
    struct UART_CFG_T serialuwb_cfg = {
@@ -590,18 +1166,43 @@
        .int_tx = false,
    };
    uart_open(UART_ID1, &serialuwb_cfg);
    uart_open(SERIAL_NUM, &serialuwb_cfg);
    uwb_serial_cb_init(&tx_cb, &rx_cb);
    uwb_dm_rx_config(rx_cb.buffer[rx_cb.head].msg);
    uart_receive(UART_ID1, pkt_header_buff, sizeof(pkt_header_buff), serial_receive_callback);
    uart_receive(SERIAL_NUM, pkt_header_buff, sizeof(pkt_header_buff), serial_receive_callback);
#elif UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0
    struct UART_CFG_T serialuwb_cfg = {
        .parity = UART_PARITY_NONE,
        .stop = UART_STOP_BITS_1,
        .data = UART_DATA_BITS_8,
        .flow = UART_FLOW_CONTROL_NONE,
        .rx_level = UART_RXFIFO_CHAR_1,
        .tx_level = UART_TXFIFO_EMPTY,
        .baud = BAUD_921600,
        .dma_en = false,
        .int_rx = true,
        .int_tx = true,
    };
    uart_open(SERIAL_NUM, &serialuwb_cfg);
    uwb_cb_init(serial_tx_msg, serial_rx_msg);
    uwb_dm_rx_config(g_rx_pool.free->start);
    uart_receive(SERIAL_NUM, &ch, 1, serial_receive_callback);
#endif
    return;
}
#else
#elif UWB_DATA_TRANSFER_MODE == DATA_TRANSFER_TEST_MODE
#include "mk_timer.h"
@@ -641,29 +1242,13 @@
    return;
}
static void timer_callback(void *dev, uint32_t time)
{
    uwb_data_transfer_send_test();
}
void uwb_data_transfer_init_test(void)
{
    if (uwb_app_config.session_param.device_role == DEV_ROLE_INITIATOR)
    {
        data_gen(length);
        struct TIMER_CFG_T timer_cfg = {
            .extin_type = TIMER_EXTIN_NONE,
            .load = 0x7A12,
            .int_en = true,
            .callback = timer_callback,
        };
        timer_open(TIMER_ID0, &timer_cfg);
    }
    data_gen(length);
    uwb_dm_rx_config(rx_buff);
    return;
}
#endif
#endif //#if ((UWB_DATA_TRANSFER_MODE == SERIAL_DATA_TRANSFER_MODE_0 || SERIAL_DATA_TRANSFER_MODE_1 || DATA_TRANSFER_TEST_MODE))