| | |
| | | #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]; |
| | |
| | | .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, |
| | |
| | | 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 ... |
| | |
| | | #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); |
| | |
| | | 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) |
| | | { |
| | |
| | | |
| | | 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 = { |
| | |
| | | .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" |
| | | |
| | |
| | | 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)) |