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