feat(Puya-PY32F040): add OTA dual-project codegen template
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+120
@@ -0,0 +1,120 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AlignConsecutiveMacros: true # 宏定义对齐(若存在宏)
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false # 赋值对齐
|
||||
AlignConsecutiveDeclarations: false # 变量声明对齐
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true # 保持行尾注释对齐(可选)
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: MultiLine
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 0
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IndentCaseLabels: false
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
|
||||
...
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
# =============================================================================
|
||||
# PY32F040 OTA 开发框架 — Git 忽略规则
|
||||
# 原则:只跟踪源码/工程/契约/文档;编译产物与 IDE 个人配置不入库
|
||||
# =============================================================================
|
||||
|
||||
# ── Keil MDK 编译产物(App / Bootloader 两工程)────────────────────────────
|
||||
**/MDK-ARM/Objects/
|
||||
**/MDK-ARM/Listings/
|
||||
**/MDK-ARM/Output/
|
||||
|
||||
# App 侧历史 hex 输出目录
|
||||
App/Output/
|
||||
|
||||
# ── 顶层构建输出(build_all.py / merge_hex.py / pack.py)────────────────────
|
||||
Output/
|
||||
|
||||
# ── Keil 个人/本地 IDE 配置 ─────────────────────────────────────────────────
|
||||
*.uvguix*
|
||||
*.uvoptx
|
||||
*.scvd
|
||||
**/MDK-ARM/Prg_Output.txt
|
||||
**/MDK-ARM/Build_Output.txt
|
||||
**/MDK-ARM/JLinkLog.txt
|
||||
|
||||
# DebugConfig/*.dbgconf 建议保留入库(芯片调试配置,团队可共享)
|
||||
|
||||
# ── 中间文件扩展名(散落于工程目录时兜底)──────────────────────────────────
|
||||
*.o
|
||||
*.d
|
||||
*.crf
|
||||
*.axf
|
||||
*.lnp
|
||||
*.dep
|
||||
*.htm
|
||||
*.map
|
||||
*.lst
|
||||
*.iex
|
||||
*.sct.bak
|
||||
*_sct.Bak
|
||||
*.bak
|
||||
|
||||
# ── 固件二进制(应由 CI/本地构建生成,不入库)──────────────────────────────
|
||||
*.hex
|
||||
*.bin
|
||||
*.elf
|
||||
*.zip
|
||||
|
||||
# 例外:若需跟踪某份参考 hex,可用 git add -f 强制加入
|
||||
|
||||
# ── 日志与临时文件 ─────────────────────────────────────────────────────────
|
||||
Log/
|
||||
*.log
|
||||
|
||||
# ── 编辑器 / Agent / Python ─────────────────────────────────────────────────
|
||||
.vscode/
|
||||
.cursor/
|
||||
.idea/
|
||||
*.swp
|
||||
*~
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
.Python
|
||||
*.egg-info/
|
||||
.eggs/
|
||||
|
||||
# ── OS 杂项 ─────────────────────────────────────────────────────────────────
|
||||
Thumbs.db
|
||||
Desktop.ini
|
||||
.DS_Store
|
||||
@@ -0,0 +1,99 @@
|
||||
/******************************************************************************
|
||||
* @file app_boot.c
|
||||
* @brief APP 启动流程(Bootloader 交接、时钟、IWDG、OTA 确认)
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.18
|
||||
* @version V1.0.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.18, cyWu, 从 main.c 拆出启动逻辑
|
||||
******************************************************************************/
|
||||
|
||||
#include "app_boot.h"
|
||||
#include "application.h"
|
||||
#include "iwdg.h"
|
||||
#include "ota_ab.h"
|
||||
#include "main.h"
|
||||
|
||||
/**
|
||||
* @brief 从 Bootloader 跳转过来后,重新打开全局中断
|
||||
*
|
||||
* Bootloader 跳转 APP 前会 __disable_irq(),且函数跳转不会复位芯片,
|
||||
* 因此 PRIMASK 仍为 1(中断关)。APP 第一件事须 __enable_irq(),
|
||||
* 否则 SysTick / TIM6 / UART 等中断进不来,HAL_Delay、协议超时都会失效。
|
||||
*/
|
||||
static void app_boot_early_handover(void)
|
||||
{
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 配置 APP 系统时钟(HSI → PLL → SYSCLK)
|
||||
*
|
||||
* 与官网例程的差异:OscillatorType 故意不含 LSI。
|
||||
* Bootloader 跳转前已启动 IWDG,IWDG 运行期间 LSI 被硬件锁定关不掉;
|
||||
* 若在此配置 LSI OFF,HAL_RCC_OscConfig 会卡死等待 LSIRDY 变 0。
|
||||
* LSI 由 IWDG 维持即可,APP 只配置 HSI/PLL 主时钟树。
|
||||
*/
|
||||
static void app_system_clock_config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
|
||||
/* 主时钟:HSI 24MHz → PLL,不含 LSI(见上方说明) */
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
|
||||
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_24MHz;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
|
||||
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
|
||||
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
|
||||
{
|
||||
Error_Handler(__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 双备份 OTA:新固件启动确认后,上报一次升级完成(0x34)
|
||||
*
|
||||
* 须在 app_Init() 之后调用(依赖 uartInit / jbInit)。
|
||||
* ota_boot_check_confirm() 已将 Flash 置为 IDLE,0x34 仅为尽力通知云端;
|
||||
* 发一次即可,丢帧由 jbSendOtaResult 内 SEND_MAX_NUM 重传兜底。
|
||||
*/
|
||||
static void app_boot_ota_report(void)
|
||||
{
|
||||
uint8_t ver[3];
|
||||
|
||||
if (!ota_boot_check_confirm())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ver[0] = JB_MCU_SW_VERSION_MAJOR;
|
||||
ver[1] = JB_MCU_SW_VERSION_MINOR;
|
||||
ver[2] = JB_MCU_SW_VERSION_PATCH;
|
||||
(void)jbSendOtaResult(JB_OK, ver);
|
||||
appPrintf(LOG_NOTIC, "OTA upgrade complete reported\r\n");
|
||||
}
|
||||
|
||||
void app_startup(void)
|
||||
{
|
||||
app_boot_early_handover();
|
||||
HAL_Init();
|
||||
iwdg_init();
|
||||
app_system_clock_config();
|
||||
app_Init();
|
||||
app_boot_ota_report();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef __APP_BOOT_H
|
||||
#define __APP_BOOT_H
|
||||
|
||||
/**
|
||||
* @brief APP 启动入口:Bootloader 交接 → HAL/时钟/IWDG → 应用初始化 → OTA 确认
|
||||
*/
|
||||
void app_startup(void);
|
||||
|
||||
#endif /* __APP_BOOT_H */
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef __FLASH_H
|
||||
#define __FLASH_H
|
||||
|
||||
#include "main.h"
|
||||
#include "ota_config.h"
|
||||
|
||||
void APP_FlashWrite(uint32_t PageAddress, uint8_t *Data, uint32_t DataSize);
|
||||
void APP_FlashRead(uint32_t PageAddress, uint8_t *Data, uint32_t DataSize);
|
||||
void APP_FlashEraseWithCheck(uint32_t PageAddress, uint32_t DataSize);
|
||||
|
||||
/* OTA 状态区读写(AB:4 页轮换磨损均衡;SINGLE:固定页 0 直写) */
|
||||
void ota_param_load(ota_param_t *p);
|
||||
void ota_param_store(const ota_param_t *p);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
/******************************************************************************
|
||||
* @file iwdg.c
|
||||
* @brief 独立看门狗(HAL 封装)
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.18
|
||||
* @version V1.1.0
|
||||
* @history
|
||||
* - V1.1.0, 2026.08.18, cyWu, 改用 HAL_IWDG,参数见 Shared/iwdg_config.h
|
||||
* - V1.0.0, 2026.08.18, cyWu, 首次发布(寄存器版)
|
||||
******************************************************************************/
|
||||
|
||||
#include "iwdg.h"
|
||||
#include "main.h"
|
||||
#include "iwdg_config.h"
|
||||
|
||||
static IWDG_HandleTypeDef s_hiwdg;
|
||||
|
||||
/**
|
||||
* @brief 初始化/接管 IWDG(Bootloader 可能已启动,HAL 调用幂等)
|
||||
*/
|
||||
void iwdg_init(void)
|
||||
{
|
||||
s_hiwdg.Instance = IWDG;
|
||||
s_hiwdg.Init.Prescaler = IWDG_PRESCALER_16;
|
||||
s_hiwdg.Init.Reload = IWDG_RELOAD_VALUE;
|
||||
|
||||
if (HAL_IWDG_Init(&s_hiwdg) != HAL_OK)
|
||||
{
|
||||
Error_Handler(__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 喂狗,主循环周期调用(间隔须小于超时时间)
|
||||
*/
|
||||
void iwdg_feed(void)
|
||||
{
|
||||
(void)HAL_IWDG_Refresh(&s_hiwdg);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef __IWDG_H
|
||||
#define __IWDG_H
|
||||
|
||||
/**
|
||||
* @brief 独立看门狗 HAL 封装(参数见 Shared/iwdg_config.h)
|
||||
*
|
||||
* Bootloader 跳转前可能已启动 IWDG;APP 须在 HAL_Init 后尽早 iwdg_init()。
|
||||
* 时钟配置勿关闭 LSI,详见 app_boot.c 中 app_system_clock_config()。
|
||||
*/
|
||||
|
||||
void iwdg_init(void);
|
||||
void iwdg_feed(void);
|
||||
|
||||
#endif /* __IWDG_H */
|
||||
@@ -0,0 +1,66 @@
|
||||
/******************************************************************************
|
||||
* @file jb_port.c
|
||||
* @brief 协议硬件对接层:串口/定时器 ↔ 协议 API
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.10
|
||||
* @version V1.0.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.10, cyWu, 首次发布
|
||||
******************************************************************************/
|
||||
|
||||
#include "jb_port.h"
|
||||
#include "jb_uart.h"
|
||||
#include "jb_timer.h"
|
||||
#include "jb_protocol.h"
|
||||
#include "main.h"
|
||||
|
||||
/**
|
||||
* @brief UART RX 单字节 → 协议环形缓冲(不放在 jb_product 中)
|
||||
* @param byte 收到的字节
|
||||
*/
|
||||
static void jb_port_on_uart_rx(uint8_t byte)
|
||||
{
|
||||
jbPutData(&byte, 1U);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化协议串口
|
||||
*/
|
||||
void jb_port_uart_init(void)
|
||||
{
|
||||
jb_uart_set_rx_callback(jb_port_on_uart_rx);
|
||||
if (jb_uart_init() != JB_UART_OK)
|
||||
{
|
||||
Error_Handler((uint8_t *)__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 协议串口发送
|
||||
* @param buf 数据
|
||||
* @param len 长度
|
||||
* @return 成功返回 len,失败 -1
|
||||
*/
|
||||
int32_t jb_port_uart_write(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
return jb_uart_write(buf, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 主循环串口处理
|
||||
*/
|
||||
void jb_port_uart_run(void)
|
||||
{
|
||||
jb_uart_run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化 1ms 定时器硬件
|
||||
*/
|
||||
void jb_port_timer_init(void)
|
||||
{
|
||||
if (jb_timer_init() != JB_TIMER_OK)
|
||||
{
|
||||
Error_Handler((uint8_t *)__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/******************************************************************************
|
||||
* @file jb_port.h
|
||||
* @brief 协议硬件对接层(与自动生成的 jb_product 解耦)
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.10
|
||||
* @version V1.0.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.10, cyWu, 首次发布
|
||||
*
|
||||
* @note
|
||||
* 移植新协议生成代码时:
|
||||
* 1. 覆盖 Protocol/jb_*.c/h(保留本文件不改)
|
||||
* 2. 在 jb_product.c 的 uartInit/timerInit/uartWrite 中各填一行 jb_port_xxx
|
||||
* 3. jbTimerIrq / jbGetTimerCount / timerMs 保持生成模板原样
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __JB_PORT_H__
|
||||
#define __JB_PORT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief 初始化协议串口(含 RX→jbPutData 回调注册)
|
||||
*/
|
||||
void jb_port_uart_init(void);
|
||||
|
||||
/**
|
||||
* @brief 协议串口发送
|
||||
* @param buf 数据
|
||||
* @param len 长度
|
||||
* @return 成功返回 len,失败返回 -1
|
||||
*/
|
||||
int32_t jb_port_uart_write(uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief 主循环调用:串口调试日志等
|
||||
*/
|
||||
void jb_port_uart_run(void);
|
||||
|
||||
/**
|
||||
* @brief 初始化协议用 1ms 定时器硬件(TIM6)
|
||||
*/
|
||||
void jb_port_timer_init(void);
|
||||
|
||||
#endif /* __JB_PORT_H__ */
|
||||
@@ -0,0 +1,86 @@
|
||||
/******************************************************************************
|
||||
* @file jb_timer.c
|
||||
* @brief TIM6 1ms 基础定时器硬件驱动实现
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.10
|
||||
* @version V1.0.1
|
||||
* @history
|
||||
* - V1.0.1, 2026.08.10, cyWu, 软件 ms 计数交还协议层,本模块仅负责 TIM6 硬件
|
||||
* - V1.0.0, 2026.08.10, cyWu, 首次发布
|
||||
******************************************************************************/
|
||||
|
||||
#include "jb_timer.h"
|
||||
#include "log.h"
|
||||
|
||||
/*============================================================================*/
|
||||
/* 私有变量 */
|
||||
/*============================================================================*/
|
||||
|
||||
TIM_HandleTypeDef g_jb_tim_handle;
|
||||
static uint8_t s_initialized;
|
||||
|
||||
/*============================================================================*/
|
||||
/* 公有接口 */
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief 初始化 TIM6 为 1ms 周期中断
|
||||
* @return JbTimer_Ret_t
|
||||
*/
|
||||
JbTimer_Ret_t jb_timer_init(void)
|
||||
{
|
||||
uint32_t pclk1;
|
||||
uint32_t tim_clk;
|
||||
|
||||
if (s_initialized)
|
||||
{
|
||||
return JB_TIMER_OK;
|
||||
}
|
||||
|
||||
/* APB 不分频时 TIMCLK=PCLK1;分频时 TIMCLK=2*PCLK1 */
|
||||
pclk1 = HAL_RCC_GetPCLK1Freq();
|
||||
if ((RCC->CFGR & RCC_CFGR_PPRE) == RCC_HCLK_DIV1)
|
||||
{
|
||||
tim_clk = pclk1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tim_clk = pclk1 * 2U;
|
||||
}
|
||||
|
||||
g_jb_tim_handle.Instance = JB_TIMER;
|
||||
g_jb_tim_handle.Init.Prescaler = (tim_clk / 1000000U) - 1U;
|
||||
g_jb_tim_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
g_jb_tim_handle.Init.Period = (1000U * JB_TIMER_PERIOD_MS) - 1U;
|
||||
g_jb_tim_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
g_jb_tim_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
g_jb_tim_handle.Init.RepetitionCounter = 0;
|
||||
|
||||
if (HAL_TIM_Base_Init(&g_jb_tim_handle) != HAL_OK)
|
||||
{
|
||||
return JB_TIMER_ERR_HAL;
|
||||
}
|
||||
|
||||
if (HAL_TIM_Base_Start_IT(&g_jb_tim_handle) != HAL_OK)
|
||||
{
|
||||
return JB_TIMER_ERR_HAL;
|
||||
}
|
||||
|
||||
s_initialized = 1U;
|
||||
appPrintf(LOG_NOTIC, "TIM6 1ms timer started, pclk=%lu tim_clk=%lu\r\n",
|
||||
(unsigned long)pclk1, (unsigned long)tim_clk);
|
||||
return JB_TIMER_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取初始化状态
|
||||
* @return JbTimer_Ret_t
|
||||
*/
|
||||
JbTimer_Ret_t jb_timer_get_status(void)
|
||||
{
|
||||
if (!s_initialized)
|
||||
{
|
||||
return JB_TIMER_ERR_NOT_INIT;
|
||||
}
|
||||
return JB_TIMER_OK;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/******************************************************************************
|
||||
* @file jb_timer.h
|
||||
* @brief TIM6 1ms 基础定时器硬件驱动(ms 计数由协议层 jbTimerIrq 维护)
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.10
|
||||
* @version V1.0.1
|
||||
* @history
|
||||
* - V1.0.1, 2026.08.10, cyWu, 软件 ms 计数交还协议层,本模块仅负责 TIM6 硬件
|
||||
* - V1.0.0, 2026.08.10, cyWu, 首次发布
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __JB_TIMER_H__
|
||||
#define __JB_TIMER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "py32f0xx_hal.h"
|
||||
|
||||
/*============================================================================*/
|
||||
/* 宏定义 */
|
||||
/*============================================================================*/
|
||||
|
||||
#ifndef JB_TIMER_PERIOD_MS
|
||||
#define JB_TIMER_PERIOD_MS (1U) /**< 定时周期 ms */
|
||||
#endif
|
||||
|
||||
#define JB_TIMER TIM6
|
||||
#define JB_TIMER_IRQn TIM6_LPTIM1_IRQn
|
||||
#define JB_TIMER_CLK_ENABLE() __HAL_RCC_TIM6_CLK_ENABLE()
|
||||
|
||||
/*============================================================================*/
|
||||
/* 错误码 */
|
||||
/*============================================================================*/
|
||||
|
||||
typedef enum {
|
||||
JB_TIMER_OK = 0,
|
||||
JB_TIMER_ERR_PARAM,
|
||||
JB_TIMER_ERR_BUSY,
|
||||
JB_TIMER_ERR_TIMEOUT,
|
||||
JB_TIMER_ERR_NOT_INIT,
|
||||
JB_TIMER_ERR_HAL,
|
||||
JB_TIMER_ERR_UNKNOWN
|
||||
} JbTimer_Ret_t;
|
||||
|
||||
/*============================================================================*/
|
||||
/* 句柄(供 MSP / IRQ) */
|
||||
/*============================================================================*/
|
||||
|
||||
extern TIM_HandleTypeDef g_jb_tim_handle;
|
||||
#define TimHandle g_jb_tim_handle
|
||||
|
||||
/*============================================================================*/
|
||||
/* 外部接口 */
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief 初始化 TIM6 为 1ms 周期中断
|
||||
* @note 更新回调中应调用协议层 jbTimerIrq(),由协议维护 timerMs
|
||||
* @return JbTimer_Ret_t
|
||||
*/
|
||||
JbTimer_Ret_t jb_timer_init(void);
|
||||
|
||||
/**
|
||||
* @brief 获取初始化状态
|
||||
* @return JbTimer_Ret_t
|
||||
*/
|
||||
JbTimer_Ret_t jb_timer_get_status(void);
|
||||
|
||||
#endif /* __JB_TIMER_H__ */
|
||||
@@ -0,0 +1,280 @@
|
||||
/******************************************************************************
|
||||
* @file jb_uart.c
|
||||
* @brief USART3 协议串口驱动实现
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.10
|
||||
* @version V1.0.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.10, cyWu, 首次发布
|
||||
******************************************************************************/
|
||||
|
||||
#include "jb_uart.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*============================================================================*/
|
||||
/* 私有宏 */
|
||||
/*============================================================================*/
|
||||
|
||||
#define UART_DBG_BUF_SIZE (256U)
|
||||
#define UART_DBG_IDLE_MS (30U)
|
||||
/* 协议 MAX_PACKAGE_LEN(128) + 前置 0x00 */
|
||||
#define JB_UART_TX_MAX_LEN (129U)
|
||||
|
||||
/*============================================================================*/
|
||||
/* 私有变量 */
|
||||
/*============================================================================*/
|
||||
|
||||
UART_HandleTypeDef g_jb_uart_handle;
|
||||
|
||||
static uint8_t s_initialized;
|
||||
static uint8_t s_uart_rx_byte;
|
||||
static JbUartRxCallback_t s_rx_cb;
|
||||
|
||||
static uint8_t s_dbg_buf[UART_DBG_BUF_SIZE];
|
||||
static volatile uint16_t s_dbg_head;
|
||||
static volatile uint16_t s_dbg_tail;
|
||||
static volatile uint32_t s_dbg_last_rx_ms;
|
||||
static volatile uint32_t s_rx_total;
|
||||
static volatile uint32_t s_err_code;
|
||||
static volatile uint8_t s_err_pending;
|
||||
|
||||
/*============================================================================*/
|
||||
/* 私有函数 */
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief ISR 安全:调试缓冲写入 1 字节
|
||||
* @param byte 数据
|
||||
*/
|
||||
static void uart_dbg_push(uint8_t byte)
|
||||
{
|
||||
uint16_t next = (uint16_t)((s_dbg_head + 1U) % UART_DBG_BUF_SIZE);
|
||||
|
||||
if (next == s_dbg_tail)
|
||||
{
|
||||
s_dbg_tail = (uint16_t)((s_dbg_tail + 1U) % UART_DBG_BUF_SIZE);
|
||||
}
|
||||
s_dbg_buf[s_dbg_head] = byte;
|
||||
s_dbg_head = next;
|
||||
s_dbg_last_rx_ms = HAL_GetTick();
|
||||
s_rx_total++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 打印十六进制
|
||||
* @param tag 标签
|
||||
* @param buf 数据
|
||||
* @param len 长度
|
||||
*/
|
||||
static void uart_dbg_print_hex(const char *tag, const uint8_t *buf, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
printf("UART %s %lu bytes:", tag, (unsigned long)len);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
printf(" %02X", buf[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 刷出 RX 调试与错误日志
|
||||
*/
|
||||
static void uart_dbg_flush(void)
|
||||
{
|
||||
uint8_t dump[UART_DBG_BUF_SIZE];
|
||||
uint16_t dump_len = 0;
|
||||
uint16_t tail;
|
||||
uint16_t head;
|
||||
|
||||
if (s_err_pending)
|
||||
{
|
||||
s_err_pending = 0;
|
||||
printf("UART RX error: 0x%08lX, total_rx=%lu\r\n",
|
||||
(unsigned long)s_err_code,
|
||||
(unsigned long)s_rx_total);
|
||||
}
|
||||
|
||||
head = s_dbg_head;
|
||||
tail = s_dbg_tail;
|
||||
if (head == tail)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((HAL_GetTick() - s_dbg_last_rx_ms) < UART_DBG_IDLE_MS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while ((tail != head) && (dump_len < UART_DBG_BUF_SIZE))
|
||||
{
|
||||
dump[dump_len++] = s_dbg_buf[tail];
|
||||
tail = (uint16_t)((tail + 1U) % UART_DBG_BUF_SIZE);
|
||||
}
|
||||
s_dbg_tail = tail;
|
||||
|
||||
uart_dbg_print_hex("RX", dump, dump_len);
|
||||
printf("UART RX total=%lu\r\n", (unsigned long)s_rx_total);
|
||||
}
|
||||
|
||||
/*============================================================================*/
|
||||
/* 公有接口 */
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief 注册 RX 回调
|
||||
* @param cb 回调
|
||||
*/
|
||||
void jb_uart_set_rx_callback(JbUartRxCallback_t cb)
|
||||
{
|
||||
s_rx_cb = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化 USART3
|
||||
* @return JbUart_Ret_t
|
||||
*/
|
||||
JbUart_Ret_t jb_uart_init(void)
|
||||
{
|
||||
if (s_initialized)
|
||||
{
|
||||
return JB_UART_OK;
|
||||
}
|
||||
|
||||
g_jb_uart_handle.Instance = JB_USART;
|
||||
g_jb_uart_handle.Init.BaudRate = JB_UART_BAUDRATE;
|
||||
g_jb_uart_handle.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
g_jb_uart_handle.Init.StopBits = UART_STOPBITS_1;
|
||||
g_jb_uart_handle.Init.Parity = UART_PARITY_NONE;
|
||||
g_jb_uart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
g_jb_uart_handle.Init.Mode = UART_MODE_TX_RX;
|
||||
g_jb_uart_handle.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
g_jb_uart_handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
|
||||
if (HAL_UART_Init(&g_jb_uart_handle) != HAL_OK)
|
||||
{
|
||||
return JB_UART_ERR_HAL;
|
||||
}
|
||||
|
||||
if (HAL_UART_Receive_IT(&g_jb_uart_handle, &s_uart_rx_byte, 1U) != HAL_OK)
|
||||
{
|
||||
return JB_UART_ERR_HAL;
|
||||
}
|
||||
|
||||
s_initialized = 1U;
|
||||
printf("USART3 ready: PB10=TX PB11=RX baud=%lu 8N1, waiting RX...\r\n",
|
||||
(unsigned long)JB_UART_BAUDRATE);
|
||||
return JB_UART_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 主循环周期处理
|
||||
*/
|
||||
void jb_uart_run(void)
|
||||
{
|
||||
if (!s_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uart_dbg_flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 阻塞发送
|
||||
* @param buf 数据
|
||||
* @param len 长度
|
||||
* @return 成功返回 len,失败 -1
|
||||
*/
|
||||
int32_t jb_uart_write(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
static uint8_t s_tx_buf[JB_UART_TX_MAX_LEN];
|
||||
uint32_t tx_len;
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (len == 0U)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!s_initialized)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if ((len + 1U) > JB_UART_TX_MAX_LEN)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 协议帧前加 0x00 后连续发送,避免越界读与帧间空隙 */
|
||||
s_tx_buf[0] = 0x00U;
|
||||
s_tx_buf[1] = 0x00U;
|
||||
memcpy(&s_tx_buf[2], buf, len);
|
||||
tx_len = len + 2U;
|
||||
|
||||
uart_dbg_print_hex("TX", s_tx_buf, tx_len);
|
||||
|
||||
if (HAL_UART_Transmit(&g_jb_uart_handle, s_tx_buf, (uint16_t)tx_len, 1000U) != HAL_OK)
|
||||
{
|
||||
printf("UART TX failed, len=%lu\r\n", (unsigned long)tx_len);
|
||||
return -1;
|
||||
}
|
||||
return (int32_t)len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取初始化状态
|
||||
* @return JbUart_Ret_t
|
||||
*/
|
||||
JbUart_Ret_t jb_uart_get_status(void)
|
||||
{
|
||||
if (!s_initialized)
|
||||
{
|
||||
return JB_UART_ERR_NOT_INIT;
|
||||
}
|
||||
return JB_UART_OK;
|
||||
}
|
||||
|
||||
/*============================================================================*/
|
||||
/* HAL 回调 */
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief UART RX 完成回调
|
||||
* @param huart 句柄
|
||||
*/
|
||||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart->Instance == JB_USART)
|
||||
{
|
||||
uart_dbg_push(s_uart_rx_byte);
|
||||
if (s_rx_cb != NULL)
|
||||
{
|
||||
s_rx_cb(s_uart_rx_byte);
|
||||
}
|
||||
(void)HAL_UART_Receive_IT(&g_jb_uart_handle, &s_uart_rx_byte, 1U);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART 错误回调
|
||||
* @param huart 句柄
|
||||
*/
|
||||
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart->Instance == JB_USART)
|
||||
{
|
||||
s_err_code = HAL_UART_GetError(huart);
|
||||
s_err_pending = 1U;
|
||||
__HAL_UART_CLEAR_PEFLAG(huart);
|
||||
__HAL_UART_CLEAR_FEFLAG(huart);
|
||||
__HAL_UART_CLEAR_NEFLAG(huart);
|
||||
__HAL_UART_CLEAR_OREFLAG(huart);
|
||||
(void)HAL_UART_Receive_IT(&g_jb_uart_handle, &s_uart_rx_byte, 1U);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/******************************************************************************
|
||||
* @file jb_uart.h
|
||||
* @brief USART3 协议串口驱动(PB10=TX / PB11=RX)
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.10
|
||||
* @version V1.0.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.10, cyWu, 首次发布
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __JB_UART_H__
|
||||
#define __JB_UART_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "py32f0xx_hal.h"
|
||||
|
||||
/*============================================================================*/
|
||||
/* 宏定义(PY32F040 手册 PortB AF:PB10/PB11 = USART3 @ AF4) */
|
||||
/*============================================================================*/
|
||||
|
||||
#ifndef JB_UART_BAUDRATE
|
||||
#define JB_UART_BAUDRATE (9600U)
|
||||
#endif
|
||||
|
||||
#define JB_USART USART3
|
||||
#define JB_USART_IRQn USART3_4_IRQn
|
||||
#define JB_USART_CLK_ENABLE() __HAL_RCC_USART3_CLK_ENABLE()
|
||||
|
||||
#define JB_USART_TX_PIN GPIO_PIN_10
|
||||
#define JB_USART_TX_GPIO_PORT GPIOB
|
||||
#define JB_USART_TX_AF GPIO_AF4_USART3
|
||||
#define JB_USART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
|
||||
|
||||
#define JB_USART_RX_PIN GPIO_PIN_11
|
||||
#define JB_USART_RX_GPIO_PORT GPIOB
|
||||
#define JB_USART_RX_AF GPIO_AF4_USART3
|
||||
#define JB_USART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
|
||||
|
||||
/*============================================================================*/
|
||||
/* 错误码 */
|
||||
/*============================================================================*/
|
||||
|
||||
typedef enum {
|
||||
JB_UART_OK = 0,
|
||||
JB_UART_ERR_PARAM,
|
||||
JB_UART_ERR_BUSY,
|
||||
JB_UART_ERR_TIMEOUT,
|
||||
JB_UART_ERR_NOT_INIT,
|
||||
JB_UART_ERR_HAL,
|
||||
JB_UART_ERR_UNKNOWN
|
||||
} JbUart_Ret_t;
|
||||
|
||||
/**
|
||||
* @brief 单字节 RX 回调(上层注册,驱动不依赖协议)
|
||||
* @param byte 收到的字节
|
||||
*/
|
||||
typedef void (*JbUartRxCallback_t)(uint8_t byte);
|
||||
|
||||
/*============================================================================*/
|
||||
/* 句柄(供 MSP / IRQ) */
|
||||
/*============================================================================*/
|
||||
|
||||
extern UART_HandleTypeDef g_jb_uart_handle;
|
||||
#define UartHandle g_jb_uart_handle
|
||||
|
||||
/*============================================================================*/
|
||||
/* 外部接口 */
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief 注册 RX 回调(建议在 jb_uart_init 前调用)
|
||||
* @param cb 回调,NULL 表示不向上层投递
|
||||
*/
|
||||
void jb_uart_set_rx_callback(JbUartRxCallback_t cb);
|
||||
|
||||
/**
|
||||
* @brief 初始化 USART3:9600 8N1 + RX 中断
|
||||
* @return JbUart_Ret_t
|
||||
*/
|
||||
JbUart_Ret_t jb_uart_init(void);
|
||||
|
||||
/**
|
||||
* @brief 主循环调用:刷出 RX 调试日志
|
||||
*/
|
||||
void jb_uart_run(void);
|
||||
|
||||
/**
|
||||
* @brief 阻塞发送
|
||||
* @param buf 数据
|
||||
* @param len 长度
|
||||
* @return 成功返回 len,失败返回 -1
|
||||
*/
|
||||
int32_t jb_uart_write(uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief 获取初始化状态
|
||||
* @return JbUart_Ret_t
|
||||
*/
|
||||
JbUart_Ret_t jb_uart_get_status(void);
|
||||
|
||||
#endif /* __JB_UART_H__ */
|
||||
@@ -0,0 +1,290 @@
|
||||
/******************************************************************************
|
||||
* @file ota_ab.c
|
||||
* @brief APP 侧 OTA 下载实现:收固件 → 写入备份区 → CRC 校验 → 通知 Bootloader
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.18
|
||||
* @version V1.0.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.18, cyWu, 补充注释(逻辑与原先一致)
|
||||
*
|
||||
* 本文件只负责「下载阶段」,不负责把新固件切到运行区。
|
||||
* 切换/拷贝由复位后的 Bootloader 根据状态区 PENDING 完成:
|
||||
*
|
||||
* 协议 0x30 ota_start() 擦备份区,准备接收
|
||||
* 协议 0x32 ota_receive_chunk() 分片写入备份区(页缓冲)
|
||||
* ota_finish() 长度+CRC 通过后写 PENDING
|
||||
* 复位
|
||||
* Bootloader 读到 PENDING 单备份:拷贝到运行区
|
||||
* 双备份:A/B 交换后写 BOOT_NEW
|
||||
* 新 APP ota_boot_check_confirm() 双备份首次启动确认(单备份恒 false)
|
||||
******************************************************************************/
|
||||
|
||||
#include "ota_ab.h"
|
||||
#include "flash.h"
|
||||
#include "crc32.h"
|
||||
#include "log.h"
|
||||
|
||||
/*============================================================================*/
|
||||
/* 私有变量 */
|
||||
/*============================================================================*/
|
||||
|
||||
static ota_param_t g_ota; /**< 本次升级参数(长度/CRC/状态),结束时写入状态区 */
|
||||
static uint32_t g_crc_acc; /**< 流式 CRC32 累加器,边收边算,不必整包再读 Flash */
|
||||
static uint32_t g_recv_len; /**< 已接收且计入固件的字节数(不含尾包填充) */
|
||||
static bool g_running; /**< true=正在收包;abort/finish 后清掉 */
|
||||
|
||||
/*
|
||||
* 页缓冲:协议分片约 96B,Flash 页编程必须整页 256B。
|
||||
* 分片先攒进 s_page_buf,满页或收尾时再 APP_FlashWrite。
|
||||
*/
|
||||
static uint8_t s_page_buf[OTA_PAGE_SIZE];
|
||||
static uint32_t s_page_addr; /**< 当前缓冲对应的 Flash 页起始地址 */
|
||||
static uint32_t s_page_fill; /**< 当前页已填字节数,0 表示缓冲空 */
|
||||
|
||||
/*============================================================================*/
|
||||
/* 私有函数 */
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief 把页缓冲写入 Flash,然后清空缓冲
|
||||
* @note 尾页不足 256B 时先补 0xFF(擦除态),满足整页编程要求。
|
||||
* 补的 0xFF 不参与 CRC(CRC 在收包时已按原始固件字节累计)。
|
||||
* @return 0 成功;缓冲为空时直接返回 0
|
||||
*/
|
||||
static int ota_flush_page(void)
|
||||
{
|
||||
if (s_page_fill == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s_page_fill < OTA_PAGE_SIZE)
|
||||
{
|
||||
memset(&s_page_buf[s_page_fill], 0xFF, OTA_PAGE_SIZE - s_page_fill);
|
||||
}
|
||||
APP_FlashWrite(s_page_addr, s_page_buf, OTA_PAGE_SIZE);
|
||||
s_page_fill = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*============================================================================*/
|
||||
/* 公有函数:下载流程 */
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief 开始 OTA:擦备份区并初始化接收状态(协议 0x30 接受升级后调用)
|
||||
* @param total_len 固件总长度,来自 0x30 的 fwLength
|
||||
* @param fw_crc32 固件 CRC32,来自 0x30 的 fwCrc32,收完后与流式 CRC 比对
|
||||
* @return 0 成功;-1 长度非法
|
||||
* @note 目标地址固定 OTA_BAK_ADDR_BASE:
|
||||
* 单备份 = BAK 下载缓冲;双备份 = B 区。运行区固件此时不动。
|
||||
* 下载期间状态保持 IDLE,避免半包掉电被 Bootloader 误当成待升级。
|
||||
*/
|
||||
int ota_start(uint32_t total_len, uint32_t fw_crc32)
|
||||
{
|
||||
uint32_t base = OTA_BAK_ADDR_BASE;
|
||||
|
||||
if ((total_len == 0) || (total_len > OTA_SLOT_MAX_SIZE))
|
||||
{
|
||||
Log("[OTA] invalid length %lu\r\n", (unsigned long)total_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Log("[OTA] start len=%lu crc=%08X target=%08X\r\n",
|
||||
(unsigned long)total_len, (unsigned int)fw_crc32, (unsigned int)base);
|
||||
|
||||
memset(&g_ota, 0, sizeof(g_ota));
|
||||
g_ota.magic = OTA_MAGIC;
|
||||
g_ota.state = OTA_STATE_IDLE;
|
||||
g_ota.fw_size = total_len;
|
||||
g_ota.fw_crc32 = fw_crc32;
|
||||
|
||||
g_crc_acc = crc32_init();
|
||||
g_recv_len = 0;
|
||||
g_running = true;
|
||||
s_page_addr = 0;
|
||||
s_page_fill = 0;
|
||||
|
||||
/* 整槽擦除。调用点在 0x30 应答之前,擦完才让 BLE 开始发 0x32 */
|
||||
APP_FlashEraseWithCheck(base, OTA_SLOT_MAX_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 写入一个 OTA 数据分片(协议 0x32 每包调用)
|
||||
* @param data 本包固件数据
|
||||
* @param len 本包长度;尾包可能按 MaxDataLen 补齐,内部会截到 fw_size
|
||||
* @return 0 成功(含已收满后的多余包,直接忽略)
|
||||
* -1 未处于下载中
|
||||
* -2 参数非法
|
||||
* -3 超出备份区容量
|
||||
* @note 边收边做两件事:更新流式 CRC;按 256B 页对齐写入备份区。
|
||||
*/
|
||||
int ota_receive_chunk(const uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t offset;
|
||||
const uint8_t *p;
|
||||
uint32_t remain;
|
||||
|
||||
if (!g_running)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if ((data == NULL) || (len == 0))
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
if (g_recv_len >= g_ota.fw_size)
|
||||
{
|
||||
return 0; /* 已收满,忽略多余分片 */
|
||||
}
|
||||
|
||||
/* 尾包若带协议填充,只取固件剩余字节,避免把填充算进 CRC / 写入 Flash */
|
||||
if ((g_recv_len + len) > g_ota.fw_size)
|
||||
{
|
||||
len = g_ota.fw_size - g_recv_len;
|
||||
}
|
||||
if ((g_recv_len + len) > OTA_SLOT_MAX_SIZE)
|
||||
{
|
||||
Log("[OTA] overflow\r\n");
|
||||
return -3;
|
||||
}
|
||||
|
||||
base = OTA_BAK_ADDR_BASE;
|
||||
offset = g_recv_len;
|
||||
p = data;
|
||||
remain = len;
|
||||
|
||||
g_crc_acc = crc32_update(g_crc_acc, data, len);
|
||||
|
||||
while (remain > 0)
|
||||
{
|
||||
/* 当前字节所属 Flash 页的起始地址(256B 对齐) */
|
||||
uint32_t page_addr = base + (offset & ~(OTA_PAGE_SIZE - 1));
|
||||
uint32_t in_page;
|
||||
uint32_t n;
|
||||
|
||||
/* 跨页:先把上一页写进去,再开新页缓冲 */
|
||||
if (page_addr != s_page_addr)
|
||||
{
|
||||
ota_flush_page();
|
||||
s_page_addr = page_addr;
|
||||
s_page_fill = 0;
|
||||
}
|
||||
|
||||
/* 本页还能塞多少:页大小 - 页内偏移 */
|
||||
in_page = OTA_PAGE_SIZE - (offset & (OTA_PAGE_SIZE - 1));
|
||||
n = (remain < in_page) ? remain : in_page;
|
||||
memcpy(&s_page_buf[s_page_fill], p, n);
|
||||
s_page_fill += n;
|
||||
|
||||
if (s_page_fill == OTA_PAGE_SIZE)
|
||||
{
|
||||
ota_flush_page();
|
||||
}
|
||||
|
||||
p += n;
|
||||
offset += n;
|
||||
remain -= n;
|
||||
}
|
||||
|
||||
g_recv_len = offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 是否已收满 0x30 声明的 fwLength
|
||||
* @return true 已收满,可调用 ota_finish();不依赖分片序号从 0 还是从 1 起
|
||||
*/
|
||||
bool ota_is_download_complete(void)
|
||||
{
|
||||
return (g_running && (g_recv_len >= g_ota.fw_size) && (g_ota.fw_size > 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 收包结束:刷尾页、核对长度和 CRC,通过则把状态写成 PENDING
|
||||
* @return 0 校验通过,已写 PENDING,调用方可复位进 Bootloader
|
||||
* 1 长度或 CRC 失败(备份区数据作废,运行区仍是旧固件)
|
||||
* -1 当前不在下载中
|
||||
* @note 只有这里才会把状态区改成 PENDING。半包掉电时仍是 IDLE,下次启动正常跑旧固件。
|
||||
*/
|
||||
int ota_finish(void)
|
||||
{
|
||||
uint32_t crc;
|
||||
|
||||
if (!g_running)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ota_flush_page();
|
||||
g_running = false;
|
||||
|
||||
Log("[OTA] recv %lu bytes, expect %lu\r\n",
|
||||
(unsigned long)g_recv_len, (unsigned long)g_ota.fw_size);
|
||||
|
||||
if (g_recv_len != g_ota.fw_size)
|
||||
{
|
||||
Log("[OTA] length mismatch, abort\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
crc = crc32_final(g_crc_acc);
|
||||
Log("[OTA] crc=%08X expect=%08X\r\n",
|
||||
(unsigned int)crc, (unsigned int)g_ota.fw_crc32);
|
||||
|
||||
if (crc != g_ota.fw_crc32)
|
||||
{
|
||||
Log("[OTA] CRC32 FAILED, abort\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 告诉 Bootloader:备份区固件有效,复位后请拷贝/交换 */
|
||||
g_ota.state = OTA_STATE_PENDING;
|
||||
ota_param_store(&g_ota);
|
||||
/* 回读确认状态区已落盘,避免写失败后仍去复位 */
|
||||
ota_param_load(&g_ota);
|
||||
Log("[OTA] state=%d\r\n", g_ota.state);
|
||||
Log("[OTA] CRC32 OK, state=PENDING, ready to reboot\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 中止本次 OTA(协议 0x36 / 0x38)
|
||||
* @note 只停接收、丢页缓冲。不改状态区(仍为 IDLE),运行区不受影响。
|
||||
*/
|
||||
void ota_abort(void)
|
||||
{
|
||||
Log("[OTA] abort\r\n");
|
||||
g_running = false;
|
||||
s_page_fill = 0;
|
||||
}
|
||||
|
||||
/*============================================================================*/
|
||||
/* 公有函数:新固件首次启动确认(仅双备份有意义) */
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief APP 启动时检查是否需要确认「已切到新固件」
|
||||
* @return true 本次是双备份切换后的首次启动,已把 BOOT_NEW 改成 IDLE
|
||||
* false 普通启动,或单备份(不会出现 BOOT_NEW)
|
||||
* @note 应在 APP 自检通过后调用。若新固件崩溃、未跑到这里,
|
||||
* Bootloader 下次启动仍看到 BOOT_NEW,会回滚旧固件。
|
||||
*/
|
||||
bool ota_boot_check_confirm(void)
|
||||
{
|
||||
ota_param_t p;
|
||||
|
||||
ota_param_load(&p);
|
||||
|
||||
if (p.state == OTA_STATE_BOOT_NEW)
|
||||
{
|
||||
p.state = OTA_STATE_IDLE;
|
||||
ota_param_store(&p);
|
||||
Log("[OTA] new fw confirmed\r\n");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/******************************************************************************
|
||||
* @file ota_ab.h
|
||||
* @brief APP 侧 OTA 下载接口(写入备份区;切换由 Bootloader 完成)
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.18
|
||||
* @version V1.0.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.18, cyWu, 补充接口注释
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __OTA_AB_H
|
||||
#define __OTA_AB_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "ota_config.h"
|
||||
|
||||
/*============================================================================*/
|
||||
/* 说明 */
|
||||
/*============================================================================*/
|
||||
/*
|
||||
* 布局与状态机由 Shared/ota_config.h 唯一配置:
|
||||
* OTA_BAK_ADDR_BASE / OTA_SLOT_MAX_SIZE / ota_param_t / OTA_STATE_*
|
||||
*
|
||||
* 目标区固定 = OTA_BAK_ADDR_BASE:
|
||||
* 单备份 = BAK 下载缓冲;双备份 = B 备份区。APP 不必判断「当前跑的是 A 还是 B」。
|
||||
*
|
||||
* 状态区读写在 flash.h:ota_param_load / ota_param_store。
|
||||
*/
|
||||
|
||||
/*============================================================================*/
|
||||
/* 下载流程(协议 0x30 / 0x32 / 0x36) */
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief 0x30 接受升级后调用:擦备份区,准备收包
|
||||
* @param total_len 固件总字节数(fwLength)
|
||||
* @param fw_crc32 固件 CRC32(fwCrc32)
|
||||
* @return 0 成功,-1 长度非法
|
||||
*/
|
||||
int ota_start(uint32_t total_len, uint32_t fw_crc32);
|
||||
|
||||
/**
|
||||
* @brief 0x32 每包调用:写入备份区(内部 256B 页缓冲)
|
||||
* @param data 本包数据
|
||||
* @param len 本包长度
|
||||
* @return 0 成功,负值失败
|
||||
*/
|
||||
int ota_receive_chunk(const uint8_t *data, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief 是否已收满 fwLength(不依赖分片序号从 0 还是 1 起)
|
||||
*/
|
||||
bool ota_is_download_complete(void);
|
||||
|
||||
/**
|
||||
* @brief 收完后调用:核对长度+CRC,通过则写 PENDING
|
||||
* @return 0 成功可复位,1 校验失败,-1 未在下载中
|
||||
*/
|
||||
int ota_finish(void);
|
||||
|
||||
/**
|
||||
* @brief 0x36 / 0x38 停止升级:丢弃本次接收,不改运行区
|
||||
*/
|
||||
void ota_abort(void);
|
||||
|
||||
/*============================================================================*/
|
||||
/* 新固件确认(仅双备份) */
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* @brief APP 启动自检通过后调用
|
||||
* @return true 双备份下刚切到新固件,已确认(主循环可据此回复 OTA 完成)
|
||||
* false 普通启动;单备份恒为 false
|
||||
*/
|
||||
bool ota_boot_check_confirm(void);
|
||||
|
||||
/**
|
||||
* @brief 软件复位(实现在 Protocol/jb_product.c)
|
||||
*/
|
||||
void mcuRestart(void);
|
||||
|
||||
#endif /* __OTA_AB_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef __APPLICATION_H
|
||||
#define __APPLICATION_H
|
||||
|
||||
#include "main.h"
|
||||
|
||||
|
||||
|
||||
// DEMO是项目编号,1.0.0是软件大版本,009是软件小版本
|
||||
#define __VERSION__ "DEMO_1.0.0"
|
||||
#define __DEVELOPER__ "WuChuYuan"
|
||||
#define __EMAIL__ "1917507415@qq.com"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BOARD_POWER_OFF, // 关机状态
|
||||
} board_state_t;
|
||||
|
||||
|
||||
void app_Init(void);
|
||||
void app_lication(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file main.h
|
||||
* @author MCU Application Team
|
||||
* @brief Header for main.c file.
|
||||
* This file contains the common defines of the application.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MAIN_H
|
||||
#define __MAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "log.h"
|
||||
#include "py32f040xx_Start_Kit.h"
|
||||
#include "py32f0xx_hal.h"
|
||||
#include "jb_uart.h"
|
||||
#include "jb_timer.h"
|
||||
#include "jb_product.h"
|
||||
#include "jb_protocol.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* Exported variables prototypes ---------------------------------------------*/
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STATUS_SUCCESS,
|
||||
STATUS_ERROR,
|
||||
STATUS_OVERFLOW,
|
||||
STATUS_WAIT,
|
||||
STATUS_TIMEOUT,
|
||||
// 可以继续添加其他状态
|
||||
} User_StatusTypeDef;
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
/**
|
||||
* @brief 错误处理函数
|
||||
* @param *file:文件名,line:行号
|
||||
* @return None
|
||||
*/
|
||||
void Error_Handler(uint8_t *file, uint32_t line);
|
||||
|
||||
/**
|
||||
* @brief 计算时间差
|
||||
* @param meiosis:需要比较的时间戳,用于计算时间差
|
||||
* @retval 时间差
|
||||
*/
|
||||
uint32_t HAL_GetTickDiff(uint32_t meiosis);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MAIN_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,277 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040_hal_conf.h
|
||||
* @author MCU Application Team
|
||||
* @brief HAL configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __PY32F040_HAL_CONF_H
|
||||
#define __PY32F040_HAL_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
#define HAL_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
/* #define HAL_ADC_MODULE_ENABLED */
|
||||
/* #define HAL_CRC_MODULE_ENABLED */
|
||||
/* #define HAL_COMP_MODULE_ENABLED */
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_IWDG_MODULE_ENABLED
|
||||
/* #define HAL_WWDG_MODULE_ENABLED */
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
/* #define HAL_LPTIM_MODULE_ENABLED */
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
/* #define HAL_I2C_MODULE_ENABLED */
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
/* #define HAL_USART_MODULE_ENABLED */
|
||||
/* #define HAL_SPI_MODULE_ENABLED */
|
||||
/* #define HAL_RTC_MODULE_ENABLED */
|
||||
/* #define HAL_LCD_MODULE_ENABLED */
|
||||
/* #define HAL_EXTI_MODULE_ENABLED */
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
/* #define HAL_OPA_MODULE_ENABLED */
|
||||
/* #define HAL_DIV_MODULE_ENABLED */
|
||||
/* #define HAL_I2S_MODULE_ENABLED */
|
||||
/* #define HAL_IRDA_MODULE_ENABLED */
|
||||
/* #define HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
/* ########################## Oscillator Values adaptation ####################*/
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE ((uint32_t)24000000) /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT ((uint32_t)200) /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed Internal oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE ((uint32_t)32768) /*!< LSI Typical Value in Hz */
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
|
||||
/**
|
||||
* @brief Adjust the value of External Low Speed oscillator (LSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External oscillator in Hz*/
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
|
||||
#define PRIORITY_HIGHEST 0
|
||||
#define PRIORITY_HIGH 1
|
||||
#define PRIORITY_LOW 2
|
||||
#define PRIORITY_LOWEST 3
|
||||
#define TICK_INT_PRIORITY ((uint32_t)PRIORITY_LOWEST) /*!< tick interrupt priority (lowest by default) */
|
||||
#define USE_RTOS 0
|
||||
#define PREFETCH_ENABLE 0
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1U */
|
||||
|
||||
/* ################## SPI peripheral configuration ########################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
|
||||
#define USE_SPI_CRC 0U
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
#ifdef HAL_MODULE_ENABLED
|
||||
#include "py32f0xx_hal.h"
|
||||
#endif /* HAL_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "py32f040_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "py32f040_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "py32f040_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "py32f040_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "py32f040_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "py32f040_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "py32f040_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_COMP_MODULE_ENABLED
|
||||
#include "py32f040_hal_comp.h"
|
||||
#endif /* HAL_COMP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "py32f040_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "py32f040_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "py32f040_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "py32f040_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "py32f040_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "py32f040_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "py32f040_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "py32f040_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "py32f040_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "py32f040_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LCD_MODULE_ENABLED
|
||||
#include "py32f040_hal_lcd.h"
|
||||
#endif /* HAL_LCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "py32f040_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
|
||||
#ifdef HAL_OPA_MODULE_ENABLED
|
||||
#include "py32f040_hal_opa.h"
|
||||
#endif /* HAL_OPA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DIV_MODULE_ENABLED
|
||||
#include "py32f040_hal_div.h"
|
||||
#endif /* HAL_DIV_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "py32f040_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "py32f040_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "py32f040_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr: If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t* file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PY32F040_HAL_CONF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040_it.h
|
||||
* @author MCU Application Team
|
||||
* @brief This file contains the headers of the interrupt handlers.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __PY32F040_IT_H
|
||||
#define __PY32F040_IT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void NMI_Handler(void);
|
||||
void HardFault_Handler(void);
|
||||
void SVC_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void USART3_4_IRQHandler(void);
|
||||
void TIM6_LPTIM1_IRQHandler(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PY32F040_IT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,30 @@
|
||||
// File: PY32F030xx.dbgconf
|
||||
// Version: 1.0.0
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <h> Debug MCU configuration register (DBGMCU_CR)
|
||||
// <o.1> DBG_STOP <i> Debug stop mode
|
||||
// </h>
|
||||
DbgMCU_CR = 0x00000002;
|
||||
|
||||
// <h> Debug MCU APB freeze1 register (DBG_APB_FZ1)
|
||||
// <i> Reserved bits must be kept at reset value
|
||||
// <o.31> DBG_LPTIM_STOP <i> LPTIM stopped when core is halted
|
||||
// <o.12> DBG_IWDG_STOP <i> Independent watchdog stopped when core is halted
|
||||
// <o.11> DBG_WWDG_STOP <i> Window watchdog stopped when core is halted
|
||||
// <o.10> DBG_RTC_STOP <i> RTC stopped when core is halted
|
||||
// <o.1> DBG_TIM3_STOP <i> TIM3 counter stopped when core is halted
|
||||
// </h>
|
||||
DbgMCU_APB_Fz1 = 0x00000000;
|
||||
|
||||
// <h> Debug MCU APB freeze2 register (DBG_APB_FZ2)
|
||||
// <i> Reserved bits must be kept at reset value
|
||||
// <o.18> DBG_TIM17_STOP <i> TIM17 counter stopped when core is halted
|
||||
// <o.17> DBG_TIM16_STOP <i> TIM16 counter stopped when core is halted
|
||||
// <o.15> DBG_TIM14_STOP <i> TIM14 counter stopped when core is halted
|
||||
// <o.11> DBG_TIM1_STOP <i> TIM1 counter stopped when core is halted
|
||||
// </h>
|
||||
DbgMCU_APB_Fz2 = 0x00000000;
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
@@ -0,0 +1,30 @@
|
||||
// File: PY32F040xx.dbgconf
|
||||
// Version: 1.0.0
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <h> Debug MCU configuration register (DBGMCU_CR)
|
||||
// <o.1> DBG_STOP <i> Debug stop mode
|
||||
// </h>
|
||||
DbgMCU_CR = 0x00000002;
|
||||
|
||||
// <h> Debug MCU APB freeze1 register (DBG_APB_FZ1)
|
||||
// <i> Reserved bits must be kept at reset value
|
||||
// <o.31> DBG_LPTIM_STOP <i> LPTIM stopped when core is halted
|
||||
// <o.12> DBG_IWDG_STOP <i> Independent watchdog stopped when core is halted
|
||||
// <o.11> DBG_WWDG_STOP <i> Window watchdog stopped when core is halted
|
||||
// <o.10> DBG_RTC_STOP <i> RTC stopped when core is halted
|
||||
// <o.1> DBG_TIM3_STOP <i> TIM3 counter stopped when core is halted
|
||||
// </h>
|
||||
DbgMCU_APB_Fz1 = 0x00000000;
|
||||
|
||||
// <h> Debug MCU APB freeze2 register (DBG_APB_FZ2)
|
||||
// <i> Reserved bits must be kept at reset value
|
||||
// <o.18> DBG_TIM17_STOP <i> TIM17 counter stopped when core is halted
|
||||
// <o.17> DBG_TIM16_STOP <i> TIM16 counter stopped when core is halted
|
||||
// <o.15> DBG_TIM14_STOP <i> TIM14 counter stopped when core is halted
|
||||
// <o.11> DBG_TIM1_STOP <i> TIM1 counter stopped when core is halted
|
||||
// </h>
|
||||
DbgMCU_APB_Fz2 = 0x00000000;
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
@@ -0,0 +1,616 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
|
||||
|
||||
<SchemaVersion>2.1</SchemaVersion>
|
||||
|
||||
<Header>### uVision Project, (C) Keil Software</Header>
|
||||
|
||||
<Targets>
|
||||
<Target>
|
||||
<TargetName>Project</TargetName>
|
||||
<ToolsetNumber>0x4</ToolsetNumber>
|
||||
<ToolsetName>ARM-ADS</ToolsetName>
|
||||
<pCCUsed>5060960::V5.06 update 7 (build 960)::.\ARM_Compiler_5.06u7</pCCUsed>
|
||||
<uAC6>0</uAC6>
|
||||
<TargetOption>
|
||||
<TargetCommonOption>
|
||||
<Device>PY32F040xB</Device>
|
||||
<Vendor>Puya</Vendor>
|
||||
<PackID>Puya.PY32F0xx_DFP.1.2.0</PackID>
|
||||
<PackURL>https://www.puyasemi.com/uploadfiles/</PackURL>
|
||||
<Cpu>IRAM(0x20000000,0x00004000) IROM(0x08003000,0x0000E400) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE</Cpu>
|
||||
<FlashUtilSpec></FlashUtilSpec>
|
||||
<StartupFile></StartupFile>
|
||||
<FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0PY32F040xx_128 -FS08000000 -FL020000 -FP0($$Device:PY32F040xB$CMSIS\Flash\PY32F040xx_128.FLM))</FlashDriverDll>
|
||||
<DeviceId>0</DeviceId>
|
||||
<RegisterFile>$$Device:PY32F040xB$Drivers\CMSIS\Device\Puya\PY32F0xx\Include\py32f0xx.h</RegisterFile>
|
||||
<MemoryEnv></MemoryEnv>
|
||||
<Cmp></Cmp>
|
||||
<Asm></Asm>
|
||||
<Linker></Linker>
|
||||
<OHString></OHString>
|
||||
<InfinionOptionDll></InfinionOptionDll>
|
||||
<SLE66CMisc></SLE66CMisc>
|
||||
<SLE66AMisc></SLE66AMisc>
|
||||
<SLE66LinkerMisc></SLE66LinkerMisc>
|
||||
<SFDFile>$$Device:PY32F040xB$CMSIS\SVD\PY32F040xx.svd</SFDFile>
|
||||
<bCustSvd>0</bCustSvd>
|
||||
<UseEnv>0</UseEnv>
|
||||
<BinPath></BinPath>
|
||||
<IncludePath></IncludePath>
|
||||
<LibPath></LibPath>
|
||||
<RegisterFilePath></RegisterFilePath>
|
||||
<DBRegisterFilePath></DBRegisterFilePath>
|
||||
<TargetStatus>
|
||||
<Error>0</Error>
|
||||
<ExitCodeStop>0</ExitCodeStop>
|
||||
<ButtonStop>0</ButtonStop>
|
||||
<NotGenerated>0</NotGenerated>
|
||||
<InvalidFlash>1</InvalidFlash>
|
||||
</TargetStatus>
|
||||
<OutputDirectory>.\Objects\</OutputDirectory>
|
||||
<OutputName>Project</OutputName>
|
||||
<CreateExecutable>1</CreateExecutable>
|
||||
<CreateLib>0</CreateLib>
|
||||
<CreateHexFile>1</CreateHexFile>
|
||||
<DebugInformation>1</DebugInformation>
|
||||
<BrowseInformation>1</BrowseInformation>
|
||||
<ListingPath>.\Listings\</ListingPath>
|
||||
<HexFormatSelection>1</HexFormatSelection>
|
||||
<Merge32K>0</Merge32K>
|
||||
<CreateBatchFile>0</CreateBatchFile>
|
||||
<BeforeCompile>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopU1X>0</nStopU1X>
|
||||
<nStopU2X>0</nStopU2X>
|
||||
</BeforeCompile>
|
||||
<BeforeMake>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopB1X>0</nStopB1X>
|
||||
<nStopB2X>0</nStopB2X>
|
||||
</BeforeMake>
|
||||
<AfterMake>
|
||||
<RunUserProg1>1</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name>"$P..\OutputHex.bat" $K</UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopA1X>0</nStopA1X>
|
||||
<nStopA2X>0</nStopA2X>
|
||||
</AfterMake>
|
||||
<SelectedForBatchBuild>0</SelectedForBatchBuild>
|
||||
<SVCSIdString></SVCSIdString>
|
||||
</TargetCommonOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>0</UseCPPCompiler>
|
||||
<RVCTCodeConst>0</RVCTCodeConst>
|
||||
<RVCTZI>0</RVCTZI>
|
||||
<RVCTOtherData>0</RVCTOtherData>
|
||||
<ModuleSelection>0</ModuleSelection>
|
||||
<IncludeInBuild>1</IncludeInBuild>
|
||||
<AlwaysBuild>0</AlwaysBuild>
|
||||
<GenerateAssemblyFile>0</GenerateAssemblyFile>
|
||||
<AssembleAssemblyFile>0</AssembleAssemblyFile>
|
||||
<PublicsOnly>0</PublicsOnly>
|
||||
<StopOnExitCode>3</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<DllOption>
|
||||
<SimDllName>SARMCM3.DLL</SimDllName>
|
||||
<SimDllArguments> -REMAP </SimDllArguments>
|
||||
<SimDlgDll>DARMCM1.DLL</SimDlgDll>
|
||||
<SimDlgDllArguments>-pCM0+</SimDlgDllArguments>
|
||||
<TargetDllName>SARMCM3.DLL</TargetDllName>
|
||||
<TargetDllArguments> </TargetDllArguments>
|
||||
<TargetDlgDll>TARMCM1.DLL</TargetDlgDll>
|
||||
<TargetDlgDllArguments>-pCM0+</TargetDlgDllArguments>
|
||||
</DllOption>
|
||||
<DebugOption>
|
||||
<OPTHX>
|
||||
<HexSelection>1</HexSelection>
|
||||
<HexRangeLowAddress>0</HexRangeLowAddress>
|
||||
<HexRangeHighAddress>0</HexRangeHighAddress>
|
||||
<HexOffset>0</HexOffset>
|
||||
<Oh166RecLen>16</Oh166RecLen>
|
||||
</OPTHX>
|
||||
</DebugOption>
|
||||
<Utilities>
|
||||
<Flash1>
|
||||
<UseTargetDll>1</UseTargetDll>
|
||||
<UseExternalTool>0</UseExternalTool>
|
||||
<RunIndependent>0</RunIndependent>
|
||||
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
|
||||
<Capability>1</Capability>
|
||||
<DriverSelection>4096</DriverSelection>
|
||||
</Flash1>
|
||||
<bUseTDR>1</bUseTDR>
|
||||
<Flash2>BIN\UL2CM3.DLL</Flash2>
|
||||
<Flash3></Flash3>
|
||||
<Flash4></Flash4>
|
||||
<pFcarmOut></pFcarmOut>
|
||||
<pFcarmGrp></pFcarmGrp>
|
||||
<pFcArmRoot></pFcArmRoot>
|
||||
<FcArmLst>0</FcArmLst>
|
||||
</Utilities>
|
||||
<TargetArmAds>
|
||||
<ArmAdsMisc>
|
||||
<GenerateListings>0</GenerateListings>
|
||||
<asHll>1</asHll>
|
||||
<asAsm>1</asAsm>
|
||||
<asMacX>1</asMacX>
|
||||
<asSyms>1</asSyms>
|
||||
<asFals>1</asFals>
|
||||
<asDbgD>1</asDbgD>
|
||||
<asForm>1</asForm>
|
||||
<ldLst>0</ldLst>
|
||||
<ldmm>1</ldmm>
|
||||
<ldXref>1</ldXref>
|
||||
<BigEnd>0</BigEnd>
|
||||
<AdsALst>1</AdsALst>
|
||||
<AdsACrf>1</AdsACrf>
|
||||
<AdsANop>0</AdsANop>
|
||||
<AdsANot>0</AdsANot>
|
||||
<AdsLLst>1</AdsLLst>
|
||||
<AdsLmap>1</AdsLmap>
|
||||
<AdsLcgr>1</AdsLcgr>
|
||||
<AdsLsym>1</AdsLsym>
|
||||
<AdsLszi>1</AdsLszi>
|
||||
<AdsLtoi>1</AdsLtoi>
|
||||
<AdsLsun>1</AdsLsun>
|
||||
<AdsLven>1</AdsLven>
|
||||
<AdsLsxf>1</AdsLsxf>
|
||||
<RvctClst>0</RvctClst>
|
||||
<GenPPlst>0</GenPPlst>
|
||||
<AdsCpuType>"Cortex-M0+"</AdsCpuType>
|
||||
<RvctDeviceName></RvctDeviceName>
|
||||
<mOS>0</mOS>
|
||||
<uocRom>0</uocRom>
|
||||
<uocRam>0</uocRam>
|
||||
<hadIROM>1</hadIROM>
|
||||
<hadIRAM>1</hadIRAM>
|
||||
<hadXRAM>0</hadXRAM>
|
||||
<uocXRam>0</uocXRam>
|
||||
<RvdsVP>0</RvdsVP>
|
||||
<RvdsMve>0</RvdsMve>
|
||||
<RvdsCdeCp>0</RvdsCdeCp>
|
||||
<nBranchProt>0</nBranchProt>
|
||||
<hadIRAM2>0</hadIRAM2>
|
||||
<hadIROM2>0</hadIROM2>
|
||||
<StupSel>8</StupSel>
|
||||
<useUlib>1</useUlib>
|
||||
<EndSel>0</EndSel>
|
||||
<uLtcg>0</uLtcg>
|
||||
<nSecure>0</nSecure>
|
||||
<RoSelD>3</RoSelD>
|
||||
<RwSelD>3</RwSelD>
|
||||
<CodeSel>0</CodeSel>
|
||||
<OptFeed>0</OptFeed>
|
||||
<NoZi1>0</NoZi1>
|
||||
<NoZi2>0</NoZi2>
|
||||
<NoZi3>0</NoZi3>
|
||||
<NoZi4>0</NoZi4>
|
||||
<NoZi5>0</NoZi5>
|
||||
<Ro1Chk>0</Ro1Chk>
|
||||
<Ro2Chk>0</Ro2Chk>
|
||||
<Ro3Chk>0</Ro3Chk>
|
||||
<Ir1Chk>1</Ir1Chk>
|
||||
<Ir2Chk>0</Ir2Chk>
|
||||
<Ra1Chk>0</Ra1Chk>
|
||||
<Ra2Chk>0</Ra2Chk>
|
||||
<Ra3Chk>0</Ra3Chk>
|
||||
<Im1Chk>1</Im1Chk>
|
||||
<Im2Chk>0</Im2Chk>
|
||||
<OnChipMemories>
|
||||
<Ocm1>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm1>
|
||||
<Ocm2>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm2>
|
||||
<Ocm3>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm3>
|
||||
<Ocm4>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm4>
|
||||
<Ocm5>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm5>
|
||||
<Ocm6>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm6>
|
||||
<IRAM>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x20000000</StartAddress>
|
||||
<Size>0x4000</Size>
|
||||
</IRAM>
|
||||
<IROM>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x8003000</StartAddress>
|
||||
<Size>0xe400</Size>
|
||||
</IROM>
|
||||
<XRAM>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</XRAM>
|
||||
<OCR_RVCT1>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT1>
|
||||
<OCR_RVCT2>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT2>
|
||||
<OCR_RVCT3>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT3>
|
||||
<OCR_RVCT4>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x8003000</StartAddress>
|
||||
<Size>0xe400</Size>
|
||||
</OCR_RVCT4>
|
||||
<OCR_RVCT5>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT5>
|
||||
<OCR_RVCT6>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT6>
|
||||
<OCR_RVCT7>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT7>
|
||||
<OCR_RVCT8>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT8>
|
||||
<OCR_RVCT9>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x20000000</StartAddress>
|
||||
<Size>0x4000</Size>
|
||||
</OCR_RVCT9>
|
||||
<OCR_RVCT10>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT10>
|
||||
</OnChipMemories>
|
||||
<RvctStartVector></RvctStartVector>
|
||||
</ArmAdsMisc>
|
||||
<Cads>
|
||||
<interw>1</interw>
|
||||
<Optim>3</Optim>
|
||||
<oTime>0</oTime>
|
||||
<SplitLS>0</SplitLS>
|
||||
<OneElfS>1</OneElfS>
|
||||
<Strict>0</Strict>
|
||||
<EnumInt>0</EnumInt>
|
||||
<PlainCh>0</PlainCh>
|
||||
<Ropi>0</Ropi>
|
||||
<Rwpi>0</Rwpi>
|
||||
<wLevel>2</wLevel>
|
||||
<uThumb>0</uThumb>
|
||||
<uSurpInc>0</uSurpInc>
|
||||
<uC99>1</uC99>
|
||||
<uGnu>0</uGnu>
|
||||
<useXO>0</useXO>
|
||||
<v6Lang>3</v6Lang>
|
||||
<v6LangP>5</v6LangP>
|
||||
<vShortEn>1</vShortEn>
|
||||
<vShortWch>1</vShortWch>
|
||||
<v6Lto>0</v6Lto>
|
||||
<v6WtE>0</v6WtE>
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>USE_HAL_DRIVER,PY32F040xB</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\Inc;..\..\Shared;..\..\Drivers\CMSIS\Include;..\..\Drivers\CMSIS\Device\PY32F040\Include;..\..\Drivers\PY32F040_HAL_Driver\Inc;..\Core;..\..\Drivers\BSP\PY32F040xx_Start_Kit;..\Protocol;..\Utils;..</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
<interw>1</interw>
|
||||
<Ropi>0</Ropi>
|
||||
<Rwpi>0</Rwpi>
|
||||
<thumb>0</thumb>
|
||||
<SplitLS>0</SplitLS>
|
||||
<SwStkChk>0</SwStkChk>
|
||||
<NoWarn>0</NoWarn>
|
||||
<uSurpInc>0</uSurpInc>
|
||||
<useXO>0</useXO>
|
||||
<ClangAsOpt>4</ClangAsOpt>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Aads>
|
||||
<LDads>
|
||||
<umfTarg>1</umfTarg>
|
||||
<Ropi>0</Ropi>
|
||||
<Rwpi>0</Rwpi>
|
||||
<noStLib>0</noStLib>
|
||||
<RepFail>1</RepFail>
|
||||
<useFile>0</useFile>
|
||||
<TextAddressRange>0x08003000</TextAddressRange>
|
||||
<DataAddressRange>0x20000000</DataAddressRange>
|
||||
<pXoBase></pXoBase>
|
||||
<ScatterFile></ScatterFile>
|
||||
<IncludeLibs></IncludeLibs>
|
||||
<IncludeLibsPath></IncludeLibsPath>
|
||||
<Misc></Misc>
|
||||
<LinkerInputFile></LinkerInputFile>
|
||||
<DisabledWarnings></DisabledWarnings>
|
||||
</LDads>
|
||||
</TargetArmAds>
|
||||
</TargetOption>
|
||||
<Groups>
|
||||
<Group>
|
||||
<GroupName>User</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>main.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Src\main.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>application.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Src\application.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_msp.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Src\py32f040_hal_msp.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_it.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Src\py32f040_it.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>Core</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>jb_uart.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Core\jb_uart.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>jb_timer.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Core\jb_timer.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>jb_port.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Core\jb_port.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>flash.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Shared\flash.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>crc32.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Shared\crc32.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>ota_ab.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Core\ota_ab.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>app_boot.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Core\app_boot.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>iwdg.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Core\iwdg.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>Common</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>system_py32f040.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Src\system_py32f040.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>startup_py32f040xx.s</FileName>
|
||||
<FileType>2</FileType>
|
||||
<FilePath>.\startup_py32f040xx.s</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>PY32F040xx_HAL_Driver</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>py32f040_hal.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_adc.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_adc.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_crc.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_crc.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_gpio.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_gpio.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_rcc.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_rcc.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_rcc_ex.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_rcc_ex.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_tim.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_tim.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_tim_ex.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_tim_ex.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_uart.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_uart.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_comp.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_comp.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_cortex.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_cortex.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_div.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_div.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_flash.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_flash.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_pwr.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_pwr.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_dma.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_dma.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_iwdg.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_iwdg.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>Doc</GroupName>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>PY32F040xx_Start_Kit</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>py32f040xx_Start_Kit.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\BSP\PY32F040xx_Start_Kit\py32f040xx_Start_Kit.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>Protocol</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>jb_product.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Protocol\jb_product.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>jb_protocol.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Protocol\jb_protocol.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>Utils</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>jb_common.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Utils\jb_common.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>jb_ringbuffer.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Utils\jb_ringbuffer.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
</Groups>
|
||||
</Target>
|
||||
</Targets>
|
||||
|
||||
<RTE>
|
||||
<apis/>
|
||||
<components/>
|
||||
<files/>
|
||||
</RTE>
|
||||
|
||||
<LayerInfo>
|
||||
<Layers>
|
||||
<Layer>
|
||||
<LayName>ChickenCoopDoor</LayName>
|
||||
<LayPrjMark>1</LayPrjMark>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</LayerInfo>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,262 @@
|
||||
;******************************************************************************
|
||||
;* @file startup_py32f040xx.s
|
||||
;* @author MCU Application Team
|
||||
;* @brief PY32F040xx devices vector table for MDK-ARM toolchain.
|
||||
;* This module performs:
|
||||
;* - Set the initial SP
|
||||
;* - Set the initial PC == Reset_Handler
|
||||
;* - Set the vector table entries with the exceptions ISR address
|
||||
;* - Branches to __main in the C library (which eventually
|
||||
;* calls main()).
|
||||
;* After Reset the CortexM0+ processor is in Thread mode,
|
||||
;* priority is Privileged, and the Stack is set to Main.
|
||||
;******************************************************************************
|
||||
;* @attention
|
||||
;*
|
||||
;* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
;* All rights reserved.</center></h2>
|
||||
;*
|
||||
;* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
;* the "License"; You may not use this file except in compliance with the
|
||||
;* License. You may obtain a copy of the License at:
|
||||
;* opensource.org/licenses/BSD-3-Clause
|
||||
;*
|
||||
;******************************************************************************
|
||||
;* @attention
|
||||
;*
|
||||
;* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
;* All rights reserved.</center></h2>
|
||||
;*
|
||||
;* This software component is licensed by ST under BSD 3-Clause license,
|
||||
;* the "License"; You may not use this file except in compliance with the
|
||||
;* License. You may obtain a copy of the License at:
|
||||
;* opensource.org/licenses/BSD-3-Clause
|
||||
;*
|
||||
;******************************************************************************
|
||||
;* <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
; Amount of memory (in bytes) allocated for Stack
|
||||
; Tailor this value to your application needs
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000200
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WWDG_IRQHandler ; 0Window Watchdog
|
||||
DCD PVD_IRQHandler ; 1PVD through EXTI Line detect
|
||||
DCD RTC_IRQHandler ; 2RTC through EXTI Line
|
||||
DCD FLASH_IRQHandler ; 3FLASH
|
||||
DCD RCC_IRQHandler ; 4RCC
|
||||
DCD EXTI0_1_IRQHandler ; 5EXTI Line 0 and 1
|
||||
DCD EXTI2_3_IRQHandler ; 6EXTI Line 2 and 3
|
||||
DCD EXTI4_15_IRQHandler ; 7EXTI Line 4 to 15
|
||||
DCD LCD_IRQHandler ; 8LCD
|
||||
DCD DMA1_Channel1_IRQHandler ; 9DMA1 Channel 1
|
||||
DCD DMA1_Channel2_3_IRQHandler ; 10DMA1 Channel 2 and Channel 3
|
||||
DCD DMA1_Channel4_5_6_7_IRQHandler ; 11DMA1 Channel 4, Channel 5, Channel 6, Channel 7
|
||||
DCD ADC_COMP_IRQHandler ; 12ADC&COMP
|
||||
DCD TIM1_BRK_UP_TRG_COM_IRQHandler ; 13TIM1 Break, Update, Trigger and Commutation
|
||||
DCD TIM1_CC_IRQHandler ; 14TIM1 Capture Compare
|
||||
DCD TIM2_IRQHandler ; 15TIM2
|
||||
DCD TIM3_IRQHandler ; 16TIM3
|
||||
DCD TIM6_LPTIM1_IRQHandler ; 17TIM6&LPTIM1
|
||||
DCD TIM7_IRQHandler ; 18TIM7
|
||||
DCD TIM14_IRQHandler ; 19TIM14
|
||||
DCD TIM15_IRQHandler ; 20TIM15
|
||||
DCD TIM16_IRQHandler ; 21TIM16
|
||||
DCD TIM17_IRQHandler ; 22TIM17
|
||||
DCD I2C1_IRQHandler ; 23I2C1
|
||||
DCD I2C2_IRQHandler ; 24I2C2
|
||||
DCD SPI1_IRQHandler ; 25SPI1
|
||||
DCD SPI2_IRQHandler ; 26SPI2
|
||||
DCD USART1_IRQHandler ; 27USART1
|
||||
DCD USART2_IRQHandler ; 28USART2
|
||||
DCD USART3_4_IRQHandler ; 29USART3&USART4
|
||||
DCD 0 ; 30Reserved
|
||||
DCD 0 ; 31Reserved
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WWDG_IRQHandler [WEAK]
|
||||
EXPORT PVD_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT FLASH_IRQHandler [WEAK]
|
||||
EXPORT RCC_IRQHandler [WEAK]
|
||||
EXPORT EXTI0_1_IRQHandler [WEAK]
|
||||
EXPORT EXTI2_3_IRQHandler [WEAK]
|
||||
EXPORT EXTI4_15_IRQHandler [WEAK]
|
||||
EXPORT LCD_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel1_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel2_3_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel4_5_6_7_IRQHandler [WEAK]
|
||||
EXPORT ADC_COMP_IRQHandler [WEAK]
|
||||
EXPORT TIM1_BRK_UP_TRG_COM_IRQHandler [WEAK]
|
||||
EXPORT TIM1_CC_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT TIM3_IRQHandler [WEAK]
|
||||
EXPORT TIM6_LPTIM1_IRQHandler [WEAK]
|
||||
EXPORT TIM7_IRQHandler [WEAK]
|
||||
EXPORT TIM14_IRQHandler [WEAK]
|
||||
EXPORT TIM15_IRQHandler [WEAK]
|
||||
EXPORT TIM16_IRQHandler [WEAK]
|
||||
EXPORT TIM17_IRQHandler [WEAK]
|
||||
EXPORT I2C1_IRQHandler [WEAK]
|
||||
EXPORT I2C2_IRQHandler [WEAK]
|
||||
EXPORT SPI1_IRQHandler [WEAK]
|
||||
EXPORT SPI2_IRQHandler [WEAK]
|
||||
EXPORT USART1_IRQHandler [WEAK]
|
||||
EXPORT USART2_IRQHandler [WEAK]
|
||||
EXPORT USART3_4_IRQHandler [WEAK]
|
||||
|
||||
WWDG_IRQHandler
|
||||
PVD_IRQHandler
|
||||
RTC_IRQHandler
|
||||
FLASH_IRQHandler
|
||||
RCC_IRQHandler
|
||||
EXTI0_1_IRQHandler
|
||||
EXTI2_3_IRQHandler
|
||||
EXTI4_15_IRQHandler
|
||||
LCD_IRQHandler
|
||||
DMA1_Channel1_IRQHandler
|
||||
DMA1_Channel2_3_IRQHandler
|
||||
DMA1_Channel4_5_6_7_IRQHandler
|
||||
ADC_COMP_IRQHandler
|
||||
TIM1_BRK_UP_TRG_COM_IRQHandler
|
||||
TIM1_CC_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
TIM3_IRQHandler
|
||||
TIM6_LPTIM1_IRQHandler
|
||||
TIM7_IRQHandler
|
||||
TIM14_IRQHandler
|
||||
TIM15_IRQHandler
|
||||
TIM16_IRQHandler
|
||||
TIM17_IRQHandler
|
||||
I2C1_IRQHandler
|
||||
I2C2_IRQHandler
|
||||
SPI1_IRQHandler
|
||||
SPI2_IRQHandler
|
||||
USART1_IRQHandler
|
||||
USART2_IRQHandler
|
||||
USART3_4_IRQHandler
|
||||
B .
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap
|
||||
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
END
|
||||
|
||||
;************************ (C) COPYRIGHT Puya *****END OF FILE*******************
|
||||
@@ -0,0 +1,182 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
@REM ============================================================
|
||||
@REM Keil AfterMake: copy HEX and generate BIN after each build
|
||||
@REM Working dir may be MDK-ARM, so always switch to script dir
|
||||
@REM ============================================================
|
||||
cd /d "%~dp0"
|
||||
|
||||
@REM Executable name (same as Keil OutputName)
|
||||
set HEX_NAME=Project
|
||||
|
||||
@REM Keil output directory
|
||||
set HEX_PATH=%cd%\MDK-ARM\Objects
|
||||
|
||||
@REM Custom output directory
|
||||
set OUTPUT_PATH=%cd%\Output
|
||||
|
||||
@REM Software version header
|
||||
set VERSION_FILE_PATH=%cd%\Inc\application.h
|
||||
|
||||
@REM Software version string format
|
||||
set SOFTWARE_VERSION="#define __VERSION__"
|
||||
|
||||
@REM Optional arg1: Keil root ($K) passed by AfterMake
|
||||
set "KEIL_ROOT=%~1"
|
||||
|
||||
@REM ------------------------------------------------------------
|
||||
@REM Timestamp: yyMMdd_HHmmss
|
||||
@REM ------------------------------------------------------------
|
||||
for /f %%i in ('powershell -NoProfile -Command "Get-Date -Format yyMMdd_HHmmss"') do set CURRENT_DATE=%%i
|
||||
|
||||
@REM ------------------------------------------------------------
|
||||
@REM Read software version from application.h
|
||||
@REM ------------------------------------------------------------
|
||||
set SW_Ver=unknown
|
||||
for /f "tokens=3 delims= " %%i in ('findstr /C:%SOFTWARE_VERSION% "%VERSION_FILE_PATH%"') do set SW_Ver=%%i
|
||||
if defined SW_Ver set SW_Ver=%SW_Ver:"=%
|
||||
|
||||
@REM Custom output file name
|
||||
set output_file_name=%SW_Ver%_%CURRENT_DATE%
|
||||
|
||||
if not exist "%OUTPUT_PATH%" mkdir "%OUTPUT_PATH%"
|
||||
|
||||
@REM ------------------------------------------------------------
|
||||
@REM Copy HEX
|
||||
@REM ------------------------------------------------------------
|
||||
if exist "%HEX_PATH%\%HEX_NAME%.hex" (
|
||||
echo Output hex file: %OUTPUT_PATH%\%output_file_name%.hex
|
||||
copy /Y "%HEX_PATH%\%HEX_NAME%.hex" "%OUTPUT_PATH%\%output_file_name%.hex" >nul
|
||||
if errorlevel 1 (
|
||||
echo [ERROR] Failed to copy HEX
|
||||
) else (
|
||||
echo [OK] HEX copied
|
||||
)
|
||||
) else (
|
||||
echo [ERROR] HEX not found: %HEX_PATH%\%HEX_NAME%.hex
|
||||
)
|
||||
|
||||
@REM ------------------------------------------------------------
|
||||
@REM Generate BIN via fromelf (AXF), fallback: HEX to BIN
|
||||
@REM ------------------------------------------------------------
|
||||
set "FROMELF="
|
||||
set "BIN_FILE=%HEX_PATH%\%HEX_NAME%.bin"
|
||||
|
||||
call :find_fromelf
|
||||
|
||||
if not "%FROMELF%"=="" if exist "%HEX_PATH%\%HEX_NAME%.axf" (
|
||||
echo Using fromelf: %FROMELF%
|
||||
"%FROMELF%" --bincombined --output="%BIN_FILE%" "%HEX_PATH%\%HEX_NAME%.axf"
|
||||
if errorlevel 1 (
|
||||
echo [WARN] fromelf --bincombined failed, try --bin
|
||||
"%FROMELF%" --bin --output="%BIN_FILE%" "%HEX_PATH%\%HEX_NAME%.axf"
|
||||
)
|
||||
)
|
||||
|
||||
if not exist "%BIN_FILE%" (
|
||||
echo [WARN] Convert HEX to BIN
|
||||
call :hex2bin
|
||||
)
|
||||
|
||||
if not exist "%BIN_FILE%" (
|
||||
echo [ERROR] BIN not generated
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo Output bin file: %OUTPUT_PATH%\%output_file_name%.bin
|
||||
copy /Y "%BIN_FILE%" "%OUTPUT_PATH%\%output_file_name%.bin" >nul
|
||||
if errorlevel 1 (
|
||||
echo [ERROR] Failed to copy BIN
|
||||
exit /b 1
|
||||
) else (
|
||||
echo [OK] BIN copied
|
||||
)
|
||||
|
||||
exit /b 0
|
||||
|
||||
@REM ============================================================
|
||||
@REM Find fromelf.exe
|
||||
@REM ============================================================
|
||||
:find_fromelf
|
||||
if not "%KEIL_ROOT%"=="" (
|
||||
if exist "%KEIL_ROOT%\ARM\ARM_Compiler_5.06u7\bin\fromelf.exe" (
|
||||
set "FROMELF=%KEIL_ROOT%\ARM\ARM_Compiler_5.06u7\bin\fromelf.exe"
|
||||
goto :eof
|
||||
)
|
||||
if exist "%KEIL_ROOT%\ARM\ARMCC\bin\fromelf.exe" (
|
||||
set "FROMELF=%KEIL_ROOT%\ARM\ARMCC\bin\fromelf.exe"
|
||||
goto :eof
|
||||
)
|
||||
if exist "%KEIL_ROOT%\ARM\ARMCLANG\bin\fromelf.exe" (
|
||||
set "FROMELF=%KEIL_ROOT%\ARM\ARMCLANG\bin\fromelf.exe"
|
||||
goto :eof
|
||||
)
|
||||
)
|
||||
|
||||
set "KEIL_ARM="
|
||||
for /f "tokens=2*" %%a in ('reg query "HKLM\SOFTWARE\WOW6432Node\Keil\Products\MDK" /v Path 2^>nul') do set "KEIL_ARM=%%b"
|
||||
if "%KEIL_ARM%"=="" (
|
||||
for /f "tokens=2*" %%a in ('reg query "HKLM\SOFTWARE\Keil\Products\MDK" /v Path 2^>nul') do set "KEIL_ARM=%%b"
|
||||
)
|
||||
|
||||
if not "%KEIL_ARM%"=="" (
|
||||
if exist "%KEIL_ARM%\ARM_Compiler_5.06u7\bin\fromelf.exe" (
|
||||
set "FROMELF=%KEIL_ARM%\ARM_Compiler_5.06u7\bin\fromelf.exe"
|
||||
goto :eof
|
||||
)
|
||||
if exist "%KEIL_ARM%\ARMCC\bin\fromelf.exe" (
|
||||
set "FROMELF=%KEIL_ARM%\ARMCC\bin\fromelf.exe"
|
||||
goto :eof
|
||||
)
|
||||
if exist "%KEIL_ARM%\ARMCLANG\bin\fromelf.exe" (
|
||||
set "FROMELF=%KEIL_ARM%\ARMCLANG\bin\fromelf.exe"
|
||||
goto :eof
|
||||
)
|
||||
)
|
||||
|
||||
where fromelf.exe >nul 2>&1
|
||||
if not errorlevel 1 set "FROMELF=fromelf.exe"
|
||||
goto :eof
|
||||
|
||||
@REM ============================================================
|
||||
@REM Fallback: Intel HEX -> BIN (image starts at first data addr)
|
||||
@REM Write a temp ps1 to avoid cmd parenthesis parsing issues
|
||||
@REM ============================================================
|
||||
:hex2bin
|
||||
if not exist "%HEX_PATH%\%HEX_NAME%.hex" (
|
||||
echo [ERROR] HEX not found, cannot convert to BIN
|
||||
goto :eof
|
||||
)
|
||||
|
||||
set "PS1_FILE=%TEMP%\ota_hex2bin.ps1"
|
||||
> "%PS1_FILE%" echo $hex = $args[0]
|
||||
>> "%PS1_FILE%" echo $bin = $args[1]
|
||||
>> "%PS1_FILE%" echo $map = @{}
|
||||
>> "%PS1_FILE%" echo $min = [uint32]::MaxValue
|
||||
>> "%PS1_FILE%" echo $max = [uint32]0
|
||||
>> "%PS1_FILE%" echo $ext = [uint32]0
|
||||
>> "%PS1_FILE%" echo Get-Content -LiteralPath $hex ^| ForEach-Object {
|
||||
>> "%PS1_FILE%" echo if ($_.Length -lt 11) { return }
|
||||
>> "%PS1_FILE%" echo if ($_[0] -ne [char]58) { return }
|
||||
>> "%PS1_FILE%" echo $len = [Convert]::ToInt32($_.Substring(1,2),16)
|
||||
>> "%PS1_FILE%" echo $addr = [Convert]::ToUInt32($_.Substring(3,4),16)
|
||||
>> "%PS1_FILE%" echo $type = [Convert]::ToInt32($_.Substring(7,2),16)
|
||||
>> "%PS1_FILE%" echo if ($type -eq 4) { $ext = [Convert]::ToUInt32($_.Substring(9,4),16) -shl 16; return }
|
||||
>> "%PS1_FILE%" echo if ($type -eq 2) { $ext = [Convert]::ToUInt32($_.Substring(9,4),16) * 16; return }
|
||||
>> "%PS1_FILE%" echo if ($type -ne 0) { return }
|
||||
>> "%PS1_FILE%" echo $fa = $ext + $addr
|
||||
>> "%PS1_FILE%" echo if ($fa -lt $min) { $min = $fa }
|
||||
>> "%PS1_FILE%" echo for ($i = 0; $i -lt $len; $i++) { $map[$fa+$i] = [Convert]::ToByte($_.Substring(9+$i*2,2),16) }
|
||||
>> "%PS1_FILE%" echo if (($fa+$len) -gt $max) { $max = $fa+$len }
|
||||
>> "%PS1_FILE%" echo }
|
||||
>> "%PS1_FILE%" echo if ($max -le $min) { throw 'No HEX data records' }
|
||||
>> "%PS1_FILE%" echo $size = $max - $min
|
||||
>> "%PS1_FILE%" echo $bytes = New-Object byte[] $size
|
||||
>> "%PS1_FILE%" echo for ($i = 0; $i -lt $size; $i++) { $bytes[$i] = 0xFF }
|
||||
>> "%PS1_FILE%" echo foreach ($k in $map.Keys) { $bytes[$k-$min] = $map[$k] }
|
||||
>> "%PS1_FILE%" echo [IO.File]::WriteAllBytes($bin, $bytes)
|
||||
>> "%PS1_FILE%" echo Write-Host ('[OK] HEX converted to BIN, size={0} bytes, base=0x{1:X8}' -f $size, $min)
|
||||
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File "%PS1_FILE%" "%HEX_PATH%\%HEX_NAME%.hex" "%BIN_FILE%"
|
||||
goto :eof
|
||||
@@ -0,0 +1,362 @@
|
||||
/* ================================================================
|
||||
* jb_product.c — 用户层实现(请填补空白处)
|
||||
* 设备: 侠客猫激光 | 生成时间: 2026-07-28 15:42:40
|
||||
*
|
||||
* ══ 开发流程 ══
|
||||
* 1. 实现硬件抽象: uartInit / timerInit / uartWrite / jbGetTimerCount
|
||||
* 2. userInit() 设置 DP 默认值与外设初始化
|
||||
* 3. userHandle() 用户数据采集
|
||||
* 4. jbEventProcess() 处理 APP 下发的控制命令
|
||||
* 5. main.c 模板:
|
||||
*
|
||||
* int main(void)
|
||||
* {
|
||||
* uartInit();
|
||||
* timerInit();
|
||||
* jbInit();
|
||||
* userInit();
|
||||
* while (1)
|
||||
* {
|
||||
* userHandle();
|
||||
* jbProtocolHandle(&gDevData);
|
||||
* }
|
||||
* }
|
||||
* ================================================================
|
||||
*/
|
||||
|
||||
#include "jb_product.h"
|
||||
#include "jb_port.h"
|
||||
#include "main.h"
|
||||
#include "ota_ab.h"
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 全局变量
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
|
||||
jb_data_point_t gDevData;
|
||||
static volatile uint32_t timerMs;
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* userInit — DP 默认值
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
void userInit(void)
|
||||
{
|
||||
memset(&gDevData, 0, sizeof(jb_data_point_t));
|
||||
|
||||
gDevData.power = 0; /* DP0 开关 0=关 1=开 */
|
||||
gDevData.play_mode = 0; /* PLAY_MODE_0 (关) */
|
||||
gDevData.hand_mode = 0; /* HAND_MODE_0 (关) */
|
||||
gDevData.alm_low_battery = 0; /* DP3 低电量报警 0=关 1=开 */
|
||||
gDevData.beep_trig = 0; /* DP4 声音开关 0=关 1=开 */
|
||||
gDevData.battery = 0; /* DP5 电量上报 */
|
||||
gDevData.shake_wake = 0; /* DP6 震动触发开机 0=关 1=开 */
|
||||
memset(gDevData.no_disturb_enable, 0, 13); /* DP7 勿扰模式开关 */
|
||||
gDevData.reserva_dp1 = 0; /* DP8 预留DP1 */
|
||||
gDevData.reserva_dp2 = 0; /* DP9 预留DP2 */
|
||||
gDevData.reserva_dp3 = 0; /* DP10 预留DP3 */
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* userHandle — 用户数据采集
|
||||
* 协议层自动检测变化并上报(注意:此处是上报,不是下发控制)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
void userHandle(void)
|
||||
{
|
||||
/* ── 可上报 DP (RO / RW): 用户数据采集 ── */
|
||||
// gDevData.power = read_sensor(); /* DP0 开关 */
|
||||
// gDevData.play_mode = read_sensor(); /* DP1 自动模式 */
|
||||
// gDevData.alm_low_battery = read_sensor(); /* DP3 低电量报警 */
|
||||
// gDevData.beep_trig = read_sensor(); /* DP4 声音开关 */
|
||||
// gDevData.battery = read_sensor(); /* DP5 电量上报 */
|
||||
// gDevData.shake_wake = read_sensor(); /* DP6 震动触发开机 */
|
||||
// memcpy(gDevData.no_disturb_enable, sensor_read(), 13); /* DP7 勿扰模式开关 */
|
||||
// gDevData.reserva_dp1 = read_sensor(); /* DP8 预留DP1 */
|
||||
// gDevData.reserva_dp2 = read_sensor(); /* DP9 预留DP2 */
|
||||
// gDevData.reserva_dp3 = read_sensor(); /* DP10 预留DP3 */
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbEventProcess — 0x03 APP 控制事件处理(下行 / DP 赋值方向)
|
||||
*
|
||||
* 协议层自动解包 0x03 帧后调用本函数。
|
||||
* info->dp_ids[] = 被控制的 DP ID 列表
|
||||
* ctrl 已填入下发的值;复制到 gDevData 并执行动作
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
|
||||
{
|
||||
if (!info || !ctrl)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < info->count; i++)
|
||||
{
|
||||
switch (info->dp_ids[i])
|
||||
{
|
||||
|
||||
/* ── DP0 开关 (bool) ── */
|
||||
case DP_ID_POWER:
|
||||
if (ctrl->power)
|
||||
{
|
||||
gDevData.power = 1;
|
||||
// TODO: 开 — 执行动作
|
||||
}
|
||||
else
|
||||
{
|
||||
gDevData.power = 0;
|
||||
// TODO: 关 — 执行动作
|
||||
}
|
||||
break;
|
||||
|
||||
/* ── DP1 自动模式 (enum) ── */
|
||||
case DP_ID_PLAY_MODE:
|
||||
gDevData.play_mode = ctrl->play_mode;
|
||||
switch (ctrl->play_mode)
|
||||
{
|
||||
case PLAY_MODE_0: /* 关 */
|
||||
// TODO: 处理 关
|
||||
break;
|
||||
case PLAY_MODE_1: /* mode1 */
|
||||
// TODO: 处理 mode1
|
||||
break;
|
||||
case PLAY_MODE_2: /* mode2 */
|
||||
// TODO: 处理 mode2
|
||||
break;
|
||||
case PLAY_MODE_3: /* mode3 */
|
||||
// TODO: 处理 mode3
|
||||
break;
|
||||
case PLAY_MODE_4: /* mode4 */
|
||||
// TODO: 处理 mode4
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* ── DP2 手动模式 (enum) ── */
|
||||
case DP_ID_HAND_MODE:
|
||||
gDevData.hand_mode = ctrl->hand_mode;
|
||||
switch (ctrl->hand_mode)
|
||||
{
|
||||
case HAND_MODE_0: /* 关 */
|
||||
// TODO: 处理 关
|
||||
break;
|
||||
case HAND_MODE_1: /* 顺时针 */
|
||||
// TODO: 处理 顺时针
|
||||
break;
|
||||
case HAND_MODE_2: /* 逆时针 */
|
||||
// TODO: 处理 逆时针
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* ── DP4 声音开关 (bool) ── */
|
||||
case DP_ID_BEEP_TRIG:
|
||||
if (ctrl->beep_trig)
|
||||
{
|
||||
gDevData.beep_trig = 1;
|
||||
// TODO: 开 — 执行动作
|
||||
}
|
||||
else
|
||||
{
|
||||
gDevData.beep_trig = 0;
|
||||
// TODO: 关 — 执行动作
|
||||
}
|
||||
break;
|
||||
|
||||
/* ── DP6 震动触发开机 (bool) ── */
|
||||
case DP_ID_SHAKE_WAKE:
|
||||
if (ctrl->shake_wake)
|
||||
{
|
||||
gDevData.shake_wake = 1;
|
||||
// TODO: 开 — 执行动作
|
||||
}
|
||||
else
|
||||
{
|
||||
gDevData.shake_wake = 0;
|
||||
// TODO: 关 — 执行动作
|
||||
}
|
||||
break;
|
||||
|
||||
/* ── DP7 勿扰模式开关 (raw) ── */
|
||||
case DP_ID_NO_DISTURB_ENABLE:
|
||||
memcpy(gDevData.no_disturb_enable, ctrl->no_disturb_enable, 13);
|
||||
// TODO: 根据 gDevData.no_disturb_enable 执行动作 (长度 13 字节)
|
||||
break;
|
||||
|
||||
/* ── DP8 预留DP1 (uint32) ── */
|
||||
case DP_ID_RESERVA_DP1:
|
||||
gDevData.reserva_dp1 = ctrl->reserva_dp1;
|
||||
// TODO: 根据 ctrl->reserva_dp1 执行动作
|
||||
break;
|
||||
|
||||
/* ── DP9 预留DP2 (uint32) ── */
|
||||
case DP_ID_RESERVA_DP2:
|
||||
gDevData.reserva_dp2 = ctrl->reserva_dp2;
|
||||
// TODO: 根据 ctrl->reserva_dp2 执行动作
|
||||
break;
|
||||
|
||||
/* ── DP10 预留DP3 (uint32) ── */
|
||||
case DP_ID_RESERVA_DP3:
|
||||
gDevData.reserva_dp3 = ctrl->reserva_dp3;
|
||||
// TODO: 根据 ctrl->reserva_dp3 执行动作
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* BLE → MCU 回调(按需实现)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* 0x14 工作状态同步(含 RSSI)*/
|
||||
void jbOnWorkState(uint8_t state, int8_t rssi)
|
||||
{
|
||||
(void)state;
|
||||
(void)rssi;
|
||||
// Bit0=已配网 Bit1=外网 Bit2=App在线 Bit3=BLE连接 Bit4=OTA Bit5=配对
|
||||
// TODO: 按状态位更新状态指示;rssi: >=-60 优秀, -61~-70 良好, -71~-80 一般, -81~-90 较差, <-90 极差
|
||||
}
|
||||
|
||||
/* 0x1A BLE 通知 MCU 重启 */
|
||||
void jbOnBleRestartRequest(void)
|
||||
{
|
||||
ota_abort();
|
||||
mcuRestart();
|
||||
}
|
||||
|
||||
/* 0x30 OTA 升级请求
|
||||
* 返回 0=接受升级(协议层应答 JB_OK + MaxDataLen)
|
||||
* 非 0=拒绝,返回值即错误码(JB_OTA_*) */
|
||||
int8_t jbOnOtaNotify(uint32_t fwVersion, uint32_t fwLength, uint32_t fwCrc32)
|
||||
{
|
||||
/* 版本校验:拒绝「版本一致」与「降级」,只允许升级到更高版本。 */
|
||||
const uint32_t curVer = ((uint32_t)JB_MCU_SW_VERSION_MAJOR << 16) |
|
||||
((uint32_t)JB_MCU_SW_VERSION_MINOR << 8) |
|
||||
(uint32_t)JB_MCU_SW_VERSION_PATCH;
|
||||
appPrintf(LOG_NOTIC, "OTA notify: ver=%06X cur=%06X len=%lu crc=%08X\r\n",
|
||||
(unsigned int)fwVersion, (unsigned int)curVer,
|
||||
(unsigned long)fwLength, (unsigned int)fwCrc32);
|
||||
|
||||
if (fwVersion == curVer)
|
||||
{
|
||||
appPrintf(LOG_NOTIC, "OTA reject: same version, no need to upgrade\r\n");
|
||||
return JB_OTA_NO_NEED; /* 0x20 版本一致,无需升级 */
|
||||
}
|
||||
if (fwVersion < curVer)
|
||||
{
|
||||
appPrintf(LOG_NOTIC, "OTA reject: version lower than current\r\n");
|
||||
return JB_OTA_VER_LOW; /* 0x21 版本低于当前,拒绝降级 */
|
||||
}
|
||||
|
||||
if ((fwLength == 0) || (fwLength > OTA_SLOT_MAX_SIZE))
|
||||
{
|
||||
appPrintf(LOG_ERROR, "OTA reject: length %lu out of range\r\n", (unsigned long)fwLength);
|
||||
return JB_OTA_SPACE_ERR;
|
||||
}
|
||||
if (ota_start(fwLength, fwCrc32) != 0)
|
||||
{
|
||||
return JB_OTA_STATE_ERR;
|
||||
}
|
||||
return JB_OK;
|
||||
}
|
||||
|
||||
/* 0x32 OTA 数据(含分片序号)*/
|
||||
void jbOnOtaData(const uint8_t *data, uint16_t len, uint16_t shardIdx, uint16_t totalShards)
|
||||
{
|
||||
if (ota_receive_chunk(data, len) != 0)
|
||||
{
|
||||
appPrintf(LOG_ERROR, "OTA chunk write fail (shard %u/%u)\r\n", shardIdx, totalShards);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 以 0x30 的 fwLength 收满为准,不依赖分片序号 0/1 基 */
|
||||
if (ota_is_download_complete())
|
||||
{
|
||||
appPrintf(LOG_NOTIC, "OTA download complete (shard %u/%u), verify...\r\n",
|
||||
shardIdx, totalShards);
|
||||
if (ota_finish() == 0)
|
||||
{
|
||||
appPrintf(LOG_NOTIC, "OTA verify OK, rebooting...\r\n");
|
||||
HAL_Delay(100);
|
||||
mcuRestart();
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t ver[3] = {
|
||||
JB_MCU_SW_VERSION_MAJOR,
|
||||
JB_MCU_SW_VERSION_MINOR,
|
||||
JB_MCU_SW_VERSION_PATCH};
|
||||
appPrintf(LOG_ERROR, "OTA verify FAILED\r\n");
|
||||
(void)jbSendOtaResult(JB_OTA_FILE_ERR, ver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 0x36 / 0x38 停止 OTA */
|
||||
void jbOnOtaStop(void)
|
||||
{
|
||||
ota_abort();
|
||||
}
|
||||
|
||||
/* 0x1D 时间同步应答 */
|
||||
void jbOnTimeSync(uint32_t timestamp)
|
||||
{
|
||||
/* Unix 时间戳(秒);后续可在此写入 MCU RTC */
|
||||
appPrintf(LOG_NOTIC, "RTC time sync: timestamp=%lu\r\n",
|
||||
(unsigned long)timestamp);
|
||||
}
|
||||
|
||||
/* 任意 MCU→BLE 请求的 ACK 回调(cmd 标识是哪条请求的应答,result 为结果码)
|
||||
- 如配对 0x11 / 产测 0x21 / 拍照 0x23 / 录像 0x25 / 音频 0x27 / OTA完成 0x35 / 停止 0x39
|
||||
- 可在本回调中设置"XX 完成/失败"标志,供主循环判断"确认成功才继续" */
|
||||
void jbOnAck(uint8_t cmd, uint8_t result)
|
||||
{
|
||||
(void)cmd;
|
||||
(void)result;
|
||||
// TODO: switch(cmd){ case CMD_PAIRING_ACK: gPairingDone = (result==JB_OK); break; ... }
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 硬件抽象(按实际平台实现)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* ── 定时器 ── */
|
||||
void jbTimerIrq(void)
|
||||
{
|
||||
timerMs++;
|
||||
} /* 在 1ms 中断中调用本函数 */
|
||||
|
||||
uint32_t jbGetTimerCount(void)
|
||||
{
|
||||
return timerMs;
|
||||
}
|
||||
|
||||
void timerInit(void)
|
||||
{
|
||||
timerMs = 0;
|
||||
jb_port_timer_init();
|
||||
}
|
||||
|
||||
/* ── UART ── */
|
||||
void uartInit(void)
|
||||
{
|
||||
jb_port_uart_init();
|
||||
}
|
||||
|
||||
int32_t uartWrite(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
return jb_port_uart_write(buf, len);
|
||||
}
|
||||
|
||||
/* ── 系统 ── */
|
||||
void mcuRestart(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/* ================================================================
|
||||
* jb_product.h — 用户层头文件(自动生成)
|
||||
* 设备: 侠客猫激光 | 生成时间: 2026-07-28 15:42:40
|
||||
*
|
||||
* 声明用户需实现的函数。数据结构定义见 jb_protocol.h
|
||||
* ================================================================
|
||||
*/
|
||||
|
||||
#ifndef _JB_PRODUCT_H
|
||||
#define _JB_PRODUCT_H
|
||||
|
||||
#include "jb_protocol.h"
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 硬件配置(按实际 MCU 调整)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
#define UART_BAUDRATE 9600
|
||||
#define TIMER_PERIOD_MS 1
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 版本管理
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
/* MCU software version: Vmajor.minor.patch */
|
||||
#define JB_MCU_SW_VERSION_MAJOR 1
|
||||
#define JB_MCU_SW_VERSION_MINOR 0
|
||||
#define JB_MCU_SW_VERSION_PATCH 0
|
||||
|
||||
/* MCU hardware version: Vmajor.minor.patch */
|
||||
#define JB_MCU_HW_VERSION_MAJOR 1
|
||||
#define JB_MCU_HW_VERSION_MINOR 0
|
||||
#define JB_MCU_HW_VERSION_PATCH 0
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 用户 API
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* 全局设备数据 — 协议层直接读写该变量 */
|
||||
extern jb_data_point_t gDevData;
|
||||
|
||||
/* ==================== 用户必须实现 ============================== */
|
||||
void userInit(void); /* DP 默认值与外设初始化 */
|
||||
void userHandle(void); /* 用户数据采集 */
|
||||
void uartInit(void); /* UART 9600 8N1 */
|
||||
void timerInit(void); /* 1ms 定时器 */
|
||||
void jbTimerIrq(void); /* Call from 1ms timer ISR */
|
||||
void mcuRestart(void); /* 软件复位 */
|
||||
|
||||
/* =========== 协议回调(声明见 jb_protocol.h)================== */
|
||||
/* int8_t jbEventProcess(...); // 0x03 控制事件 */
|
||||
/* void jbOnWorkState(...); // 0x14 状态同步(含RSSI) */
|
||||
/* void jbOnBleRestartRequest(); // 0x1A BLE 通知重启 */
|
||||
/* void jbOnOtaNotify(...); // 0x30 OTA 请求 */
|
||||
/* void jbOnOtaData(...); // 0x32 OTA 数据 */
|
||||
/* void jbOnOtaStop(); // 0x36/0x38 停止 OTA */
|
||||
/* void jbOnTimeSync(...); // 0x1D 时间同步应答 */
|
||||
/* void jbOnAck(...); // 任意请求 ACK(结果) */
|
||||
|
||||
/* ============= 主动请求(声明见 jb_protocol.h)================ */
|
||||
/* int32_t jbRequestPairing(...); // 0x10 请求配对 */
|
||||
/* int32_t jbRequestTime(); // 0x1C 获取时间 */
|
||||
/* int32_t jbRequestBleReset(); // 0x16 重置 BLE */
|
||||
/* int32_t jbRequestBleRestart(); // 0x18 重启 BLE */
|
||||
/* int32_t jbRequestProduction(...); // 0x20 产测模式 */
|
||||
/* int32_t jbRequestPhoto(); // 0x22 开启拍照 */
|
||||
/* int32_t jbRequestRecord(...); // 0x24 开启录像 */
|
||||
/* int32_t jbRequestAudio(...); // 0x26 启动音频 */
|
||||
/* int32_t jbNotifyOtaStop(); // 0x38 通知 BLE 停止 OTA */
|
||||
/* int32_t jbSendOtaResult(...); // 0x34 OTA 结果 */
|
||||
|
||||
#endif /* _JB_PRODUCT_H */
|
||||
@@ -0,0 +1,943 @@
|
||||
/* ================================================================
|
||||
* jb_protocol.c — 见宝 IOT 协议实现(自动生成)
|
||||
* 设备: 侠客猫激光 | 生成时间: 2026-07-28 15:42:40
|
||||
* ================================================================
|
||||
*/
|
||||
|
||||
#include "jb_protocol.h"
|
||||
#include "jb_common.h"
|
||||
#include "jb_product.h"
|
||||
#include "jb_ringbuffer.h"
|
||||
#include "stdio.h"
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 全局实例
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
jb_protocol_t jbProtocol;
|
||||
static jb_ringbuffer_t rb; /* UART 接收缓冲区 */
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbInit — 协议层初始化
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
void jbInit(void)
|
||||
{
|
||||
memset(&jbProtocol, 0, sizeof(jb_protocol_t));
|
||||
jbRbInit(&rb);
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbPutData — UART 中断将数据压入环形缓冲区
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
int32_t jbPutData(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
if (!buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
for (uint32_t i = 0; i < len; i++)
|
||||
{
|
||||
jbRbPush(&rb, buf[i]);
|
||||
}
|
||||
return (int32_t)len;
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbSendFrame — 组装协议帧并发送到 UART
|
||||
* 返回帧总长度,< 0 表示出错
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
static int32_t jbSendFrame(uint8_t cmd, uint8_t sn,
|
||||
const uint8_t *payload, uint16_t pLen)
|
||||
{
|
||||
uint8_t buf[MAX_PACKAGE_LEN];
|
||||
uint16_t lenField = pLen + 3; /* CMD + SN + payload + CKSUM */
|
||||
uint16_t total = lenField + 4;
|
||||
|
||||
if (total > MAX_PACKAGE_LEN)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 55 AA | LEN_H LEN_L | CMD | SN | payload | CKSUM */
|
||||
buf[0] = PKT_HEAD_0;
|
||||
buf[1] = PKT_HEAD_1;
|
||||
jbWriteU16BE(&buf[2], lenField);
|
||||
buf[4] = cmd;
|
||||
buf[5] = sn;
|
||||
if (payload && pLen > 0)
|
||||
{
|
||||
memcpy(&buf[6], payload, pLen);
|
||||
}
|
||||
buf[total - 1] = jbChecksum(buf, total);
|
||||
|
||||
return uartWrite(buf, total);
|
||||
}
|
||||
|
||||
/* 发送单字节结果应答 */
|
||||
static void jbSendAck(uint8_t cmd, uint8_t sn, uint8_t result)
|
||||
{
|
||||
jbSendFrame(cmd, sn, &result, 1);
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbGetOnePacket — 从环形缓冲区提取完整帧
|
||||
* 返回: 0 = 成功, 1 = 需要更多数据, -2 = 校验和错误
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
static int8_t jbGetOnePacket(uint8_t *out, uint16_t *outLen)
|
||||
{
|
||||
static uint8_t state = 0;
|
||||
static uint16_t expect = 0;
|
||||
static uint16_t idx = 0;
|
||||
static uint8_t prev = 0;
|
||||
|
||||
while (jbRbAvailable(&rb))
|
||||
{
|
||||
uint8_t b = jbRbPop(&rb);
|
||||
|
||||
if (state == 0)
|
||||
{
|
||||
/* 搜索同步头 55 AA */
|
||||
if (prev == PKT_HEAD_0 && b == PKT_HEAD_1)
|
||||
{
|
||||
out[0] = PKT_HEAD_0;
|
||||
out[1] = PKT_HEAD_1;
|
||||
idx = 2;
|
||||
state = 1;
|
||||
}
|
||||
}
|
||||
else if (state == 1)
|
||||
{
|
||||
/* 接收 LEN(2B) + CMD + SN */
|
||||
out[idx++] = b;
|
||||
if (idx == 6)
|
||||
{
|
||||
expect = 4 + jbReadU16BE(&out[2]);
|
||||
if (expect > MAX_PACKAGE_LEN || expect < 7)
|
||||
{
|
||||
state = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 接收剩余数据 */
|
||||
out[idx++] = b;
|
||||
if (idx >= expect)
|
||||
{
|
||||
state = 0;
|
||||
if (out[expect - 1] == jbChecksum(out, expect))
|
||||
{
|
||||
*outLen = expect;
|
||||
return 0;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
prev = b;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbPackDps — dataPoint → outBuf[bitmap | values]
|
||||
* mask 指定要打包的 DP(bit 序号 = DP ID)
|
||||
* 返回 outBuf 总字节数(bitmap + values)
|
||||
* 仅打包 RO / RW 方向的 DP
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
static uint16_t jbPackDps(const jb_data_point_t *dp,
|
||||
const uint8_t *mask, uint8_t *outBuf)
|
||||
{
|
||||
uint8_t *bitmap = outBuf;
|
||||
uint8_t *out = outBuf + DP_BITMAP_SIZE;
|
||||
uint16_t valIdx = 0;
|
||||
memset(bitmap, 0, DP_BITMAP_SIZE);
|
||||
|
||||
/* DP0 开关 (bool, 1B, RW) */
|
||||
if (mask[DP_ID_POWER / 8] & (1 << (DP_ID_POWER % 8)))
|
||||
{
|
||||
bitmap[DP_ID_POWER / 8] |= (1 << (DP_ID_POWER % 8));
|
||||
out[valIdx++] = dp->power ? 1 : 0;
|
||||
}
|
||||
/* DP1 自动模式 (enum, 1B, RW) */
|
||||
if (mask[DP_ID_PLAY_MODE / 8] & (1 << (DP_ID_PLAY_MODE % 8)))
|
||||
{
|
||||
bitmap[DP_ID_PLAY_MODE / 8] |= (1 << (DP_ID_PLAY_MODE % 8));
|
||||
out[valIdx++] = (uint8_t)dp->play_mode;
|
||||
}
|
||||
/* DP3 低电量报警 (bool, 1B, RO) */
|
||||
if (mask[DP_ID_ALM_LOW_BATTERY / 8] & (1 << (DP_ID_ALM_LOW_BATTERY % 8)))
|
||||
{
|
||||
bitmap[DP_ID_ALM_LOW_BATTERY / 8] |= (1 << (DP_ID_ALM_LOW_BATTERY % 8));
|
||||
out[valIdx++] = dp->alm_low_battery ? 1 : 0;
|
||||
}
|
||||
/* DP4 声音开关 (bool, 1B, RW) */
|
||||
if (mask[DP_ID_BEEP_TRIG / 8] & (1 << (DP_ID_BEEP_TRIG % 8)))
|
||||
{
|
||||
bitmap[DP_ID_BEEP_TRIG / 8] |= (1 << (DP_ID_BEEP_TRIG % 8));
|
||||
out[valIdx++] = dp->beep_trig ? 1 : 0;
|
||||
}
|
||||
/* DP5 电量上报 (uint8, 1B, RO) */
|
||||
if (mask[DP_ID_BATTERY / 8] & (1 << (DP_ID_BATTERY % 8)))
|
||||
{
|
||||
bitmap[DP_ID_BATTERY / 8] |= (1 << (DP_ID_BATTERY % 8));
|
||||
out[valIdx++] = (uint8_t)dp->battery;
|
||||
}
|
||||
/* DP6 震动触发开机 (bool, 1B, RW) */
|
||||
if (mask[DP_ID_SHAKE_WAKE / 8] & (1 << (DP_ID_SHAKE_WAKE % 8)))
|
||||
{
|
||||
bitmap[DP_ID_SHAKE_WAKE / 8] |= (1 << (DP_ID_SHAKE_WAKE % 8));
|
||||
out[valIdx++] = dp->shake_wake ? 1 : 0;
|
||||
}
|
||||
/* DP7 勿扰模式开关 (raw, 13B, RW) */
|
||||
if (mask[DP_ID_NO_DISTURB_ENABLE / 8] & (1 << (DP_ID_NO_DISTURB_ENABLE % 8)))
|
||||
{
|
||||
bitmap[DP_ID_NO_DISTURB_ENABLE / 8] |= (1 << (DP_ID_NO_DISTURB_ENABLE % 8));
|
||||
memcpy(&out[valIdx], dp->no_disturb_enable, 13);
|
||||
valIdx += 13;
|
||||
}
|
||||
/* DP8 预留DP1 (uint32, 4B, RW) */
|
||||
if (mask[DP_ID_RESERVA_DP1 / 8] & (1 << (DP_ID_RESERVA_DP1 % 8)))
|
||||
{
|
||||
bitmap[DP_ID_RESERVA_DP1 / 8] |= (1 << (DP_ID_RESERVA_DP1 % 8));
|
||||
jbWriteU32BE(&out[valIdx], (uint32_t)dp->reserva_dp1);
|
||||
valIdx += 4;
|
||||
}
|
||||
/* DP9 预留DP2 (uint32, 4B, RW) */
|
||||
if (mask[DP_ID_RESERVA_DP2 / 8] & (1 << (DP_ID_RESERVA_DP2 % 8)))
|
||||
{
|
||||
bitmap[DP_ID_RESERVA_DP2 / 8] |= (1 << (DP_ID_RESERVA_DP2 % 8));
|
||||
jbWriteU32BE(&out[valIdx], (uint32_t)dp->reserva_dp2);
|
||||
valIdx += 4;
|
||||
}
|
||||
/* DP10 预留DP3 (uint32, 4B, RW) */
|
||||
if (mask[DP_ID_RESERVA_DP3 / 8] & (1 << (DP_ID_RESERVA_DP3 % 8)))
|
||||
{
|
||||
bitmap[DP_ID_RESERVA_DP3 / 8] |= (1 << (DP_ID_RESERVA_DP3 % 8));
|
||||
jbWriteU32BE(&out[valIdx], (uint32_t)dp->reserva_dp3);
|
||||
valIdx += 4;
|
||||
}
|
||||
|
||||
return DP_BITMAP_SIZE + valIdx;
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbUnpackDps — bitmap+values → dataPoint + event_info
|
||||
* 仅解包 WO / RW 方向的 DP
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
static void jbUnpackDps(const uint8_t *bitmap, const uint8_t *values,
|
||||
uint16_t valLen, jb_data_point_t *dp,
|
||||
jb_event_info_t *info)
|
||||
{
|
||||
uint16_t valIdx = 0;
|
||||
if (info)
|
||||
{
|
||||
info->count = 0;
|
||||
}
|
||||
|
||||
/* DP0 开关 (bool, 1B, RW) */
|
||||
if (bitmap[DP_ID_POWER / 8] & (1 << (DP_ID_POWER % 8)))
|
||||
{
|
||||
if (valIdx < valLen)
|
||||
{
|
||||
dp->power = (values[valIdx++] != 0);
|
||||
}
|
||||
if (info && info->count < DP_ID_MAX)
|
||||
{
|
||||
info->dp_ids[info->count++] = DP_ID_POWER;
|
||||
}
|
||||
}
|
||||
/* DP1 自动模式 (enum, 1B, RW) */
|
||||
if (bitmap[DP_ID_PLAY_MODE / 8] & (1 << (DP_ID_PLAY_MODE % 8)))
|
||||
{
|
||||
if (valIdx < valLen)
|
||||
{
|
||||
dp->play_mode = values[valIdx++];
|
||||
}
|
||||
if (info && info->count < DP_ID_MAX)
|
||||
{
|
||||
info->dp_ids[info->count++] = DP_ID_PLAY_MODE;
|
||||
}
|
||||
}
|
||||
/* DP2 手动模式 (enum, 1B, WO) */
|
||||
if (bitmap[DP_ID_HAND_MODE / 8] & (1 << (DP_ID_HAND_MODE % 8)))
|
||||
{
|
||||
if (valIdx < valLen)
|
||||
{
|
||||
dp->hand_mode = values[valIdx++];
|
||||
}
|
||||
if (info && info->count < DP_ID_MAX)
|
||||
{
|
||||
info->dp_ids[info->count++] = DP_ID_HAND_MODE;
|
||||
}
|
||||
}
|
||||
/* DP4 声音开关 (bool, 1B, RW) */
|
||||
if (bitmap[DP_ID_BEEP_TRIG / 8] & (1 << (DP_ID_BEEP_TRIG % 8)))
|
||||
{
|
||||
if (valIdx < valLen)
|
||||
{
|
||||
dp->beep_trig = (values[valIdx++] != 0);
|
||||
}
|
||||
if (info && info->count < DP_ID_MAX)
|
||||
{
|
||||
info->dp_ids[info->count++] = DP_ID_BEEP_TRIG;
|
||||
}
|
||||
}
|
||||
/* DP6 震动触发开机 (bool, 1B, RW) */
|
||||
if (bitmap[DP_ID_SHAKE_WAKE / 8] & (1 << (DP_ID_SHAKE_WAKE % 8)))
|
||||
{
|
||||
if (valIdx < valLen)
|
||||
{
|
||||
dp->shake_wake = (values[valIdx++] != 0);
|
||||
}
|
||||
if (info && info->count < DP_ID_MAX)
|
||||
{
|
||||
info->dp_ids[info->count++] = DP_ID_SHAKE_WAKE;
|
||||
}
|
||||
}
|
||||
/* DP7 勿扰模式开关 (raw, 13B, RW) */
|
||||
if (bitmap[DP_ID_NO_DISTURB_ENABLE / 8] & (1 << (DP_ID_NO_DISTURB_ENABLE % 8)))
|
||||
{
|
||||
if (valIdx + 13 <= valLen)
|
||||
{
|
||||
memcpy(dp->no_disturb_enable, &values[valIdx], 13);
|
||||
valIdx += 13;
|
||||
}
|
||||
if (info && info->count < DP_ID_MAX)
|
||||
{
|
||||
info->dp_ids[info->count++] = DP_ID_NO_DISTURB_ENABLE;
|
||||
}
|
||||
}
|
||||
/* DP8 预留DP1 (uint32, 4B, RW) */
|
||||
if (bitmap[DP_ID_RESERVA_DP1 / 8] & (1 << (DP_ID_RESERVA_DP1 % 8)))
|
||||
{
|
||||
if (valIdx + 4 <= valLen)
|
||||
{
|
||||
dp->reserva_dp1 = (uint32_t)jbReadU32BE(&values[valIdx]);
|
||||
valIdx += 4;
|
||||
}
|
||||
if (info && info->count < DP_ID_MAX)
|
||||
{
|
||||
info->dp_ids[info->count++] = DP_ID_RESERVA_DP1;
|
||||
}
|
||||
}
|
||||
/* DP9 预留DP2 (uint32, 4B, RW) */
|
||||
if (bitmap[DP_ID_RESERVA_DP2 / 8] & (1 << (DP_ID_RESERVA_DP2 % 8)))
|
||||
{
|
||||
if (valIdx + 4 <= valLen)
|
||||
{
|
||||
dp->reserva_dp2 = (uint32_t)jbReadU32BE(&values[valIdx]);
|
||||
valIdx += 4;
|
||||
}
|
||||
if (info && info->count < DP_ID_MAX)
|
||||
{
|
||||
info->dp_ids[info->count++] = DP_ID_RESERVA_DP2;
|
||||
}
|
||||
}
|
||||
/* DP10 预留DP3 (uint32, 4B, RW) */
|
||||
if (bitmap[DP_ID_RESERVA_DP3 / 8] & (1 << (DP_ID_RESERVA_DP3 % 8)))
|
||||
{
|
||||
if (valIdx + 4 <= valLen)
|
||||
{
|
||||
dp->reserva_dp3 = (uint32_t)jbReadU32BE(&values[valIdx]);
|
||||
valIdx += 4;
|
||||
}
|
||||
if (info && info->count < DP_ID_MAX)
|
||||
{
|
||||
info->dp_ids[info->count++] = DP_ID_RESERVA_DP3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbBuildDiffMask — 比较上次与当前值,为变化的可上报 DP 置 mask 位
|
||||
* 返回: 1 = 有 DP 发生变化, 0 = 全部未变化
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
static uint8_t jbBuildDiffMask(const jb_data_point_t *last,
|
||||
const jb_data_point_t *cur,
|
||||
uint8_t *mask)
|
||||
{
|
||||
uint8_t hasChange = 0;
|
||||
memset(mask, 0, DP_BITMAP_SIZE);
|
||||
|
||||
/* DP0 开关 */
|
||||
if (last->power != cur->power)
|
||||
{
|
||||
mask[DP_ID_POWER / 8] |= (1 << (DP_ID_POWER % 8));
|
||||
hasChange = 1;
|
||||
}
|
||||
/* DP1 自动模式 */
|
||||
if (last->play_mode != cur->play_mode)
|
||||
{
|
||||
mask[DP_ID_PLAY_MODE / 8] |= (1 << (DP_ID_PLAY_MODE % 8));
|
||||
hasChange = 1;
|
||||
}
|
||||
/* DP3 低电量报警 */
|
||||
if (last->alm_low_battery != cur->alm_low_battery)
|
||||
{
|
||||
mask[DP_ID_ALM_LOW_BATTERY / 8] |= (1 << (DP_ID_ALM_LOW_BATTERY % 8));
|
||||
hasChange = 1;
|
||||
}
|
||||
/* DP4 声音开关 */
|
||||
if (last->beep_trig != cur->beep_trig)
|
||||
{
|
||||
mask[DP_ID_BEEP_TRIG / 8] |= (1 << (DP_ID_BEEP_TRIG % 8));
|
||||
hasChange = 1;
|
||||
}
|
||||
/* DP5 电量上报 */
|
||||
if (last->battery != cur->battery)
|
||||
{
|
||||
mask[DP_ID_BATTERY / 8] |= (1 << (DP_ID_BATTERY % 8));
|
||||
hasChange = 1;
|
||||
}
|
||||
/* DP6 震动触发开机 */
|
||||
if (last->shake_wake != cur->shake_wake)
|
||||
{
|
||||
mask[DP_ID_SHAKE_WAKE / 8] |= (1 << (DP_ID_SHAKE_WAKE % 8));
|
||||
hasChange = 1;
|
||||
}
|
||||
/* DP7 勿扰模式开关 */
|
||||
if (memcmp(last->no_disturb_enable, cur->no_disturb_enable, 13))
|
||||
{
|
||||
mask[DP_ID_NO_DISTURB_ENABLE / 8] |= (1 << (DP_ID_NO_DISTURB_ENABLE % 8));
|
||||
hasChange = 1;
|
||||
}
|
||||
/* DP8 预留DP1 */
|
||||
if (last->reserva_dp1 != cur->reserva_dp1)
|
||||
{
|
||||
mask[DP_ID_RESERVA_DP1 / 8] |= (1 << (DP_ID_RESERVA_DP1 % 8));
|
||||
hasChange = 1;
|
||||
}
|
||||
/* DP9 预留DP2 */
|
||||
if (last->reserva_dp2 != cur->reserva_dp2)
|
||||
{
|
||||
mask[DP_ID_RESERVA_DP2 / 8] |= (1 << (DP_ID_RESERVA_DP2 % 8));
|
||||
hasChange = 1;
|
||||
}
|
||||
/* DP10 预留DP3 */
|
||||
if (last->reserva_dp3 != cur->reserva_dp3)
|
||||
{
|
||||
mask[DP_ID_RESERVA_DP3 / 8] |= (1 << (DP_ID_RESERVA_DP3 % 8));
|
||||
hasChange = 1;
|
||||
}
|
||||
|
||||
return hasChange;
|
||||
}
|
||||
|
||||
/* 置全量掩码(所有可上报 DP)*/
|
||||
static void jbSetFullMask(uint8_t *mask)
|
||||
{
|
||||
memset(mask, 0xFF, DP_BITMAP_SIZE);
|
||||
if (DP_COUNT % 8)
|
||||
{
|
||||
mask[DP_BITMAP_SIZE - 1] &= (1 << (DP_COUNT % 8)) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbSendReqWithAck — 发送请求帧并登记 ACK 重传
|
||||
*
|
||||
* 与 jbSendFrame 不同,本函数把完整帧缓存到 waitAck.buf,
|
||||
* 并启动 ACK 等待。本协议约定 ACK 命令码 = 请求命令码 + 1
|
||||
* (如 0x10→0x11),收到对应 ACK 时由 jbWaitAckCheck() 清除
|
||||
* 等待;若 SEND_MAX_TIME 内未收到,jbAckRetry() 自动重传,
|
||||
* 最多 SEND_MAX_NUM 次。
|
||||
* 返回 uartWrite 结果(<0 出错)。
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
static int32_t jbSendReqWithAck(uint8_t cmd, uint8_t sn,
|
||||
const uint8_t *payload, uint16_t pLen)
|
||||
{
|
||||
uint16_t lenField = pLen + 3; /* CMD + SN + payload + CKSUM */
|
||||
uint16_t total = lenField + 4; /* + 55 AA + LEN(2) */
|
||||
|
||||
if (total > MAX_PACKAGE_LEN)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t buf[MAX_PACKAGE_LEN];
|
||||
buf[0] = PKT_HEAD_0;
|
||||
buf[1] = PKT_HEAD_1;
|
||||
jbWriteU16BE(&buf[2], lenField);
|
||||
buf[4] = cmd;
|
||||
buf[5] = sn;
|
||||
if (payload && pLen > 0)
|
||||
{
|
||||
memcpy(&buf[6], payload, pLen);
|
||||
}
|
||||
buf[total - 1] = jbChecksum(buf, total);
|
||||
|
||||
/* 缓存整帧,供超时重传 */
|
||||
memcpy(jbProtocol.waitAck.buf, buf, total);
|
||||
jbProtocol.waitAck.len = total;
|
||||
jbProtocol.waitAck.active = 1;
|
||||
jbProtocol.waitAck.sn = sn;
|
||||
jbProtocol.waitAck.retry = 0;
|
||||
jbProtocol.waitAck.sendTime = jbGetTimerCount();
|
||||
|
||||
return uartWrite(buf, total);
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbAckRetry — ACK 超时重传
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
static void jbAckRetry(void)
|
||||
{
|
||||
if (!jbProtocol.waitAck.active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (jbProtocol.waitAck.retry >= SEND_MAX_NUM)
|
||||
{
|
||||
memset(&jbProtocol.waitAck, 0, sizeof(jb_wait_ack_t));
|
||||
return;
|
||||
}
|
||||
if (jbGetTimerCount() - jbProtocol.waitAck.sendTime > SEND_MAX_TIME)
|
||||
{
|
||||
uartWrite(jbProtocol.waitAck.buf, jbProtocol.waitAck.len);
|
||||
jbProtocol.waitAck.retry++;
|
||||
jbProtocol.waitAck.sendTime = jbGetTimerCount();
|
||||
}
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbWaitAckCheck — ACK 等待处理
|
||||
*
|
||||
* 收到一个 BLE→MCU 的 ACK 帧后,在每个 ACK 的 case 中调用本函数。
|
||||
* 若当前有等待中的请求,且其命令码 +1 等于本帧命令码
|
||||
* (本协议约定:ACK 命令码 = 请求命令码 + 1,如 0x10→0x11),
|
||||
* 则清除 waitAck、停止重传。
|
||||
*
|
||||
* head: 该 ACK 帧首地址(即 jbProtocol.rxBuf)。
|
||||
* 返回: -1=参数错误; 1=命中并清除等待; 0=未命中(无等待或非对应 ACK)。
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
static int8_t jbWaitAckCheck(const uint8_t *head)
|
||||
{
|
||||
if (NULL == head)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (jbProtocol.waitAck.active &&
|
||||
(jbProtocol.waitAck.buf[4] + 1 == head[4]))
|
||||
{
|
||||
uint8_t cmd = head[4];
|
||||
uint8_t result = head[6]; /* 应答结果字节固定位于偏移 6 */
|
||||
memset(&jbProtocol.waitAck, 0, sizeof(jb_wait_ack_t));
|
||||
jbOnAck(cmd, result);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbSendReport — 发送主动上报 (0x07)
|
||||
*
|
||||
* mask 指定本次上报包含哪些 DP:
|
||||
* - 差分掩码(来自 jbBuildDiffMask) → 仅上报变化的 DP
|
||||
* - 全量掩码(来自 jbSetFullMask) → 定时全量同步
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
static void jbSendReport(jb_data_point_t *data, const uint8_t *mask)
|
||||
{
|
||||
uint8_t payload[MAX_PACKAGE_LEN];
|
||||
uint16_t plen = jbPackDps(data, mask, payload);
|
||||
uint8_t sn = jbProtocol.sn++;
|
||||
jbSendReqWithAck(CMD_REPORT, sn, payload, plen);
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbReportPolicy — 变化上报(差分) + 定时上报(全量)
|
||||
*
|
||||
* 策略:
|
||||
* 1. DP 发生变化 → 仅上报变化的 DP(差分掩码)
|
||||
* 2. 每隔 REPORT_PERIOD ms → 上报全部可上报 DP(全量同步)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
static void jbReportPolicy(jb_data_point_t *data)
|
||||
{
|
||||
uint32_t now = jbGetTimerCount();
|
||||
uint8_t diffMask[DP_BITMAP_SIZE];
|
||||
|
||||
/* ── 1. 变化上报(差分) ── */
|
||||
uint8_t hasChange = jbBuildDiffMask(&jbProtocol.lastData, data, diffMask);
|
||||
if (hasChange && !jbProtocol.waitAck.active &&
|
||||
(now - jbProtocol.lastChangeTime > REPORT_DEBOUNCE))
|
||||
{
|
||||
jbSendReport(data, diffMask);
|
||||
memcpy(&jbProtocol.lastData, data, sizeof(jb_data_point_t));
|
||||
jbProtocol.lastChangeTime = now;
|
||||
jbProtocol.lastReportTime = now;
|
||||
return;
|
||||
}
|
||||
|
||||
/* ── 2. 定时全量上报 ── */
|
||||
if (!jbProtocol.waitAck.active &&
|
||||
(now - jbProtocol.lastReportTime > REPORT_PERIOD))
|
||||
{
|
||||
uint8_t fullMask[DP_BITMAP_SIZE];
|
||||
jbSetFullMask(fullMask);
|
||||
jbSendReport(data, fullMask);
|
||||
memcpy(&jbProtocol.lastData, data, sizeof(jb_data_point_t));
|
||||
jbProtocol.lastReportTime = now;
|
||||
}
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 命令处理函数(BLE → MCU 下行帧)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* ── 0x03 APP 下发控制 ── */
|
||||
static void jbHandleControl(uint8_t *frame, uint16_t len)
|
||||
{
|
||||
uint8_t sn = frame[5];
|
||||
uint8_t *bitmap = &frame[6];
|
||||
uint8_t *values = &frame[6 + DP_BITMAP_SIZE];
|
||||
uint16_t valLen = len - 7 - DP_BITMAP_SIZE;
|
||||
|
||||
jb_event_info_t info;
|
||||
jb_data_point_t ctrlData;
|
||||
memset(&ctrlData, 0, sizeof(ctrlData));
|
||||
jbUnpackDps(bitmap, values, valLen, &ctrlData, &info);
|
||||
|
||||
/* 分发给用户层;用户在回调中更新 gDevData */
|
||||
jbEventProcess(&info, &ctrlData);
|
||||
jbSendAck(CMD_CONTROL_ACK, sn, JB_OK);
|
||||
}
|
||||
|
||||
/* ── 0x05 APP 读取请求 ── */
|
||||
static void jbHandleRead(uint8_t *frame, uint16_t len,
|
||||
jb_data_point_t *data)
|
||||
{
|
||||
uint8_t sn = frame[5];
|
||||
uint8_t *reqBitmap = &frame[6];
|
||||
|
||||
uint8_t mask[DP_BITMAP_SIZE];
|
||||
memcpy(mask, reqBitmap, DP_BITMAP_SIZE);
|
||||
|
||||
/* bitmap 全 1(=0xFF...) 表示读取全部 DP */
|
||||
uint8_t allOnes = 1;
|
||||
for (int i = 0; i < DP_BITMAP_SIZE; i++)
|
||||
{
|
||||
if (mask[i] != 0xFF)
|
||||
{
|
||||
allOnes = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allOnes)
|
||||
{
|
||||
jbSetFullMask(mask);
|
||||
}
|
||||
|
||||
uint8_t payload[MAX_PACKAGE_LEN];
|
||||
uint16_t plen = jbPackDps(data, mask, payload);
|
||||
jbSendFrame(CMD_READ_ACK, sn, payload, plen);
|
||||
}
|
||||
|
||||
/* ── 0x01 BLE 请求设备身份信息 ── */
|
||||
static void jbHandleIdentityReq(uint8_t *frame, uint16_t len)
|
||||
{
|
||||
uint8_t sn = frame[5];
|
||||
uint8_t payload[64];
|
||||
uint16_t p = 0;
|
||||
(void)len;
|
||||
payload[p++] = JB_OK;
|
||||
jbWriteU16BE(&payload[p], JB_PROTOCOL_VERSION);
|
||||
p += 2;
|
||||
memset(&payload[p], 0, 8);
|
||||
memcpy(&payload[p], JB_CATEGORY_CODE, sizeof(JB_CATEGORY_CODE) - 1);
|
||||
p += 8;
|
||||
memset(&payload[p], 0, 8);
|
||||
memcpy(&payload[p], JB_PRODUCT_CODE, sizeof(JB_PRODUCT_CODE) - 1);
|
||||
p += 8;
|
||||
memset(&payload[p], JB_DEVICE_SN, 16);
|
||||
p += 16;
|
||||
jbWriteU32BE(&payload[p], (uint32_t)(JB_DEVICE_CAPABILITY >> 32));
|
||||
p += 4;
|
||||
jbWriteU32BE(&payload[p], (uint32_t)(JB_DEVICE_CAPABILITY & 0xFFFFFFFFULL));
|
||||
p += 4;
|
||||
jbSendFrame(CMD_IDENTITY_ACK, sn, payload, p);
|
||||
}
|
||||
|
||||
/* ── 0x40 BLE 请求 MCU 信息 ── */
|
||||
static void jbHandleMcuInfoReq(uint8_t *frame, uint16_t len)
|
||||
{
|
||||
uint8_t sn = frame[5];
|
||||
uint8_t payload[8];
|
||||
uint16_t p = 0;
|
||||
(void)len;
|
||||
payload[p++] = JB_OK;
|
||||
payload[p++] = JB_MCU_SW_VERSION_MAJOR;
|
||||
payload[p++] = JB_MCU_SW_VERSION_MINOR;
|
||||
payload[p++] = JB_MCU_SW_VERSION_PATCH;
|
||||
payload[p++] = JB_MCU_HW_VERSION_MAJOR;
|
||||
payload[p++] = JB_MCU_HW_VERSION_MINOR;
|
||||
payload[p++] = JB_MCU_HW_VERSION_PATCH;
|
||||
jbSendFrame(CMD_MCU_INFO_ACK, sn, payload, p);
|
||||
}
|
||||
|
||||
/* ── 0x12 心跳(BLE → MCU)── */
|
||||
static void jbHandleHeartbeat(uint8_t *frame, uint16_t len)
|
||||
{
|
||||
uint8_t sn = frame[5];
|
||||
jbSendAck(CMD_HEARTBEAT_ACK, sn, JB_OK);
|
||||
}
|
||||
|
||||
/* ── 0x14 BLE 工作状态同步(含 RSSI)── */
|
||||
static void jbHandleWorkState(uint8_t *frame, uint16_t len)
|
||||
{
|
||||
uint8_t sn = frame[5];
|
||||
uint8_t state = frame[6];
|
||||
int8_t rssi = (int8_t)frame[7]; /* uint8 补码 → int8 dBm */
|
||||
jbOnWorkState(state, rssi);
|
||||
jbSendAck(CMD_WORK_STATE_ACK, sn, JB_OK);
|
||||
}
|
||||
|
||||
/* ── 0x1A BLE 通知 MCU 重启 ── */
|
||||
static void jbHandleBleRestart(uint8_t *frame, uint16_t len)
|
||||
{
|
||||
uint8_t sn = frame[5];
|
||||
jbSendAck(CMD_RESTART_MCU_ACK, sn, JB_OK);
|
||||
jbOnBleRestartRequest();
|
||||
}
|
||||
|
||||
/* ── 0x30 OTA 升级请求 ── */
|
||||
static void jbHandleOtaNotify(uint8_t *frame, uint16_t len)
|
||||
{
|
||||
uint8_t sn = frame[5];
|
||||
uint32_t fwVersion = ((uint32_t)frame[6] << 16) | ((uint32_t)frame[7] << 8) | frame[8];
|
||||
uint32_t fwLength = jbReadU32BE(&frame[9]);
|
||||
uint32_t fwCrc32 = jbReadU32BE(&frame[13]);
|
||||
|
||||
/* 应答: 结果码 + 最大单包长度(2B)(协议原格式,3 字节) */
|
||||
int8_t otaRet = jbOnOtaNotify(fwVersion, fwLength, fwCrc32);
|
||||
uint8_t ack[3];
|
||||
ack[0] = (otaRet == 0) ? JB_OK : (uint8_t)otaRet;
|
||||
ack[1] = (uint8_t)(JB_OTA_MAX_PAYLOAD >> 8);
|
||||
ack[2] = (uint8_t)(JB_OTA_MAX_PAYLOAD & 0xFF);
|
||||
jbSendFrame(CMD_OTA_NOTIFY_ACK, sn, ack, 3);
|
||||
}
|
||||
|
||||
/* ── 0x32 OTA 数据(含分片序号)── */
|
||||
static void jbHandleOtaData(uint8_t *frame, uint16_t len)
|
||||
{
|
||||
uint8_t sn = frame[5];
|
||||
uint16_t shardIdx = jbReadU16BE(&frame[6]);
|
||||
uint16_t totalShards = jbReadU16BE(&frame[8]);
|
||||
const uint8_t *pData = &frame[10];
|
||||
uint16_t dataLen = (len > 11) ? (len - 11) : 0;
|
||||
/* 先发本包 0x33 应答,再调用户回调满足「先回复、再重启」 */
|
||||
jbSendAck(CMD_OTA_DATA_ACK, sn, JB_OK);
|
||||
jbOnOtaData(pData, dataLen, shardIdx, totalShards);
|
||||
}
|
||||
|
||||
/* ── 0x36 BLE 通知停止 OTA ── */
|
||||
static void jbHandleOtaStop(uint8_t *frame, uint16_t len)
|
||||
{
|
||||
uint8_t sn = frame[5];
|
||||
jbOnOtaStop();
|
||||
jbSendAck(CMD_OTA_STOP_BLE_ACK, sn, JB_OK);
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* MCU → BLE 请求 API
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* 0x10 请求配对(cfg_mode: 1=纯蓝牙 2=WIFI双模; param 仅 WIFI 有效)*/
|
||||
int32_t jbRequestPairing(uint8_t cfg_mode, uint16_t timeout_sec,
|
||||
const uint8_t *param, uint8_t param_len)
|
||||
{
|
||||
uint8_t payload[64];
|
||||
uint16_t p = 0;
|
||||
payload[p++] = cfg_mode;
|
||||
jbWriteU16BE(&payload[p], timeout_sec);
|
||||
p += 2;
|
||||
if (param && param_len > 0 && (p + 1 + param_len) <= sizeof(payload))
|
||||
{
|
||||
payload[p++] = param_len;
|
||||
memcpy(&payload[p], param, param_len);
|
||||
p += param_len;
|
||||
}
|
||||
uint8_t sn = jbProtocol.sn++;
|
||||
return jbSendReqWithAck(CMD_PAIRING_REQ, sn, payload, p);
|
||||
}
|
||||
|
||||
/* 0x1C 获取网络时间(等待 ACK,超时重传)*/
|
||||
int32_t jbRequestTime(void)
|
||||
{
|
||||
uint8_t sn = jbProtocol.sn++;
|
||||
return jbSendReqWithAck(CMD_TIME_REQ, sn, NULL, 0);
|
||||
}
|
||||
|
||||
/* 0x16 重置 BLE 模组(恢复出厂,等待 ACK 重传)*/
|
||||
int32_t jbRequestBleReset(void)
|
||||
{
|
||||
uint8_t sn = jbProtocol.sn++;
|
||||
return jbSendReqWithAck(CMD_RESET_BLE, sn, NULL, 0);
|
||||
}
|
||||
|
||||
/* 0x18 重启 BLE 模组(等待 ACK 重传)*/
|
||||
int32_t jbRequestBleRestart(void)
|
||||
{
|
||||
uint8_t sn = jbProtocol.sn++;
|
||||
return jbSendReqWithAck(CMD_RESTART_BLE, sn, NULL, 0);
|
||||
}
|
||||
|
||||
/* 0x20 产测模式(0=退出 1=进入,等待 ACK 重传)*/
|
||||
int32_t jbRequestProduction(uint8_t mode)
|
||||
{
|
||||
uint8_t sn = jbProtocol.sn++;
|
||||
return jbSendReqWithAck(CMD_PRODUCTION, sn, &mode, 1);
|
||||
}
|
||||
|
||||
/* 0x22 开启拍照(预留 2 字节,等待 ACK 重传)*/
|
||||
int32_t jbRequestPhoto(void)
|
||||
{
|
||||
uint8_t sn = jbProtocol.sn++;
|
||||
uint8_t payload[2] = {0, 0};
|
||||
return jbSendReqWithAck(CMD_PHOTO_REQ, sn, payload, 2);
|
||||
}
|
||||
|
||||
/* 0x24 开启录像(duration_sec: 0=关闭; 预留 2 字节,等待 ACK 重传)*/
|
||||
int32_t jbRequestRecord(uint16_t duration_sec)
|
||||
{
|
||||
uint8_t sn = jbProtocol.sn++;
|
||||
uint8_t payload[4];
|
||||
jbWriteU16BE(&payload[0], duration_sec);
|
||||
payload[2] = 0;
|
||||
payload[3] = 0;
|
||||
return jbSendReqWithAck(CMD_RECORD_REQ, sn, payload, 4);
|
||||
}
|
||||
|
||||
/* 0x26 启动音频(audio_id: 音频编号; 预留 2 字节,等待 ACK 重传)*/
|
||||
int32_t jbRequestAudio(uint8_t audio_id)
|
||||
{
|
||||
uint8_t sn = jbProtocol.sn++;
|
||||
uint8_t payload[3];
|
||||
payload[0] = audio_id;
|
||||
payload[1] = 0;
|
||||
payload[2] = 0;
|
||||
return jbSendReqWithAck(CMD_AUDIO_REQ, sn, payload, 3);
|
||||
}
|
||||
|
||||
/* 0x38 通知 BLE 停止 OTA(MCU 主动,等待 ACK 重传)*/
|
||||
int32_t jbNotifyOtaStop(void)
|
||||
{
|
||||
uint8_t sn = jbProtocol.sn++;
|
||||
return jbSendReqWithAck(CMD_OTA_STOP_MCU, sn, NULL, 0);
|
||||
}
|
||||
|
||||
/* 0x34 OTA 升级完成(result + MCU 版本 3B,等待 ACK 重传)*/
|
||||
int32_t jbSendOtaResult(uint8_t result, const uint8_t *mcuVersion)
|
||||
{
|
||||
uint8_t sn = jbProtocol.sn++;
|
||||
uint8_t payload[4];
|
||||
payload[0] = result;
|
||||
if (mcuVersion)
|
||||
{
|
||||
memcpy(&payload[1], mcuVersion, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&payload[1], 0, 3);
|
||||
}
|
||||
return jbSendReqWithAck(CMD_OTA_COMPLETE, sn, payload, 4);
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* jbProtocolHandle — 协议主循环(在 while(1) 中调用)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
int32_t jbProtocolHandle(jb_data_point_t *data)
|
||||
{
|
||||
if (!data)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ACK 超时重传 */
|
||||
jbAckRetry();
|
||||
|
||||
/* 提取一帧 */
|
||||
uint16_t pktLen = 0;
|
||||
int8_t ret = jbGetOnePacket(jbProtocol.rxBuf, &pktLen);
|
||||
uint8_t cmd;
|
||||
if (ret == 0)
|
||||
{
|
||||
cmd = jbProtocol.rxBuf[4];
|
||||
printf("cmd: %02X\r\n", cmd);
|
||||
/* 按命令码统一分发 BLE → MCU 的所有帧(含 MCU 主动请求的应答)*/
|
||||
switch (cmd)
|
||||
{
|
||||
/* ── 身份信息 / MCU 信息 ── */
|
||||
case CMD_IDENTITY_REQ:
|
||||
jbHandleIdentityReq(jbProtocol.rxBuf, pktLen);
|
||||
break;
|
||||
case CMD_MCU_INFO_REQ:
|
||||
jbHandleMcuInfoReq(jbProtocol.rxBuf, pktLen);
|
||||
break;
|
||||
|
||||
/* ── APP-BLE 数据 ── */
|
||||
case CMD_CONTROL:
|
||||
jbHandleControl(jbProtocol.rxBuf, pktLen);
|
||||
break;
|
||||
case CMD_READ:
|
||||
jbHandleRead(jbProtocol.rxBuf, pktLen, data);
|
||||
break;
|
||||
|
||||
/* ── 心跳 / 状态同步 ── */
|
||||
case CMD_HEARTBEAT:
|
||||
jbHandleHeartbeat(jbProtocol.rxBuf, pktLen);
|
||||
break;
|
||||
case CMD_WORK_STATE:
|
||||
jbHandleWorkState(jbProtocol.rxBuf, pktLen);
|
||||
break;
|
||||
|
||||
/* ── BLE 通知 MCU 重启 ── */
|
||||
case CMD_RESTART_MCU:
|
||||
jbHandleBleRestart(jbProtocol.rxBuf, pktLen);
|
||||
break;
|
||||
|
||||
/* ── BLE-MCU OTA ── */
|
||||
case CMD_OTA_NOTIFY:
|
||||
jbHandleOtaNotify(jbProtocol.rxBuf, pktLen);
|
||||
break;
|
||||
case CMD_OTA_DATA:
|
||||
jbHandleOtaData(jbProtocol.rxBuf, pktLen);
|
||||
break;
|
||||
case CMD_OTA_STOP_BLE:
|
||||
jbHandleOtaStop(jbProtocol.rxBuf, pktLen);
|
||||
break;
|
||||
|
||||
/* ── BLE → MCU 的 ACK(MCU 主动请求后的应答)──
|
||||
各 ACK 分支统一调用 jbWaitAckCheck:命中等待则清除等待、
|
||||
停止重传,并回调 jbOnAck 通知应答结果;其余帧由 default 忽略。 */
|
||||
case CMD_TIME_ACK:
|
||||
jbWaitAckCheck(jbProtocol.rxBuf);
|
||||
if (pktLen >= 18)
|
||||
{
|
||||
uint32_t ts = jbReadU32BE(&jbProtocol.rxBuf[14]);
|
||||
jbOnTimeSync(ts);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_REPORT_ACK:
|
||||
case CMD_PAIRING_ACK:
|
||||
case CMD_RESET_BLE_ACK:
|
||||
case CMD_RESTART_BLE_ACK:
|
||||
case CMD_PRODUCTION_ACK:
|
||||
case CMD_PHOTO_ACK:
|
||||
case CMD_RECORD_ACK:
|
||||
case CMD_AUDIO_ACK:
|
||||
case CMD_OTA_COMPLETE_ACK:
|
||||
case CMD_OTA_STOP_MCU_ACK:
|
||||
jbWaitAckCheck(jbProtocol.rxBuf);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
jbReportPolicy(data);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
/* ================================================================
|
||||
* jb_protocol.h — 见宝 IOT 协议层(自动生成)
|
||||
* 设备: 侠客猫激光 | DP 数: 11 | Bitmap: 2B
|
||||
* 协议版本: V1.0 | 生成时间: 2026-07-28 15:42:40
|
||||
*
|
||||
* 帧格式: [55 AA] [LEN_H LEN_L] [CMD] [SN] [payload...] [CKSUM]
|
||||
* LEN = CMD(1) + SN(1) + payload + CKSUM(1) = payload + 3
|
||||
* CKSUM = sum(LEN_H .. payload_last) & 0xFF
|
||||
* Bitmap = 每个 DP 占 1 bit,bit 序号 = DP ID(0 起始)
|
||||
* Values = 按 bitmap 置位顺序排列,每个 DP 占完整 byte_length
|
||||
* ================================================================
|
||||
*/
|
||||
|
||||
#ifndef _JB_PROTOCOL_H
|
||||
#define _JB_PROTOCOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 协议常量
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
#define PKT_HEAD_0 0x55
|
||||
#define PKT_HEAD_1 0xAA
|
||||
#define MAX_PACKAGE_LEN 128
|
||||
#define JB_OTA_MAX_PAYLOAD 96 /* OTA 单包 Payload 上限(Byte); 须 <= MAX_PACKAGE_LEN - 11(0x32 帧开销) */
|
||||
|
||||
#define DP_COUNT 11
|
||||
#define DP_BITMAP_SIZE 2
|
||||
|
||||
#define SEND_MAX_TIME 2000 /* ACK 重传超时(ms) */
|
||||
#define SEND_MAX_NUM 3 /* 最大重传次数 */
|
||||
#define REPORT_DEBOUNCE 2000 /* 变化上报防抖时间(ms) */
|
||||
#define REPORT_PERIOD 600000 /* 定时全量上报周期(ms) */
|
||||
|
||||
/* Device identity: change these values for the target product. */
|
||||
#define JB_PROTOCOL_VERSION 0x0100 /* V1.0 */
|
||||
#define JB_CATEGORY_CODE "CBC0"
|
||||
#define JB_PRODUCT_CODE "PICBC0"
|
||||
#define JB_DEVICE_SN 0x00
|
||||
#define JB_DEVICE_CAPABILITY 0ULL
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 命令码(见《MCU方案接入协议通讯文档》)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
typedef enum
|
||||
{
|
||||
/* ── 设备身份信息(2) ── */
|
||||
CMD_IDENTITY_REQ = 0x01, /* BLE → MCU: 请求身份信息 */
|
||||
CMD_IDENTITY_ACK = 0x02, /* MCU → BLE: 身份应答 */
|
||||
|
||||
/* ── APP-BLE 数据(6) ── */
|
||||
CMD_CONTROL = 0x03, /* APP/BLE → MCU: 下发控制 */
|
||||
CMD_CONTROL_ACK = 0x04, /* MCU → APP/BLE: 控制应答 */
|
||||
CMD_READ = 0x05, /* APP/BLE → MCU: 读取请求 */
|
||||
CMD_READ_ACK = 0x06, /* MCU → APP/BLE: 读取应答 */
|
||||
CMD_REPORT = 0x07, /* MCU → APP/BLE: 主动上报 */
|
||||
CMD_REPORT_ACK = 0x08, /* APP/BLE → MCU: 上报应答 */
|
||||
|
||||
/* ── 配对 / 心跳 / 状态(6) ── */
|
||||
CMD_PAIRING_REQ = 0x10, /* MCU → BLE: 请求配对 */
|
||||
CMD_PAIRING_ACK = 0x11, /* BLE → MCU: 配对应答 */
|
||||
CMD_HEARTBEAT = 0x12, /* BLE → MCU: 心跳 */
|
||||
CMD_HEARTBEAT_ACK = 0x13, /* MCU → BLE: 心跳应答 */
|
||||
CMD_WORK_STATE = 0x14, /* BLE → MCU: 状态同步(含RSSI) */
|
||||
CMD_WORK_STATE_ACK= 0x15, /* MCU → BLE: 状态应答 */
|
||||
|
||||
/* ── BLE 模组控制(4) ── */
|
||||
CMD_RESET_BLE = 0x16, /* MCU → BLE: 重置 BLE(恢复出厂) */
|
||||
CMD_RESET_BLE_ACK = 0x17, /* BLE → MCU: 重置应答 */
|
||||
CMD_RESTART_BLE = 0x18, /* MCU → BLE: 重启 BLE */
|
||||
CMD_RESTART_BLE_ACK=0x19, /* BLE → MCU: 重启应答 */
|
||||
CMD_RESTART_MCU = 0x1A, /* BLE → MCU: 通知 MCU 重启 */
|
||||
CMD_RESTART_MCU_ACK=0x1B, /* MCU → BLE: 重启应答 */
|
||||
|
||||
/* ── 时间 / 产测(4) ── */
|
||||
CMD_TIME_REQ = 0x1C, /* MCU → BLE: 获取网络时间 */
|
||||
CMD_TIME_ACK = 0x1D, /* BLE → MCU: 时间应答 */
|
||||
CMD_PRODUCTION = 0x20, /* MCU → BLE: 产测模式 */
|
||||
CMD_PRODUCTION_ACK= 0x21, /* BLE → MCU: 产测应答 */
|
||||
|
||||
/* ── 拍照 / 录像 / 音频(6) ── */
|
||||
CMD_PHOTO_REQ = 0x22, /* MCU → BLE: 开启拍照 */
|
||||
CMD_PHOTO_ACK = 0x23, /* BLE → MCU: 拍照应答 */
|
||||
CMD_RECORD_REQ = 0x24, /* MCU → BLE: 开启录像 */
|
||||
CMD_RECORD_ACK = 0x25, /* BLE → MCU: 录像应答 */
|
||||
CMD_AUDIO_REQ = 0x26, /* MCU → BLE: 启动音频 */
|
||||
CMD_AUDIO_ACK = 0x27, /* BLE → MCU: 音频应答 */
|
||||
|
||||
/* ── OTA(10) ── */
|
||||
CMD_OTA_NOTIFY = 0x30, /* BLE → MCU: OTA 升级请求 */
|
||||
CMD_OTA_NOTIFY_ACK = 0x31, /* MCU → BLE: OTA 应答(含MaxLen) */
|
||||
CMD_OTA_DATA = 0x32, /* BLE → MCU: OTA 数据 */
|
||||
CMD_OTA_DATA_ACK = 0x33, /* MCU → BLE: OTA 数据应答 */
|
||||
CMD_OTA_COMPLETE = 0x34, /* MCU → BLE: OTA 完成 */
|
||||
CMD_OTA_COMPLETE_ACK = 0x35, /* BLE → MCU: OTA 完成应答 */
|
||||
CMD_OTA_STOP_BLE = 0x36, /* BLE → MCU: 停止 OTA */
|
||||
CMD_OTA_STOP_BLE_ACK = 0x37, /* MCU → BLE: 停止应答 */
|
||||
CMD_OTA_STOP_MCU = 0x38, /* MCU → BLE: 通知停止 OTA */
|
||||
CMD_OTA_STOP_MCU_ACK = 0x39, /* BLE → MCU: 停止应答 */
|
||||
|
||||
/* ── MCU 信息(2) ── */
|
||||
CMD_MCU_INFO_REQ = 0x40, /* BLE → MCU: 请求 MCU 信息 */
|
||||
CMD_MCU_INFO_ACK = 0x41, /* MCU → BLE: MCU 信息应答 */
|
||||
} jb_cmd_t;
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 结果码
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
typedef enum
|
||||
{
|
||||
JB_OK = 0x00,
|
||||
JB_PARAM_ERR = 0x01,
|
||||
JB_BUSY = 0x02,
|
||||
JB_NOT_SUPPORT = 0x03,
|
||||
JB_CRC_ERR = 0x04,
|
||||
JB_FAIL = 0x05,
|
||||
/* ── OTA 专用错误码 ── */
|
||||
JB_OTA_NO_NEED = 0x20, /* 无需升级(版本一致) */
|
||||
JB_OTA_VER_LOW = 0x21, /* OTA 版本低于当前版本 */
|
||||
JB_OTA_SPACE_ERR = 0x22, /* Flash 空间不足 */
|
||||
JB_OTA_STATE_ERR = 0x23, /* OTA 状态错误 */
|
||||
JB_OTA_FILE_ERR = 0x24, /* OTA 文件检验失败 */
|
||||
JB_OTA_FAIL = 0x25, /* 升级失败 */
|
||||
} jb_result_t;
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* BLE 工作状态位 (0x14)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
#define WS_CONFIGURED (1 << 0) /* 已配网 */
|
||||
#define WS_INTERNET (1 << 1) /* 已连外网 */
|
||||
#define WS_APP_ONLINE (1 << 2) /* App 在线 */
|
||||
#define WS_BLE_CONNECTED (1 << 3) /* 手机 BLE 已连接 */
|
||||
#define WS_OTA_UPGRADING (1 << 4) /* OTA 升级中 */
|
||||
#define WS_PAIRING_MODE (1 << 5) /* 配对模式激活 */
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 设备能力位图 (0x02 Capability Bitmap, 8B 大端)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
#define CAP_BLE_OTA (1ULL << 0) /* BLE OTA */
|
||||
#define CAP_MCU_OTA (1ULL << 1) /* MCU OTA */
|
||||
#define CAP_APP_DIRECT (1ULL << 2) /* APP 直连 BLE */
|
||||
#define CAP_IPC_GATEWAY (1ULL << 3) /* IPC 网关连接 */
|
||||
#define CAP_PRODUCTION (1ULL << 4) /* 产测模式 */
|
||||
#define CAP_PARAM_CFG (1ULL << 5) /* 参数配置 */
|
||||
#define CAP_LOG (1ULL << 6) /* 日志功能 */
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 身份信息 (0x02) / MCU 信息 (0x41)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* DP ID 枚举(从 Excel 自动生成)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
typedef enum
|
||||
{
|
||||
DP_ID_POWER = 0, /* 开关 (bool, RW) */
|
||||
DP_ID_PLAY_MODE = 1, /* 自动模式 (enum, RW) */
|
||||
DP_ID_HAND_MODE = 2, /* 手动模式 (enum, WO) */
|
||||
DP_ID_ALM_LOW_BATTERY = 3, /* 低电量报警 (bool, RO) */
|
||||
DP_ID_BEEP_TRIG = 4, /* 声音开关 (bool, RW) */
|
||||
DP_ID_BATTERY = 5, /* 电量上报 (uint8, RO) */
|
||||
DP_ID_SHAKE_WAKE = 6, /* 震动触发开机 (bool, RW) */
|
||||
DP_ID_NO_DISTURB_ENABLE = 7, /* 勿扰模式开关 (raw, RW) */
|
||||
DP_ID_RESERVA_DP1 = 8, /* 预留DP1 (uint32, RW) */
|
||||
DP_ID_RESERVA_DP2 = 9, /* 预留DP2 (uint32, RW) */
|
||||
DP_ID_RESERVA_DP3 = 10, /* 预留DP3 (uint32, RW) */
|
||||
DP_ID_MAX
|
||||
} dp_id_t;
|
||||
|
||||
/* DP 数据长度(字节) */
|
||||
#define DP_LEN_POWER 1
|
||||
#define DP_LEN_PLAY_MODE 1
|
||||
#define DP_LEN_HAND_MODE 1
|
||||
#define DP_LEN_ALM_LOW_BATTERY 1
|
||||
#define DP_LEN_BEEP_TRIG 1
|
||||
#define DP_LEN_BATTERY 1
|
||||
#define DP_LEN_SHAKE_WAKE 1
|
||||
#define DP_LEN_NO_DISTURB_ENABLE 13
|
||||
#define DP_LEN_RESERVA_DP1 4
|
||||
#define DP_LEN_RESERVA_DP2 4
|
||||
#define DP_LEN_RESERVA_DP3 4
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* DP 枚举值定义
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
/* 自动模式 */
|
||||
typedef enum
|
||||
{
|
||||
PLAY_MODE_0 = 0, /* 关 */
|
||||
PLAY_MODE_1 = 1, /* mode1 */
|
||||
PLAY_MODE_2 = 2, /* mode2 */
|
||||
PLAY_MODE_3 = 3, /* mode3 */
|
||||
PLAY_MODE_4 = 4, /* mode4 */
|
||||
} PLAY_MODE_t;
|
||||
|
||||
/* 手动模式 */
|
||||
typedef enum
|
||||
{
|
||||
HAND_MODE_0 = 0, /* 关 */
|
||||
HAND_MODE_1 = 1, /* 顺时针 */
|
||||
HAND_MODE_2 = 2, /* 逆时针 */
|
||||
} HAND_MODE_t;
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 数据结构
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* 数据点 — 所有 DP 的当前值 */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t power; /* DP0 开关 */
|
||||
uint8_t play_mode; /* DP1 自动模式 */
|
||||
uint8_t hand_mode; /* DP2 手动模式 */
|
||||
uint8_t alm_low_battery;/* DP3 低电量报警 */
|
||||
uint8_t beep_trig; /* DP4 声音开关 */
|
||||
uint8_t battery; /* DP5 电量上报 */
|
||||
uint8_t shake_wake; /* DP6 震动触发开机 */
|
||||
uint8_t no_disturb_enable[13];/* DP7 勿扰模式开关 */
|
||||
uint32_t reserva_dp1; /* DP8 预留DP1 */
|
||||
uint32_t reserva_dp2; /* DP9 预留DP2 */
|
||||
uint32_t reserva_dp3; /* DP10 预留DP3 */
|
||||
} jb_data_point_t;
|
||||
|
||||
/* 控制事件信息 */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t count;
|
||||
uint8_t dp_ids[DP_ID_MAX];
|
||||
} jb_event_info_t;
|
||||
|
||||
/* ACK 等待 / 重传管理器 */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t active; /* 是否有等待中的请求 */
|
||||
uint8_t sn; /* 帧序列号 */
|
||||
uint8_t retry;
|
||||
uint8_t buf[MAX_PACKAGE_LEN];
|
||||
uint16_t len;
|
||||
uint32_t sendTime;
|
||||
} jb_wait_ack_t;
|
||||
|
||||
/* 协议全局状态 */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t sn; /* 设备 SN 计数器 */
|
||||
uint8_t rxBuf[MAX_PACKAGE_LEN];
|
||||
jb_wait_ack_t waitAck; /* ACK 重传管理器 */
|
||||
jb_data_point_t lastData; /* 上次上报快照 */
|
||||
uint32_t lastReportTime; /* 上次上报时刻 */
|
||||
uint32_t lastChangeTime; /* 上次变化上报时刻 */
|
||||
} jb_protocol_t;
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 全局实例
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
extern jb_protocol_t jbProtocol;
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 协议层 API(自动生成)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
void jbInit(void);
|
||||
int32_t jbPutData(uint8_t *buf, uint32_t len);
|
||||
|
||||
/* MCU → BLE 主动请求 / 通知 */
|
||||
int32_t jbRequestPairing(uint8_t cfg_mode, uint16_t timeout_sec,
|
||||
const uint8_t *param, uint8_t param_len);
|
||||
int32_t jbRequestTime(void);
|
||||
int32_t jbRequestBleReset(void);
|
||||
int32_t jbRequestBleRestart(void);
|
||||
int32_t jbRequestProduction(uint8_t mode);
|
||||
int32_t jbRequestPhoto(void);
|
||||
int32_t jbRequestRecord(uint16_t duration_sec);
|
||||
int32_t jbRequestAudio(uint8_t audio_id);
|
||||
int32_t jbNotifyOtaStop(void);
|
||||
int32_t jbSendOtaResult(uint8_t result, const uint8_t *mcuVersion);
|
||||
|
||||
int32_t jbProtocolHandle(jb_data_point_t *data);
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 硬件抽象(用户实现)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
uint32_t jbGetTimerCount(void); /* ms 计数器 */
|
||||
int32_t uartWrite(uint8_t *buf, uint32_t len); /* UART 发送 */
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 用户回调(用户实现)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
/* 0x03 APP 下发控制事件 */
|
||||
int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *data);
|
||||
|
||||
/* BLE → MCU 事件回调 */
|
||||
void jbOnWorkState(uint8_t state, int8_t rssi); /* 0x14 状态(含RSSI) */
|
||||
void jbOnBleRestartRequest(void); /* 0x1A 请求重启 */
|
||||
int8_t jbOnOtaNotify(uint32_t fwVersion, uint32_t fwLength, uint32_t fwCrc32); /* 0x30, 返回0=接受,非0=拒绝码 */
|
||||
void jbOnOtaData(const uint8_t *data, uint16_t len,
|
||||
uint16_t shardIdx, uint16_t totalShards); /* 0x32 */
|
||||
void jbOnOtaStop(void); /* 0x36 / 0x38 停止 */
|
||||
|
||||
/* MCU → BLE 应答回调(收到 BLE 应答时触发)*/
|
||||
void jbOnTimeSync(uint32_t timestamp); /* 0x1D 时间同步 */
|
||||
void jbOnAck(uint8_t cmd, uint8_t result); /* 任意请求 ACK(结果) */
|
||||
|
||||
#endif /* _JB_PROTOCOL_H */
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "application.h"
|
||||
#include "iwdg.h"
|
||||
#include "jb_port.h"
|
||||
#include "jb_protocol.h"
|
||||
|
||||
/*******************状态机应用层开始********************/
|
||||
void app_machine_handle(void)
|
||||
{
|
||||
}
|
||||
|
||||
/***************状态机应用层结束************************/
|
||||
|
||||
void version_printf(void)
|
||||
{
|
||||
appPrintf(LOG_NOTIC, "Developer:%s\r\n", __DEVELOPER__);
|
||||
appPrintf(LOG_NOTIC, "Email:%s\r\n", __EMAIL__);
|
||||
appPrintf(LOG_NOTIC, "Version:%s\r\n", __VERSION__);
|
||||
appPrintf(LOG_NOTIC, "Compiler Date:%s\r\n", __DATE__);
|
||||
appPrintf(LOG_NOTIC, "Compiler Time:%s\r\n", __TIME__);
|
||||
}
|
||||
|
||||
void app_Init(void)
|
||||
{
|
||||
// 系统初始化
|
||||
DEBUG_USART_Config(); /* 将串口配置成日志口 */
|
||||
version_printf(); /* 打印版本信息 */
|
||||
timerInit(); /* TIM6 1ms 节拍,供协议超时/重传 */
|
||||
jbInit(); /* 协议初始化 */
|
||||
userInit(); /* 用户初始化 */
|
||||
uartInit(); /* USART3 PB10/PB11,9600 8N1 */
|
||||
}
|
||||
|
||||
void app_lication(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
app_machine_handle(); /* 状态机处理函数 */
|
||||
jb_port_uart_run(); /* 串口调试日志 */
|
||||
userHandle(); /* 用户处理函数 */
|
||||
jbProtocolHandle(&gDevData); /* 协议处理函数 */
|
||||
iwdg_feed(); /* 看门狗喂狗 */
|
||||
}
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file main.c
|
||||
* @author MCU Application Team
|
||||
* @brief Main program body
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "application.h"
|
||||
#include "app_boot.h"
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
uint8_t lptim_flag = 0;
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
app_startup();
|
||||
app_lication();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Period elapsed callback in non blocking mode
|
||||
* @param htim:TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
if (htim->Instance == JB_TIMER)
|
||||
{
|
||||
jbTimerIrq();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 计算时间差
|
||||
* @param meiosis:需要比较的时间戳,用于计算时间差
|
||||
* @retval 时间差
|
||||
*/
|
||||
uint32_t HAL_GetTickDiff(uint32_t meiosis)
|
||||
{
|
||||
uint32_t temp = HAL_GetTick();
|
||||
if (temp >= meiosis)
|
||||
{
|
||||
temp = temp - meiosis;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = 0xFFFFFFFFU - meiosis + temp;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 错误处理函数
|
||||
* @param *file:文件名,line:行号
|
||||
* @return None
|
||||
*/
|
||||
void Error_Handler(uint8_t *file, uint32_t line)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
appPrintf(LOG_ERROR, "%s %d\r\n", file, line);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
* @param file: pointer to the source file name
|
||||
* @param line: assert_param error line source number
|
||||
* @retval None
|
||||
*/
|
||||
void assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
/* User can add his own implementation to report the file name and line number,
|
||||
for example: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* Infinite loop */
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040_hal_msp.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides code for the MSP Initialization
|
||||
* and de-Initialization codes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* External functions --------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initialize global MSP.
|
||||
*/
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP 初始化
|
||||
* @param huart UART 句柄
|
||||
* @retval None
|
||||
* @note USART3: PB10=TX(AF4), PB11=RX(AF4) — 见 PY32F040 手册 PortB AF 表
|
||||
*/
|
||||
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
|
||||
{
|
||||
GPIO_InitTypeDef gpio_init = {0};
|
||||
|
||||
if (huart->Instance == JB_USART)
|
||||
{
|
||||
JB_USART_CLK_ENABLE();
|
||||
JB_USART_TX_GPIO_CLK_ENABLE();
|
||||
JB_USART_RX_GPIO_CLK_ENABLE();
|
||||
|
||||
/* PB10 ------> USART3_TX */
|
||||
gpio_init.Pin = JB_USART_TX_PIN;
|
||||
gpio_init.Mode = GPIO_MODE_AF_PP;
|
||||
gpio_init.Pull = GPIO_PULLUP;
|
||||
gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
gpio_init.Alternate = JB_USART_TX_AF;
|
||||
HAL_GPIO_Init(JB_USART_TX_GPIO_PORT, &gpio_init);
|
||||
|
||||
/* PB11 ------> USART3_RX */
|
||||
gpio_init.Pin = JB_USART_RX_PIN;
|
||||
gpio_init.Alternate = JB_USART_RX_AF;
|
||||
HAL_GPIO_Init(JB_USART_RX_GPIO_PORT, &gpio_init);
|
||||
|
||||
HAL_NVIC_SetPriority(JB_USART_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(JB_USART_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP 反初始化
|
||||
* @param huart UART 句柄
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart->Instance == JB_USART)
|
||||
{
|
||||
__HAL_RCC_USART3_CLK_DISABLE();
|
||||
HAL_GPIO_DeInit(JB_USART_TX_GPIO_PORT, JB_USART_TX_PIN);
|
||||
HAL_GPIO_DeInit(JB_USART_RX_GPIO_PORT, JB_USART_RX_PIN);
|
||||
HAL_NVIC_DisableIRQ(JB_USART_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM Base MSP 初始化
|
||||
* @param htim TIM 句柄
|
||||
* @retval None
|
||||
* @note TIM6 用作协议层 1ms 节拍
|
||||
*/
|
||||
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
if (htim->Instance == JB_TIMER)
|
||||
{
|
||||
JB_TIMER_CLK_ENABLE();
|
||||
HAL_NVIC_SetPriority(JB_TIMER_IRQn, 2, 0);
|
||||
HAL_NVIC_EnableIRQ(JB_TIMER_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM Base MSP 反初始化
|
||||
* @param htim TIM 句柄
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
if (htim->Instance == JB_TIMER)
|
||||
{
|
||||
__HAL_RCC_TIM6_CLK_DISABLE();
|
||||
HAL_NVIC_DisableIRQ(JB_TIMER_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040_it.c
|
||||
* @author MCU Application Team
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f040_it.h"
|
||||
#include "main.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M0+ Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @brief This function handles Non maskable interrupt.
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System service call via SWI instruction.
|
||||
*/
|
||||
void SVC_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Pendable request for system service.
|
||||
*/
|
||||
void PendSV_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System tick timer.
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
HAL_IncTick();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* PY32F040 Peripheral Interrupt Handlers */
|
||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||
/* For the available peripheral interrupt handler names, */
|
||||
/* please refer to the startup file. */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief USART3/4 中断服务:协议口收发
|
||||
*/
|
||||
void USART3_4_IRQHandler(void)
|
||||
{
|
||||
HAL_UART_IRQHandler(&UartHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM6/LPTIM1 中断服务:1ms 节拍
|
||||
*/
|
||||
void TIM6_LPTIM1_IRQHandler(void)
|
||||
{
|
||||
HAL_TIM_IRQHandler(&TimHandle);
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_py32f040.c
|
||||
* @author MCU Application Team
|
||||
* @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "py32f0xx.h"
|
||||
|
||||
#if !defined(HSE_VALUE)
|
||||
#define HSE_VALUE 24000000U /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined(HSI_VALUE)
|
||||
#define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
#if !defined(LSI_VALUE)
|
||||
#define LSI_VALUE 32768U /*!< Value of LSI in Hz*/
|
||||
#endif /* LSI_VALUE */
|
||||
|
||||
#if !defined(LSE_VALUE)
|
||||
#define LSE_VALUE 32768U /*!< Value of LSE in Hz*/
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
/************************* Miscellaneous Configuration ************************/
|
||||
/*!< Uncomment the following line if you need to relocate your vector Table in
|
||||
Internal SRAM. */
|
||||
/* #define FORBID_VECT_TAB_MIGRATION */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#define VECT_TAB_OFFSET 0x3000 /*!< Vector Table base offset field. \
|
||||
APP 链接在 0x08003000, 偏移须为 0x3000 (标准 CMSIS 用户配置项) \
|
||||
This value must be a multiple of 0x100. */
|
||||
/******************************************************************************/
|
||||
/*----------------------------------------------------------------------------
|
||||
Clock Variable definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = HSI_VALUE;
|
||||
|
||||
const uint32_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
const uint32_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||
const uint32_t HSIFreqTable[8] = {4000000U, 8000000U, 16000000U, 22120000U, 24000000U, 4000000U, 4000000U, 4000000U};
|
||||
|
||||
/**
|
||||
* @brief Clock functions.
|
||||
* @param none
|
||||
* @return none
|
||||
*/
|
||||
void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
|
||||
{
|
||||
uint32_t tmp;
|
||||
uint32_t hsidiv;
|
||||
uint32_t hsifs;
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
uint32_t pllmul = 0;
|
||||
const uint8_t pllMulValue[4] = {2, 3, 2, 2};
|
||||
#endif /* RCC_PLL_SUPPORT */
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
switch (RCC->CFGR & RCC_CFGR_SWS)
|
||||
{
|
||||
case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
|
||||
case RCC_SYSCLKSOURCE_STATUS_LSI: /* LSI used as system clock */
|
||||
SystemCoreClock = LSI_VALUE;
|
||||
break;
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
case RCC_SYSCLKSOURCE_STATUS_LSE: /* LSE used as system clock */
|
||||
SystemCoreClock = LSE_VALUE;
|
||||
break;
|
||||
#endif /* RCC_LSE_SUPPORT */
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */
|
||||
pllmul = pllMulValue[((RCC->PLLCFGR & RCC_PLLCFGR_PLLMUL) >> RCC_PLLCFGR_PLLMUL_Pos)];
|
||||
|
||||
if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI) /* HSI used as PLL clock source */
|
||||
{
|
||||
hsifs = ((READ_BIT(RCC->ICSCR, RCC_ICSCR_HSI_FS)) >> RCC_ICSCR_HSI_FS_Pos);
|
||||
SystemCoreClock = pllmul * (HSIFreqTable[hsifs]);
|
||||
}
|
||||
else /* HSE used as PLL clock source */
|
||||
{
|
||||
SystemCoreClock = pllmul * HSE_VALUE;
|
||||
}
|
||||
break;
|
||||
#endif /* RCC_PLL_SUPPORT */
|
||||
case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock */
|
||||
default: /* HSI used as system clock */
|
||||
hsifs = ((READ_BIT(RCC->ICSCR, RCC_ICSCR_HSI_FS)) >> RCC_ICSCR_HSI_FS_Pos);
|
||||
hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos));
|
||||
SystemCoreClock = (HSIFreqTable[hsifs] / hsidiv);
|
||||
break;
|
||||
}
|
||||
/* Compute HCLK clock frequency --------------------------------------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
* Initialize the System.
|
||||
* @param none
|
||||
* @return none
|
||||
*/
|
||||
void SystemInit(void)
|
||||
{
|
||||
/* Set the HSI clock to 8MHz by default */
|
||||
/* Set the LSI clock to 32.768KHz by default */
|
||||
RCC->ICSCR = (RCC->ICSCR & 0xFE000000) | (0x1 << 13) | ((*(uint32_t *)(0x1fff3208)) & 0x0000FFFF) | ((*(uint32_t *)(0x1fff3348)) << 16);
|
||||
|
||||
/* Configure the Vector Table location add offset address ------------------*/
|
||||
#ifdef VECT_TAB_SRAM
|
||||
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
|
||||
#else
|
||||
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
|
||||
#endif /* VECT_TAB_SRAM */
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,69 @@
|
||||
/* ================================================================
|
||||
* jb_common.c — 工具函数实现
|
||||
* ================================================================
|
||||
*/
|
||||
#include "jb_common.h"
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 校验和
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
uint8_t jbChecksum(const uint8_t *frame, uint16_t totalLen)
|
||||
{
|
||||
if (!frame || totalLen < 4)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint16_t sum = 0;
|
||||
/* 从 LEN_H(buf[2]) 累加到最后一个 payload 字节(buf[totalLen-2]) */
|
||||
for (uint16_t i = 2; i < totalLen - 1; i++)
|
||||
{
|
||||
sum += frame[i];
|
||||
}
|
||||
return (uint8_t)(sum & 0xFF);
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 大端序读写
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
uint16_t jbReadU16BE(const uint8_t *buf)
|
||||
{
|
||||
if (!buf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return ((uint16_t)buf[0] << 8) | buf[1];
|
||||
}
|
||||
|
||||
uint32_t jbReadU32BE(const uint8_t *buf)
|
||||
{
|
||||
if (!buf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return ((uint32_t)buf[0] << 24)
|
||||
| ((uint32_t)buf[1] << 16)
|
||||
| ((uint32_t)buf[2] << 8)
|
||||
| buf[3];
|
||||
}
|
||||
|
||||
void jbWriteU16BE(uint8_t *buf, uint16_t val)
|
||||
{
|
||||
if (!buf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
buf[0] = (uint8_t)(val >> 8);
|
||||
buf[1] = (uint8_t)(val & 0xFF);
|
||||
}
|
||||
|
||||
void jbWriteU32BE(uint8_t *buf, uint32_t val)
|
||||
{
|
||||
if (!buf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
buf[0] = (uint8_t)(val >> 24);
|
||||
buf[1] = (uint8_t)(val >> 16);
|
||||
buf[2] = (uint8_t)(val >> 8);
|
||||
buf[3] = (uint8_t)(val & 0xFF);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/* ================================================================
|
||||
* jb_common.h — 工具函数(校验和、大端序转换)
|
||||
*
|
||||
* 说明: 见宝协议采用大端序(Big-Endian)。
|
||||
* 多字节值(uint16/uint32)按高位在前传输。
|
||||
* ================================================================
|
||||
*/
|
||||
#ifndef _JB_COMMON_H
|
||||
#define _JB_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 校验和
|
||||
* sum(LEN_H, LEN_L, CMD, SN, ...payload_last) & 0xFF
|
||||
* buf[0]=55, buf[1]=AA,累加范围从 buf[2] 到 buf[totalLen-2]
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
uint8_t jbChecksum(const uint8_t *frame, uint16_t totalLen);
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* 大端序转换
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
|
||||
/* 从字节数组读取 uint16(大端序)*/
|
||||
uint16_t jbReadU16BE(const uint8_t *buf);
|
||||
|
||||
/* 从字节数组读取 uint32(大端序)*/
|
||||
uint32_t jbReadU32BE(const uint8_t *buf);
|
||||
|
||||
/* 将 uint16 写入字节数组(大端序)*/
|
||||
void jbWriteU16BE(uint8_t *buf, uint16_t val);
|
||||
|
||||
/* 将 uint32 写入字节数组(大端序)*/
|
||||
void jbWriteU32BE(uint8_t *buf, uint32_t val);
|
||||
|
||||
#endif /* _JB_COMMON_H */
|
||||
@@ -0,0 +1,75 @@
|
||||
/* ================================================================
|
||||
* jb_ringbuffer.c — 环形缓冲区实现
|
||||
* ================================================================
|
||||
*/
|
||||
#include "jb_ringbuffer.h"
|
||||
|
||||
/* ── 初始化 ── */
|
||||
void jbRbInit(jb_ringbuffer_t *rb)
|
||||
{
|
||||
if (!rb)
|
||||
{
|
||||
return;
|
||||
}
|
||||
rb->write = rb->read = rb->count = 0;
|
||||
}
|
||||
|
||||
/* ── 压入一个字节 ── */
|
||||
void jbRbPush(jb_ringbuffer_t *rb, uint8_t byte)
|
||||
{
|
||||
if (!rb)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (rb->count >= JB_RB_CAPACITY)
|
||||
{
|
||||
return; /* 已满 — 丢弃 */
|
||||
}
|
||||
rb->buf[rb->write] = byte;
|
||||
rb->write = (rb->write + 1) % JB_RB_CAPACITY;
|
||||
rb->count++;
|
||||
}
|
||||
|
||||
/* ── 弹出一个字节 ── */
|
||||
uint8_t jbRbPop(jb_ringbuffer_t *rb)
|
||||
{
|
||||
if (!rb || rb->count == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint8_t byte = rb->buf[rb->read];
|
||||
rb->read = (rb->read + 1) % JB_RB_CAPACITY;
|
||||
rb->count--;
|
||||
return byte;
|
||||
}
|
||||
|
||||
/* ── 查看指定偏移字节(不消费)── */
|
||||
uint8_t jbRbPeek(const jb_ringbuffer_t *rb, uint16_t offset)
|
||||
{
|
||||
if (!rb || offset >= rb->count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint16_t idx = (rb->read + offset) % JB_RB_CAPACITY;
|
||||
return rb->buf[idx];
|
||||
}
|
||||
|
||||
/* ── 可读字节数 ── */
|
||||
uint16_t jbRbAvailable(const jb_ringbuffer_t *rb)
|
||||
{
|
||||
if (!rb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return rb->count;
|
||||
}
|
||||
|
||||
/* ── 清空缓冲区 ── */
|
||||
void jbRbClear(jb_ringbuffer_t *rb)
|
||||
{
|
||||
if (!rb)
|
||||
{
|
||||
return;
|
||||
}
|
||||
rb->write = rb->read = rb->count = 0;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/* ================================================================
|
||||
* jb_ringbuffer.h — 环形缓冲区(UART 接收)
|
||||
* ================================================================
|
||||
*/
|
||||
#ifndef _JB_RINGBUFFER_H
|
||||
#define _JB_RINGBUFFER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* 缓冲区配置 */
|
||||
#define JB_RB_CAPACITY 256 /* 缓冲区容量(2 的幂可优化取模运算)*/
|
||||
|
||||
/* 环形缓冲区实例 */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t buf[JB_RB_CAPACITY];
|
||||
uint16_t write; /* 写索引 */
|
||||
uint16_t read; /* 读索引 */
|
||||
uint16_t count; /* 已用字节数 */
|
||||
} jb_ringbuffer_t;
|
||||
|
||||
void jbRbInit(jb_ringbuffer_t *rb);
|
||||
void jbRbPush(jb_ringbuffer_t *rb, uint8_t byte);
|
||||
uint8_t jbRbPop(jb_ringbuffer_t *rb);
|
||||
uint8_t jbRbPeek(const jb_ringbuffer_t *rb, uint16_t offset);
|
||||
uint16_t jbRbAvailable(const jb_ringbuffer_t *rb);
|
||||
void jbRbClear(jb_ringbuffer_t *rb);
|
||||
|
||||
#endif /* _JB_RINGBUFFER_H */
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef __FLASH_H
|
||||
#define __FLASH_H
|
||||
|
||||
#include "boot_main.h"
|
||||
#include "ota_config.h"
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* Flash 布局与 OTA 状态机 — 统一由 ota_config.h 配置(唯一入口)
|
||||
* (布局宏 OTA_RUN_ADDR_BASE / OTA_BAK_ADDR_BASE / OTA_SLOT_MAX_SIZE
|
||||
* 及状态结构 ota_param_t / OTA_STATE_* 均在 ota_config.h 中定义)
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
#define SYS_BOOTLOADER_ADDR_BASE 0x08000000UL /* Bootloader,17KB */
|
||||
#define FLASH_END_ADDR 0x08020000UL /* 128KB 边界 */
|
||||
|
||||
#define RAM_BASE_ADDR 0x20000000UL
|
||||
#define RAM_END_ADDR 0x20004000UL /* 16KB RAM */
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
* Flash 操作 API
|
||||
* ════════════════════════════════════════════════════════════════ */
|
||||
void APP_FlashWrite(uint32_t PageAddress, uint8_t *Data, uint32_t DataSize);
|
||||
void APP_FlashRead(uint32_t PageAddress, uint8_t *Data, uint32_t DataSize);
|
||||
void APP_FlashEraseWithCheck(uint32_t PageAddress, uint32_t DataSize);
|
||||
|
||||
/* OTA 状态区读写(AB:4 页轮换磨损均衡;SINGLE:固定页 0 直写) */
|
||||
void ota_param_load(ota_param_t *p);
|
||||
void ota_param_store(const ota_param_t *p);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file main.h
|
||||
* @author MCU Application Team
|
||||
* @brief Header for main.c file.
|
||||
* This file contains the common defines of the application.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __BOOT_MAIN_H
|
||||
#define __BOOT_MAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_hal.h"
|
||||
#include "py32f040xx_Start_Kit.h"
|
||||
#include "log.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
typedef int32_t s32;
|
||||
typedef int16_t s16;
|
||||
typedef int8_t s8;
|
||||
|
||||
typedef const int32_t sc32; /*!< Read Only */
|
||||
typedef const int16_t sc16; /*!< Read Only */
|
||||
typedef const int8_t sc8; /*!< Read Only */
|
||||
|
||||
typedef __IO int32_t vs32;
|
||||
typedef __IO int16_t vs16;
|
||||
typedef __IO int8_t vs8;
|
||||
|
||||
typedef __I int32_t vsc32; /*!< Read Only */
|
||||
typedef __I int16_t vsc16; /*!< Read Only */
|
||||
typedef __I int8_t vsc8; /*!< Read Only */
|
||||
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
|
||||
typedef const uint32_t uc32; /*!< Read Only */
|
||||
typedef const uint16_t uc16; /*!< Read Only */
|
||||
typedef const uint8_t uc8; /*!< Read Only */
|
||||
|
||||
typedef __IO uint32_t vu32;
|
||||
typedef __IO uint16_t vu16;
|
||||
typedef __IO uint8_t vu8;
|
||||
|
||||
typedef __I uint32_t vuc32; /*!< Read Only */
|
||||
typedef __I uint16_t vuc16; /*!< Read Only */
|
||||
typedef __I uint8_t vuc8; /*!< Read Only */
|
||||
/* Exported variables prototypes ---------------------------------------------*/
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void Error_Handler(uint8_t *file, uint32_t line);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BOOT_MAIN_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,281 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040_hal_conf.h
|
||||
* @author MCU Application Team
|
||||
* @brief HAL configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __PY32F040_HAL_CONF_H
|
||||
#define __PY32F040_HAL_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
#define HAL_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
/* #define HAL_ADC_MODULE_ENABLED */
|
||||
/* #define HAL_CRC_MODULE_ENABLED */
|
||||
/* #define HAL_COMP_MODULE_ENABLED */
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
/* #define HAL_IWDG_MODULE_ENABLED */
|
||||
/* #define HAL_WWDG_MODULE_ENABLED */
|
||||
/* #define HAL_TIM_MODULE_ENABLED */
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
/* #define HAL_LPTIM_MODULE_ENABLED */
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
/* #define HAL_I2C_MODULE_ENABLED */
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
/* #define HAL_USART_MODULE_ENABLED */
|
||||
/* #define HAL_SPI_MODULE_ENABLED */
|
||||
/* #define HAL_RTC_MODULE_ENABLED */
|
||||
/* #define HAL_LCD_MODULE_ENABLED */
|
||||
/* #define HAL_EXTI_MODULE_ENABLED */
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
/* #define HAL_CTC_MODULE_ENABLED */
|
||||
/* #define HAL_OPA_MODULE_ENABLED */
|
||||
/* #define HAL_DIV_MODULE_ENABLED */
|
||||
/* #define HAL_I2S_MODULE_ENABLED */
|
||||
/* #define HAL_IRDA_MODULE_ENABLED */
|
||||
/* #define HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
/* ########################## Oscillator Values adaptation ####################*/
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE ((uint32_t)24000000) /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT ((uint32_t)200) /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed Internal oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE ((uint32_t)32768) /*!< LSI Typical Value in Hz */
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
|
||||
/**
|
||||
* @brief Adjust the value of External Low Speed oscillator (LSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External oscillator in Hz*/
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
|
||||
#define PRIORITY_HIGHEST 0
|
||||
#define PRIORITY_HIGH 1
|
||||
#define PRIORITY_LOW 2
|
||||
#define PRIORITY_LOWEST 3
|
||||
#define TICK_INT_PRIORITY ((uint32_t)PRIORITY_LOWEST) /*!< tick interrupt priority (lowest by default) */
|
||||
#define USE_RTOS 0
|
||||
#define PREFETCH_ENABLE 0
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1U */
|
||||
|
||||
/* ################## SPI peripheral configuration ########################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
|
||||
#define USE_SPI_CRC 0U
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
#ifdef HAL_MODULE_ENABLED
|
||||
#include "py32f0xx_hal.h"
|
||||
#endif /* HAL_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "py32f040_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "py32f040_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "py32f040_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "py32f040_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "py32f040_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "py32f040_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "py32f040_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_COMP_MODULE_ENABLED
|
||||
#include "py32f040_hal_comp.h"
|
||||
#endif /* HAL_COMP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "py32f040_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "py32f040_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "py32f040_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "py32f040_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "py32f040_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "py32f040_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "py32f040_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "py32f040_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "py32f040_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "py32f040_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LCD_MODULE_ENABLED
|
||||
#include "py32f040_hal_lcd.h"
|
||||
#endif /* HAL_LCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "py32f040_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CTC_MODULE_ENABLED
|
||||
#include "py32f040_hal_ctc.h"
|
||||
#endif /* HAL_CTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_OPA_MODULE_ENABLED
|
||||
#include "py32f040_hal_opa.h"
|
||||
#endif /* HAL_OPA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DIV_MODULE_ENABLED
|
||||
#include "py32f040_hal_div.h"
|
||||
#endif /* HAL_DIV_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "py32f040_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "py32f040_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "py32f040_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr: If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t* file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PY32F040_HAL_CONF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040_it.h
|
||||
* @author MCU Application Team
|
||||
* @brief This file contains the headers of the interrupt handlers.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __PY32F040_IT_H
|
||||
#define __PY32F040_IT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void NMI_Handler(void);
|
||||
void HardFault_Handler(void);
|
||||
void SVC_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PY32F040_IT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,526 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
|
||||
|
||||
<SchemaVersion>2.1</SchemaVersion>
|
||||
|
||||
<Header>### uVision Project, (C) Keil Software</Header>
|
||||
|
||||
<Targets>
|
||||
<Target>
|
||||
<TargetName>Project</TargetName>
|
||||
<ToolsetNumber>0x4</ToolsetNumber>
|
||||
<ToolsetName>ARM-ADS</ToolsetName>
|
||||
<pCCUsed>5060960::V5.06 update 7 (build 960)::.\ARM_Compiler_5.06u7</pCCUsed>
|
||||
<uAC6>0</uAC6>
|
||||
<TargetOption>
|
||||
<TargetCommonOption>
|
||||
<Device>PY32F040xB</Device>
|
||||
<Vendor>Puya</Vendor>
|
||||
<PackID>Puya.PY32F0xx_DFP.1.2.0</PackID>
|
||||
<PackURL>https://www.puyasemi.com/uploadfiles/</PackURL>
|
||||
<Cpu>IRAM(0x20000000,0x00004000) IROM(0x08000000,0x00020000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE</Cpu>
|
||||
<FlashUtilSpec></FlashUtilSpec>
|
||||
<StartupFile></StartupFile>
|
||||
<FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0PY32F040xx_128 -FS08000000 -FL020000 -FP0($$Device:PY32F040xB$CMSIS\Flash\PY32F040xx_128.FLM))</FlashDriverDll>
|
||||
<DeviceId>0</DeviceId>
|
||||
<RegisterFile>$$Device:PY32F040xB$Drivers\CMSIS\Device\Puya\PY32F0xx\Include\py32f0xx.h</RegisterFile>
|
||||
<MemoryEnv></MemoryEnv>
|
||||
<Cmp></Cmp>
|
||||
<Asm></Asm>
|
||||
<Linker></Linker>
|
||||
<OHString></OHString>
|
||||
<InfinionOptionDll></InfinionOptionDll>
|
||||
<SLE66CMisc></SLE66CMisc>
|
||||
<SLE66AMisc></SLE66AMisc>
|
||||
<SLE66LinkerMisc></SLE66LinkerMisc>
|
||||
<SFDFile>$$Device:PY32F040xB$CMSIS\SVD\PY32F040xx.svd</SFDFile>
|
||||
<bCustSvd>0</bCustSvd>
|
||||
<UseEnv>0</UseEnv>
|
||||
<BinPath></BinPath>
|
||||
<IncludePath></IncludePath>
|
||||
<LibPath></LibPath>
|
||||
<RegisterFilePath></RegisterFilePath>
|
||||
<DBRegisterFilePath></DBRegisterFilePath>
|
||||
<TargetStatus>
|
||||
<Error>0</Error>
|
||||
<ExitCodeStop>0</ExitCodeStop>
|
||||
<ButtonStop>0</ButtonStop>
|
||||
<NotGenerated>0</NotGenerated>
|
||||
<InvalidFlash>1</InvalidFlash>
|
||||
</TargetStatus>
|
||||
<OutputDirectory>.\Output\</OutputDirectory>
|
||||
<OutputName>Project</OutputName>
|
||||
<CreateExecutable>1</CreateExecutable>
|
||||
<CreateLib>0</CreateLib>
|
||||
<CreateHexFile>1</CreateHexFile>
|
||||
<DebugInformation>1</DebugInformation>
|
||||
<BrowseInformation>1</BrowseInformation>
|
||||
<ListingPath>.\Output\</ListingPath>
|
||||
<HexFormatSelection>1</HexFormatSelection>
|
||||
<Merge32K>0</Merge32K>
|
||||
<CreateBatchFile>0</CreateBatchFile>
|
||||
<BeforeCompile>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopU1X>0</nStopU1X>
|
||||
<nStopU2X>0</nStopU2X>
|
||||
</BeforeCompile>
|
||||
<BeforeMake>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopB1X>0</nStopB1X>
|
||||
<nStopB2X>0</nStopB2X>
|
||||
</BeforeMake>
|
||||
<AfterMake>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopA1X>0</nStopA1X>
|
||||
<nStopA2X>0</nStopA2X>
|
||||
</AfterMake>
|
||||
<SelectedForBatchBuild>0</SelectedForBatchBuild>
|
||||
<SVCSIdString></SVCSIdString>
|
||||
</TargetCommonOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>0</UseCPPCompiler>
|
||||
<RVCTCodeConst>0</RVCTCodeConst>
|
||||
<RVCTZI>0</RVCTZI>
|
||||
<RVCTOtherData>0</RVCTOtherData>
|
||||
<ModuleSelection>0</ModuleSelection>
|
||||
<IncludeInBuild>1</IncludeInBuild>
|
||||
<AlwaysBuild>0</AlwaysBuild>
|
||||
<GenerateAssemblyFile>0</GenerateAssemblyFile>
|
||||
<AssembleAssemblyFile>0</AssembleAssemblyFile>
|
||||
<PublicsOnly>0</PublicsOnly>
|
||||
<StopOnExitCode>3</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<DllOption>
|
||||
<SimDllName>SARMCM3.DLL</SimDllName>
|
||||
<SimDllArguments> -REMAP </SimDllArguments>
|
||||
<SimDlgDll>DARMCM1.DLL</SimDlgDll>
|
||||
<SimDlgDllArguments>-pCM0+</SimDlgDllArguments>
|
||||
<TargetDllName>SARMCM3.DLL</TargetDllName>
|
||||
<TargetDllArguments> </TargetDllArguments>
|
||||
<TargetDlgDll>TARMCM1.DLL</TargetDlgDll>
|
||||
<TargetDlgDllArguments>-pCM0+</TargetDlgDllArguments>
|
||||
</DllOption>
|
||||
<DebugOption>
|
||||
<OPTHX>
|
||||
<HexSelection>1</HexSelection>
|
||||
<HexRangeLowAddress>0</HexRangeLowAddress>
|
||||
<HexRangeHighAddress>0</HexRangeHighAddress>
|
||||
<HexOffset>0</HexOffset>
|
||||
<Oh166RecLen>16</Oh166RecLen>
|
||||
</OPTHX>
|
||||
</DebugOption>
|
||||
<Utilities>
|
||||
<Flash1>
|
||||
<UseTargetDll>1</UseTargetDll>
|
||||
<UseExternalTool>0</UseExternalTool>
|
||||
<RunIndependent>0</RunIndependent>
|
||||
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
|
||||
<Capability>1</Capability>
|
||||
<DriverSelection>4096</DriverSelection>
|
||||
</Flash1>
|
||||
<bUseTDR>1</bUseTDR>
|
||||
<Flash2>BIN\UL2CM3.DLL</Flash2>
|
||||
<Flash3>"" ()</Flash3>
|
||||
<Flash4></Flash4>
|
||||
<pFcarmOut></pFcarmOut>
|
||||
<pFcarmGrp></pFcarmGrp>
|
||||
<pFcArmRoot></pFcArmRoot>
|
||||
<FcArmLst>0</FcArmLst>
|
||||
</Utilities>
|
||||
<TargetArmAds>
|
||||
<ArmAdsMisc>
|
||||
<GenerateListings>0</GenerateListings>
|
||||
<asHll>1</asHll>
|
||||
<asAsm>1</asAsm>
|
||||
<asMacX>1</asMacX>
|
||||
<asSyms>1</asSyms>
|
||||
<asFals>1</asFals>
|
||||
<asDbgD>1</asDbgD>
|
||||
<asForm>1</asForm>
|
||||
<ldLst>0</ldLst>
|
||||
<ldmm>1</ldmm>
|
||||
<ldXref>1</ldXref>
|
||||
<BigEnd>0</BigEnd>
|
||||
<AdsALst>1</AdsALst>
|
||||
<AdsACrf>1</AdsACrf>
|
||||
<AdsANop>0</AdsANop>
|
||||
<AdsANot>0</AdsANot>
|
||||
<AdsLLst>1</AdsLLst>
|
||||
<AdsLmap>1</AdsLmap>
|
||||
<AdsLcgr>1</AdsLcgr>
|
||||
<AdsLsym>1</AdsLsym>
|
||||
<AdsLszi>1</AdsLszi>
|
||||
<AdsLtoi>1</AdsLtoi>
|
||||
<AdsLsun>1</AdsLsun>
|
||||
<AdsLven>1</AdsLven>
|
||||
<AdsLsxf>1</AdsLsxf>
|
||||
<RvctClst>0</RvctClst>
|
||||
<GenPPlst>0</GenPPlst>
|
||||
<AdsCpuType>"Cortex-M0+"</AdsCpuType>
|
||||
<RvctDeviceName></RvctDeviceName>
|
||||
<mOS>0</mOS>
|
||||
<uocRom>0</uocRom>
|
||||
<uocRam>0</uocRam>
|
||||
<hadIROM>1</hadIROM>
|
||||
<hadIRAM>1</hadIRAM>
|
||||
<hadXRAM>0</hadXRAM>
|
||||
<uocXRam>0</uocXRam>
|
||||
<RvdsVP>0</RvdsVP>
|
||||
<RvdsMve>0</RvdsMve>
|
||||
<RvdsCdeCp>0</RvdsCdeCp>
|
||||
<nBranchProt>0</nBranchProt>
|
||||
<hadIRAM2>0</hadIRAM2>
|
||||
<hadIROM2>0</hadIROM2>
|
||||
<StupSel>8</StupSel>
|
||||
<useUlib>1</useUlib>
|
||||
<EndSel>0</EndSel>
|
||||
<uLtcg>0</uLtcg>
|
||||
<nSecure>0</nSecure>
|
||||
<RoSelD>3</RoSelD>
|
||||
<RwSelD>3</RwSelD>
|
||||
<CodeSel>0</CodeSel>
|
||||
<OptFeed>0</OptFeed>
|
||||
<NoZi1>0</NoZi1>
|
||||
<NoZi2>0</NoZi2>
|
||||
<NoZi3>0</NoZi3>
|
||||
<NoZi4>0</NoZi4>
|
||||
<NoZi5>0</NoZi5>
|
||||
<Ro1Chk>0</Ro1Chk>
|
||||
<Ro2Chk>0</Ro2Chk>
|
||||
<Ro3Chk>0</Ro3Chk>
|
||||
<Ir1Chk>1</Ir1Chk>
|
||||
<Ir2Chk>0</Ir2Chk>
|
||||
<Ra1Chk>0</Ra1Chk>
|
||||
<Ra2Chk>0</Ra2Chk>
|
||||
<Ra3Chk>0</Ra3Chk>
|
||||
<Im1Chk>1</Im1Chk>
|
||||
<Im2Chk>0</Im2Chk>
|
||||
<OnChipMemories>
|
||||
<Ocm1>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm1>
|
||||
<Ocm2>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm2>
|
||||
<Ocm3>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm3>
|
||||
<Ocm4>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm4>
|
||||
<Ocm5>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm5>
|
||||
<Ocm6>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</Ocm6>
|
||||
<IRAM>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x20000000</StartAddress>
|
||||
<Size>0x4000</Size>
|
||||
</IRAM>
|
||||
<IROM>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x8000000</StartAddress>
|
||||
<Size>0x20000</Size>
|
||||
</IROM>
|
||||
<XRAM>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</XRAM>
|
||||
<OCR_RVCT1>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT1>
|
||||
<OCR_RVCT2>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT2>
|
||||
<OCR_RVCT3>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT3>
|
||||
<OCR_RVCT4>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x8000000</StartAddress>
|
||||
<Size>0x2c00</Size>
|
||||
</OCR_RVCT4>
|
||||
<OCR_RVCT5>
|
||||
<Type>1</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT5>
|
||||
<OCR_RVCT6>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT6>
|
||||
<OCR_RVCT7>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT7>
|
||||
<OCR_RVCT8>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT8>
|
||||
<OCR_RVCT9>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x20000000</StartAddress>
|
||||
<Size>0x4000</Size>
|
||||
</OCR_RVCT9>
|
||||
<OCR_RVCT10>
|
||||
<Type>0</Type>
|
||||
<StartAddress>0x0</StartAddress>
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT10>
|
||||
</OnChipMemories>
|
||||
<RvctStartVector></RvctStartVector>
|
||||
</ArmAdsMisc>
|
||||
<Cads>
|
||||
<interw>1</interw>
|
||||
<Optim>1</Optim>
|
||||
<oTime>0</oTime>
|
||||
<SplitLS>0</SplitLS>
|
||||
<OneElfS>1</OneElfS>
|
||||
<Strict>0</Strict>
|
||||
<EnumInt>0</EnumInt>
|
||||
<PlainCh>0</PlainCh>
|
||||
<Ropi>0</Ropi>
|
||||
<Rwpi>0</Rwpi>
|
||||
<wLevel>2</wLevel>
|
||||
<uThumb>0</uThumb>
|
||||
<uSurpInc>0</uSurpInc>
|
||||
<uC99>1</uC99>
|
||||
<uGnu>0</uGnu>
|
||||
<useXO>0</useXO>
|
||||
<v6Lang>1</v6Lang>
|
||||
<v6LangP>1</v6LangP>
|
||||
<vShortEn>1</vShortEn>
|
||||
<vShortWch>1</vShortWch>
|
||||
<v6Lto>0</v6Lto>
|
||||
<v6WtE>0</v6WtE>
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>USE_HAL_DRIVER,PY32F040xB</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\Inc;..\..\Shared;..\..\Drivers\BSP\PY32F040xx_Start_Kit;..\..\Drivers\CMSIS\Include;..\..\Drivers\CMSIS\Device\PY32F040\Include;..\..\Drivers\PY32F040_HAL_Driver\Inc;..\Code;..\..\Shared</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
<interw>1</interw>
|
||||
<Ropi>0</Ropi>
|
||||
<Rwpi>0</Rwpi>
|
||||
<thumb>0</thumb>
|
||||
<SplitLS>0</SplitLS>
|
||||
<SwStkChk>0</SwStkChk>
|
||||
<NoWarn>0</NoWarn>
|
||||
<uSurpInc>0</uSurpInc>
|
||||
<useXO>0</useXO>
|
||||
<ClangAsOpt>4</ClangAsOpt>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Aads>
|
||||
<LDads>
|
||||
<umfTarg>1</umfTarg>
|
||||
<Ropi>0</Ropi>
|
||||
<Rwpi>0</Rwpi>
|
||||
<noStLib>0</noStLib>
|
||||
<RepFail>1</RepFail>
|
||||
<useFile>0</useFile>
|
||||
<TextAddressRange>0x00000000</TextAddressRange>
|
||||
<DataAddressRange>0x20000000</DataAddressRange>
|
||||
<pXoBase></pXoBase>
|
||||
<ScatterFile></ScatterFile>
|
||||
<IncludeLibs></IncludeLibs>
|
||||
<IncludeLibsPath></IncludeLibsPath>
|
||||
<Misc></Misc>
|
||||
<LinkerInputFile></LinkerInputFile>
|
||||
<DisabledWarnings></DisabledWarnings>
|
||||
</LDads>
|
||||
</TargetArmAds>
|
||||
</TargetOption>
|
||||
<Groups>
|
||||
<Group>
|
||||
<GroupName>Common</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>startup_py32f040xx.s</FileName>
|
||||
<FileType>2</FileType>
|
||||
<FilePath>.\startup_py32f040xx.s</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>system_py32f040.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Src\system_py32f040.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>User</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>py32f040_hal_msp.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Src\py32f040_hal_msp.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_it.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Src\py32f040_it.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>boot_main.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Src\boot_main.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>Core</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>flash.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Shared\flash.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>crc32.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Shared\crc32.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>PY32F040xx_Start_Kit</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>py32f040xx_Start_Kit.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\BSP\PY32F040xx_Start_Kit\py32f040xx_Start_Kit.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>PY32F040_HAL_Driver</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>py32f040_hal_flash.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_flash.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_rcc.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_rcc.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_pwr.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_pwr.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_rcc_ex.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_rcc_ex.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_cortex.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_cortex.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_gpio.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_gpio.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_uart.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_uart.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>py32f040_hal_dma.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\Drivers\PY32F040_HAL_Driver\Src\py32f040_hal_dma.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>Doc</GroupName>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>::CMSIS</GroupName>
|
||||
</Group>
|
||||
</Groups>
|
||||
</Target>
|
||||
</Targets>
|
||||
|
||||
<RTE>
|
||||
<apis/>
|
||||
<components>
|
||||
<component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.2.0" condition="ARMv6_7_8-M Device">
|
||||
<package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.5.1"/>
|
||||
<targetInfos>
|
||||
<targetInfo name="Project"/>
|
||||
</targetInfos>
|
||||
</component>
|
||||
</components>
|
||||
<files/>
|
||||
</RTE>
|
||||
|
||||
<LayerInfo>
|
||||
<Layers>
|
||||
<Layer>
|
||||
<LayName>Bootloder</LayName>
|
||||
<LayPrjMark>1</LayPrjMark>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</LayerInfo>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,30 @@
|
||||
// File: PY32F040xx.dbgconf
|
||||
// Version: 1.0.0
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <h> Debug MCU configuration register (DBGMCU_CR)
|
||||
// <o.1> DBG_STOP <i> Debug stop mode
|
||||
// </h>
|
||||
DbgMCU_CR = 0x00000002;
|
||||
|
||||
// <h> Debug MCU APB freeze1 register (DBG_APB_FZ1)
|
||||
// <i> Reserved bits must be kept at reset value
|
||||
// <o.31> DBG_LPTIM_STOP <i> LPTIM stopped when core is halted
|
||||
// <o.12> DBG_IWDG_STOP <i> Independent watchdog stopped when core is halted
|
||||
// <o.11> DBG_WWDG_STOP <i> Window watchdog stopped when core is halted
|
||||
// <o.10> DBG_RTC_STOP <i> RTC stopped when core is halted
|
||||
// <o.1> DBG_TIM3_STOP <i> TIM3 counter stopped when core is halted
|
||||
// </h>
|
||||
DbgMCU_APB_Fz1 = 0x00000000;
|
||||
|
||||
// <h> Debug MCU APB freeze2 register (DBG_APB_FZ2)
|
||||
// <i> Reserved bits must be kept at reset value
|
||||
// <o.18> DBG_TIM17_STOP <i> TIM17 counter stopped when core is halted
|
||||
// <o.17> DBG_TIM16_STOP <i> TIM16 counter stopped when core is halted
|
||||
// <o.15> DBG_TIM14_STOP <i> TIM14 counter stopped when core is halted
|
||||
// <o.11> DBG_TIM1_STOP <i> TIM1 counter stopped when core is halted
|
||||
// </h>
|
||||
DbgMCU_APB_Fz2 = 0x00000000;
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'Bootloader'
|
||||
* Target: 'Project'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "py32f0xx.h"
|
||||
|
||||
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
||||
@@ -0,0 +1,262 @@
|
||||
;******************************************************************************
|
||||
;* @file startup_py32f040xx.s
|
||||
;* @author MCU Application Team
|
||||
;* @brief PY32F040xx devices vector table for MDK-ARM toolchain.
|
||||
;* This module performs:
|
||||
;* - Set the initial SP
|
||||
;* - Set the initial PC == Reset_Handler
|
||||
;* - Set the vector table entries with the exceptions ISR address
|
||||
;* - Branches to __main in the C library (which eventually
|
||||
;* calls main()).
|
||||
;* After Reset the CortexM0+ processor is in Thread mode,
|
||||
;* priority is Privileged, and the Stack is set to Main.
|
||||
;******************************************************************************
|
||||
;* @attention
|
||||
;*
|
||||
;* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
;* All rights reserved.</center></h2>
|
||||
;*
|
||||
;* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
;* the "License"; You may not use this file except in compliance with the
|
||||
;* License. You may obtain a copy of the License at:
|
||||
;* opensource.org/licenses/BSD-3-Clause
|
||||
;*
|
||||
;******************************************************************************
|
||||
;* @attention
|
||||
;*
|
||||
;* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
;* All rights reserved.</center></h2>
|
||||
;*
|
||||
;* This software component is licensed by ST under BSD 3-Clause license,
|
||||
;* the "License"; You may not use this file except in compliance with the
|
||||
;* License. You may obtain a copy of the License at:
|
||||
;* opensource.org/licenses/BSD-3-Clause
|
||||
;*
|
||||
;******************************************************************************
|
||||
;* <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
; Amount of memory (in bytes) allocated for Stack
|
||||
; Tailor this value to your application needs
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000200
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WWDG_IRQHandler ; 0Window Watchdog
|
||||
DCD PVD_IRQHandler ; 1PVD through EXTI Line detect
|
||||
DCD RTC_IRQHandler ; 2RTC through EXTI Line
|
||||
DCD FLASH_IRQHandler ; 3FLASH
|
||||
DCD RCC_IRQHandler ; 4RCC
|
||||
DCD EXTI0_1_IRQHandler ; 5EXTI Line 0 and 1
|
||||
DCD EXTI2_3_IRQHandler ; 6EXTI Line 2 and 3
|
||||
DCD EXTI4_15_IRQHandler ; 7EXTI Line 4 to 15
|
||||
DCD LCD_IRQHandler ; 8LCD
|
||||
DCD DMA1_Channel1_IRQHandler ; 9DMA1 Channel 1
|
||||
DCD DMA1_Channel2_3_IRQHandler ; 10DMA1 Channel 2 and Channel 3
|
||||
DCD DMA1_Channel4_5_6_7_IRQHandler ; 11DMA1 Channel 4, Channel 5, Channel 6, Channel 7
|
||||
DCD ADC_COMP_IRQHandler ; 12ADC&COMP
|
||||
DCD TIM1_BRK_UP_TRG_COM_IRQHandler ; 13TIM1 Break, Update, Trigger and Commutation
|
||||
DCD TIM1_CC_IRQHandler ; 14TIM1 Capture Compare
|
||||
DCD TIM2_IRQHandler ; 15TIM2
|
||||
DCD TIM3_IRQHandler ; 16TIM3
|
||||
DCD TIM6_LPTIM1_IRQHandler ; 17TIM6&LPTIM1
|
||||
DCD TIM7_IRQHandler ; 18TIM7
|
||||
DCD TIM14_IRQHandler ; 19TIM14
|
||||
DCD TIM15_IRQHandler ; 20TIM15
|
||||
DCD TIM16_IRQHandler ; 21TIM16
|
||||
DCD TIM17_IRQHandler ; 22TIM17
|
||||
DCD I2C1_IRQHandler ; 23I2C1
|
||||
DCD I2C2_IRQHandler ; 24I2C2
|
||||
DCD SPI1_IRQHandler ; 25SPI1
|
||||
DCD SPI2_IRQHandler ; 26SPI2
|
||||
DCD USART1_IRQHandler ; 27USART1
|
||||
DCD USART2_IRQHandler ; 28USART2
|
||||
DCD USART3_4_IRQHandler ; 29USART3&USART4
|
||||
DCD 0 ; 30Reserved
|
||||
DCD 0 ; 31Reserved
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WWDG_IRQHandler [WEAK]
|
||||
EXPORT PVD_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT FLASH_IRQHandler [WEAK]
|
||||
EXPORT RCC_IRQHandler [WEAK]
|
||||
EXPORT EXTI0_1_IRQHandler [WEAK]
|
||||
EXPORT EXTI2_3_IRQHandler [WEAK]
|
||||
EXPORT EXTI4_15_IRQHandler [WEAK]
|
||||
EXPORT LCD_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel1_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel2_3_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel4_5_6_7_IRQHandler [WEAK]
|
||||
EXPORT ADC_COMP_IRQHandler [WEAK]
|
||||
EXPORT TIM1_BRK_UP_TRG_COM_IRQHandler [WEAK]
|
||||
EXPORT TIM1_CC_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT TIM3_IRQHandler [WEAK]
|
||||
EXPORT TIM6_LPTIM1_IRQHandler [WEAK]
|
||||
EXPORT TIM7_IRQHandler [WEAK]
|
||||
EXPORT TIM14_IRQHandler [WEAK]
|
||||
EXPORT TIM15_IRQHandler [WEAK]
|
||||
EXPORT TIM16_IRQHandler [WEAK]
|
||||
EXPORT TIM17_IRQHandler [WEAK]
|
||||
EXPORT I2C1_IRQHandler [WEAK]
|
||||
EXPORT I2C2_IRQHandler [WEAK]
|
||||
EXPORT SPI1_IRQHandler [WEAK]
|
||||
EXPORT SPI2_IRQHandler [WEAK]
|
||||
EXPORT USART1_IRQHandler [WEAK]
|
||||
EXPORT USART2_IRQHandler [WEAK]
|
||||
EXPORT USART3_4_IRQHandler [WEAK]
|
||||
|
||||
WWDG_IRQHandler
|
||||
PVD_IRQHandler
|
||||
RTC_IRQHandler
|
||||
FLASH_IRQHandler
|
||||
RCC_IRQHandler
|
||||
EXTI0_1_IRQHandler
|
||||
EXTI2_3_IRQHandler
|
||||
EXTI4_15_IRQHandler
|
||||
LCD_IRQHandler
|
||||
DMA1_Channel1_IRQHandler
|
||||
DMA1_Channel2_3_IRQHandler
|
||||
DMA1_Channel4_5_6_7_IRQHandler
|
||||
ADC_COMP_IRQHandler
|
||||
TIM1_BRK_UP_TRG_COM_IRQHandler
|
||||
TIM1_CC_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
TIM3_IRQHandler
|
||||
TIM6_LPTIM1_IRQHandler
|
||||
TIM7_IRQHandler
|
||||
TIM14_IRQHandler
|
||||
TIM15_IRQHandler
|
||||
TIM16_IRQHandler
|
||||
TIM17_IRQHandler
|
||||
I2C1_IRQHandler
|
||||
I2C2_IRQHandler
|
||||
SPI1_IRQHandler
|
||||
SPI2_IRQHandler
|
||||
USART1_IRQHandler
|
||||
USART2_IRQHandler
|
||||
USART3_4_IRQHandler
|
||||
B .
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap
|
||||
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
END
|
||||
|
||||
;************************ (C) COPYRIGHT Puya *****END OF FILE*******************
|
||||
@@ -0,0 +1,504 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file boot_main.c
|
||||
* @brief 可配置 OTA Bootloader — PY32F040
|
||||
*
|
||||
* 三种模式(由 ota_config.h 的 OTA_BACKUP_MODE / OTA_SWAP_STRATEGY 决定):
|
||||
*
|
||||
* ① 单备份(SINGLE):
|
||||
* PENDING → 校验 BAK → 拷贝覆盖主区 → 跳转主区(无回滚)
|
||||
* 掉电:PENDING 不清除,下次启动重新校验+拷贝(BAK 完好,天然安全)
|
||||
*
|
||||
* ② 双备份 + RAM 缓冲交换(AB + RAM):
|
||||
* PENDING → 校验 B 区 → 逐页交换(RAM 双页缓冲)→ BOOT_NEW → 跳转 A 区
|
||||
* SWAPPING → 交换掉电中断,续做(phase/progress 恢复)
|
||||
* BOOT_NEW 未确认(崩溃/IWDG 复位)→ 反向交换回滚 → 跳转 A 区
|
||||
*
|
||||
* ③ 双备份 + Flash 暂存区交换(AB + SCRATCH):
|
||||
* 同上,但交换用 scratch 暂存一页(Flash 持久),掉电恢复可完整保留两页,
|
||||
* 回滚永远可用;升级耗时更短。
|
||||
*
|
||||
* 跳转新固件前使能 IWDG:新固件崩溃则看门狗复位,Bootloader 再次判定并回滚。
|
||||
* 交换/拷贝期间使能 IWDG 并逐页喂狗(单页耗时 < 100ms,远小于 1s 超时)。
|
||||
******************************************************************************
|
||||
*/
|
||||
#include "boot_main.h"
|
||||
#include "flash.h"
|
||||
#include "crc32.h"
|
||||
#include "iwdg_config.h"
|
||||
|
||||
#define DEBUG
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
static ota_param_t g_ota;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static int fw_vector_ok(uint32_t base);
|
||||
static int fw_validate(uint32_t base, uint32_t size, uint32_t crc);
|
||||
static void boot_iwdg_enable(void);
|
||||
static void boot_iwdg_feed(void);
|
||||
static void boot_jump(uint32_t base);
|
||||
|
||||
#if (OTA_BACKUP_MODE == OTA_MODE_SINGLE)
|
||||
static void copy_bak_to_run(void);
|
||||
#else
|
||||
static void swap_execute(int reverse);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 系统复位
|
||||
*/
|
||||
void mcuRestart(void)
|
||||
{
|
||||
Log("[OTA] Restarting MCU...\r\n");
|
||||
HAL_NVIC_SystemReset();
|
||||
}
|
||||
|
||||
/* ── OTA 状态区读写 ─────────────────────────────────────────────────────────
|
||||
* 由 flash.h 的 ota_param_load / ota_param_store 提供(4 页轮换磨损均衡)。
|
||||
* 状态区无效时 load 自动回退默认 IDLE。 */
|
||||
|
||||
/* ── 固件校验 ─────────────────────────────────────────────────────────────── */
|
||||
|
||||
/* 向量表合法性:栈顶在 RAM,复位向量落在运行区 Flash 范围内。
|
||||
* 注意:固件始终链接运行区 OTA_RUN_ADDR_BASE,BAK/B 区只是下载/备份缓冲,
|
||||
* 存储位置 ≠ 链接地址。无论 base 传 RUN 还是 BAK,都应校验复位向量是否指向
|
||||
* 运行区(固件真正执行处),否则 BAK 校验会因复位向量指向 RUN 而被误判非法。 */
|
||||
static int fw_vector_ok(uint32_t base)
|
||||
{
|
||||
uint32_t sp = *(volatile uint32_t *)base;
|
||||
uint32_t rv = *(volatile uint32_t *)(base + 4);
|
||||
|
||||
(void)base;
|
||||
|
||||
if ((sp < RAM_BASE_ADDR) || (sp >= RAM_END_ADDR))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ((rv < OTA_RUN_ADDR_BASE) || (rv >= (OTA_RUN_ADDR_BASE + OTA_SLOT_MAX_SIZE)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 完整校验:向量表合法 + CRC32 匹配 */
|
||||
static int fw_validate(uint32_t base, uint32_t size, uint32_t crc)
|
||||
{
|
||||
if ((size == 0) || (size > OTA_SLOT_MAX_SIZE))
|
||||
{
|
||||
Log("[BL] fw size invalid: %lu\r\n", (unsigned long)size);
|
||||
return 0;
|
||||
}
|
||||
if (!fw_vector_ok(base))
|
||||
{
|
||||
Log("[BL] fw vector invalid @ %08X\r\n", (unsigned int)base);
|
||||
return 0;
|
||||
}
|
||||
if (crc32_compute((uint8_t *)base, size) != crc)
|
||||
{
|
||||
Log("[BL] fw CRC32 mismatch @ %08X\r\n", (unsigned int)base);
|
||||
return 0;
|
||||
}
|
||||
Log("[BL] fw validate OK @ %08X (size %lu)\r\n", (unsigned int)base, (unsigned long)size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ── IWDG:跳转前使能,新固件崩溃则由看门狗复位回滚;交换/拷贝期间逐页喂狗 ── */
|
||||
|
||||
static void boot_iwdg_enable(void)
|
||||
{
|
||||
/* 使能 LSI 并等待就绪 */
|
||||
SET_BIT(RCC->CSR, RCC_CSR_LSION);
|
||||
for (uint32_t i = 0; i < 10000; i++)
|
||||
{
|
||||
if (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* IWDG 配置:参数见 Shared/iwdg_config.h */
|
||||
IWDG->KR = 0x5555; /* 解锁 */
|
||||
IWDG->PR = IWDG_PR_REG; /* /16 */
|
||||
IWDG->RLR = IWDG_RELOAD_VALUE;
|
||||
IWDG->KR = 0xAAAA; /* 重装 */
|
||||
IWDG->KR = 0xCCCC; /* 启动 */
|
||||
Log("[BL] IWDG enabled (~1s)\r\n");
|
||||
}
|
||||
|
||||
static void boot_iwdg_feed(void)
|
||||
{
|
||||
IWDG->KR = 0xAAAA; /* 重装计数,防交换/拷贝期间复位 */
|
||||
}
|
||||
|
||||
/* ── 跳转到 APP ───────────────────────────────────────────────────────────── */
|
||||
|
||||
typedef void (*iapfun)(void);
|
||||
|
||||
__asm void MSR_MSP(uint32_t addr)
|
||||
{
|
||||
MSR MSP, r0
|
||||
BX r14
|
||||
}
|
||||
|
||||
static void boot_jump(uint32_t base)
|
||||
{
|
||||
uint32_t sp, rv;
|
||||
|
||||
if (!fw_vector_ok(base))
|
||||
{
|
||||
Log("[BL] Jump target vector invalid! Hang.\r\n");
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
sp = *(volatile uint32_t *)base;
|
||||
rv = *(volatile uint32_t *)(base + 4);
|
||||
|
||||
Log("[BL] Jump to APP @ %08X\r\n", (unsigned int)base);
|
||||
|
||||
/* 关闭全局中断,设置向量表与栈,跳转 */
|
||||
__disable_irq();
|
||||
SCB->VTOR = base; /* PY32F040 支持 VTOR */
|
||||
MSR_MSP(sp);
|
||||
((iapfun)rv)();
|
||||
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/* ── 单备份:BAK 拷贝覆盖主区 ─────────────────────────────────────────────── */
|
||||
|
||||
#if (OTA_BACKUP_MODE == OTA_MODE_SINGLE)
|
||||
static void copy_bak_to_run(void)
|
||||
{
|
||||
uint8_t buf[OTA_PAGE_SIZE];
|
||||
uint32_t i, pages = OTA_SLOT_PAGE_NB;
|
||||
|
||||
Log("[BL] copy BAK(%08X) -> RUN(%08X), %lu pages\r\n",
|
||||
(unsigned int)OTA_BAK_ADDR_BASE, (unsigned int)OTA_RUN_ADDR_BASE,
|
||||
(unsigned long)pages);
|
||||
|
||||
for (i = 0; i < pages; i++)
|
||||
{
|
||||
uint32_t src = OTA_BAK_ADDR_BASE + i * OTA_PAGE_SIZE;
|
||||
uint32_t dst = OTA_RUN_ADDR_BASE + i * OTA_PAGE_SIZE;
|
||||
APP_FlashRead(src, buf, OTA_PAGE_SIZE);
|
||||
APP_FlashEraseWithCheck(dst, OTA_PAGE_SIZE);
|
||||
APP_FlashWrite(dst, buf, OTA_PAGE_SIZE);
|
||||
boot_iwdg_feed();
|
||||
}
|
||||
|
||||
/* 拷贝完成:置 BOOT_NEW(等待 App 确认并回复 OTA 完成;单备份无回滚目标,
|
||||
* 若 App 未确认崩溃,下次启动见 BOOT_NEW 直接继续运行)。
|
||||
* 中途掉电则下次重新拷贝(PENDING 未清,BAK 完好) */
|
||||
g_ota.state = OTA_STATE_BOOT_NEW;
|
||||
ota_param_store(&g_ota);
|
||||
Log("[BL] copy done\r\n");
|
||||
}
|
||||
#endif /* SINGLE */
|
||||
|
||||
/* ── 双备份:A/B 区交换 ───────────────────────────────────────────────────── */
|
||||
|
||||
#if (OTA_BACKUP_MODE == OTA_MODE_AB)
|
||||
|
||||
#if (OTA_SWAP_STRATEGY == OTA_SWAP_SCRATCH)
|
||||
/**
|
||||
* @brief Flash 暂存区交换(scratch 持久保存一页,掉电可完整恢复)
|
||||
* @param reverse 0=正向(A=旧,B=新 → A=新,B=旧,部署新固件)
|
||||
* 1=反向(A=新,B=旧 → A=旧,B=新,回滚旧固件)
|
||||
*/
|
||||
static void swap_execute(int reverse)
|
||||
{
|
||||
uint32_t a = OTA_RUN_ADDR_BASE;
|
||||
uint32_t b = OTA_BAK_ADDR_BASE;
|
||||
uint32_t i, total_pages = OTA_SLOT_PAGE_NB;
|
||||
uint8_t buf[OTA_PAGE_SIZE];
|
||||
|
||||
if (g_ota.state != OTA_STATE_SWAPPING)
|
||||
{
|
||||
g_ota.state = OTA_STATE_SWAPPING;
|
||||
g_ota.progress = 0;
|
||||
g_ota.phase = 0;
|
||||
ota_param_store(&g_ota);
|
||||
}
|
||||
Log("[BL] swap(%s) %lu pages\r\n", reverse ? "rollback" : "forward",
|
||||
(unsigned long)total_pages);
|
||||
|
||||
for (i = g_ota.progress; i < total_pages; i++)
|
||||
{
|
||||
uint32_t addr_a = a + i * OTA_PAGE_SIZE;
|
||||
uint32_t addr_b = b + i * OTA_PAGE_SIZE;
|
||||
|
||||
/* 掉电恢复:phase==1 时 scratch 保存着 addr_a 的原内容,
|
||||
* 直接补写 addr_b 完成本页,再继续(scratch 持久,不丢) */
|
||||
if ((g_ota.phase == 1) && (i == g_ota.progress))
|
||||
{
|
||||
APP_FlashRead(OTA_SCRATCH_ADDR, buf, OTA_PAGE_SIZE);
|
||||
APP_FlashEraseWithCheck(addr_b, OTA_PAGE_SIZE);
|
||||
APP_FlashWrite(addr_b, buf, OTA_PAGE_SIZE);
|
||||
g_ota.phase = 0;
|
||||
g_ota.progress = (uint16_t)(i + 1);
|
||||
ota_param_store(&g_ota);
|
||||
boot_iwdg_feed();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 1) scratch ← A[i](持久保存被覆盖方) */
|
||||
APP_FlashRead(addr_a, buf, OTA_PAGE_SIZE);
|
||||
APP_FlashEraseWithCheck(OTA_SCRATCH_ADDR, OTA_SCRATCH_SIZE);
|
||||
APP_FlashWrite(OTA_SCRATCH_ADDR, buf, OTA_PAGE_SIZE);
|
||||
|
||||
g_ota.phase = 1;
|
||||
ota_param_store(&g_ota);
|
||||
|
||||
/* 2) A[i] ← B[i] */
|
||||
APP_FlashRead(addr_b, buf, OTA_PAGE_SIZE);
|
||||
APP_FlashEraseWithCheck(addr_a, OTA_PAGE_SIZE);
|
||||
APP_FlashWrite(addr_a, buf, OTA_PAGE_SIZE);
|
||||
|
||||
/* 3) B[i] ← scratch(原 A[i]) */
|
||||
APP_FlashRead(OTA_SCRATCH_ADDR, buf, OTA_PAGE_SIZE);
|
||||
APP_FlashEraseWithCheck(addr_b, OTA_PAGE_SIZE);
|
||||
APP_FlashWrite(addr_b, buf, OTA_PAGE_SIZE);
|
||||
|
||||
g_ota.phase = 0;
|
||||
g_ota.progress = (uint16_t)(i + 1);
|
||||
ota_param_store(&g_ota);
|
||||
boot_iwdg_feed();
|
||||
}
|
||||
|
||||
g_ota.state = reverse ? OTA_STATE_IDLE : OTA_STATE_BOOT_NEW;
|
||||
ota_param_store(&g_ota);
|
||||
Log("[BL] swap done, state=%u\r\n", g_ota.state);
|
||||
}
|
||||
|
||||
#else /* OTA_SWAP_STRATEGY == OTA_SWAP_RAM */
|
||||
|
||||
/**
|
||||
* @brief RAM 缓冲交换(不预留暂存区,A/B 各 55K;掉电恢复见 phase 说明)
|
||||
* @param reverse 0=正向(部署新) 1=反向(回滚)
|
||||
*
|
||||
* 正向每页顺序(关键:先部署新到 A,再备份旧到 B):
|
||||
* phase=1 写入后 → 擦/写 A[i](若中断,B[i] 仍是新固件页,可重建 A[i])
|
||||
* → 擦/写 B[i](若中断,旧固件页丢失,但新固件完整 → 升级成功、回滚失效)
|
||||
* 掉电恢复(phase==1 且 i==progress):从 B[i] 重建 A[i],
|
||||
* 放弃本页旧备份(B[i] 保持新固件页),继续后续页 —— 保证新固件永远可收敛。
|
||||
*/
|
||||
static void swap_execute(int reverse)
|
||||
{
|
||||
uint32_t a = OTA_RUN_ADDR_BASE;
|
||||
uint32_t b = OTA_BAK_ADDR_BASE;
|
||||
uint32_t i, total_pages = OTA_SLOT_PAGE_NB;
|
||||
uint8_t buf_new[OTA_PAGE_SIZE];
|
||||
uint8_t buf_old[OTA_PAGE_SIZE];
|
||||
|
||||
if (g_ota.state != OTA_STATE_SWAPPING)
|
||||
{
|
||||
g_ota.state = OTA_STATE_SWAPPING;
|
||||
g_ota.progress = 0;
|
||||
g_ota.phase = 0;
|
||||
ota_param_store(&g_ota);
|
||||
}
|
||||
Log("[BL] swap(%s) %lu pages (RAM buf)\r\n", reverse ? "rollback" : "forward",
|
||||
(unsigned long)total_pages);
|
||||
|
||||
for (i = g_ota.progress; i < total_pages; i++)
|
||||
{
|
||||
uint32_t addr_a = a + i * OTA_PAGE_SIZE;
|
||||
uint32_t addr_b = b + i * OTA_PAGE_SIZE;
|
||||
|
||||
/* 掉电恢复:phase==1 时 A[i] 可能半写,B[i] 必为新固件页(未动)→ 重建 A[i] */
|
||||
if ((g_ota.phase == 1) && (i == g_ota.progress))
|
||||
{
|
||||
APP_FlashRead(addr_b, buf_new, OTA_PAGE_SIZE);
|
||||
APP_FlashEraseWithCheck(addr_a, OTA_PAGE_SIZE);
|
||||
APP_FlashWrite(addr_a, buf_new, OTA_PAGE_SIZE);
|
||||
/* 旧固件页已在掉电时丢失 → 本页放弃旧备份(B[i] 保持新固件页) */
|
||||
g_ota.phase = 0;
|
||||
g_ota.progress = (uint16_t)(i + 1);
|
||||
ota_param_store(&g_ota);
|
||||
boot_iwdg_feed();
|
||||
continue;
|
||||
}
|
||||
|
||||
APP_FlashRead(addr_a, buf_old, OTA_PAGE_SIZE);
|
||||
APP_FlashRead(addr_b, buf_new, OTA_PAGE_SIZE);
|
||||
|
||||
/* 先写 A(部署新):中断时 B[i] 完好可重建 */
|
||||
g_ota.phase = 1;
|
||||
ota_param_store(&g_ota);
|
||||
APP_FlashEraseWithCheck(addr_a, OTA_PAGE_SIZE);
|
||||
APP_FlashWrite(addr_a, buf_new, OTA_PAGE_SIZE);
|
||||
|
||||
/* 再写 B(备份旧) */
|
||||
APP_FlashEraseWithCheck(addr_b, OTA_PAGE_SIZE);
|
||||
APP_FlashWrite(addr_b, buf_old, OTA_PAGE_SIZE);
|
||||
|
||||
g_ota.phase = 0;
|
||||
g_ota.progress = (uint16_t)(i + 1);
|
||||
ota_param_store(&g_ota);
|
||||
boot_iwdg_feed();
|
||||
}
|
||||
|
||||
g_ota.state = reverse ? OTA_STATE_IDLE : OTA_STATE_BOOT_NEW;
|
||||
ota_param_store(&g_ota);
|
||||
Log("[BL] swap done, state=%u\r\n", g_ota.state);
|
||||
}
|
||||
#endif /* OTA_SWAP_STRATEGY */
|
||||
|
||||
#endif /* OTA_BACKUP_MODE == AB */
|
||||
|
||||
/**
|
||||
* @brief Main program.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
HAL_Init();
|
||||
#ifdef DEBUG
|
||||
DEBUG_USART_Config(); /* 将串口配置成日志口 */
|
||||
#endif
|
||||
Log("\r\n==== PY32F040 OTA Bootloader V3.0 ====\r\n");
|
||||
#if (OTA_BACKUP_MODE == OTA_MODE_SINGLE)
|
||||
Log("[BL] mode: SINGLE backup\r\n");
|
||||
#else
|
||||
/* 双备份:OTA_SWAP_STRATEGY / OTA_SCRATCH_* 由 ota_config.h 的
|
||||
* #if (OTA_BACKUP_MODE == OTA_MODE_AB) 保护,此处一定已定义 */
|
||||
#if (OTA_SWAP_STRATEGY == OTA_SWAP_SCRATCH)
|
||||
Log("[BL] mode: AB backup, SCRATCH swap\r\n");
|
||||
#else
|
||||
Log("[BL] mode: AB backup, RAM swap\r\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ota_param_load(&g_ota);
|
||||
Log("[BL] state=%u fw_size=%lu\r\n", g_ota.state, (unsigned long)g_ota.fw_size);
|
||||
|
||||
#if (OTA_BACKUP_MODE == OTA_MODE_SINGLE)
|
||||
|
||||
/* ── ① 单备份 ── */
|
||||
switch (g_ota.state)
|
||||
{
|
||||
case OTA_STATE_PENDING:
|
||||
Log("[BL] Pending: validate BAK ...\r\n");
|
||||
if (fw_validate(OTA_BAK_ADDR_BASE, g_ota.fw_size, g_ota.fw_crc32))
|
||||
{
|
||||
boot_iwdg_enable();
|
||||
copy_bak_to_run();
|
||||
Log("[BL] Switch to NEW fw in RUN area\r\n");
|
||||
boot_jump(OTA_RUN_ADDR_BASE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 新固件无效 → 继续跑主区旧固件(BAK 被丢弃) */
|
||||
Log("[BL] New fw invalid, keep old RUN fw\r\n");
|
||||
g_ota.state = OTA_STATE_IDLE;
|
||||
ota_param_store(&g_ota);
|
||||
boot_iwdg_enable();
|
||||
boot_jump(OTA_RUN_ADDR_BASE);
|
||||
}
|
||||
break;
|
||||
|
||||
case OTA_STATE_BOOT_NEW:
|
||||
/* 单备份无回滚目标:App 未确认(崩溃/掉电)也只能继续运行主区 */
|
||||
Log("[BL] SINGLE: BOOT_NEW not confirmed, keep RUN fw\r\n");
|
||||
g_ota.state = OTA_STATE_IDLE;
|
||||
ota_param_store(&g_ota);
|
||||
boot_iwdg_enable();
|
||||
boot_jump(OTA_RUN_ADDR_BASE);
|
||||
break;
|
||||
|
||||
case OTA_STATE_IDLE:
|
||||
default:
|
||||
Log("[BL] Normal boot, RUN area\r\n");
|
||||
boot_iwdg_enable();
|
||||
boot_jump(OTA_RUN_ADDR_BASE);
|
||||
break;
|
||||
}
|
||||
|
||||
#else /* OTA_BACKUP_MODE == AB */
|
||||
|
||||
/* ── ②/③ 双备份 ── */
|
||||
switch (g_ota.state)
|
||||
{
|
||||
case OTA_STATE_PENDING:
|
||||
Log("[BL] Pending: validate B area ...\r\n");
|
||||
if (fw_validate(OTA_BAK_ADDR_BASE, g_ota.fw_size, g_ota.fw_crc32))
|
||||
{
|
||||
boot_iwdg_enable(); /* 交换期间逐页喂狗,跳转后由新固件喂狗 */
|
||||
swap_execute(0); /* 正向交换:A=新, B=旧 */
|
||||
Log("[BL] Switch to NEW fw\r\n");
|
||||
boot_jump(OTA_RUN_ADDR_BASE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 新固件无效 → 继续跑 A 区旧固件 */
|
||||
Log("[BL] New fw invalid, keep old RUN fw\r\n");
|
||||
g_ota.state = OTA_STATE_IDLE;
|
||||
ota_param_store(&g_ota);
|
||||
boot_iwdg_enable();
|
||||
boot_jump(OTA_RUN_ADDR_BASE);
|
||||
}
|
||||
break;
|
||||
|
||||
case OTA_STATE_SWAPPING:
|
||||
/* 上次交换掉电中断 → 续做(部署新固件) */
|
||||
Log("[BL] Resuming interrupted swap ...\r\n");
|
||||
boot_iwdg_enable();
|
||||
swap_execute(0);
|
||||
Log("[BL] Switch to NEW fw (resumed)\r\n");
|
||||
boot_jump(OTA_RUN_ADDR_BASE);
|
||||
break;
|
||||
|
||||
case OTA_STATE_BOOT_NEW:
|
||||
/* 上次启动的新固件未确认(崩溃/掉电)→ 回滚旧固件 */
|
||||
Log("[BL] New fw not confirmed, ROLLBACK ...\r\n");
|
||||
boot_iwdg_enable();
|
||||
swap_execute(1); /* 反向交换:A=旧, B=新 */
|
||||
Log("[BL] Rollback done, boot old fw\r\n");
|
||||
boot_jump(OTA_RUN_ADDR_BASE);
|
||||
break;
|
||||
|
||||
case OTA_STATE_IDLE:
|
||||
default:
|
||||
Log("[BL] Normal boot, RUN area\r\n");
|
||||
boot_iwdg_enable();
|
||||
boot_jump(OTA_RUN_ADDR_BASE);
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* OTA_BACKUP_MODE */
|
||||
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Function Name: Error_Handler
|
||||
* @brief 错误处理函数
|
||||
* @param *file:文件名,line:行号
|
||||
* @return None
|
||||
***********************************************************************************************************************/
|
||||
void Error_Handler(uint8_t *file, uint32_t line)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
appPrintf(LOG_ERROR, "%s %d\r\n", file, line);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
void assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040_hal_msp.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides code for the MSP Initialization
|
||||
* and de-Initialization codes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "boot_main.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* External functions --------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Initialize global MSP.
|
||||
*/
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040_it.c
|
||||
* @author MCU Application Team
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "boot_main.h"
|
||||
#include "py32f040_it.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M0+ Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @brief This function handles Non maskable interrupt.
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System service call via SWI instruction.
|
||||
*/
|
||||
void SVC_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Pendable request for system service.
|
||||
*/
|
||||
void PendSV_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System tick timer.
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
HAL_IncTick();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* PY32F040 Peripheral Interrupt Handlers */
|
||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||
/* For the available peripheral interrupt handler names, */
|
||||
/* please refer to the startup file. */
|
||||
/******************************************************************************/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_py32f040.c
|
||||
* @author MCU Application Team
|
||||
* @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "py32f0xx.h"
|
||||
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 24000000U /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE 32768U /*!< Value of LSI in Hz*/
|
||||
#endif /* LSI_VALUE */
|
||||
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE 32768U /*!< Value of LSE in Hz*/
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
|
||||
/************************* Miscellaneous Configuration ************************/
|
||||
/*!< Uncomment the following line if you need to relocate your vector Table in
|
||||
Internal SRAM. */
|
||||
/* #define FORBID_VECT_TAB_MIGRATION */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x100. */
|
||||
/******************************************************************************/
|
||||
/*----------------------------------------------------------------------------
|
||||
Clock Variable definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = HSI_VALUE;
|
||||
|
||||
const uint32_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
const uint32_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||
const uint32_t HSIFreqTable[8] = {4000000U, 8000000U, 16000000U, 22120000U, 24000000U, 4000000U, 4000000U, 4000000U};
|
||||
|
||||
/**
|
||||
* @brief Clock functions.
|
||||
* @param none
|
||||
* @return none
|
||||
*/
|
||||
void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
|
||||
{
|
||||
uint32_t tmp;
|
||||
uint32_t hsidiv;
|
||||
uint32_t hsifs;
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
uint32_t pllmul=0;
|
||||
const uint8_t pllMulValue[4] = {2,3,2,2};
|
||||
#endif /* RCC_PLL_SUPPORT */
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
switch (RCC->CFGR & RCC_CFGR_SWS)
|
||||
{
|
||||
case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
|
||||
case RCC_SYSCLKSOURCE_STATUS_LSI: /* LSI used as system clock */
|
||||
SystemCoreClock = LSI_VALUE;
|
||||
break;
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
case RCC_SYSCLKSOURCE_STATUS_LSE: /* LSE used as system clock */
|
||||
SystemCoreClock = LSE_VALUE;
|
||||
break;
|
||||
#endif /* RCC_LSE_SUPPORT */
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */
|
||||
pllmul = pllMulValue[((RCC->PLLCFGR & RCC_PLLCFGR_PLLMUL)>>RCC_PLLCFGR_PLLMUL_Pos)] ;
|
||||
|
||||
if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI) /* HSI used as PLL clock source */
|
||||
{
|
||||
hsifs = ((READ_BIT(RCC->ICSCR, RCC_ICSCR_HSI_FS)) >> RCC_ICSCR_HSI_FS_Pos);
|
||||
SystemCoreClock = pllmul * (HSIFreqTable[hsifs]);
|
||||
}
|
||||
else /* HSE used as PLL clock source */
|
||||
{
|
||||
SystemCoreClock = pllmul * HSE_VALUE;
|
||||
}
|
||||
break;
|
||||
#endif /* RCC_PLL_SUPPORT */
|
||||
case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock */
|
||||
default: /* HSI used as system clock */
|
||||
hsifs = ((READ_BIT(RCC->ICSCR, RCC_ICSCR_HSI_FS)) >> RCC_ICSCR_HSI_FS_Pos);
|
||||
hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos));
|
||||
SystemCoreClock = (HSIFreqTable[hsifs] / hsidiv);
|
||||
break;
|
||||
}
|
||||
/* Compute HCLK clock frequency --------------------------------------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
* Initialize the System.
|
||||
* @param none
|
||||
* @return none
|
||||
*/
|
||||
void SystemInit(void)
|
||||
{
|
||||
/* Set the HSI clock to 8MHz by default */
|
||||
/* Set the LSI clock to 32.768KHz by default */
|
||||
RCC->ICSCR = (RCC->ICSCR & 0xFE000000) | (0x1 << 13) | ((*(uint32_t *)(0x1fff3208)) & 0x0000FFFF) | ((*(uint32_t *)(0x1fff3348))<<16);
|
||||
|
||||
/* Configure the Vector Table location add offset address ------------------*/
|
||||
#ifdef VECT_TAB_SRAM
|
||||
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
|
||||
#else
|
||||
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
|
||||
#endif /* VECT_TAB_SRAM */
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
|
||||
@@ -0,0 +1,276 @@
|
||||
# PY32F040 开发框架 — OTA 升级设计(三模式可配置)
|
||||
|
||||
> 本框架提供**可配置的三种 OTA 模式**:单备份 / 双备份+RAM 交换 / 双备份+Flash 暂存区交换。
|
||||
> 协议对接 jb_protocol(见宝 IOT 协议,OTA 命令 0x30/0x32/0x34),**协议层原样使用,无需修改**。
|
||||
|
||||
---
|
||||
|
||||
## 0. 模式配置(唯一入口:`Shared/ota_config.h`,APP 与 Bootloader 共用)
|
||||
|
||||
```c
|
||||
/* ① 备份模式 —— 唯一必选开关 */
|
||||
#define OTA_MODE_SINGLE 0 /* 单备份:BAK 下载→校验→拷贝覆盖主区 */
|
||||
#define OTA_MODE_AB 1 /* 双备份:A/B 区交换(新固件崩溃可回滚旧固件)*/
|
||||
#define OTA_BACKUP_MODE OTA_MODE_AB
|
||||
|
||||
/* ═══ 以下 ②③ 仅 OTA_BACKUP_MODE == OTA_MODE_AB 时编译(#if 保护)═══ */
|
||||
#if (OTA_BACKUP_MODE == OTA_MODE_AB)
|
||||
|
||||
/* ② 双备份交换策略 */
|
||||
#define OTA_SWAP_SCRATCH 0 /* Flash 暂存区交换:升级快、掉电恢复最稳 */
|
||||
#define OTA_SWAP_RAM 1 /* RAM 缓冲交换:不预留暂存区,A/B 保持 58K */
|
||||
#define OTA_SWAP_STRATEGY OTA_SWAP_SCRATCH
|
||||
|
||||
/* ③ 暂存区参数(仅 SCRATCH 生效,需页对齐) */
|
||||
#if (OTA_SWAP_STRATEGY == OTA_SWAP_SCRATCH)
|
||||
#define OTA_SCRATCH_ADDR 0x0801F800UL
|
||||
#define OTA_SCRATCH_SIZE OTA_PAGE_SIZE /* 暂存区只需 1 页:交换时每次仅暂存 1 页(256B) */
|
||||
#endif
|
||||
#endif
|
||||
```
|
||||
|
||||
布局宏、状态结构体(`seq/progress/phase` 字段)、`OTA_STATE_SWAPPING` 状态
|
||||
均由上述 `#if` **自动联动**:单备份模式下不存在的配置/字段/状态**根本不会编译**,
|
||||
只需改 `OTA_BACKUP_MODE` 一个开关即可,无需关心哪些配置生效。
|
||||
|
||||
三种模式均**只编译/上传一份固件**(链接运行区 0x08003000),BLE 按原协议流程发同一份 bin,
|
||||
**不需要 active_slot、不需要打包路由**。
|
||||
|
||||
| 模式 | 固件份数 | 回滚 | 升级耗时 | 掉电安全 | 布局 |
|
||||
|---|---|---|---|---|---|
|
||||
| 单备份 | 1 | ❌ | ~1s | 拷贝中掉电=主区需重烧 | 主区 58K + BAK 58K |
|
||||
| 双备份+RAM | 1 | ✅ | 7~12s | 位图恢复,最坏=升级失败回旧版 | A/B 各 58K,无暂存区 |
|
||||
| 双备份+暂存区 | 1 | ✅ | 1~3s | 最稳(scratch 持久) | A/B 各 57K + scratch 1页 |
|
||||
|
||||
---
|
||||
|
||||
## 1. Flash 布局(128KB,PY32F040xB,页 256B)
|
||||
|
||||
**模式 ① 单备份 / 模式 ② 双备份+RAM(布局相同):**
|
||||
```
|
||||
0x08000000 ┌─────────────────────┐
|
||||
│ Bootloader │ 11KB (0x00000 ~ 0x02C00) 固定,芯片复位入口
|
||||
0x08002C00 ├─────────────────────┤
|
||||
│ OTA 状态区 │ 1KB (0x02C00 ~ 0x03000) 状态机 + 固件信息
|
||||
0x08003000 ├─────────────────────┤
|
||||
│ 运行区 (主区/A区) │ 58KB (0x03000 ~ 0x11800) 固件链接地址,出厂固件
|
||||
0x08011800 ├─────────────────────┤
|
||||
│ 备份区 (BAK/B区) │ 58KB (0x11800 ~ 0x20000) 下载目标 / 回滚备份
|
||||
0x08020000 └─────────────────────┘ (128KB 边界,A+B 正好填满)
|
||||
```
|
||||
|
||||
**模式 ③ 双备份+暂存区(A/B 各 57K,scratch 1页放 Flash 最底部):**
|
||||
```
|
||||
0x08000000 Bootloader(11K) | 0x08002C00 状态区(1K)
|
||||
0x08003000 A 区(57K) | 0x08011400 B 区(57K) | 0x0801F800 scratch(1页, 最底部)
|
||||
0x0801FC00 剩余空闲
|
||||
```
|
||||
|
||||
## 2. OTA 状态区(0x08002C00,1KB = 4 页,策略由备份模式决定)
|
||||
|
||||
**写入频率差异决定策略**(由 `Shared/flash.c` 的 `ota_param_load/store` 实现):
|
||||
|
||||
| 模式 | 每次升级状态区写入次数 | 10K 次擦写寿命可撑 | 策略 |
|
||||
|---|---|---|---|
|
||||
| 双备份 AB(swap) | 约 440 次(每页交换 2 次记 phase/progress) | 约 23 次升级 | **4 页轮换磨损均衡** |
|
||||
| 单备份 SINGLE | 2~3 次(无逐页交换过程) | 数千次升级 | **固定页 0 直写** |
|
||||
|
||||
**AB 模式(4 页轮换):**
|
||||
```
|
||||
每页副本格式:[ota_param_t(含 seq,28B)][0xFF 填充]
|
||||
写:顺序写下一页(seq 单调递增,uint32 实际不会溢出)
|
||||
读:扫描 4 页,取"seq 最大且 magic+CRC16 校验通过"的副本
|
||||
```
|
||||
|
||||
- 磨损均摊到 4 页(÷4):升级可承受次数 23 → **约 92 次**(按 10K 保守寿命;普冉标称值可能更高);
|
||||
- 擦除任一页时其他 3 页仍有有效数据,**擦除窗口掉电安全**;最新页损坏自动回退次新状态;
|
||||
- 若量产需要更大余量,可把 `OTA_PARAM_ADDR_BASE` 前移扩大状态区页数(Bootloader 相应缩小链接)。
|
||||
|
||||
**SINGLE 模式(固定页 0):** 每次写入直接擦写页 0(结构体无 `seq` 字段,无轮换),简单且寿命足够。
|
||||
|
||||
> 注:`seq` 存放在 `ota_param_t` 结构体**内部**(AB 模式首字段,参与 CRC16 保护),
|
||||
> 坏 seq 会被 CRC16 拒绝并回退次新副本,比单独放在页头更稳。
|
||||
> 结构体由 `#if` 条件编译:AB 28B / SINGLE 20B。
|
||||
|
||||
```c
|
||||
#define OTA_MAGIC 0xA55A
|
||||
#define OTA_STATE_IDLE 0x00 /* 正常运行 */
|
||||
#define OTA_STATE_PENDING 0x01 /* 新固件已下载,待 Bootloader 校验/拷贝/交换 */
|
||||
#if (OTA_BACKUP_MODE == OTA_MODE_AB)
|
||||
#define OTA_STATE_SWAPPING 0x02 /* 双备份:交换进行中(掉电恢复入口)*/
|
||||
#endif
|
||||
#define OTA_STATE_BOOT_NEW 0x03 /* 已切到新固件,等待 APP 确认(未确认=回滚)*/
|
||||
|
||||
typedef struct {
|
||||
#if (OTA_BACKUP_MODE == OTA_MODE_AB)
|
||||
uint32_t seq; /* 写入序号:4 页轮换判新(参与 CRC16) */
|
||||
#endif
|
||||
uint16_t magic; /* 0xA55A,有效标志 */
|
||||
uint8_t state; /* 状态机(见上) */
|
||||
uint8_t rsv;
|
||||
uint32_t fw_size; /* 新固件长度(字节) */
|
||||
uint32_t fw_crc32; /* 新固件 CRC32 */
|
||||
uint32_t fw_version; /* 新固件版本(透传) */
|
||||
#if (OTA_BACKUP_MODE == OTA_MODE_AB)
|
||||
uint16_t progress; /* 双备份:交换已完成页数(掉电恢复) */
|
||||
uint8_t phase; /* 双备份:交换阶段标志(掉电恢复) */
|
||||
#endif
|
||||
uint8_t rsv2;
|
||||
uint16_t crc16; /* 结构体自身 CRC16 保护(含 seq,读取无效视为 IDLE) */
|
||||
} ota_param_t; /* AB 28B / SINGLE 20B(OTA_PARAM_SIZE 自动) */
|
||||
```
|
||||
|
||||
无 `active_slot / target_slot`:**运行区固定 = OTA_RUN_ADDR_BASE(0x08003000)**,
|
||||
设备无需知道"当前在哪个区",目标区固定 = OTA_BAK_ADDR_BASE。
|
||||
|
||||
## 3. 状态机(核心)
|
||||
|
||||
**双备份(AB,swap):**
|
||||
```
|
||||
IDLE(运行区跑旧固件)
|
||||
│ 0x30 通知 → 校验版本/空间 → 应答 JB_OK
|
||||
│ 0x32 分片 → 写入备份区(固定) + 累计 CRC32
|
||||
│ 收完 CRC32==fwCrc32 → 写 {PENDING} → 复位
|
||||
▼
|
||||
Bootloader:
|
||||
PENDING → 校验备份区(向量+CRC32)
|
||||
├ 通过 → 写 {SWAPPING} → 交换 A/B(逐页)→ 写 {BOOT_NEW} → 使能 IWDG → 跳运行区
|
||||
└ 失败 → 写 {IDLE} → 跳运行区(旧固件)
|
||||
SWAPPING → 交换掉电中断 → 续做交换(progress/phase 恢复)→ {BOOT_NEW} → 跳转
|
||||
BOOT_NEW → 新固件未确认(崩溃) → 反向交换回滚 → 写 {IDLE} → 跳运行区
|
||||
IDLE/无效 → 跳运行区
|
||||
▼
|
||||
新固件(运行区):
|
||||
启动 → 外设自检 → app_boot_ota_report() 确认并上报 0x34「OTA升级完成」
|
||||
崩溃 → IWDG 复位 → Bootloader 见 BOOT_NEW 未确认 → 回滚
|
||||
```
|
||||
|
||||
**单备份:**
|
||||
```
|
||||
IDLE → PENDING → Bootloader 校验 BAK → 拷贝 BAK→主区 → 写 {BOOT_NEW} → 跳主区
|
||||
新固件启动 → 确认 → 回「OTA 升级完成」(无回滚目标,BOOT_NEW 未确认也继续运行)
|
||||
拷贝中途掉电 → PENDING 未清,下次重新校验+拷贝(BAK 完好,天然安全)
|
||||
```
|
||||
|
||||
## 4. 关键机制
|
||||
|
||||
### 4.1 “切换成功”判定
|
||||
采用 **BOOT_NEW 状态 + 独立看门狗(IWDG) + APP 自检确认**:
|
||||
1. Bootloader 交换/拷贝完成后写 `BOOT_NEW` 并**使能 IWDG(约 1s)**,交换期间逐页喂狗;
|
||||
2. 新固件 `app_Init()` 完成后,`app_boot_ota_report()` 调用 `ota_boot_check_confirm()`:见 BOOT_NEW → 写确认(IDLE) → 上报 0x34;
|
||||
3. 新固件启动即崩溃 → IWDG 复位 → Bootloader 见 BOOT_NEW 未确认 → **双备份反向交换回滚**;单备份无回滚目标,继续运行;
|
||||
4. 确认后运行区正式生效,备份区保留旧固件作为下次回滚备份。
|
||||
|
||||
### 4.2 单份固件 + swap 交换(双备份核心)
|
||||
固件为绝对地址链接(运行区 0x08003000),**只编译一份**。双备份不再"双区跳转",
|
||||
而是 **Bootloader 把 A/B 内容交换**:
|
||||
- 正向(部署新):A=旧,B=新 → **A=新(能跑),B=旧(备份)**
|
||||
- 反向(回滚):A=新(崩溃),B=旧 → **A=旧(能跑),B=新**
|
||||
|
||||
**RAM 缓冲交换**(A/B 各 58K 布局):每页用 RAM 双缓冲(512B)交换,逐页写
|
||||
`progress/phase` 到状态区。掉电恢复:phase==1 时 B 页仍完好(新固件页),从 B 重建 A,
|
||||
放弃本页旧备份——**保证新固件可收敛;最坏情况=升级成功但该页回滚失效**。
|
||||
|
||||
**Flash 暂存区交换**(scratch,A/B 各 57K):交换前先把被覆盖页存入 scratch(Flash 持久,
|
||||
位于 Flash 最底部 0x0801F800,仅占 1 页),掉电后可完整恢复两页,回滚永远可用。
|
||||
|
||||
- **构建方式**(重要):Keil 命令行(UV4)构建的链接地址由 **Target 对话框 ROM1
|
||||
(uvprojx 中 `<OCR_RVCT4>` 标签)** 决定,散列文件(ScatterFile)在命令行模式下不生效。
|
||||
`tools/build_all.py` 将 APP 链接固定为 0x08003000。
|
||||
- Bootloader 校验**复位向量必须落在运行区地址范围**,从硬件层面兜底"固件地址不匹配"。
|
||||
|
||||
### 4.3 中断向量表(PY32F040 带 VTOR)
|
||||
- Bootloader 跳转 APP 前设置 `SCB->VTOR` 并关中断;APP 启动时 `__enable_irq()` 恢复;
|
||||
- APP `system_py32f040.c` 中 `SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET`(0x08003000)。
|
||||
|
||||
### 4.4 固件校验(CRC32)
|
||||
- 协议 0x30 携带 `fwCrc32`,APP 接收分片时累计 CRC32,收完与 `fwCrc32` 比对;
|
||||
- Bootloader 启动前重新计算备份区 CRC32 验证;
|
||||
- CRC32 采用标准 **CRC-32/IEEE**(多项式 0x04C11DB7,初值 0xFFFFFFFF,输出异或 0xFFFFFFFF),APP 与 Bootloader 共用 `Shared/crc32.c`。
|
||||
|
||||
### 4.5 协议层(原样使用)
|
||||
- 0x31 应答保持协议原格式(3 字节:结果码 + MaxDataLen 2B),**无 active_slot**;
|
||||
- 0x30 应答支持用户层拒绝:`jbOnOtaNotify` 返回结果码(0=接受,非 0=拒绝码如
|
||||
`JB_OTA_NO_NEED`/`JB_OTA_VER_LOW`/`JB_OTA_SPACE_ERR`),按返回值构造 ACK;
|
||||
- `jbOnOtaData` 已带 `shardIdx/totalShards`,用户层据此计算写入偏移。
|
||||
|
||||
## 5. 升级完整时序(双备份+RAM 为例)
|
||||
|
||||
```
|
||||
BLE/APP MCU APP(运行区) Bootloader Flash
|
||||
│ 0x30 通知 │ │ │
|
||||
│ ────────────────────► │ 校验版本/空间 │ │
|
||||
│ ◄── 0x31 应答(3B) │ │ │
|
||||
│ 0x32 分片×N ────────► │ 写备份区 + 累计 CRC32 │ 写B区
|
||||
│ ◄── 0x32 ACK │ │ │
|
||||
│ 数据收完 │ CRC32 校验 → 写状态区 │ 写状态区
|
||||
│ │ {PENDING} → 复位 ────────────► │ │
|
||||
│ │ │ 校验 B 区(向量+CRC) │
|
||||
│ │ │ 交换 A/B(逐页) │
|
||||
│ │ │ 写 {BOOT_NEW} + IWDG │
|
||||
│ │ ◄── 跳转运行区 ────────────────│ │
|
||||
│ │ 自检 → 确认 → 回 0x34 完成 │ 写状态区
|
||||
│ ◄── 0x34 完成(JB_OK) ─│ │ │
|
||||
└───────────────────────┴──────────────────────────────┴──────────────────────┘
|
||||
若新固件崩溃:IWDG 复位 → Bootloader 见 BOOT_NEW 未确认 → 反向交换回滚旧固件
|
||||
```
|
||||
|
||||
## 6. 文件清单
|
||||
|
||||
### 共享层 `Shared/`(APP 与 Bootloader 共用,单一真源)
|
||||
| 文件 | 说明 |
|
||||
|---|---|
|
||||
| `Shared/ota_config.h` | **三模式唯一配置入口**:模式开关 + 布局宏 + 状态结构/状态机常量 |
|
||||
| `Shared/flash.c` + 各工程 `flash.h` | OTA 状态区读写、Flash 擦写 |
|
||||
| `Shared/crc32.c/.h` | CRC32 算法 |
|
||||
| `Shared/iwdg_config.h` | IWDG 超时参数(BL/APP 一致) |
|
||||
| `Shared/log.h` | 日志宏 |
|
||||
|
||||
### APP 工程 `App/`
|
||||
| 文件 | 说明 |
|
||||
|---|---|
|
||||
| `Core/ota_ab.c/.h` | OTA 下载:分片写入备份区 / 校验 / 写 PENDING |
|
||||
| `Core/iwdg.c/.h` | IWDG HAL 封装(启动接管 + 主循环喂狗) |
|
||||
| `Core/app_boot.c/.h` | 启动流程:中断交接 / 时钟 / IWDG / OTA 确认与 0x34 上报 |
|
||||
| `Src/main.c` | 入口:`app_startup()` → `app_lication()` |
|
||||
| `Src/application.c` | 应用初始化 + 主循环 |
|
||||
| `Protocol/jb_product.c` | 实现 `jbOnOtaNotify` / `jbOnOtaData` / `jbOnOtaStop` |
|
||||
| `MDK-ARM/project.uvprojx` | Keil 工程,ROM1 = 0x08003000 |
|
||||
|
||||
### Bootloader 工程 `Bootloader/`
|
||||
| 文件 | 说明 |
|
||||
|---|---|
|
||||
| `Src/boot_main.c` | 三模式状态机:单备份拷贝 / 双备份交换(RAM 与 scratch,按宏裁剪) |
|
||||
| `Code/flash.h` | Flash 头文件(实现引用 `Shared/flash.c`) |
|
||||
| `MDK-ARM/Bootloader.uvprojx` | Keil 工程,ROM1 = 0x08000000 |
|
||||
|
||||
### 构建/工具
|
||||
| 文件 | 说明 |
|
||||
|---|---|
|
||||
| `build.bat` | 一键编译 Bootloader + APP |
|
||||
| `tools/build_all.py` | 构建脚本,产出 hex/bin 并打印 fwCrc32 |
|
||||
| `tools/merge_hex.py` | 合并 bootloader + app hex(出厂烧录) |
|
||||
| `tools/pack.py` | 打包可分发 zip(工程 + Drivers + Shared) |
|
||||
|
||||
## 7. 升级失败/异常场景汇总
|
||||
|
||||
| 场景 | 单备份 | 双备份+RAM | 双备份+暂存区 |
|
||||
|---|---|---|---|
|
||||
| 下载中掉电 | 备份区半写,主区不受影响 | 同左 | 同左 |
|
||||
| 下载完 CRC32 失败 | 不写状态区,继续旧固件 | 同左 | 同左 |
|
||||
| Bootloader 校验备份区失败 | 继续主区旧固件 | 同左 | 同左 |
|
||||
| 拷贝/交换中掉电 | PENDING 未清,下次重新拷贝(安全) | SWAPPING 续做(新固件可收敛) | scratch 持久,完整恢复 |
|
||||
| 新固件启动崩溃(IWDG) | 无回滚(主区已覆盖) | 反向交换回滚 | 反向交换回滚 |
|
||||
| 新固件确认成功 | 运行新固件 | 运行新固件,旧固件留备份 | 同左 |
|
||||
|
||||
## 8. 框架特性摘要
|
||||
|
||||
| 项 | 说明 |
|
||||
|---|---|
|
||||
| 固件份数 | 一份 app.bin,链接 0x08003000,三模式通用 |
|
||||
| 升级写入 | 固定备份区 `OTA_BAK_ADDR_BASE` |
|
||||
| 切换方式 | 单备份=拷贝覆盖;双备份=A/B 页交换 |
|
||||
| 校验 | CRC32(协议 0x30 携带 fwCrc32) |
|
||||
| 回滚 | 双备份:BOOT_NEW 未确认 → 反向交换;单备份:无自动回滚 |
|
||||
| 确认机制 | APP 自检 + Flash 写 IDLE + IWDG 兜底 |
|
||||
| 协议 | jb_protocol 0x30/0x32/0x34,用户层在 `jb_product.c` 对接 |
|
||||
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f002xx_Start_Kit.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f002xx_Start_Kit.h"
|
||||
|
||||
/**
|
||||
* @brief PY32F002xx STK BSP Driver version number
|
||||
*/
|
||||
#define __PY32F002xx_STK_BSP_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||
#define __PY32F002xx_STK_BSP_VERSION_SUB1 (0x00U) /*!< [23:16] sub1 version */
|
||||
#define __PY32F002xx_STK_BSP_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
|
||||
#define __PY32F002xx_STK_BSP_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __PY32F002xx_STK_BSP_VERSION ((__PY32F002xx_STK_BSP_VERSION_MAIN << 24) \
|
||||
|(__PY32F002xx_STK_BSP_VERSION_SUB1 << 16) \
|
||||
|(__PY32F002xx_STK_BSP_VERSION_SUB2 << 8 ) \
|
||||
|(__PY32F002xx_STK_BSP_VERSION_RC))
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
UART_HandleTypeDef DebugUartHandle;
|
||||
#endif
|
||||
GPIO_TypeDef* LED_PORT[LEDn] = {LED3_GPIO_PORT};
|
||||
const uint16_t LED_PIN[LEDn] = {LED3_PIN};
|
||||
|
||||
GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT };
|
||||
const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN };
|
||||
const uint8_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn };
|
||||
|
||||
/** @addtogroup PY32F002xx_STK_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This method returns the PY32F002 STK BSP Driver revision.
|
||||
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void)
|
||||
{
|
||||
return __PY32F002xx_STK_BSP_VERSION;
|
||||
}
|
||||
|
||||
/** @addtogroup LED_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configures LED GPIO.
|
||||
* @param Led Specifies the Led to be configured.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Init(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
/* Enable the GPIO_LED Clock */
|
||||
LEDx_GPIO_CLK_ENABLE(Led);
|
||||
|
||||
/* Configure the GPIO_LED pin */
|
||||
GPIO_InitStruct.Pin = LED_PIN[Led];
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
|
||||
HAL_GPIO_Init(LED_PORT[Led], &GPIO_InitStruct);
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize LED GPIO.
|
||||
* @param Led Specifies the Led to be deconfigured.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg LED3
|
||||
* @note BSP_LED_DeInit() does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_DeInit(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
/* Turn off LED */
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
|
||||
/* DeInit the GPIO_LED pin */
|
||||
GPIO_InitStruct.Pin = LED_PIN[Led];
|
||||
HAL_GPIO_DeInit(LED_PORT[Led], GPIO_InitStruct.Pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED On.
|
||||
* @param Led Specifies the Led to be set on.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_On(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED Off.
|
||||
* @param Led Specifies the Led to be set off.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Off(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggles the selected LED.
|
||||
* @param Led Specifies the Led to be toggled.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Toggle(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures Button GPIO and EXTI Line.
|
||||
* @param Button: Specifies the Button to be configured.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @param ButtonMode: Specifies Button mode.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg BUTTON_MODE_GPIO: Button will be used as simple IO
|
||||
* @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
|
||||
* generation capability
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
|
||||
{
|
||||
GPIO_InitTypeDef gpioinitstruct;
|
||||
|
||||
/* Enable the BUTTON Clock */
|
||||
BUTTONx_GPIO_CLK_ENABLE(Button);
|
||||
|
||||
gpioinitstruct.Pin = BUTTON_PIN[Button];
|
||||
gpioinitstruct.Pull = GPIO_NOPULL;
|
||||
gpioinitstruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_GPIO)
|
||||
{
|
||||
/* Configure Button pin as input */
|
||||
gpioinitstruct.Mode = GPIO_MODE_INPUT;
|
||||
|
||||
HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
|
||||
}
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_EXTI)
|
||||
{
|
||||
/* Configure Button pin as input with External interrupt */
|
||||
gpioinitstruct.Mode = GPIO_MODE_IT_FALLING;
|
||||
HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
|
||||
|
||||
/* Enable and set Button EXTI Interrupt to the lowest priority */
|
||||
HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0);
|
||||
HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Push Button DeInit.
|
||||
* @param Button: Button to be configured
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @note PB DeInit does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_DeInit(Button_TypeDef Button)
|
||||
{
|
||||
GPIO_InitTypeDef gpio_init_structure;
|
||||
|
||||
gpio_init_structure.Pin = BUTTON_PIN[Button];
|
||||
HAL_NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
HAL_GPIO_DeInit(BUTTON_PORT[Button], gpio_init_structure.Pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the selected Button state.
|
||||
* @param Button: Specifies the Button to be checked.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @retval Button state.
|
||||
*/
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button)
|
||||
{
|
||||
return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
|
||||
}
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
/**
|
||||
* @brief DEBUG_USART GPIO Config,Mode Config,115200 8-N-1
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_USART_Config(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
DEBUG_USART_CLK_ENABLE();
|
||||
|
||||
DebugUartHandle.Instance = DEBUG_USART;
|
||||
|
||||
DebugUartHandle.Init.BaudRate = DEBUG_USART_BAUDRATE;
|
||||
DebugUartHandle.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
DebugUartHandle.Init.StopBits = UART_STOPBITS_1;
|
||||
DebugUartHandle.Init.Parity = UART_PARITY_NONE;
|
||||
DebugUartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
DebugUartHandle.Init.Mode = UART_MODE_TX_RX;
|
||||
DebugUartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
DebugUartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
|
||||
HAL_UART_Init(&DebugUartHandle);
|
||||
|
||||
DEBUG_USART_RX_GPIO_CLK_ENABLE();
|
||||
DEBUG_USART_TX_GPIO_CLK_ENABLE();
|
||||
|
||||
/**USART1 GPIO Configuration
|
||||
PA2 ------> USART1_TX
|
||||
PA3 ------> USART1_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = DEBUG_USART_TX_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = DEBUG_USART_TX_AF;
|
||||
HAL_GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN;
|
||||
GPIO_InitStruct.Alternate = DEBUG_USART_RX_AF;
|
||||
|
||||
HAL_GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* ENABLE NVIC */
|
||||
HAL_NVIC_SetPriority(DEBUG_USART_IRQ,0,1);
|
||||
HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ );
|
||||
}
|
||||
|
||||
#if (defined (__CC_ARM)) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get a character from the usart
|
||||
* @param *f
|
||||
* @retval a character
|
||||
*/
|
||||
int fgetc(FILE *f)
|
||||
{
|
||||
int ch;
|
||||
HAL_UART_Receive(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
return (ch);
|
||||
}
|
||||
#elif defined(__ICCARM__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* @retval the character
|
||||
*/
|
||||
int __io_putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
for (DataIdx=0;DataIdx<len;DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f002xx_Start_Kit.h
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef PY32F0XX_START_KIT_H
|
||||
#define PY32F0XX_START_KIT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_hal.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit
|
||||
* @brief This section contains the exported types, contants and functions
|
||||
* required to use the Nucleo 32 board.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit_Exported_Types Exported Types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LED3 = 0,
|
||||
LED_GREEN = LED3
|
||||
} Led_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_USER = 0,
|
||||
/* Alias */
|
||||
BUTTON_KEY = BUTTON_USER
|
||||
} Button_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_MODE_GPIO = 0,
|
||||
BUTTON_MODE_EXTI = 1
|
||||
} ButtonMode_TypeDef;
|
||||
|
||||
#define LEDn 1
|
||||
|
||||
#define LED3_PIN GPIO_PIN_5
|
||||
#define LED3_GPIO_PORT GPIOA
|
||||
#define LED3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define LED3_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
|
||||
|
||||
#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do {LED3_GPIO_CLK_ENABLE(); } while(0U)
|
||||
#define LEDx_GPIO_CLK_DISABLE(__INDEX__) LED3_GPIO_CLK_DISABLE())
|
||||
|
||||
#define BUTTONn 1
|
||||
|
||||
/**
|
||||
* @brief User push-button
|
||||
*/
|
||||
#define USER_BUTTON_PIN GPIO_PIN_2
|
||||
#define USER_BUTTON_GPIO_PORT GPIOB
|
||||
#define USER_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
|
||||
#define USER_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
|
||||
#define USER_BUTTON_EXTI_IRQn EXTI2_3_IRQn
|
||||
|
||||
/* Aliases */
|
||||
#define KEY_BUTTON_PIN USER_BUTTON_PIN
|
||||
#define KEY_BUTTON_GPIO_PORT USER_BUTTON_GPIO_PORT
|
||||
#define KEY_BUTTON_GPIO_CLK_ENABLE() USER_BUTTON_GPIO_CLK_ENABLE()
|
||||
#define KEY_BUTTON_GPIO_CLK_DISABLE() USER_BUTTON_GPIO_CLK_DISABLE()
|
||||
#define KEY_BUTTON_EXTI_IRQn USER_BUTTON_EXTI_IRQn
|
||||
|
||||
#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) USER_BUTTON_GPIO_CLK_ENABLE();} while(0)
|
||||
#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? USER_BUTTON_GPIO_CLK_DISABLE() : 0)
|
||||
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
//debug printf redirect config
|
||||
#define DEBUG_USART_BAUDRATE 115200
|
||||
|
||||
#define DEBUG_USART USART1
|
||||
#define DEBUG_USART_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->APBENR2, RCC_APBENR2_USART1EN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->APBENR2, RCC_APBENR2_USART1EN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define __GPIOA_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define DEBUG_USART_RX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define DEBUG_USART_RX_PIN GPIO_PIN_3
|
||||
#define DEBUG_USART_RX_AF GPIO_AF1_USART1
|
||||
|
||||
#define DEBUG_USART_TX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define DEBUG_USART_TX_PIN GPIO_PIN_2
|
||||
#define DEBUG_USART_TX_AF GPIO_AF1_USART1
|
||||
|
||||
#define DEBUG_USART_IRQHandler USART1_IRQHandler
|
||||
#define DEBUG_USART_IRQ USART1_IRQn
|
||||
#endif
|
||||
/************************************************************/
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
extern UART_HandleTypeDef DebugUartHandle;
|
||||
#endif
|
||||
|
||||
/** @defgroup Functions
|
||||
* @{
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void);
|
||||
|
||||
void BSP_LED_Init(Led_TypeDef Led);
|
||||
void BSP_LED_DeInit(Led_TypeDef Led);
|
||||
void BSP_LED_On(Led_TypeDef Led);
|
||||
void BSP_LED_Off(Led_TypeDef Led);
|
||||
void BSP_LED_Toggle(Led_TypeDef Led);
|
||||
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
|
||||
void BSP_PB_DeInit(Button_TypeDef Button);
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button);
|
||||
|
||||
void BSP_USART_Config(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PY32F002_START_KIT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,331 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f002xx_ll_Start_Kit.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f002xx_ll_Start_Kit.h"
|
||||
|
||||
/**
|
||||
* @brief PY32F002xx STK BSP Driver version number
|
||||
*/
|
||||
#define __PY32F002xx_STK_BSP_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||
#define __PY32F002xx_STK_BSP_VERSION_SUB1 (0x00U) /*!< [23:16] sub1 version */
|
||||
#define __PY32F002xx_STK_BSP_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
|
||||
#define __PY32F002xx_STK_BSP_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __PY32F002xx_STK_BSP_VERSION ((__PY32F002xx_STK_BSP_VERSION_MAIN << 24) \
|
||||
|(__PY32F002xx_STK_BSP_VERSION_SUB1 << 16) \
|
||||
|(__PY32F002xx_STK_BSP_VERSION_SUB2 << 8 ) \
|
||||
|(__PY32F002xx_STK_BSP_VERSION_RC))
|
||||
|
||||
GPIO_TypeDef* LED_PORT[LEDn] = {LED3_GPIO_PORT};
|
||||
const uint16_t LED_PIN[LEDn] = {LED3_PIN};
|
||||
|
||||
GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT };
|
||||
const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN };
|
||||
const uint8_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn };
|
||||
const uint32_t BUTTON_EXTI_LINE[BUTTONn] = {USER_BUTTON_EXTI_LINE };
|
||||
|
||||
/** @addtogroup PY32F002xx_STK_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This method returns the PY32F002 STK BSP Driver revision.
|
||||
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void)
|
||||
{
|
||||
return __PY32F002xx_STK_BSP_VERSION;
|
||||
}
|
||||
|
||||
/** @addtogroup LED_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configures LED GPIO.
|
||||
* @param Led Specifies the Led to be configured.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Init(Led_TypeDef Led)
|
||||
{
|
||||
/* Enable the GPIO_LED Clock */
|
||||
LEDx_GPIO_CLK_ENABLE(Led);
|
||||
|
||||
/* Configure the GPIO_LED pin */
|
||||
LL_GPIO_SetPinMode(LED_PORT[Led], LED_PIN[Led], LL_GPIO_MODE_OUTPUT);
|
||||
/* LL_GPIO_SetPinOutputType(LED_PORT[Led], LED_PIN[Led], LL_GPIO_OUTPUT_PUSHPULL); */
|
||||
/* LL_GPIO_SetPinSpeed(LED_PORT[Led], LED_PIN[Led], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(LED_PORT[Led], LED_PIN[Led], LL_GPIO_PULL_NO); */
|
||||
|
||||
LL_GPIO_SetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize LED GPIO.
|
||||
* @param Led Specifies the Led to be deconfigured.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg LED3
|
||||
* @note BSP_LED_DeInit() does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_DeInit(Led_TypeDef Led)
|
||||
{
|
||||
/* Turn off LED */
|
||||
LL_GPIO_ResetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
/* DeInit the GPIO_LED pin */
|
||||
LL_GPIO_SetPinMode(LED_PORT[Led], LED_PIN[Led], LL_GPIO_MODE_ANALOG);
|
||||
/* LL_GPIO_SetPinOutputType(LED_PORT[Led], LED_PIN[Led], LL_GPIO_OUTPUT_PUSHPULL); */
|
||||
/* LL_GPIO_SetPinSpeed(LED_PORT[Led], LED_PIN[Led], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(LED_PORT[Led], LED_PIN[Led], LL_GPIO_PULL_NO); */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED On.
|
||||
* @param Led Specifies the Led to be set on.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_On(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_ResetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED Off.
|
||||
* @param Led Specifies the Led to be set off.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Off(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_SetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggles the selected LED.
|
||||
* @param Led Specifies the Led to be toggled.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Toggle(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures Button GPIO and EXTI Line.
|
||||
* @param Button: Specifies the Button to be configured.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @param ButtonMode: Specifies Button mode.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg BUTTON_MODE_GPIO: Button will be used as simple IO
|
||||
* @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
|
||||
* generation capability
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
|
||||
{
|
||||
/* Enable the BUTTON Clock */
|
||||
BUTTONx_GPIO_CLK_ENABLE(Button);
|
||||
|
||||
/* Configure GPIO for BUTTON */
|
||||
LL_GPIO_SetPinMode(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_MODE_INPUT);
|
||||
LL_GPIO_SetPinPull(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_PULL_NO);
|
||||
/* LL_GPIO_SetPinSpeed(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_SPEED_FREQ_HIGH); */
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_EXTI)
|
||||
{
|
||||
/* Configure Button pin as input with External interrupt */
|
||||
LL_EXTI_EnableIT(BUTTON_EXTI_LINE[Button]);
|
||||
LL_EXTI_EnableFallingTrig(BUTTON_EXTI_LINE[Button]);
|
||||
|
||||
/* Enable and set Button EXTI Interrupt to the lowest priority */
|
||||
NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F);
|
||||
NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Push Button DeInit.
|
||||
* @param Button: Button to be configured
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @note PB DeInit does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_DeInit(Button_TypeDef Button)
|
||||
{
|
||||
NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
LL_GPIO_SetPinMode(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_MODE_ANALOG);
|
||||
/* LL_GPIO_SetPinSpeed(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_PULL_NO); */
|
||||
/* LL_GPIO_SetAFPin_8_15(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_AF_0); */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the selected Button state.
|
||||
* @param Button: Specifies the Button to be checked.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @retval Button state.
|
||||
*/
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button)
|
||||
{
|
||||
return LL_GPIO_IsInputPinSet(BUTTON_PORT[Button], BUTTON_PIN[Button]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DEBUG_USART GPIO Config,Mode Config,115200 8-N-1
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_USART_Config(void)
|
||||
{
|
||||
DEBUG_USART_CLK_ENABLE();
|
||||
|
||||
/* USART Init */
|
||||
LL_USART_SetBaudRate(DEBUG_USART, SystemCoreClock, LL_USART_OVERSAMPLING_16, DEBUG_USART_BAUDRATE);
|
||||
LL_USART_SetDataWidth(DEBUG_USART, LL_USART_DATAWIDTH_8B);
|
||||
LL_USART_SetStopBitsLength(DEBUG_USART, LL_USART_STOPBITS_1);
|
||||
LL_USART_SetParity(DEBUG_USART, LL_USART_PARITY_NONE);
|
||||
LL_USART_SetHWFlowCtrl(DEBUG_USART, LL_USART_HWCONTROL_NONE);
|
||||
LL_USART_SetTransferDirection(DEBUG_USART, LL_USART_DIRECTION_TX_RX);
|
||||
LL_USART_Enable(DEBUG_USART);
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
/**USART GPIO Configuration
|
||||
PA2 ------> USART1_TX
|
||||
PA3 ------> USART1_RX
|
||||
*/
|
||||
DEBUG_USART_RX_GPIO_CLK_ENABLE();
|
||||
DEBUG_USART_TX_GPIO_CLK_ENABLE();
|
||||
|
||||
LL_GPIO_SetPinMode(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetPinSpeed(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
|
||||
LL_GPIO_SetPinPull(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_PULL_UP);
|
||||
LL_GPIO_SetAFPin_0_7(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, DEBUG_USART_TX_AF);
|
||||
|
||||
LL_GPIO_SetPinMode(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetPinSpeed(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
|
||||
LL_GPIO_SetPinPull(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_PULL_UP);
|
||||
LL_GPIO_SetAFPin_0_7(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, DEBUG_USART_RX_AF);
|
||||
}
|
||||
|
||||
#if (defined (__CC_ARM)) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get a character from the usart
|
||||
* @param *f
|
||||
* @retval a character
|
||||
*/
|
||||
int fgetc(FILE *f)
|
||||
{
|
||||
int ch;
|
||||
while (!LL_USART_IsActiveFlag_RXNE(DEBUG_USART));
|
||||
ch = LL_USART_ReceiveData8(DEBUG_USART);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* @retval the character
|
||||
*/
|
||||
int __io_putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
return ch;
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
for (DataIdx=0;DataIdx<len;DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f002xx_ll_Start_Kit.h
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef PY32F0XX_LL_START_KIT_H
|
||||
#define PY32F0XX_LL_START_KIT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include "py32f0xx_ll_rcc.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
#include "py32f0xx_ll_system.h"
|
||||
#include "py32f0xx_ll_exti.h"
|
||||
#include "py32f0xx_ll_cortex.h"
|
||||
#include "py32f0xx_ll_utils.h"
|
||||
#include "py32f0xx_ll_pwr.h"
|
||||
#include "py32f0xx_ll_gpio.h"
|
||||
#include "py32f0xx_ll_usart.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit
|
||||
* @brief This section contains the exported types, contants and functions
|
||||
* required to use the Nucleo 32 board.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit_Exported_Types Exported Types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LED3 = 0,
|
||||
LED_GREEN = LED3
|
||||
} Led_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_USER = 0,
|
||||
/* Alias */
|
||||
BUTTON_KEY = BUTTON_USER
|
||||
} Button_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_MODE_GPIO = 0,
|
||||
BUTTON_MODE_EXTI = 1
|
||||
} ButtonMode_TypeDef;
|
||||
|
||||
#define LEDn 1
|
||||
|
||||
#define LED3_PIN LL_GPIO_PIN_5
|
||||
#define LED3_GPIO_PORT GPIOA
|
||||
#define LED3_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define LED3_GPIO_CLK_DISABLE() LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
|
||||
#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do {LED3_GPIO_CLK_ENABLE(); } while(0U)
|
||||
#define LEDx_GPIO_CLK_DISABLE(__INDEX__) LED3_GPIO_CLK_DISABLE())
|
||||
|
||||
#define BUTTONn 1
|
||||
|
||||
/**
|
||||
* @brief User push-button
|
||||
*/
|
||||
#define USER_BUTTON_PIN LL_GPIO_PIN_2
|
||||
#define USER_BUTTON_GPIO_PORT GPIOB
|
||||
#define USER_BUTTON_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB)
|
||||
#define USER_BUTTON_GPIO_CLK_DISABLE() LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOB)
|
||||
#define USER_BUTTON_EXTI_IRQn EXTI2_3_IRQn
|
||||
#define USER_BUTTON_EXTI_LINE LL_EXTI_LINE_2
|
||||
#define USER_BUTTON_EXTI_LINE_ENABLE() LL_EXTI_EnableIT(USER_BUTTON_EXTI_LINE)
|
||||
#define USER_BUTTON_EXTI_FALLING_TRIG_ENABLE() LL_EXTI_EnableFallingTrig(USER_BUTTON_EXTI_LINE)
|
||||
#define USER_BUTTON_IRQHANDLER EXTI2_3_IRQHandler
|
||||
|
||||
/* Aliases */
|
||||
#define KEY_BUTTON_PIN USER_BUTTON_PIN
|
||||
#define KEY_BUTTON_GPIO_PORT USER_BUTTON_GPIO_PORT
|
||||
#define KEY_BUTTON_GPIO_CLK_ENABLE() USER_BUTTON_GPIO_CLK_ENABLE()
|
||||
#define KEY_BUTTON_GPIO_CLK_DISABLE() USER_BUTTON_GPIO_CLK_DISABLE()
|
||||
#define KEY_BUTTON_EXTI_IRQn USER_BUTTON_EXTI_IRQn
|
||||
|
||||
#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) USER_BUTTON_GPIO_CLK_ENABLE();} while(0)
|
||||
#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? USER_BUTTON_GPIO_CLK_DISABLE() : 0)
|
||||
|
||||
|
||||
//debug printf redirect config
|
||||
#define DEBUG_USART_BAUDRATE 115200
|
||||
|
||||
#define DEBUG_USART USART1
|
||||
#define DEBUG_USART_CLK_ENABLE() LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_USART1)
|
||||
|
||||
#define __GPIOA_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define DEBUG_USART_RX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_RX_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define DEBUG_USART_RX_PIN LL_GPIO_PIN_3
|
||||
#define DEBUG_USART_RX_AF LL_GPIO_AF_1
|
||||
|
||||
#define DEBUG_USART_TX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_TX_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define DEBUG_USART_TX_PIN LL_GPIO_PIN_2
|
||||
#define DEBUG_USART_TX_AF LL_GPIO_AF_1
|
||||
|
||||
#define DEBUG_USART_IRQHandler USART1_IRQHandler
|
||||
#define DEBUG_USART_IRQ USART1_IRQn
|
||||
/************************************************************/
|
||||
|
||||
/** @defgroup Functions
|
||||
* @{
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void);
|
||||
|
||||
void BSP_LED_Init(Led_TypeDef Led);
|
||||
void BSP_LED_DeInit(Led_TypeDef Led);
|
||||
void BSP_LED_On(Led_TypeDef Led);
|
||||
void BSP_LED_Off(Led_TypeDef Led);
|
||||
void BSP_LED_Toggle(Led_TypeDef Led);
|
||||
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
|
||||
void BSP_PB_DeInit(Button_TypeDef Button);
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button);
|
||||
|
||||
void BSP_USART_Config(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PY32F002XX_LL_START_KIT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,350 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f003xx_Start_Kit.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f003xx_Start_Kit.h"
|
||||
|
||||
/**
|
||||
* @brief PY32F003xx STK BSP Driver version number
|
||||
*/
|
||||
#define __PY32F003xx_STK_BSP_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||
#define __PY32F003xx_STK_BSP_VERSION_SUB1 (0x00U) /*!< [23:16] sub1 version */
|
||||
#define __PY32F003xx_STK_BSP_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
|
||||
#define __PY32F003xx_STK_BSP_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __PY32F003xx_STK_BSP_VERSION ((__PY32F003xx_STK_BSP_VERSION_MAIN << 24) \
|
||||
|(__PY32F003xx_STK_BSP_VERSION_SUB1 << 16) \
|
||||
|(__PY32F003xx_STK_BSP_VERSION_SUB2 << 8 ) \
|
||||
|(__PY32F003xx_STK_BSP_VERSION_RC))
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
UART_HandleTypeDef DebugUartHandle;
|
||||
#endif
|
||||
GPIO_TypeDef* LED_PORT[LEDn] = {LED3_GPIO_PORT};
|
||||
const uint16_t LED_PIN[LEDn] = {LED3_PIN};
|
||||
|
||||
GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT };
|
||||
const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN };
|
||||
const uint8_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn };
|
||||
|
||||
/** @addtogroup PY32F003xx_STK_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This method returns the PY32F030 STK BSP Driver revision.
|
||||
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void)
|
||||
{
|
||||
return __PY32F003xx_STK_BSP_VERSION;
|
||||
}
|
||||
|
||||
/** @addtogroup LED_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configures LED GPIO.
|
||||
* @param Led Specifies the Led to be configured.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Init(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
/* Enable the GPIO_LED Clock */
|
||||
LEDx_GPIO_CLK_ENABLE(Led);
|
||||
|
||||
/* Configure the GPIO_LED pin */
|
||||
GPIO_InitStruct.Pin = LED_PIN[Led];
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
|
||||
HAL_GPIO_Init(LED_PORT[Led], &GPIO_InitStruct);
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize LED GPIO.
|
||||
* @param Led Specifies the Led to be deconfigured.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg LED3
|
||||
* @note BSP_LED_DeInit() does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_DeInit(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
/* Turn off LED */
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
|
||||
/* DeInit the GPIO_LED pin */
|
||||
GPIO_InitStruct.Pin = LED_PIN[Led];
|
||||
HAL_GPIO_DeInit(LED_PORT[Led], GPIO_InitStruct.Pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED On.
|
||||
* @param Led Specifies the Led to be set on.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_On(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED Off.
|
||||
* @param Led Specifies the Led to be set off.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Off(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggles the selected LED.
|
||||
* @param Led Specifies the Led to be toggled.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Toggle(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures Button GPIO and EXTI Line.
|
||||
* @param Button: Specifies the Button to be configured.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @param ButtonMode: Specifies Button mode.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg BUTTON_MODE_GPIO: Button will be used as simple IO
|
||||
* @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
|
||||
* generation capability
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
|
||||
{
|
||||
GPIO_InitTypeDef gpioinitstruct;
|
||||
|
||||
/* Enable the BUTTON Clock */
|
||||
BUTTONx_GPIO_CLK_ENABLE(Button);
|
||||
|
||||
gpioinitstruct.Pin = BUTTON_PIN[Button];
|
||||
gpioinitstruct.Pull = GPIO_NOPULL;
|
||||
gpioinitstruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_GPIO)
|
||||
{
|
||||
/* Configure Button pin as input */
|
||||
gpioinitstruct.Mode = GPIO_MODE_INPUT;
|
||||
|
||||
HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
|
||||
}
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_EXTI)
|
||||
{
|
||||
/* Configure Button pin as input with External interrupt */
|
||||
gpioinitstruct.Mode = GPIO_MODE_IT_FALLING;
|
||||
HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
|
||||
|
||||
/* Enable and set Button EXTI Interrupt to the lowest priority */
|
||||
HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0);
|
||||
HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Push Button DeInit.
|
||||
* @param Button: Button to be configured
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @note PB DeInit does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_DeInit(Button_TypeDef Button)
|
||||
{
|
||||
GPIO_InitTypeDef gpio_init_structure;
|
||||
|
||||
gpio_init_structure.Pin = BUTTON_PIN[Button];
|
||||
HAL_NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
HAL_GPIO_DeInit(BUTTON_PORT[Button], gpio_init_structure.Pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the selected Button state.
|
||||
* @param Button: Specifies the Button to be checked.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @retval Button state.
|
||||
*/
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button)
|
||||
{
|
||||
return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
|
||||
}
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
/**
|
||||
* @brief DEBUG_USART GPIO Config,Mode Config,115200 8-N-1
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_USART_Config(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
DEBUG_USART_CLK_ENABLE();
|
||||
|
||||
DebugUartHandle.Instance = DEBUG_USART;
|
||||
|
||||
DebugUartHandle.Init.BaudRate = DEBUG_USART_BAUDRATE;
|
||||
DebugUartHandle.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
DebugUartHandle.Init.StopBits = UART_STOPBITS_1;
|
||||
DebugUartHandle.Init.Parity = UART_PARITY_NONE;
|
||||
DebugUartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
DebugUartHandle.Init.Mode = UART_MODE_TX_RX;
|
||||
DebugUartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
DebugUartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
|
||||
HAL_UART_Init(&DebugUartHandle);
|
||||
|
||||
DEBUG_USART_RX_GPIO_CLK_ENABLE();
|
||||
DEBUG_USART_TX_GPIO_CLK_ENABLE();
|
||||
|
||||
/**USART1 GPIO Configuration
|
||||
PA2 ------> USART2_TX
|
||||
PA3 ------> USART2_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = DEBUG_USART_TX_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = DEBUG_USART_TX_AF;
|
||||
HAL_GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN;
|
||||
GPIO_InitStruct.Alternate = DEBUG_USART_RX_AF;
|
||||
|
||||
HAL_GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* ENABLE NVIC */
|
||||
HAL_NVIC_SetPriority(DEBUG_USART_IRQ,0,1);
|
||||
HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ );
|
||||
}
|
||||
|
||||
#if (defined (__CC_ARM)) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get a character from the usart
|
||||
* @param *f
|
||||
* @retval a character
|
||||
*/
|
||||
int fgetc(FILE *f)
|
||||
{
|
||||
int ch;
|
||||
HAL_UART_Receive(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* @retval the character
|
||||
*/
|
||||
int __io_putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
for (DataIdx=0;DataIdx<len;DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f003xx_Start_Kit.h
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef PY32F003_START_KIT_H
|
||||
#define PY32F003_START_KIT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_hal.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit
|
||||
* @brief This section contains the exported types, contants and functions
|
||||
* required to use the Nucleo 32 board.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit_Exported_Types Exported Types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LED3 = 0,
|
||||
LED_GREEN = LED3
|
||||
} Led_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_USER = 0,
|
||||
/* Alias */
|
||||
BUTTON_KEY = BUTTON_USER
|
||||
} Button_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_MODE_GPIO = 0,
|
||||
BUTTON_MODE_EXTI = 1
|
||||
} ButtonMode_TypeDef;
|
||||
|
||||
#define LEDn 1
|
||||
|
||||
#define LED3_PIN GPIO_PIN_5
|
||||
#define LED3_GPIO_PORT GPIOB
|
||||
#define LED3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
|
||||
#define LED3_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
|
||||
|
||||
#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do {LED3_GPIO_CLK_ENABLE(); } while(0U)
|
||||
#define LEDx_GPIO_CLK_DISABLE(__INDEX__) LED3_GPIO_CLK_DISABLE())
|
||||
|
||||
#define BUTTONn 1
|
||||
|
||||
/**
|
||||
* @brief User push-button
|
||||
*/
|
||||
#define USER_BUTTON_PIN GPIO_PIN_12
|
||||
#define USER_BUTTON_GPIO_PORT GPIOA
|
||||
#define USER_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define USER_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
|
||||
#define USER_BUTTON_EXTI_IRQn EXTI4_15_IRQn
|
||||
|
||||
/* Aliases */
|
||||
#define KEY_BUTTON_PIN USER_BUTTON_PIN
|
||||
#define KEY_BUTTON_GPIO_PORT USER_BUTTON_GPIO_PORT
|
||||
#define KEY_BUTTON_GPIO_CLK_ENABLE() USER_BUTTON_GPIO_CLK_ENABLE()
|
||||
#define KEY_BUTTON_GPIO_CLK_DISABLE() USER_BUTTON_GPIO_CLK_DISABLE()
|
||||
#define KEY_BUTTON_EXTI_IRQn USER_BUTTON_EXTI_IRQn
|
||||
|
||||
#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) USER_BUTTON_GPIO_CLK_ENABLE();} while(0)
|
||||
#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? USER_BUTTON_GPIO_CLK_DISABLE() : 0)
|
||||
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
//debug printf redirect config
|
||||
#define DEBUG_USART_BAUDRATE 115200
|
||||
|
||||
#define DEBUG_USART USART2
|
||||
#define DEBUG_USART_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->APBENR1, RCC_APBENR1_USART2EN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->APBENR1, RCC_APBENR1_USART2EN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define __GPIOA_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define DEBUG_USART_RX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define DEBUG_USART_RX_PIN GPIO_PIN_3
|
||||
#define DEBUG_USART_RX_AF GPIO_AF4_USART2
|
||||
|
||||
#define DEBUG_USART_TX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define DEBUG_USART_TX_PIN GPIO_PIN_2
|
||||
#define DEBUG_USART_TX_AF GPIO_AF4_USART2
|
||||
|
||||
#define DEBUG_USART_IRQHandler USART2_IRQHandler
|
||||
#define DEBUG_USART_IRQ USART2_IRQn
|
||||
#endif
|
||||
/************************************************************/
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
extern UART_HandleTypeDef DebugUartHandle;
|
||||
#endif
|
||||
|
||||
/** @defgroup Functions
|
||||
* @{
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void);
|
||||
|
||||
void BSP_LED_Init(Led_TypeDef Led);
|
||||
void BSP_LED_DeInit(Led_TypeDef Led);
|
||||
void BSP_LED_On(Led_TypeDef Led);
|
||||
void BSP_LED_Off(Led_TypeDef Led);
|
||||
void BSP_LED_Toggle(Led_TypeDef Led);
|
||||
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
|
||||
void BSP_PB_DeInit(Button_TypeDef Button);
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button);
|
||||
|
||||
void BSP_USART_Config(void);
|
||||
#define DEBUG_USART_Config BSP_USART_Config
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PY32F003_START_KIT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,331 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f003xx_ll_Start_Kit.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f003xx_ll_Start_Kit.h"
|
||||
|
||||
/**
|
||||
* @brief PY32F003xx STK BSP Driver version number
|
||||
*/
|
||||
#define __PY32F003xx_STK_BSP_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||
#define __PY32F003xx_STK_BSP_VERSION_SUB1 (0x00U) /*!< [23:16] sub1 version */
|
||||
#define __PY32F003xx_STK_BSP_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
|
||||
#define __PY32F003xx_STK_BSP_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __PY32F003xx_STK_BSP_VERSION ((__PY32F003xx_STK_BSP_VERSION_MAIN << 24) \
|
||||
|(__PY32F003xx_STK_BSP_VERSION_SUB1 << 16) \
|
||||
|(__PY32F003xx_STK_BSP_VERSION_SUB2 << 8 ) \
|
||||
|(__PY32F003xx_STK_BSP_VERSION_RC))
|
||||
|
||||
GPIO_TypeDef* LED_PORT[LEDn] = {LED3_GPIO_PORT};
|
||||
const uint16_t LED_PIN[LEDn] = {LED3_PIN};
|
||||
|
||||
GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT };
|
||||
const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN };
|
||||
const uint8_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn };
|
||||
const uint32_t BUTTON_EXTI_LINE[BUTTONn] = {USER_BUTTON_EXTI_LINE };
|
||||
|
||||
/** @addtogroup PY32F003xx_STK_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This method returns the PY32F003 STK BSP Driver revision.
|
||||
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void)
|
||||
{
|
||||
return __PY32F003xx_STK_BSP_VERSION;
|
||||
}
|
||||
|
||||
/** @addtogroup LED_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configures LED GPIO.
|
||||
* @param Led Specifies the Led to be configured.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Init(Led_TypeDef Led)
|
||||
{
|
||||
/* Enable the GPIO_LED Clock */
|
||||
LEDx_GPIO_CLK_ENABLE(Led);
|
||||
|
||||
/* Configure the GPIO_LED pin */
|
||||
LL_GPIO_SetPinMode(LED_PORT[Led], LED_PIN[Led], LL_GPIO_MODE_OUTPUT);
|
||||
/* LL_GPIO_SetPinOutputType(LED_PORT[Led], LED_PIN[Led], LL_GPIO_OUTPUT_PUSHPULL); */
|
||||
/* LL_GPIO_SetPinSpeed(LED_PORT[Led], LED_PIN[Led], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(LED_PORT[Led], LED_PIN[Led], LL_GPIO_PULL_NO); */
|
||||
|
||||
LL_GPIO_SetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize LED GPIO.
|
||||
* @param Led Specifies the Led to be deconfigured.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg LED3
|
||||
* @note BSP_LED_DeInit() does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_DeInit(Led_TypeDef Led)
|
||||
{
|
||||
/* Turn off LED */
|
||||
LL_GPIO_ResetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
/* DeInit the GPIO_LED pin */
|
||||
LL_GPIO_SetPinMode(LED_PORT[Led], LED_PIN[Led], LL_GPIO_MODE_ANALOG);
|
||||
/* LL_GPIO_SetPinOutputType(LED_PORT[Led], LED_PIN[Led], LL_GPIO_OUTPUT_PUSHPULL); */
|
||||
/* LL_GPIO_SetPinSpeed(LED_PORT[Led], LED_PIN[Led], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(LED_PORT[Led], LED_PIN[Led], LL_GPIO_PULL_NO); */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED On.
|
||||
* @param Led Specifies the Led to be set on.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_On(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_ResetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED Off.
|
||||
* @param Led Specifies the Led to be set off.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Off(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_SetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggles the selected LED.
|
||||
* @param Led Specifies the Led to be toggled.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Toggle(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures Button GPIO and EXTI Line.
|
||||
* @param Button: Specifies the Button to be configured.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @param ButtonMode: Specifies Button mode.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg BUTTON_MODE_GPIO: Button will be used as simple IO
|
||||
* @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
|
||||
* generation capability
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
|
||||
{
|
||||
/* Enable the BUTTON Clock */
|
||||
BUTTONx_GPIO_CLK_ENABLE(Button);
|
||||
|
||||
/* Configure GPIO for BUTTON */
|
||||
LL_GPIO_SetPinMode(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_MODE_INPUT);
|
||||
LL_GPIO_SetPinPull(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_PULL_NO);
|
||||
/* LL_GPIO_SetPinSpeed(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_SPEED_FREQ_HIGH); */
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_EXTI)
|
||||
{
|
||||
/* Configure Button pin as input with External interrupt */
|
||||
LL_EXTI_EnableIT(BUTTON_EXTI_LINE[Button]);
|
||||
LL_EXTI_EnableFallingTrig(BUTTON_EXTI_LINE[Button]);
|
||||
|
||||
/* Enable and set Button EXTI Interrupt to the lowest priority */
|
||||
NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F);
|
||||
NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Push Button DeInit.
|
||||
* @param Button: Button to be configured
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @note PB DeInit does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_DeInit(Button_TypeDef Button)
|
||||
{
|
||||
NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
LL_GPIO_SetPinMode(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_MODE_ANALOG);
|
||||
/* LL_GPIO_SetPinSpeed(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_PULL_NO); */
|
||||
/* LL_GPIO_SetAFPin_8_15(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_AF_0); */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the selected Button state.
|
||||
* @param Button: Specifies the Button to be checked.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @retval Button state.
|
||||
*/
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button)
|
||||
{
|
||||
return LL_GPIO_IsInputPinSet(BUTTON_PORT[Button], BUTTON_PIN[Button]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DEBUG_USART GPIO Config,Mode Config,115200 8-N-1
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_USART_Config(void)
|
||||
{
|
||||
DEBUG_USART_CLK_ENABLE();
|
||||
|
||||
/* USART Init */
|
||||
LL_USART_SetBaudRate(DEBUG_USART, SystemCoreClock, LL_USART_OVERSAMPLING_16, DEBUG_USART_BAUDRATE);
|
||||
LL_USART_SetDataWidth(DEBUG_USART, LL_USART_DATAWIDTH_8B);
|
||||
LL_USART_SetStopBitsLength(DEBUG_USART, LL_USART_STOPBITS_1);
|
||||
LL_USART_SetParity(DEBUG_USART, LL_USART_PARITY_NONE);
|
||||
LL_USART_SetHWFlowCtrl(DEBUG_USART, LL_USART_HWCONTROL_NONE);
|
||||
LL_USART_SetTransferDirection(DEBUG_USART, LL_USART_DIRECTION_TX_RX);
|
||||
LL_USART_Enable(DEBUG_USART);
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
/**USART GPIO Configuration
|
||||
PA2 ------> USART1_TX
|
||||
PA3 ------> USART1_RX
|
||||
*/
|
||||
DEBUG_USART_RX_GPIO_CLK_ENABLE();
|
||||
DEBUG_USART_TX_GPIO_CLK_ENABLE();
|
||||
|
||||
LL_GPIO_SetPinMode(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetPinSpeed(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
|
||||
LL_GPIO_SetPinPull(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_PULL_UP);
|
||||
LL_GPIO_SetAFPin_0_7(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, DEBUG_USART_TX_AF);
|
||||
|
||||
LL_GPIO_SetPinMode(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetPinSpeed(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
|
||||
LL_GPIO_SetPinPull(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_PULL_UP);
|
||||
LL_GPIO_SetAFPin_0_7(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, DEBUG_USART_RX_AF);
|
||||
}
|
||||
|
||||
#if (defined (__CC_ARM)) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get a character from the usart
|
||||
* @param *f
|
||||
* @retval a character
|
||||
*/
|
||||
int fgetc(FILE *f)
|
||||
{
|
||||
int ch;
|
||||
while (!LL_USART_IsActiveFlag_RXNE(DEBUG_USART));
|
||||
ch = LL_USART_ReceiveData8(DEBUG_USART);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* @retval the character
|
||||
*/
|
||||
int __io_putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
return ch;
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
for (DataIdx=0;DataIdx<len;DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f003xx_ll_Start_Kit.h
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef PY32F0XX_LL_START_KIT_H
|
||||
#define PY32F0XX_LL_START_KIT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include "py32f0xx_ll_rcc.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
#include "py32f0xx_ll_system.h"
|
||||
#include "py32f0xx_ll_exti.h"
|
||||
#include "py32f0xx_ll_cortex.h"
|
||||
#include "py32f0xx_ll_utils.h"
|
||||
#include "py32f0xx_ll_pwr.h"
|
||||
#include "py32f0xx_ll_dma.h"
|
||||
#include "py32f0xx_ll_gpio.h"
|
||||
#include "py32f0xx_ll_usart.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit
|
||||
* @brief This section contains the exported types, contants and functions
|
||||
* required to use the Nucleo 32 board.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit_Exported_Types Exported Types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LED3 = 0,
|
||||
LED_GREEN = LED3
|
||||
} Led_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_USER = 0,
|
||||
/* Alias */
|
||||
BUTTON_KEY = BUTTON_USER
|
||||
} Button_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_MODE_GPIO = 0,
|
||||
BUTTON_MODE_EXTI = 1
|
||||
} ButtonMode_TypeDef;
|
||||
|
||||
#define LEDn 1
|
||||
|
||||
#define LED3_PIN LL_GPIO_PIN_5
|
||||
#define LED3_GPIO_PORT GPIOB
|
||||
#define LED3_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB)
|
||||
#define LED3_GPIO_CLK_DISABLE() LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOB)
|
||||
|
||||
#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do {LED3_GPIO_CLK_ENABLE(); } while(0U)
|
||||
#define LEDx_GPIO_CLK_DISABLE(__INDEX__) LED3_GPIO_CLK_DISABLE())
|
||||
|
||||
#define BUTTONn 1
|
||||
|
||||
/**
|
||||
* @brief User push-button
|
||||
*/
|
||||
#define USER_BUTTON_PIN LL_GPIO_PIN_12
|
||||
#define USER_BUTTON_GPIO_PORT GPIOA
|
||||
#define USER_BUTTON_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define USER_BUTTON_GPIO_CLK_DISABLE() LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define USER_BUTTON_EXTI_IRQn EXTI4_15_IRQn
|
||||
#define USER_BUTTON_EXTI_LINE LL_EXTI_LINE_12
|
||||
#define USER_BUTTON_EXTI_LINE_ENABLE() LL_EXTI_EnableIT(USER_BUTTON_EXTI_LINE)
|
||||
#define USER_BUTTON_EXTI_FALLING_TRIG_ENABLE() LL_EXTI_EnableFallingTrig(USER_BUTTON_EXTI_LINE)
|
||||
#define USER_BUTTON_IRQHANDLER EXTI4_15_IRQHandler
|
||||
|
||||
/* Aliases */
|
||||
#define KEY_BUTTON_PIN USER_BUTTON_PIN
|
||||
#define KEY_BUTTON_GPIO_PORT USER_BUTTON_GPIO_PORT
|
||||
#define KEY_BUTTON_GPIO_CLK_ENABLE() USER_BUTTON_GPIO_CLK_ENABLE()
|
||||
#define KEY_BUTTON_GPIO_CLK_DISABLE() USER_BUTTON_GPIO_CLK_DISABLE()
|
||||
#define KEY_BUTTON_EXTI_IRQn USER_BUTTON_EXTI_IRQn
|
||||
|
||||
#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) USER_BUTTON_GPIO_CLK_ENABLE();} while(0)
|
||||
#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? USER_BUTTON_GPIO_CLK_DISABLE() : 0)
|
||||
|
||||
|
||||
//debug printf redirect config
|
||||
#define DEBUG_USART_BAUDRATE 115200
|
||||
|
||||
#define DEBUG_USART USART2
|
||||
#define DEBUG_USART_CLK_ENABLE() LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2)
|
||||
|
||||
#define __GPIOA_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define DEBUG_USART_RX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_RX_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define DEBUG_USART_RX_PIN LL_GPIO_PIN_3
|
||||
#define DEBUG_USART_RX_AF LL_GPIO_AF_4
|
||||
|
||||
#define DEBUG_USART_TX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_TX_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define DEBUG_USART_TX_PIN LL_GPIO_PIN_2
|
||||
#define DEBUG_USART_TX_AF LL_GPIO_AF_4
|
||||
|
||||
#define DEBUG_USART_IRQHandler USART2_IRQHandler
|
||||
#define DEBUG_USART_IRQ USART2_IRQn
|
||||
/************************************************************/
|
||||
|
||||
/** @defgroup Functions
|
||||
* @{
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void);
|
||||
|
||||
void BSP_LED_Init(Led_TypeDef Led);
|
||||
void BSP_LED_DeInit(Led_TypeDef Led);
|
||||
void BSP_LED_On(Led_TypeDef Led);
|
||||
void BSP_LED_Off(Led_TypeDef Led);
|
||||
void BSP_LED_Toggle(Led_TypeDef Led);
|
||||
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
|
||||
void BSP_PB_DeInit(Button_TypeDef Button);
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button);
|
||||
|
||||
void BSP_USART_Config(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PY32F003XX_LL_START_KIT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,354 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f030xx_Start_Kit.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f030xx_Start_Kit.h"
|
||||
|
||||
/**
|
||||
* @brief PY32F030xx STK BSP Driver version number
|
||||
*/
|
||||
#define __PY32F030xx_STK_BSP_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||
#define __PY32F030xx_STK_BSP_VERSION_SUB1 (0x00U) /*!< [23:16] sub1 version */
|
||||
#define __PY32F030xx_STK_BSP_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
|
||||
#define __PY32F030xx_STK_BSP_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __PY32F030xx_STK_BSP_VERSION ((__PY32F030xx_STK_BSP_VERSION_MAIN << 24) \
|
||||
|(__PY32F030xx_STK_BSP_VERSION_SUB1 << 16) \
|
||||
|(__PY32F030xx_STK_BSP_VERSION_SUB2 << 8 ) \
|
||||
|(__PY32F030xx_STK_BSP_VERSION_RC))
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
UART_HandleTypeDef DebugUartHandle;
|
||||
#endif
|
||||
GPIO_TypeDef* LED_PORT[LEDn] = {LED3_GPIO_PORT};
|
||||
const uint16_t LED_PIN[LEDn] = {LED3_PIN};
|
||||
|
||||
GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT };
|
||||
const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN };
|
||||
const uint8_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn };
|
||||
|
||||
/** @addtogroup PY32F030xx_STK_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This method returns the PY32F030 STK BSP Driver revision.
|
||||
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void)
|
||||
{
|
||||
return __PY32F030xx_STK_BSP_VERSION;
|
||||
}
|
||||
|
||||
/** @addtogroup LED_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configures LED GPIO.
|
||||
* @param Led Specifies the Led to be configured.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Init(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
/* Enable the GPIO_LED Clock */
|
||||
LEDx_GPIO_CLK_ENABLE(Led);
|
||||
|
||||
/* Configure the GPIO_LED pin */
|
||||
GPIO_InitStruct.Pin = LED_PIN[Led];
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
|
||||
HAL_GPIO_Init(LED_PORT[Led], &GPIO_InitStruct);
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize LED GPIO.
|
||||
* @param Led Specifies the Led to be deconfigured.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg LED3
|
||||
* @note BSP_LED_DeInit() does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_DeInit(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
/* Turn off LED */
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
|
||||
/* DeInit the GPIO_LED pin */
|
||||
GPIO_InitStruct.Pin = LED_PIN[Led];
|
||||
HAL_GPIO_DeInit(LED_PORT[Led], GPIO_InitStruct.Pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED On.
|
||||
* @param Led Specifies the Led to be set on.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_On(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED Off.
|
||||
* @param Led Specifies the Led to be set off.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Off(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggles the selected LED.
|
||||
* @param Led Specifies the Led to be toggled.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Toggle(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures Button GPIO and EXTI Line.
|
||||
* @param Button: Specifies the Button to be configured.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @param ButtonMode: Specifies Button mode.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg BUTTON_MODE_GPIO: Button will be used as simple IO
|
||||
* @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
|
||||
* generation capability
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
|
||||
{
|
||||
GPIO_InitTypeDef gpioinitstruct;
|
||||
|
||||
/* Enable the BUTTON Clock */
|
||||
BUTTONx_GPIO_CLK_ENABLE(Button);
|
||||
|
||||
gpioinitstruct.Pin = BUTTON_PIN[Button];
|
||||
gpioinitstruct.Pull = GPIO_NOPULL;
|
||||
gpioinitstruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_GPIO)
|
||||
{
|
||||
/* Configure Button pin as input */
|
||||
gpioinitstruct.Mode = GPIO_MODE_INPUT;
|
||||
|
||||
HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
|
||||
}
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_EXTI)
|
||||
{
|
||||
/* Configure Button pin as input with External interrupt */
|
||||
gpioinitstruct.Mode = GPIO_MODE_IT_FALLING;
|
||||
HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
|
||||
|
||||
/* Enable and set Button EXTI Interrupt to the lowest priority */
|
||||
HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0);
|
||||
HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Push Button DeInit.
|
||||
* @param Button: Button to be configured
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @note PB DeInit does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_DeInit(Button_TypeDef Button)
|
||||
{
|
||||
GPIO_InitTypeDef gpio_init_structure;
|
||||
|
||||
gpio_init_structure.Pin = BUTTON_PIN[Button];
|
||||
HAL_NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
HAL_GPIO_DeInit(BUTTON_PORT[Button], gpio_init_structure.Pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the selected Button state.
|
||||
* @param Button: Specifies the Button to be checked.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @retval Button state.
|
||||
*/
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button)
|
||||
{
|
||||
return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
|
||||
}
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
/**
|
||||
* @brief DEBUG_USART GPIO Config,Mode Config,115200 8-N-1
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_USART_Config(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
#if defined(__GNUC__)
|
||||
setvbuf(stdout, NULL, _IONBF, 0 );
|
||||
#endif
|
||||
|
||||
DEBUG_USART_CLK_ENABLE();
|
||||
|
||||
DebugUartHandle.Instance = DEBUG_USART;
|
||||
|
||||
DebugUartHandle.Init.BaudRate = DEBUG_USART_BAUDRATE;
|
||||
DebugUartHandle.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
DebugUartHandle.Init.StopBits = UART_STOPBITS_1;
|
||||
DebugUartHandle.Init.Parity = UART_PARITY_NONE;
|
||||
DebugUartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
DebugUartHandle.Init.Mode = UART_MODE_TX_RX;
|
||||
DebugUartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
DebugUartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
|
||||
HAL_UART_Init(&DebugUartHandle);
|
||||
|
||||
// DEBUG_USART_RX_GPIO_CLK_ENABLE();
|
||||
DEBUG_USART_TX_GPIO_CLK_ENABLE();
|
||||
|
||||
/**USART GPIO Configuration
|
||||
PA2 ------> USART1_TX
|
||||
PA3 ------> USART1_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = DEBUG_USART_TX_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = DEBUG_USART_TX_AF;
|
||||
HAL_GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
// GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN;
|
||||
// GPIO_InitStruct.Alternate = DEBUG_USART_RX_AF;
|
||||
|
||||
// HAL_GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* ENABLE NVIC */
|
||||
HAL_NVIC_SetPriority(DEBUG_USART_IRQ,0,1);
|
||||
HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ );
|
||||
}
|
||||
|
||||
#if (defined (__CC_ARM)) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get a character from the usart
|
||||
* @param *f
|
||||
* @retval a character
|
||||
*/
|
||||
int fgetc(FILE *f)
|
||||
{
|
||||
int ch;
|
||||
HAL_UART_Receive(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* @retval the character
|
||||
*/
|
||||
int __io_putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
for (DataIdx=0;DataIdx<len;DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f030xx_Start_Kit.h
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef PY32F030_START_KIT_H
|
||||
#define PY32F030_START_KIT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_hal.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit
|
||||
* @brief This section contains the exported types, contants and functions
|
||||
* required to use the Nucleo 32 board.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit_Exported_Types Exported Types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LED3 = 0,
|
||||
LED_GREEN = LED3
|
||||
} Led_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_USER = 0,
|
||||
/* Alias */
|
||||
BUTTON_KEY = BUTTON_USER
|
||||
} Button_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_MODE_GPIO = 0,
|
||||
BUTTON_MODE_EXTI = 1
|
||||
} ButtonMode_TypeDef;
|
||||
|
||||
#define LEDn 1
|
||||
|
||||
#define LED3_PIN GPIO_PIN_11
|
||||
#define LED3_GPIO_PORT GPIOA
|
||||
#define LED3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define LED3_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
|
||||
|
||||
#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do {LED3_GPIO_CLK_ENABLE(); } while(0U)
|
||||
#define LEDx_GPIO_CLK_DISABLE(__INDEX__) LED3_GPIO_CLK_DISABLE())
|
||||
|
||||
#define BUTTONn 1
|
||||
|
||||
/**
|
||||
* @brief User push-button
|
||||
*/
|
||||
#define USER_BUTTON_PIN GPIO_PIN_12
|
||||
#define USER_BUTTON_GPIO_PORT GPIOA
|
||||
#define USER_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define USER_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
|
||||
#define USER_BUTTON_EXTI_IRQn EXTI4_15_IRQn
|
||||
|
||||
/* Aliases */
|
||||
#define KEY_BUTTON_PIN USER_BUTTON_PIN
|
||||
#define KEY_BUTTON_GPIO_PORT USER_BUTTON_GPIO_PORT
|
||||
#define KEY_BUTTON_GPIO_CLK_ENABLE() USER_BUTTON_GPIO_CLK_ENABLE()
|
||||
#define KEY_BUTTON_GPIO_CLK_DISABLE() USER_BUTTON_GPIO_CLK_DISABLE()
|
||||
#define KEY_BUTTON_EXTI_IRQn USER_BUTTON_EXTI_IRQn
|
||||
|
||||
#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) USER_BUTTON_GPIO_CLK_ENABLE();} while(0)
|
||||
#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? USER_BUTTON_GPIO_CLK_DISABLE() : 0)
|
||||
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
//debug printf redirect config
|
||||
#define DEBUG_USART_BAUDRATE 115200
|
||||
|
||||
#define DEBUG_USART USART2
|
||||
#define DEBUG_USART_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->APBENR1, RCC_APBENR1_USART2EN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->APBENR1, RCC_APBENR1_USART2EN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define __GPIOA_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define DEBUG_USART_RX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define DEBUG_USART_RX_PIN GPIO_PIN_3
|
||||
#define DEBUG_USART_RX_AF GPIO_AF4_USART2
|
||||
|
||||
#define DEBUG_USART_TX_GPIO_PORT GPIOF
|
||||
#define DEBUG_USART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
|
||||
#define DEBUG_USART_TX_PIN GPIO_PIN_0
|
||||
#define DEBUG_USART_TX_AF GPIO_AF9_USART2
|
||||
|
||||
#define DEBUG_USART_IRQHandler USART2_IRQHandler
|
||||
#define DEBUG_USART_IRQ USART2_IRQn
|
||||
#endif
|
||||
/************************************************************/
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
extern UART_HandleTypeDef DebugUartHandle;
|
||||
#endif
|
||||
|
||||
/** @defgroup Functions
|
||||
* @{
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void);
|
||||
|
||||
void BSP_LED_Init(Led_TypeDef Led);
|
||||
void BSP_LED_DeInit(Led_TypeDef Led);
|
||||
void BSP_LED_On(Led_TypeDef Led);
|
||||
void BSP_LED_Off(Led_TypeDef Led);
|
||||
void BSP_LED_Toggle(Led_TypeDef Led);
|
||||
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
|
||||
void BSP_PB_DeInit(Button_TypeDef Button);
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button);
|
||||
|
||||
void BSP_USART_Config(void);
|
||||
#define DEBUG_USART_Config BSP_USART_Config
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PY32F030xx_START_KIT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,335 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f030xx_ll_Start_Kit.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f030xx_ll_Start_Kit.h"
|
||||
|
||||
/**
|
||||
* @brief PY32F030xx STK BSP Driver version number
|
||||
*/
|
||||
#define __PY32F030xx_STK_BSP_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||
#define __PY32F030xx_STK_BSP_VERSION_SUB1 (0x00U) /*!< [23:16] sub1 version */
|
||||
#define __PY32F030xx_STK_BSP_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
|
||||
#define __PY32F030xx_STK_BSP_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __PY32F030xx_STK_BSP_VERSION ((__PY32F030xx_STK_BSP_VERSION_MAIN << 24) \
|
||||
|(__PY32F030xx_STK_BSP_VERSION_SUB1 << 16) \
|
||||
|(__PY32F030xx_STK_BSP_VERSION_SUB2 << 8 ) \
|
||||
|(__PY32F030xx_STK_BSP_VERSION_RC))
|
||||
|
||||
GPIO_TypeDef* LED_PORT[LEDn] = {LED3_GPIO_PORT};
|
||||
const uint16_t LED_PIN[LEDn] = {LED3_PIN};
|
||||
|
||||
GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT };
|
||||
const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN };
|
||||
const uint8_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn };
|
||||
const uint32_t BUTTON_EXTI_LINE[BUTTONn] = {USER_BUTTON_EXTI_LINE };
|
||||
|
||||
/** @addtogroup PY32F030xx_STK_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This method returns the PY32F030 STK BSP Driver revision.
|
||||
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void)
|
||||
{
|
||||
return __PY32F030xx_STK_BSP_VERSION;
|
||||
}
|
||||
|
||||
/** @addtogroup LED_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configures LED GPIO.
|
||||
* @param Led Specifies the Led to be configured.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Init(Led_TypeDef Led)
|
||||
{
|
||||
/* Enable the GPIO_LED Clock */
|
||||
LEDx_GPIO_CLK_ENABLE(Led);
|
||||
|
||||
/* Configure the GPIO_LED pin */
|
||||
LL_GPIO_SetPinMode(LED_PORT[Led], LED_PIN[Led], LL_GPIO_MODE_OUTPUT);
|
||||
/* LL_GPIO_SetPinOutputType(LED_PORT[Led], LED_PIN[Led], LL_GPIO_OUTPUT_PUSHPULL); */
|
||||
/* LL_GPIO_SetPinSpeed(LED_PORT[Led], LED_PIN[Led], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(LED_PORT[Led], LED_PIN[Led], LL_GPIO_PULL_NO); */
|
||||
|
||||
LL_GPIO_SetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize LED GPIO.
|
||||
* @param Led Specifies the Led to be deconfigured.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg LED3
|
||||
* @note BSP_LED_DeInit() does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_DeInit(Led_TypeDef Led)
|
||||
{
|
||||
/* Turn off LED */
|
||||
LL_GPIO_ResetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
/* DeInit the GPIO_LED pin */
|
||||
LL_GPIO_SetPinMode(LED_PORT[Led], LED_PIN[Led], LL_GPIO_MODE_ANALOG);
|
||||
/* LL_GPIO_SetPinOutputType(LED_PORT[Led], LED_PIN[Led], LL_GPIO_OUTPUT_PUSHPULL); */
|
||||
/* LL_GPIO_SetPinSpeed(LED_PORT[Led], LED_PIN[Led], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(LED_PORT[Led], LED_PIN[Led], LL_GPIO_PULL_NO); */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED On.
|
||||
* @param Led Specifies the Led to be set on.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_On(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_ResetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED Off.
|
||||
* @param Led Specifies the Led to be set off.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Off(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_SetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggles the selected LED.
|
||||
* @param Led Specifies the Led to be toggled.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Toggle(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures Button GPIO and EXTI Line.
|
||||
* @param Button: Specifies the Button to be configured.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @param ButtonMode: Specifies Button mode.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg BUTTON_MODE_GPIO: Button will be used as simple IO
|
||||
* @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
|
||||
* generation capability
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
|
||||
{
|
||||
/* Enable the BUTTON Clock */
|
||||
BUTTONx_GPIO_CLK_ENABLE(Button);
|
||||
|
||||
/* Configure GPIO for BUTTON */
|
||||
LL_GPIO_SetPinMode(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_MODE_INPUT);
|
||||
LL_GPIO_SetPinPull(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_PULL_NO);
|
||||
/* LL_GPIO_SetPinSpeed(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_SPEED_FREQ_HIGH); */
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_EXTI)
|
||||
{
|
||||
/* Configure Button pin as input with External interrupt */
|
||||
LL_EXTI_EnableIT(BUTTON_EXTI_LINE[Button]);
|
||||
LL_EXTI_EnableFallingTrig(BUTTON_EXTI_LINE[Button]);
|
||||
|
||||
/* Enable and set Button EXTI Interrupt to the lowest priority */
|
||||
NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F);
|
||||
NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Push Button DeInit.
|
||||
* @param Button: Button to be configured
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @note PB DeInit does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_DeInit(Button_TypeDef Button)
|
||||
{
|
||||
NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
LL_GPIO_SetPinMode(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_MODE_ANALOG);
|
||||
/* LL_GPIO_SetPinSpeed(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_PULL_NO); */
|
||||
/* LL_GPIO_SetAFPin_8_15(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_AF_0); */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the selected Button state.
|
||||
* @param Button: Specifies the Button to be checked.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @retval Button state.
|
||||
*/
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button)
|
||||
{
|
||||
return LL_GPIO_IsInputPinSet(BUTTON_PORT[Button], BUTTON_PIN[Button]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DEBUG_USART GPIO Config,Mode Config,115200 8-N-1
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_USART_Config(void)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
setvbuf(stdout, NULL, _IONBF, 0 );
|
||||
#endif
|
||||
|
||||
DEBUG_USART_CLK_ENABLE();
|
||||
|
||||
/* USART Init */
|
||||
LL_USART_SetBaudRate(DEBUG_USART, SystemCoreClock, LL_USART_OVERSAMPLING_16, DEBUG_USART_BAUDRATE);
|
||||
LL_USART_SetDataWidth(DEBUG_USART, LL_USART_DATAWIDTH_8B);
|
||||
LL_USART_SetStopBitsLength(DEBUG_USART, LL_USART_STOPBITS_1);
|
||||
LL_USART_SetParity(DEBUG_USART, LL_USART_PARITY_NONE);
|
||||
LL_USART_SetHWFlowCtrl(DEBUG_USART, LL_USART_HWCONTROL_NONE);
|
||||
LL_USART_SetTransferDirection(DEBUG_USART, LL_USART_DIRECTION_TX_RX);
|
||||
LL_USART_Enable(DEBUG_USART);
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
/**USART GPIO Configuration
|
||||
PA2 ------> USART1_TX
|
||||
PA3 ------> USART1_RX
|
||||
*/
|
||||
DEBUG_USART_RX_GPIO_CLK_ENABLE();
|
||||
DEBUG_USART_TX_GPIO_CLK_ENABLE();
|
||||
|
||||
LL_GPIO_SetPinMode(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetPinSpeed(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
|
||||
LL_GPIO_SetPinPull(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_PULL_UP);
|
||||
LL_GPIO_SetAFPin_0_7(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, DEBUG_USART_TX_AF);
|
||||
|
||||
LL_GPIO_SetPinMode(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetPinSpeed(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
|
||||
LL_GPIO_SetPinPull(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_PULL_UP);
|
||||
LL_GPIO_SetAFPin_0_7(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, DEBUG_USART_RX_AF);
|
||||
}
|
||||
|
||||
#if (defined (__CC_ARM)) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get a character from the usart
|
||||
* @param *f
|
||||
* @retval a character
|
||||
*/
|
||||
int fgetc(FILE *f)
|
||||
{
|
||||
int ch;
|
||||
while (!LL_USART_IsActiveFlag_RXNE(DEBUG_USART));
|
||||
ch = LL_USART_ReceiveData8(DEBUG_USART);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* @retval the character
|
||||
*/
|
||||
int __io_putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
return ch;
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
for (DataIdx=0;DataIdx<len;DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f030xx_ll_Start_Kit.h
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef PY32F0XX_LL_START_KIT_H
|
||||
#define PY32F0XX_LL_START_KIT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include "py32f0xx_ll_rcc.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
#include "py32f0xx_ll_system.h"
|
||||
#include "py32f0xx_ll_exti.h"
|
||||
#include "py32f0xx_ll_cortex.h"
|
||||
#include "py32f0xx_ll_utils.h"
|
||||
#include "py32f0xx_ll_pwr.h"
|
||||
#include "py32f0xx_ll_dma.h"
|
||||
#include "py32f0xx_ll_gpio.h"
|
||||
#include "py32f0xx_ll_usart.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit
|
||||
* @brief This section contains the exported types, contants and functions
|
||||
* required to use the Nucleo 32 board.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f0xx_Start_Kit_Exported_Types Exported Types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LED3 = 0,
|
||||
LED_GREEN = LED3
|
||||
} Led_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_USER = 0,
|
||||
/* Alias */
|
||||
BUTTON_KEY = BUTTON_USER
|
||||
} Button_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_MODE_GPIO = 0,
|
||||
BUTTON_MODE_EXTI = 1
|
||||
} ButtonMode_TypeDef;
|
||||
|
||||
#define LEDn 1
|
||||
|
||||
#define LED3_PIN LL_GPIO_PIN_11
|
||||
#define LED3_GPIO_PORT GPIOA
|
||||
#define LED3_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define LED3_GPIO_CLK_DISABLE() LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
|
||||
#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do {LED3_GPIO_CLK_ENABLE(); } while(0U)
|
||||
#define LEDx_GPIO_CLK_DISABLE(__INDEX__) LED3_GPIO_CLK_DISABLE())
|
||||
|
||||
#define BUTTONn 1
|
||||
|
||||
/**
|
||||
* @brief User push-button
|
||||
*/
|
||||
#define USER_BUTTON_PIN LL_GPIO_PIN_12
|
||||
#define USER_BUTTON_GPIO_PORT GPIOA
|
||||
#define USER_BUTTON_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define USER_BUTTON_GPIO_CLK_DISABLE() LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define USER_BUTTON_EXTI_IRQn EXTI4_15_IRQn
|
||||
#define USER_BUTTON_EXTI_LINE LL_EXTI_LINE_12
|
||||
#define USER_BUTTON_EXTI_LINE_ENABLE() LL_EXTI_EnableIT(USER_BUTTON_EXTI_LINE)
|
||||
#define USER_BUTTON_EXTI_FALLING_TRIG_ENABLE() LL_EXTI_EnableFallingTrig(USER_BUTTON_EXTI_LINE)
|
||||
#define USER_BUTTON_IRQHANDLER EXTI4_15_IRQHandler
|
||||
|
||||
/* Aliases */
|
||||
#define KEY_BUTTON_PIN USER_BUTTON_PIN
|
||||
#define KEY_BUTTON_GPIO_PORT USER_BUTTON_GPIO_PORT
|
||||
#define KEY_BUTTON_GPIO_CLK_ENABLE() USER_BUTTON_GPIO_CLK_ENABLE()
|
||||
#define KEY_BUTTON_GPIO_CLK_DISABLE() USER_BUTTON_GPIO_CLK_DISABLE()
|
||||
#define KEY_BUTTON_EXTI_IRQn USER_BUTTON_EXTI_IRQn
|
||||
|
||||
#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) USER_BUTTON_GPIO_CLK_ENABLE();} while(0)
|
||||
#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? USER_BUTTON_GPIO_CLK_DISABLE() : 0)
|
||||
|
||||
|
||||
//debug printf redirect config
|
||||
#define DEBUG_USART_BAUDRATE 115200
|
||||
|
||||
#define DEBUG_USART USART2
|
||||
#define DEBUG_USART_CLK_ENABLE() LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2)
|
||||
|
||||
#define __GPIOA_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define DEBUG_USART_RX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_RX_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define DEBUG_USART_RX_PIN LL_GPIO_PIN_3
|
||||
#define DEBUG_USART_RX_AF LL_GPIO_AF_4
|
||||
|
||||
#define DEBUG_USART_TX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_TX_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define DEBUG_USART_TX_PIN LL_GPIO_PIN_2
|
||||
#define DEBUG_USART_TX_AF LL_GPIO_AF_4
|
||||
|
||||
#define DEBUG_USART_IRQHandler USART2_IRQHandler
|
||||
#define DEBUG_USART_IRQ USART2_IRQn
|
||||
/************************************************************/
|
||||
|
||||
/** @defgroup Functions
|
||||
* @{
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void);
|
||||
|
||||
void BSP_LED_Init(Led_TypeDef Led);
|
||||
void BSP_LED_DeInit(Led_TypeDef Led);
|
||||
void BSP_LED_On(Led_TypeDef Led);
|
||||
void BSP_LED_Off(Led_TypeDef Led);
|
||||
void BSP_LED_Toggle(Led_TypeDef Led);
|
||||
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
|
||||
void BSP_PB_DeInit(Button_TypeDef Button);
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button);
|
||||
|
||||
void BSP_USART_Config(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PY32F030xx_LL_START_KIT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,358 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040xx_Start_Kit.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f040xx_Start_Kit.h"
|
||||
|
||||
/**
|
||||
* @brief PY32F040xx STK BSP Driver version number
|
||||
*/
|
||||
#define __PY32F040xx_STK_BSP_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||
#define __PY32F040xx_STK_BSP_VERSION_SUB1 (0x00U) /*!< [23:16] sub1 version */
|
||||
#define __PY32F040xx_STK_BSP_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
|
||||
#define __PY32F040xx_STK_BSP_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __PY32F040xx_STK_BSP_VERSION ((__PY32F040xx_STK_BSP_VERSION_MAIN << 24) \
|
||||
|(__PY32F040xx_STK_BSP_VERSION_SUB1 << 16) \
|
||||
|(__PY32F040xx_STK_BSP_VERSION_SUB2 << 8 ) \
|
||||
|(__PY32F040xx_STK_BSP_VERSION_RC))
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
UART_HandleTypeDef DebugUartHandle;
|
||||
#endif
|
||||
GPIO_TypeDef* LED_PORT[LEDn] = {LED3_GPIO_PORT};
|
||||
const uint16_t LED_PIN[LEDn] = {LED3_PIN};
|
||||
|
||||
GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT };
|
||||
const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN };
|
||||
const uint8_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn };
|
||||
|
||||
/** @addtogroup PY32F040xx_STK_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This method returns the PY32F040 STK BSP Driver revision.
|
||||
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void)
|
||||
{
|
||||
return __PY32F040xx_STK_BSP_VERSION;
|
||||
}
|
||||
|
||||
/** @addtogroup LED_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configures LED GPIO.
|
||||
* @param Led Specifies the Led to be configured.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Init(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
/* Enable the GPIO_LED Clock */
|
||||
LEDx_GPIO_CLK_ENABLE(Led);
|
||||
|
||||
/* Configure the GPIO_LED pin */
|
||||
GPIO_InitStruct.Pin = LED_PIN[Led];
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
|
||||
HAL_GPIO_Init(LED_PORT[Led], &GPIO_InitStruct);
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize LED GPIO.
|
||||
* @param Led Specifies the Led to be deconfigured.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg LED3
|
||||
* @note BSP_LED_DeInit() does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_DeInit(Led_TypeDef Led)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
/* Turn off LED */
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
|
||||
/* DeInit the GPIO_LED pin */
|
||||
GPIO_InitStruct.Pin = LED_PIN[Led];
|
||||
HAL_GPIO_DeInit(LED_PORT[Led], GPIO_InitStruct.Pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED On.
|
||||
* @param Led Specifies the Led to be set on.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_On(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED Off.
|
||||
* @param Led Specifies the Led to be set off.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Off(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggles the selected LED.
|
||||
* @param Led Specifies the Led to be toggled.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Toggle(Led_TypeDef Led)
|
||||
{
|
||||
HAL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures Button GPIO and EXTI Line.
|
||||
* @param Button: Specifies the Button to be configured.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @param ButtonMode: Specifies Button mode.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg BUTTON_MODE_GPIO: Button will be used as simple IO
|
||||
* @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
|
||||
* generation capability
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
|
||||
{
|
||||
GPIO_InitTypeDef gpioinitstruct = {0};
|
||||
|
||||
/* Enable the BUTTON Clock */
|
||||
BUTTONx_GPIO_CLK_ENABLE(Button);
|
||||
|
||||
gpioinitstruct.Pin = BUTTON_PIN[Button];
|
||||
gpioinitstruct.Pull = GPIO_NOPULL;
|
||||
gpioinitstruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_GPIO)
|
||||
{
|
||||
/* Configure Button pin as input */
|
||||
gpioinitstruct.Mode = GPIO_MODE_INPUT;
|
||||
|
||||
HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
|
||||
}
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_EXTI)
|
||||
{
|
||||
/* Configure Button pin as input with External interrupt */
|
||||
gpioinitstruct.Mode = GPIO_MODE_IT_FALLING;
|
||||
HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
|
||||
|
||||
/* Enable and set Button EXTI Interrupt to the lowest priority */
|
||||
HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0);
|
||||
HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Push Button DeInit.
|
||||
* @param Button: Button to be configured
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @note PB DeInit does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_DeInit(Button_TypeDef Button)
|
||||
{
|
||||
GPIO_InitTypeDef gpio_init_structure = {0};
|
||||
|
||||
gpio_init_structure.Pin = BUTTON_PIN[Button];
|
||||
HAL_NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
HAL_GPIO_DeInit(BUTTON_PORT[Button], gpio_init_structure.Pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the selected Button state.
|
||||
* @param Button: Specifies the Button to be checked.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @retval Button state.
|
||||
*/
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button)
|
||||
{
|
||||
#if StartKitVersion == 2
|
||||
return (HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]) == GPIO_PIN_RESET);
|
||||
#else
|
||||
return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
/**
|
||||
* @brief DEBUG_USART GPIO Config,Mode Config,115200 8-N-1
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_USART_Config(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
#if defined (__GNUC__)
|
||||
setvbuf(stdout,NULL,_IONBF,0);
|
||||
#endif
|
||||
|
||||
DEBUG_USART_CLK_ENABLE();
|
||||
|
||||
DebugUartHandle.Instance = DEBUG_USART;
|
||||
|
||||
DebugUartHandle.Init.BaudRate = DEBUG_USART_BAUDRATE;
|
||||
DebugUartHandle.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
DebugUartHandle.Init.StopBits = UART_STOPBITS_1;
|
||||
DebugUartHandle.Init.Parity = UART_PARITY_NONE;
|
||||
DebugUartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
DebugUartHandle.Init.Mode = UART_MODE_TX_RX;
|
||||
DebugUartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
DebugUartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
|
||||
HAL_UART_Init(&DebugUartHandle);
|
||||
|
||||
DEBUG_USART_RX_GPIO_CLK_ENABLE();
|
||||
DEBUG_USART_TX_GPIO_CLK_ENABLE();
|
||||
|
||||
/**USART GPIO Configuration
|
||||
PA2 ------> USART2_TX
|
||||
PA3 ------> USART2_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = DEBUG_USART_TX_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = DEBUG_USART_TX_AF;
|
||||
HAL_GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN;
|
||||
GPIO_InitStruct.Alternate = DEBUG_USART_RX_AF;
|
||||
|
||||
HAL_GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* ENABLE NVIC */
|
||||
HAL_NVIC_SetPriority(DEBUG_USART_IRQ,0,1);
|
||||
HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ );
|
||||
}
|
||||
|
||||
#if (defined (__CC_ARM)) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get a character from the usart
|
||||
* @param *f
|
||||
* @retval a character
|
||||
*/
|
||||
int fgetc(FILE *f)
|
||||
{
|
||||
int ch;
|
||||
HAL_UART_Receive(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
#elif defined(__GNUC__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* @retval the character
|
||||
*/
|
||||
int __io_putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
for (DataIdx=0;DataIdx<len;DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040xx_Start_Kit.h
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef PY32F040_START_KIT_H
|
||||
#define PY32F040_START_KIT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_hal.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f040_Start_Kit
|
||||
* @brief This section contains the exported types, contants and functions
|
||||
* required to use the Nucleo 32 board.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f040_Start_Kit_Exported_Types Exported Types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LED3 = 0,
|
||||
LED_GREEN = LED3
|
||||
} Led_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_USER = 0,
|
||||
/* Alias */
|
||||
BUTTON_KEY = BUTTON_USER
|
||||
} Button_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_MODE_GPIO = 0,
|
||||
BUTTON_MODE_EXTI = 1
|
||||
} ButtonMode_TypeDef;
|
||||
|
||||
#define StartKitVersion 2
|
||||
/* #define StartKitVersion 1 */
|
||||
|
||||
#define LEDn 1
|
||||
|
||||
#define LED3_PIN GPIO_PIN_2
|
||||
#define LED3_GPIO_PORT GPIOB
|
||||
#define LED3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
|
||||
#define LED3_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
|
||||
|
||||
#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do {LED3_GPIO_CLK_ENABLE(); } while(0U)
|
||||
#define LEDx_GPIO_CLK_DISABLE(__INDEX__) LED3_GPIO_CLK_DISABLE())
|
||||
|
||||
#define BUTTONn 1
|
||||
|
||||
/**
|
||||
* @brief User push-button
|
||||
*/
|
||||
#define USER_BUTTON_PIN GPIO_PIN_0
|
||||
#define USER_BUTTON_GPIO_PORT GPIOB
|
||||
#define USER_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
|
||||
#define USER_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
|
||||
#define USER_BUTTON_EXTI_IRQn EXTI0_1_IRQn
|
||||
|
||||
/* Aliases */
|
||||
#define KEY_BUTTON_PIN USER_BUTTON_PIN
|
||||
#define KEY_BUTTON_GPIO_PORT USER_BUTTON_GPIO_PORT
|
||||
#define KEY_BUTTON_GPIO_CLK_ENABLE() USER_BUTTON_GPIO_CLK_ENABLE()
|
||||
#define KEY_BUTTON_GPIO_CLK_DISABLE() USER_BUTTON_GPIO_CLK_DISABLE()
|
||||
#define KEY_BUTTON_EXTI_IRQn USER_BUTTON_EXTI_IRQn
|
||||
|
||||
#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) USER_BUTTON_GPIO_CLK_ENABLE();} while(0)
|
||||
#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? USER_BUTTON_GPIO_CLK_DISABLE() : 0)
|
||||
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
//debug printf redirect config
|
||||
#define DEBUG_USART_BAUDRATE 115200
|
||||
|
||||
#define DEBUG_USART USART1
|
||||
#define DEBUG_USART_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->APBENR2, RCC_APBENR2_USART1EN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->APBENR2, RCC_APBENR2_USART1EN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define __GPIOA_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define DEBUG_USART_RX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define DEBUG_USART_RX_PIN GPIO_PIN_3
|
||||
#define DEBUG_USART_RX_AF GPIO_AF1_USART2
|
||||
|
||||
#define DEBUG_USART_TX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define DEBUG_USART_TX_PIN GPIO_PIN_9
|
||||
#define DEBUG_USART_TX_AF GPIO_AF1_USART1
|
||||
|
||||
#define DEBUG_USART_IRQHandler USART1_IRQHandler
|
||||
#define DEBUG_USART_IRQ USART1_IRQn
|
||||
#endif
|
||||
/************************************************************/
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
extern UART_HandleTypeDef DebugUartHandle;
|
||||
#endif
|
||||
|
||||
/** @defgroup Functions
|
||||
* @{
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void);
|
||||
|
||||
void BSP_LED_Init(Led_TypeDef Led);
|
||||
void BSP_LED_DeInit(Led_TypeDef Led);
|
||||
void BSP_LED_On(Led_TypeDef Led);
|
||||
void BSP_LED_Off(Led_TypeDef Led);
|
||||
void BSP_LED_Toggle(Led_TypeDef Led);
|
||||
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
|
||||
void BSP_PB_DeInit(Button_TypeDef Button);
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button);
|
||||
|
||||
void BSP_USART_Config(void);
|
||||
#define DEBUG_USART_Config BSP_USART_Config
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PY32F040xx_START_KIT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,339 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040xx_ll_Start_Kit.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f040xx_ll_Start_Kit.h"
|
||||
|
||||
/**
|
||||
* @brief PY32F040xx STK BSP Driver version number
|
||||
*/
|
||||
#define __PY32F040xx_STK_BSP_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||
#define __PY32F040xx_STK_BSP_VERSION_SUB1 (0x00U) /*!< [23:16] sub1 version */
|
||||
#define __PY32F040xx_STK_BSP_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
|
||||
#define __PY32F040xx_STK_BSP_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __PY32F040xx_STK_BSP_VERSION ((__PY32F040xx_STK_BSP_VERSION_MAIN << 24) \
|
||||
|(__PY32F040xx_STK_BSP_VERSION_SUB1 << 16) \
|
||||
|(__PY32F040xx_STK_BSP_VERSION_SUB2 << 8 ) \
|
||||
|(__PY32F040xx_STK_BSP_VERSION_RC))
|
||||
|
||||
GPIO_TypeDef* LED_PORT[LEDn] = {LED3_GPIO_PORT};
|
||||
const uint16_t LED_PIN[LEDn] = {LED3_PIN};
|
||||
|
||||
GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT };
|
||||
const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN };
|
||||
const uint8_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn };
|
||||
const uint32_t BUTTON_EXTI_LINE[BUTTONn] = {USER_BUTTON_EXTI_LINE };
|
||||
|
||||
/** @addtogroup PY32F040xx_STK_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This method returns the PY32F040 STK BSP Driver revision.
|
||||
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void)
|
||||
{
|
||||
return __PY32F040xx_STK_BSP_VERSION;
|
||||
}
|
||||
|
||||
/** @addtogroup LED_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configures LED GPIO.
|
||||
* @param Led Specifies the Led to be configured.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Init(Led_TypeDef Led)
|
||||
{
|
||||
/* Enable the GPIO_LED Clock */
|
||||
LEDx_GPIO_CLK_ENABLE(Led);
|
||||
|
||||
/* Configure the GPIO_LED pin */
|
||||
LL_GPIO_SetPinMode(LED_PORT[Led], LED_PIN[Led], LL_GPIO_MODE_OUTPUT);
|
||||
/* LL_GPIO_SetPinOutputType(LED_PORT[Led], LED_PIN[Led], LL_GPIO_OUTPUT_PUSHPULL); */
|
||||
/* LL_GPIO_SetPinSpeed(LED_PORT[Led], LED_PIN[Led], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(LED_PORT[Led], LED_PIN[Led], LL_GPIO_PULL_NO); */
|
||||
|
||||
LL_GPIO_SetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize LED GPIO.
|
||||
* @param Led Specifies the Led to be deconfigured.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg LED3
|
||||
* @note BSP_LED_DeInit() does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_DeInit(Led_TypeDef Led)
|
||||
{
|
||||
/* Turn off LED */
|
||||
LL_GPIO_ResetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
/* DeInit the GPIO_LED pin */
|
||||
LL_GPIO_SetPinMode(LED_PORT[Led], LED_PIN[Led], LL_GPIO_MODE_ANALOG);
|
||||
/* LL_GPIO_SetPinOutputType(LED_PORT[Led], LED_PIN[Led], LL_GPIO_OUTPUT_PUSHPULL); */
|
||||
/* LL_GPIO_SetPinSpeed(LED_PORT[Led], LED_PIN[Led], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(LED_PORT[Led], LED_PIN[Led], LL_GPIO_PULL_NO); */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED On.
|
||||
* @param Led Specifies the Led to be set on.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_On(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_ResetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns selected LED Off.
|
||||
* @param Led Specifies the Led to be set off.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Off(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_SetOutputPin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggles the selected LED.
|
||||
* @param Led Specifies the Led to be toggled.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg LED3
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LED_Toggle(Led_TypeDef Led)
|
||||
{
|
||||
LL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures Button GPIO and EXTI Line.
|
||||
* @param Button: Specifies the Button to be configured.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @param ButtonMode: Specifies Button mode.
|
||||
* This parameter can be one of following parameters:
|
||||
* @arg BUTTON_MODE_GPIO: Button will be used as simple IO
|
||||
* @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
|
||||
* generation capability
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
|
||||
{
|
||||
/* Enable the BUTTON Clock */
|
||||
BUTTONx_GPIO_CLK_ENABLE(Button);
|
||||
|
||||
/* Configure GPIO for BUTTON */
|
||||
LL_GPIO_SetPinMode(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_MODE_INPUT);
|
||||
LL_GPIO_SetPinPull(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_PULL_NO);
|
||||
/* LL_GPIO_SetPinSpeed(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_SPEED_FREQ_HIGH); */
|
||||
|
||||
if(ButtonMode == BUTTON_MODE_EXTI)
|
||||
{
|
||||
/* Configure Button pin as input with External interrupt */
|
||||
LL_EXTI_EnableIT(BUTTON_EXTI_LINE[Button]);
|
||||
LL_EXTI_EnableFallingTrig(BUTTON_EXTI_LINE[Button]);
|
||||
|
||||
/* Enable and set Button EXTI Interrupt to the lowest priority */
|
||||
NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F);
|
||||
NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Push Button DeInit.
|
||||
* @param Button: Button to be configured
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @note PB DeInit does not disable the GPIO clock
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_PB_DeInit(Button_TypeDef Button)
|
||||
{
|
||||
NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
|
||||
LL_GPIO_SetPinMode(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_MODE_ANALOG);
|
||||
/* LL_GPIO_SetPinSpeed(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_SPEED_FREQ_LOW); */
|
||||
/* LL_GPIO_SetPinPull(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_PULL_NO); */
|
||||
/* LL_GPIO_SetAFPin_8_15(BUTTON_PORT[Button], BUTTON_PIN[Button], LL_GPIO_AF_0); */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the selected Button state.
|
||||
* @param Button: Specifies the Button to be checked.
|
||||
* This parameter should be: BUTTON_USER
|
||||
* @retval Button state.
|
||||
*/
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button)
|
||||
{
|
||||
#if StartKitVersion == 2
|
||||
return (LL_GPIO_IsInputPinSet(BUTTON_PORT[Button], BUTTON_PIN[Button]) == RESET);
|
||||
#else
|
||||
return LL_GPIO_IsInputPinSet(BUTTON_PORT[Button], BUTTON_PIN[Button]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DEBUG_USART GPIO Config,Mode Config,115200 8-N-1
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_USART_Config(void)
|
||||
{
|
||||
#if defined (__GNUC__)
|
||||
setvbuf(stdout,NULL,_IONBF,0);
|
||||
#endif
|
||||
|
||||
DEBUG_USART_CLK_ENABLE();
|
||||
|
||||
/* USART Init */
|
||||
LL_USART_SetBaudRate(DEBUG_USART, SystemCoreClock, LL_USART_OVERSAMPLING_16, DEBUG_USART_BAUDRATE);
|
||||
LL_USART_SetDataWidth(DEBUG_USART, LL_USART_DATAWIDTH_8B);
|
||||
LL_USART_SetStopBitsLength(DEBUG_USART, LL_USART_STOPBITS_1);
|
||||
LL_USART_SetParity(DEBUG_USART, LL_USART_PARITY_NONE);
|
||||
LL_USART_SetHWFlowCtrl(DEBUG_USART, LL_USART_HWCONTROL_NONE);
|
||||
LL_USART_SetTransferDirection(DEBUG_USART, LL_USART_DIRECTION_TX_RX);
|
||||
LL_USART_Enable(DEBUG_USART);
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
/**USART GPIO Configuration
|
||||
PA2 ------> USART2_TX
|
||||
PA3 ------> USART2_RX
|
||||
*/
|
||||
DEBUG_USART_RX_GPIO_CLK_ENABLE();
|
||||
DEBUG_USART_TX_GPIO_CLK_ENABLE();
|
||||
|
||||
LL_GPIO_SetPinMode(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetPinSpeed(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
|
||||
LL_GPIO_SetPinPull(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, LL_GPIO_PULL_UP);
|
||||
LL_GPIO_SetAFPin_0_7(DEBUG_USART_TX_GPIO_PORT, DEBUG_USART_TX_PIN, DEBUG_USART_TX_AF);
|
||||
|
||||
LL_GPIO_SetPinMode(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetPinSpeed(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_SPEED_FREQ_VERY_HIGH);
|
||||
LL_GPIO_SetPinPull(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, LL_GPIO_PULL_UP);
|
||||
LL_GPIO_SetAFPin_0_7(DEBUG_USART_RX_GPIO_PORT, DEBUG_USART_RX_PIN, DEBUG_USART_RX_AF);
|
||||
}
|
||||
|
||||
#if (defined (__CC_ARM)) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get a character from the usart
|
||||
* @param *f
|
||||
* @retval a character
|
||||
*/
|
||||
int fgetc(FILE *f)
|
||||
{
|
||||
int ch;
|
||||
while (!LL_USART_IsActiveFlag_RXNE(DEBUG_USART));
|
||||
ch = LL_USART_ReceiveData8(DEBUG_USART);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
#elif defined(__ICCARM__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* *f
|
||||
* @retval the character
|
||||
*/
|
||||
int putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
/**
|
||||
* @brief writes a character to the usart
|
||||
* @param ch
|
||||
* @retval the character
|
||||
*/
|
||||
int __io_putchar(int ch)
|
||||
{
|
||||
/* Send a byte to USART */
|
||||
LL_USART_TransmitData8(DEBUG_USART, ch);
|
||||
while (!LL_USART_IsActiveFlag_TC(DEBUG_USART));
|
||||
LL_USART_ClearFlag_TC(DEBUG_USART);
|
||||
return ch;
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
int DataIdx;
|
||||
for (DataIdx=0;DataIdx<len;DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f040xx_ll_Start_Kit.h
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides set of firmware functions to manage Leds,
|
||||
* push-button available on Start Kit.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2023 Puya Semiconductor Co.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by Puya under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef PY32F040_LL_START_KIT_H
|
||||
#define PY32F040_LL_START_KIT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include "py32f040_ll_rcc.h"
|
||||
#include "py32f040_ll_bus.h"
|
||||
#include "py32f040_ll_system.h"
|
||||
#include "py32f040_ll_exti.h"
|
||||
#include "py32f040_ll_cortex.h"
|
||||
#include "py32f040_ll_utils.h"
|
||||
#include "py32f040_ll_pwr.h"
|
||||
#include "py32f040_ll_dma.h"
|
||||
#include "py32f040_ll_gpio.h"
|
||||
#include "py32f040_ll_usart.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f040_Start_Kit
|
||||
* @brief This section contains the exported types, contants and functions
|
||||
* required to use the Nucleo 32 board.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup py32f040_Start_Kit_Exported_Types Exported Types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
LED3 = 0,
|
||||
LED_GREEN = LED3
|
||||
} Led_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_USER = 0,
|
||||
/* Alias */
|
||||
BUTTON_KEY = BUTTON_USER
|
||||
} Button_TypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BUTTON_MODE_GPIO = 0,
|
||||
BUTTON_MODE_EXTI = 1
|
||||
} ButtonMode_TypeDef;
|
||||
|
||||
#define StartKitVersion 2
|
||||
/* #define StartKitVersion 1 */
|
||||
|
||||
#define LEDn 1
|
||||
|
||||
#define LED3_PIN LL_GPIO_PIN_2
|
||||
#define LED3_GPIO_PORT GPIOB
|
||||
#define LED3_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB)
|
||||
#define LED3_GPIO_CLK_DISABLE() LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOB)
|
||||
|
||||
#define LEDx_GPIO_CLK_ENABLE(__INDEX__) do {LED3_GPIO_CLK_ENABLE(); } while(0U)
|
||||
#define LEDx_GPIO_CLK_DISABLE(__INDEX__) LED3_GPIO_CLK_DISABLE())
|
||||
|
||||
#define BUTTONn 1
|
||||
|
||||
/**
|
||||
* @brief User push-button
|
||||
*/
|
||||
#define USER_BUTTON_PIN LL_GPIO_PIN_0
|
||||
#define USER_BUTTON_GPIO_PORT GPIOB
|
||||
#define USER_BUTTON_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB)
|
||||
#define USER_BUTTON_GPIO_CLK_DISABLE() LL_IOP_GRP1_DisableClock(LL_IOP_GRP1_PERIPH_GPIOB)
|
||||
#define USER_BUTTON_EXTI_IRQn EXTI0_1_IRQn
|
||||
#define USER_BUTTON_EXTI_LINE LL_EXTI_LINE_0
|
||||
#define USER_BUTTON_EXTI_LINE_ENABLE() LL_EXTI_EnableIT(USER_BUTTON_EXTI_LINE)
|
||||
#define USER_BUTTON_EXTI_FALLING_TRIG_ENABLE() LL_EXTI_EnableFallingTrig(USER_BUTTON_EXTI_LINE)
|
||||
#define USER_BUTTON_IRQHANDLER EXTI0_1_IRQHandler
|
||||
|
||||
/* Aliases */
|
||||
#define KEY_BUTTON_PIN USER_BUTTON_PIN
|
||||
#define KEY_BUTTON_GPIO_PORT USER_BUTTON_GPIO_PORT
|
||||
#define KEY_BUTTON_GPIO_CLK_ENABLE() USER_BUTTON_GPIO_CLK_ENABLE()
|
||||
#define KEY_BUTTON_GPIO_CLK_DISABLE() USER_BUTTON_GPIO_CLK_DISABLE()
|
||||
#define KEY_BUTTON_EXTI_IRQn USER_BUTTON_EXTI_IRQn
|
||||
|
||||
#define BUTTONx_GPIO_CLK_ENABLE(__INDEX__) do { if((__INDEX__) == 0) USER_BUTTON_GPIO_CLK_ENABLE();} while(0)
|
||||
#define BUTTONx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? USER_BUTTON_GPIO_CLK_DISABLE() : 0)
|
||||
|
||||
|
||||
//debug printf redirect config
|
||||
#define DEBUG_USART_BAUDRATE 115200
|
||||
|
||||
#define DEBUG_USART USART2
|
||||
#define DEBUG_USART_CLK_ENABLE() LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2)
|
||||
|
||||
#define __GPIOA_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg = 0x00U; \
|
||||
SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
/* Delay after an RCC peripheral clock enabling */ \
|
||||
tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);\
|
||||
UNUSED(tmpreg); \
|
||||
} while(0U)
|
||||
|
||||
#define DEBUG_USART_RX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_RX_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define DEBUG_USART_RX_PIN LL_GPIO_PIN_3
|
||||
#define DEBUG_USART_RX_AF LL_GPIO_AF_1
|
||||
|
||||
#define DEBUG_USART_TX_GPIO_PORT GPIOA
|
||||
#define DEBUG_USART_TX_GPIO_CLK_ENABLE() LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA)
|
||||
#define DEBUG_USART_TX_PIN LL_GPIO_PIN_2
|
||||
#define DEBUG_USART_TX_AF LL_GPIO_AF_1
|
||||
|
||||
#define DEBUG_USART_IRQHandler USART2_IRQHandler
|
||||
#define DEBUG_USART_IRQ USART2_IRQn
|
||||
/************************************************************/
|
||||
|
||||
/** @defgroup Functions
|
||||
* @{
|
||||
*/
|
||||
uint32_t BSP_GetVersion(void);
|
||||
|
||||
void BSP_LED_Init(Led_TypeDef Led);
|
||||
void BSP_LED_DeInit(Led_TypeDef Led);
|
||||
void BSP_LED_On(Led_TypeDef Led);
|
||||
void BSP_LED_Off(Led_TypeDef Led);
|
||||
void BSP_LED_Toggle(Led_TypeDef Led);
|
||||
|
||||
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode);
|
||||
void BSP_PB_DeInit(Button_TypeDef Button);
|
||||
uint32_t BSP_PB_GetState(Button_TypeDef Button);
|
||||
|
||||
void BSP_USART_Config(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PY32F040xx_LL_START_KIT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,165 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_abs_f32.c
|
||||
*
|
||||
* Description: Vector absolute value.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup BasicAbs Vector Absolute Value
|
||||
*
|
||||
* Computes the absolute value of a vector on an element-by-element basis.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = abs(pSrc[n]), 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* The functions support in-place computation allowing the source and
|
||||
* destination pointers to reference the same memory buffer.
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAbs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point vector absolute value.
|
||||
* @param[in] *pSrc points to the input buffer
|
||||
* @param[out] *pDst points to the output buffer
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_abs_f32(
|
||||
float32_t * pSrc,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t in1, in2, in3, in4; /* temporary variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Calculate absolute and then store the results in the destination buffer. */
|
||||
/* read sample from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
|
||||
/* find absolute value */
|
||||
in1 = fabsf(in1);
|
||||
|
||||
/* read sample from source */
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* find absolute value */
|
||||
in2 = fabsf(in2);
|
||||
|
||||
/* read sample from source */
|
||||
*pDst = in1;
|
||||
|
||||
/* find absolute value */
|
||||
in3 = fabsf(in3);
|
||||
|
||||
/* find absolute value */
|
||||
in4 = fabsf(in4);
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 1) = in2;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 2) = in3;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 3) = in4;
|
||||
|
||||
|
||||
/* Update source pointer to process next sampels */
|
||||
pSrc += 4u;
|
||||
|
||||
/* Update destination pointer to process next sampels */
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Calculate absolute and then store the results in the destination buffer. */
|
||||
*pDst++ = fabsf(*pSrc++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAbs group
|
||||
*/
|
||||
@@ -0,0 +1,179 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_abs_q15.c
|
||||
*
|
||||
* Description: Q15 vector absolute value.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAbs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 vector absolute value.
|
||||
* @param[in] *pSrc points to the input buffer
|
||||
* @param[out] *pDst points to the output buffer
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q15 value -1 (0x8000) will be saturated to the maximum allowable positive value 0x7FFF.
|
||||
*/
|
||||
|
||||
void arm_abs_q15(
|
||||
q15_t * pSrc,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
__SIMD32_TYPE *simd;
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
q15_t in1; /* Input value1 */
|
||||
q15_t in2; /* Input value2 */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
simd = __SIMD32_CONST(pDst);
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Read two inputs */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
|
||||
|
||||
/* Store the Absolute result in the destination buffer by packing the two values, in a single cycle */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
*simd++ =
|
||||
__PKHBT(((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)),
|
||||
((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)), 16);
|
||||
|
||||
#else
|
||||
|
||||
|
||||
*simd++ =
|
||||
__PKHBT(((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)),
|
||||
((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*simd++ =
|
||||
__PKHBT(((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)),
|
||||
((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)), 16);
|
||||
|
||||
#else
|
||||
|
||||
|
||||
*simd++ =
|
||||
__PKHBT(((in2 > 0) ? in2 : (q15_t)__QSUB16(0, in2)),
|
||||
((in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1)), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
pDst = (q15_t *)simd;
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Read the input */
|
||||
in1 = *pSrc++;
|
||||
|
||||
/* Calculate absolute value of input and then store the result in the destination buffer. */
|
||||
*pDst++ = (in1 > 0) ? in1 : (q15_t)__QSUB16(0, in1);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
q15_t in; /* Temporary input variable */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Read the input */
|
||||
in = *pSrc++;
|
||||
|
||||
/* Calculate absolute value of input and then store the result in the destination buffer. */
|
||||
*pDst++ = (in > 0) ? in : ((in == (q15_t) 0x8000) ? 0x7fff : -in);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAbs group
|
||||
*/
|
||||
@@ -0,0 +1,130 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_abs_q31.c
|
||||
*
|
||||
* Description: Q31 vector absolute value.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAbs
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q31 vector absolute value.
|
||||
* @param[in] *pSrc points to the input buffer
|
||||
* @param[out] *pDst points to the output buffer
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q31 value -1 (0x80000000) will be saturated to the maximum allowable positive value 0x7FFFFFFF.
|
||||
*/
|
||||
|
||||
void arm_abs_q31(
|
||||
q31_t * pSrc,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q31_t in; /* Input value */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t in1, in2, in3, in4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Calculate absolute of input (if -1 then saturated to 0x7fffffff) and then store the results in the destination buffer. */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
in3 = *pSrc++;
|
||||
in4 = *pSrc++;
|
||||
|
||||
*pDst++ = (in1 > 0) ? in1 : (q31_t)__QSUB(0, in1);
|
||||
*pDst++ = (in2 > 0) ? in2 : (q31_t)__QSUB(0, in2);
|
||||
*pDst++ = (in3 > 0) ? in3 : (q31_t)__QSUB(0, in3);
|
||||
*pDst++ = (in4 > 0) ? in4 : (q31_t)__QSUB(0, in4);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Calculate absolute value of the input (if -1 then saturated to 0x7fffffff) and then store the results in the destination buffer. */
|
||||
in = *pSrc++;
|
||||
*pDst++ = (in > 0) ? in : ((in == INT32_MIN) ? INT32_MAX : -in);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAbs group
|
||||
*/
|
||||
@@ -0,0 +1,157 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_abs_q7.c
|
||||
*
|
||||
* Description: Q7 vector absolute value.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAbs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 vector absolute value.
|
||||
* @param[in] *pSrc points to the input buffer
|
||||
* @param[out] *pDst points to the output buffer
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* \par Conditions for optimum performance
|
||||
* Input and output buffers should be aligned by 32-bit
|
||||
*
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q7 value -1 (0x80) will be saturated to the maximum allowable positive value 0x7F.
|
||||
*/
|
||||
|
||||
void arm_abs_q7(
|
||||
q7_t * pSrc,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q7_t in; /* Input value1 */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t in1, in2, in3, in4; /* temporary input variables */
|
||||
q31_t out1, out2, out3, out4; /* temporary output variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Read inputs */
|
||||
in1 = (q31_t) * pSrc;
|
||||
in2 = (q31_t) * (pSrc + 1);
|
||||
in3 = (q31_t) * (pSrc + 2);
|
||||
|
||||
/* find absolute value */
|
||||
out1 = (in1 > 0) ? in1 : (q31_t)__QSUB8(0, in1);
|
||||
|
||||
/* read input */
|
||||
in4 = (q31_t) * (pSrc + 3);
|
||||
|
||||
/* find absolute value */
|
||||
out2 = (in2 > 0) ? in2 : (q31_t)__QSUB8(0, in2);
|
||||
|
||||
/* store result to destination */
|
||||
*pDst = (q7_t) out1;
|
||||
|
||||
/* find absolute value */
|
||||
out3 = (in3 > 0) ? in3 : (q31_t)__QSUB8(0, in3);
|
||||
|
||||
/* find absolute value */
|
||||
out4 = (in4 > 0) ? in4 : (q31_t)__QSUB8(0, in4);
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 1) = (q7_t) out2;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 2) = (q7_t) out3;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 3) = (q7_t) out4;
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #define ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = |A| */
|
||||
/* Read the input */
|
||||
in = *pSrc++;
|
||||
|
||||
/* Store the Absolute result in the destination buffer */
|
||||
*pDst++ = (in > 0) ? in : ((in == (q7_t) 0x80) ? 0x7f : -in);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAbs group
|
||||
*/
|
||||
@@ -0,0 +1,150 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_add_f32.c
|
||||
*
|
||||
* Description: Floating-point vector addition.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup BasicAdd Vector Addition
|
||||
*
|
||||
* Element-by-element addition of two vectors.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrcA[n] + pSrcB[n], 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAdd
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point vector addition.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_add_f32(
|
||||
float32_t * pSrcA,
|
||||
float32_t * pSrcB,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t inA1, inA2, inA3, inA4; /* temporary input variabels */
|
||||
float32_t inB1, inB2, inB3, inB4; /* temporary input variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
|
||||
/* read four inputs from sourceA and four inputs from sourceB */
|
||||
inA1 = *pSrcA;
|
||||
inB1 = *pSrcB;
|
||||
inA2 = *(pSrcA + 1);
|
||||
inB2 = *(pSrcB + 1);
|
||||
inA3 = *(pSrcA + 2);
|
||||
inB3 = *(pSrcB + 2);
|
||||
inA4 = *(pSrcA + 3);
|
||||
inB4 = *(pSrcB + 3);
|
||||
|
||||
/* C = A + B */
|
||||
/* add and store result to destination */
|
||||
*pDst = inA1 + inB1;
|
||||
*(pDst + 1) = inA2 + inB2;
|
||||
*(pDst + 2) = inA3 + inB3;
|
||||
*(pDst + 3) = inA4 + inB4;
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrcA += 4u;
|
||||
pSrcB += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (*pSrcA++) + (*pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAdd group
|
||||
*/
|
||||
@@ -0,0 +1,140 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_add_q15.c
|
||||
*
|
||||
* Description: Q15 vector addition
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAdd
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 vector addition.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_add_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inB1, inB2;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
inA1 = *__SIMD32(pSrcA)++;
|
||||
inA2 = *__SIMD32(pSrcA)++;
|
||||
inB1 = *__SIMD32(pSrcB)++;
|
||||
inB2 = *__SIMD32(pSrcB)++;
|
||||
|
||||
*__SIMD32(pDst)++ = __QADD16(inA1, inB1);
|
||||
*__SIMD32(pDst)++ = __QADD16(inA2, inB2);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (q15_t) __QADD16(*pSrcA++, *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (q15_t) __SSAT(((q31_t) * pSrcA++ + *pSrcB++), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAdd group
|
||||
*/
|
||||
@@ -0,0 +1,148 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_add_q31.c
|
||||
*
|
||||
* Description: Q31 vector addition.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAdd
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q31 vector addition.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_add_q31(
|
||||
q31_t * pSrcA,
|
||||
q31_t * pSrcB,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inA3, inA4;
|
||||
q31_t inB1, inB2, inB3, inB4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
inA1 = *pSrcA++;
|
||||
inA2 = *pSrcA++;
|
||||
inB1 = *pSrcB++;
|
||||
inB2 = *pSrcB++;
|
||||
|
||||
inA3 = *pSrcA++;
|
||||
inA4 = *pSrcA++;
|
||||
inB3 = *pSrcB++;
|
||||
inB4 = *pSrcB++;
|
||||
|
||||
*pDst++ = __QADD(inA1, inB1);
|
||||
*pDst++ = __QADD(inA2, inB2);
|
||||
*pDst++ = __QADD(inA3, inB3);
|
||||
*pDst++ = __QADD(inA4, inB4);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = __QADD(*pSrcA++, *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrcA++ + *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAdd group
|
||||
*/
|
||||
@@ -0,0 +1,134 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_add_q7.c
|
||||
*
|
||||
* Description: Q7 vector addition.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicAdd
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 vector addition.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_add_q7(
|
||||
q7_t * pSrcA,
|
||||
q7_t * pSrcB,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*__SIMD32(pDst)++ = __QADD8(*__SIMD32(pSrcA)++, *__SIMD32(pSrcB)++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT(*pSrcA++ + *pSrcB++, 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + B */
|
||||
/* Add and then store the results in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT((q15_t) * pSrcA++ + *pSrcB++, 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicAdd group
|
||||
*/
|
||||
@@ -0,0 +1,135 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_dot_prod_f32.c
|
||||
*
|
||||
* Description: Floating-point dot product.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup dot_prod Vector Dot Product
|
||||
*
|
||||
* Computes the dot product of two vectors.
|
||||
* The vectors are multiplied element-by-element and then summed.
|
||||
*
|
||||
* <pre>
|
||||
* sum = pSrcA[0]*pSrcB[0] + pSrcA[1]*pSrcB[1] + ... + pSrcA[blockSize-1]*pSrcB[blockSize-1]
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup dot_prod
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Dot product of floating-point vectors.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @param[out] *result output result returned here
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
|
||||
void arm_dot_prod_f32(
|
||||
float32_t * pSrcA,
|
||||
float32_t * pSrcB,
|
||||
uint32_t blockSize,
|
||||
float32_t * result)
|
||||
{
|
||||
float32_t sum = 0.0f; /* Temporary result storage */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the result in a temporary buffer */
|
||||
sum += (*pSrcA++) * (*pSrcB++);
|
||||
sum += (*pSrcA++) * (*pSrcB++);
|
||||
sum += (*pSrcA++) * (*pSrcB++);
|
||||
sum += (*pSrcA++) * (*pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the result in a temporary buffer. */
|
||||
sum += (*pSrcA++) * (*pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
/* Store the result back in the destination buffer */
|
||||
*result = sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of dot_prod group
|
||||
*/
|
||||
@@ -0,0 +1,140 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_dot_prod_q15.c
|
||||
*
|
||||
* Description: Q15 dot product.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup dot_prod
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Dot product of Q15 vectors.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @param[out] *result output result returned here
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The intermediate multiplications are in 1.15 x 1.15 = 2.30 format and these
|
||||
* results are added to a 64-bit accumulator in 34.30 format.
|
||||
* Nonsaturating additions are used and given that there are 33 guard bits in the accumulator
|
||||
* there is no risk of overflow.
|
||||
* The return result is in 34.30 format.
|
||||
*/
|
||||
|
||||
void arm_dot_prod_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
uint32_t blockSize,
|
||||
q63_t * result)
|
||||
{
|
||||
q63_t sum = 0; /* Temporary result storage */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the result in a temporary buffer. */
|
||||
sum = __SMLALD(*__SIMD32(pSrcA)++, *__SIMD32(pSrcB)++, sum);
|
||||
sum = __SMLALD(*__SIMD32(pSrcA)++, *__SIMD32(pSrcB)++, sum);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the results in a temporary buffer. */
|
||||
sum = __SMLALD(*pSrcA++, *pSrcB++, sum);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the results in a temporary buffer. */
|
||||
sum += (q63_t) ((q31_t) * pSrcA++ * *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
/* Store the result in the destination buffer in 34.30 format */
|
||||
*result = sum;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of dot_prod group
|
||||
*/
|
||||
@@ -0,0 +1,143 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_dot_prod_q31.c
|
||||
*
|
||||
* Description: Q31 dot product.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup dot_prod
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Dot product of Q31 vectors.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @param[out] *result output result returned here
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The intermediate multiplications are in 1.31 x 1.31 = 2.62 format and these
|
||||
* are truncated to 2.48 format by discarding the lower 14 bits.
|
||||
* The 2.48 result is then added without saturation to a 64-bit accumulator in 16.48 format.
|
||||
* There are 15 guard bits in the accumulator and there is no risk of overflow as long as
|
||||
* the length of the vectors is less than 2^16 elements.
|
||||
* The return result is in 16.48 format.
|
||||
*/
|
||||
|
||||
void arm_dot_prod_q31(
|
||||
q31_t * pSrcA,
|
||||
q31_t * pSrcB,
|
||||
uint32_t blockSize,
|
||||
q63_t * result)
|
||||
{
|
||||
q63_t sum = 0; /* Temporary result storage */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inA3, inA4;
|
||||
q31_t inB1, inB2, inB3, inB4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the result in a temporary buffer. */
|
||||
inA1 = *pSrcA++;
|
||||
inA2 = *pSrcA++;
|
||||
inA3 = *pSrcA++;
|
||||
inA4 = *pSrcA++;
|
||||
inB1 = *pSrcB++;
|
||||
inB2 = *pSrcB++;
|
||||
inB3 = *pSrcB++;
|
||||
inB4 = *pSrcB++;
|
||||
|
||||
sum += ((q63_t) inA1 * inB1) >> 14u;
|
||||
sum += ((q63_t) inA2 * inB2) >> 14u;
|
||||
sum += ((q63_t) inA3 * inB3) >> 14u;
|
||||
sum += ((q63_t) inA4 * inB4) >> 14u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Calculate dot product and then store the result in a temporary buffer. */
|
||||
sum += ((q63_t) * pSrcA++ * *pSrcB++) >> 14u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* Store the result in the destination buffer in 16.48 format */
|
||||
*result = sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of dot_prod group
|
||||
*/
|
||||
@@ -0,0 +1,159 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_dot_prod_q7.c
|
||||
*
|
||||
* Description: Q7 dot product.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup dot_prod
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Dot product of Q7 vectors.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @param[out] *result output result returned here
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The intermediate multiplications are in 1.7 x 1.7 = 2.14 format and these
|
||||
* results are added to an accumulator in 18.14 format.
|
||||
* Nonsaturating additions are used and there is no danger of wrap around as long as
|
||||
* the vectors are less than 2^18 elements long.
|
||||
* The return result is in 18.14 format.
|
||||
*/
|
||||
|
||||
void arm_dot_prod_q7(
|
||||
q7_t * pSrcA,
|
||||
q7_t * pSrcB,
|
||||
uint32_t blockSize,
|
||||
q31_t * result)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
q31_t sum = 0; /* Temporary variables to store output */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
q31_t input1, input2; /* Temporary variables to store input */
|
||||
q31_t inA1, inA2, inB1, inB2; /* Temporary variables to store input */
|
||||
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* read 4 samples at a time from sourceA */
|
||||
input1 = *__SIMD32(pSrcA)++;
|
||||
/* read 4 samples at a time from sourceB */
|
||||
input2 = *__SIMD32(pSrcB)++;
|
||||
|
||||
/* extract two q7_t samples to q15_t samples */
|
||||
inA1 = __SXTB16(__ROR(input1, 8));
|
||||
/* extract reminaing two samples */
|
||||
inA2 = __SXTB16(input1);
|
||||
/* extract two q7_t samples to q15_t samples */
|
||||
inB1 = __SXTB16(__ROR(input2, 8));
|
||||
/* extract reminaing two samples */
|
||||
inB2 = __SXTB16(input2);
|
||||
|
||||
/* multiply and accumulate two samples at a time */
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
sum = __SMLAD(inA2, inB2, sum);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Dot product and then store the results in a temporary buffer. */
|
||||
sum = __SMLAD(*pSrcA++, *pSrcB++, sum);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A[0]* B[0] + A[1]* B[1] + A[2]* B[2] + .....+ A[blockSize-1]* B[blockSize-1] */
|
||||
/* Dot product and then store the results in a temporary buffer. */
|
||||
sum += (q31_t) ((q15_t) * pSrcA++ * *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
/* Store the result in the destination buffer in 18.14 format */
|
||||
*result = sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of dot_prod group
|
||||
*/
|
||||
@@ -0,0 +1,174 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mult_f32.c
|
||||
*
|
||||
* Description: Floating-point vector multiplication.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup BasicMult Vector Multiplication
|
||||
*
|
||||
* Element-by-element multiplication of two vectors.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrcA[n] * pSrcB[n], 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Floating-point vector multiplication.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_mult_f32(
|
||||
float32_t * pSrcA,
|
||||
float32_t * pSrcB,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t inA1, inA2, inA3, inA4; /* temporary input variables */
|
||||
float32_t inB1, inB2, inB3, inB4; /* temporary input variables */
|
||||
float32_t out1, out2, out3, out4; /* temporary output variables */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and store the results in output buffer */
|
||||
/* read sample from sourceA */
|
||||
inA1 = *pSrcA;
|
||||
/* read sample from sourceB */
|
||||
inB1 = *pSrcB;
|
||||
/* read sample from sourceA */
|
||||
inA2 = *(pSrcA + 1);
|
||||
/* read sample from sourceB */
|
||||
inB2 = *(pSrcB + 1);
|
||||
|
||||
/* out = sourceA * sourceB */
|
||||
out1 = inA1 * inB1;
|
||||
|
||||
/* read sample from sourceA */
|
||||
inA3 = *(pSrcA + 2);
|
||||
/* read sample from sourceB */
|
||||
inB3 = *(pSrcB + 2);
|
||||
|
||||
/* out = sourceA * sourceB */
|
||||
out2 = inA2 * inB2;
|
||||
|
||||
/* read sample from sourceA */
|
||||
inA4 = *(pSrcA + 3);
|
||||
|
||||
/* store result to destination buffer */
|
||||
*pDst = out1;
|
||||
|
||||
/* read sample from sourceB */
|
||||
inB4 = *(pSrcB + 3);
|
||||
|
||||
/* out = sourceA * sourceB */
|
||||
out3 = inA3 * inB3;
|
||||
|
||||
/* store result to destination buffer */
|
||||
*(pDst + 1) = out2;
|
||||
|
||||
/* out = sourceA * sourceB */
|
||||
out4 = inA4 * inB4;
|
||||
/* store result to destination buffer */
|
||||
*(pDst + 2) = out3;
|
||||
/* store result to destination buffer */
|
||||
*(pDst + 3) = out4;
|
||||
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrcA += 4u;
|
||||
pSrcB += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and store the results in output buffer */
|
||||
*pDst++ = (*pSrcA++) * (*pSrcB++);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicMult group
|
||||
*/
|
||||
@@ -0,0 +1,154 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. October 2015
|
||||
* $Revision: V.1.4.5 a
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mult_q15.c
|
||||
*
|
||||
* Description: Q15 vector multiplication.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Q15 vector multiplication
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_mult_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inB1, inB2; /* temporary input variables */
|
||||
q15_t out1, out2, out3, out4; /* temporary output variables */
|
||||
q31_t mul1, mul2, mul3, mul4; /* temporary variables */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* read two samples at a time from sourceA */
|
||||
inA1 = *__SIMD32(pSrcA)++;
|
||||
/* read two samples at a time from sourceB */
|
||||
inB1 = *__SIMD32(pSrcB)++;
|
||||
/* read two samples at a time from sourceA */
|
||||
inA2 = *__SIMD32(pSrcA)++;
|
||||
/* read two samples at a time from sourceB */
|
||||
inB2 = *__SIMD32(pSrcB)++;
|
||||
|
||||
/* multiply mul = sourceA * sourceB */
|
||||
mul1 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1 >> 16));
|
||||
mul2 = (q31_t) ((q15_t) inA1 * (q15_t) inB1);
|
||||
mul3 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) (inB2 >> 16));
|
||||
mul4 = (q31_t) ((q15_t) inA2 * (q15_t) inB2);
|
||||
|
||||
/* saturate result to 16 bit */
|
||||
out1 = (q15_t) __SSAT(mul1 >> 15, 16);
|
||||
out2 = (q15_t) __SSAT(mul2 >> 15, 16);
|
||||
out3 = (q15_t) __SSAT(mul3 >> 15, 16);
|
||||
out4 = (q15_t) __SSAT(mul4 >> 15, 16);
|
||||
|
||||
/* store the result */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(out2, out1, 16);
|
||||
*__SIMD32(pDst)++ = __PKHBT(out4, out3, 16);
|
||||
|
||||
#else
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(out2, out1, 16);
|
||||
*__SIMD32(pDst)++ = __PKHBT(out4, out3, 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and store the result in the destination buffer */
|
||||
*pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++)) >> 15), 16);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicMult group
|
||||
*/
|
||||
@@ -0,0 +1,160 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mult_q31.c
|
||||
*
|
||||
* Description: Q31 vector multiplication.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 vector multiplication.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range[0x80000000 0x7FFFFFFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_mult_q31(
|
||||
q31_t * pSrcA,
|
||||
q31_t * pSrcB,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inA3, inA4; /* temporary input variables */
|
||||
q31_t inB1, inB2, inB3, inB4; /* temporary input variables */
|
||||
q31_t out1, out2, out3, out4; /* temporary output variables */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and then store the results in the destination buffer. */
|
||||
inA1 = *pSrcA++;
|
||||
inA2 = *pSrcA++;
|
||||
inA3 = *pSrcA++;
|
||||
inA4 = *pSrcA++;
|
||||
inB1 = *pSrcB++;
|
||||
inB2 = *pSrcB++;
|
||||
inB3 = *pSrcB++;
|
||||
inB4 = *pSrcB++;
|
||||
|
||||
out1 = ((q63_t) inA1 * inB1) >> 32;
|
||||
out2 = ((q63_t) inA2 * inB2) >> 32;
|
||||
out3 = ((q63_t) inA3 * inB3) >> 32;
|
||||
out4 = ((q63_t) inA4 * inB4) >> 32;
|
||||
|
||||
out1 = __SSAT(out1, 31);
|
||||
out2 = __SSAT(out2, 31);
|
||||
out3 = __SSAT(out3, 31);
|
||||
out4 = __SSAT(out4, 31);
|
||||
|
||||
*pDst++ = out1 << 1u;
|
||||
*pDst++ = out2 << 1u;
|
||||
*pDst++ = out3 << 1u;
|
||||
*pDst++ = out4 << 1u;
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and then store the results in the destination buffer. */
|
||||
inA1 = *pSrcA++;
|
||||
inB1 = *pSrcB++;
|
||||
out1 = ((q63_t) inA1 * inB1) >> 32;
|
||||
out1 = __SSAT(out1, 31);
|
||||
*pDst++ = out1 << 1u;
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and then store the results in the destination buffer. */
|
||||
*pDst++ =
|
||||
(q31_t) clip_q63_to_q31(((q63_t) (*pSrcA++) * (*pSrcB++)) >> 31);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicMult group
|
||||
*/
|
||||
@@ -0,0 +1,127 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_mult_q7.c
|
||||
*
|
||||
* Description: Q7 vector multiplication.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicMult
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 vector multiplication
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_mult_q7(
|
||||
q7_t * pSrcA,
|
||||
q7_t * pSrcB,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q7_t out1, out2, out3, out4; /* Temporary variables to store the product */
|
||||
|
||||
/* loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and store the results in temporary variables */
|
||||
out1 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
|
||||
out2 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
|
||||
out3 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
|
||||
out4 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
|
||||
|
||||
/* Store the results of 4 inputs in the destination buffer in single cycle by packing */
|
||||
*__SIMD32(pDst)++ = __PACKq7(out1, out2, out3, out4);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * B */
|
||||
/* Multiply the inputs and store the result in the destination buffer */
|
||||
*pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++)) >> 7), 8);
|
||||
|
||||
/* Decrement the blockSize loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicMult group
|
||||
*/
|
||||
@@ -0,0 +1,146 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_negate_f32.c
|
||||
*
|
||||
* Description: Negates floating-point vectors.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup negate Vector Negate
|
||||
*
|
||||
* Negates the elements of a vector.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = -pSrc[n], 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* The functions support in-place computation allowing the source and
|
||||
* destination pointers to reference the same memory buffer.
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup negate
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Negates the elements of a floating-point vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_negate_f32(
|
||||
float32_t * pSrc,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t in1, in2, in3, in4; /* temporary variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* read inputs from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* negate the input */
|
||||
in1 = -in1;
|
||||
in2 = -in2;
|
||||
in3 = -in3;
|
||||
in4 = -in4;
|
||||
|
||||
/* store the result to destination */
|
||||
*pDst = in1;
|
||||
*(pDst + 1) = in2;
|
||||
*(pDst + 2) = in3;
|
||||
*(pDst + 3) = in4;
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Negate and then store the results in the destination buffer. */
|
||||
*pDst++ = -*pSrc++;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of negate group
|
||||
*/
|
||||
@@ -0,0 +1,142 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_negate_q15.c
|
||||
*
|
||||
* Description: Negates Q15 vectors.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup negate
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Negates the elements of a Q15 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* \par Conditions for optimum performance
|
||||
* Input and output buffers should be aligned by 32-bit
|
||||
*
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q15 value -1 (0x8000) will be saturated to the maximum allowable positive value 0x7FFF.
|
||||
*/
|
||||
|
||||
void arm_negate_q15(
|
||||
q15_t * pSrc,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q15_t in;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
q31_t in1, in2; /* Temporary variables */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Read two inputs at a time */
|
||||
in1 = _SIMD32_OFFSET(pSrc);
|
||||
in2 = _SIMD32_OFFSET(pSrc + 2);
|
||||
|
||||
/* negate two samples at a time */
|
||||
in1 = __QSUB16(0, in1);
|
||||
|
||||
/* negate two samples at a time */
|
||||
in2 = __QSUB16(0, in2);
|
||||
|
||||
/* store the result to destination 2 samples at a time */
|
||||
_SIMD32_OFFSET(pDst) = in1;
|
||||
/* store the result to destination 2 samples at a time */
|
||||
_SIMD32_OFFSET(pDst + 2) = in2;
|
||||
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Negate and then store the result in the destination buffer. */
|
||||
in = *pSrc++;
|
||||
*pDst++ = (in == (q15_t) 0x8000) ? 0x7fff : -in;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of negate group
|
||||
*/
|
||||
@@ -0,0 +1,129 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_negate_q31.c
|
||||
*
|
||||
* Description: Negates Q31 vectors.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup negate
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Negates the elements of a Q31 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q31 value -1 (0x80000000) will be saturated to the maximum allowable positive value 0x7FFFFFFF.
|
||||
*/
|
||||
|
||||
void arm_negate_q31(
|
||||
q31_t * pSrc,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
q31_t in; /* Temporary variable */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t in1, in2, in3, in4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Negate and then store the results in the destination buffer. */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
in3 = *pSrc++;
|
||||
in4 = *pSrc++;
|
||||
|
||||
*pDst++ = __QSUB(0, in1);
|
||||
*pDst++ = __QSUB(0, in2);
|
||||
*pDst++ = __QSUB(0, in3);
|
||||
*pDst++ = __QSUB(0, in4);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Negate and then store the result in the destination buffer. */
|
||||
in = *pSrc++;
|
||||
*pDst++ = (in == INT32_MIN) ? INT32_MAX : -in;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of negate group
|
||||
*/
|
||||
@@ -0,0 +1,125 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_negate_q7.c
|
||||
*
|
||||
* Description: Negates Q7 vectors.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup negate
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Negates the elements of a Q7 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* The Q7 value -1 (0x80) will be saturated to the maximum allowable positive value 0x7F.
|
||||
*/
|
||||
|
||||
void arm_negate_q7(
|
||||
q7_t * pSrc,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q7_t in;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t input; /* Input values1-4 */
|
||||
q31_t zero = 0x00000000;
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Read four inputs */
|
||||
input = *__SIMD32(pSrc)++;
|
||||
|
||||
/* Store the Negated results in the destination buffer in a single cycle by packing the results */
|
||||
*__SIMD32(pDst)++ = __QSUB8(zero, input);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = -A */
|
||||
/* Negate and then store the results in the destination buffer. */ \
|
||||
in = *pSrc++;
|
||||
*pDst++ = (in == (q7_t) 0x80) ? 0x7f : -in;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of negate group
|
||||
*/
|
||||
@@ -0,0 +1,165 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_offset_f32.c
|
||||
*
|
||||
* Description: Floating-point vector offset.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup offset Vector Offset
|
||||
*
|
||||
* Adds a constant offset to each element of a vector.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrc[n] + offset, 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* The functions support in-place computation allowing the source and
|
||||
* destination pointers to reference the same memory buffer.
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup offset
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Adds a constant offset to a floating-point vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] offset is the offset to be added
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
|
||||
void arm_offset_f32(
|
||||
float32_t * pSrc,
|
||||
float32_t offset,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t in1, in2, in3, in4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination buffer. */
|
||||
/* read samples from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
|
||||
/* add offset to input */
|
||||
in1 = in1 + offset;
|
||||
|
||||
/* read samples from source */
|
||||
in3 = *(pSrc + 2);
|
||||
|
||||
/* add offset to input */
|
||||
in2 = in2 + offset;
|
||||
|
||||
/* read samples from source */
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* add offset to input */
|
||||
in3 = in3 + offset;
|
||||
|
||||
/* store result to destination */
|
||||
*pDst = in1;
|
||||
|
||||
/* add offset to input */
|
||||
in4 = in4 + offset;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 1) = in2;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 2) = in3;
|
||||
|
||||
/* store result to destination */
|
||||
*(pDst + 3) = in4;
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the result in the destination buffer. */
|
||||
*pDst++ = (*pSrc++) + offset;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of offset group
|
||||
*/
|
||||
@@ -0,0 +1,136 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_offset_q15.c
|
||||
*
|
||||
* Description: Q15 vector offset.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup offset
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Adds a constant offset to a Q15 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] offset is the offset to be added
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] are saturated.
|
||||
*/
|
||||
|
||||
void arm_offset_q15(
|
||||
q15_t * pSrc,
|
||||
q15_t offset,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t offset_packed; /* Offset packed to 32 bit */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* Offset is packed to 32 bit in order to use SIMD32 for addition */
|
||||
offset_packed = __PKHBT(offset, offset, 16);
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination buffer, 2 samples at a time. */
|
||||
*__SIMD32(pDst)++ = __QADD16(*__SIMD32(pSrc)++, offset_packed);
|
||||
*__SIMD32(pDst)++ = __QADD16(*__SIMD32(pSrc)++, offset_packed);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination buffer. */
|
||||
*pDst++ = (q15_t) __QADD16(*pSrc++, offset);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination buffer. */
|
||||
*pDst++ = (q15_t) __SSAT(((q31_t) * pSrc++ + offset), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of offset group
|
||||
*/
|
||||
@@ -0,0 +1,140 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_offset_q31.c
|
||||
*
|
||||
* Description: Q31 vector offset.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup offset
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Adds a constant offset to a Q31 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] offset is the offset to be added
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] are saturated.
|
||||
*/
|
||||
|
||||
void arm_offset_q31(
|
||||
q31_t * pSrc,
|
||||
q31_t offset,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t in1, in2, in3, in4;
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination buffer. */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
in3 = *pSrc++;
|
||||
in4 = *pSrc++;
|
||||
|
||||
*pDst++ = __QADD(in1, offset);
|
||||
*pDst++ = __QADD(in2, offset);
|
||||
*pDst++ = __QADD(in3, offset);
|
||||
*pDst++ = __QADD(in4, offset);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the result in the destination buffer. */
|
||||
*pDst++ = __QADD(*pSrc++, offset);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the result in the destination buffer. */
|
||||
*pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrc++ + offset);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of offset group
|
||||
*/
|
||||
@@ -0,0 +1,135 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_offset_q7.c
|
||||
*
|
||||
* Description: Q7 vector offset.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup offset
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Adds a constant offset to a Q7 vector.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] offset is the offset to be added
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q7 range [0x80 0x7F] are saturated.
|
||||
*/
|
||||
|
||||
void arm_offset_q7(
|
||||
q7_t * pSrc,
|
||||
q7_t offset,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t offset_packed; /* Offset packed to 32 bit */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* Offset is packed to 32 bit in order to use SIMD32 for addition */
|
||||
offset_packed = __PACKq7(offset, offset, offset, offset);
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the results in the destination bufferfor 4 samples at a time. */
|
||||
*__SIMD32(pDst)++ = __QADD8(*__SIMD32(pSrc)++, offset_packed);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT(*pSrc++ + offset, 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A + offset */
|
||||
/* Add offset and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT((q15_t) * pSrc++ + offset, 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of offset group
|
||||
*/
|
||||
@@ -0,0 +1,169 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_scale_f32.c
|
||||
*
|
||||
* Description: Multiplies a floating-point vector by a scalar.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup scale Vector Scale
|
||||
*
|
||||
* Multiply a vector by a scalar value. For floating-point data, the algorithm used is:
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrc[n] * scale, 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* In the fixed-point Q7, Q15, and Q31 functions, <code>scale</code> is represented by
|
||||
* a fractional multiplication <code>scaleFract</code> and an arithmetic shift <code>shift</code>.
|
||||
* The shift allows the gain of the scaling operation to exceed 1.0.
|
||||
* The algorithm used with fixed-point data is:
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = (pSrc[n] * scaleFract) << shift, 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* The overall scale factor applied to the fixed-point data is
|
||||
* <pre>
|
||||
* scale = scaleFract * 2^shift.
|
||||
* </pre>
|
||||
*
|
||||
* The functions support in-place computation allowing the source and destination
|
||||
* pointers to reference the same memory buffer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup scale
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Multiplies a floating-point vector by a scalar.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] scale scale factor to be applied
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
|
||||
void arm_scale_f32(
|
||||
float32_t * pSrc,
|
||||
float32_t scale,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t in1, in2, in3, in4; /* temporary variabels */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the results in the destination buffer. */
|
||||
/* read input samples from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
|
||||
/* multiply with scaling factor */
|
||||
in1 = in1 * scale;
|
||||
|
||||
/* read input sample from source */
|
||||
in3 = *(pSrc + 2);
|
||||
|
||||
/* multiply with scaling factor */
|
||||
in2 = in2 * scale;
|
||||
|
||||
/* read input sample from source */
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* multiply with scaling factor */
|
||||
in3 = in3 * scale;
|
||||
in4 = in4 * scale;
|
||||
/* store the result to destination */
|
||||
*pDst = in1;
|
||||
*(pDst + 1) = in2;
|
||||
*(pDst + 2) = in3;
|
||||
*(pDst + 3) = in4;
|
||||
|
||||
/* update pointers to process next samples */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (*pSrc++) * scale;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of scale group
|
||||
*/
|
||||
@@ -0,0 +1,162 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_scale_q15.c
|
||||
*
|
||||
* Description: Multiplies a Q15 vector by a scalar.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup scale
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Multiplies a Q15 vector by a scalar.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] scaleFract fractional portion of the scale value
|
||||
* @param[in] shift number of bits to shift the result by
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.15 format.
|
||||
* These are multiplied to yield a 2.30 intermediate result and this is shifted with saturation to 1.15 format.
|
||||
*/
|
||||
|
||||
|
||||
void arm_scale_q15(
|
||||
q15_t * pSrc,
|
||||
q15_t scaleFract,
|
||||
int8_t shift,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
int8_t kShift = 15 - shift; /* shift to apply after scaling */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q15_t in1, in2, in3, in4;
|
||||
q31_t inA1, inA2; /* Temporary variables */
|
||||
q31_t out1, out2, out3, out4;
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* Reading 2 inputs from memory */
|
||||
inA1 = *__SIMD32(pSrc)++;
|
||||
inA2 = *__SIMD32(pSrc)++;
|
||||
|
||||
/* C = A * scale */
|
||||
/* Scale the inputs and then store the 2 results in the destination buffer
|
||||
* in single cycle by packing the outputs */
|
||||
out1 = (q31_t) ((q15_t) (inA1 >> 16) * scaleFract);
|
||||
out2 = (q31_t) ((q15_t) inA1 * scaleFract);
|
||||
out3 = (q31_t) ((q15_t) (inA2 >> 16) * scaleFract);
|
||||
out4 = (q31_t) ((q15_t) inA2 * scaleFract);
|
||||
|
||||
/* apply shifting */
|
||||
out1 = out1 >> kShift;
|
||||
out2 = out2 >> kShift;
|
||||
out3 = out3 >> kShift;
|
||||
out4 = out4 >> kShift;
|
||||
|
||||
/* saturate the output */
|
||||
in1 = (q15_t) (__SSAT(out1, 16));
|
||||
in2 = (q15_t) (__SSAT(out2, 16));
|
||||
in3 = (q15_t) (__SSAT(out3, 16));
|
||||
in4 = (q15_t) (__SSAT(out4, 16));
|
||||
|
||||
/* store the result to destination */
|
||||
*__SIMD32(pDst)++ = __PKHBT(in2, in1, 16);
|
||||
*__SIMD32(pDst)++ = __PKHBT(in4, in3, 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q15_t) (__SSAT(((*pSrc++) * scaleFract) >> kShift, 16));
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q15_t) (__SSAT(((q31_t) * pSrc++ * scaleFract) >> kShift, 16));
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of scale group
|
||||
*/
|
||||
@@ -0,0 +1,239 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_scale_q31.c
|
||||
*
|
||||
* Description: Multiplies a Q31 vector by a scalar.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup scale
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Multiplies a Q31 vector by a scalar.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] scaleFract fractional portion of the scale value
|
||||
* @param[in] shift number of bits to shift the result by
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.31 format.
|
||||
* These are multiplied to yield a 2.62 intermediate result and this is shifted with saturation to 1.31 format.
|
||||
*/
|
||||
|
||||
void arm_scale_q31(
|
||||
q31_t * pSrc,
|
||||
q31_t scaleFract,
|
||||
int8_t shift,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
int8_t kShift = shift + 1; /* Shift to apply after scaling */
|
||||
int8_t sign = (kShift & 0x80);
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
q31_t in, out;
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
q31_t in1, in2, in3, in4; /* temporary input variables */
|
||||
q31_t out1, out2, out3, out4; /* temporary output variabels */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* read four inputs from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* multiply input with scaler value */
|
||||
in1 = ((q63_t) in1 * scaleFract) >> 32;
|
||||
in2 = ((q63_t) in2 * scaleFract) >> 32;
|
||||
in3 = ((q63_t) in3 * scaleFract) >> 32;
|
||||
in4 = ((q63_t) in4 * scaleFract) >> 32;
|
||||
|
||||
/* apply shifting */
|
||||
out1 = in1 << kShift;
|
||||
out2 = in2 << kShift;
|
||||
|
||||
/* saturate the results. */
|
||||
if(in1 != (out1 >> kShift))
|
||||
out1 = 0x7FFFFFFF ^ (in1 >> 31);
|
||||
|
||||
if(in2 != (out2 >> kShift))
|
||||
out2 = 0x7FFFFFFF ^ (in2 >> 31);
|
||||
|
||||
out3 = in3 << kShift;
|
||||
out4 = in4 << kShift;
|
||||
|
||||
*pDst = out1;
|
||||
*(pDst + 1) = out2;
|
||||
|
||||
if(in3 != (out3 >> kShift))
|
||||
out3 = 0x7FFFFFFF ^ (in3 >> 31);
|
||||
|
||||
if(in4 != (out4 >> kShift))
|
||||
out4 = 0x7FFFFFFF ^ (in4 >> 31);
|
||||
|
||||
/* Store result destination */
|
||||
*(pDst + 2) = out3;
|
||||
*(pDst + 3) = out4;
|
||||
|
||||
/* Update pointers to process next sampels */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* read four inputs from source */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* multiply input with scaler value */
|
||||
in1 = ((q63_t) in1 * scaleFract) >> 32;
|
||||
in2 = ((q63_t) in2 * scaleFract) >> 32;
|
||||
in3 = ((q63_t) in3 * scaleFract) >> 32;
|
||||
in4 = ((q63_t) in4 * scaleFract) >> 32;
|
||||
|
||||
/* apply shifting */
|
||||
out1 = in1 >> -kShift;
|
||||
out2 = in2 >> -kShift;
|
||||
|
||||
out3 = in3 >> -kShift;
|
||||
out4 = in4 >> -kShift;
|
||||
|
||||
/* Store result destination */
|
||||
*pDst = out1;
|
||||
*(pDst + 1) = out2;
|
||||
|
||||
*(pDst + 2) = out3;
|
||||
*(pDst + 3) = out4;
|
||||
|
||||
/* Update pointers to process next sampels */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
if(sign == 0)
|
||||
{
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
in = *pSrc++;
|
||||
in = ((q63_t) in * scaleFract) >> 32;
|
||||
|
||||
out = in << kShift;
|
||||
|
||||
if(in != (out >> kShift))
|
||||
out = 0x7FFFFFFF ^ (in >> 31);
|
||||
|
||||
*pDst++ = out;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
in = *pSrc++;
|
||||
in = ((q63_t) in * scaleFract) >> 32;
|
||||
|
||||
out = in >> -kShift;
|
||||
|
||||
*pDst++ = out;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of scale group
|
||||
*/
|
||||
@@ -0,0 +1,149 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_scale_q7.c
|
||||
*
|
||||
* Description: Multiplies a Q7 vector by a scalar.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup scale
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Multiplies a Q7 vector by a scalar.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] scaleFract fractional portion of the scale value
|
||||
* @param[in] shift number of bits to shift the result by
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The input data <code>*pSrc</code> and <code>scaleFract</code> are in 1.7 format.
|
||||
* These are multiplied to yield a 2.14 intermediate result and this is shifted with saturation to 1.7 format.
|
||||
*/
|
||||
|
||||
void arm_scale_q7(
|
||||
q7_t * pSrc,
|
||||
q7_t scaleFract,
|
||||
int8_t shift,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
int8_t kShift = 7 - shift; /* shift to apply after scaling */
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q7_t in1, in2, in3, in4, out1, out2, out3, out4; /* Temporary variables to store input & output */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* Reading 4 inputs from memory */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
in3 = *pSrc++;
|
||||
in4 = *pSrc++;
|
||||
|
||||
/* C = A * scale */
|
||||
/* Scale the inputs and then store the results in the temporary variables. */
|
||||
out1 = (q7_t) (__SSAT(((in1) * scaleFract) >> kShift, 8));
|
||||
out2 = (q7_t) (__SSAT(((in2) * scaleFract) >> kShift, 8));
|
||||
out3 = (q7_t) (__SSAT(((in3) * scaleFract) >> kShift, 8));
|
||||
out4 = (q7_t) (__SSAT(((in4) * scaleFract) >> kShift, 8));
|
||||
|
||||
/* Packing the individual outputs into 32bit and storing in
|
||||
* destination buffer in single write */
|
||||
*__SIMD32(pDst)++ = __PACKq7(out1, out2, out3, out4);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) (__SSAT(((*pSrc++) * scaleFract) >> kShift, 8));
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A * scale */
|
||||
/* Scale the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) (__SSAT((((q15_t) * pSrc++ * scaleFract) >> kShift), 8));
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of scale group
|
||||
*/
|
||||
@@ -0,0 +1,248 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_shift_q15.c
|
||||
*
|
||||
* Description: Shifts the elements of a Q15 vector by a specified number of bits.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup shift
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Shifts the elements of a Q15 vector a specified number of bits.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_shift_q15(
|
||||
q15_t * pSrc,
|
||||
int8_t shiftBits,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
uint8_t sign; /* Sign of shiftBits */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
|
||||
q15_t in1, in2; /* Temporary variables */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* Getting the sign of shiftBits */
|
||||
sign = (shiftBits & 0x80);
|
||||
|
||||
/* If the shift value is positive then do right shift else left shift */
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* Read 2 inputs */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
/* C = A << shiftBits */
|
||||
/* Shift the inputs and then store the results in the destination buffer. */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(__SSAT((in1 << shiftBits), 16),
|
||||
__SSAT((in2 << shiftBits), 16), 16);
|
||||
|
||||
#else
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(__SSAT((in2 << shiftBits), 16),
|
||||
__SSAT((in1 << shiftBits), 16), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(__SSAT((in1 << shiftBits), 16),
|
||||
__SSAT((in2 << shiftBits), 16), 16);
|
||||
|
||||
#else
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT(__SSAT((in2 << shiftBits), 16),
|
||||
__SSAT((in1 << shiftBits), 16), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Shift and then store the results in the destination buffer. */
|
||||
*pDst++ = __SSAT((*pSrc++ << shiftBits), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* Read 2 inputs */
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the inputs and then store the results in the destination buffer. */
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT((in1 >> -shiftBits),
|
||||
(in2 >> -shiftBits), 16);
|
||||
|
||||
#else
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT((in2 >> -shiftBits),
|
||||
(in1 >> -shiftBits), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
in1 = *pSrc++;
|
||||
in2 = *pSrc++;
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT((in1 >> -shiftBits),
|
||||
(in2 >> -shiftBits), 16);
|
||||
|
||||
#else
|
||||
|
||||
*__SIMD32(pDst)++ = __PKHBT((in2 >> -shiftBits),
|
||||
(in1 >> -shiftBits), 16);
|
||||
|
||||
#endif /* #ifndef ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the inputs and then store the results in the destination buffer. */
|
||||
*pDst++ = (*pSrc++ >> -shiftBits);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Getting the sign of shiftBits */
|
||||
sign = (shiftBits & 0x80);
|
||||
|
||||
/* If the shift value is positive then do right shift else left shift */
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Shift and then store the results in the destination buffer. */
|
||||
*pDst++ = __SSAT(((q31_t) * pSrc++ << shiftBits), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the inputs and then store the results in the destination buffer. */
|
||||
*pDst++ = (*pSrc++ >> -shiftBits);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of shift group
|
||||
*/
|
||||
@@ -0,0 +1,203 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_shift_q31.c
|
||||
*
|
||||
* Description: Shifts the elements of a Q31 vector by a specified number of bits.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
/**
|
||||
* @defgroup shift Vector Shift
|
||||
*
|
||||
* Shifts the elements of a fixed-point vector by a specified number of bits.
|
||||
* There are separate functions for Q7, Q15, and Q31 data types.
|
||||
* The underlying algorithm used is:
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrc[n] << shift, 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* If <code>shift</code> is positive then the elements of the vector are shifted to the left.
|
||||
* If <code>shift</code> is negative then the elements of the vector are shifted to the right.
|
||||
*
|
||||
* The functions support in-place computation allowing the source and destination
|
||||
* pointers to reference the same memory buffer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup shift
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Shifts the elements of a Q31 vector a specified number of bits.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_shift_q31(
|
||||
q31_t * pSrc,
|
||||
int8_t shiftBits,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
uint8_t sign = (shiftBits & 0x80); /* Sign of shiftBits */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
q31_t in1, in2, in3, in4; /* Temporary input variables */
|
||||
q31_t out1, out2, out3, out4; /* Temporary output variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Shift the input and then store the results in the destination buffer. */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
out1 = in1 << shiftBits;
|
||||
in3 = *(pSrc + 2);
|
||||
out2 = in2 << shiftBits;
|
||||
in4 = *(pSrc + 3);
|
||||
if(in1 != (out1 >> shiftBits))
|
||||
out1 = 0x7FFFFFFF ^ (in1 >> 31);
|
||||
|
||||
if(in2 != (out2 >> shiftBits))
|
||||
out2 = 0x7FFFFFFF ^ (in2 >> 31);
|
||||
|
||||
*pDst = out1;
|
||||
out3 = in3 << shiftBits;
|
||||
*(pDst + 1) = out2;
|
||||
out4 = in4 << shiftBits;
|
||||
|
||||
if(in3 != (out3 >> shiftBits))
|
||||
out3 = 0x7FFFFFFF ^ (in3 >> 31);
|
||||
|
||||
if(in4 != (out4 >> shiftBits))
|
||||
out4 = 0x7FFFFFFF ^ (in4 >> 31);
|
||||
|
||||
*(pDst + 2) = out3;
|
||||
*(pDst + 3) = out4;
|
||||
|
||||
/* Update destination pointer to process next sampels */
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the input and then store the results in the destination buffer. */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
*pDst = (in1 >> -shiftBits);
|
||||
*(pDst + 1) = (in2 >> -shiftBits);
|
||||
*(pDst + 2) = (in3 >> -shiftBits);
|
||||
*(pDst + 3) = (in4 >> -shiftBits);
|
||||
|
||||
|
||||
pSrc += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A (>> or <<) shiftBits */
|
||||
/* Shift the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (sign == 0u) ? clip_q63_to_q31((q63_t) * pSrc++ << shiftBits) :
|
||||
(*pSrc++ >> -shiftBits);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of shift group
|
||||
*/
|
||||
@@ -0,0 +1,220 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_shift_q7.c
|
||||
*
|
||||
* Description: Processing function for the Q7 Shifting
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup shift
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Shifts the elements of a Q7 vector a specified number of bits.
|
||||
* @param[in] *pSrc points to the input vector
|
||||
* @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in the vector
|
||||
* @return none.
|
||||
*
|
||||
* \par Conditions for optimum performance
|
||||
* Input and output buffers should be aligned by 32-bit
|
||||
*
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q7 range [0x8 0x7F] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_shift_q7(
|
||||
q7_t * pSrc,
|
||||
int8_t shiftBits,
|
||||
q7_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
uint8_t sign; /* Sign of shiftBits */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q7_t in1; /* Input value1 */
|
||||
q7_t in2; /* Input value2 */
|
||||
q7_t in3; /* Input value3 */
|
||||
q7_t in4; /* Input value4 */
|
||||
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* Getting the sign of shiftBits */
|
||||
sign = (shiftBits & 0x80);
|
||||
|
||||
/* If the shift value is positive then do right shift else left shift */
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Read 4 inputs */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* Store the Shifted result in the destination buffer in single cycle by packing the outputs */
|
||||
*__SIMD32(pDst)++ = __PACKq7(__SSAT((in1 << shiftBits), 8),
|
||||
__SSAT((in2 << shiftBits), 8),
|
||||
__SSAT((in3 << shiftBits), 8),
|
||||
__SSAT((in4 << shiftBits), 8));
|
||||
/* Update source pointer to process next sampels */
|
||||
pSrc += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Shift the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT((*pSrc++ << shiftBits), 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shiftBits = -shiftBits;
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Read 4 inputs */
|
||||
in1 = *pSrc;
|
||||
in2 = *(pSrc + 1);
|
||||
in3 = *(pSrc + 2);
|
||||
in4 = *(pSrc + 3);
|
||||
|
||||
/* Store the Shifted result in the destination buffer in single cycle by packing the outputs */
|
||||
*__SIMD32(pDst)++ = __PACKq7((in1 >> shiftBits), (in2 >> shiftBits),
|
||||
(in3 >> shiftBits), (in4 >> shiftBits));
|
||||
|
||||
|
||||
pSrc += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the input and then store the result in the destination buffer. */
|
||||
in1 = *pSrc++;
|
||||
*pDst++ = (in1 >> shiftBits);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Getting the sign of shiftBits */
|
||||
sign = (shiftBits & 0x80);
|
||||
|
||||
/* If the shift value is positive then do right shift else left shift */
|
||||
if(sign == 0u)
|
||||
{
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A << shiftBits */
|
||||
/* Shift the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (q7_t) __SSAT(((q15_t) * pSrc++ << shiftBits), 8);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A >> shiftBits */
|
||||
/* Shift the input and then store the result in the destination buffer. */
|
||||
*pDst++ = (*pSrc++ >> -shiftBits);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of shift group
|
||||
*/
|
||||
@@ -0,0 +1,150 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sub_f32.c
|
||||
*
|
||||
* Description: Floating-point vector subtraction.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup BasicSub Vector Subtraction
|
||||
*
|
||||
* Element-by-element subtraction of two vectors.
|
||||
*
|
||||
* <pre>
|
||||
* pDst[n] = pSrcA[n] - pSrcB[n], 0 <= n < blockSize.
|
||||
* </pre>
|
||||
*
|
||||
* There are separate functions for floating-point, Q7, Q15, and Q31 data types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicSub
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Floating-point vector subtraction.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*/
|
||||
|
||||
void arm_sub_f32(
|
||||
float32_t * pSrcA,
|
||||
float32_t * pSrcB,
|
||||
float32_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
float32_t inA1, inA2, inA3, inA4; /* temporary variables */
|
||||
float32_t inB1, inB2, inB3, inB4; /* temporary variables */
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the results in the destination buffer. */
|
||||
/* Read 4 input samples from sourceA and sourceB */
|
||||
inA1 = *pSrcA;
|
||||
inB1 = *pSrcB;
|
||||
inA2 = *(pSrcA + 1);
|
||||
inB2 = *(pSrcB + 1);
|
||||
inA3 = *(pSrcA + 2);
|
||||
inB3 = *(pSrcB + 2);
|
||||
inA4 = *(pSrcA + 3);
|
||||
inB4 = *(pSrcB + 3);
|
||||
|
||||
/* dst = srcA - srcB */
|
||||
/* subtract and store the result */
|
||||
*pDst = inA1 - inB1;
|
||||
*(pDst + 1) = inA2 - inB2;
|
||||
*(pDst + 2) = inA3 - inB3;
|
||||
*(pDst + 3) = inA4 - inB4;
|
||||
|
||||
|
||||
/* Update pointers to process next sampels */
|
||||
pSrcA += 4u;
|
||||
pSrcB += 4u;
|
||||
pDst += 4u;
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the results in the destination buffer. */
|
||||
*pDst++ = (*pSrcA++) - (*pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicSub group
|
||||
*/
|
||||
@@ -0,0 +1,140 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sub_q15.c
|
||||
*
|
||||
* Description: Q15 vector subtraction.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicSub
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 vector subtraction.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_sub_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
q15_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2;
|
||||
q31_t inB1, inB2;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the results in the destination buffer two samples at a time. */
|
||||
inA1 = *__SIMD32(pSrcA)++;
|
||||
inA2 = *__SIMD32(pSrcA)++;
|
||||
inB1 = *__SIMD32(pSrcB)++;
|
||||
inB2 = *__SIMD32(pSrcB)++;
|
||||
|
||||
*__SIMD32(pDst)++ = __QSUB16(inA1, inB1);
|
||||
*__SIMD32(pDst)++ = __QSUB16(inA2, inB2);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the result in the destination buffer. */
|
||||
*pDst++ = (q15_t) __QSUB16(*pSrcA++, *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the result in the destination buffer. */
|
||||
*pDst++ = (q15_t) __SSAT(((q31_t) * pSrcA++ - *pSrcB++), 16);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicSub group
|
||||
*/
|
||||
@@ -0,0 +1,146 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 19. March 2015
|
||||
* $Revision: V.1.4.5
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_sub_q31.c
|
||||
*
|
||||
* Description: Q31 vector subtraction.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form 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.
|
||||
* - Neither the name of ARM LIMITED nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER 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 "arm_math.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupMath
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup BasicSub
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q31 vector subtraction.
|
||||
* @param[in] *pSrcA points to the first input vector
|
||||
* @param[in] *pSrcB points to the second input vector
|
||||
* @param[out] *pDst points to the output vector
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q31 range [0x80000000 0x7FFFFFFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_sub_q31(
|
||||
q31_t * pSrcA,
|
||||
q31_t * pSrcB,
|
||||
q31_t * pDst,
|
||||
uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counter */
|
||||
|
||||
|
||||
#ifndef ARM_MATH_CM0_FAMILY
|
||||
|
||||
/* Run the below code for Cortex-M4 and Cortex-M3 */
|
||||
q31_t inA1, inA2, inA3, inA4;
|
||||
q31_t inB1, inB2, inB3, inB4;
|
||||
|
||||
/*loop Unrolling */
|
||||
blkCnt = blockSize >> 2u;
|
||||
|
||||
/* First part of the processing with loop unrolling. Compute 4 outputs at a time.
|
||||
** a second loop below computes the remaining 1 to 3 samples. */
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the results in the destination buffer. */
|
||||
inA1 = *pSrcA++;
|
||||
inA2 = *pSrcA++;
|
||||
inB1 = *pSrcB++;
|
||||
inB2 = *pSrcB++;
|
||||
|
||||
inA3 = *pSrcA++;
|
||||
inA4 = *pSrcA++;
|
||||
inB3 = *pSrcB++;
|
||||
inB4 = *pSrcB++;
|
||||
|
||||
*pDst++ = __QSUB(inA1, inB1);
|
||||
*pDst++ = __QSUB(inA2, inB2);
|
||||
*pDst++ = __QSUB(inA3, inB3);
|
||||
*pDst++ = __QSUB(inA4, inB4);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
|
||||
** No loop unrolling is used. */
|
||||
blkCnt = blockSize % 0x4u;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the result in the destination buffer. */
|
||||
*pDst++ = __QSUB(*pSrcA++, *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Run the below code for Cortex-M0 */
|
||||
|
||||
/* Initialize blkCnt with number of samples */
|
||||
blkCnt = blockSize;
|
||||
|
||||
while(blkCnt > 0u)
|
||||
{
|
||||
/* C = A - B */
|
||||
/* Subtract and then store the result in the destination buffer. */
|
||||
*pDst++ = (q31_t) clip_q63_to_q31((q63_t) * pSrcA++ - *pSrcB++);
|
||||
|
||||
/* Decrement the loop counter */
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of BasicSub group
|
||||
*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user