/*
|
* Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and
|
* its subsidiaries and affiliates (collectly called MKSEMI).
|
*
|
* All rights reserved.
|
*
|
* Redistribution and use in source and binary forms, with or without
|
* modification, are permitted provided that the following conditions are met:
|
*
|
* 1. Redistributions of source code must retain the above copyright notice,
|
* this list of conditions and the following disclaimer.
|
*
|
* 2. Redistributions in binary form, except as embedded into an MKSEMI
|
* integrated circuit in a product or a software update for such product,
|
* must reproduce the above copyright notice, this list of conditions and
|
* the following disclaimer in the documentation and/or other materials
|
* provided with the distribution.
|
*
|
* 3. Neither the name of MKSEMI nor the names of its contributors may be used
|
* to endorse or promote products derived from this software without
|
* specific prior written permission.
|
*
|
* 4. This software, with or without modification, must only be used with a
|
* MKSEMI integrated circuit.
|
*
|
* 5. Any software provided in binary form under this license must not be
|
* reverse engineered, decompiled, modified and/or disassembled.
|
*
|
* THIS SOFTWARE IS PROVIDED BY MKSEMI "AS IS" AND ANY EXPRESS OR IMPLIED
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* DISCLAIMED. IN NO EVENT SHALL MKSEMI OR CONTRIBUTORS BE LIABLE FOR ANY
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
*/
|
|
#include "mk_trace.h"
|
#include "mk_uwb.h"
|
#include "mk_aes.h"
|
#include "mk_power.h"
|
|
#include "lib_aoa.h"
|
#include "lib_ranging.h"
|
#include "uwb_data_transfer.h"
|
#include "uwb_data.h"
|
|
struct RANGING_ENV_T ranging_env;
|
uint8_t fira_uwb_tx_buf[PHY_PAYLOAD_LEN_MAX];
|
|
static struct DATA_TRANSFER_CB_T data_transfer_cb;
|
|
static struct UWB_OP_T op = {
|
.session_configure = data_transfer_configure,
|
.session_start = data_transfer_start,
|
.session_stop = data_transfer_stop,
|
.session_local_addr_set = ranging_local_addr_set,
|
.session_peer_addr_set = ranging_peer_addr_set,
|
.session_responder_addr_add = ranging_responder_addr_add,
|
.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_dynamic_update_responder_list = NULL,
|
.session_set_ccc_ursk = NULL,
|
.vendor_session_configure = NULL,
|
.vendor_session_start = NULL,
|
.vendor_session_stop = NULL,
|
};
|
|
static void data_transfer_tx_process(struct MAC_HW_REPORT_T *tx_report);
|
static void data_transfer_rx_process(struct MAC_HW_REPORT_T *rx_report);
|
void app_session_init(void);
|
|
//------------------------------------------------------------------------------
|
int data_transfer_init(uint8_t handle_id)
|
{
|
/* store handler ID */
|
data_transfer_cb.handle_id = handle_id;
|
|
/* init rx queue */
|
WSF_QUEUE_INIT(&data_transfer_cb.msg_queue);
|
|
LOG_INFO(TRACE_MODULE_APP, "Ranging lib version: %s\r\n", MK8000_get_rangelib_version());
|
LOG_INFO(TRACE_MODULE_APP, "AoA lib version: %s\r\n", MK8000_get_aoalib_version());
|
|
return 0;
|
}
|
|
int data_transfer_deinit(void)
|
{
|
return 0;
|
}
|
|
// This function will be called by uwbapi_session_init()
|
void app_session_init(void)
|
{
|
// register process handler for MAC TX done and RX done
|
mac_register_process_handler(data_transfer_tx_process, data_transfer_rx_process);
|
|
uwbs_handler_init(&op);
|
}
|
|
void data_transfer_configure(void)
|
{
|
fira_keys_generate();
|
|
aes_update_key(AES_ID0, &fira_key.devPayKey.ukey.keyByte[0]);
|
mac_update_ccm_key((uint32_t *)&fira_key.devPayKey.ukey.keyWord[0]);
|
|
uwb_app_config.ranging_stage = RANGING_IDLE;
|
|
ranging_env.uwb_period_prefetch_time = UWB_PERIOD_PREFETCH_TIME;
|
ranging_env.uwb_evt_prefetch_time = UWB_EVT_PREFETCH_TIME;
|
ranging_env.uwb_rx_open_in_advance = UWB_RX_OPEN_IN_ADVANCE;
|
ranging_env.uwb_rx_window = UWB_RX_WINDOW;
|
ranging_env.uwb_rx_open_in_advance_wakeup = UWB_RX_OPEN_IN_ADVANCE;
|
ranging_env.uwb_rx_window_wakeup = UWB_RX_WINDOW;
|
ranging_env.ranging_period = MS_TO_PHY_TIMER_COUNT(uwb_app_config.session_param.ranging_interval);
|
|
ranging_env.slots_per_block = (uint16_t)(uwb_app_config.session_param.ranging_interval / RSTU_TO_MS(uwb_app_config.session_param.slot_duration));
|
ASSERT(ranging_env.slots_per_block >= uwb_app_config.session_param.slots_per_round, "Ranging block parameters configure wrong");
|
|
ranging_env.slot_interval = RSTU_TO_PHY_TIMER_COUNT(uwb_app_config.session_param.slot_duration);
|
ranging_env.round_duration = ranging_env.slot_interval * uwb_app_config.session_param.slots_per_round;
|
ranging_env.phy_sts_index = fira_key.phyStsIdxInit - ranging_env.slots_per_block;
|
ranging_env.enable = 0;
|
|
ranging_env.slot_idx = 0;
|
ranging_env.tof = 0;
|
|
ranging_env.range_data.ranging_type = 0x1; // TWR (SS-TWR, DS-TWR)
|
ranging_env.range_data.ranging_interval = uwb_app_config.session_param.ranging_interval;
|
ranging_env.range_data.mac_addr_mode = uwbs_mac_addr_mode_get();
|
ranging_env.range_data.session_id = uwb_app_config.session_id;
|
ranging_env.stride_length = uwb_app_config.session_param.stride_length;
|
ranging_env.round_offset_in_block = 0;
|
ranging_env.next_round_index = 0;
|
|
uwbs_configure(PHY_TX | PHY_RX, uwb_app_config.session_param.tx_power_level);
|
|
// uwb_dm_config(&mdsdu_tx, &mdsdu_rx);
|
|
LOG_INFO(TRACE_MODULE_FIRA, "slot duration %d slots per round %d ranging interval %d\r\n", uwb_app_config.session_param.slot_duration,
|
uwb_app_config.session_param.slots_per_round, uwb_app_config.session_param.ranging_interval);
|
}
|
|
void data_transfer_start(void)
|
{
|
ranging_env.enable = 1;
|
ranging_env.lost_cnt = 0xFF;
|
ranging_env.anchor_point = phy_timer_count_get();
|
ranging_env.slot_idx = 0;
|
ranging_env.is_hopping = uwb_app_config.session_param.hopping_mode;
|
enum DEV_ROLE_T role = uwb_app_config.session_param.device_role;
|
if ((role == DEV_ROLE_INITIATOR) || (role == DEV_ROLE_GATE_CONTROLLER))
|
{
|
uwb_app_config.ranging_stage = RANGING_DTPCM;
|
phy_timer_target_set(ranging_env.anchor_point + ranging_env.ranging_period - ranging_env.uwb_period_prefetch_time, session_timer_callback);
|
power_mode_request(POWER_UNIT_APP, POWER_MODE_POWER_DOWN);
|
}
|
else
|
{
|
ranging_env.is_hopping = 0;
|
ranging_env.stride_length = 0;
|
ranging_env.round_offset_in_block = 0;
|
ranging_env.next_round_index = 0;
|
power_on_radio(0, 1);
|
uwb_app_config.ranging_stage = RANGING_SYNC;
|
phy_sts_pkt_cfg_set(SP0);
|
ranging_update_slot_index(ranging_env.slot_idx);
|
mac_rx(EVT_MODE_MAC_PHY_ASAP, 0, ranging_env.ranging_period);
|
mac_start();
|
power_mode_request(POWER_UNIT_APP, POWER_MODE_SLEEP);
|
}
|
|
ranging_env.count = 0;
|
ranging_env.count_last = 0;
|
|
LOG_INFO(TRACE_MODULE_FIRA, "Ranging start, role %d\r\n", uwb_app_config.session_param.device_role);
|
}
|
|
void data_transfer_stop(void)
|
{
|
ranging_env.enable = 0;
|
LOG_INFO(TRACE_MODULE_FIRA, "Ranging stop\r\n");
|
}
|
|
#if 0
|
/*
|
bitmap for 1 responder
|
slot idx: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
|
TX bitmap: 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 ...
|
RX bitmap: 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ...
|
|
bitmap for 2 responders
|
slot idx: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
|
TX bitmap: 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 ...
|
RX bitmap: 0 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 ...
|
|
bitmap for 3 responders
|
slot idx: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
|
TX bitmap: 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 ...
|
RX bitmap: 0 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 ...
|
*/
|
void uwb_slot_bitmap_generate(uint8_t *bits, uint8_t dev_idx, uint8_t dev_num)
|
{
|
ASSERT(bits, "Input bits is null");
|
uint8_t offset = dev_idx;
|
uint8_t size = uwb_slot_bitmap_size_get();
|
|
while (offset < size * 8)
|
{
|
bits[offset >> 3] |= (uint8_t)(1 << (offset & 0x7));
|
offset += dev_num;
|
}
|
}
|
|
#else
|
|
void uwb_slot_bitmap_generate(uint8_t *bits, uint8_t dev_idx, uint8_t dev_num)
|
{
|
ASSERT(bits, "Input bits is null");
|
|
uint8_t size = uwb_slot_bitmap_size_get();
|
uint8_t offset = 0;
|
int bitValue;
|
while (offset < size * 8)
|
{
|
if (dev_idx == 0)
|
{
|
bitValue = ((offset + 1) % 3 == 0) ? 0 : 1;
|
bits[offset / 8] |= (bitValue << (offset % 8));
|
}
|
else
|
{
|
bitValue = ((offset + 1) % 3 == 0) ? 1 : 0;
|
bits[offset / 8] |= (bitValue << (offset % 8));
|
}
|
offset++;
|
}
|
}
|
#endif
|
|
uint8_t uwb_dm_rx_responder_idx(uint8_t slot_idx, uint8_t dev_num)
|
{
|
ASSERT(slot_idx > 1, "RX slot idx is wrong");
|
uint8_t dev_idx = (slot_idx - 2) % (dev_num + 1);
|
return dev_idx;
|
}
|
|
void uwb_pkt_tx_done_ind(const struct MAC_HW_REPORT_T *tx, enum RANGING_STAGE_T stage, uint8_t slot_idx)
|
{
|
#if DM_PRINT_PAYLOAD_EN
|
struct UWB_PKT_TX_DONE_IND_T *ind = WsfMsgAlloc(sizeof(struct UWB_PKT_TX_DONE_IND_T) + tx->pkt_len);
|
#else
|
struct UWB_PKT_TX_DONE_IND_T *ind = WsfMsgAlloc(sizeof(struct UWB_PKT_TX_DONE_IND_T));
|
#endif
|
if (ind != NULL)
|
{
|
ind->hdr.event = UWB_PKT_TX_DONE_MSG;
|
ind->ranging_stage = (uint8_t)stage;
|
ind->slot_idx = slot_idx;
|
ind->status = tx->err_code;
|
|
ind->tx_len = tx->pkt_len;
|
|
#if DM_PRINT_PAYLOAD_EN
|
if ((ind->tx_len) && (tx->pkt_data != NULL))
|
{
|
memcpy(ind->tx_data, tx->pkt_data, tx->pkt_len);
|
}
|
#endif
|
|
// Send the message
|
WsfMsgSend(data_transfer_cb.handle_id, ind);
|
}
|
else
|
{
|
LOG_WARNING(TRACE_MODULE_UWB, "memory is not enough for UWB_PKT_TX_DONE_IND_T\r\n");
|
}
|
}
|
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
#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;
|
|
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);
|
ind->status |= (ind->rx_len ? 0 : UWB_MAC_DEC_ERR);
|
#endif
|
}
|
|
// Send the message
|
WsfMsgSend(data_transfer_cb.handle_id, ind);
|
return ind->status;
|
}
|
else
|
{
|
LOG_WARNING(TRACE_MODULE_UWB, "memory is not enough for UWB_PKT_RX_DONE_IND_T\r\n");
|
return 0xFFFF;
|
}
|
}
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
#pragma clang diagnostic pop
|
#endif
|
|
void session_timer_callback(void *dev, uint32_t time)
|
{
|
// LOG_INFO(TRACE_MODULE_FIRA, "PHY timer slot %d\r\n", ranging_env.slot_idx);
|
// board_led_on(BOARD_LED_2);
|
|
if (uwb_app_config.session_param.ranging_round_usage == DATA_TRANSFER_PHASE)
|
{
|
data_transfer_phy_timer_callback(dev, time);
|
}
|
|
// board_led_off(BOARD_LED_2);
|
}
|
|
enum RANGING_STAGE_T session_fsm(const struct MAC_HW_REPORT_T *ind)
|
{
|
// LOG_INFO(TRACE_MODULE_FIRA, "FSM %02x slot %d\r\n", uwb_app_config.ranging_stage, ranging_env.slot_idx);
|
// board_led_on(BOARD_LED_1);
|
enum RANGING_STAGE_T stage = RANGING_IDLE;
|
|
if (uwb_app_config.session_param.ranging_round_usage == DATA_TRANSFER_PHASE)
|
{
|
stage = data_transfer_fsm(ind);
|
}
|
|
// board_led_off(BOARD_LED_1);
|
return stage;
|
}
|
|
static void data_transfer_tx_process(struct MAC_HW_REPORT_T *tx_report)
|
{
|
session_fsm(tx_report);
|
}
|
|
static void data_transfer_rx_process(struct MAC_HW_REPORT_T *rx_report)
|
{
|
session_fsm(rx_report);
|
}
|
|
#if UWB_SERIAL_DATA_TRANSFER_EN
|
|
static uint8_t pkt_header_buff[2];
|
|
static uint8_t data_buff[SERIAL_MESSAGE_MAX_LEN];
|
|
static struct RING_BUFFER_T tx_cb;
|
static struct RING_BUFFER_T rx_cb;
|
|
static void uwb_serial_cb_init(struct RING_BUFFER_T *tx, struct RING_BUFFER_T *rx)
|
{
|
for (int i = 0; i < UWB_SERIAL_DATA_POOL_SIZE; i++)
|
{
|
tx->buffer[i].flag = true;
|
rx->buffer[i].flag = true;
|
}
|
tx->head = 0;
|
tx->tail = 0;
|
tx->check = 0;
|
|
rx->head = 0;
|
rx->tail = 0;
|
rx->check = 0;
|
|
return;
|
}
|
|
static bool uwb_serial_cb_is_full(struct RING_BUFFER_T *cb)
|
{
|
if (cb->buffer[cb->tail].flag == false && ((cb->tail + 1) % (UWB_SERIAL_DATA_POOL_SIZE) == cb->head))
|
{
|
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");
|
return;
|
}
|
|
if (cb->buffer[cb->tail].flag == true)
|
{
|
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
|
}
|
else
|
{
|
LOG_INFO(TRACE_MODULE_APP, "uwb fifo block number %d\r\n", cb->tail);
|
}
|
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)
|
{
|
rx_cb.buffer[rx_cb.check].length = rx->len;
|
rx_cb.buffer[rx_cb.check].flag = false;
|
|
rx_cb.check = (rx_cb.check + 1) % UWB_SERIAL_DATA_POOL_SIZE;
|
|
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)
|
{
|
#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++)
|
{
|
LOG_INFO(TRACE_NO_OPTION | TRACE_MODULE_APP, "%02x ", rx_cb.buffer[rx_cb.tail].msg[i]);
|
}
|
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);
|
|
if (ret != DRV_OK)
|
{
|
LOG_INFO(TRACE_MODULE_APP, "UART ERROR 0x%02x\r\n", ret);
|
}
|
else
|
{
|
rx_cb.buffer[rx_cb.tail].flag = true;
|
rx_cb.tail = (rx_cb.tail + 1) % UWB_SERIAL_DATA_POOL_SIZE;
|
}
|
}
|
|
return;
|
}
|
|
static void serial_receive_callback(void *dev, uint32_t err_code)
|
{
|
uint32_t lock = int_lock();
|
|
volatile static uint16_t tmp_read_idx = 0;
|
|
if (tmp_read_idx == 0)
|
{
|
uint16_t sum_bytes = (uint16_t)((pkt_header_buff[1] << 8) + (pkt_header_buff[0]));
|
|
ASSERT(sum_bytes <= SERIAL_MESSAGE_MAX_LEN, "Frame length is over range %u", sum_bytes);
|
|
tmp_read_idx = sum_bytes;
|
|
uart_receive(UART_ID1, data_buff, sum_bytes, serial_receive_callback);
|
}
|
else
|
{
|
#if 0
|
LOG_INFO(TRACE_MODULE_APP, "serial recv bytes [%d]\r\n",tmp_read_idx);
|
for (uint8_t i = 0; i < tmp_read_idx; i++)
|
{
|
LOG_INFO(TRACE_NO_OPTION | TRACE_MODULE_APP, "%02x ", data_buff[i]);
|
}
|
LOG_INFO(TRACE_NO_OPTION | TRACE_MODULE_APP, "\r\n");
|
#endif
|
if (tmp_read_idx <= MDSDU_MTU_MAX)
|
{
|
uwb_serial_cb_write(&tx_cb, data_buff, tmp_read_idx);
|
}
|
else
|
{
|
while (tmp_read_idx >= MDSDU_MTU_MAX)
|
{
|
uwb_serial_cb_write(&tx_cb, data_buff, MDSDU_MTU_MAX);
|
tmp_read_idx -= MDSDU_MTU_MAX;
|
}
|
|
uwb_serial_cb_write(&tx_cb, &data_buff[MDSDU_MTU_MAX], tmp_read_idx);
|
}
|
tmp_read_idx = 0;
|
}
|
|
if (tmp_read_idx == 0)
|
{
|
uart_receive(UART_ID1, pkt_header_buff, sizeof(pkt_header_buff), serial_receive_callback);
|
}
|
int_unlock(lock);
|
}
|
|
void uwb_serial_data_transfer_init(void)
|
{
|
LOG_INFO(TRACE_MODULE_APP, "UART input data format: Length(2B) + Data \r\n");
|
|
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 = true,
|
.int_rx = false,
|
.int_tx = false,
|
};
|
|
uart_open(UART_ID1, &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);
|
|
return;
|
}
|
|
#else
|
|
#include "mk_timer.h"
|
|
static uint8_t tx_buff[1024];
|
static uint8_t rx_buff[1024];
|
|
static uint16_t length = 977;
|
|
static void data_gen(uint16_t len)
|
{
|
uint16_t offset = 0;
|
|
while (len)
|
{
|
for (uint8_t i = 0; i < 255; i++)
|
{
|
if (len == 0)
|
{
|
break;
|
}
|
tx_buff[offset++] = i;
|
len--;
|
}
|
}
|
}
|
|
void uwb_data_transfer_send_test(void)
|
{
|
struct DM_MDSDU_T mdsdu_tx;
|
mdsdu_tx.mac_addr = ranging_responder_addr_get(0);
|
mdsdu_tx.len = length;
|
mdsdu_tx.data = tx_buff;
|
mdsdu_tx.ready = 1;
|
|
uwb_dm_tx_pkt(&mdsdu_tx);
|
|
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);
|
}
|
|
uwb_dm_rx_config(rx_buff);
|
|
return;
|
}
|
|
#endif
|