From cc432b761c884a0bd8e9d83db0a4e26109fc08b1 Mon Sep 17 00:00:00 2001 From: chen <15335560115@163.com> Date: 星期五, 08 十一月 2024 15:35:38 +0800 Subject: [PATCH] 安邦手环GPS删除部分无用数据和修改4G波特率9600出厂测试固件 --- keil/include/components/uci/src/uci_spi_driver.c | 354 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 354 insertions(+), 0 deletions(-) diff --git a/keil/include/components/uci/src/uci_spi_driver.c b/keil/include/components/uci/src/uci_spi_driver.c new file mode 100644 index 0000000..21a4895 --- /dev/null +++ b/keil/include/components/uci/src/uci_spi_driver.c @@ -0,0 +1,354 @@ +/* + * 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 "wsf_queue.h" +#include "wsf_buf.h" +#include "mk_spi.h" +#include "mk_power.h" +#include "mk_misc.h" +#include "uwb_api.h" +#include "uci_tl_comm.h" +#include "uci_tl_task.h" + +#include "board.h" + +#if UCI_INTF_PORT == 1 + +#define UCI_PORT SPI_ID0 +#define UCI_SEND_RETRY_MAX (2) + +static void uci_tl_up_req(void); +static void uci_tl_timer_notify(void); +static void uci_tl_setup(void); +static bool uci_tl_up_is_active(void); +static void rx_over_callback(void *dev, uint32_t err_code); +static void tx_over_callback(void *dev, uint32_t err_code); + +extern int uci_validate(uint8_t *buf); + +uci_tl_dev_t g_uci_tl_dev = { + .uci_tl_setup = &uci_tl_setup, + .uci_tl_resume = &uci_tl_setup, + .uci_tl_up_is_active = &uci_tl_up_is_active, + .uci_tl_up_req = &uci_tl_up_req, + .uci_tl_timer_notify = &uci_tl_timer_notify, +}; + +static struct SPI_CFG_T uci_spi_cfg = { + .bit_rate = UCI_INTF_SPI_SPEED, + .data_bits = 8, + .slave = 1, + .clk_polarity = 0, + .clk_phase = 1, + .ti_mode = 0, + .dma_rx = true, + .dma_tx = true, + .int_rx = false, + .int_tx = false, +}; + +static uint8_t recv_buff[UCI_RX_BUFF_SIZE] = {0}; +static uint8_t send_buff[UCI_TX_BUFF_SIZE] = {0}; +static struct UCI_TL_MSG_T *tl_up_msg = NULL; +static bool tx_idle = true; +static bool rx_idle = true; +static uint8_t retry_cnt = 0; +static void host2slave_gpio_callback(enum IO_PIN_T pin); + +static void uci_tl_setup(void) +{ + /*SCK of SPI pin pull-down.*/ + io_pull_set(IO_PIN_13, IO_PULL_DOWN, IO_PULL_UP_NONE); + /*Host to slave pin pull-up. */ + io_pull_set(HOST2SLAVE_HS_GPIO, IO_PULL_UP, IO_PULL_UP_LEVEL0); + /*Host to salve pin wake-up enalbe by low level.*/ + power_wakeup_enable((enum POWER_WAKEUP_SOURCE_T)HOST2SLAVE_HS_GPIO, POWER_WAKEUP_LEVEL_LOW); + + gpio_pin_set_dir(SLAVE2HOST_HS_GPIO, GPIO_DIR_OUT, 1); + gpio_pin_set_dir(HOST2SLAVE_HS_GPIO, GPIO_DIR_IN, 0); + gpio_enable_irq(HOST2SLAVE_HS_GPIO, GPIO_IRQ_TYPE_FALLING_EDGE, host2slave_gpio_callback); + + spi_open(UCI_PORT, &uci_spi_cfg); +} + +static void rx_over_callback(void *dev, uint32_t err_code) +{ + if (uci_validate(recv_buff)) + { + uint16_t frame_len = *(recv_buff + 3) + UCI_HEADER_SIZE; + + if (WsfQueueCount(&g_uci_tl_dev.tl_down_queue) < UCI_MAX_DL_ITEMS) + { + struct UCI_TL_MSG_T *p; + + if ((p = WsfBufAlloc((uint16_t)(frame_len + sizeof(struct UCI_TL_MSG_T)))) != NULL) + { + memcpy(p->msg, recv_buff, frame_len); + p->msg_length = frame_len; + WsfQueueEnq(&g_uci_tl_dev.tl_down_queue, p); + } + else + { + LOG_INFO(TRACE_MODULE_UCI, "No buff to queue cmd\r\n"); + } + } + + /* Set UCI receive event */ + if (g_uci_tl_dev.uci_tl_down_notify != NULL) + { + g_uci_tl_dev.uci_tl_down_notify(); + } + } +} + +static void tx_over_callback(void *dev, uint32_t err_code) +{ + WsfTimerStop(&g_uci_tl_dev.tl_timer); + + if (tl_up_msg) + { + WsfBufFree(tl_up_msg); + tl_up_msg = NULL; + } + + retry_cnt = 0; + g_uci_tl_dev.uci_tl_up_done_notify(); +} + +#if !(UCI_INTF_SPI_FD_HS) +static void host2slave_gpio_callback(enum IO_PIN_T pin) +{ + if (0 == gpio_pin_get_val(pin)) + { + if (!tx_idle) + { + gpio_pin_set(SLAVE2HOST_HS_GPIO); + WsfTimerStop(&g_uci_tl_dev.tl_timer); + spi_abort_dma(UCI_PORT, SPI_DMA_ABORT_TX | SPI_DMA_ABORT_RX, NULL, NULL); + if (tl_up_msg != NULL) + { + WsfQueuePush(&g_uci_tl_dev.tl_up_queue, tl_up_msg); + tl_up_msg = NULL; + g_uci_tl_dev.uci_tl_up_done_notify(); + } + tx_idle = true; + } + memset(recv_buff, 0, UCI_RX_BUFF_SIZE); + memset(send_buff, 0, UCI_TX_BUFF_SIZE); + spi_open(UCI_PORT, &uci_spi_cfg); + spi_transfer(UCI_PORT, send_buff, recv_buff, UCI_RX_BUFF_SIZE, NULL); + gpio_pin_clr(SLAVE2HOST_HS_GPIO); + rx_idle = false; + gpio_enable_irq(HOST2SLAVE_HS_GPIO, GPIO_IRQ_TYPE_RISING_EDGE, host2slave_gpio_callback); + power_mode_request(POWER_UNIT_UCI_RX, POWER_MODE_SLEEP); + } + else + { + spi_abort_dma(UCI_PORT, SPI_DMA_ABORT_TX | SPI_DMA_ABORT_RX, NULL, NULL); + rx_over_callback(NULL, 0); + memset(recv_buff, 0, UCI_RX_BUFF_SIZE); + memset(send_buff, 0, UCI_TX_BUFF_SIZE); + gpio_pin_set(SLAVE2HOST_HS_GPIO); + rx_idle = true; + gpio_enable_irq(HOST2SLAVE_HS_GPIO, GPIO_IRQ_TYPE_FALLING_EDGE, host2slave_gpio_callback); + power_mode_clear(POWER_UNIT_UCI_RX); + } +} +#endif + +#if (UCI_INTF_SPI_FD_HS) +static void host2slave_gpio_callback(enum IO_PIN_T pin) +{ + if (0 == gpio_pin_get_val(pin)) + { + if (tx_idle) + { + memset(recv_buff, 0, UCI_RX_BUFF_SIZE); + memset(send_buff, 0, UCI_TX_BUFF_SIZE); + tl_up_msg = WsfQueueDeq(&g_uci_tl_dev.tl_up_queue); + if (tl_up_msg != NULL) + { + memcpy(send_buff, tl_up_msg->msg, tl_up_msg->msg_length); + tx_idle = false; + power_mode_request(POWER_UNIT_UCI_TX, POWER_MODE_SLEEP); + } + spi_open(UCI_PORT, &uci_spi_cfg); + spi_transfer(UCI_PORT, send_buff, recv_buff, UCI_RX_BUFF_SIZE, NULL); + gpio_pin_clr(SLAVE2HOST_HS_GPIO); + } + else + { + WsfTimerStop(&g_uci_tl_dev.tl_timer); + } + + rx_idle = false; + gpio_enable_irq(HOST2SLAVE_HS_GPIO, GPIO_IRQ_TYPE_RISING_EDGE, host2slave_gpio_callback); + power_mode_request(POWER_UNIT_UCI_RX, POWER_MODE_SLEEP); + } + else + { + spi_abort_dma(UCI_PORT, SPI_DMA_ABORT_TX | SPI_DMA_ABORT_RX, NULL, NULL); + rx_over_callback(NULL, 0); + if (!tx_idle) + { + tx_over_callback(NULL, 0); + tx_idle = true; + } + memset(recv_buff, 0, UCI_RX_BUFF_SIZE); + memset(send_buff, 0, UCI_TX_BUFF_SIZE); + gpio_pin_set(SLAVE2HOST_HS_GPIO); + rx_idle = true; + gpio_enable_irq(HOST2SLAVE_HS_GPIO, GPIO_IRQ_TYPE_FALLING_EDGE, host2slave_gpio_callback); + power_mode_clear(POWER_UNIT_UCI_RX); + power_mode_clear(POWER_UNIT_UCI_TX); + } +} +#endif + +static void uci_tl_up_req(void) +{ + if (!tx_idle || !rx_idle) + { + return; + } + + if (0 == gpio_pin_get_val(HOST2SLAVE_HS_GPIO)) + { + return; + } + + uint32_t lock = int_lock(); + + /* Get messages from the up queue */ + tl_up_msg = WsfQueueDeq(&g_uci_tl_dev.tl_up_queue); + + if (tl_up_msg != NULL) + { + if (tl_up_msg->msg_length == 0) + { + WsfBufFree(tl_up_msg); + tl_up_msg = NULL; + g_uci_tl_dev.uci_tl_up_done_notify(); + } + else + { +#if !(UCI_INTF_SPI_FD_HS) + if (!rx_idle || (0 == gpio_pin_get_val(HOST2SLAVE_HS_GPIO))) + { + WsfQueuePush(&g_uci_tl_dev.tl_up_queue, tl_up_msg); + tl_up_msg = NULL; + g_uci_tl_dev.uci_tl_up_done_notify(); + } + else +#endif + { + tx_idle = false; + memset(recv_buff, 0, UCI_RX_BUFF_SIZE); + memset(send_buff, 0, UCI_TX_BUFF_SIZE); + memcpy(send_buff, tl_up_msg->msg, tl_up_msg->msg_length); + spi_open(UCI_PORT, &uci_spi_cfg); +#if !(UCI_INTF_SPI_FD_HS) + spi_transfer(UCI_PORT, send_buff, recv_buff, tl_up_msg->msg_length, tx_over_callback); +#else + spi_transfer(UCI_PORT, send_buff, recv_buff, UCI_RX_BUFF_SIZE, NULL); +#endif + gpio_pin_clr(SLAVE2HOST_HS_GPIO); + WsfTimerStartMs(&g_uci_tl_dev.tl_timer, UCI_HS_TIMEOUT_MS, WSF_TIMER_ONE_SHOT); + power_mode_request(POWER_UNIT_UCI_TX, POWER_MODE_SLEEP); + } + } + } + else + { + LOG_INFO(TRACE_MODULE_UCI, "Up queue is empty\r\n"); + g_uci_tl_dev.uci_tl_up_done_notify(); + } + int_unlock(lock); +} + +static bool uci_tl_up_is_active(void) +{ + if (!spi_is_busy(UCI_PORT) && !tx_idle && rx_idle) + { + gpio_pin_set(SLAVE2HOST_HS_GPIO); + tx_idle = true; + power_mode_clear(POWER_UNIT_UCI_TX); + } + + return !tx_idle; +} + +static void uci_tl_timer_notify(void) +{ + uint32_t lock = int_lock(); + if (!tx_idle) + { + LOG_INFO(TRACE_MODULE_UCI, "UCI Host did not ACK in time\n"); + gpio_pin_set(SLAVE2HOST_HS_GPIO); + spi_abort_dma(UCI_PORT, SPI_DMA_ABORT_TX | SPI_DMA_ABORT_RX, NULL, NULL); + + if (++retry_cnt > UCI_SEND_RETRY_MAX) + { + if (tl_up_msg) + { + WsfBufFree(tl_up_msg); + tl_up_msg = NULL; + } + + retry_cnt = 0; + } + else + { + if (tl_up_msg != NULL) + { + WsfQueuePush(&g_uci_tl_dev.tl_up_queue, tl_up_msg); + tl_up_msg = NULL; + } + } + + g_uci_tl_dev.uci_tl_up_done_notify(); + tx_idle = true; + } + int_unlock(lock); + + power_mode_clear(POWER_UNIT_UCI_TX); +} + +#endif -- Gitblit v1.9.3