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/drivers/mk_misc.c | 529 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 529 insertions(+), 0 deletions(-) diff --git a/keil/include/drivers/mk_misc.c b/keil/include/drivers/mk_misc.c new file mode 100644 index 0000000..6f8560d --- /dev/null +++ b/keil/include/drivers/mk_misc.c @@ -0,0 +1,529 @@ +/* + * 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_misc.h" +#include "mk_dual_timer.h" +#include "mk_clock.h" +#include "mk_trace.h" +#include "mk_sleep_timer.h" +#include "mk_reset.h" +// #include "board.h" + +uint32_t mk_chip_id(void) +{ + return REG_READ(0x4000000C); +} + +void mk_chip_uuid(uint8_t *uuid) +{ + ASSERT(uuid, "uuid is null"); + uint8_t y = REG_READ_BYTE(0x40010074); + uint8_t x = REG_READ_BYTE(0x40010075); + uint8_t w = REG_READ_BYTE(0x40010076); + uint8_t l = REG_READ_BYTE(0x4001007F) - 'A'; + + uuid[0] = ((l << 3) & 0x80) | (y & 0x7F); + uuid[1] = ((l << 4) & 0x80) | (x & 0x7f); + uuid[2] = ((l << 5) & 0xE0) | (w & 0x1f); + uuid[3] = REG_READ_BYTE(0x4001007A); + uuid[4] = REG_READ_BYTE(0x4001007B); + uuid[5] = REG_READ_BYTE(0x4001007C); + uuid[6] = REG_READ_BYTE(0x4001007D); + uuid[7] = REG_READ_BYTE(0x4001007E); +} + +/* BOD */ + +static const struct BOD_BOR_CFG_T default_bod_cfg = { + .level = BOD_BOR_TH_LVL0, + .hyst = BOD_BOR_HYST_LVL0, +}; + +void bod_open(const struct BOD_BOR_CFG_T *cfg) +{ + const struct BOD_BOR_CFG_T *config = (cfg == NULL) ? &default_bod_cfg : cfg; + + // enable BOD + uint32_t bod_bor_cfg = SYSCON->BOD_BOR; + bod_bor_cfg &= 0xFF00FFFF; + bod_bor_cfg |= SYSCON_BOD_EN_MSK | SYSCON_BOD_TH_SEL(config->level) | SYSCON_BOD_HYST_SEL(config->hyst); + SYSCON->BOD_BOR = bod_bor_cfg; + + NVIC_SetPriority(BOD_IRQn, IRQ_PRIORITY_NORMAL); + NVIC_ClearPendingIRQ(BOD_IRQn); + NVIC_EnableIRQ(BOD_IRQn); +} + +void bod_close(void) +{ + // disable BOD + SYSCON->BOD_BOR &= ~SYSCON_BOD_EN_MSK; + + NVIC_DisableIRQ(BOD_IRQn); + NVIC_ClearPendingIRQ(BOD_IRQn); +} + +void BOD_IRQHandler(void) +{ +} + +/* BOR */ + +static const struct BOD_BOR_CFG_T default_bor_cfg = { + .level = BOD_BOR_TH_LVL0, + .hyst = BOD_BOR_HYST_LVL0, +}; + +void bor_open(const struct BOD_BOR_CFG_T *cfg) +{ + const struct BOD_BOR_CFG_T *config = (cfg == NULL) ? &default_bor_cfg : cfg; + + // enable BOR + uint32_t bod_bor_cfg = SYSCON->BOD_BOR; + bod_bor_cfg &= 0xFFFFFF00; + bod_bor_cfg |= SYSCON_BOR_EN_MSK | SYSCON_BOR_TH_SEL(config->level) | SYSCON_BOR_HYST_SEL(config->hyst); + SYSCON->BOD_BOR = bod_bor_cfg; +} + +void bor_close(void) +{ + // disable BOD + SYSCON->BOD_BOR &= ~SYSCON_BOR_EN_MSK; +} + +/* SYS Timer */ + +uint32_t sys_timer_freq = 0; + +void sys_timer_open(void) +{ + // DIV = 1 (max: ~68.8s, resolution: ~16ns) + // DIV = 16 (max: ~1101.2s, resolution: ~256ns) + // DIV = 256 (max: ~17620.3s resolution: ~65us) + struct DUAL_TIMER_CFG_T sys_timer_cfg = { + .type = DUAL_TIMER_TYPE_FREERUNNING, + .prescale = DUAL_TIMER_PRESCALE_DIV1, + .width = DUAL_TIMER_SIZE_32BIT, + .int_en = false, + .load = 0xffffffff, + .callback = NULL, + }; + + dual_timer_open(DUAL_TIMER_ID0, &sys_timer_cfg); + dual_timer_start(DUAL_TIMER_ID0, sys_timer_cfg.load); + uint16_t div = sys_timer_cfg.prescale == DUAL_TIMER_PRESCALE_DIV1 ? 1 : sys_timer_cfg.prescale == DUAL_TIMER_PRESCALE_DIV16 ? 16 : 256; + sys_timer_freq = clock_get_frequency(CLOCK_APB_CLK) / div; +} + +void sys_timer_close(void) +{ + dual_timer_close(DUAL_TIMER_ID0); +} + +uint32_t sys_timer_get(void) +{ + return -dual_timer_get(DUAL_TIMER_ID0); +} + +// max: 68829 us (DIV = 1) +void sys_timer_delay_us(uint32_t time_us) +{ + uint32_t start = dual_timer_get(DUAL_TIMER_ID0); + uint32_t ticks = __US_TO_TICKS(time_us); + + while (start - dual_timer_get(DUAL_TIMER_ID0) < ticks) + { + } +} + +// max: 68829 ms (DIV = 1) +void sys_timer_delay_ms(uint32_t time_ms) +{ + uint32_t start = dual_timer_get(DUAL_TIMER_ID0); + uint32_t ticks = __MS_TO_TICKS(time_ms); + + while (start - dual_timer_get(DUAL_TIMER_ID0) < ticks) + { + } +} + +/* MAC timer */ + +void mac_timer_open(drv_callback_t callback) +{ + // DIV = 1 (max: ~68.8s, resolution: ~16ns) + // DIV = 16 (max: ~1101.2s, resolution: ~256ns) + // DIV = 256 (max: ~17620.3s resolution: ~65us) + struct DUAL_TIMER_CFG_T mac_timer_cfg = { + .type = DUAL_TIMER_TYPE_ONESHOT, + .prescale = DUAL_TIMER_PRESCALE_DIV1, + .width = DUAL_TIMER_SIZE_32BIT, + .int_en = true, + .load = 0xffffffff, + .callback = NULL, + }; + + mac_timer_cfg.callback = callback; + dual_timer_open(DUAL_TIMER_ID1, &mac_timer_cfg); +} + +void mac_timer_close(void) +{ + dual_timer_close(DUAL_TIMER_ID1); +} + +void mac_timer_start(uint32_t count) +{ + dual_timer_start(DUAL_TIMER_ID1, count); + // board_led_on(BOARD_LED_1); +} + +void mac_timer_stop(void) +{ + dual_timer_stop(DUAL_TIMER_ID1); + // board_led_off(BOARD_LED_1); +} + +/* SYS Tick */ + +static struct SYS_TICK_ENV_T sys_tick_env = {0}; + +void sys_tick_start(uint32_t ticks) +{ + ASSERT(ticks <= SysTick_LOAD_RELOAD_Msk + 1, "Reload value impossible\r\n"); + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority(SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* A write of any value clears the field to 0 */ + SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ +} + +uint32_t sys_tick_us(void) +{ + uint32_t lock = int_lock(); + + uint32_t count = sys_tick_env.count; + uint32_t load = SysTick->LOAD + 1; + uint32_t val = SysTick->VAL; + + uint32_t flag_pending = REG_READ(0xE000ED04) & (1 << 26); + if (flag_pending) + { + count += 1; + + val = load; + } + else if (val == 0) + { + val = load; + } + + uint32_t tick_us = (count * 328 + (load - val)) * 30; + + int_unlock(lock); + + return tick_us; +} + +uint32_t sys_tick_ms(void) +{ + uint32_t lock = int_lock(); + + uint32_t count = sys_tick_env.count; + uint32_t load = SysTick->LOAD + 1; + uint32_t val = SysTick->VAL; + + uint32_t flag_pending = REG_READ(0xE000ED04) & (1 << 26); + if (flag_pending) + { + count += 1; + + val = load; + } + else if (val == 0) + { + val = load; + } + + uint32_t tick_ms = (count * 10 + (load - val) * 10 / 328); + + int_unlock(lock); + + return tick_ms; +} + +uint32_t sys_tick_get(void) +{ + return sys_tick_env.count; +} + +void sys_tick_callback_set(void (*callback)(void)) +{ + sys_tick_env.callback = callback; +} + +uint32_t sys_tick_elapse_ms(void) +{ + uint32_t lock = int_lock(); + + uint32_t load = SysTick->LOAD + 1; + uint32_t val = SysTick->VAL; + + uint32_t flag_pending = REG_READ(0xE000ED04) & (1 << 26); + if (flag_pending) + { + val = 0; + } + else if (val == 0) + { + val = load; + } + + uint32_t elapse_ms = (load - val) * 10 / 328; + + int_unlock(lock); + + return elapse_ms; +} + +void sys_tick_pause(void) +{ + // Stop SysTick + SysTick->CTRL = 0; + uint32_t val = SysTick->VAL; + uint32_t load = SysTick->LOAD + 1; + uint32_t flag_pending = REG_READ(0xE000ED04) & (1 << 26); + + if (flag_pending) + { + sys_tick_env.count += 1; + val = load; + + // clear pending systick interrupt + REG_WRITE(0xE000ED04, (1 << 25)); + } + else if (val == 0) + { + val = load; + } + + // Store SysTick counter + sys_tick_env.load = load; + // SysTick->VAL cannot be set + sys_tick_env.elapse += (load - val); +} + +void sys_tick_resume(void) +{ + sys_tick_start(sys_tick_env.load); + + uint32_t slp_cnt = high_xtal_off_time(); + uint32_t cnt = slp_cnt / sys_tick_env.load; + sys_tick_env.elapse += (slp_cnt - cnt * sys_tick_env.load); + while (sys_tick_env.elapse >= sys_tick_env.load) + { + sys_tick_env.elapse -= sys_tick_env.load; + cnt += 1; + } + + sys_tick_env.count += cnt; + if ((sys_tick_env.callback != NULL) && (cnt)) + { + sys_tick_env.callback(); + } +} + +void SysTick_Handler(void) +{ + // board_led_on(BOARD_LED_2); + sys_tick_env.count++; + if (sys_tick_env.callback != NULL) + { + sys_tick_env.callback(); + } + // board_led_off(BOARD_LED_2); +} + +void sys_reset(uint32_t error) +{ + //LOG_INFO(TRACE_MODULE_DRIVER, "system reboot%x", error); + + delay_us(10000); + + // reboot + reset_module(RESET_MODULE_REBOOT); +} + +void delay_us(uint32_t cnt) +{ +#define SYSTEM_CLOCK_MHZ 62.4 + +// the larger LSLS bits the more accurate of this delay function but the shorter of available delay time +#define SYSTEM_CLOCK_LSLS_BITS 5 +#define SYSTEM_CLOCK_LSLS (uint16_t)(SYSTEM_CLOCK_MHZ * (1 << SYSTEM_CLOCK_LSLS_BITS)) + +// you should adjust these num manually if SYSTEM_CLOCK_MHZ or SYSTEM_CLOCK_LSLS_BITS changes +#define SYSTEM_CLOCK_MULT_HI 0x07 // (uint8_t)((SYSTEM_CLOCK_LSLS & 0xFF00) >> 8) +#define SYSTEM_CLOCK_MULT_LO 0xCD // (uint8_t)(SYSTEM_CLOCK_LSLS & 0x00FF) + +#define AAPCS_PREP_CYCLES 18 +#define DELAY_LOOP_CYCLES 4 + +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) + __asm volatile(".syntax unified\n"); +#endif + + __asm volatile( + "cmp r0, #0\n" + "beq exit%=\n" + "push {r4,r5}\n" + "movs r5, %[mult_hi]\n" + "lsls r4, r5, #8\n" + "movs r5, %[mult_lo]\n" + "adds r4, r4, r5\n" + "muls r0, r4\n" + "lsrs r0, r0, %[shift]\n" + "subs r0, r0, %[adjust]\n" + "loop%=:\n" + "subs r0, r0, %[decr]\n" + "bhi loop%=\n" + "pop {r4,r5}\n" + "exit%=:\n" + : + : [mult_hi] "i"(SYSTEM_CLOCK_MULT_HI), [mult_lo] "i"(SYSTEM_CLOCK_MULT_LO), [shift] "i"(SYSTEM_CLOCK_LSLS_BITS), [adjust] "i"(AAPCS_PREP_CYCLES), + [decr] "i"(DELAY_LOOP_CYCLES)); + +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) + __asm volatile(".syntax divided\n"); +#endif +} + +uint8_t count_bits(uint32_t value) +{ + uint8_t count = 0; + while (value) + { + value &= value - 1; + count++; + } + return count; +} + +uint8_t search_byte_right_one(uint8_t value) +{ + uint8_t index = 1; + if (value == 0) + { + return 0; + } + + if ((value & 0x0F) == 0) + { + value >>= 4; + index += 4; + } + + if ((value & 0x03) == 0) + { + value >>= 2; + index += 2; + } + + if ((value & 0x01) == 0) + { + index += 1; + } + return index; +} + +uint8_t byte_right_one_mask(uint8_t value) +{ + return (value & (~value + 1)); +} + +int32_t average_filter(int32_t input) +{ +#define TOTAL_SAMPLES (5) +#if 1 + // arithmetical averaging + static int32_t data_buffer[TOTAL_SAMPLES] = {0}; + static uint8_t data_num = 0; + int64_t sum = 0; + + // if buffer is full, remove the oldest data + if (data_num == TOTAL_SAMPLES) + { + data_num--; + } + + // add a new data in buffer + for (int i = data_num; i > 0; i--) + { + data_buffer[i] = data_buffer[i - 1]; + sum += data_buffer[i]; + } + data_buffer[0] = input; + sum += data_buffer[0]; + data_num++; + + return (int32_t)(sum / data_num); +#else + // weighted averaging +#endif +} + +int16_t mk_q7_to_s16(int16_t data) +{ + return (data / 128); +} + +int16_t mk_s16_to_q7(int16_t data) +{ + return (data * 128); +} + +float mk_q7_to_f32(int16_t data) +{ + return (float)(data / 128.0); +} + +int16_t mk_f32_to_q7(float data) +{ + return (int16_t)(data * 128); +} -- Gitblit v1.9.3