diff --git a/README.md b/README.md index 2beca6f704c26c7e6d04a2baac99c786e382f1cd..680437c40e65c5691baf5e63c20cfa158368d702 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## 介绍 - open_mcu代码仓为支持3061M和3065M解决方案SDK。 + open_mcu代码仓为支持3061M、3065H、3066M解决方案SDK。 ## 购买渠道 @@ -30,9 +30,9 @@ | ECBMCU105H![](docs/pic/readme/3061M.png) | [开发板硬件原理图](https://gitee.com/HiSpark/open_mcu/tree/master/docs/hardware/3065H) | 参考示例教程 | [开发板购买链接](https://m.tb.cn/h.gMEbHlepTLs5DNB?tk=aKIe356U3bY) | 3065H是RISC-V内核的高性能实时控制专用MCU, 具有高性能、高集成度、高可靠性、易开发的特点,同时配合强大的算法团队和嵌入式AI能力,使得3065H上市后快速获得家电、能源、工业等行业内多个客户的认可和好评。 | ## 支持的调试器 -| 调试器名称 | 使用说明 | 购买链接 | 调试器介绍 | -| :----------------------------------------------------------: | ------------------------------------------------------------ | ------------------------------------------------------------ | ----------------------------------------------- | -| ![image-20250121114616068](./docs/pic/tools/image-20250121114616068.png) | [HiSpark调试器系列 使用指南](https://gitee.com/HiSpark/open_mcu/tree/master/tools) | [调试器购买链接](https://e.tb.cn/h.T8tE2Ot1oR359nj?tk=Fy3He1qiATn) | ARM 仿真调试器 Hispark 烧录器 4合1调试器 编码器 | +| 调试器名称 | 使用说明 | 购买链接 | 调试器介绍 | +| :----------------------------------------------------------: | ------------------------------------------------------------ | ------------------------------------------------------------ | ---------------------------------------- | +| ![image-20250121114616068](./docs/pic/tools/image-20250121114616068.png) | [HiSpark调试器系列 使用指南](https://gitee.com/HiSpark/open_mcu/tree/master/tools) | [调试器购买链接](https://e.tb.cn/h.T8tE2Ot1oR359nj?tk=Fy3He1qiATn) | ARM 仿真调试器 Hispark 烧录器 4合1调试器 | @@ -46,7 +46,7 @@ ## 示例教程 -ECBMCU201MPC、ECBMCU105H提供了以下Demo供开发参考: +ECBMCU201MPC、ECBMCU105H、ECBMCU301M提供了以下Demo供开发参考: @@ -269,7 +269,7 @@ ECBMOTORA是电机驱动扩展板,支持一个 BLDC或 PMSM电机控制。该 ![image-20240715162244103](docs/pic/tools/image-20240715162244103.png) -3061M通用生态板用户手册详细内容请查阅:3061M系列 通用生态板用户手册 00B01 +3061M通用生态板用户手册详细内容请查阅:3061M系列 通用生态板用户手册 00B01 ### 3065H介绍 @@ -289,7 +289,29 @@ ECBMOTORA是电机驱动扩展板,支持一个 BLDC 或 PMSM 电机控制。 ![image-20240527103127826](docs/pic/tools/image-20240527103127826.png) -3065H通用生态板用户手册详细内容请查阅:3065H通用生态板用户手册 V03 +3065H通用生态板用户手册详细内容请查阅:3065H通用生态板用户手册 V03 + +### 3066M介绍 + +3065H 通用生态板由 ECBMCU301M (核心板)和 ECBMOTORA (电机驱动板)组成。 + +ECBMCU301M是针对 3066M 生态核心板,用于 3066M 初始评估和设计参考,内嵌一块 USB 接口的调试板。 + +ECBMOTORA是电机驱动扩展板,支持一个 BLDC 或 PMSM 电机控制。该单板支持24V/12V DCIN 输入。 + +核心板电机驱动扩展板的常用组装方式是电机驱动板通过两个40pin 连接器扣接到核心板,如下图所示。 + +image-20240530173305431 + +### 3066M硬件说明 + + 3066M通用生态板通过ECBMCU301M 核心板实现控制、 ECBMOTORA 扩展板实现接口扩展以及电源接口,同时提供USB TypeC线进行调试 / 供电、12V电源适配器和一个电机。 + +![image-20240527103127826](docs/pic/tools/image-20240527103127826.png) + +3066M通用生态板用户手册详细内容请查阅:3066M通用生态板用户手册 V00B01 + + ## 开发环境搭建 @@ -297,7 +319,7 @@ ECBMOTORA是电机驱动扩展板,支持一个 BLDC 或 PMSM 电机控制。 ## Demo -3061M/3065H提供了以下Demo供开发参考,sample存放路径:[application_sample](https://gitee.com/HiSpark/open_mcu/tree/master/src/application) +3061M/3065H/3066M提供了以下Demo供开发参考,sample存放路径:[application_sample](https://gitee.com/HiSpark/open_mcu/tree/master/src/application) **主目录结构说明** diff --git a/src/README.md b/src/README.md index e827e701ec2e8a6889160b2d8a66f25963394fa7..63873b0df8918767242ceee5efafd3ee454c8f9f 100644 --- a/src/README.md +++ b/src/README.md @@ -1,4 +1,4 @@ -SolarA2 1.0.1.2 +SolarA2_1.1.0.1 # 目录整体结构 **表 1** 目录整体结构说明 diff --git a/src/Version.md b/src/Version.md index d8b177f6199eeb46284a902731abd4e93a17d07c..c1735a2b9fde3d7778a4f724f53f71ce38dbdafc 100644 --- a/src/Version.md +++ b/src/Version.md @@ -1,3 +1,3 @@ # driver -Version : SolarA2_1.0.1.2 \ No newline at end of file +Version : SolarA2_1.1.0.1 diff --git a/src/application/drivers_sample/acmp/sample_acmp/init/main.c b/src/application/drivers_sample/acmp/sample_acmp/init/main.c index a27060e7ff338b085c487b271955b26c22975996..93930569aa1fdc719b662b912ca2dc8f74f3f746 100644 --- a/src/application/drivers_sample/acmp/sample_acmp/init/main.c +++ b/src/application/drivers_sample/acmp/sample_acmp/init/main.c @@ -19,15 +19,39 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" #include "main.h" - +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ ACMP_Handle g_acmp1; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ SystemInit(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/acmp/sample_acmp/init/main.h b/src/application/drivers_sample/acmp/sample_acmp/init/main.h index 6fdb77a4d48bf21b0c4488f40f9aaa0ec7f79aaf..c3693a552da385f7d586bfe1fd4e6f08e05bd966 100644 --- a/src/application/drivers_sample/acmp/sample_acmp/init/main.h +++ b/src/application/drivers_sample/acmp/sample_acmp/init/main.h @@ -35,9 +35,18 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern ACMP_Handle g_acmp1; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/acmp/sample_acmp/init/system_init.c b/src/application/drivers_sample/acmp/sample_acmp/init/system_init.c index 7d6d9fe21045e77b43ba8a71a981e2a2c7930405..f6f5f32e9ff4e861e77264b89da80d3236947ffc 100644 --- a/src/application/drivers_sample/acmp/sample_acmp/init/system_init.c +++ b/src/application/drivers_sample/acmp/sample_acmp/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { @@ -32,6 +33,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -41,44 +43,41 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void ACMP1_Init(void) { - g_acmp1.baseAddress = ACMP1_BASE; + HAL_CRG_IpEnableSet(ACMP1_BASE, BASE_CFG_ENABLE); /* Enable ACMP clock */ + + g_acmp1.baseAddress = ACMP1_BASE; /* ACMP baseAddr */ - g_acmp1.enable = true; - g_acmp1.syncEn = false; - g_acmp1.inOutConfig.vinNNum = ACMP_VIN_MUX3; /* input select */ - g_acmp1.inOutConfig.vinPNum = ACMP_VIN_MUX3; /* input select */ + g_acmp1.inOutConfig.vinNNum = ACMP_VIN_MUX3; /* input channel 3 */ + g_acmp1.inOutConfig.vinPNum = ACMP_VIN_MUX3; /* input channel 3 */ g_acmp1.inOutConfig.swVinPNum = ACMP_SW_VIN3; g_acmp1.inOutConfig.swVinNNum = ACMP_SW_VIN3; - g_acmp1.inOutConfig.polarity = ACMP_OUT_NOT_INVERT; - g_acmp1.filterCtrl.filterMode = ACMP_FILTER_NONE; /* filter level */ - g_acmp1.hysteresisVol = 0; /* 0: without hysteresis */ + g_acmp1.inOutConfig.polarity = ACMP_OUT_NOT_INVERT; /* ACMP out not invert */ + g_acmp1.filterCtrl.filterMode = ACMP_FILTER_NONE; + g_acmp1.hysteresisVol = ACMP_HYS_VOL_30MV; /* 30mv: without hysteresis */ HAL_ACMP_Init(&g_acmp1); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_18.BIT.func = 0x9; /* 0x9 is ACMP1_ANA_N */ - iconfig->iocmg_18.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_18.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_18.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_18.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_18.BIT.se = BASE_CFG_DISABLE; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; + HAL_IOCMG_SetPinAltFuncMode(IO2_AS_ACMP1_ANA_N2); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO2_AS_ACMP1_ANA_N2, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO2_AS_ACMP1_ANA_N2, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO2_AS_ACMP1_ANA_N2, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO2_AS_ACMP1_ANA_N2, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_21.BIT.func = 0x9; /* 0x9 is ACMP1_ANA_P */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_ACMP1_ANA_P2); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_ACMP1_ANA_P2, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_ACMP1_ANA_P2, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_ACMP1_ANA_P2, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_ACMP1_ANA_P2, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_26.BIT.func = 0x2; /* 0x2 is ACMP1_OUT */ - iconfig->iocmg_26.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_26.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_26.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_26.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_26.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO10_AS_ACMP1_OUT); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO10_AS_ACMP1_OUT, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO10_AS_ACMP1_OUT, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO10_AS_ACMP1_OUT, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO10_AS_ACMP1_OUT, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/acmp/sample_acmp/readme.md b/src/application/drivers_sample/acmp/sample_acmp/readme.md index 3c3ec24e23b4ed246986c95cea2f0f5286fcddf8..320d65c715e22707da7893219329ddb0d52df46d 100644 --- a/src/application/drivers_sample/acmp/sample_acmp/readme.md +++ b/src/application/drivers_sample/acmp/sample_acmp/readme.md @@ -1,18 +1,21 @@ -# 模拟比较器-对比IOCMG_21和IOCMG_18的输入电压值 +# 模拟比较器-比较差分运算放大器的正输入端ACMP_ANA_P和负输入端ACMP_ANA_N的大小,并将比较结果输出至ACMP_OUT管脚 ## 关键字: ACMP, 电压比较 **【功能描述】** -+ 对两个输入源进行电压比较,输出比较结果。输入和输出信号都可配,本示例中的输入的正端信号为IOCMG_18,输入的负端信号为IOCMG_18,在IOCMG_26输出比较结果。 ++ 对两个输入源进行电压比较,输出比较结果。输入和输出信号都可配,本示例中的输入的正端信号ACMP_ANA_P和负端信号ACMP_ANA_N均为IO管脚输入,用户需手动接入两个模拟输入信号,输出结果在ACMP_OUT管脚输出。 **【示例配置】** + ACMP的输入比较信号,可在ACMP配置界面中,配置“Input And Output Setting”进行更改。 -+ 当配置的正端的电压值高于负端的电压值时输出高,反之则输出低。示例中输入源、输出的配置,可以通过ACMP的配置界面,或在“system_init.c”文件中修改ACMP初始化代码实现。 ++ 输出极性不翻转时,当配置的正端的电压值高于负端的电压值时输出高,反之则输出低。示例中输入源、输出的配置,可以通过ACMP的配置界面,或在“system_init.c”文件中修改ACMP初始化代码实现。 **【示例效果】** -+ 当用户烧录编译后的示例代码后,ACMP初始化和配置完成后,会在IOCMG_26输出输入源的比较结果。用户可以通过交换输入源信号,并测量输出端的电压,比较输入源的电压大小。 ++ 当用户烧录编译后的示例代码后,ACMP初始化和配置完成后,会在ACMP_OUT管脚输出输入源的比较结果。用户可以通过交换输入源信号,并测量输出端的电压,比较输入源的电压大小。 **【注意事项】** + 输入的比较电压不能超过0V~输入电源大小(3.3V)。 ++ 最小可识别有效差分输入电压为20mV。 -+ 最小可识别有效差分输入电压为20mV。 \ No newline at end of file ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/acmp/sample_acmp_interrupt/readme.md b/src/application/drivers_sample/acmp/sample_acmp_interrupt/readme.md index f66fcc0bdd5e0d6a6e1c0fb6c50d455f923180e0..1997151b28c2695848bb636a62ccd7bb3140bd0f 100644 --- a/src/application/drivers_sample/acmp/sample_acmp_interrupt/readme.md +++ b/src/application/drivers_sample/acmp/sample_acmp_interrupt/readme.md @@ -12,9 +12,13 @@ + ACMP的比较结果输出,当配置的正端的电压值高于负端的电压值时输出高,反之则输出低。示例中输入源、输出的配置,可以通过ACMP的配置界面,或在“system_init.c”文件中修改ACMP初始化代码实现。 **【示例效果】** -+ 当用户烧录编译后的示例代码后,ACMP初始化和配置完成后,会在IOCMG_26输出输入源的比较结果,并调用触发相应的回调函数,用户可以通过交换输入源信号,并测量输出端的电压,比较输入源的电压大小。 ++ 当用户烧录编译后的示例代码后,ACMP初始化和配置完成后,会在ACMP_OUT输出输入源的比较结果,并调用触发相应的回调函数,用户可以通过交换输入源信号,并测量输出端的电压,比较输入源的电压大小。 **【注意事项】** + 输入的比较电压不能超过0V~输入电源大小(3.3V)。 -+ 最小可识别有效差分输入电压为20mV。 \ No newline at end of file ++ 最小可识别有效差分输入电压为20mV。 + ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/acmp/sample_acmp_out_result/readme.md b/src/application/drivers_sample/acmp/sample_acmp_out_result/readme.md index 7992f5e80a8cfa77ec3c6112f15c2bc0881627e7..9999c6cd27362be6ca8472857da057f40b10022c 100644 --- a/src/application/drivers_sample/acmp/sample_acmp_out_result/readme.md +++ b/src/application/drivers_sample/acmp/sample_acmp_out_result/readme.md @@ -2,7 +2,7 @@ ## 关键字: ACMP, DAC内部输入 **【功能描述】** -+ 对两个输入源进行电压比较,输出比较结果。输入和输出信号都可配,本示例中的输入的N端信号为DAC的内部输出,输入的P端信号为GPIO2_6,在GPIO0_7中输出比较结 果。 ++ 对两个输入源进行电压比较,输出比较结果。输入和输出信号都可配,本示例中的输入的P端信号为DAC的内部输出,输入的N端信号为GPIO输入,在ACMPx_OUT管脚中输出比较结果。 **【示例配置】** + ACMP的输入比较信号,可在ACMP配置界面中,配置“Input And Output Setting”进行更改。 @@ -15,4 +15,8 @@ **【注意事项】** + 输入的比较电压不能超过0V~输入电源大小(3.3V)。 -+ 最小可识别有效差分输入电压为20mV。 \ No newline at end of file ++ 最小可识别有效差分输入电压为20mV。 + ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_associative_trigger_of_apt/init/system_init.c b/src/application/drivers_sample/adc/sample_adc_associative_trigger_of_apt/init/system_init.c index ca9b700761a6bc4da2600cd3c5663887368e9250..f38b822c2a3976a15efe86d0e2aedbb672fda259 100644 --- a/src/application/drivers_sample/adc/sample_adc_associative_trigger_of_apt/init/system_init.c +++ b/src/application/drivers_sample/adc/sample_adc_associative_trigger_of_apt/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,42 +46,64 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) __weak void ADC_Init2FromApt(ADC_Handle *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN ADC_Init2FromApt */ - /* USER CODE END ADC_Init2FromApt */ + /* USER CODE BEGIN ADC2_CALLBACK_INT2 */ + /* USER CODE END ADC2_CALLBACK_INT2 */ } -static void ADC1_Init(void) +static void ADC2_Init(void) { - HAL_CRG_IpEnableSet(ADC1_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(ADC1_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); - HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); + HAL_CRG_IpEnableSet(ADC2_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(ADC2_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); /* select PLL as clock. */ + HAL_CRG_IpClkDivSet(ADC2_BASE, CRG_ADC_DIV_5); - g_adc.baseAddress = ADC1; + g_adc.baseAddress = ADC2; g_adc.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc.vrefBuf = ADC_VREF_2P5V; - g_adc.irqNumOver = IRQ_ADC1_OVINT; - g_adc.ADC_IntxParam[0].irqNum = IRQ_ADC1_INT1; /* interrupt 0 */ - g_adc.ADC_IntxParam[1].irqNum = IRQ_ADC1_INT2; /* interrupt 1 */ - g_adc.ADC_IntxParam[2].irqNum = IRQ_ADC1_INT3; /* interrupt 2 */ - g_adc.ADC_IntxParam[3].irqNum = IRQ_ADC1_INT4; /* interrupt 3 */ + g_adc.handleEx.vrefBuf = ADC_VREF_2P5V; HAL_ADC_Init(&g_adc); SOC_Param socParam = {0}; - socParam.adcInput = ADC_CH_ADCINA1; + socParam.adcInput = ADC_CH_ADCINA7; /* PIN36(ADC INA7) */ socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ socParam.sampleTotalTime = 127; /* adc sample total time 127 adc_clk */ socParam.softTrigSource = ADC_TRIGSOC_NONESOFT; socParam.intTrigSource = ADC_TRIGSOC_NONEINT; - socParam.periphTrigSource = ADC_TRIGSOC_APT0_SOCA; + socParam.periphTrigSource = ADC_TRIGSOC_APT0_SOCA; /* select apt0 as TrigSource */ socParam.finishMode = ADC_SOCFINISH_INT2; HAL_ADC_ConfigureSoc(&g_adc, ADC_SOC_NUM1, &socParam); + HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_INT2, (ADC_CallbackType)ADC_Init2FromApt); + + IRQ_Register(IRQ_ADC2_INT2, HAL_ADC_IrqHandlerInt2, &g_adc); + IRQ_SetPriority(IRQ_ADC2_INT2, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_ADC2_INT2); +} + +__weak void APT0EventCallback(void *aptHandle) +{ + BASE_FUNC_UNUSED(aptHandle); + /* USER CODE BEGIN APT0_EVENT_INTERRUPT */ + /* USER CODE END APT0_EVENT_INTERRUPT */ +} - HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_INT2, ADC_Init2FromApt); - IRQ_SetPriority(IRQ_ADC1_INT2, 4); /* Set the priority to level 4 */ - IRQ_EnableN(IRQ_ADC1_INT2); - HAL_ADC_IrqService(&g_adc); +__weak void APT0TimerCallback(void *aptHandle) +{ + BASE_FUNC_UNUSED(aptHandle); + /* USER CODE BEGIN APT0_TIMER_INTERRUPT */ + /* USER CODE END APT0_TIMER_INTERRUPT */ +} + +static void APT0_ProtectInit(void) +{ + APT_OutCtrlProtectEx protectApt = {0}; + protectApt.ocEventEnEx = BASE_CFG_ENABLE; + protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; + protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; /* APT protection action. */ + protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; + protectApt.ocEvtInterruptEnEx = BASE_CFG_ENABLE; /* Enable APT even interrupt. */ + protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; + protectApt.filterCycleNumEx = 0; + HAL_APT_ProtectInitEx(&g_hAptU, &protectApt); } static void APT0_Init(void) @@ -87,34 +111,32 @@ static void APT0_Init(void) HAL_CRG_IpEnableSet(APT0_BASE, IP_CLK_ENABLE); g_hAptU.baseAddress = APT0; - g_hAptU.irqNumEvt = IRQ_APT0_EVT; - g_hAptU.irqNumTmr = IRQ_APT0_TMR; /* Clock Settings */ g_hAptU.waveform.dividerFactor = 1 - 1; /* Timer Settings */ - g_hAptU.waveform.timerPeriod = 20000; /* timerPeriod is 20000 */ + g_hAptU.waveform.timerPeriod = 20000; /* 20000 is count period of APT time-base timer */ g_hAptU.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; /* Wave Form */ g_hAptU.waveform.basicType = APT_PWM_BASIC_A_LOW_B_HIGH; g_hAptU.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; g_hAptU.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; - g_hAptU.waveform.divInitVal = 0U; - g_hAptU.waveform.cntInitVal = 0U; - g_hAptU.waveform.cntCmpLeftEdge = 1; - g_hAptU.waveform.cntCmpRightEdge = 19999; /* cntCmpRightEdge is 19999 */ + g_hAptU.waveform.divInitVal = 0; + g_hAptU.waveform.cntInitVal = 0; + g_hAptU.waveform.cntCmpLeftEdge = 1; /* 1 is count compare point of the left edge of PWM waveform */ + g_hAptU.waveform.cntCmpRightEdge = 19999; /* 19999 is count compare point of the right edge of PWM waveform */ g_hAptU.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_hAptU.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; - g_hAptU.waveform.deadBandCnt = 60; /* deadBandCnt is 60 */ + g_hAptU.waveform.deadBandCnt = 60; /* 60 is dead-band value */ - /* ADC Triggle SOCA */ + /* ADC Trigger SOCA */ g_hAptU.adcTrg.trgEnSOCA = BASE_CFG_ENABLE; - g_hAptU.adcTrg.cntCmpSOCA = 1; + g_hAptU.adcTrg.cntCmpSOCA = 1; /* 1 is count compare point of ADC trigger source SOCA when using CMPA */ g_hAptU.adcTrg.trgSrcSOCA = APT_CS_SRC_CNTR_CMPA_UP; g_hAptU.adcTrg.trgScaleSOCA = 1; - /* ADC Triggle SOCB */ + /* ADC Trigger SOCB */ g_hAptU.adcTrg.trgEnSOCB = BASE_CFG_ENABLE; g_hAptU.adcTrg.cntCmpSOCB = 1; g_hAptU.adcTrg.trgSrcSOCB = APT_CS_SRC_CNTR_CMPB_UP; @@ -123,22 +145,23 @@ static void APT0_Init(void) g_hAptU.adcTrg.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_hAptU.adcTrg.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; - /* Timer Triggle */ + /* Timer Trigger */ g_hAptU.tmrInterrupt.tmrInterruptEn = BASE_CFG_ENABLE; g_hAptU.tmrInterrupt.tmrInterruptSrc = APT_INT_SRC_CNTR_ZERO_PERIOD; g_hAptU.tmrInterrupt.tmrInterruptScale = 1; - /* Output Protect */ - g_hProtectU.ocEventEn = BASE_CFG_ENABLE; - g_hProtectU.ocEventMode = APT_OUT_CTRL_ONE_SHOT; - g_hProtectU.evtPolarity = APT_EM_EVENT_POLARITY_INVERT; - g_hProtectU.ocEvent = APT_OC_GPIO_EVENT_1; - g_hProtectU.cbcClrMode = APT_CLEAR_CBC_ON_CNTR_ZERO; - g_hProtectU.ocAction = APT_OUT_CTRL_ACTION_LOW; - g_hProtectU.ocEvtInterruptEn = true; - HAL_APT_ProtectInit(&g_hAptU, &g_hProtectU); + APT0_ProtectInit(); HAL_APT_PWMInit(&g_hAptU); + IRQ_Register(IRQ_APT0_EVT, HAL_APT_EventIrqHandler, &g_hAptU); + HAL_APT_RegisterCallBack(&g_hAptU, APT_EVENT_INTERRUPT, APT0EventCallback); + IRQ_SetPriority(IRQ_APT0_EVT, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_APT0_EVT); + + IRQ_Register(IRQ_APT0_TMR, HAL_APT_TimerIrqHandler, &g_hAptU); + HAL_APT_RegisterCallBack(&g_hAptU, APT_TIMER_INTERRUPT, APT0TimerCallback); + IRQ_SetPriority(IRQ_APT0_TMR, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_APT0_TMR); } static void UART0_Init(void) @@ -147,7 +170,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -164,42 +186,36 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_21.BIT.func = 0x8; /* 0x8 is ADC1_ANA_A1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_32.BIT.func = 0x3; /* 0x3 is APT0_PWMA */ - iconfig->iocmg_32.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_32.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_32.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_32.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_32.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_35.BIT.func = 0x3; /* 0x3 is APT0_PWMB */ - iconfig->iocmg_35.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_35.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_35.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_35.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_35.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + /* Config PIN15 */ + HAL_IOCMG_SetPinAltFuncMode(IO15_AS_APT0_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO15_AS_APT0_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO15_AS_APT0_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO15_AS_APT0_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO15_AS_APT0_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN18 */ + HAL_IOCMG_SetPinAltFuncMode(IO18_AS_APT0_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO18_AS_APT0_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO18_AS_APT0_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO18_AS_APT0_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO18_AS_APT0_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN36 */ + HAL_IOCMG_SetPinAltFuncMode(IO36_AS_ADC2_ANA_A7); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO36_AS_ADC2_ANA_A7, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO36_AS_ADC2_ANA_A7, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO36_AS_ADC2_ANA_A7, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO36_AS_ADC2_ANA_A7, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -207,7 +223,7 @@ void SystemInit(void) IOConfig(); UART0_Init(); APT0_Init(); - ADC1_Init(); + ADC2_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/adc/sample_adc_associative_trigger_of_apt/readme.md b/src/application/drivers_sample/adc/sample_adc_associative_trigger_of_apt/readme.md index 5792eef5287eedb2965aa69c0d7e1d8063141072..9d40df17bfeda6e208ecff198e12f7cd13765483 100644 --- a/src/application/drivers_sample/adc/sample_adc_associative_trigger_of_apt/readme.md +++ b/src/application/drivers_sample/adc/sample_adc_associative_trigger_of_apt/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中APT会周期性的对ADC进行触发采样。采样成功后,会通过串口打印中断服务函数内读取到的ADC采样结果。在串口打印输出中,会不断打印中断回调函数中读出的ADC采样结果。 **【注意事项】** -+ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 \ No newline at end of file ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_continue_trigger/init/system_init.c b/src/application/drivers_sample/adc/sample_adc_continue_trigger/init/system_init.c index d94418ac1190d1c63d63a2d811cc7729e9dd78fb..dfadf468bd01daafde081d52884afe9c69109fa4 100644 --- a/src/application/drivers_sample/adc/sample_adc_continue_trigger/init/system_init.c +++ b/src/application/drivers_sample/adc/sample_adc_continue_trigger/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,29 +46,24 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) __weak void ADC_ContinueInt(ADC_Handle *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN ADC_ContinueInt */ - /* USER CODE END ADC_ContinueInt */ + /* USER CODE BEGIN ADC1_CALLBACK_INT2 */ + /* USER CODE END ADC1_CALLBACK_INT2 */ } static void ADC1_Init(void) { HAL_CRG_IpEnableSet(ADC1_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(ADC1_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); + HAL_CRG_IpClkSelectSet(ADC1_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); /* Select PLL as clock. */ HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); g_adc.baseAddress = ADC1; - g_adc.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc.vrefBuf = ADC_VREF_2P5V; - g_adc.irqNumOver = IRQ_ADC1_OVINT; - g_adc.ADC_IntxParam[0].irqNum = IRQ_ADC1_INT1; /* interrupt 0 */ - g_adc.ADC_IntxParam[1].irqNum = IRQ_ADC1_INT2; /* interrupt 1 */ - g_adc.ADC_IntxParam[2].irqNum = IRQ_ADC1_INT3; /* interrupt 2 */ - g_adc.ADC_IntxParam[3].irqNum = IRQ_ADC1_INT4; /* interrupt 3 */ + g_adc.socPriority = ADC_PRIMODE_ALL_PRIORITY; + g_adc.handleEx.vrefBuf = ADC_VREF_2P5V; - HAL_ADC_Init(&g_adc); + HAL_ADC_Init(&g_adc); /* ADC init. */ SOC_Param socParam = {0}; - socParam.adcInput = ADC_CH_ADCINA1; + socParam.adcInput = ADC_CH_ADCINA1; /* PIN5(ADC INA1) */ socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ socParam.sampleTotalTime = 127; /* adc sample total time 127 adc_clk */ @@ -75,11 +72,10 @@ static void ADC1_Init(void) socParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; socParam.finishMode = ADC_SOCFINISH_INT2; HAL_ADC_ConfigureSoc(&g_adc, ADC_SOC_NUM1, &socParam); - - HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_INT2, ADC_ContinueInt); - IRQ_SetPriority(IRQ_ADC1_INT2, 4); /* Set the priority to level 4 */ + HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_INT2, (ADC_CallbackType)ADC_ContinueInt); + IRQ_Register(IRQ_ADC1_INT2, HAL_ADC_IrqHandlerInt2, &g_adc); + IRQ_SetPriority(IRQ_ADC1_INT2, 4); /* 4 is priority value */ IRQ_EnableN(IRQ_ADC1_INT2); - HAL_ADC_IrqService(&g_adc); } static void UART0_Init(void) @@ -88,7 +84,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -105,35 +100,29 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_21.BIT.func = 0x8; /* 0x8 is ADC1_ANA_A1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_ADC1_ANA_A1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_ADC1_ANA_A1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_ADC1_ANA_A1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_ADC1_ANA_A1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_ADC1_ANA_A1, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); - ADC1_Init(); UART0_Init(); + ADC1_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/adc/sample_adc_continue_trigger/readme.md b/src/application/drivers_sample/adc/sample_adc_continue_trigger/readme.md index 8de1d26e86558b9a4a00cb363df3520d613af84c..b38dc1c05e49a51d155f62035260f7d981a19d79 100644 --- a/src/application/drivers_sample/adc/sample_adc_continue_trigger/readme.md +++ b/src/application/drivers_sample/adc/sample_adc_continue_trigger/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后,软件触发后,ADC进行连续触发采样,持续产生中断。采样成功后,会通过串口打印中断服务函数内读取到的ADC采样结果。在串口打印输出中,会不断打印中断回调函数中读出的ADC采样结果。 **【注意事项】** -+ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 \ No newline at end of file ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_over_sample/init/system_init.c b/src/application/drivers_sample/adc/sample_adc_over_sample/init/system_init.c index c379b76aa901f1188f5057bbfc4a2707067f25b5..a93092a6772d3915a4bf7b3752d388f523989183 100644 --- a/src/application/drivers_sample/adc/sample_adc_over_sample/init/system_init.c +++ b/src/application/drivers_sample/adc/sample_adc_over_sample/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -48,18 +50,13 @@ static void ADC1_Init(void) HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); g_adc.baseAddress = ADC1; - g_adc.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc.vrefBuf = ADC_VREF_2P5V; - g_adc.irqNumOver = IRQ_ADC1_OVINT; - g_adc.ADC_IntxParam[0].irqNum = IRQ_ADC1_INT1; /* interrupt 0 */ - g_adc.ADC_IntxParam[1].irqNum = IRQ_ADC1_INT2; /* interrupt 1 */ - g_adc.ADC_IntxParam[2].irqNum = IRQ_ADC1_INT3; /* interrupt 2 */ - g_adc.ADC_IntxParam[3].irqNum = IRQ_ADC1_INT4; /* interrupt 3 */ + g_adc.socPriority = ADC_PRIMODE_ALL_PRIORITY; + g_adc.handleEx.vrefBuf = ADC_VREF_2P5V; HAL_ADC_Init(&g_adc); SOC_Param socParam = {0}; - socParam.adcInput = ADC_CH_ADCINA1; + socParam.adcInput = ADC_CH_ADCINA1; /* PIN5(ADC INA1) */ socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ socParam.sampleTotalTime = 127; /* adc sample total time 127 adc_clk */ @@ -69,7 +66,7 @@ static void ADC1_Init(void) socParam.finishMode = ADC_SOCFINISH_NONE; HAL_ADC_ConfigureSoc(&g_adc, ADC_SOC_NUM3, &socParam); - socParam.adcInput = ADC_CH_ADCINA1; + socParam.adcInput = ADC_CH_ADCINA1; /* PIN5(ADC INA1) */ socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ socParam.sampleTotalTime = 127; /* adc sample total time 127 adc_clk */ @@ -86,7 +83,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -103,35 +99,31 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_21.BIT.func = 0x8; /* 0x8 is ADC1_ANA_A1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_ADC1_ANA_A1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_ADC1_ANA_A1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_ADC1_ANA_A1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_ADC1_ANA_A1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_ADC1_ANA_A1, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); - ADC1_Init(); UART0_Init(); + ADC1_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/adc/sample_adc_over_sample/readme.md b/src/application/drivers_sample/adc/sample_adc_over_sample/readme.md index 161013de969229c9f3b69225a36c392c9c30df84..8e5cf6b9628959ca6fd1b77ac785858cdb42af41 100644 --- a/src/application/drivers_sample/adc/sample_adc_over_sample/readme.md +++ b/src/application/drivers_sample/adc/sample_adc_over_sample/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成,软件触发后,ADC进行同时对同一个采样源采样两次。等待5ms后检查ADC采样结是否转换完成,若转换完成串口打印出采样结果,若采样未完成打印未完成提示字符串。 **【注意事项】** -+ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 \ No newline at end of file ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_oversampling_it/readme.md b/src/application/drivers_sample/adc/sample_adc_oversampling_it/readme.md index 45e4a1cf3910372ec698cf07925bb7fbcc92d2d6..1b9d4b8af91983cb8072cfb9964bcafd48ef1c05 100644 --- a/src/application/drivers_sample/adc/sample_adc_oversampling_it/readme.md +++ b/src/application/drivers_sample/adc/sample_adc_oversampling_it/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成,软件触发。过采样全过程结束后,会在过采样的中断回调函数中打印出过采样的结果。 **【注意事项】** -+ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 \ No newline at end of file ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_single_trigger/init/system_init.c b/src/application/drivers_sample/adc/sample_adc_single_trigger/init/system_init.c index 09b25530d33196dfe450079759e1522d059e9aa5..4a1d0c6ed8e9159ca1421632066d4906b915ba23 100644 --- a/src/application/drivers_sample/adc/sample_adc_single_trigger/init/system_init.c +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -45,29 +47,24 @@ static void ADC1_Init(void) { HAL_CRG_IpEnableSet(ADC1_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(ADC1_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); - HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); + HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); /* Clock division 5 */ g_adc.baseAddress = ADC1; - g_adc.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc.vrefBuf = ADC_VREF_2P5V; - g_adc.irqNumOver = IRQ_ADC1_OVINT; - g_adc.ADC_IntxParam[0].irqNum = IRQ_ADC1_INT1; /* interrupt 0 */ - g_adc.ADC_IntxParam[1].irqNum = IRQ_ADC1_INT2; /* interrupt 1 */ - g_adc.ADC_IntxParam[2].irqNum = IRQ_ADC1_INT3; /* interrupt 2 */ - g_adc.ADC_IntxParam[3].irqNum = IRQ_ADC1_INT4; /* interrupt 3 */ + g_adc.socPriority = ADC_PRIMODE_ALL_PRIORITY; + g_adc.handleEx.vrefBuf = ADC_VREF_2P5V; HAL_ADC_Init(&g_adc); SOC_Param socParam = {0}; - socParam.adcInput = ADC_CH_ADCINA1; + socParam.adcInput = ADC_CH_ADCINA1; /* PIN5(ADC INA1) */ socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ socParam.sampleTotalTime = 127; /* adc sample total time 127 adc_clk */ - socParam.softTrigSource = ADC_TRIGSOC_SOFT; + socParam.softTrigSource = ADC_TRIGSOC_SOFT; /* Soft triggle ADC */ socParam.intTrigSource = ADC_TRIGSOC_NONEINT; socParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; socParam.finishMode = ADC_SOCFINISH_NONE; - HAL_ADC_ConfigureSoc(&g_adc, ADC_SOC_NUM1, &socParam); + HAL_ADC_ConfigureSoc(&g_adc, ADC_SOC_NUM1, &socParam); /* Config SOC param */ } static void UART0_Init(void) @@ -75,53 +72,48 @@ static void UART0_Init(void) HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; + g_uart0.baseAddress = UART0; /* UART0 base address */ g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; - g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.txMode = UART_MODE_BLOCKING; /* Tx Blocking mode */ + g_uart0.rxMode = UART_MODE_BLOCKING; /* Rx Blocking mode */ g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; - HAL_UART_Init(&g_uart0); + HAL_UART_Init(&g_uart0); /* Uart Init */ } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_21.BIT.func = 0x8; /* 0x8 is ADC1_ANA_A1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_ADC1_ANA_A1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_ADC1_ANA_A1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_ADC1_ANA_A1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_ADC1_ANA_A1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_ADC1_ANA_A1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); - ADC1_Init(); UART0_Init(); + ADC1_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/adc/sample_adc_single_trigger/readme.md b/src/application/drivers_sample/adc/sample_adc_single_trigger/readme.md index 9c1e6fa6f94fc5024ea9a901fb6638dfd4258875..82084f20cf9949bf56c2a91f6a2456816f920ded 100644 --- a/src/application/drivers_sample/adc/sample_adc_single_trigger/readme.md +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成,软件触发后,ADC进行单次采样转换。等待10ms后检查ADC采样结是否转换完成,若转换完成串口打印出采样结果,若采样未完成打印未完成提示字符串。 **【注意事项】** -+ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 \ No newline at end of file ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_single_trigger_dma/init/system_init.c b/src/application/drivers_sample/adc/sample_adc_single_trigger_dma/init/system_init.c index 9f1769b9e79db6c5f974293415be2543d9a9206b..eb33987f639fdd039cdb683ca87aeb89714d216f 100644 --- a/src/application/drivers_sample/adc/sample_adc_single_trigger_dma/init/system_init.c +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger_dma/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -41,75 +43,71 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -static void DMA_Channel1Init(void *handle) +static void DMA_Channel0Init(void *handle) { DMA_ChannelParam dma_param; - dma_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; /* DMA transmission direction */ + dma_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; /* Periph to memory */ dma_param.srcAddrInc = DMA_ADDR_UNALTERED; dma_param.destAddrInc = DMA_ADDR_UNALTERED; - dma_param.srcPeriph = DMA_REQUEST_ADC1; /* ADC as DMA Request Source */ - dma_param.destPeriph = DMA_REQUEST_MEM; - dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; - dma_param.destWidth = DMA_TRANSWIDTH_BYTE; + dma_param.srcPeriph = DMA_REQUEST_ADC1; /* Source Request by ADC */ + dma_param.destPeriph = DMA_REQUEST_MEM; /* Destination Request by ADC */ + dma_param.srcWidth = DMA_TRANSWIDTH_WORD; + dma_param.destWidth = DMA_TRANSWIDTH_WORD; dma_param.srcBurst = DMA_BURST_LENGTH_1; dma_param.destBurst = DMA_BURST_LENGTH_1; dma_param.pHandle = handle; - HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ONE); /* Initializing the DMA Channel */ + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ZERO); /* Init DMA Channel Param */ } static void DMA_Init(void) { + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; - g_dmac.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.irqNumTc = IRQ_DMA_TC; - g_dmac.irqNumError = IRQ_DMA_ERR; - HAL_DMA_IRQService(&g_dmac); + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_BIGENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_BIGENDIAN; + /* Rigister DMA TC IRQ */ + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + /* Rigister DMA ERR IRQ */ + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); - HAL_DMA_Init(&g_dmac); /* Initializing the DMA controller */ + HAL_DMA_Init(&g_dmac); /* Init DMA */ - DMA_Channel1Init((void *)(&g_adc)); + DMA_Channel0Init((void *)(&g_adc)); } -__weak void ADC1DMACallback(ADC_Handle *handle) +__weak void ADC_DMACallback(ADC_Handle *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN ADC1DMACallback */ - /* USER CODE END ADC1DMACallback */ + /* USER CODE BEGIN ADC1_CALLBACK_DMA */ + /* USER CODE END ADC1_CALLBACK_DMA */ } static void ADC1_Init(void) { HAL_CRG_IpEnableSet(ADC1_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(ADC1_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); - HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); + HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); /* Clock divison 5 */ g_adc.baseAddress = ADC1; g_adc.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc.vrefBuf = ADC_VREF_2P5V; - g_adc.irqNumOver = IRQ_ADC1_OVINT; - g_adc.ADC_IntxParam[0].irqNum = IRQ_ADC1_INT1; /* interrupt 0 */ - g_adc.ADC_IntxParam[1].irqNum = IRQ_ADC1_INT2; /* interrupt 1 */ - g_adc.ADC_IntxParam[2].irqNum = IRQ_ADC1_INT3; /* interrupt 2 */ - g_adc.ADC_IntxParam[3].irqNum = IRQ_ADC1_INT4; /* interrupt 3 */ + g_adc.handleEx.vrefBuf = ADC_VREF_2P5V; g_adc.dmaHandle = &g_dmac; - g_adc.adcDmaChn = 1; /* DMA Channel 1 */ - HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_DMA, ADC1DMACallback); - + g_adc.adcDmaChn = 0; /* DMA Channel 0 */ HAL_ADC_Init(&g_adc); SOC_Param socParam = {0}; - socParam.adcInput = ADC_CH_ADCINA1; + socParam.adcInput = ADC_CH_ADCINA1; /* PIN5(ADC INA1) */ socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ socParam.sampleTotalTime = 127; /* adc sample total time 127 adc_clk */ - socParam.softTrigSource = ADC_TRIGSOC_SOFT; + socParam.softTrigSource = ADC_TRIGSOC_SOFT; /* Soft triggle sample */ socParam.intTrigSource = ADC_TRIGSOC_NONEINT; socParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; socParam.finishMode = ADC_SOCFINISH_DMA; - HAL_ADC_ConfigureSoc(&g_adc, ADC_SOC_NUM1, &socParam); + HAL_ADC_ConfigureSoc(&g_adc, ADC_SOC_NUM1, &socParam); /* Config SOC param */ + HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_DMA, (ADC_CallbackType)ADC_DMACallback); } static void UART0_Init(void) @@ -118,7 +116,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -135,36 +132,33 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_21.BIT.func = 0x8; /* 0x8 is ADC1_ANA_A1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_ADC1_ANA_A1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_ADC1_ANA_A1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_ADC1_ANA_A1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_ADC1_ANA_A1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_ADC1_ANA_A1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); DMA_Init(); - ADC1_Init(); UART0_Init(); + ADC1_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_single_trigger_dma/readme.md b/src/application/drivers_sample/adc/sample_adc_single_trigger_dma/readme.md index 0e5ceb911acfa3c6d7ed4e0c6c50c9835f95580e..8b4ee7154c88806ff414490a701fe1dc325e1060 100644 --- a/src/application/drivers_sample/adc/sample_adc_single_trigger_dma/readme.md +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger_dma/readme.md @@ -16,3 +16,6 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 diff --git a/src/middleware/hisilicon/nostask/kernel/nos_task_global.c b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/inc/sample_adc_single_trigger_gpio.h similarity index 70% rename from src/middleware/hisilicon/nostask/kernel/nos_task_global.c rename to src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/inc/sample_adc_single_trigger_gpio.h index 9fc411bb8c687326fd47d67676eb903a7658032b..3e54c807c06ca9d17eddfd239de008d5753a07dc 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_task_global.c +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/inc/sample_adc_single_trigger_gpio.h @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,29 +15,30 @@ * 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. - * @file nos_task_global.c + * @file adc_single_trigger_gpio.h + * @author MCU Driver Team + * @brief adc sample module. + * @details This file provides users with sample code to help use ADC function: + * ADC sampling by software trigger */ -#include "nos_task_internal.h" -#include "nos_config.h" +#ifndef SAMPLE_ADC_SINGLETRIGGER_GPIO_H +#define SAMPLE_ADC_SINGLETRIGGER_GPIO_H -/* 数据定义放到XXX.c中是为了解决SAI报Data Module */ +#include "debug.h" +#include "adc.h" +#include "main.h" -unsigned int g_tskMaxNum = OS_TSK_MAX_SUPPORT_NUM; -struct TagTskCB g_tskCBArray[OS_MAX_TCB_NUM]; +#include "feature.h" -unsigned int g_idleTaskID; -unsigned short g_uniTaskLock; -struct TagTskCB *g_highestTask; +#ifdef CHIP_3061MNPICA + #define ADCHANDLE g_adc0 -void OsTskSwitchHookCaller(unsigned int prevPid, unsigned int nextPid) -{ - /* 保留 */ - (void)prevPid; - (void)nextPid; -} +#endif -unsigned int OsTskMaxNumGet(void) -{ - /* MAX task num */ - return g_tskMaxNum; -} +#if defined (CHIP_3065HRPIRZ) || defined (CHIP_3065ARPIRZ) + #define ADCHANDLE g_adc2 + +#endif + +void ADC_SingleTrigger(void); +#endif \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/init/main.c b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..3a6ac4fc4a26c8df337e1d8cc42eac2117d645df --- /dev/null +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/init/main.c @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_adc_single_trigger_gpio.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +ADC_Handle g_adc0; +GPIO_Handle g_gpio2; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + ADC_SingleTrigger(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/init/main.h b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..ec74d82833f7c61f38f33553a4177e496fa3bf9c --- /dev/null +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/init/main.h @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "adc.h" +#include "adc_ex.h" +#include "uart.h" +#include "uart_ex.h" +#include "gpio.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern ADC_Handle g_adc0; + +extern GPIO_Handle g_gpio2; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/init/system_init.c b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..ea65ad41b06be0fe37f46c53e1df17b378032b2f --- /dev/null +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/init/system_init.c @@ -0,0 +1,150 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void ADC0_Init(void) +{ + /* enable adc clk */ + HAL_CRG_IpEnableSet(ADC0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(ADC0_BASE, CRG_ADC_CLK_ASYN_PLL_DIV); + HAL_CRG_IpClkDivSet(ADC0_BASE, CRG_ADC_DIV_1); + + g_adc0.baseAddress = ADC0; + g_adc0.socPriority = ADC_PRIMODE_ALL_ROUND; + /* initialize adc config */ + HAL_ADC_Init(&g_adc0); + + SOC_Param socParam = {0}; + socParam.adcInput = ADC_CH_ADCINA15; /* PIN14(ADC AIN15) */ + socParam.sampleTotalTime = ADC_SOCSAMPLE_5CLK; /* adc sample total time 5 adc_clk */ + socParam.trigSource = ADC_TRIGSOC_GPIOPF1; + socParam.continueMode = BASE_CFG_DISABLE; + socParam.finishMode = ADC_SOCFINISH_NONE; + HAL_ADC_ConfigureSoc(&g_adc0, ADC_SOC_NUM0, &socParam); +} + +static void GPIO_Init(void) +{ + /* enable gpio clk */ + HAL_CRG_IpEnableSet(GPIO2_BASE, IP_CLK_ENABLE); + g_gpio2.baseAddress = GPIO2; + + g_gpio2.pins = GPIO_PIN_1; + HAL_GPIO_Init(&g_gpio2); + /* set gpio output mode */ + HAL_GPIO_SetDirection(&g_gpio2, g_gpio2.pins, GPIO_OUTPUT_MODE); + HAL_GPIO_SetValue(&g_gpio2, g_gpio2.pins, GPIO_LOW_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio2, g_gpio2.pins, GPIO_INT_TYPE_NONE); + return; +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + /* set UART0 bandrate. */ + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + /* set UART0 one stop bit. */ + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + /* enable fifo */ + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + /* set UART0 overSample. */ + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_1_AS_GPIO2_1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_1_AS_GPIO2_1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_1_AS_GPIO2_1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_1_AS_GPIO2_1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_1_AS_GPIO2_1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_7_AS_ADC_AIN15); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_7_AS_ADC_AIN15, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_7_AS_ADC_AIN15, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_7_AS_ADC_AIN15, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_7_AS_ADC_AIN15, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO5_1_AS_ADC_EXT_TRIG3); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO5_1_AS_ADC_EXT_TRIG3, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO5_1_AS_ADC_EXT_TRIG3, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO5_1_AS_ADC_EXT_TRIG3, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO5_1_AS_ADC_EXT_TRIG3, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + ADC0_Init(); + GPIO_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/readme.md b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..da295ba4306ae161f2dacb6e03acec7da2346dba --- /dev/null +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/readme.md @@ -0,0 +1,21 @@ +# 配置ADC的采样功能,采用GPIO电平翻转的方式进行触发 + +**【功能描述】** ++ 通过配置GPIO翻转的方式触发ADC采样功能 + +**【示例配置】** ++ ADC触发源:GPIO。通过配置ADC触发方式为GPIO 进行ADC采样触发。 + ++ ADC采样源: 挂载到SOC0 外部采样源。SOC的在文件“system_init.c”中配置,SOC可以配置为“ADC_SOC_NUM0~ADC_SOC_NUM15”中任何一个。 + ++ ADC采样结果:ADC可以选择4个数据完成中断的任一个,配置请见"System_Init()”。在回调函数中调用“HAL_ADC_GetConvResult()”获取结果。 ++ 用户需将配置的GPIO2_1(J2.14)管脚与ADC采样触发管脚[GPIO5_1(J1.39)3061MNPICA芯片ECBMCU201M系列生态板]/[GPIO6_3(J1.37)3066MNPIRH芯片ECBMCU301M系列生态板]通过跳线进行连接。 + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中会对ADC进行触发采样。采样成功后,会通过串口打印读取到的ADC采样结果。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的,选用3061M 系列通用生态板作为示例对象。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/src/sample_adc_single_trigger_gpio.c b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/src/sample_adc_single_trigger_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..b4ba45cbd718d067aa257dafab1218001f5049c8 --- /dev/null +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger_gpio/src/sample_adc_single_trigger_gpio.c @@ -0,0 +1,46 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_adc_single_trigger_it.c + * @author MCU Driver Team + * @brief adc sample module. + * @details In single sampling mode, the ADC sampling is triggered by GPIO. After the sampling is complete, + * the ADC interrupt is triggered and the ADC conversion result is read in the interrupt callback function. + * (1) ADC strigger source is gpio. Use HAL_ADC_GetConvResult() to get adc data. + * (2) ADC sample source is ADCHANDLE. Select sample source in "g_adc.baseAddress" of SystemInit(), + * "ADC_SOC_NUM0" can be Modified. External input source: GPIO2_1 + */ +#include "sample_adc_single_trigger_gpio.h" + +/** + * @brief ADC single channel sample with gpio. + * @param None. + * @retval None. + */ +float g_udc = 0.0f; +void ADC_SingleTrigger(void) +{ + SystemInit(); + while (1) { + HAL_GPIO_TogglePin(&g_gpio2, GPIO_PIN_1); + /* Delay 500ms */ + BASE_FUNC_DELAY_MS(500); + /* udc is input voltage, 0.01289f is voltage sample coffecient */ + g_udc = ((float)HAL_ADC_GetConvResult(&ADCHANDLE, ADC_SOC_NUM0)) * 0.01289f; + DBG_PRINTF("g_udc: %f\r\n", g_udc); + } +} \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_single_trigger_it/init/system_init.c b/src/application/drivers_sample/adc/sample_adc_single_trigger_it/init/system_init.c index 447acce0cb07ff5d4bf03e311b54bd4bdd0a38be..2f3b0a4243ad717897b0ba632619485729b5a984 100644 --- a/src/application/drivers_sample/adc/sample_adc_single_trigger_it/init/system_init.c +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger_it/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,29 +46,24 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) __weak void ADC_Int1Finish(ADC_Handle *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN ADC_Int1Finish */ - /* USER CODE END ADC_Int1Finish */ + /* USER CODE BEGIN ADC1_CALLBACK_INT1 */ + /* USER CODE END ADC1_CALLBACK_INT1 */ } static void ADC1_Init(void) { HAL_CRG_IpEnableSet(ADC1_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(ADC1_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); - HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); + HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); /* Clock division 5 */ g_adc.baseAddress = ADC1; - g_adc.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc.vrefBuf = ADC_VREF_2P5V; - g_adc.irqNumOver = IRQ_ADC1_OVINT; - g_adc.ADC_IntxParam[0].irqNum = IRQ_ADC1_INT1; /* interrupt 0 */ - g_adc.ADC_IntxParam[1].irqNum = IRQ_ADC1_INT2; /* interrupt 1 */ - g_adc.ADC_IntxParam[2].irqNum = IRQ_ADC1_INT3; /* interrupt 2 */ - g_adc.ADC_IntxParam[3].irqNum = IRQ_ADC1_INT4; /* interrupt 3 */ + g_adc.socPriority = ADC_PRIMODE_ALL_PRIORITY; + g_adc.handleEx.vrefBuf = ADC_VREF_2P5V; HAL_ADC_Init(&g_adc); SOC_Param socParam = {0}; - socParam.adcInput = ADC_CH_ADCINA1; + socParam.adcInput = ADC_CH_ADCINA1; /* PIN5(ADC INA1) */ socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ socParam.sampleTotalTime = 127; /* adc sample total time 127 adc_clk */ @@ -75,11 +72,11 @@ static void ADC1_Init(void) socParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; socParam.finishMode = ADC_SOCFINISH_INT1; HAL_ADC_ConfigureSoc(&g_adc, ADC_SOC_NUM0, &socParam); - - HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_INT1, ADC_Int1Finish); - IRQ_SetPriority(IRQ_ADC1_INT1, 7); /* Set the priority to level 7 */ + HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_INT1, (ADC_CallbackType)ADC_Int1Finish); + /* Rigister ADC INT1 IRQ */ + IRQ_Register(IRQ_ADC1_INT1, HAL_ADC_IrqHandlerInt1, &g_adc); + IRQ_SetPriority(IRQ_ADC1_INT1, 7); /* 7 is priority value */ IRQ_EnableN(IRQ_ADC1_INT1); - HAL_ADC_IrqService(&g_adc); } static void UART0_Init(void) @@ -87,53 +84,48 @@ static void UART0_Init(void) HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; + g_uart0.baseAddress = UART0; /* UART0 base address */ g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; - g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.txMode = UART_MODE_BLOCKING; /* Tx Blocking mode */ + g_uart0.rxMode = UART_MODE_BLOCKING; /* Rx Blocking mode */ g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; - HAL_UART_Init(&g_uart0); + HAL_UART_Init(&g_uart0); /* Uart Init */ } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_21.BIT.func = 0x8; /* 0x8 is ADC1_ANA_A1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_ADC1_ANA_A1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_ADC1_ANA_A1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_ADC1_ANA_A1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_ADC1_ANA_A1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_ADC1_ANA_A1, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); - ADC1_Init(); UART0_Init(); + ADC1_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/adc/sample_adc_single_trigger_it/readme.md b/src/application/drivers_sample/adc/sample_adc_single_trigger_it/readme.md index fb280a9d88e62ff3c3bea184a176182d93ff1dd6..33172bc24ba288240296006a130e8ee77d63b583 100644 --- a/src/application/drivers_sample/adc/sample_adc_single_trigger_it/readme.md +++ b/src/application/drivers_sample/adc/sample_adc_single_trigger_it/readme.md @@ -16,3 +16,6 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_single_with_ppb/readme.md b/src/application/drivers_sample/adc/sample_adc_single_with_ppb/readme.md index a83d0ef5238fa0b31149fb25b4619efc09682915..99b704661ca96673b6167aa250858760fefb6af7 100644 --- a/src/application/drivers_sample/adc/sample_adc_single_with_ppb/readme.md +++ b/src/application/drivers_sample/adc/sample_adc_single_with_ppb/readme.md @@ -17,4 +17,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成,软件触发。第一次触发采样结束后,只打印出ADC的采样结果。后两次触发,按照后处理参数的配置和当前采样结果,触发不同的后处理中断,然后在中断回调函数中打印相应的字符串。 **【注意事项】** -+ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 \ No newline at end of file ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 + ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_sync_sample/init/system_init.c b/src/application/drivers_sample/adc/sample_adc_sync_sample/init/system_init.c index 771dace7052154145df91e38b3851322fd10ab01..84b7fe5f90b1735c3a7e8b13d13873d5f93aaa64 100644 --- a/src/application/drivers_sample/adc/sample_adc_sync_sample/init/system_init.c +++ b/src/application/drivers_sample/adc/sample_adc_sync_sample/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -48,19 +50,14 @@ static void ADC1_Init(void) HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); g_adc.baseAddress = ADC1; - g_adc.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc.vrefBuf = ADC_VREF_2P5V; - g_adc.irqNumOver = IRQ_ADC1_OVINT; - g_adc.ADC_IntxParam[0].irqNum = IRQ_ADC1_INT1; /* interrupt 0 */ - g_adc.ADC_IntxParam[1].irqNum = IRQ_ADC1_INT2; /* interrupt 1 */ - g_adc.ADC_IntxParam[2].irqNum = IRQ_ADC1_INT3; /* interrupt 2 */ - g_adc.ADC_IntxParam[3].irqNum = IRQ_ADC1_INT4; /* interrupt 3 */ + g_adc.socPriority = ADC_PRIMODE_ALL_PRIORITY; + g_adc.handleEx.vrefBuf = ADC_VREF_2P5V; HAL_ADC_Init(&g_adc); SOC_SyncParam syncParam = {0}; - syncParam.ChannelA = ADC_CH_ADCINA1; - syncParam.ChannelB = ADC_CH_ADCINB2; + syncParam.ChannelA = ADC_CH_ADCINA1; /* PIN5(ADC INA1) */ + syncParam.ChannelB = ADC_CH_ADCINB2; /* PIN7(ADC INB2) */ syncParam.group = ADC_SYNCSAMPLE_GROUP_1; syncParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ @@ -69,7 +66,7 @@ static void ADC1_Init(void) syncParam.intTrigSource = ADC_TRIGSOC_NONEINT; syncParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; syncParam.finishMode = ADC_SOCFINISH_NONE; - HAL_ADC_StartSyncSample(&g_adc, &syncParam); + HAL_ADC_StartSyncSampleEx(&g_adc, &syncParam); } static void UART0_Init(void) @@ -78,7 +75,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -95,42 +91,37 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_21.BIT.func = 0x8; /* 0x8 is ADC1_ANA_A1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_23.BIT.func = 0x8; /* 0x8 is ADC1_ANA_B2 */ - iconfig->iocmg_23.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_23.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_23.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_23.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_23.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_ADC1_ANA_A1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_ADC1_ANA_A1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_ADC1_ANA_A1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_ADC1_ANA_A1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_ADC1_ANA_A1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO7_AS_ADC1_ANA_B2); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO7_AS_ADC1_ANA_B2, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO7_AS_ADC1_ANA_B2, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO7_AS_ADC1_ANA_B2, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO7_AS_ADC1_ANA_B2, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); - ADC1_Init(); UART0_Init(); + ADC1_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/adc/sample_adc_sync_sample/readme.md b/src/application/drivers_sample/adc/sample_adc_sync_sample/readme.md index 362f110d551959f74fb0ec3957ce2237811ac662..ec34c1c2c53a29b65c9bebad83e0bdb9cb9c851b 100644 --- a/src/application/drivers_sample/adc/sample_adc_sync_sample/readme.md +++ b/src/application/drivers_sample/adc/sample_adc_sync_sample/readme.md @@ -16,3 +16,6 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/adc/sample_adc_sync_sample_dma/init/system_init.c b/src/application/drivers_sample/adc/sample_adc_sync_sample_dma/init/system_init.c index 21a1083a48b75ed6da64632b24a6963379c16820..bbe28cacf0a93d630cb123f9b93016e2621f714b 100644 --- a/src/application/drivers_sample/adc/sample_adc_sync_sample_dma/init/system_init.c +++ b/src/application/drivers_sample/adc/sample_adc_sync_sample_dma/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,30 +46,30 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void DMA_Channel1Init(void *handle) { DMA_ChannelParam dma_param; - dma_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; /* DMA transmission direction */ - dma_param.srcAddrInc = DMA_ADDR_INCREASE; - dma_param.destAddrInc = DMA_ADDR_INCREASE; - dma_param.srcPeriph = DMA_REQUEST_ADC1; /* ADC as DMA Request Source */ + dma_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; /* Periph to memory */ + dma_param.srcAddrInc = DMA_ADDR_INCREASE; /* Addr increase */ + dma_param.destAddrInc = DMA_ADDR_INCREASE; /* Addr increase */ + dma_param.srcPeriph = DMA_REQUEST_ADC1; dma_param.destPeriph = DMA_REQUEST_MEM; dma_param.srcWidth = DMA_TRANSWIDTH_WORD; dma_param.destWidth = DMA_TRANSWIDTH_WORD; dma_param.srcBurst = DMA_BURST_LENGTH_16; dma_param.destBurst = DMA_BURST_LENGTH_16; dma_param.pHandle = handle; - HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ONE); /* Initializing the DMA Channel */ + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ONE); /* DMA init channel */ } static void DMA_Init(void) { + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; - g_dmac.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.irqNumTc = IRQ_DMA_TC; - g_dmac.irqNumError = IRQ_DMA_ERR; - HAL_DMA_IRQService(&g_dmac); + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_BIGENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_BIGENDIAN; + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); - HAL_DMA_Init(&g_dmac); /* Initializing the DMA controller */ + HAL_DMA_Init(&g_dmac); DMA_Channel1Init((void *)(&g_adc)); } @@ -75,8 +77,8 @@ static void DMA_Init(void) __weak void ADC_SyncIntCallBack(ADC_Handle *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN ADC_SyncIntCallBack */ - /* USER CODE END ADC_SyncIntCallBack */ + /* USER CODE BEGIN ADC1_CALLBACK_DMA */ + /* USER CODE END ADC1_CALLBACK_DMA */ } static void ADC1_Init(void) @@ -87,22 +89,15 @@ static void ADC1_Init(void) g_adc.baseAddress = ADC1; g_adc.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc.vrefBuf = ADC_VREF_2P5V; - g_adc.irqNumOver = IRQ_ADC1_OVINT; - g_adc.ADC_IntxParam[0].irqNum = IRQ_ADC1_INT1; /* interrupt 0 */ - g_adc.ADC_IntxParam[1].irqNum = IRQ_ADC1_INT2; /* interrupt 1 */ - g_adc.ADC_IntxParam[2].irqNum = IRQ_ADC1_INT3; /* interrupt 2 */ - g_adc.ADC_IntxParam[3].irqNum = IRQ_ADC1_INT4; /* interrupt 3 */ + g_adc.handleEx.vrefBuf = ADC_VREF_2P5V; g_adc.dmaHandle = &g_dmac; g_adc.adcDmaChn = 1; /* DMA Channel 1 */ - HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_DMA, ADC_SyncIntCallBack); - HAL_ADC_Init(&g_adc); SOC_SyncParam syncParam = {0}; - syncParam.ChannelA = ADC_CH_ADCINA1; - syncParam.ChannelB = ADC_CH_ADCINB3; + syncParam.ChannelA = ADC_CH_ADCINA1; /* PIN5(ADC INA1) */ + syncParam.ChannelB = ADC_CH_ADCINB3; /* PIN2(ADC INB3) */ syncParam.group = ADC_SYNCSAMPLE_GROUP_3; syncParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ @@ -111,7 +106,8 @@ static void ADC1_Init(void) syncParam.intTrigSource = ADC_TRIGSOC_NONEINT; syncParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; syncParam.finishMode = ADC_SOCFINISH_DMA; - HAL_ADC_StartSyncSample(&g_adc, &syncParam); + HAL_ADC_StartSyncSampleEx(&g_adc, &syncParam); + HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_DMA, (ADC_CallbackType)ADC_SyncIntCallBack); } static void UART0_Init(void) @@ -120,7 +116,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -137,43 +132,40 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_21.BIT.func = 0x8; /* 0x8 is ADC1_ANA_A1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_18.BIT.func = 0x8; /* 0x8 is ADC1_ANA_B3 */ - iconfig->iocmg_18.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_18.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_18.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_18.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_18.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_ADC1_ANA_A1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_ADC1_ANA_A1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_ADC1_ANA_A1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_ADC1_ANA_A1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_ADC1_ANA_A1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO2_AS_ADC1_ANA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO2_AS_ADC1_ANA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO2_AS_ADC1_ANA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO2_AS_ADC1_ANA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO2_AS_ADC1_ANA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); DMA_Init(); - ADC1_Init(); UART0_Init(); + ADC1_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/adc/sample_adc_sync_sample_dma/readme.md b/src/application/drivers_sample/adc/sample_adc_sync_sample_dma/readme.md index 302614278723c3eb2face6bcefbb241aa0741a3a..2406015efb40852b12f87c55f1e08a4e13691367 100644 --- a/src/application/drivers_sample/adc/sample_adc_sync_sample_dma/readme.md +++ b/src/application/drivers_sample/adc/sample_adc_sync_sample_dma/readme.md @@ -16,3 +16,6 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 diff --git a/src/application/drivers_sample/adc/sample_adc_sync_sample_it/init/system_init.c b/src/application/drivers_sample/adc/sample_adc_sync_sample_it/init/system_init.c index e62df67d0945a1f9b13857a21598d4cf22c8f384..d1d78d12f2e1952d34ef3ce372ae245fa4c406b2 100644 --- a/src/application/drivers_sample/adc/sample_adc_sync_sample_it/init/system_init.c +++ b/src/application/drivers_sample/adc/sample_adc_sync_sample_it/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,8 +46,8 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) __weak void ADC1Interrupt4Callback(ADC_Handle *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN ADC1Interrupt4Callback */ - /* USER CODE END ADC1Interrupt4Callback */ + /* USER CODE BEGIN ADC1_CALLBACK_INT4 */ + /* USER CODE END ADC1_CALLBACK_INT4 */ } static void ADC1_Init(void) @@ -56,18 +58,13 @@ static void ADC1_Init(void) g_adc.baseAddress = ADC1; g_adc.socPriority = ADC_PRIMODE_ALL_PRIORITY; - g_adc.vrefBuf = ADC_VREF_2P5V; - g_adc.irqNumOver = IRQ_ADC1_OVINT; - g_adc.ADC_IntxParam[0].irqNum = IRQ_ADC1_INT1; /* interrupt 0 */ - g_adc.ADC_IntxParam[1].irqNum = IRQ_ADC1_INT2; /* interrupt 1 */ - g_adc.ADC_IntxParam[2].irqNum = IRQ_ADC1_INT3; /* interrupt 2 */ - g_adc.ADC_IntxParam[3].irqNum = IRQ_ADC1_INT4; /* interrupt 3 */ + g_adc.handleEx.vrefBuf = ADC_VREF_2P5V; HAL_ADC_Init(&g_adc); SOC_SyncParam syncParam = {0}; - syncParam.ChannelA = ADC_CH_ADCINA1; - syncParam.ChannelB = ADC_CH_ADCINB1; + syncParam.ChannelA = ADC_CH_ADCINA1; /* PIN5(ADC INA1) */ + syncParam.ChannelB = ADC_CH_ADCINB1; /* PGA2_OUT(ADC INB1) */ syncParam.group = ADC_SYNCSAMPLE_GROUP_3; syncParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ @@ -76,12 +73,12 @@ static void ADC1_Init(void) syncParam.intTrigSource = ADC_TRIGSOC_NONEINT; syncParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; syncParam.finishMode = ADC_SOCFINISH_INT4; - HAL_ADC_StartSyncSample(&g_adc, &syncParam); + HAL_ADC_StartSyncSampleEx(&g_adc, &syncParam); + HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_INT4, (ADC_CallbackType)ADC1Interrupt4Callback); - HAL_ADC_RegisterCallBack(&g_adc, ADC_CALLBACK_INT4, ADC1Interrupt4Callback); - IRQ_SetPriority(IRQ_ADC1_INT4, 1); + IRQ_Register(IRQ_ADC1_INT4, HAL_ADC_IrqHandlerInt4, &g_adc); + IRQ_SetPriority(IRQ_ADC1_INT4, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_ADC1_INT4); - HAL_ADC_IrqService(&g_adc); } static void UART0_Init(void) @@ -90,7 +87,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -107,28 +103,24 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_21.BIT.func = 0x8; /* 0x8 is ADC1_ANA_A1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_ADC1_ANA_A1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_ADC1_ANA_A1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_ADC1_ANA_A1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_ADC1_ANA_A1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_ADC1_ANA_A1, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/adc/sample_adc_sync_sample_it/readme.md b/src/application/drivers_sample/adc/sample_adc_sync_sample_it/readme.md index 82b32cbbcaf2b695c53b203a270a99128a0a6842..cd8ea9758f02c319dde15a875a79b942a7e860c8 100644 --- a/src/application/drivers_sample/adc/sample_adc_sync_sample_it/readme.md +++ b/src/application/drivers_sample/adc/sample_adc_sync_sample_it/readme.md @@ -16,3 +16,6 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_output/inc/sample_apt_pwm_output.h b/src/application/drivers_sample/apt/sample_apt_pwm_output/inc/sample_apt_pwm_output.h new file mode 100644 index 0000000000000000000000000000000000000000..1637b7632094aee4b6cc3eac9bad37aa8740d853 --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_output/inc/sample_apt_pwm_output.h @@ -0,0 +1,56 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_apt_pwm_output.h + * @author MCU Driver Team + * @brief APT module sample of HAL API. + * This file provides some configuration example of APT module HAL API. + * + PWM waveform configuration and ADC trigger time configuration sample. + * + Output control protection configuration sample. + * + Interrupt callback function and user registration function sample. + */ + +#ifndef McuMagicTag_SAMPLE_APT_PWM_OUTPUT_H +#define McuMagicTag_SAMPLE_APT_PWM_OUTPUT_H + +#include "apt_ip.h" +#include "interrupt.h" +#include "apt.h" + +/** + * @brief ADC current sample mode. + */ +typedef enum { + ADC_SINGLE_RESISTOR = 0x00000000U, + ADC_THREE_RESISTORS = 0x00000001U, +} ADC_SampleMode; + +/* Action of apt channel a and b */ +typedef enum { + APT_CHA_HIGH_CHB_LOW, + APT_CHA_LOW_CHB_HIGH, + APT_CHA_LOW_CHB_LOW, + APT_CHA_HIGH_CHB_HIGH, +} APT_Act; + +void APT_SampleMain(void); +void APT_SetADCTrgTime(unsigned short cntCmpSOCA, unsigned short cntCmpSOCB, ADC_SampleMode mode); +void APT_SetPwmDuty(APT_Handle *aptHandle, unsigned int duty); +void APT_OutputEnable(APT_Handle *aptHandle); +void APT_OutputDisable(APT_Handle *aptHandle); +void APT_ForceOutput(APT_Handle *aptHandle, APT_Act aptAct); +#endif /* McuMagicTag_APT_HAL_SAMPLE_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_output/init/main.c b/src/application/drivers_sample/apt/sample_apt_pwm_output/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..62cf982444e29f028601bb5dcfd92b55d735f954 --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_output/init/main.c @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +#include "sample_apt_pwm_output.h" +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +APT_Handle g_apt0; +APT_Handle g_apt1; +APT_Handle g_apt2; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + APT_SampleMain(); + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_output/init/main.h b/src/application/drivers_sample/apt/sample_apt_pwm_output/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..b3e644f682643e463d5429bc30c7a7d11a50580d --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_output/init/main.h @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "apt.h" +#include "uart.h" +#include "uart_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern APT_Handle g_apt0; +extern APT_Handle g_apt1; +extern APT_Handle g_apt2; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +void APT0EventCallback(void *aptHandle); +void APT0TimerCallback(void *aptHandle); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_output/init/system_init.c b/src/application/drivers_sample/apt/sample_apt_pwm_output/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..ce827e270396f1abfdfb5f303f542d1d8bd3b9c5 --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_output/init/system_init.c @@ -0,0 +1,319 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +__weak void APT0EventCallback(void *aptHandle) +{ + BASE_FUNC_UNUSED(aptHandle); + /* USER CODE BEGIN APT0_EVENT_INTERRUPT */ + /* USER CODE END APT0_EVENT_INTERRUPT */ +} + +__weak void APT0TimerCallback(void *aptHandle) +{ + BASE_FUNC_UNUSED(aptHandle); + /* USER CODE BEGIN APT0_TIMER_INTERRUPT */ + /* USER CODE END APT0_TIMER_INTERRUPT */ +} + +static void APT0_ProtectInit(void) +{ + APT_OutCtrlProtectEx protectApt = {0}; + protectApt.ocEventEnEx = BASE_CFG_ENABLE; + protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; /* one shot */ + protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; /* protect low */ + protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; /* protect low */ + protectApt.ocEvtInterruptEnEx = BASE_CFG_ENABLE; + protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; + protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_POE0; + protectApt.filterCycleNumEx = 0; + HAL_APT_ProtectInitEx(&g_apt0, &protectApt); +} + +static void APT0_Init(void) +{ + HAL_CRG_IpEnableSet(APT0_BASE, IP_CLK_ENABLE); + + g_apt0.baseAddress = APT0; + + /* Clock Settings */ + g_apt0.waveform.dividerFactor = 1 - 1; + /* Timer Settings */ + g_apt0.waveform.timerPeriod = 20000; /* 20000 is count period of APT time-base timer */ + g_apt0.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; + + /* Wave Form */ + g_apt0.waveform.basicType = APT_PWM_BASIC_A_HIGH_B_LOW; + g_apt0.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt0.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt0.waveform.divInitVal = 0; + g_apt0.waveform.cntInitVal = 0; + g_apt0.waveform.cntCmpLeftEdge = 500; /* 500 is count compare point of the left edge of PWM waveform */ + g_apt0.waveform.cntCmpRightEdge = 500; /* 500 is count compare point of the right edge of PWM waveform */ + g_apt0.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; + g_apt0.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; + g_apt0.waveform.deadBandCnt = 200; /* 200 is dead-band value */ + + /* Timer Trigger */ + g_apt0.tmrInterrupt.tmrInterruptEn = BASE_CFG_ENABLE; + g_apt0.tmrInterrupt.tmrInterruptSrc = APT_INT_SRC_CNTR_ZERO; + g_apt0.tmrInterrupt.tmrInterruptScale = 1; + + APT0_ProtectInit(); + + HAL_APT_PWMInit(&g_apt0); + HAL_APT_RegisterCallBack(&g_apt0, APT_EVENT_INTERRUPT, APT0EventCallback); + IRQ_SetPriority(IRQ_APT0_EVT, 7); /* 7 is priority value */ + IRQ_Register(IRQ_APT0_EVT, HAL_APT_EventIrqHandler, &g_apt0); + IRQ_EnableN(IRQ_APT0_EVT); + HAL_APT_RegisterCallBack(&g_apt0, APT_TIMER_INTERRUPT, APT0TimerCallback); + IRQ_SetPriority(IRQ_APT0_TMR, 6); /* 6 is priority value */ + IRQ_Register(IRQ_APT0_TMR, HAL_APT_TimerIrqHandler, &g_apt0); + IRQ_EnableN(IRQ_APT0_TMR); +} + +static void APT1_ProtectInit(void) +{ + APT_OutCtrlProtectEx protectApt = {0}; + protectApt.ocEventEnEx = BASE_CFG_ENABLE; + protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; /* one shot */ + protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; /* protect low */ + protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; /* protect low */ + protectApt.ocEvtInterruptEnEx = BASE_CFG_DISABLE; + protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; + protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_POE0; + protectApt.filterCycleNumEx = 0; + HAL_APT_ProtectInitEx(&g_apt1, &protectApt); +} + +static void APT1_Init(void) +{ + HAL_CRG_IpEnableSet(APT1_BASE, IP_CLK_ENABLE); + + g_apt1.baseAddress = APT1; + + /* Clock Settings */ + g_apt1.waveform.dividerFactor = 1 - 1; + /* Timer Settings */ + g_apt1.waveform.timerPeriod = 20000; /* 20000 is count period of APT time-base timer */ + g_apt1.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; + + /* Wave Form */ + g_apt1.waveform.basicType = APT_PWM_BASIC_A_HIGH_B_LOW; + g_apt1.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt1.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt1.waveform.divInitVal = 0; + g_apt1.waveform.cntInitVal = 0; + g_apt1.waveform.cntCmpLeftEdge = 500; /* 500 is count compare point of the left edge of PWM waveform */ + g_apt1.waveform.cntCmpRightEdge = 500; /* 500 is count compare point of the right edge of PWM waveform */ + g_apt1.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; + g_apt1.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; + g_apt1.waveform.deadBandCnt = 200; /* 200 is dead-band value */ + + APT1_ProtectInit(); + + HAL_APT_PWMInit(&g_apt1); +} + +static void APT2_ProtectInit(void) +{ + APT_OutCtrlProtectEx protectApt = {0}; + protectApt.ocEventEnEx = BASE_CFG_ENABLE; + protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; /* one shot */ + protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; /* protect low */ + protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; /* protect low */ + protectApt.ocEvtInterruptEnEx = BASE_CFG_DISABLE; + protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; + protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_POE0; + protectApt.filterCycleNumEx = 0; + HAL_APT_ProtectInitEx(&g_apt2, &protectApt); +} + +static void APT2_Init(void) +{ + HAL_CRG_IpEnableSet(APT2_BASE, IP_CLK_ENABLE); + + g_apt2.baseAddress = APT2; + + /* Clock Settings */ + g_apt2.waveform.dividerFactor = 1 - 1; + /* Timer Settings */ + g_apt2.waveform.timerPeriod = 20000; /* 20000 is count period of APT time-base timer */ + g_apt2.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; + + /* Wave Form */ + g_apt2.waveform.basicType = APT_PWM_BASIC_A_HIGH_B_LOW; + g_apt2.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt2.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt2.waveform.divInitVal = 0; + g_apt2.waveform.cntInitVal = 0; + g_apt2.waveform.cntCmpLeftEdge = 500; /* 500 is count compare point of the left edge of PWM waveform */ + g_apt2.waveform.cntCmpRightEdge = 500; /* 500 is count compare point of the right edge of PWM waveform */ + g_apt2.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; + g_apt2.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; + g_apt2.waveform.deadBandCnt = 200; /* 200 is dead-band value */ + + APT2_ProtectInit(); + + HAL_APT_PWMInit(&g_apt2); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; /* Band rate 115200 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; /* Length 8bit */ + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + /* Config PIN15 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_5_AS_APT0_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_5_AS_APT0_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_5_AS_APT0_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_5_AS_APT0_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_5_AS_APT0_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN18 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_0_AS_APT0_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_0_AS_APT0_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_0_AS_APT0_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_0_AS_APT0_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_0_AS_APT0_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN30 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO5_0_AS_POE0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO5_0_AS_POE0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO5_0_AS_POE0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO5_0_AS_POE0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO5_0_AS_POE0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN16 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_6_AS_APT1_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_6_AS_APT1_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_6_AS_APT1_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_6_AS_APT1_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_6_AS_APT1_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN19 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_1_AS_APT1_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_1_AS_APT1_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_1_AS_APT1_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_1_AS_APT1_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_1_AS_APT1_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN17 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_7_AS_APT2_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_7_AS_APT2_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_7_AS_APT2_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_7_AS_APT2_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_7_AS_APT2_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN20 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_2_AS_APT2_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_2_AS_APT2_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_2_AS_APT2_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_2_AS_APT2_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_2_AS_APT2_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +static void APT_SyncMasterInit(void) +{ + /* Master config */ + HAL_APT_MasterSyncInit(&g_apt0, APT_SYNC_OUT_ON_CNTR_ZERO); +} + +static void APT_SyncSlaveInit(void) +{ + APT_SlaveSyncIn aptSlave; + + aptSlave.cntPhase = 0; /* counter phase value */ + aptSlave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; + aptSlave.syncInSrc = APT_SYNCIN_SRC_APT0_SYNCOUT; /* sync source selection */ + aptSlave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; + HAL_APT_SlaveSyncInit(&g_apt1, &aptSlave); + + aptSlave.cntPhase = 0; /* counter phase value */ + aptSlave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; + aptSlave.syncInSrc = APT_SYNCIN_SRC_APT0_SYNCOUT; /* sync source selection */ + aptSlave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; + HAL_APT_SlaveSyncInit(&g_apt2, &aptSlave); +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + APT0_Init(); + APT1_Init(); + APT2_Init(); + + APT_SyncMasterInit(); + APT_SyncSlaveInit(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_output/readme.md b/src/application/drivers_sample/apt/sample_apt_pwm_output/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..198cdbf2b6885d928b1e6b192ef4b33ed5067eff --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_output/readme.md @@ -0,0 +1,37 @@ +# 高级脉宽调制PWM-波形相关配置、可变占空比输出、强制输出配置示例 +## 关键字: 可变占空比、强制输出 + +**【功能描述】** ++ 该示例为APT波形输出示例,基于A_H_B_L模式,提供了四种强制输出: ++ (1)通道A输出高、通道B输出低 ++ (2)通道A输出高、通道B输出高 ++ (2)通道A输出低、通道B输出高 ++ (2)通道A输出低、通道B输出低 + ++ 在U相配置有触发ADC采样的SOC信号。 + +**【示例配置】** ++ 在system_init.c文件中,通过配置APT0,APT1和APT2来配置三相的互补PWM波,配置控制周期,死区时间,APT主从同步,加载方式等。 + ++ PWM输出保护,三相PWM输出都配置了保护时间,分别为指定管脚拉高保护,调试模式保护,时钟错误保护,内存泄漏保护。 + ++ 以上配置可通过APT配置界面进行更改,或在“system_init.c”中更改APT对应的配置。 + +**【示例效果】** ++ 若保护事件来临,APT模块会停止PWM波的输出,保护电机等硬件设备。 + +**【注意事项】** ++ 占空比可通过“HAL_APT_SetPWMDutyByNumber”进行更改。 + ++ 分频器的分频系数的范围为 0到4095,计数器的计数周期值的范围为 0到65535。死区延时计数值范围 0到65535。 + ++ PWM 波的频率: +```c +①递增/递减计时模式,PWM 波的频率 = 工作时钟频率 / ((分频器的分频系数+1)*(计数器的计数周期值+1)); +②先增后减计时模式,PWM 波的频率 = 工作时钟频率 / ((分频器的分频系数+1)*(计数器的计数周期值*2))。 +``` ++ 死区的宽度:插入死区的宽度 = 工作时钟周期 * 死区延时计数值。 + ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_output/src/sample_apt_pwm_output.c b/src/application/drivers_sample/apt/sample_apt_pwm_output/src/sample_apt_pwm_output.c new file mode 100644 index 0000000000000000000000000000000000000000..e250e7e6116aff630fe65878a39e372eec37e1e5 --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_output/src/sample_apt_pwm_output.c @@ -0,0 +1,374 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_apt_pwm_output.c + * @author MCU Driver Team + * @brief APT module sample of HAL API. + * This file provides some configuration example of APT module HAL API. + * + PWM waveform configuration and ADC trigger time configuration sample. + * + Output control protection configuration sample. + * + Interrupt callback function and user registration function sample. + */ + +#include "sample_apt_pwm_output.h" +#include "apt.h" +#include "debug.h" +#include "crg.h" +#include "gpio.h" +#include "main.h" +#include "debug.h" +#include "iocmg_ip.h" + +/* Some configuration values of APT modules. */ +/* You can also use HAL_CRG_GetIpFreq(APT0) to get the CPU clock frequency (In units of Hz). */ +#define APT_CLK_FREQ HAL_CRG_GetIpFreq((void *)APT0) +#define APT_PWM_FREQ 5000U /* Set PWM frequency to 5000Hz. */ +#define APT_TIMER_PERIOD (APT_CLK_FREQ / (APT_PWM_FREQ * 2)) /* Period value when using APT_COUNT_MODE_UP_DOWN. */ +#define APT_DIVIDER_FACTOR 1U /* The APT clock is not divided. */ + + +/** + * @brief Pwm force output of channel A and B in A_H_B_L mode. + * @param aptHandle APT Handle. + * @param aptAct Action of channel A and B. + * @retval None. + */ +static void APT_AHBLModeForceOutput(APT_Handle *aptHandle, APT_Act aptAct) +{ + /* Enable force output of channel a and b */ + DCL_APT_EnableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A); + DCL_APT_EnableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B); + switch (aptAct) { + case APT_CHA_HIGH_CHB_LOW: + /* Channel A output is High level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_HIGH); + /* Channel B output is Low because of inversion in A_H_B_L mode. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + + case APT_CHA_LOW_CHB_HIGH: + /* Channel A output is Low level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + /* Channel B output is High because of inversion in A_H_B_L mode. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_LOW); + break; + + case APT_CHA_LOW_CHB_LOW: + /* Channel A output is Low level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + /* Channel B output is Low because of inversion in A_H_B_L mode. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + + case APT_CHA_HIGH_CHB_HIGH: + /* Channel A output is High level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_HIGH); + /* Channel B output is High because of inversion in A_H_B_L mode. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_LOW); + break; + + default: + break; + } +} + + +/** + * @brief Pwm force output of channel A and B in A_H_B_H mode. + * @param aptHandle APT Handle. + * @param aptAct Action of channel A and B. + * @retval None. + */ +static void APT_AHBHModeForceOutput(APT_Handle *aptHandle, APT_Act aptAct) +{ + /* Enable force output of channel a and b */ + DCL_APT_EnableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A); + DCL_APT_EnableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B); + switch (aptAct) { + case APT_CHA_HIGH_CHB_LOW: + /* Channel A output is High level. */ + /* Channel B output is Low level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_HIGH); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_LOW); + break; + + case APT_CHA_LOW_CHB_HIGH: + /* Channel A output is Low level. */ + /* Channel B output is High level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + + case APT_CHA_HIGH_CHB_HIGH: + /* Channel A output is High level. */ + /* Channel B output is High level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_HIGH); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + + case APT_CHA_LOW_CHB_LOW: + /* Channel A output is Low level. */ + /* Channel B output is Low level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_LOW); + break; + + default: + break; + } +} + +/** + * @brief Pwm force output of channel A and B in A_L_B_H mode. + * @param aptHandle APT Handle. + * @param aptAct Action of channel A and B. + * @retval None. + */ +static void APT_ALBHModeForceOutput(APT_Handle *aptHandle, APT_Act aptAct) +{ + /* Enable force output of channel a and b */ + DCL_APT_EnableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A); + DCL_APT_EnableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B); + switch (aptAct) { + case APT_CHA_HIGH_CHB_LOW: + /* Channel A output is High level. */ + /* Channel B output is Low level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_HIGH); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + + case APT_CHA_LOW_CHB_LOW: + /* Channel A output is Low level. */ + /* Channel B output is Low level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_HIGH); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_LOW); + break; + + case APT_CHA_LOW_CHB_HIGH: + /* Channel A output is Low level. */ + /* Channel B output is High level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_LOW); + break; + + case APT_CHA_HIGH_CHB_HIGH: + /* Channel A output is High level. */ + /* Channel B output is High level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + + default: + break; + } +} + +/** + * @brief Pwm force output of channel A and B in A_L_B_L mode. + * @param aptHandle APT Handle. + * @param aptAct Action of channel A and B. + * @retval None. + */ +static void APT_ALBLModeForceOutput(APT_Handle *aptHandle, APT_Act aptAct) +{ + /* Enable force output of channel a and b */ + DCL_APT_EnableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A); + DCL_APT_EnableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B); + switch (aptAct) { + case APT_CHA_HIGH_CHB_LOW: + /* Channel A output is High level. */ + /* Channel B output is Low level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + + case APT_CHA_LOW_CHB_LOW: + /* Channel A output is Low level. */ + /* Channel B output is Low level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_LOW); + break; + + case APT_CHA_LOW_CHB_HIGH: + /* Channel A output is Low level. */ + /* Channel B output is High level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_HIGH); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_LOW); + break; + + case APT_CHA_HIGH_CHB_HIGH: + /* Channel A output is High level. */ + /* Channel B output is High level. */ + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_HIGH); + DCL_APT_SetSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + + default: + break; + } +} + +/** + * @brief Pwm force output of channel A and B. + * @param aptHandle APT Handle. + * @param aptAct Action of channel A and B. + * @retval None. + */ +void APT_ForceOutput(APT_Handle *aptHandle, APT_Act aptAct) +{ + switch (aptHandle->waveform.basicType) { + case APT_PWM_BASIC_A_HIGH_B_LOW: + /* Output type of channel a and b */ + APT_AHBLModeForceOutput(aptHandle, aptAct); + break; + + case APT_PWM_BASIC_A_LOW_B_HIGH: + /* Output type of channel a and b */ + APT_ALBHModeForceOutput(aptHandle, aptAct); + break; + + case APT_PWM_BASIC_A_HIGH_B_HIGH: + /* Output type of channel a and b */ + APT_AHBHModeForceOutput(aptHandle, aptAct); + break; + + case APT_PWM_BASIC_A_LOW_B_LOW: + /* Output type of channel a and b */ + APT_ALBLModeForceOutput(aptHandle, aptAct); + break; + + default: + break; + } +} + +/** + * @brief Modify the ADC trigger time of master APT module (U phase). + * @param cntCmpSOCA Count compare value of SOCA. + * @param cntCmpSOCB Counnt compare value of SOCB. + * @param mode Sample mode, include 1shunt/2shunt/3shunt sample. + * @retval None. + */ +void APT_SetADCTrgTime(unsigned short cntCmpSOCA, unsigned short cntCmpSOCB, ADC_SampleMode mode) +{ + /* AptU use CMPA and CMPB as the trigger source of SOCA and SOCB. */ + /* SOCA is used to trigger 1st ADC sampling when using single resistor sampling. */ + /* SOCB is used to trigger 2nd ADC sampling when using single resistor sampling. */ + if (mode == ADC_SINGLE_RESISTOR) { + HAL_APT_SetADCTriggerTime(&g_apt0, cntCmpSOCA, cntCmpSOCB); + } else { + HAL_APT_SetADCTriggerTime(&g_apt0, cntCmpSOCA, cntCmpSOCB); + HAL_APT_SetADCTriggerTime(&g_apt1, cntCmpSOCA, cntCmpSOCB); + HAL_APT_SetADCTriggerTime(&g_apt2, cntCmpSOCA, cntCmpSOCB); + } +} + +/** + * @brief Pwm output disable. + * @param aptHandle APT Handle. + * @retval None. + */ +void APT_OutputDisable(APT_Handle *aptHandle) +{ + /* Disable PWM waveform output. */ + DCL_APT_EnableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A); + DCL_APT_EnableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B); + DCL_APT_ForcePWMOutputLow(aptHandle->baseAddress); +} + +/** + * @brief Pwm output enable. + * @param aptHandle APT Handle. + * @retval None. + */ +void APT_OutputEnable(APT_Handle *aptHandle) +{ + /* Disable PWM waveform output. */ + DCL_APT_DisableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_A); + DCL_APT_DisableSwContPWMAction(aptHandle->baseAddress, APT_PWM_CHANNEL_B); +} + +/** + * @brief Set pwm duty. + * @param aptHandle APT Handle. + * @param duty Duty cycle. + * @retval None. + */ +void APT_SetPwmDuty(APT_Handle *aptHandle, unsigned int duty) +{ + HAL_APT_SetPWMDutyByNumber(aptHandle, duty); +} + +unsigned int g_aptDuty = 0; +/** + * @brief Timer interrupt callback function of APT module. + * @param aptHandle APT module handle. + * @retval None. + */ +void APT0TimerCallback(void *aptHandle) +{ + g_aptDuty++; + /* 100 means 100% duty */ + if (g_aptDuty > 100) { + g_aptDuty = 0; + } + /* Five output mode */ + if (g_aptDuty == 0) { + /** Four kinds of pwm out put action, please select an action for verification: + * APT_ForceOutput(&g_apt0, APT_CHA_LOW_CHB_LOW); + * APT_ForceOutput(&g_apt0, APT_CHA_LOW_CHB_HIGH); + * APT_ForceOutput(&g_apt0, APT_CHA_HIGH_CHB_LOW); + * APT_ForceOutput(&g_apt0, APT_CHA_HIGH_CHB_HIGH); + */ + APT_ForceOutput(&g_apt0, APT_CHA_HIGH_CHB_HIGH); + } else if (g_aptDuty >= 50) { /* 50: Pwm duty output from 50% to 100% */ + APT_OutputEnable(&g_apt0); + APT_SetPwmDuty(&g_apt0, g_aptDuty); + } + BASE_FUNC_UNUSED(aptHandle); +} + +/** + * @brief Event interrupt callback function of U phase APT module. + * @param aptHandle APT module handle. + * @retval None. + */ +void APT0EventCallback(void *aptHandle) +{ + BASE_FUNC_UNUSED(aptHandle); +} + +/** + * @brief Initialize and start the APT modules of U, V, W phases. + * @param mode: ADC sampling mode. + * @retval None. + */ +void APT_SampleMain(void) +{ + /* Initialize GPIO pin for timer interrupt test. */ + SystemInit(); + /* Set the buff load mode of forcible output to independent load and the update time to zero. */ + APT0->PG_BUF_EN.BIT.rg_frc_buf_en = 1; + APT0->PG_ACT_LD.BIT.rg_pg_frcld_zroen = 1; + APT1->PG_BUF_EN.BIT.rg_frc_buf_en = 1; + APT1->PG_ACT_LD.BIT.rg_pg_frcld_zroen = 1; + APT2->PG_BUF_EN.BIT.rg_frc_buf_en = 1; + APT2->PG_ACT_LD.BIT.rg_pg_frcld_zroen = 1; + + /* Start APT module of U, V, W phases. */ + HAL_APT_StartModule(RUN_APT0 | RUN_APT1 | RUN_APT2); +} \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/inc/sample_apt_pwm_poe_status.h b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/inc/sample_apt_pwm_poe_status.h new file mode 100644 index 0000000000000000000000000000000000000000..5139ecf4b9da9fa0cbf88a760a9882a88fdb144c --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/inc/sample_apt_pwm_poe_status.h @@ -0,0 +1,32 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_apt_pwm_poe_status.h + * @author MCU Driver Team + * @brief APT sample module driver + * @details This file provides APT sample of pwm and poe status. + */ + +#ifndef McuMagicTag_SAMPLE_APT_PWM_POE_STATUS_H +#define McuMagicTag_SAMPLE_APT_PWM_POE_STATUS_H + +#include "apt.h" +#include "apt_ex.h" + +void APT_PwmPoeStatus(void); + +#endif /* McuMagicTag_SAMPLE_APT_PWM_POE_STATUS_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/init/main.c b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..1eb4bfb4a9752198a839fa1166e038e83aac8e5a --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/init/main.c @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +#include "sample_apt_pwm_poe_status.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +APT_Handle g_apt0; +APT_Handle g_apt1; +APT_Handle g_apt2; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + APT_PwmPoeStatus(); + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/init/main.h b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..b3e644f682643e463d5429bc30c7a7d11a50580d --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/init/main.h @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "apt.h" +#include "uart.h" +#include "uart_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern APT_Handle g_apt0; +extern APT_Handle g_apt1; +extern APT_Handle g_apt2; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +void APT0EventCallback(void *aptHandle); +void APT0TimerCallback(void *aptHandle); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/init/system_init.c b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..45399627a78362b71ad88f54c7e306dd659971df --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/init/system_init.c @@ -0,0 +1,319 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +__weak void APT0EventCallback(void *aptHandle) +{ + BASE_FUNC_UNUSED(aptHandle); + /* USER CODE BEGIN APT0_EVENT_INTERRUPT */ + /* USER CODE END APT0_EVENT_INTERRUPT */ +} + +__weak void APT0TimerCallback(void *aptHandle) +{ + BASE_FUNC_UNUSED(aptHandle); + /* USER CODE BEGIN APT0_TIMER_INTERRUPT */ + /* USER CODE END APT0_TIMER_INTERRUPT */ +} + +static void APT0_ProtectInit(void) +{ + APT_OutCtrlProtectEx protectApt = {0}; + protectApt.ocEventEnEx = BASE_CFG_ENABLE; + protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; /* One shot */ + protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; /* Protect low */ + protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; /* Protect low */ + protectApt.ocEvtInterruptEnEx = BASE_CFG_ENABLE; + protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; + protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_POE0; + protectApt.filterCycleNumEx = 0; + HAL_APT_ProtectInitEx(&g_apt0, &protectApt); +} + +static void APT0_Init(void) +{ + HAL_CRG_IpEnableSet(APT0_BASE, IP_CLK_ENABLE); + + g_apt0.baseAddress = APT0; + + /* Clock Settings */ + g_apt0.waveform.dividerFactor = 1 - 1; + /* Timer Settings */ + g_apt0.waveform.timerPeriod = 20000; /* 20000 is count period of APT time-base timer */ + g_apt0.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; + + /* Wave Form */ + g_apt0.waveform.basicType = APT_PWM_BASIC_A_HIGH_B_LOW; + g_apt0.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt0.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt0.waveform.divInitVal = 0; + g_apt0.waveform.cntInitVal = 0; + g_apt0.waveform.cntCmpLeftEdge = 500; /* 500 is count compare point of the left edge of PWM waveform */ + g_apt0.waveform.cntCmpRightEdge = 500; /* 500 is count compare point of the right edge of PWM waveform */ + g_apt0.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; + g_apt0.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; + g_apt0.waveform.deadBandCnt = 200; /* 200 is dead-band value */ + + /* Timer Trigger */ + g_apt0.tmrInterrupt.tmrInterruptEn = BASE_CFG_ENABLE; + g_apt0.tmrInterrupt.tmrInterruptSrc = APT_INT_SRC_CNTR_ZERO; + g_apt0.tmrInterrupt.tmrInterruptScale = 1; + + APT0_ProtectInit(); + + HAL_APT_PWMInit(&g_apt0); + HAL_APT_RegisterCallBack(&g_apt0, APT_EVENT_INTERRUPT, APT0EventCallback); + IRQ_SetPriority(IRQ_APT0_EVT, 7); /* 7 is priority value */ + IRQ_Register(IRQ_APT0_EVT, HAL_APT_EventIrqHandler, &g_apt0); + IRQ_EnableN(IRQ_APT0_EVT); + HAL_APT_RegisterCallBack(&g_apt0, APT_TIMER_INTERRUPT, APT0TimerCallback); + IRQ_SetPriority(IRQ_APT0_TMR, 6); /* 6 is priority value */ + IRQ_Register(IRQ_APT0_TMR, HAL_APT_TimerIrqHandler, &g_apt0); + IRQ_EnableN(IRQ_APT0_TMR); +} + +static void APT1_ProtectInit(void) +{ + APT_OutCtrlProtectEx protectApt = {0}; + protectApt.ocEventEnEx = BASE_CFG_ENABLE; + protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; /* One shot */ + protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; /* Protect low */ + protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; /* Protect low */ + protectApt.ocEvtInterruptEnEx = BASE_CFG_DISABLE; + protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; + protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_POE0; + protectApt.filterCycleNumEx = 0; + HAL_APT_ProtectInitEx(&g_apt1, &protectApt); +} + +static void APT1_Init(void) +{ + HAL_CRG_IpEnableSet(APT1_BASE, IP_CLK_ENABLE); + + g_apt1.baseAddress = APT1; + + /* Clock Settings */ + g_apt1.waveform.dividerFactor = 1 - 1; + /* Timer Settings */ + g_apt1.waveform.timerPeriod = 20000; /* 20000 is count period of APT time-base timer */ + g_apt1.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; + + /* Wave Form */ + g_apt1.waveform.basicType = APT_PWM_BASIC_A_HIGH_B_LOW; + g_apt1.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt1.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt1.waveform.divInitVal = 0; + g_apt1.waveform.cntInitVal = 0; + g_apt1.waveform.cntCmpLeftEdge = 500; /* 500 is count compare point of the left edge of PWM waveform */ + g_apt1.waveform.cntCmpRightEdge = 500; /* 500 is count compare point of the right edge of PWM waveform */ + g_apt1.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; + g_apt1.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; + g_apt1.waveform.deadBandCnt = 200; /* 200 is dead-band value */ + + APT1_ProtectInit(); + + HAL_APT_PWMInit(&g_apt1); +} + +static void APT2_ProtectInit(void) +{ + APT_OutCtrlProtectEx protectApt = {0}; + protectApt.ocEventEnEx = BASE_CFG_ENABLE; + protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; /* One shot */ + protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; /* Protect low */ + protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; /* Protect low */ + protectApt.ocEvtInterruptEnEx = BASE_CFG_DISABLE; + protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; + protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_POE0; + protectApt.filterCycleNumEx = 0; + HAL_APT_ProtectInitEx(&g_apt2, &protectApt); +} + +static void APT2_Init(void) +{ + HAL_CRG_IpEnableSet(APT2_BASE, IP_CLK_ENABLE); + + g_apt2.baseAddress = APT2; + + /* Clock Settings */ + g_apt2.waveform.dividerFactor = 1 - 1; + /* Timer Settings */ + g_apt2.waveform.timerPeriod = 20000; /* 20000 is count period of APT time-base timer */ + g_apt2.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; + + /* Wave Form */ + g_apt2.waveform.basicType = APT_PWM_BASIC_A_HIGH_B_LOW; + g_apt2.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt2.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt2.waveform.divInitVal = 0; + g_apt2.waveform.cntInitVal = 0; + g_apt2.waveform.cntCmpLeftEdge = 500; /* 500 is count compare point of the left edge of PWM waveform */ + g_apt2.waveform.cntCmpRightEdge = 500; /* 500 is count compare point of the right edge of PWM waveform */ + g_apt2.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; + g_apt2.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; + g_apt2.waveform.deadBandCnt = 200; /* 200 is dead-band value */ + + APT2_ProtectInit(); + + HAL_APT_PWMInit(&g_apt2); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; /* Band rate 115200 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; /* Length 8bit */ + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + /* Config PIN15 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_5_AS_APT0_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_5_AS_APT0_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_5_AS_APT0_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_5_AS_APT0_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_5_AS_APT0_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN18 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_0_AS_APT0_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_0_AS_APT0_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_0_AS_APT0_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_0_AS_APT0_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_0_AS_APT0_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN30 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO5_0_AS_POE0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO5_0_AS_POE0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO5_0_AS_POE0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO5_0_AS_POE0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO5_0_AS_POE0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN16 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_6_AS_APT1_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_6_AS_APT1_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_6_AS_APT1_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_6_AS_APT1_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_6_AS_APT1_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN19 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_1_AS_APT1_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_1_AS_APT1_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_1_AS_APT1_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_1_AS_APT1_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_1_AS_APT1_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN17 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_7_AS_APT2_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_7_AS_APT2_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_7_AS_APT2_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_7_AS_APT2_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_7_AS_APT2_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN20 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_2_AS_APT2_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_2_AS_APT2_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_2_AS_APT2_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_2_AS_APT2_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_2_AS_APT2_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +static void APT_SyncMasterInit(void) +{ + /* Master config */ + HAL_APT_MasterSyncInit(&g_apt0, APT_SYNC_OUT_ON_CNTR_ZERO); +} + +static void APT_SyncSlaveInit(void) +{ + APT_SlaveSyncIn aptSlave; + + aptSlave.cntPhase = 0; /* counter phase value */ + aptSlave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; + aptSlave.syncInSrc = APT_SYNCIN_SRC_APT0_SYNCOUT; /* sync source selection */ + aptSlave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; + HAL_APT_SlaveSyncInit(&g_apt1, &aptSlave); + + aptSlave.cntPhase = 0; /* counter phase value */ + aptSlave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; + aptSlave.syncInSrc = APT_SYNCIN_SRC_APT0_SYNCOUT; /* sync source selection */ + aptSlave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; + HAL_APT_SlaveSyncInit(&g_apt2, &aptSlave); +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + APT0_Init(); + APT1_Init(); + APT2_Init(); + + APT_SyncMasterInit(); + APT_SyncSlaveInit(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/readme.md b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..10250c3388af9349f0e01aa267226170c5fd8d1c --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/readme.md @@ -0,0 +1,23 @@ +# 获取PWM输出状态和POE电平 +## 关键字: PWM输出、POE电平 + +**【功能描述】** ++ 该示例为APT强制动作状态下,读取PWM的输出状态和POE电平; ++ 以及手动触发POE保护后,读取PWM的输出状态和POE电平。 + +**【示例配置】** ++ 配置APT0输出模式为AHBL,POE0信号高保护。 + ++ APT保护行为是低电平。 + ++ 以上配置可通过APT配置界面进行更改,或在“system_init.c”中更改APT对应的配置。 + +**【示例效果】** ++ APT未发生保护,读取g_testRes1和g_testRes2的结果,若结果为1,说明PWM状态和POE状态正确。 + ++ 手动触发POE0高电平,APT进入保护模式,APT模块会停止PWM波的输出,读取g_testRes3,若结果为1,说明PWM状态和POE状态正确。 + +**【注意事项】** ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/src/sample_apt_pwm_poe_status.c b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/src/sample_apt_pwm_poe_status.c new file mode 100644 index 0000000000000000000000000000000000000000..739ad3b804fa5be39a90f3f4ecd90b0bc3e187b7 --- /dev/null +++ b/src/application/drivers_sample/apt/sample_apt_pwm_poe_status/src/sample_apt_pwm_poe_status.c @@ -0,0 +1,240 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_apt_pwm_poe_status.c + * @author MCU Driver Team + * @brief APT sample module driver + * @details This file provides APT sample of pwm and poe status. + */ + +#include "sample_apt_pwm_poe_status.h" +#include "apt.h" +#include "debug.h" +#include "crg.h" +#include "main.h" + + +typedef enum { + APT_CHA_PWM_CHB_PWM, + APT_CHA_PWM_CHB_LOW, + APT_CHA_LOW_CHB_HIGH, + APT_CHA_LOW_CHB_LOW, + APT_CHA_HIGH_CHB_LOW, +} AptAct; + + +static void APT_Config(APT_RegStruct* aptAddr, AptAct aptAct); +static bool CheckStatusPwmChAHighChBLow(APT_Handle *aptHandle); +static bool CheckStatusPwmChALowChBHigh(APT_Handle *aptHandle); +static bool POE_CheckStatus(APT_Handle *aptHandle); + +/** + * @brief Event interrupt callback function of U phase APT module. + * @param aptHandle APT module handle. + * @retval None. + */ +void APT0EventCallback(void *aptHandle) +{ + BASE_FUNC_UNUSED(aptHandle); + /* POE is manually triggered High, the output will meet the expectation. */ + bool g_testRes3 = POE_CheckStatus(&g_apt0); + if (g_testRes3) { + APT_PwmStatus aptChAStatus; + APT_PwmStatus aptChBStatus; + APT_PoeStatus POEStatus; + /* Read pwm status and poe status */ + /* Desired output of CHA: APT_PWM_LOW_LEVEL */ + aptChAStatus = HAL_APT_GetPwmStatus(aptHandle, APT_PWM_CHANNEL_A); + /* Desired output of CHB: APT_PWM_LOW_LEVEL */ + aptChBStatus = HAL_APT_GetPwmStatus(aptHandle, APT_PWM_CHANNEL_B); + /* Desired output of POE: APT_POE_HIGH_LEVEL */ + POEStatus = HAL_APT_GetPoeStatus(aptHandle, APT_POE0); + DBG_PRINTF("POE0 is triggered, PWM A status is %d, PWM B status is %d, POE status is %d, correct!\n", \ + aptChAStatus, aptChBStatus, POEStatus); + } +} + +/** + * @brief Timer interrupt callback function of APT module. + * @param aptHandle APT module handle. + * @retval None. + */ +void APT0TimerCallback(void *aptHandle) +{ + BASE_FUNC_UNUSED(aptHandle); + HAL_APT_SetPWMDutyByNumber(&g_apt0, 50); /* Pwm duty is 50% */ +} + +/** + * @brief Test pwm status and poe status in three condition. + * @retval None. + */ +void APT_PwmPoeStatus(void) +{ + SystemInit(); + HAL_APT_StartModule(RUN_APT0 | RUN_APT0 | RUN_APT0); + + BASE_FUNC_DELAY_S(3); /* Delay 3s */ + /* Pwm channel A output High level and channel B output Low level */ + bool g_testRes1 = CheckStatusPwmChAHighChBLow(&g_apt0); + if (g_testRes1) { + DBG_PRINTF("PWM A is High, PWM B is Low, POE status is Low, correct!\n"); + } + + BASE_FUNC_DELAY_S(3); /* Delay 3s */ + /* Pwm channel A output Low level and channel B output High level */ + bool g_testRes2 = CheckStatusPwmChALowChBHigh(&g_apt0); + if (g_testRes2) { + DBG_PRINTF("PWM A is Low, PWM B is High, POE status is Low, correct!\n"); + } + + BASE_FUNC_DELAY_S(3); /* Delay 3s */ + /* Channel A and B output pwm */ + DCL_APT_DisableSwContPWMAction(g_apt0.baseAddress, APT_PWM_CHANNEL_A); + DCL_APT_DisableSwContPWMAction(g_apt0.baseAddress, APT_PWM_CHANNEL_B); + + while (1) { + } +} + +/** + * @brief Configure APT action. + * @param aptAddr APT base address. + * @param aptAct The APT action. + */ +static void APT_Config(APT_RegStruct* aptAddr, AptAct aptAct) +{ + switch (aptAct) { + case APT_CHA_PWM_CHB_PWM: + /* Channel A: 0 means not force output enable, channel A output PWM. */ + DCL_APT_DisableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A); + /* Channel B: 0 means not force output enable, channel B output PWM. */ + DCL_APT_DisableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B); + break; + case APT_CHA_PWM_CHB_LOW: + /* Channel A: 0 means not force output enable, channel A output PWM. */ + DCL_APT_DisableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A); + /* Channel B: 1 means force output enable. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B); + /* Channel B: 2 means channel B force output LOW due to the A_H_B_L invert. */ + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + case APT_CHA_LOW_CHB_HIGH: + /* Channel A: 1 means force output enable. */ + /* Channel A: 1 means channel A force output LOW. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A); + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + /* Channel B: 1 means force output enable. */ + /* Channel B: 1 means channel A force output HIGH due to the A_H_B_L invert. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B); + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_LOW); + break; + case APT_CHA_LOW_CHB_LOW: + /* Channel A: 1 means force output enable. */ + /* Channel A: 1 means channel A force output LOW. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A); + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + /* Channel B: 1 means force output enable. */ + /* Channel B: 2 means channel A force output LOW due to the A_H_B_L invert. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B); + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + case APT_CHA_HIGH_CHB_LOW: + /* Channel A: 1 means force output enable. */ + /* Channel A: 1 means channel A force output HIGH. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A); + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_HIGH); + /* Channel B: 1 means force output enable. */ + /* Channel B: 2 means channel A force output LOW due to the A_H_B_L invert. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B); + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + default: + break; + } +} + +/** + * @brief Check pwm and poe status when channel A output high, channel B output low. + * @param aptHandle APT Handle. + * @retval bool. + * true: The obtained PWM and POE status is consistent with the preset status. + * false: The obtained PWM and PO status is not consistent with the preset status. + */ +static bool CheckStatusPwmChAHighChBLow(APT_Handle *aptHandle) +{ + APT_PwmStatus aptChAStatus; + APT_PwmStatus aptChBStatus; + APT_PoeStatus POEStatus; + + APT_Config(aptHandle->baseAddress, APT_CHA_HIGH_CHB_LOW); + /* delay 100 ms */ + BASE_FUNC_DELAY_MS(100); + /* Read pwm status and poe status */ + aptChAStatus = HAL_APT_GetPwmStatus(aptHandle, APT_PWM_CHANNEL_A); /* Desired output of CHA: APT_PWM_HIGH_LEVEL */ + aptChBStatus = HAL_APT_GetPwmStatus(aptHandle, APT_PWM_CHANNEL_B); /* Desired output of CHB: APT_PWM_LOW_LEVEL */ + POEStatus = HAL_APT_GetPoeStatus(aptHandle, APT_POE0); /* Desired output of POE: APT_POE_LOW_LEVEL */ + return (aptChAStatus == APT_PWM_HIGH_LEVEL && \ + aptChBStatus == APT_PWM_LOW_LEVEL && \ + POEStatus == APT_POE_LOW_LEVEL); +} + +/** + * @brief Check pwm and poe status when channel A output high, channel B output low. + * @param aptHandle APT Handle. + * @retval bool. + * true: The obtained PWM and POE status is consistent with the preset status. + * false: The obtained PWM and PO status is not consistent with the preset status. + */ +static bool CheckStatusPwmChALowChBHigh(APT_Handle *aptHandle) +{ + APT_PwmStatus aptChAStatus; + APT_PwmStatus aptChBStatus; + APT_PoeStatus POEStatus; + APT_Config(aptHandle->baseAddress, APT_CHA_LOW_CHB_HIGH); + /* delay 100 ms */ + BASE_FUNC_DELAY_MS(100); + /* Read pwm status and poe status */ + aptChAStatus = HAL_APT_GetPwmStatus(aptHandle, APT_PWM_CHANNEL_A); /* Desired output of CHA: APT_PWM_LOW_LEVEL */ + aptChBStatus = HAL_APT_GetPwmStatus(aptHandle, APT_PWM_CHANNEL_B); /* Desired output of CHB: APT_PWM_HIGH_LEVEL */ + POEStatus = HAL_APT_GetPoeStatus(aptHandle, APT_POE0); /* Desired output of POE: APT_POE_LOW_LEVEL */ + return (aptChAStatus == APT_PWM_LOW_LEVEL && \ + aptChBStatus == APT_PWM_HIGH_LEVEL && \ + POEStatus == APT_POE_LOW_LEVEL); +} + +/** + * @brief Check pwm and poe status when poe is trigger high manually. + * @param aptHandle APT Handle. + * @retval bool. + * true: The obtained PWM and POE status is consistent with the preset status. + * false: The obtained PWM and PO status is not consistent with the preset status. + */ +static bool POE_CheckStatus(APT_Handle *aptHandle) +{ + APT_PwmStatus aptChAStatus; + APT_PwmStatus aptChBStatus; + APT_PoeStatus POEStatus; + /* Read pwm status and poe status */ + aptChAStatus = HAL_APT_GetPwmStatus(aptHandle, APT_PWM_CHANNEL_A); /* Desired output of CHA: APT_PWM_LOW_LEVEL */ + aptChBStatus = HAL_APT_GetPwmStatus(aptHandle, APT_PWM_CHANNEL_B); /* Desired output of CHB: APT_PWM_LOW_LEVEL */ + POEStatus = HAL_APT_GetPoeStatus(aptHandle, APT_POE0); /* Desired output of POE: APT_POE_HIGH_LEVEL */ + + return (aptChAStatus == APT_PWM_LOW_LEVEL && \ + aptChBStatus == APT_PWM_LOW_LEVEL && \ + POEStatus == APT_POE_HIGH_LEVEL); +} diff --git a/src/application/drivers_sample/apt/sample_apt_single_resistor/inc/sample_apt_single_resistor.h b/src/application/drivers_sample/apt/sample_apt_single_resistor/inc/sample_apt_single_resistor.h index 6ec216fa16274064f5c697fd8daeb43b0e5308f1..62d94778af537f5f9732de99ab54e08a3b2ec56d 100644 --- a/src/application/drivers_sample/apt/sample_apt_single_resistor/inc/sample_apt_single_resistor.h +++ b/src/application/drivers_sample/apt/sample_apt_single_resistor/inc/sample_apt_single_resistor.h @@ -20,8 +20,8 @@ * @brief Header file containing functions prototypes of APT module HAL sample. */ -#ifndef McuMagicTag_APT_HAL_SAMPLE_H -#define McuMagicTag_APT_HAL_SAMPLE_H +#ifndef McuMagicTag_SAMPLE_APT_SINGLE_RESISTOR_H +#define McuMagicTag_SAMPLE_APT_SINGLE_RESISTOR_H #include "apt_ip.h" #include "interrupt.h" diff --git a/src/application/drivers_sample/apt/sample_apt_single_resistor/readme.md b/src/application/drivers_sample/apt/sample_apt_single_resistor/readme.md index 3d4224711ba365124e554a4db8b9ba712609cab6..64150f1065d5d93da26dadadada2ca7df0587308 100644 --- a/src/application/drivers_sample/apt/sample_apt_single_resistor/readme.md +++ b/src/application/drivers_sample/apt/sample_apt_single_resistor/readme.md @@ -26,4 +26,8 @@ ①递增/递减计时模式,PWM 波的频率 = 工作时钟频率 / ((分频器的分频系数+1)*(计数器的计数周期值+1)); ②先增后减计时模式,PWM 波的频率 = 工作时钟频率 / ((分频器的分频系数+1)*(计数器的计数周期值*2))。 ``` -+ 死区的宽度:插入死区的宽度 = 工作时钟周期 * 死区延时计数值。 \ No newline at end of file ++ 死区的宽度:插入死区的宽度 = 工作时钟周期 * 死区延时计数值。 + ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/apt/sample_apt_three_resistor/inc/sample_apt_three_resistor.h b/src/application/drivers_sample/apt/sample_apt_three_resistor/inc/sample_apt_three_resistor.h index 6ec216fa16274064f5c697fd8daeb43b0e5308f1..27f79f1e6f93af5a774e060c075b05929102f853 100644 --- a/src/application/drivers_sample/apt/sample_apt_three_resistor/inc/sample_apt_three_resistor.h +++ b/src/application/drivers_sample/apt/sample_apt_three_resistor/inc/sample_apt_three_resistor.h @@ -20,8 +20,8 @@ * @brief Header file containing functions prototypes of APT module HAL sample. */ -#ifndef McuMagicTag_APT_HAL_SAMPLE_H -#define McuMagicTag_APT_HAL_SAMPLE_H +#ifndef McuMagicTag_SAMPLE_APT_THREE_RESISTOR_H +#define McuMagicTag_SAMPLE_APT_THREE_RESISTOR_H #include "apt_ip.h" #include "interrupt.h" diff --git a/src/application/drivers_sample/apt/sample_apt_three_resistor/readme.md b/src/application/drivers_sample/apt/sample_apt_three_resistor/readme.md index ef54a5b89fc59e596accaab0d8b12017c126c620..817242d8942912ceb5a3f883d63e76e174ac0fa9 100644 --- a/src/application/drivers_sample/apt/sample_apt_three_resistor/readme.md +++ b/src/application/drivers_sample/apt/sample_apt_three_resistor/readme.md @@ -27,4 +27,8 @@ ②先增后减计时模式,PWM 波的频率 = 工作时钟频率 / ((分频器的分频系数+1)*(计数器的计数周期值*2))。 ``` -+ 死区的宽度:插入死区的宽度 = 工作时钟周期 * 死区延时计数值。 \ No newline at end of file ++ 死区的宽度:插入死区的宽度 = 工作时钟周期 * 死区延时计数值。 + ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/can/sample_can_send_receive/init/main.h b/src/application/drivers_sample/can/sample_can_send_receive/init/main.h index ae1c13877551f6b3adc20b938a6ef83fee90f0f4..7f48eb30562d25dcd1869d35a050798b4afde180 100644 --- a/src/application/drivers_sample/can/sample_can_send_receive/init/main.h +++ b/src/application/drivers_sample/can/sample_can_send_receive/init/main.h @@ -28,6 +28,7 @@ #include "uart_ex.h" #include "can.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U diff --git a/src/application/drivers_sample/can/sample_can_send_receive/init/system_init.c b/src/application/drivers_sample/can/sample_can_send_receive/init/system_init.c index d4409cb628f01e839929649e254429ed24360d35..b85ee430cb9bc5caeb3440c9c945bb4025c49b9a 100644 --- a/src/application/drivers_sample/can/sample_can_send_receive/init/system_init.c +++ b/src/application/drivers_sample/can/sample_can_send_receive/init/system_init.c @@ -22,7 +22,7 @@ #include "main.h" #include "ioconfig.h" -#include "iocmg.h" +#include "iocmg_ip.h" #define UART0_BAND_RATE 115200 @@ -34,9 +34,11 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 48; /* PLL Multiplier 48 */ crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -84,7 +86,7 @@ static void CAN_Init(void) HAL_CAN_RegisterCallBack(&g_can, CAN_WRITE_FINISH, CAN_WriteFinish); HAL_CAN_RegisterCallBack(&g_can, CAN_TRNS_ERROR, CAN_Transmit_Error); IRQ_Register(IRQ_CAN, HAL_CAN_IrqHandler, &g_can); - IRQ_SetPriority(IRQ_CAN, 1); + IRQ_SetPriority(IRQ_CAN, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_CAN); } @@ -117,17 +119,23 @@ static void IOConfig(void) HAL_IOCMG_SetPinLevelShiftRate(GPIO3_5_AS_CAN_TX, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO3_5_AS_CAN_TX, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_6_AS_CAN_RX); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_6_AS_CAN_RX, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_6_AS_CAN_RX, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_6_AS_CAN_RX, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_6_AS_CAN_RX, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/can/sample_can_send_receive/readme.md b/src/application/drivers_sample/can/sample_can_send_receive/readme.md index 0d83947848602ef505e1b6332e4e031f4e564527..afd5531f16d4618619443b5254cc8f35bab25468 100644 --- a/src/application/drivers_sample/can/sample_can_send_receive/readme.md +++ b/src/application/drivers_sample/can/sample_can_send_receive/readme.md @@ -7,7 +7,7 @@ + CAN模块数据的发送和接收采用的都是中断形式。 **【示例配置】** -+ 初始化CAN:通过g_can.typeMode配置CAN的工作模式,配置CAN的传输波特率,接收FIFO的深度以及否开启自动重传。这些配置可以通过CAN的配置界面进行更改。默认配置参数可以通过CAN的配置界面或“system_init.c”文件中的进行查看。 ++ 初始化CAN:通过g_can.typeMode配置CAN的工作模式,配置CAN的传输波特率,接收FIFO的深度以及否开启自动重传。这些配置可以通过CAN的配置界面进行更改。默认配置参数可以通过CAN的配置界面或“system_init.c”文件进行查看。 + 发送数据帧g_sendFrame:分配发送数据帧的类型为扩展帧,指定发送帧的ID,填入需要发送的数据和长度,调用“HAL_CAN_Write”函数进行数据的发送。发送成功之后会调用回调函数“Can_WriteFinish”,此回调函数可以通过“HAL_CAN_RegisterCallBack”进行注册。 @@ -16,11 +16,14 @@ + 过滤条件rxFilter:配置过滤的帧类型和过滤ID和过滤掩码。并通过“HAL_CAN_ReadIT”使过滤规则生效,接收成功之后,会调用接收成功回调函数“Can_ReadFinish”,此回调函数也可以通过“HAL_CAN_RegisterCallBack”进行注册。 **【示例效果】** -+ 编译烧录此示例,此示例会向总线发送ID为0x1314的扩展数据帧,数据内容为字符‘0’。接收总线上ID为0x1X14的扩展帧(X代表任意0-F的数字)。 ++ 编译烧录此示例,此示例会向总线发送ID为0x1314的扩展数据帧,数据内容为字符‘0’。接收总线上ID为0x1X14的扩展帧(X代表任意0-F的数字)。 + 串口0打印提示信息:CAN发送给总线的数据和接收到总线的数据。 **【注意事项】** + 发送给总线的数据帧为扩展帧类型,且满足过滤条件,才会被接收,其他数据默认会被总线丢弃。 -+ 此示例默认开启自动重发,数据发送失败,会重新发送。若不想重发,需在配置中关闭“Auto Retransmission”项,或在“system_init.c”中关闭“g_can.autoRetrans”配置项。 \ No newline at end of file ++ 此示例默认开启自动重发,数据发送失败,会重新发送。若不想重发,需在配置中关闭“Auto Retransmission”项,或在“system_init.c”中关闭“g_can.autoRetrans”配置项。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/capm/capm_hall_sample/inc/capm_hall_sample.h b/src/application/drivers_sample/capm/sample_capm_hall/inc/sample_capm_hall.h similarity index 90% rename from src/application/drivers_sample/capm/capm_hall_sample/inc/capm_hall_sample.h rename to src/application/drivers_sample/capm/sample_capm_hall/inc/sample_capm_hall.h index a106aa41d55166358a0dbc5e0f591a4f5282f415..44764c97268cfa1495e82b4386bde82a06295b17 100644 --- a/src/application/drivers_sample/capm/capm_hall_sample/inc/capm_hall_sample.h +++ b/src/application/drivers_sample/capm/sample_capm_hall/inc/sample_capm_hall.h @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,13 +15,13 @@ * 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. - * @file capm_hall_sample.h + * @file sample_capm_hall.h * @author MCU Driver Team * @brief CAPM HAL level module driver head file. * This file shows a sample to get hall position information */ -#ifndef McuMagicTag_CAPM_HALL_SAMPLE_H -#define McuMagicTag_CAPM_HALL_SAMPLE_H +#ifndef McuMagicTag_SAMPLE_CAPM_HALL_H +#define McuMagicTag_SAMPLE_CAPM_HALL_H #include "baseinc.h" #include "capm_ip.h" #include "capm.h" diff --git a/src/application/drivers_sample/capm/sample_capm_hall/init/main.c b/src/application/drivers_sample/capm/sample_capm_hall/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..4eaab45e06afebe9b541ab5cbe060f28228ff1dd --- /dev/null +++ b/src/application/drivers_sample/capm/sample_capm_hall/init/main.c @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_capm_hall.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +CAPM_Handle g_capmAConfig; +CAPM_Handle g_capmBConfig; +CAPM_Handle g_capmCConfig; +UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + CAPM_HallSample(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/capm/capm_hall_sample/init/main.h b/src/application/drivers_sample/capm/sample_capm_hall/init/main.h similarity index 88% rename from src/application/drivers_sample/capm/capm_hall_sample/init/main.h rename to src/application/drivers_sample/capm/sample_capm_hall/init/main.h index 3e18da3b81ba96ceac63d0ae4c0a2424c3eb17fa..75314ac7a5544d3f20fbc73309699fa8c32fb09f 100644 --- a/src/application/drivers_sample/capm/capm_hall_sample/init/main.h +++ b/src/application/drivers_sample/capm/sample_capm_hall/init/main.h @@ -36,13 +36,21 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern CAPM_Handle g_capmAConfig; extern CAPM_Handle g_capmBConfig; extern CAPM_Handle g_capmCConfig; - extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/capm/capm_hall_sample/init/system_init.c b/src/application/drivers_sample/capm/sample_capm_hall/init/system_init.c similarity index 55% rename from src/application/drivers_sample/capm/capm_hall_sample/init/system_init.c rename to src/application/drivers_sample/capm/sample_capm_hall/init/system_init.c index d3016cc979fe639b51c7b776ff384a1a68e14787..e32c71c716f8c8e468cf2550d521a4fdfc8e533d 100644 --- a/src/application/drivers_sample/capm/capm_hall_sample/init/system_init.c +++ b/src/application/drivers_sample/capm/sample_capm_hall/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -46,19 +48,17 @@ static void CAPM0_Init(void) HAL_CRG_IpEnableSet(CAPM0_BASE, IP_CLK_ENABLE); g_capmAConfig.baseAddress = CAPM0; - g_capmAConfig.evtIrqNum = IRQ_CAPM0; g_capmAConfig.deburrNum = 0; /* deburr value */ g_capmAConfig.capMode = CAPM_CONTINUECAP; /* capture mode */ - g_capmAConfig.preScale = 1; - g_capmAConfig.capRegConfig[0].capEvent = CAPM_RISING; /* capture rising edge */ - g_capmAConfig.capRegConfig[0].regReset = CAPM_RESET; - g_capmAConfig.capRegConfig[1].capEvent = CAPM_FALLING; /* capture falling edge */ - g_capmAConfig.capRegConfig[1].regReset = CAPM_RESET; + g_capmAConfig.preScale = 0; + g_capmAConfig.capRegConfig[CAPM_ECR_NUM1].capEvent = CAPM_RISING; /* capture rising edge */ + g_capmAConfig.capRegConfig[CAPM_ECR_NUM1].regReset = CAPM_NOTRESET; + g_capmAConfig.capRegConfig[CAPM_ECR_NUM2].capEvent = CAPM_FALLING; /* capture falling edge */ + g_capmAConfig.capRegConfig[CAPM_ECR_NUM2].regReset = CAPM_NOTRESET; g_capmAConfig.useCapNum = 2; /* 2: use 2 ECR */ g_capmAConfig.tscntDiv = 1 - 1; g_capmAConfig.inputSrc = CAPM_INPUT_SRC1; /* input source 1 */ - HAL_CAPM_Init(&g_capmAConfig); } @@ -67,19 +67,17 @@ static void CAPM1_Init(void) HAL_CRG_IpEnableSet(CAPM1_BASE, IP_CLK_ENABLE); g_capmBConfig.baseAddress = CAPM1; - g_capmBConfig.evtIrqNum = IRQ_CAPM1; g_capmBConfig.deburrNum = 0; /* deburr value */ g_capmBConfig.capMode = CAPM_CONTINUECAP; /* capture mode */ - g_capmBConfig.preScale = 1; - g_capmBConfig.capRegConfig[0].capEvent = CAPM_RISING; /* capture rising edge */ - g_capmBConfig.capRegConfig[0].regReset = CAPM_RESET; - g_capmBConfig.capRegConfig[1].capEvent = CAPM_FALLING; /* capture falling edge */ - g_capmBConfig.capRegConfig[1].regReset = CAPM_RESET; + g_capmBConfig.preScale = 0; + g_capmBConfig.capRegConfig[CAPM_ECR_NUM1].capEvent = CAPM_RISING; /* capture rising edge */ + g_capmBConfig.capRegConfig[CAPM_ECR_NUM1].regReset = CAPM_NOTRESET; + g_capmBConfig.capRegConfig[CAPM_ECR_NUM2].capEvent = CAPM_FALLING; /* capture falling edge */ + g_capmBConfig.capRegConfig[CAPM_ECR_NUM2].regReset = CAPM_NOTRESET; g_capmBConfig.useCapNum = 2; /* 2: use 2 ECR */ g_capmBConfig.tscntDiv = 1 - 1; - g_capmBConfig.inputSrc = CAPM_INPUT_SRC0; /* input source 0 */ - + g_capmBConfig.inputSrc = CAPM_INPUT_SRC0; /* input source 1 */ HAL_CAPM_Init(&g_capmBConfig); } @@ -88,19 +86,17 @@ static void CAPM2_Init(void) HAL_CRG_IpEnableSet(CAPM2_BASE, IP_CLK_ENABLE); g_capmCConfig.baseAddress = CAPM2; - g_capmCConfig.evtIrqNum = IRQ_CAPM2; g_capmCConfig.deburrNum = 0; /* deburr value */ g_capmCConfig.capMode = CAPM_CONTINUECAP; /* capture mode */ - g_capmCConfig.preScale = 1; - g_capmCConfig.capRegConfig[0].capEvent = CAPM_RISING; /* capture rising edge */ - g_capmCConfig.capRegConfig[0].regReset = CAPM_RESET; - g_capmCConfig.capRegConfig[1].capEvent = CAPM_FALLING; /* capture falling edge */ - g_capmCConfig.capRegConfig[1].regReset = CAPM_RESET; + g_capmCConfig.preScale = 0; + g_capmCConfig.capRegConfig[CAPM_ECR_NUM1].capEvent = CAPM_RISING; /* capture rising edge */ + g_capmCConfig.capRegConfig[CAPM_ECR_NUM1].regReset = CAPM_NOTRESET; + g_capmCConfig.capRegConfig[CAPM_ECR_NUM2].capEvent = CAPM_FALLING; /* capture falling edge */ + g_capmCConfig.capRegConfig[CAPM_ECR_NUM2].regReset = CAPM_NOTRESET; g_capmCConfig.useCapNum = 2; /* 2: use 2 ECR */ g_capmCConfig.tscntDiv = 1 - 1; g_capmCConfig.inputSrc = CAPM_INPUT_SRC1; /* input source 1 */ - HAL_CAPM_Init(&g_capmCConfig); } @@ -110,7 +106,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; /* uart0 base address */ - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; /* uart bandrate */ g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -127,51 +122,45 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_20.BIT.func = 0x3; /* 0x3 is CAPM0_SRC */ - iconfig->iocmg_20.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_20.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_20.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_20.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_20.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_8.BIT.func = 0x3; /* 0x3 is CAPM1_SRC */ - iconfig->iocmg_8.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_8.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_8.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_8.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_8.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_19.BIT.func = 0x3; /* 0x3 is CAPM2_SRC */ - iconfig->iocmg_19.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_19.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_19.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_19.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_19.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO4_AS_CAPM0_SRC1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO4_AS_CAPM0_SRC1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO4_AS_CAPM0_SRC1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO4_AS_CAPM0_SRC1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO4_AS_CAPM0_SRC1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO54_AS_CAPM1_SRC0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO54_AS_CAPM1_SRC0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO54_AS_CAPM1_SRC0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO54_AS_CAPM1_SRC0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO54_AS_CAPM1_SRC0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO3_AS_CAPM2_SRC1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO3_AS_CAPM2_SRC1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO3_AS_CAPM2_SRC1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO3_AS_CAPM2_SRC1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO3_AS_CAPM2_SRC1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); + UART0_Init(); CAPM0_Init(); CAPM1_Init(); CAPM2_Init(); - UART0_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/capm/capm_hall_sample/readme.md b/src/application/drivers_sample/capm/sample_capm_hall/readme.md similarity index 74% rename from src/application/drivers_sample/capm/capm_hall_sample/readme.md rename to src/application/drivers_sample/capm/sample_capm_hall/readme.md index 063867325627f281d23fb038e87fec2fc27c560d..d7279a43b382818eb5738f5c19d6ffe0fab75a34 100644 --- a/src/application/drivers_sample/capm/capm_hall_sample/readme.md +++ b/src/application/drivers_sample/capm/sample_capm_hall/readme.md @@ -16,3 +16,7 @@ **【注意事项】** + 需要转动电机才能进行CAPM捕获霍尔传感器信号 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/capm/capm_hall_sample/src/capm_hall_sample.c b/src/application/drivers_sample/capm/sample_capm_hall/src/sample_capm_hall.c similarity index 69% rename from src/application/drivers_sample/capm/capm_hall_sample/src/capm_hall_sample.c rename to src/application/drivers_sample/capm/sample_capm_hall/src/sample_capm_hall.c index 98721f9b940d288bcc16b44ab1f45e0746ae4b44..5cd0011c22b17b545beef8f377e9e063240a5bf9 100644 --- a/src/application/drivers_sample/capm/capm_hall_sample/src/capm_hall_sample.c +++ b/src/application/drivers_sample/capm/sample_capm_hall/src/sample_capm_hall.c @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,12 +15,12 @@ * 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. - * @file capm_hall_sample.c + * @file sample_capm_hall.h * @author MCU Driver Team - * @brief CAPM use HALL sensor implementation sample. - * @details This file provides CAPM use HALL sensor implementation sample. + * @brief CAPM HAL level module driver head file. + * This file shows a sample to get hall position information */ -#include "capm_hall_sample.h" +#include "sample_capm_hall.h" #include "interrupt.h" #include "debug.h" #include "main.h" @@ -53,14 +53,28 @@ static unsigned char CAPM_CalculateLevel(CAPM_Handle *handle) */ unsigned char CAPM_GetHallValue(void) { - unsigned char hallALevel, hallBLevel, hallCLevel; unsigned char hallPosition; - hallALevel = CAPM_CalculateLevel(&g_capmAConfig); /* get A phase's level */ - hallBLevel = CAPM_CalculateLevel(&g_capmBConfig); /* get B phase's level */ - hallCLevel = CAPM_CalculateLevel(&g_capmCConfig); /* get C phase's level */ +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || \ + defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + /* 3066m */ + unsigned char hall0Level = CAPM_CalculateLevel(&g_capm0); /* get capm0 level */ + unsigned char hall1Level = CAPM_CalculateLevel(&g_capm1); /* get capm1 level */ + unsigned char hall2Level = CAPM_CalculateLevel(&g_capm2); /* get capm2 level */ + + hallPosition = hall0Level << SECOND_BIT_SHIFT; /* move to the 2nd bit */ + hallPosition |= hall1Level << FIRST_BIT_SHIFT; /* move to the 1st bit */ + hallPosition |= hall2Level; +#else + /* 3061m/3065h */ + unsigned char hallALevel = CAPM_CalculateLevel(&g_capmAConfig); /* get A phase's level */ + unsigned char hallBLevel = CAPM_CalculateLevel(&g_capmBConfig); /* get B phase's level */ + unsigned char hallCLevel = CAPM_CalculateLevel(&g_capmCConfig); /* get C phase's level */ + hallPosition = hallALevel << SECOND_BIT_SHIFT; /* move to the 2nd bit */ hallPosition |= hallBLevel << FIRST_BIT_SHIFT; /* move to the 1st bit */ hallPosition |= hallCLevel; +#endif + return hallPosition; } @@ -73,7 +87,7 @@ void CAPM_HallSample(void) { SystemInit(); while (1) { - unsigned char data = CAPM_GetHallValue(); /* get hall sensor value */ + unsigned char data = CAPM_GetHallValue(); /* get hall sensor value. */ DBG_PRINTF("hall = 0x%x\r\n", data); } } \ No newline at end of file diff --git a/src/application/drivers_sample/cfd/sample_cfd_check_error/init/main.c b/src/application/drivers_sample/cfd/sample_cfd_check_error/init/main.c index 3438c6be10c853816b8d59b8cfb7a7b87784a5ac..80fa804d25b027d5ecf817c0fd9250763d639c2b 100644 --- a/src/application/drivers_sample/cfd/sample_cfd_check_error/init/main.c +++ b/src/application/drivers_sample/cfd/sample_cfd_check_error/init/main.c @@ -19,17 +19,41 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "cfd_check_error_sample.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ CFD_Handle g_cfd; UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ CFD_SampleMain(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/cfd/sample_cfd_check_error/init/main.h b/src/application/drivers_sample/cfd/sample_cfd_check_error/init/main.h index 86e2fa358b75b0cc8c152e5566e063dc9769924a..82f2cdac41285c9ce8af4aa34f03509bd4a18635 100644 --- a/src/application/drivers_sample/cfd/sample_cfd_check_error/init/main.h +++ b/src/application/drivers_sample/cfd/sample_cfd_check_error/init/main.h @@ -36,14 +36,22 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U -extern CFD_Handle g_cfd; +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U +extern CFD_Handle g_cfd; extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); -void CFDCheckEndCallback(CFD_Handle *handle); -void CFDClockStopCallback(CFD_Handle *handle); +void CheckEndCallback(CFD_Handle *handle); +void PllClockStopCallback(CFD_Handle *handle); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/cfd/sample_cfd_check_error/init/system_init.c b/src/application/drivers_sample/cfd/sample_cfd_check_error/init/system_init.c index a19630d3043ecb31f87a08a5e9bb7cc12d92fad6..5f7926a33fe2aa454aad224adb6aa1902360e9ad 100644 --- a/src/application/drivers_sample/cfd/sample_cfd_check_error/init/system_init.c +++ b/src/application/drivers_sample/cfd/sample_cfd_check_error/init/system_init.c @@ -22,18 +22,20 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; - crg.baseAddress = CRG; + crg.baseAddress = CRG; /* CRG base address */ crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -41,18 +43,18 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -__weak void CFDCheckEndCallback(CFD_Handle *handle) +__weak void CheckEndCallback(CFD_Handle *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN CFDCheckEndCallback */ - /* USER CODE END CFDCheckEndCallback */ + /* USER CODE BEGIN CFD_INT_CHECK_END_MASK */ + /* USER CODE END CFD_INT_CHECK_END_MASK */ } -__weak void CFD_CheckErrorCallback(CFD_Handle *handle) +__weak void PllClockStopCallback(CFD_Handle *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN CFDClockStopCallback */ - /* USER CODE END CFDClockStopCallback */ + /* USER CODE BEGIN CFD_INT_PLL_REF_CLOCK_STOP_MASK */ + /* USER CODE END CFD_INT_PLL_REF_CLOCK_STOP_MASK */ } static BASE_StatusType CFD_Init(void) @@ -60,24 +62,22 @@ static BASE_StatusType CFD_Init(void) g_cfd.baseAddress = CFD; g_cfd.upperBound = 2; /* 2: Upper limit of internal reference clock count value */ g_cfd.interruptType = CFD_INT_PLL_REF_CLOCK_STOP_MASK; - g_cfd.irqNum = IRQ_CFD; /* Register callback functions to be defined by users. only the selected interrupt type takes effect. */ - HAL_CFD_RegisterCallback(&g_cfd, CFD_INT_CHECK_END_MASK, CFDCheckEndCallback); - HAL_CFD_RegisterCallback(&g_cfd, CFD_INT_PLL_REF_CLOCK_STOP_MASK, CFD_CheckErrorCallback); + HAL_CFD_RegisterCallback(&g_cfd, CFD_INT_CHECK_END_MASK, (CFD_CallBackFuncType)CheckEndCallback); + HAL_CFD_RegisterCallback(&g_cfd, CFD_INT_PLL_REF_CLOCK_STOP_MASK, (CFD_CallBackFuncType)PllClockStopCallback); /* Associating irqNum with Callbacks */ - HAL_CFD_IRQService(&g_cfd); - IRQ_SetPriority(g_cfd.irqNum, 1); /* The value ranges from 1 to 7. A smaller value indicates a lower priority. */ - IRQ_EnableN(g_cfd.irqNum); + IRQ_Register(IRQ_CFD, HAL_CFD_IrqHandler, &g_cfd); + IRQ_SetPriority(IRQ_CFD, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_CFD); return HAL_CFD_Init(&g_cfd); } static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* Enable Uart Clock */ + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); /* Set uart clock div value 0 */ g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -85,37 +85,35 @@ static void UART0_Init(void) g_uart0.parity = UART_PARITY_NONE; g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; - g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoMode = BASE_CFG_ENABLE; /* Enable UART FIFO */ g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; - HAL_UART_Init(&g_uart0); + HAL_UART_Init(&g_uart0); /* UART Init */ } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); - CFD_Init(); UART0_Init(); + CFD_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/cfd/sample_cfd_check_error/readme.md b/src/application/drivers_sample/cfd/sample_cfd_check_error/readme.md index 80ba155fa21ef614371697bef72e2167cd44822a..ab7b4a146822eace8d32b8d792212c62efad9ff7 100644 --- a/src/application/drivers_sample/cfd/sample_cfd_check_error/readme.md +++ b/src/application/drivers_sample/cfd/sample_cfd_check_error/readme.md @@ -19,3 +19,7 @@ **【注意事项】** + 时钟失效中断触发硬件系统事件2会自动关闭APT并将主时钟切换为LOSC进行保护,用户可在中断服务函数中进行时钟恢复或者复位等安全操作; + 每次中断触发后自行判断计数值是否在门限内,非门限内则判定为异常时钟;该模块目标时钟分配比固化为2048分频,参考时钟不分频。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/cmm/sample_cmm_check_error/init/main.c b/src/application/drivers_sample/cmm/sample_cmm_check_error/init/main.c index 10c799d6f809070ae55fb8953a8b3d4f13319100..820b66d71e3e64f88b1e9b08976e889bebd43aa2 100644 --- a/src/application/drivers_sample/cmm/sample_cmm_check_error/init/main.c +++ b/src/application/drivers_sample/cmm/sample_cmm_check_error/init/main.c @@ -19,17 +19,41 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "cmm_check_error_sample.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ CMM_Handle g_cmm; UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ CMM_SampleMain(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/cmm/sample_cmm_check_error/init/main.h b/src/application/drivers_sample/cmm/sample_cmm_check_error/init/main.h index 46d13260e9cf87090ab855fc148c2f97262d6ddf..3b6be1f2670b647b995ad819c8261ee2535adeea 100644 --- a/src/application/drivers_sample/cmm/sample_cmm_check_error/init/main.h +++ b/src/application/drivers_sample/cmm/sample_cmm_check_error/init/main.h @@ -36,15 +36,23 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U -extern CMM_Handle g_cmm; +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U +extern CMM_Handle g_cmm; extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); -void CMMCheckEndCallback(CMM_Handle *handle); -void CMMCounterOverFlowCallback(CMM_Handle *handle); -void CMM_CheckErrorCallback(CMM_Handle *handle); +void CountOverflowCallback(CMM_Handle *handle); +void CheckEndCallback(CMM_Handle *handle); +void FreqErrorCallback(CMM_Handle *handle); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/cmm/sample_cmm_check_error/init/system_init.c b/src/application/drivers_sample/cmm/sample_cmm_check_error/init/system_init.c index 6604598a4b2157b45ca32b76a5cb4af72c3b12c0..0d9ed85a9d6099c9bc64c65d9a7641f21b660883 100644 --- a/src/application/drivers_sample/cmm/sample_cmm_check_error/init/system_init.c +++ b/src/application/drivers_sample/cmm/sample_cmm_check_error/init/system_init.c @@ -22,18 +22,20 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; - crg.baseAddress = CRG; + crg.baseAddress = CRG; /* CRG base address */ crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -41,57 +43,54 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -__weak void CMMCounterOverFlowCallback(CMM_Handle *handle) +__weak void CountOverflowCallback(CMM_Handle *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN CMMCounterOverFlowCallback */ - /* USER CODE END CMMCounterOverFlowCallback */ + /* USER CODE BEGIN CMM_INT_COUNTER_OVERFLOW_MASK */ + /* USER CODE END CMM_INT_COUNTER_OVERFLOW_MASK */ } -__weak void CMMCheckEndCallback(CMM_Handle *handle) +__weak void CheckEndCallback(CMM_Handle *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN CMMCheckEndCallback */ - /* USER CODE END CMMCheckEndCallback */ + /* USER CODE BEGIN CMM_INT_CHECK_END_MASK */ + /* USER CODE END CMM_INT_CHECK_END_MASK */ } -__weak void CMM_CheckErrorCallback(CMM_Handle *handle) +__weak void FreqErrorCallback(CMM_Handle *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN CMM_CheckErrorCallback */ - /* USER CODE END CMM_CheckErrorCallback */ + /* USER CODE BEGIN CMM_INT_FREQ_ERR_MASK */ + /* USER CODE END CMM_INT_FREQ_ERR_MASK */ } static BASE_StatusType CMM_Init(void) { - g_cmm.baseAddress = CMM; + g_cmm.baseAddress = CMM; /* CMM : clock monitor module */ g_cmm.mode = CMM_TRIGGER_RISE; g_cmm.targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; g_cmm.refFreqDivision = CMM_REF_FREQ_DIV_0; g_cmm.targetClockSource = CMM_TARGET_CLK_LOSC; g_cmm.refClockSource = CMM_REF_CLK_LOSC; - g_cmm.upperBound = 8195; /* 8195: Upper limit of internal reference clock count value */ - g_cmm.lowerBound = 8190; /* 8190: lower limit of internal reference clock count value */ + g_cmm.upperBound = 8195; /* 8195 : cmm monitor windows count value upper bound */ + g_cmm.lowerBound = 8190; /* 8190 : cmm monitor windows count value lower bound */ g_cmm.interruptType = CMM_INT_FREQ_ERR_MASK; - g_cmm.irqNum = IRQ_CMM; - /* Associating irqNum with Callbacks */ - /* Register callback functions to be defined by users. only the selected interrupt type takes effect. */ - HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_COUNTER_OVERFLOW_MASK, CMMCounterOverFlowCallback); - HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_CHECK_END_MASK, CMMCheckEndCallback); - HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_FREQ_ERR_MASK, CMM_CheckErrorCallback); - HAL_CMM_IRQService(&g_cmm); - IRQ_SetPriority(g_cmm.irqNum, 1); /* The value ranges from 1 to 7. A smaller value indicates a lower priority. */ - IRQ_EnableN(g_cmm.irqNum); + HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_COUNTER_OVERFLOW_MASK, (CMM_CallBackFuncType)CountOverflowCallback); + HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_CHECK_END_MASK, (CMM_CallBackFuncType)CheckEndCallback); + HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_FREQ_ERR_MASK, (CMM_CallBackFuncType)FreqErrorCallback); + IRQ_Register(IRQ_CMM, HAL_CMM_IrqHandler, &g_cmm); + IRQ_SetPriority(IRQ_CMM, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_CMM); return HAL_CMM_Init(&g_cmm); } static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* Enable Uart Clock */ + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); /* Set uart clock div value 0 */ + g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -99,37 +98,35 @@ static void UART0_Init(void) g_uart0.parity = UART_PARITY_NONE; g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; - g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoMode = BASE_CFG_ENABLE; /* Enable UART FIFO */ g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; - HAL_UART_Init(&g_uart0); + HAL_UART_Init(&g_uart0); /* UART Init */ } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); - CMM_Init(); UART0_Init(); + CMM_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/cmm/sample_cmm_check_error/readme.md b/src/application/drivers_sample/cmm/sample_cmm_check_error/readme.md index 1d4198cfdcd4d178e1aa502a4daf954144ee86f9..93d6de2e81e5714c7d4968cd3fa163ce41a62c2d 100644 --- a/src/application/drivers_sample/cmm/sample_cmm_check_error/readme.md +++ b/src/application/drivers_sample/cmm/sample_cmm_check_error/readme.md @@ -18,3 +18,7 @@ **【注意事项】** + 上下限值的范围可反应系统对目标时钟偏差的冗余度,可自行设计门限值和时钟分频比,门限值具体计算方法请参照芯片技术指南。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_check/init/main.c b/src/application/drivers_sample/crc/sample_crc_check/init/main.c index bac9b38519918d45b0bcdecc0027078a8dd3cb50..ae93e87e5f6273fbfe3326a4200ade6a21caaacf 100644 --- a/src/application/drivers_sample/crc/sample_crc_check/init/main.c +++ b/src/application/drivers_sample/crc/sample_crc_check/init/main.c @@ -19,17 +19,41 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "crc_check_sample.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ CRC_Handle g_checkCrcHandle; UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ CRC_CheckSample(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_check/init/main.h b/src/application/drivers_sample/crc/sample_crc_check/init/main.h index 68960053cb2a222bd88bde06a39308f6d118e079..342dbfb37b419fa45fb77fe005eba156d5b8f83c 100644 --- a/src/application/drivers_sample/crc/sample_crc_check/init/main.h +++ b/src/application/drivers_sample/crc/sample_crc_check/init/main.h @@ -36,8 +36,12 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U -extern CRC_Handle g_checkCrcHandle; +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U +extern CRC_Handle g_checkCrcHandle; extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); @@ -45,4 +49,8 @@ void SystemInit(void); void CRC_CallbackFunc(void *handle); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_check/init/system_init.c b/src/application/drivers_sample/crc/sample_crc_check/init/system_init.c index 5f5a4872fb7197ff2fe8f9638ed93cda21fd38bc..3b1fa117a92d10658fdd9e1efb0192a3851bd95e 100644 --- a/src/application/drivers_sample/crc/sample_crc_check/init/system_init.c +++ b/src/application/drivers_sample/crc/sample_crc_check/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,27 +46,25 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) __weak void CRC_CallbackFunc(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN CRC_CallbackFunc */ - /* USER CODE END CRC_CallbackFunc */ + /* USER CODE BEGIN CRC Callback */ + /* USER CODE END CRC Callback */ } static void CRC_Init(void) { HAL_CRG_IpEnableSet(CRC_BASE, IP_CLK_ENABLE); - g_checkCrcHandle.baseAddress = CRC; - g_checkCrcHandle.irqNum = IRQ_CRC; - g_checkCrcHandle.algoMode = CRC8_ROHC; - g_checkCrcHandle.inputDataFormat = CRC_MODE_BIT8; - g_checkCrcHandle.timeout = 1000; /* 1000: psread timeout upper limit value */ - g_checkCrcHandle.enableIT = BASE_CFG_ENABLE; - g_checkCrcHandle.enableErrInject = BASE_CFG_DISABLE; - /* Register callback functions to be defined by users. Associating irqNum with Callbacks */ + g_checkCrcHandle.baseAddress = CRC; /* Base address */ + g_checkCrcHandle.handleEx.algoMode = CRC8_ROHC; + g_checkCrcHandle.handleEx.timeout = 1000; /* 1000 is time out */ + g_checkCrcHandle.handleEx.enableIT = BASE_CFG_ENABLE; + g_checkCrcHandle.handleEx.enableErrInject = BASE_CFG_DISABLE; + g_checkCrcHandle.inputDataFormat = CRC_MODE_BIT8; /* Width 8 bit */ + HAL_CRC_RegisterCallback(&g_checkCrcHandle, CRC_CallbackFunc); - HAL_CRC_IRQService(&g_checkCrcHandle); - /* The value ranges from 1 to 7. A smaller value indicates a lower priority. */ - IRQ_SetPriority(g_checkCrcHandle.irqNum, 1); - IRQ_EnableN(g_checkCrcHandle.irqNum); + IRQ_Register(IRQ_CRC, HAL_CRC_IrqHandler, &g_checkCrcHandle); + IRQ_SetPriority(IRQ_CRC, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_CRC); HAL_CRC_Init(&g_checkCrcHandle); } @@ -74,7 +74,7 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; @@ -90,28 +90,26 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); - CRC_Init(); UART0_Init(); + CRC_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_check/readme.md b/src/application/drivers_sample/crc/sample_crc_check/readme.md index 43c928b2eff6f13873c0dc2720390108e8466e68..64b7398695259fcc504bf7d250fc2049d334f43a 100644 --- a/src/application/drivers_sample/crc/sample_crc_check/readme.md +++ b/src/application/drivers_sample/crc/sample_crc_check/readme.md @@ -16,3 +16,7 @@ **【注意事项】** + 目前CRC算法只支持CRC8_ROHC、CRC16_IBM、CRC16_MODBUS、CRC16_CCITT_FALSE、CRC16_XMODEM、CRC32算法,且只有算法初始值可配置,其余配置项均已硬件固化。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容 \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_check/src/crc_check_sample.c b/src/application/drivers_sample/crc/sample_crc_check/src/crc_check_sample.c index 692c93dc92976491341702482e61af4df3ee9a30..d2a7c8f67de86647a99f9defbf7ab9f395429ba9 100644 --- a/src/application/drivers_sample/crc/sample_crc_check/src/crc_check_sample.c +++ b/src/application/drivers_sample/crc/sample_crc_check/src/crc_check_sample.c @@ -46,8 +46,8 @@ #define CRC16_MAXIM_RESULT_VALUE 0xD967 #define CRC16_USB_RESULT_VALUE 0xFD67 #define CRC16_MODBUS_RESULT_VALUE 0x0298 -#define CRC16_CCIT_RESULT_VALUE 0xE376 -#define CRC16_CCIT_FALSE_RESULT_VALUE 0x5197 +#define CRC16_CCITT_RESULT_VALUE 0xE376 +#define CRC16_CCITT_FALSE_RESULT_VALUE 0x5197 #define CRC16_X25_RESULT_VALUE 0x1FA8 #define CRC16_XMODEM_RESULT_VALUE 0xD557 #define CRC32_RESULT_VALUE 0x89F75D91 @@ -67,15 +67,15 @@ CRC_AlgorithmTest g_algorithmTestTable[] = { {"CRC16_MAXIM", CRC16_MAXIM, CRC_TEST_INPUT_DATA, CRC16_MAXIM_RESULT_VALUE }, {"CRC16_USB", CRC16_USB, CRC_TEST_INPUT_DATA, CRC16_USB_RESULT_VALUE }, {"CRC16_X25", CRC16_X25, CRC_TEST_INPUT_DATA, CRC16_X25_RESULT_VALUE }, - {"CRC16_CCIT", CRC16_CCITT, CRC_TEST_INPUT_DATA, CRC16_CCIT_RESULT_VALUE }, + {"CRC16_CCITT", CRC16_CCITT, CRC_TEST_INPUT_DATA, CRC16_CCITT_RESULT_VALUE }, {"CRC32_MPEG2", CRC32_MPEG2, CRC_TEST_INPUT_DATA, CRC32_MPEG2_RESULT_VALUE }, #endif - {"CRC8_ROHC", CRC8_ROHC, CRC_TEST_INPUT_DATA, CRC8_ROHC_RESULT_VALUE }, - {"CRC16_IBM", CRC16_IBM, CRC_TEST_INPUT_DATA, CRC16_IBM_RESULT_VALUE }, - {"CRC16_MODBUS", CRC16_MODBUS, CRC_TEST_INPUT_DATA, CRC16_MODBUS_RESULT_VALUE }, - {"CRC16_CCIT_FALSE", CRC16_CCITT_FALSE, CRC_TEST_INPUT_DATA, CRC16_CCIT_FALSE_RESULT_VALUE}, - {"CRC16_XMODEM", CRC16_XMODEM, CRC_TEST_INPUT_DATA, CRC16_XMODEM_RESULT_VALUE }, - {"CRC32", CRC32, CRC_TEST_INPUT_DATA, CRC32_RESULT_VALUE }, + {"CRC8_ROHC", CRC8_ROHC, CRC_TEST_INPUT_DATA, CRC8_ROHC_RESULT_VALUE }, + {"CRC16_IBM", CRC16_IBM, CRC_TEST_INPUT_DATA, CRC16_IBM_RESULT_VALUE }, + {"CRC16_MODBUS", CRC16_MODBUS, CRC_TEST_INPUT_DATA, CRC16_MODBUS_RESULT_VALUE }, + {"CRC16_CCIT_FALSE", CRC16_CCITT_FALSE, CRC_TEST_INPUT_DATA, CRC16_CCITT_FALSE_RESULT_VALUE}, + {"CRC16_XMODEM", CRC16_XMODEM, CRC_TEST_INPUT_DATA, CRC16_XMODEM_RESULT_VALUE }, + {"CRC32", CRC32, CRC_TEST_INPUT_DATA, CRC32_RESULT_VALUE }, }; const unsigned int CRC_ALGORITHM_TABLE_SIZE = sizeof(g_algorithmTestTable) / sizeof(g_algorithmTestTable[0]); diff --git a/src/application/drivers_sample/crc/sample_crc_check_algo/init/main.c b/src/application/drivers_sample/crc/sample_crc_check_algo/init/main.c index 01c440a345d3df50223e39aa05fe4a2106ba5026..64c226ff7839659f9277026f4e34f2234d9fb821 100644 --- a/src/application/drivers_sample/crc/sample_crc_check_algo/init/main.c +++ b/src/application/drivers_sample/crc/sample_crc_check_algo/init/main.c @@ -22,28 +22,37 @@ #include "typedefs.h" #include "feature.h" +#include "sample_crc_check_algo.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ UART_Handle g_uart0; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ CRC_CheckAlgoSample(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_check_algo/init/main.h b/src/application/drivers_sample/crc/sample_crc_check_algo/init/main.h index 4d9eb3456405abe0818918379a29b681c11ddf03..d059d7d88546489111a34fdcd3c9e14467f4fe88 100644 --- a/src/application/drivers_sample/crc/sample_crc_check_algo/init/main.h +++ b/src/application/drivers_sample/crc/sample_crc_check_algo/init/main.h @@ -25,7 +25,9 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -45,4 +47,8 @@ extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_check_algo/init/system_init.c b/src/application/drivers_sample/crc/sample_crc_check_algo/init/system_init.c index ac8895321f697e9ad9c0b54eb2dd6359f88c46ab..86d72af4dde10ed1795a51ba9e52a561fc6f935d 100644 --- a/src/application/drivers_sample/crc/sample_crc_check_algo/init/system_init.c +++ b/src/application/drivers_sample/crc/sample_crc_check_algo/init/system_init.c @@ -29,16 +29,19 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; - crg.baseAddress = CRG; /* crg baseaddress */ + crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + /* 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* CRG init */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; @@ -47,19 +50,18 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - - g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; - g_uart0.dataLength = UART_DATALENGTH_8BIT; /* data length 8 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; /* blocking mode */ + g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; /* fifo size 8 */ + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; @@ -68,17 +70,17 @@ static void UART0_Init(void) static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/crc/sample_crc_check_algo/readme.md b/src/application/drivers_sample/crc/sample_crc_check_algo/readme.md index 589bf3c37d0db7029addd2596aa628168e9bdc4b..a3ba216675c7f35fe5b28a61c36b5fb6b42d5f2f 100644 --- a/src/application/drivers_sample/crc/sample_crc_check_algo/readme.md +++ b/src/application/drivers_sample/crc/sample_crc_check_algo/readme.md @@ -13,4 +13,6 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后,串口首先打印根据CRC算法模式计算的校验值结果是否正确,然后根据CRC16_MAXIM算法属性进行CRC计算打印结果校验是否正确。 **【注意事项】** -+ NA ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 diff --git a/src/application/drivers_sample/crc/sample_crc_check_algo/src/sample_crc_check_algo.c b/src/application/drivers_sample/crc/sample_crc_check_algo/src/sample_crc_check_algo.c index 9309fc928572105a988cf9b795e1fc3b581ea28b..a989c842850827598084e650e3ba2ed5bd58fd84 100644 --- a/src/application/drivers_sample/crc/sample_crc_check_algo/src/sample_crc_check_algo.c +++ b/src/application/drivers_sample/crc/sample_crc_check_algo/src/sample_crc_check_algo.c @@ -46,8 +46,8 @@ #define CRC16_MAXIM_RESULT_VALUE 0xD967 #define CRC16_USB_RESULT_VALUE 0xFD67 #define CRC16_MODBUS_RESULT_VALUE 0x0298 -#define CRC16_CCIT_RESULT_VALUE 0xE376 -#define CRC16_CCIT_FALSE_RESULT_VALUE 0x5197 +#define CRC16_CCITT_RESULT_VALUE 0xE376 +#define CRC16_CCITT_FALSE_RESULT_VALUE 0x5197 #define CRC16_X25_RESULT_VALUE 0x1FA8 #define CRC16_XMODEM_RESULT_VALUE 0xD557 #define CRC32_RESULT_VALUE 0x89F75D91 @@ -67,15 +67,15 @@ CRC_AlgorithmTest g_algorithmTestTable[] = { {"CRC16_MAXIM", CRC16_MAXIM, CRC_TEST_INPUT_DATA, CRC16_MAXIM_RESULT_VALUE }, {"CRC16_USB", CRC16_USB, CRC_TEST_INPUT_DATA, CRC16_USB_RESULT_VALUE }, {"CRC16_X25", CRC16_X25, CRC_TEST_INPUT_DATA, CRC16_X25_RESULT_VALUE }, - {"CRC16_CCIT", CRC16_CCITT, CRC_TEST_INPUT_DATA, CRC16_CCIT_RESULT_VALUE }, + {"CRC16_CCITT", CRC16_CCITT, CRC_TEST_INPUT_DATA, CRC16_CCITT_RESULT_VALUE }, {"CRC32_MPEG2", CRC32_MPEG2, CRC_TEST_INPUT_DATA, CRC32_MPEG2_RESULT_VALUE }, #endif - {"CRC8_ROHC", CRC8_ROHC, CRC_TEST_INPUT_DATA, CRC8_ROHC_RESULT_VALUE }, - {"CRC16_IBM", CRC16_IBM, CRC_TEST_INPUT_DATA, CRC16_IBM_RESULT_VALUE }, - {"CRC16_MODBUS", CRC16_MODBUS, CRC_TEST_INPUT_DATA, CRC16_MODBUS_RESULT_VALUE }, - {"CRC16_CCIT_FALSE", CRC16_CCITT_FALSE, CRC_TEST_INPUT_DATA, CRC16_CCIT_FALSE_RESULT_VALUE}, - {"CRC16_XMODEM", CRC16_XMODEM, CRC_TEST_INPUT_DATA, CRC16_XMODEM_RESULT_VALUE }, - {"CRC32", CRC32, CRC_TEST_INPUT_DATA, CRC32_RESULT_VALUE }, + {"CRC8_ROHC", CRC8_ROHC, CRC_TEST_INPUT_DATA, CRC8_ROHC_RESULT_VALUE }, + {"CRC16_IBM", CRC16_IBM, CRC_TEST_INPUT_DATA, CRC16_IBM_RESULT_VALUE }, + {"CRC16_MODBUS", CRC16_MODBUS, CRC_TEST_INPUT_DATA, CRC16_MODBUS_RESULT_VALUE }, + {"CRC16_CCITT_FALSE", CRC16_CCITT_FALSE, CRC_TEST_INPUT_DATA, CRC16_CCITT_FALSE_RESULT_VALUE}, + {"CRC16_XMODEM", CRC16_XMODEM, CRC_TEST_INPUT_DATA, CRC16_XMODEM_RESULT_VALUE }, + {"CRC32", CRC32, CRC_TEST_INPUT_DATA, CRC32_RESULT_VALUE }, }; const unsigned int CRC_ALGORITHM_TABLE_SIZE = sizeof(g_algorithmTestTable) / sizeof(g_algorithmTestTable[0]); diff --git a/src/application/drivers_sample/crc/sample_crc_gen/init/main.c b/src/application/drivers_sample/crc/sample_crc_gen/init/main.c index c19100f662bfa50a7e31db0f7827ce443b4d65ae..6007af8868390b55bac44c134dd847e87bada0c2 100644 --- a/src/application/drivers_sample/crc/sample_crc_gen/init/main.c +++ b/src/application/drivers_sample/crc/sample_crc_gen/init/main.c @@ -19,17 +19,41 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "crc_gen_sample.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ CRC_Handle g_genCrcHandle; UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ CRC_GenerateSample(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_gen/init/main.h b/src/application/drivers_sample/crc/sample_crc_gen/init/main.h index a7dc8bb411d9fa6e860c82c72823d026694b7425..26e89ec1a4950a33b3375ae542ed6cef08e5319c 100644 --- a/src/application/drivers_sample/crc/sample_crc_gen/init/main.h +++ b/src/application/drivers_sample/crc/sample_crc_gen/init/main.h @@ -36,8 +36,12 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U -extern CRC_Handle g_genCrcHandle; +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U +extern CRC_Handle g_genCrcHandle; extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); @@ -45,4 +49,8 @@ void SystemInit(void); void CRC_CallbackFunc(void *handle); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_gen/init/system_init.c b/src/application/drivers_sample/crc/sample_crc_gen/init/system_init.c index 71e8e9d64275d5f7ff54a2a4155153f6c29f27ec..409f0809b2ff79cd04260aff68ee6dd458e57150 100644 --- a/src/application/drivers_sample/crc/sample_crc_gen/init/system_init.c +++ b/src/application/drivers_sample/crc/sample_crc_gen/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,26 +46,25 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) __weak void CRC_CallbackFunc(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN CRC_CallbackFunc */ - /* USER CODE END CRC_CallbackFunc */ + /* USER CODE BEGIN CRC Callback */ + /* USER CODE END CRC Callback */ } static void CRC_Init(void) { HAL_CRG_IpEnableSet(CRC_BASE, IP_CLK_ENABLE); - g_genCrcHandle.baseAddress = CRC; - g_genCrcHandle.irqNum = IRQ_CRC; - g_genCrcHandle.algoMode = CRC16_XMODEM; - g_genCrcHandle.inputDataFormat = CRC_MODE_BIT16; - g_genCrcHandle.timeout = 1000; /* 1000: psread timeout upper limit value */ - g_genCrcHandle.enableIT = BASE_CFG_ENABLE; - g_genCrcHandle.enableErrInject = BASE_CFG_DISABLE; - /* Register callback functions to be defined by users. Associating irqNum with Callbacks */ + + g_genCrcHandle.baseAddress = CRC; /* Base address */ + g_genCrcHandle.handleEx.algoMode = CRC16_XMODEM; + g_genCrcHandle.handleEx.timeout = 1000; /* 1000 is time out */ + g_genCrcHandle.handleEx.enableIT = BASE_CFG_ENABLE; + g_genCrcHandle.handleEx.enableErrInject = BASE_CFG_DISABLE; + g_genCrcHandle.inputDataFormat = CRC_MODE_BIT16; /* Width 16 bit */ + HAL_CRC_RegisterCallback(&g_genCrcHandle, CRC_CallbackFunc); - HAL_CRC_IRQService(&g_genCrcHandle); - /* The value ranges from 1 to 7. A smaller value indicates a lower priority. */ - IRQ_SetPriority(g_genCrcHandle.irqNum, 1); - IRQ_EnableN(g_genCrcHandle.irqNum); + IRQ_Register(IRQ_CRC, HAL_CRC_IrqHandler, &g_genCrcHandle); + IRQ_SetPriority(IRQ_CRC, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_CRC); HAL_CRC_Init(&g_genCrcHandle); } @@ -73,7 +74,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -90,28 +90,26 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); - CRC_Init(); UART0_Init(); + CRC_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_gen/readme.md b/src/application/drivers_sample/crc/sample_crc_gen/readme.md index 2f46a987da07fb1b7ed950c940c12ec9ad6f70f4..e5d002925e9f7fec48f0fabb6ba949ee96a74d45 100644 --- a/src/application/drivers_sample/crc/sample_crc_gen/readme.md +++ b/src/application/drivers_sample/crc/sample_crc_gen/readme.md @@ -15,4 +15,8 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后,Debug串口打印生成的CRC值和已运算数据的大小。如果产生CRC计算反压超时则产生中断,调用反压中断回调函数,打印CRC反压超时。 **【注意事项】** -+ 目前CRC算法只支持CRC8_ROHC、CRC16_IBM、CRC16_MODBUS、CRC16_CCITT_FALSE、CRC16_XMODEM、CRC32算法,且只有算法初始值可配置,其余配置项均已硬件固化。 \ No newline at end of file ++ 目前CRC算法只支持CRC8_ROHC、CRC16_IBM、CRC16_MODBUS、CRC16_CCITT_FALSE、CRC16_XMODEM、CRC32算法,且只有算法初始值可配置,其余配置项均已硬件固化。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_gen_algo/init/main.c b/src/application/drivers_sample/crc/sample_crc_gen_algo/init/main.c index d657fd4f43ac8ded8f9dfdf8c2a4b6481dc21c74..64f3e7ffa5bfa9983df4d837b74e92b102e40d93 100644 --- a/src/application/drivers_sample/crc/sample_crc_gen_algo/init/main.c +++ b/src/application/drivers_sample/crc/sample_crc_gen_algo/init/main.c @@ -22,28 +22,37 @@ #include "typedefs.h" #include "feature.h" +#include "sample_crc_gen_algo.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ UART_Handle g_uart0; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ CRC_GenerateSample(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_gen_algo/init/main.h b/src/application/drivers_sample/crc/sample_crc_gen_algo/init/main.h index 4d9eb3456405abe0818918379a29b681c11ddf03..d059d7d88546489111a34fdcd3c9e14467f4fe88 100644 --- a/src/application/drivers_sample/crc/sample_crc_gen_algo/init/main.h +++ b/src/application/drivers_sample/crc/sample_crc_gen_algo/init/main.h @@ -25,7 +25,9 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -45,4 +47,8 @@ extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_gen_algo/init/system_init.c b/src/application/drivers_sample/crc/sample_crc_gen_algo/init/system_init.c index ac8895321f697e9ad9c0b54eb2dd6359f88c46ab..aaf8d7fe63ae2bdc36f2f18fea32786c85e18ad6 100644 --- a/src/application/drivers_sample/crc/sample_crc_gen_algo/init/system_init.c +++ b/src/application/drivers_sample/crc/sample_crc_gen_algo/init/system_init.c @@ -29,16 +29,19 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; - crg.baseAddress = CRG; /* crg baseaddress */ + crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + /* 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* CRG init */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; @@ -47,19 +50,18 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - - g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; - g_uart0.dataLength = UART_DATALENGTH_8BIT; /* data length 8 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; /* blocking mode */ + g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; /* fifo size 8 */ + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; @@ -68,17 +70,17 @@ static void UART0_Init(void) static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/crc/sample_crc_gen_algo/readme.md b/src/application/drivers_sample/crc/sample_crc_gen_algo/readme.md index 04177085c0a9417959d2a4763cfba669c16205df..e4288ff587d975fc8163d25832abbc8e78418a30 100644 --- a/src/application/drivers_sample/crc/sample_crc_gen_algo/readme.md +++ b/src/application/drivers_sample/crc/sample_crc_gen_algo/readme.md @@ -13,4 +13,6 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后,Debug串口打印根据算法模式配置生成的CRC值和已运算数据的大小,然后打印根据算法属性配置生成的CRC值和已运算数据的大小。 **【注意事项】** -+ NA \ No newline at end of file ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_load/init/main.c b/src/application/drivers_sample/crc/sample_crc_load/init/main.c index 2a5fc415d80c5c78149b06905f8a42faf75d7b9b..c9439b65395bc708ea764f15272f2be6ede627d8 100644 --- a/src/application/drivers_sample/crc/sample_crc_load/init/main.c +++ b/src/application/drivers_sample/crc/sample_crc_load/init/main.c @@ -19,17 +19,41 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "crc_load_sample.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ CRC_Handle g_loadCrcHandle; UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ CRC_LoadSample(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_load/init/main.h b/src/application/drivers_sample/crc/sample_crc_load/init/main.h index 908f46ba609c5b574c09c9e55440db1c97d2940a..fdc40f7f21f93384f32ec5dd45077bfba1dc8405 100644 --- a/src/application/drivers_sample/crc/sample_crc_load/init/main.h +++ b/src/application/drivers_sample/crc/sample_crc_load/init/main.h @@ -36,8 +36,12 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U -extern CRC_Handle g_loadCrcHandle; +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U +extern CRC_Handle g_loadCrcHandle; extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); @@ -45,4 +49,8 @@ void SystemInit(void); void CRC_CallbackFunc(void *handle); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_load/init/system_init.c b/src/application/drivers_sample/crc/sample_crc_load/init/system_init.c index d1874edb25569f22b84cc5960909234674a0b9dc..5ebf750fa392891ab54769ad187e64283db05ace 100644 --- a/src/application/drivers_sample/crc/sample_crc_load/init/system_init.c +++ b/src/application/drivers_sample/crc/sample_crc_load/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,26 +46,25 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) __weak void CRC_CallbackFunc(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN CRC_CallbackFunc */ - /* USER CODE END CRC_CallbackFunc */ + /* USER CODE BEGIN CRC Callback */ + /* USER CODE END CRC Callback */ } static void CRC_Init(void) { HAL_CRG_IpEnableSet(CRC_BASE, IP_CLK_ENABLE); - g_loadCrcHandle.baseAddress = CRC; - g_loadCrcHandle.irqNum = IRQ_CRC; - g_loadCrcHandle.algoMode = CRC16_XMODEM; - g_loadCrcHandle.inputDataFormat = CRC_MODE_BIT16; - g_loadCrcHandle.timeout = 1000; /* 1000: psread timeout upper limit value */ - g_loadCrcHandle.enableIT = BASE_CFG_ENABLE; - g_loadCrcHandle.enableErrInject = BASE_CFG_DISABLE; - /* Register callback functions to be defined by users. Associating irqNum with Callbacks */ + + g_loadCrcHandle.baseAddress = CRC; /* Base address */ + g_loadCrcHandle.handleEx.algoMode = CRC16_XMODEM; + g_loadCrcHandle.handleEx.timeout = 1000; /* 1000 is time out */ + g_loadCrcHandle.handleEx.enableIT = BASE_CFG_ENABLE; + g_loadCrcHandle.handleEx.enableErrInject = BASE_CFG_DISABLE; + g_loadCrcHandle.inputDataFormat = CRC_MODE_BIT16; /* Width 16 bit */ + HAL_CRC_RegisterCallback(&g_loadCrcHandle, CRC_CallbackFunc); - HAL_CRC_IRQService(&g_loadCrcHandle); - /* The value ranges from 1 to 7. A smaller value indicates a lower priority. */ - IRQ_SetPriority(g_loadCrcHandle.irqNum, 1); - IRQ_EnableN(g_loadCrcHandle.irqNum); + IRQ_Register(IRQ_CRC, HAL_CRC_IrqHandler, &g_loadCrcHandle); + IRQ_SetPriority(IRQ_CRC, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_CRC); HAL_CRC_Init(&g_loadCrcHandle); } @@ -73,7 +74,7 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; @@ -89,28 +90,26 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); - CRC_Init(); UART0_Init(); + CRC_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_load/readme.md b/src/application/drivers_sample/crc/sample_crc_load/readme.md index d94d321315d6d99280a16cb59ac6c97c7df26ad6..59ee42f87aa22c07dc357ee2e39dbe1ef9ca1d44 100644 --- a/src/application/drivers_sample/crc/sample_crc_load/readme.md +++ b/src/application/drivers_sample/crc/sample_crc_load/readme.md @@ -2,19 +2,23 @@ ## 关键字: CRC算法,初始值 **【功能描述】** -+ 示例代码基于HAL接口完成时钟、中断和CRC初始化和功能配置。通过load初始值配置,不改变其他配置CRC16_XMODEM算法修改为CRC16_CCIT-FALSE,并对同一组数据进行CRC运算验证。 ++ 示例代码基于HAL接口完成时钟、中断和CRC初始化和功能配置。通过load初始值配置,不改变其他配置CRC16_XMODEM算法修改为CRC16_CCITT_FALSE,并对同一组数据进行CRC运算验证。 **【示例配置】** + 在"SystemInit()”接口中配置CRC输入数据长度、算法模式、反压超时时间、开启反压中断等参数。 + 在进行load初始值配置之前,根据CRC16_XMODEM算法对输入数据0x5678调用“HAL_CRC_SetInputDataGetCheck()”进行CRC计算对比结果。 -+ 调用“HAL_CRC_SetCheckInData()”修改初始值0xFFFF,再调用"HAL_CRC_SetInputDataGetCheck()"对输入数据0x5678进行CRC计算对比结果。加载初始值后,CRC16_XMODEM算法修改为CRC16_CCIT-FALSE算法。 ++ 调用“HAL_CRC_SetCheckInData()”修改初始值0xFFFF,再调用"HAL_CRC_SetInputDataGetCheck()"对输入数据0x5678进行CRC计算对比结果。加载初始值后,CRC16_XMODEM算法修改为CRC16_CCITT_FALSE算法。 + 配置反压中断的回调函数"CRC_CallbackFunc()",当产生反压中断且中断使能时调用。 **【示例效果】** -+ 当用户烧录编译后的示例代码后,初始化和配置完成后,串口打印原始算法对数据运算生成的CRC数值,并与CRC16_XMODEM算法运算的标准值对比验证正确性;load初始值后,打印load后的初始值,并对同一组数据运算生成CRC数值,并与CRC16_CCIT-FALSE算法运算的标准值对比验证正确性。如果产生CRC计算反压超时则产生中断,调用反压中断回调函数,打印CRC反压超时。 ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,串口打印原始算法对数据运算生成的CRC数值,并与CRC16_XMODEM算法运算的标准值对比验证正确性;load初始值后,打印load后的初始值,并对同一组数据运算生成CRC数值,并与CRC16_CCITT_FALSE算法运算的标准值对比验证正确性。如果产生CRC计算反压超时则产生中断,调用反压中断回调函数,打印CRC反压超时。 **【注意事项】** -+ 目前CRC算法只支持CRC8_ROHC、CRC16_IBM、CRC16_MODBUS、CRC16_CCITT_FALSE、CRC16_XMODEM、CRC32算法,且只有算法初始值可配置,其余配置项均已硬件固化。 \ No newline at end of file ++ 目前CRC算法只支持CRC8_ROHC、CRC16_IBM、CRC16_MODBUS、CRC16_CCITT_FALSE、CRC16_XMODEM、CRC32算法,且只有算法初始值可配置,其余配置项均已硬件固化。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_load/src/crc_load_sample.c b/src/application/drivers_sample/crc/sample_crc_load/src/crc_load_sample.c index d896186d206656089621112f9ff2768524d1eab7..902a7e769c596f48770184320c4bd9e4330fec7d 100644 --- a/src/application/drivers_sample/crc/sample_crc_load/src/crc_load_sample.c +++ b/src/application/drivers_sample/crc/sample_crc_load/src/crc_load_sample.c @@ -21,7 +21,7 @@ * @details Perform the CRC16_XMODEM algorithm operation on the 16-bit data of 0x5678 to obtain a CRC value. \ * Compare the CRC value with the standard value to determine whether the value is correct. Then load \ * the initial value 0x0000 to the CRC module. Therefore, the CRC16_XMODEM algorithm is configured as \ - * the CRC16_CCIT-FALSE algorithm, and then the value 0x5678 is calculated. The CRC value generated \ + * the CRC16_CCITT_FALSE algorithm, and then the value 0x5678 is calculated. The CRC value generated \ * after the calculation is compared with the standard value to determine whether the value of the \ * initial load value is correct. */ @@ -56,15 +56,15 @@ BASE_StatusType CRC_LoadSample(void) } else { DBG_PRINTF("CRC Algrithem is not right for this sample! \r\n"); } - /* load init data 0xffff, crc algrithem from CRC16_XMODEM to CRC16_CCIT-FALSE */ + /* load init data 0xffff, crc algrithem from CRC16_XMODEM to CRC16_CCITT_FALSE */ HAL_CRC_SetCheckInData(&g_loadCrcHandle, 0xFFFF); unsigned int initData = HAL_CRC_LoadCheckInData(&g_loadCrcHandle); - /* CRC16_CCIT-FALSE Algrithem, init data = 0xffff */ + /* CRC16_CCITT_FALSE Algrithem, init data = 0xffff */ unsigned int afterLoadCrcValue = HAL_CRC_SetInputDataGetCheck(&g_loadCrcHandle, 0x5678); DBG_PRINTF("initData: 0x%x \r\n", initData); DBG_PRINTF("afterLoadCrcValue: 0x%x \r\n", afterLoadCrcValue); if (afterLoadCrcValue == CRC_CCITFALSE_REF_VALUE) { - DBG_PRINTF("CRC Algrithem is CRC16_CCIT-FALSE, load init data success! \r\n"); + DBG_PRINTF("CRC Algrithem is CRC16_CCITT_FALSE, load init data success! \r\n"); } else { DBG_PRINTF("load init data fail ! \r\n"); } diff --git a/src/application/drivers_sample/crc/sample_crc_load_algo/init/main.c b/src/application/drivers_sample/crc/sample_crc_load_algo/init/main.c index a6052e82d03e79bdbe02bc84e3e1dee39ee55248..b436e6eca4a8774e6d00eb24deb2be05f4e0cc9c 100644 --- a/src/application/drivers_sample/crc/sample_crc_load_algo/init/main.c +++ b/src/application/drivers_sample/crc/sample_crc_load_algo/init/main.c @@ -22,29 +22,38 @@ #include "typedefs.h" #include "feature.h" +#include "sample_crc_load_algo.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ CRC_Handle g_loadCrcHandle; UART_Handle g_uart0; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ CRC_LoadSample(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_load_algo/init/main.h b/src/application/drivers_sample/crc/sample_crc_load_algo/init/main.h index f122dc193303fc89da92d15e2bf8354906aef732..226ebae9740df0709f583b9ff0f5915b59eed731 100644 --- a/src/application/drivers_sample/crc/sample_crc_load_algo/init/main.h +++ b/src/application/drivers_sample/crc/sample_crc_load_algo/init/main.h @@ -25,8 +25,10 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "crc.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -47,4 +49,8 @@ extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_load_algo/init/system_init.c b/src/application/drivers_sample/crc/sample_crc_load_algo/init/system_init.c index 91d131e08c513308f8b31b16461c6dd69a9667c1..cac6acead0aa59febe1505bea7f3c296908384de 100644 --- a/src/application/drivers_sample/crc/sample_crc_load_algo/init/system_init.c +++ b/src/application/drivers_sample/crc/sample_crc_load_algo/init/system_init.c @@ -32,13 +32,16 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; /* crg baseaddress */ crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + /* 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* CRG init */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; @@ -58,9 +61,8 @@ static void CRC_Init(void) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - - g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; /* data length 8 */ @@ -79,17 +81,17 @@ static void UART0_Init(void) static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/crc/sample_crc_load_algo/readme.md b/src/application/drivers_sample/crc/sample_crc_load_algo/readme.md index 16d1b1822d1743443c549f8cec7cdf5793f51195..5339d299127eddd6c4db90d41f8bd8d8d9e6bc1b 100644 --- a/src/application/drivers_sample/crc/sample_crc_load_algo/readme.md +++ b/src/application/drivers_sample/crc/sample_crc_load_algo/readme.md @@ -2,17 +2,19 @@ ## 关键字: CRC算法,初始值 **【功能描述】** -+ 示例代码基于HAL接口完成时钟、CRC初始化和功能配置。通过load初始值配置,不改变其他配置CRC16_XMODEM算法修改为CRC16_CCIT-FALSE,并对同一组数据进行CRC运算验证。 ++ 示例代码基于HAL接口完成时钟、CRC初始化和功能配置。通过load初始值配置,不改变其他配置CRC16_XMODEM算法修改为CRC16_CCITT_FALSE,并对同一组数据进行CRC运算验证。 **【示例配置】** + 在"SystemInit()”接口中配置CRC输入数据长度、算法模式等参数。 + 在进行load初始值配置之前,根据CRC16_XMODEM算法对输入数据0x5678调用“HAL_CRC_SetInputDataGetCheck()”进行CRC计算对比结果。 -+ 调用“HAL_CRC_SetCheckInData()”修改初始值0xFFFF,再调用"HAL_CRC_SetInputDataGetCheck()"对输入数据0x5678进行CRC计算对比结果。加载初始值后,CRC16_XMODEM算法修改为CRC16_CCIT-FALSE算法。 ++ 调用“HAL_CRC_SetCheckInData()”修改初始值0xFFFF,再调用"HAL_CRC_SetInputDataGetCheck()"对输入数据0x5678进行CRC计算对比结果。加载初始值后,CRC16_XMODEM算法修改为CRC16_CCITT_FALSE算法。 **【示例效果】** -+ 当用户烧录编译后的示例代码后,初始化和配置完成后,串口打印原始算法对数据运算生成的CRC数值,并与CRC16_XMODEM算法运算的标准值对比验证正确性;load初始值后,打印load后的初始值,并对同一组数据运算生成CRC数值,并与CRC16_CCIT-FALSE算法运算的标准值对比验证正确性。 ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,串口打印原始算法对数据运算生成的CRC数值,并与CRC16_XMODEM算法运算的标准值对比验证正确性;load初始值后,打印load后的初始值,并对同一组数据运算生成CRC数值,并与CRC16_CCITT_FALSE算法运算的标准值对比验证正确性。 **【注意事项】** -+ NA \ No newline at end of file ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/crc/sample_crc_load_algo/src/sample_crc_load_algo.c b/src/application/drivers_sample/crc/sample_crc_load_algo/src/sample_crc_load_algo.c index c9db4fa09fb9fe8c375c5f816fd5047a1d75a747..ee6557f5ade314b6ee54c759f973f76a72f4b2fd 100644 --- a/src/application/drivers_sample/crc/sample_crc_load_algo/src/sample_crc_load_algo.c +++ b/src/application/drivers_sample/crc/sample_crc_load_algo/src/sample_crc_load_algo.c @@ -21,7 +21,7 @@ * @details Perform the CRC16_XMODEM algorithm operation on the 16-bit data of 0x5678 to obtain a CRC value. \ * Compare the CRC value with the standard value to determine whether the value is correct. Then load \ * the initial value 0x0000 to the CRC module. Therefore, the CRC16_XMODEM algorithm is configured as \ - * the CRC16_CCIT-FALSE algorithm, and then the value 0x5678 is calculated. The CRC value generated \ + * the CRC16_CCITT_FALSE algorithm, and then the value 0x5678 is calculated. The CRC value generated \ * after the calculation is compared with the standard value to determine whether the value of the \ * initial load value is correct. */ @@ -53,15 +53,15 @@ BASE_StatusType CRC_LoadSample(void) } else { DBG_PRINTF("CRC Algrithem is not right for this sample! \r\n"); } - /* load init data 0xffff, crc algrithem from CRC16_XMODEM to CRC16_CCIT-FALSE */ + /* load init data 0xffff, crc algrithem from CRC16_XMODEM to CRC16_CCITT_FALSE */ HAL_CRC_SetCheckInData(&g_loadCrcHandle, 0xFFFF); unsigned int initData = HAL_CRC_LoadCheckInData(&g_loadCrcHandle); - /* CRC16_CCIT-FALSE Algrithem, init data = 0xffff */ + /* CRC16_CCITT_FALSE Algrithem, init data = 0xffff */ unsigned int afterLoadCrcValue = HAL_CRC_SetInputDataGetCheck(&g_loadCrcHandle, 0x00005678); DBG_PRINTF("initData: 0x%x \r\n", initData); DBG_PRINTF("afterLoadCrcValue: 0x%x \r\n", afterLoadCrcValue); if (afterLoadCrcValue == CRC_CCITFALSE_REF_VALUE) { - DBG_PRINTF("CRC Algrithem is CRC16_CCIT-FALSE, load init data success! \r\n"); + DBG_PRINTF("CRC Algrithem is CRC16_CCITT_FALSE, load init data success! \r\n"); } else { DBG_PRINTF("load init data fail ! \r\n"); } diff --git a/src/application/drivers_sample/dac/sample_dac/init/main.c b/src/application/drivers_sample/dac/sample_dac/init/main.c index 26392118706a220f6ceeab234b1c878255ea3e56..9d04b1a7bf05fa4f12ddf3cf7a6ba073c76c05f8 100644 --- a/src/application/drivers_sample/dac/sample_dac/init/main.c +++ b/src/application/drivers_sample/dac/sample_dac/init/main.c @@ -19,15 +19,39 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" #include "main.h" - +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ DAC_Handle g_dac; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ SystemInit(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/dac/sample_dac/init/main.h b/src/application/drivers_sample/dac/sample_dac/init/main.h index fbb529b7a93362d4a14fae4d6351f46ad7f86353..d1e2fe30c65ece56ef9dd27c13c8fb5a02cd74a6 100644 --- a/src/application/drivers_sample/dac/sample_dac/init/main.h +++ b/src/application/drivers_sample/dac/sample_dac/init/main.h @@ -25,6 +25,7 @@ #define McuMagicTag_SYSTEM_INIT_H #include "dac.h" +#include "dac_ex.h" #include "crg.h" #define IO_SPEED_FAST 0x00U @@ -35,6 +36,11 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern DAC_Handle g_dac; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); diff --git a/src/application/drivers_sample/dac/sample_dac/init/system_init.c b/src/application/drivers_sample/dac/sample_dac/init/system_init.c index 8769cd02f705cfeaca52be7d58e0cd0f0aa5ad61..d237ae7f95fa7c2e38e7f5f8c4a274d69e530cae 100644 --- a/src/application/drivers_sample/dac/sample_dac/init/system_init.c +++ b/src/application/drivers_sample/dac/sample_dac/init/system_init.c @@ -22,17 +22,19 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; - crg.baseAddress = CRG; + crg.baseAddress = CRG; /* CRG base address */ crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* Init CRG */ return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; @@ -41,23 +43,22 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void DAC0_Init(void) { - g_dac.baseAddress = DAC0_BASE; /* DAC0 base address */ - g_dac.dacEn = BASE_CFG_ENABLE; - g_dac.dacValue = 128; /* 128: output 1.65v at 3.3v power supply */ - g_dac.dacTstModeEn = BASE_CFG_DISABLE; + HAL_CRG_IpEnableSet(DAC0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkDivSet(DAC0_BASE, CRG_DAC_DIV_1); + + g_dac.baseAddress = DAC0_BASE; /* DAC0 base address */ + g_dac.dacValue = 120; /* 120: DAC Value */ + g_dac.handleEx.sineMode = BASE_CFG_UNSET; HAL_DAC_Init(&g_dac); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_33.BIT.func = 0x8; /* 0x8 is DAC0_ANA_OUT */ - iconfig->iocmg_33.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_33.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_33.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_33.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_33.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO16_AS_DAC0_ANA_OUT); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO16_AS_DAC0_ANA_OUT, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO16_AS_DAC0_ANA_OUT, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO16_AS_DAC0_ANA_OUT, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO16_AS_DAC0_ANA_OUT, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/dac/sample_dac/readme.md b/src/application/drivers_sample/dac/sample_dac/readme.md index 4c0942b319918109ece27bc114f6e7ce09bcce61..38d87e841064872b1d6487b6a13c8bcd006fc26b 100644 --- a/src/application/drivers_sample/dac/sample_dac/readme.md +++ b/src/application/drivers_sample/dac/sample_dac/readme.md @@ -2,17 +2,22 @@ ## 关键字: DAC, 数模转换 **【功能描述】** -+ 将软件配置的8bit数字信号,转换成对应的模拟电压量,实现数字到模拟的转换,转换成的模拟信号可便于模拟运算。 ++ 将软件配置的数值信号,转换成对应的模拟电压量,实现数字到模拟的转换,转换成的模拟信号可便于模拟运算。 **【示例配置】** -+ DAC输出的模拟电压期望值为: V = ( DAC.value * ( VDDA – VSSA )) / 256。 ++ DAC输出的模拟电压期望值为: V = ( DAC.value * ( VDDA – VSSA )) / DAC.maxRange。 + 本示例中DAC.value的值为128,其值可在DAC模块的配置界面中进行更改,可以在“system_init.c”文件中进行更改,以满足输出不同的电压值。 ++ 不同芯片的DAC.maxRange不一样,3065H系列值为256,3061M/3066M系列值为1024。 **【示例效果】** -+ 输出的电压值可配置,在IOCMG_33可测量到DAC的输出值,默认值为1.55V。 ++ 输出的电压值可配置,在DAC_OUT管脚测量到期望的模拟电压。 **【注意事项】** -+ DAC.value的配置范围为0-255,超出部分将溢出。 ++ DAC.value的配置范围不同芯片系列不同,3065H系列值为0-255,3061M/3066M系列值为0-1023,超出部分将溢出。 -+ 转速速率为300kHz。 \ No newline at end of file ++ 转速速率为300kHz。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_debug_snprintf/inc/sample_debug_snprintf.h b/src/application/drivers_sample/debug/sample_debug_snprintf/inc/sample_debug_snprintf.h new file mode 100644 index 0000000000000000000000000000000000000000..37aa0ce3efc436c9ebd3fd00ac0226c976cf98df --- /dev/null +++ b/src/application/drivers_sample/debug/sample_debug_snprintf/inc/sample_debug_snprintf.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_debug_snprintf.h + * @author MCU Driver Team + * @brief This file contains debug snprintf entry functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef SAMPLE_DEBUG_SNPRINTF_H +#define SAMPLE_DEBUG_SNPRINTF_H + +void SnprintfTestEntry(void); + +#endif /* SAMPLE_DEBUG_SNPRINTF_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_debug_snprintf/init/feature.h b/src/application/drivers_sample/debug/sample_debug_snprintf/init/feature.h new file mode 100644 index 0000000000000000000000000000000000000000..1e8331dc3060e84d7aeff4e361c01c89a64f344f --- /dev/null +++ b/src/application/drivers_sample/debug/sample_debug_snprintf/init/feature.h @@ -0,0 +1,119 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file feature.h + * @author MCU Driver Team + * @brief This file contains macro configurations related to the project. This file is generated by the IDE tool. + */ + +#ifndef McuMagicTag_FEATURE_H +#define McuMagicTag_FEATURE_H + +/* Macro definitions --------------------------------------------------------- */ +#define CHIP_3061MNPICA MACRO_ENABLE + +#define MACRO_ENABLE 1 +#define MACRO_DISABLE 0 + +/* Macro switch */ +#define BASE_DEFINE_USE_ASSERT MACRO_ENABLE +#ifndef FLASH_CRC_CONFIG +#define FLASH_CRC_CONFIG +#endif /* #ifndef FLASH_CRC_CONFIG */ +#define BASE_MATH_SINCOS_MIDDLE_TABLE MACRO_ENABLE /**< This macro is used to control the table type when the + BASE_MATH_GetSinCos() queries the table. When the value of + this macro is MACRO_ENABLE, the error value obtained by the + BASE_MATH_GetSinCos() is relatively small, and the return + value of the function may be greater than or less than the + actual value. When the value of this macro is MACRO_DISABLE, + the error value obtained by the BASE_MATH_GetSinCos() is + relatively large. However, in the range [0°, 180°) and + [180°, 360°), the return value of the function is either + greater than or less than the actual value. */ + +#define MCS_PARAM_CHECK MACRO_ENABLE +#define APT_PARAM_CHECK MACRO_ENABLE +#define ADC_PARAM_CHECK MACRO_ENABLE +#define CAPM_PARAM_CHECK MACRO_ENABLE +#define CRG_PARAM_CHECK MACRO_ENABLE +#define I2C_PARAM_CHECK MACRO_ENABLE +#define UART_PARAM_CHECK MACRO_ENABLE +#define SPI_PARAM_CHECK MACRO_ENABLE +#define TIMER_PARAM_CHECK MACRO_ENABLE +#define IWDG_PARAM_CHECK MACRO_ENABLE +#define WWDG_PARAM_CHECK MACRO_ENABLE +#define GPIO_PARAM_CHECK MACRO_ENABLE +#define GPT_PARAM_CHECK MACRO_ENABLE +#define DMA_PARAM_CHECK MACRO_ENABLE +#define CRC_PARAM_CHECK MACRO_ENABLE +#define CFD_PARAM_CHECK MACRO_ENABLE +#define CMM_PARAM_CHECK MACRO_ENABLE +#define CAN_PARAM_CHECK MACRO_ENABLE +#define FLASH_PARAM_CHECK MACRO_ENABLE +#define PMC_PARAM_CHECK MACRO_ENABLE +#define ACMP_PARAM_CHECK MACRO_ENABLE +#define DAC_PARAM_CHECK MACRO_ENABLE +#define PGA_PARAM_CHECK MACRO_ENABLE +#define IOCMG_PARAM_CHECK MACRO_ENABLE +#define QDM_PARAM_CHECK MACRO_ENABLE + +/* Peripheral module macro switch--------------------------------------------- */ +#define BOARD_DIM_NUM 1 /**< Number of dimming handle arrays. */ + +#define BOARD_KEY_NUM 10 /**< Number of key handle arrays. */ +#define BOARD_KEY_PRESS_ON GPIO_HIGH_LEVEL /**< GPIO status corresponding to long press valid. */ +#define BOARD_KEY_PRESS_OFF GPIO_LOW_LEVEL /**< GPIO status corresponding to short press valid. */ + +#define BOARD_LED_SEG_NUM 4 /**< Number of segments. */ +#define BOARD_LED_SEGMENT_ON GPIO_HIGH_LEVEL /**< GPIO level status corresponding to valid segments. */ +#define BOARD_LED_SEGMENT_OFF GPIO_LOW_LEVEL /**< GPIO level status corresponding to invalid segments. */ + +#define BOARD_MKEY_SCHEME_NUMBER BOARD_MKEY_SCHEME_NUMBER_ONE /**< Define the scheme to be adopted. */ +#define BOARD_MKEY_OUT_NUM 4 /**< Number of GPIO pins used as output during scanning. */ +#define BOARD_MKEY_IN_NUM 4 /**< Number of GPIO pins used as input during scanning. */ +#define BOARD_MKEY_OUT_PIN_VALID GPIO_LOW_LEVEL /**< GPIO level status corresponding to the valid \ + status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_OUT_PIN_INVALID GPIO_HIGH_LEVEL /**< GPIO level status corresponding to the \ + invalid status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_VALID GPIO_LOW_LEVEL /**< Indicates the GPIO level corresponding to the \ + valid status of the input GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_INVALID GPIO_HIGH_LEVEL /**< Indicates the GPIO level corresponding to the \ + invalid status of the input GPIO in the key matrix. */ + +#define BOARD_PULSES_NUM 2 /**< Number of pulse handles. */ + +#define BASE_DEFINE_SLIPAVERAGE_NUM 2 /**< Sliding average array length. */ + +#define LISTNODE_MAX 20 + +#define BASE_DEFINE_DMA_QUICKSTART + +#define XTRAIL_FREQ 30000000U + +#define DBG_USE_NO_PRINTF 0U +#define DBG_USE_UART_PRINTF 1U + +#define DBG_PRINTF_USE DBG_USE_UART_PRINTF +#if (DBG_PRINTF_USE == DBG_USE_UART_PRINTF) +#define DBG_PRINTF_UART_PORT UART0 +#endif + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_FEATURE_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_debug_snprintf/init/main.c b/src/application/drivers_sample/debug/sample_debug_snprintf/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..9f0d429739615d4430542c058e2b81fdfd9309f0 --- /dev/null +++ b/src/application/drivers_sample/debug/sample_debug_snprintf/init/main.c @@ -0,0 +1,58 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +#include "sample_debug_snprintf.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + SnprintfTestEntry(); + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_debug_snprintf/init/main.h b/src/application/drivers_sample/debug/sample_debug_snprintf/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..d059d7d88546489111a34fdcd3c9e14467f4fe88 --- /dev/null +++ b/src/application/drivers_sample/debug/sample_debug_snprintf/init/main.h @@ -0,0 +1,54 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_debug_snprintf/init/system_init.c b/src/application/drivers_sample/debug/sample_debug_snprintf/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..89d820c1328b51f913e20c87f876f11b7b1a570b --- /dev/null +++ b/src/application/drivers_sample/debug/sample_debug_snprintf/init/system_init.c @@ -0,0 +1,104 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + /* Config PIN36 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_0_AS_JTAG_TCK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_0_AS_JTAG_TCK, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_0_AS_JTAG_TCK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_0_AS_JTAG_TCK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_0_AS_JTAG_TCK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN37 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_1_AS_JTAG_TMS); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_1_AS_JTAG_TMS, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_1_AS_JTAG_TMS, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_1_AS_JTAG_TMS, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_1_AS_JTAG_TMS, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN39 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN40 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_debug_snprintf/readme.md b/src/application/drivers_sample/debug/sample_debug_snprintf/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..481a096c453e40bddc900f79042ac9b538e86f01 --- /dev/null +++ b/src/application/drivers_sample/debug/sample_debug_snprintf/readme.md @@ -0,0 +1,26 @@ +# 格式化缓存输出snprintf用法对比介绍 +## 关键字: snprintf, C标准库, 安全函数库, DBG_SNPRINTF + +**【功能描述】** ++ 示例代码基于安全函数封装的snprintf_s接口以及基于SDK封装的DBG_SNPRINTF宏函数对同一组数据进行测试比较,可通过log查看接口使用的正确性和通过最终生成的bin文件查看调用不同的snprintf接口时的内存占用,供用户不同场景性能与安全需求时进行选择。 + +**【示例配置】** ++ SNPRITF_SELECT:该宏定义由用户定义,可选择测试不同的snprintf接口函数。 + ++ NOT_USE: 即三种snprintf接口均不调用。 + ++ SECUREC_LIB: 调用安全函数库提供的snprintf_s功能,用于安全要求高的场景,对应的内存占用也更大。 + ++ DEBUG_LIB: 调用SDK debug库提供的DBG_SNPRINTF功能,内存占用最小。 + ++ 打印结果:不同snprintf接口对同一组格式化缓存输出的接口打印结果相同。 + +**【示例效果】** ++ 不同snprintf接口对同一组格式化缓存输出的接口打印结果相同。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置,且需使能DEBUG功能,DBG_SNPRINTF和DBG_PRINTF内部实现有共用部分接口。 ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_debug_snprintf/src/sample_debug_snprintf.c b/src/application/drivers_sample/debug/sample_debug_snprintf/src/sample_debug_snprintf.c new file mode 100644 index 0000000000000000000000000000000000000000..b3b903fad7f7375f54782689873f195948f45591 --- /dev/null +++ b/src/application/drivers_sample/debug/sample_debug_snprintf/src/sample_debug_snprintf.c @@ -0,0 +1,66 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_debug_snprintf.c + * @author MCU Driver Team + * @brief sample of snprintf test. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +#include "sample_debug_snprintf.h" + +#define NOT_USE 0x1U +#define SECUREC_LIB 0x2U +#define DEBUG_LIB 0x3U + +#define BUFFER_LENTH 256 + +#define SNPRITF_SELECT DEBUG_LIB /* The user selects the interface to be tested. */ + +#include "debug.h" +#if (SNPRITF_SELECT == SECUREC_LIB) +#include "securec.h" +#endif + +void SnprintfTestEntry(void) +{ + SystemInit(); +#if (SNPRITF_SELECT != NOT_USE) /* The snprintf interface is not invoked for the test. */ + char buffer[BUFFER_LENTH] = {0}; + int len = 0; + float x = 3.1415926; /* 3.1415926 : test data */ + int y = 10; /* 10 : test data */ + char z = 'z'; + char* pz = &z; + char* str = "hello world"; +#endif +#if (SNPRITF_SELECT == SECUREC_LIB) /* Security function library snprintf interface test */ + len = sprintf_s(buffer, BUFFER_LENTH, \ + "securec_test2: x = %f, y = %d, str = %s, z = %c, px = %p", x, y, str, z, pz); +#elif (SNPRITF_SELECT == DEBUG_LIB) /* Testing the snprintf interface of the debug module */ + len = DBG_SNPRINTF(buffer, BUFFER_LENTH, \ + "debug_test3: x = %f, y = %d, str = %s, z = %c, px = %p", x, y, str, z, pz); +#endif +#if (SNPRITF_SELECT != NOT_USE) /* The snprintf interface is not invoked for the test. */ + DBG_PRINTF("%s\r\n", buffer); + DBG_PRINTF("Written characters: %d\r\n", len); +#endif + while (1) { + } +} \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_dfx_log/inc/sample_dfx_log.h b/src/application/drivers_sample/debug/sample_dfx_log/inc/sample_dfx_log.h new file mode 100644 index 0000000000000000000000000000000000000000..8273c182ddbdd703384d873b491aa748adffd862 --- /dev/null +++ b/src/application/drivers_sample/debug/sample_dfx_log/inc/sample_dfx_log.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_dfx_log.h + * @author MCU Driver Team + * @brief dfx_log module sample. + * @details This file provides sample code for users to help use + * the functionalities of the dfx log. + */ +#ifndef SAMPLE_DFX_LOG_H +#define SAMPLE_DFX_LOG_H + +void DFX_SampleMain(void); + +#endif /* #ifndef SAMPLE_DFX_LOG_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_dfx_log/init/main.c b/src/application/drivers_sample/debug/sample_dfx_log/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..15ec5f9ecd0116d9c0ee5ca325f7711bef29bb09 --- /dev/null +++ b/src/application/drivers_sample/debug/sample_dfx_log/init/main.c @@ -0,0 +1,58 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_dfx_log.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + DFX_SampleMain(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_dfx_log/init/main.h b/src/application/drivers_sample/debug/sample_dfx_log/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..b9dbc2ca960d9b0bed9b2545366f889f1b702903 --- /dev/null +++ b/src/application/drivers_sample/debug/sample_dfx_log/init/main.h @@ -0,0 +1,54 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_dfx_log/init/system_init.c b/src/application/drivers_sample/debug/sample_dfx_log/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..813e1a86f3ce383cd74aa65cb8be68fb99df5097 --- /dev/null +++ b/src/application/drivers_sample/debug/sample_dfx_log/init/system_init.c @@ -0,0 +1,105 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE4; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE4; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + /* Config PIN49 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_0_AS_JTAG_TCK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_0_AS_JTAG_TCK, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_0_AS_JTAG_TCK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_0_AS_JTAG_TCK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_0_AS_JTAG_TCK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN50 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_1_AS_JTAG_TMS); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_1_AS_JTAG_TMS, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_1_AS_JTAG_TMS, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_1_AS_JTAG_TMS, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_1_AS_JTAG_TMS, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_dfx_log/readme.md b/src/application/drivers_sample/debug/sample_dfx_log/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..8f443a19a5b60abf6f8cfb6787b7a441cb7999af --- /dev/null +++ b/src/application/drivers_sample/debug/sample_dfx_log/readme.md @@ -0,0 +1,24 @@ +# 小型化日志使用样例 +## 关键字: DFX, 小型化,日志输出,命令注册 + +**【功能描述】** ++ 用例中注册不同的命令,实现不同的日志操作。注册的详细命令请查阅"sample_dfx_log.c"中"DFX_SampleMain()"函数。 + ++ 通过日志打印接口输出日志,例如UART。 + ++ 通过和配套的上位机使用,解析输出的日志数据。 + +**【示例配置】** ++ 编译示例代码,把编译输出的log.xml文件拷贝到配套的上位机软件的根目录。 + ++ 在上位机的发送窗口执行已注册的命令。 + +**【示例效果】** ++ 执行注册过的命令,执行命令动作,实现对应的配置。 + ++ 上位机解析输出日志的内容 + +**【注意事项】** ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/debug/sample_dfx_log/src/sample_dfx_log.c b/src/application/drivers_sample/debug/sample_dfx_log/src/sample_dfx_log.c new file mode 100644 index 0000000000000000000000000000000000000000..02b01319098b71f8a28bdb64e4b4c0ec5ee28761 --- /dev/null +++ b/src/application/drivers_sample/debug/sample_dfx_log/src/sample_dfx_log.c @@ -0,0 +1,529 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_dfx_log.h + * @author MCU Driver Team + * @brief dfx_log module sample. + * @details This file provides sample code for users to help use + * the functionalities of the dfx log. + */ +#include "cmd.h" +#include "dfx_log.h" +#include "log.h" +#include "module.h" +#include "config.h" +#include "event.h" +#include "ext_log.h" +#include "dfx_debug.h" +#include "cmd_common.h" +#include "main.h" +#include "sample_dfx_log.h" + +#define THIS_FILE_ID FILE_ID_SAMPLE_C /* dfx sample file ID */ + +/** + * @brief Registering a Function Instance. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int TestCmdRegister(unsigned int argc, const char *argv[]) +{ + BASE_FUNC_UNUSED(argc); + BASE_FUNC_UNUSED(argv); + /* A message is displayed indicating that the registration is successful. */ + EXT_PRINT("cmd register sucessful\n"); + return 0; +} + +/** + * @brief ExtLog0 output test at different levels. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int VerifyLogLevel(unsigned int argc, const char *argv[]) +{ + /* The input parameter is not used. */ + BASE_FUNC_UNUSED(argc); + BASE_FUNC_UNUSED(argv); + + /* Displays information about different debugging levels. */ + ExtLog0(FATAL, EXT_MODULE_APP_MAIN, "printf FATAL level log\n"); + ExtLog0(ERR, EXT_MODULE_APP_MAIN, "printf ERR level log\n"); + ExtLog0(WARN, EXT_MODULE_APP_MAIN, "printf WARN level log\n"); + ExtLog0(INFO, EXT_MODULE_APP_MAIN, "printf INFO level log\n"); + ExtLog0(DBG, EXT_MODULE_APP_MAIN, "printf DBG level log\n"); + return 0; +} + +/** + * @brief Test on the number of parameters at different levels in the app main module. + * @retval None. + */ +static void VerifyLogOutAppMain(void) +{ + ExtLog0(FATAL, EXT_MODULE_APP_MAIN, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_APP_MAIN, "printf ERR level log %d\n", 0); + /* printf value is 1 and 4294967295 */ + ExtLog2(WARN, EXT_MODULE_APP_MAIN, "printf WARN level log%d %d\n", 1, 4294967295); + /* printf value is 2 and 4294967295 */ + ExtLog3(INFO, EXT_MODULE_APP_MAIN, "printf INFO level log%d %d %d\n", 2, 2, 4294967295); +} + +/** + * @brief Test on the number of parameters at different levels in the app console module. + * @retval None. + */ +static void VerifyLogOutAppConsole(void) +{ + ExtLog0(FATAL, EXT_MODULE_APP_CONSOLE, "printf FATAL level log\n"); + /* printf value is 4294967295 */ + ExtLog1(ERR, EXT_MODULE_APP_CONSOLE, "printf ERR level log %d\n", 4294967295); + /* printf value is 100 and 199999 */ + ExtLog2(WARN, EXT_MODULE_APP_CONSOLE, "printf WARN level log%d %d\n", 100, 199999); + /* printf value is 214752 and 23649 and 4294967295 */ + ExtLog3(INFO, EXT_MODULE_APP_CONSOLE, "printf INFO level log%d %d %d\n", 214752, 23649, 4294967295); +} + +/** + * @brief Test on the number of parameters at different levels in the app chip module. + * @retval None. + */ +static void VerifyLogOutAppChip(void) +{ + ExtLog0(FATAL, EXT_MODULE_APP_CHIP, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_APP_CHIP, "printf ERR level log %d\n", 0); + /* printf value is 1 and 1 */ + ExtLog2(WARN, EXT_MODULE_APP_CHIP, "printf WARN level log%d %d\n", 1, 1); + /* printf value is 2 and 2 and 2 */ + ExtLog3(INFO, EXT_MODULE_APP_CHIP, "printf INFO level log%d %d %d\n", 2, 2, 2); +} + +/** + * @brief Test on the number of parameters at different levels in the drivers base module. + * @retval None. + */ +static void VerifyLogOutDrvBase(void) +{ + ExtLog0(FATAL, EXT_MODULE_DRV_BASE, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_DRV_BASE, "printf ERR level log %d\n", 0); + /* printf value is 1 and 1 */ + ExtLog2(WARN, EXT_MODULE_DRV_BASE, "printf WARN level log%d %d\n", 1, 1); + /* printf value is 2 and 2 and 2 */ + ExtLog3(INFO, EXT_MODULE_DRV_BASE, "printf INFO level log%d %d %d\n", 2, 2, 2); +} + +/** + * @brief Test on the number of parameters at different levels in the drivers chip module. + * @retval None. + */ +static void VerifyLogOutDrvChip(void) +{ + ExtLog0(FATAL, EXT_MODULE_DRV_CHIPS, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_DRV_CHIPS, "printf ERR level log %d\n", 0); + /* printf value is 1 and 1 */ + ExtLog2(WARN, EXT_MODULE_DRV_CHIPS, "printf WARN level log%d %d\n", 1, 1); + /* printf value is 2 and 2 and 2 */ + ExtLog3(INFO, EXT_MODULE_DRV_CHIPS, "printf INFO level log%d %d %d\n", 2, 2, 2); +} + +/** + * @brief Test on the number of parameters at different levels in the drivers crg module. + * @retval None. + */ +static void VerifyLogOutDrvCRg(void) +{ + ExtLog0(FATAL, EXT_MODULE_DRV_CRG, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_DRV_CRG, "printf ERR level log %d\n", 0); + /* printf value is 1 and 4294967295 */ + ExtLog2(WARN, EXT_MODULE_DRV_CRG, "printf WARN level log%d %d\n", 1, 4294967295); + /* printf value is 2 and 2 and 4294967295 */ + ExtLog3(INFO, EXT_MODULE_DRV_CRG, "printf INFO level log%d %d %d\n", 2, 2, 4294967295); +} + +/** + * @brief Test on the number of parameters at different levels in the drivers gpio module. + * @retval None. + */ +static void VerifyLogOutDrvGpio(void) +{ + ExtLog0(FATAL, EXT_MODULE_DRV_GPIO, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_DRV_GPIO, "printf ERR level log %d\n", 0); + /* printf value is 1 and 8 */ + ExtLog2(WARN, EXT_MODULE_DRV_GPIO, "printf WARN level log%d %d\n", 1, 8); + /* printf value is 2 and 2 and 9 */ + ExtLog3(INFO, EXT_MODULE_DRV_GPIO, "printf INFO level log%d %d %d\n", 2, 2, 9); +} + +/** + * @brief Test on the number of parameters at different levels in the drivers i2c module. + * @retval None. + */ +static void VerifyLogOutDrvI2c(void) +{ + ExtLog0(FATAL, EXT_MODULE_DRV_I2C, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_DRV_I2C, "printf ERR level log %d\n", 0); + /* printf value is 1 and 5 */ + ExtLog2(WARN, EXT_MODULE_DRV_I2C, "printf WARN level log%d %d\n", 1, 5); + /* printf value is 2 and 2 and 9 */ + ExtLog3(INFO, EXT_MODULE_DRV_I2C, "printf INFO level log%d %d %d\n", 2, 2, 9); +} + +/** + * @brief Test on the number of parameters at different levels in the drivers irq module. + * @retval None. + */ +static void VerifyLogOutDrvIrq(void) +{ + ExtLog0(FATAL, EXT_MODULE_DRV_IRQ, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_DRV_IRQ, "printf ERR level log %d\n", 0); + /* printf value is 1 and 55 */ + ExtLog2(WARN, EXT_MODULE_DRV_IRQ, "printf WARN level log%d %d\n", 1, 55); + /* printf value is 2 and 2 and 0302 */ + ExtLog3(INFO, EXT_MODULE_DRV_IRQ, "printf INFO level log%d %d %d\n", 2, 2, 0302); +} + +/** + * @brief Test on the number of parameters at different levels in the drivers pinctrl module. + * @retval None. + */ +static void VerifyLogOutDrvPinctrl(void) +{ + ExtLog0(FATAL, EXT_MODULE_DRV_PINCTRL, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_DRV_PINCTRL, "printf ERR level log %d\n", 0); + /* printf value is 1 and 88 */ + ExtLog2(WARN, EXT_MODULE_DRV_PINCTRL, "printf WARN level log%d %d\n", 1, 88); + /* printf value is 2 and 2 and 55 */ + ExtLog3(INFO, EXT_MODULE_DRV_PINCTRL, "printf INFO level log%d %d %d\n", 2, 2, 55); +} + +/** + * @brief Test on the number of parameters at different levels in the drivers timer module. + * @retval None. + */ +static void VerifyLogOutDrvTimer(void) +{ + ExtLog0(FATAL, EXT_MODULE_DRV_TIMER, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_DRV_TIMER, "printf ERR level log %d\n", 0); + /* printf value is 1 and 9999 */ + ExtLog2(WARN, EXT_MODULE_DRV_TIMER, "printf WARN level log%d %d\n", 1, 9999); + /* printf value is 2 and 2 and 99999 */ + ExtLog3(INFO, EXT_MODULE_DRV_TIMER, "printf INFO level log%d %d %d\n", 2, 2, 99999); +} + +/** + * @brief Test on the number of parameters at different levels in the drivers uart module. + * @retval None. + */ +static void VerifyLogOutDrvUart(void) +{ + ExtLog0(FATAL, EXT_MODULE_DRV_UART, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_DRV_UART, "printf ERR level log %d\n", 0); + /* printf value is 1 and 77744 */ + ExtLog2(WARN, EXT_MODULE_DRV_UART, "printf WARN level log%d %d\n", 1, 77744); + /* printf value is 2 and 2 and 8985 */ + ExtLog3(INFO, EXT_MODULE_DRV_UART, "printf INFO level log%d %d %d\n", 2, 2, 8985); +} + +/** + * @brief Test on the number of parameters at different levels in the dfx module. + * @retval None. + */ +static void VerifyLogOutDfx(void) +{ + ExtLog0(FATAL, EXT_MODULE_DFX, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_DFX, "printf ERR level log %d\n", 0); + /* printf value is 1 and 245 */ + ExtLog2(WARN, EXT_MODULE_DFX, "printf WARN level log%d %d\n", 1, 245); + /* printf value is 2 and 2 and 654654 */ + ExtLog3(INFO, EXT_MODULE_DFX, "printf INFO level log%d %d %d\n", 2, 2, 654654); +} + +/** + * @brief Test on the number of parameters at different levels in the butt module. + * @retval None. + */ +static void VerifyLogOutButt(void) +{ + ExtLog0(FATAL, EXT_MODULE_BUTT, "printf FATAL level log\n"); + ExtLog1(ERR, EXT_MODULE_BUTT, "printf ERR level log %d\n", 0); + /* printf value is 1 and 8524 */ + ExtLog2(WARN, EXT_MODULE_BUTT, "printf WARN level log%d %d\n", 1, 8524); + /* printf value is 2 and 2 and 99554 */ + ExtLog3(INFO, EXT_MODULE_BUTT, "printf INFO level log%d %d %d\n", 2, 2, 99554); +} + +/** + * @brief Log output test of different levels on different modules. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int VerifyLogOut(unsigned int argc, const char *argv[]) +{ + /* The input parameter is not used. */ + BASE_FUNC_UNUSED(argc); + BASE_FUNC_UNUSED(argv); + /* App module */ + VerifyLogOutAppMain(); + VerifyLogOutAppConsole(); + VerifyLogOutAppChip(); + /* Drive module */ + VerifyLogOutDrvBase(); + VerifyLogOutDrvChip(); + VerifyLogOutDrvCRg(); + VerifyLogOutDrvGpio(); + VerifyLogOutDrvI2c(); + VerifyLogOutDrvIrq(); + VerifyLogOutDrvPinctrl(); + VerifyLogOutDrvTimer(); + VerifyLogOutDrvUart(); + /* Other modules */ + VerifyLogOutDfx(); + VerifyLogOutButt(); + return 0; +} + +/** + * @brief Test the log output cache of a specified size. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int VerifyLogOutBuf(unsigned int argc, const char *argv[]) +{ + BASE_FUNC_UNUSED(argc); + BASE_FUNC_UNUSED(argv); + + unsigned int buf[10]; /* test out buf len is 10 */ + buf[0] = 0x81; /* test buf[0] data is 0x81 */ + buf[1] = 0x82; /* test buf[1] data is 0x82 */ + buf[2] = 0x83; /* test buf[2] data is 0x83 */ + buf[3] = 0x84; /* test buf[3] data is 0x84 */ + buf[4] = 0x85; /* test buf[4] data is 0x85 */ + buf[5] = 0x86; /* test buf[5] data is 0x86 */ + buf[6] = 0x87; /* test buf[6] data is 0x87 */ + buf[7] = 0x88; /* test buf[7] data is 0x88 */ + buf[8] = 0x89; /* test buf[8] data is 0x89 */ + buf[9] = 0x90; /* test buf[9] data is 0x90 */ + ExtLogBuf(FATAL, EXT_MODULE_DRV_PINCTRL, "printf out buf log 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + buf, 10); /* test out buf len is 10 */ + return 0; +} + +/** + * @brief Enable the debugging function by running commands. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int CmdGetDebugModeEnable(unsigned int argc, const char *argv[]) +{ + /* The input parameter is not used. */ + BASE_FUNC_UNUSED(argc); + BASE_FUNC_UNUSED(argv); + + struct SysDebugSwitch *debugSwitch = GetDebugSwitch(); + /* Configure the debugging mode. */ + ExtSetDebugMode(DEBUG); + EXT_PRINT("debug_enable : %d\n", debugSwitch->enable); + return 0; +} + +/** + * @brief Disable the debugging function by running commands. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int CmdGetDebugModeDisable(unsigned int argc, const char *argv[]) +{ + /* The input parameter is not used. */ + BASE_FUNC_UNUSED(argc); + BASE_FUNC_UNUSED(argv); + + struct SysDebugSwitch *debugSwitch = GetDebugSwitch(); + /* Configure the running mode. */ + ExtSetDebugMode(RUNNING); + EXT_PRINT("debug_disable : %d\n", debugSwitch->enable); + return 0; +} + +/** + * @brief Configuring the Debug Level by Using Commands. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int SetLogLevel(unsigned int argc, const char *argv[]) +{ + BASE_FUNC_UNUSED(argc); + int id = (int)*argv[1] - 48; /* argv[1] is a number in ASCII format, which needs to be subtracted by 48. */ + int level = (int)*argv[2] - 48; /* argv[2] is a number in ASCII format, which needs to be subtracted by 48. */ + if (!ExtDrvLogSetLogLevel(id, level)) { + EXT_PRINT("set success\r\n"); + } else { + EXT_PRINT("set failed!\r\n"); + } + return 0; +} + +#define TEST_LOAD_ADDR 0x2000000 /* Test loading address 0x2000000 */ + +/** + * @brief Writes logs to the specified address. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int GetAddressWrite(unsigned int argc, const char *argv[]) +{ + /* The input parameter is not used. */ + BASE_FUNC_UNUSED(argc); + BASE_FUNC_UNUSED(argv); + + char value[] = {'h', 'e', 'l', 'l', 'o', '!', '\0'}; + unsigned int len = sizeof(value) / sizeof(char); + EXT_PRINT("value: %s\n", value); + EXT_PRINT("len = %d\n", len); + /* Writes logs to the specified address. */ + ExtLoadWrite(TEST_LOAD_ADDR, value, len); + return 0; +} + +/** + * @brief Reads logs from a specified address. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int GetAddressRead(unsigned int argc, const char *argv[]) +{ + /* The input parameter is not used. */ + BASE_FUNC_UNUSED(argc); + BASE_FUNC_UNUSED(argv); + + char value[7] = {0}; /* test value len is 7 */ + unsigned int len = 7; /* test value len is 7 */ + + ExtLoadRead(TEST_LOAD_ADDR, value, len); + EXT_PRINT("value1: %s\n", value); + return 0; +} + +#define TEST_WRITE_ARR_MAX_LEN 49 + +/** + * @brief Write Configuration. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int GetConfigWrite(unsigned int argc, const char *argv[]) +{ + /* The input parameter is not used. */ + BASE_FUNC_UNUSED(argc); + BASE_FUNC_UNUSED(argv); + + char configWriteArr[] = {'h', 'e', 'l', 'l', 'o', '!', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'e', 'h', 'i', 'j', 'k', 'l', '!', + '@', '#', '$', '&', 'h', 'e', 'l', 'l', 'o', '!', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'e', 'h', 'i', + 'j', 'k', 'l', '!', '@', '#', '$', '&', '\0'}; + char configReadArr[TEST_WRITE_ARR_MAX_LEN] = {0}; + char *vbuff = configWriteArr; + + EXT_PRINT("configWriteArr: %s\n", configWriteArr); + /* Writes the configuration data to the specified address. */ + ExtConfigWrite(DATA_ITEM_EVENT, vbuff, TEST_WRITE_ARR_MAX_LEN); + /* Read the configuration data from the specified address. */ + ExtConfigRead(DATA_ITEM_EVENT, configReadArr, TEST_WRITE_ARR_MAX_LEN); + EXT_PRINT("read: %s\n", configReadArr); + return 0; +} + +/** + * @brief Test report. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int TestReport(unsigned int argc, const char *argv[]) +{ + /* The input parameter is not used. */ + BASE_FUNC_UNUSED(argc); + BASE_FUNC_UNUSED(argv); + + UserEventObj eventObj; + eventObj.report.event.eventType = 1; + eventObj.report.reportType = 1; + /* Initializing event reporting */ + EventInit(); + UserReportEvent(&eventObj); + return 0; +} + +/** + * @brief Run commands to obtain version information. + * @param argc argument count. + * @param argv argument vector. + * @retval 0 is success. + */ +static int TestCmdGetVersionInfo(unsigned int argc, const char *argv[]) +{ + /* The input parameter is not used. */ + BASE_FUNC_UNUSED(argc); + BASE_FUNC_UNUSED(argv); + + CmdGetVersionInfo(); + return 0; +} + +/** + * @brief The sample executes the main function. + * @retval None. + */ +void DFX_SampleMain(void) +{ + /* Chip Initialization Configuration */ + SystemInit(); + ConsoleInit(g_uart0); + + /* Registering Basic Interfaces */ + ExtCmdRegister("cmdregister", &TestCmdRegister); + ExtCmdRegister("getversion", &TestCmdGetVersionInfo); + ExtCmdRegister("verifyloglevel", &VerifyLogLevel); + ExtCmdRegister("verifylogout", &VerifyLogOut); + ExtCmdRegister("verifylogoutbuf", &VerifyLogOutBuf); + + ExtCmdRegister("userreport", &TestReport); + + /* Registration of configuration interfaces */ + ExtCmdRegister("getdebugenable", &CmdGetDebugModeEnable); + ExtCmdRegister("getdebugdisable", &CmdGetDebugModeDisable); + ExtCmdRegister("setloglevel", &SetLogLevel); + + /* Address operation interface registration */ + ExtCmdRegister("addresswrite", &GetAddressWrite); + ExtCmdRegister("addressread", &GetAddressRead); + ExtCmdRegister("configwrite", &GetConfigWrite); + + while (1) { + ExtAppCmdProcess(); + } +} \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_list_transfer/inc/sample_dma_list_transfer.h b/src/application/drivers_sample/dma/sample_dma_list_transfer/inc/sample_dma_list_transfer.h index 409b72414d8aa23695d7f184b23924b475d56bde..d792a9fb5f948234cc8d9d6cb3a1ce0bf755365a 100644 --- a/src/application/drivers_sample/dma/sample_dma_list_transfer/inc/sample_dma_list_transfer.h +++ b/src/application/drivers_sample/dma/sample_dma_list_transfer/inc/sample_dma_list_transfer.h @@ -26,7 +26,7 @@ #include "dma.h" #include "debug.h" -#include "interrupt.h" +#include "main.h" int DMA_MemoryToMemoryList(void); #endif \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_list_transfer/init/main.c b/src/application/drivers_sample/dma/sample_dma_list_transfer/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..09e9e2af1b3ea47f08e56594241e5763a81797c2 --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_list_transfer/init/main.c @@ -0,0 +1,59 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_dma_list_transfer.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +DMA_Handle g_dmac; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + DMA_MemoryToMemoryList(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_list_transfer/init/main.h b/src/application/drivers_sample/dma/sample_dma_list_transfer/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..dbd7661adcbb6ac3601d7d576af107c6b45f4fad --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_list_transfer/init/main.h @@ -0,0 +1,42 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "crg.h" +#include "dma.h" + +extern UART_Handle g_uart0; + +extern DMA_Handle g_dmac; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/sysinit/system_init.c b/src/application/drivers_sample/dma/sample_dma_list_transfer/init/system_init.c similarity index 64% rename from src/application/drivers_sample/dma/sample_dma_list_transfer_continue/sysinit/system_init.c rename to src/application/drivers_sample/dma/sample_dma_list_transfer/init/system_init.c index b1365052dfecea2513a3afe3277698dae7ad927b..b2959171263b01d61c786e329bd95e3bf9cb41f0 100644 --- a/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/sysinit/system_init.c +++ b/src/application/drivers_sample/dma/sample_dma_list_transfer/init/system_init.c @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -22,18 +22,25 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 +#define CLK1M_Div 25 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; - crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 0x30; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (CLK1M_Div - 1); + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -59,26 +66,21 @@ static void DMA_Channel2Init(void) static void DMA_Init(void) { + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; - g_dmac.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.irqNumTc = IRQ_DMA_TC; - g_dmac.irqNumError = IRQ_DMA_ERR; - HAL_DMA_IRQService(&g_dmac); + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); - DMA_Channel2Init(); } static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -87,29 +89,28 @@ static void UART0_Init(void) g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; - g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; - g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/dma/sample_dma_list_transfer/readme.md b/src/application/drivers_sample/dma/sample_dma_list_transfer/readme.md index 7a4adb3ea4b7a610566bb421f8191605ed3a84fb..ca33d81d70d44572ea1ef626c38ca44705ab1c47 100644 --- a/src/application/drivers_sample/dma/sample_dma_list_transfer/readme.md +++ b/src/application/drivers_sample/dma/sample_dma_list_transfer/readme.md @@ -15,4 +15,6 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。DMA搬运结束后,会上报中断,在中断回调函数中查看源目端数据是否一致。 **【注意事项】** -+ NA \ No newline at end of file ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_list_transfer/src/sample_dma_list_transfer.c b/src/application/drivers_sample/dma/sample_dma_list_transfer/src/sample_dma_list_transfer.c index 861436e6a97a81cc5a3b1324a7aaf71711d50e92..af475fbc5b39c0e7d86ef87937fd4b47d226ad0f 100644 --- a/src/application/drivers_sample/dma/sample_dma_list_transfer/src/sample_dma_list_transfer.c +++ b/src/application/drivers_sample/dma/sample_dma_list_transfer/src/sample_dma_list_transfer.c @@ -27,38 +27,18 @@ static unsigned char g_str1[NUM] = "1234567890123456789012345678901234567890123456789012345678901234567890"; static unsigned char g_str2[NUM] = {0}; static unsigned char g_str3[NUM] = {0}; -static DMA_Handle g_dmac; -static DMA_ChannelParam g_param; - -/** - * @brief DMA controller initialization. - * @param None. - * @retval None. - */ -static void DMA_ControllerInit(void) -{ - g_dmac.baseAddress = DMA; - g_dmac.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.irqNumTc = IRQ_DMA_TC; - g_dmac.irqNumError = IRQ_DMA_ERR; - HAL_DMA_Init(&g_dmac); -} - -/** - * @brief DMA interrupt initialization. - * @param handle DMA handle. - * @retval None. - */ -static void DMA_InterruptInit(DMA_Handle *handle) -{ - IRQ_Enable(); - handle->irqNumTc = IRQ_DMA_TC; - handle->irqNumError = IRQ_DMA_ERR; - HAL_DMA_IRQService(handle); - IRQ_EnableN(IRQ_DMA_TC); - IRQ_EnableN(IRQ_DMA_ERR); -} +static DMA_ChannelParam g_param = { + .direction = DMA_MEMORY_TO_MEMORY_BY_DMAC, + .srcAddrInc = DMA_ADDR_INCREASE, + .destAddrInc = DMA_ADDR_INCREASE, + .srcPeriph = DMA_REQUEST_MEM, + .destPeriph = DMA_REQUEST_MEM, + .srcWidth = DMA_TRANSWIDTH_BYTE, + .destWidth = DMA_TRANSWIDTH_BYTE, + .srcBurst = DMA_BURST_LENGTH_1, + .destBurst = DMA_BURST_LENGTH_1, + .pHandle = NULL, +}; /** * @brief User-defined callback function for completing the transfer of memory to the memory. @@ -86,30 +66,18 @@ static DMA_LinkList g_secondNode; */ int DMA_MemoryToMemoryList(void) { - DBG_UartPrintInit(BAUDRATE); /* baud rate is 115200 */ + SystemInit(); DBG_PRINTF("MemoryToMemoryList Begin: \r\n"); DBG_PRINTF("src_memory g_str1: %s\r\n", g_str1); DBG_PRINTF("dest_memory g_str2: %s\r\n", g_str2); DBG_PRINTF("dest_memory g_str3: %s\r\n", g_str3); - unsigned int channel = 2; /* select transfer channel 2 */ - DMA_ControllerInit(); - DMA_InterruptInit(&g_dmac); + unsigned int channel = 2; /* select transfer channel 2 */ HAL_DMA_RegisterCallback(&g_dmac, DMA_CHANNEL_FINISH, channel, DMA_MemToMemFinishList); - - g_param.direction = DMA_MEMORY_TO_MEMORY_BY_DMAC; - g_param.srcAddrInc = DMA_ADDR_UNALTERED; - g_param.destAddrInc = DMA_ADDR_INCREASE; - g_param.srcWidth = DMA_TRANSWIDTH_BYTE; - g_param.destWidth = DMA_TRANSWIDTH_BYTE; - g_param.srcBurst = DMA_BURST_LENGTH_1; - g_param.destBurst = DMA_BURST_LENGTH_1; - g_param.pHandle = &g_dmac; /* The transmission length is defined as 5 */ HAL_DMA_InitNewNode(&g_firstNode, &g_param, (uintptr_t)(void *)g_str1, (uintptr_t)(void *)g_str2, 5); /* The transmission length is defined as 50 */ HAL_DMA_InitNewNode(&g_secondNode, &g_param, (uintptr_t)(void *)g_str1, (uintptr_t)(void *)g_str3, 50); - HAL_DMA_ListAddNode(&g_firstNode, &g_secondNode); HAL_DMA_StartListTransfer(&g_dmac, &g_firstNode, channel); DBG_PRINTF("End!\r\n"); diff --git a/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/sysinit/main.c b/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/init/main.c similarity index 100% rename from src/application/drivers_sample/dma/sample_dma_list_transfer_continue/sysinit/main.c rename to src/application/drivers_sample/dma/sample_dma_list_transfer_continue/init/main.c diff --git a/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/sysinit/main.h b/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/init/main.h similarity index 89% rename from src/application/drivers_sample/dma/sample_dma_list_transfer_continue/sysinit/main.h rename to src/application/drivers_sample/dma/sample_dma_list_transfer_continue/init/main.h index ea243033c6c8da1abfd790d57df6105aed36c334..3ca5719b251fdb3ba32845d9caa00177c2999ca5 100644 --- a/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/sysinit/main.h +++ b/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/init/main.h @@ -28,14 +28,6 @@ #include "crg.h" #include "dma.h" -#define IO_SPEED_FAST 0x00U -#define IO_SPEED_SLOW 0x01U - -#define IO_DRV_LEVEL4 0x00U -#define IO_DRV_LEVEL3 0x01U -#define IO_DRV_LEVEL2 0x02U -#define IO_DRV_LEVEL1 0x03U - extern UART_Handle g_uart0; extern DMA_Handle g_dmac; @@ -43,6 +35,4 @@ extern DMA_Handle g_dmac; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); -void MemoryDMACallback(void *handle); - #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/init/system_init.c b/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..4a216e7f9f21756cd33bdc9a3cbf470ff7637ec3 --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/init/system_init.c @@ -0,0 +1,125 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg.h" + +#define UART0_BAND_RATE 115200 +#define CLK1M_Div 25 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 0x30; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (CLK1M_Div - 1); + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void DMA_Channel2Init(void) +{ + DMA_ChannelParam dma_param; + dma_param.direction = DMA_MEMORY_TO_MEMORY_BY_DMAC; + dma_param.srcAddrInc = DMA_ADDR_INCREASE; + dma_param.destAddrInc = DMA_ADDR_INCREASE; + dma_param.srcPeriph = DMA_REQUEST_MEM; + dma_param.destPeriph = DMA_REQUEST_MEM; + dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; + dma_param.destWidth = DMA_TRANSWIDTH_BYTE; + dma_param.srcBurst = DMA_BURST_LENGTH_1; + dma_param.destBurst = DMA_BURST_LENGTH_1; + dma_param.pHandle = NULL; + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_TWO); +} + +static void DMA_Init(void) +{ + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); + g_dmac.baseAddress = DMA; + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); + IRQ_EnableN(IRQ_DMA_TC); + IRQ_EnableN(IRQ_DMA_ERR); + HAL_DMA_Init(&g_dmac); + + DMA_Channel2Init(); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + DMA_Init(); + UART0_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/readme.md b/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/readme.md index fc2202829dfaaacd2b213222bbb4925c6ce717ab..bd3fed31216ee990f016a61c9c89217a0582e7f8 100644 --- a/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/readme.md +++ b/src/application/drivers_sample/dma/sample_dma_list_transfer_continue/readme.md @@ -10,10 +10,12 @@ + 链表连续处理:首先,将使用“HAL_DMA_InitNewNode()”接口配置目的内存需要接收的数据长度和内存地址,得到一个节点; 然后,使用“HAL_DMA_ListAddNode()”接口,将上一步的节点作为两个入参,使得链表循环。 -+ 使能DMA搬运:将第一个内存块的地址和选择的DMA传输通道作为入参传递至“HAL_DMA_StartListTransfer()”,使能DMA传递 ++ 使能DMA搬运:将第一个内存块的地址和选择的DMA传输通道作为入参传递至“HAL_DMA_StartListTransfer()”,使能DMA传递。 **【示例效果】** -+ 当用户烧录编译后的示例代码后,初始化和配置完成后。DMA搬运结束后,会上报中断,在中断回调函数中查看源目端数据是否一致。 ++ 当用户烧录编译后的示例代码后,初始化和配置完成后。运行后,DMA进行连续传输。 **【注意事项】** -+ NA \ No newline at end of file ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/main.c b/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/main.c index 89ffdc1fc8b54e3ecae91fe6f65824cf6e1df236..721d42d34b903acca02f039bdea61a4eefdb2c7d 100644 --- a/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/main.c +++ b/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/main.c @@ -15,22 +15,45 @@ * 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. - * @file main.h + * @file main.c * @author MCU Driver Team - * @brief This file contains driver init functions. + * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "sample_dma_mem_to_mem.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ UART_Handle g_uart0; - DMA_Handle g_dmac; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ DMA_MemoryToMemory(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/main.h b/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/main.h index 30a7c0e109829001a53343fca641666681b6ecff..08e7bab48886f20e120a3e9e889dde33497d90e5 100644 --- a/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/main.h +++ b/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/main.h @@ -36,6 +36,11 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern UART_Handle g_uart0; extern DMA_Handle g_dmac; @@ -43,6 +48,8 @@ extern DMA_Handle g_dmac; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); -void UART0_TXDMACallback(UART_Handle *handle); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/system_init.c b/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/system_init.c index 3dc6940d17c2ad01976f94c51d5d281a679d47dd..a27e22ad84d870b6ec7b731417ff8f7f690970bc 100644 --- a/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/system_init.c +++ b/src/application/drivers_sample/dma/sample_dma_mem_to_mem/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -41,7 +43,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -static void DMA_Channel2Init(void *handle) +static void DMA_Channel2Init(void) { DMA_ChannelParam dma_param; dma_param.direction = DMA_MEMORY_TO_MEMORY_BY_DMAC; @@ -53,30 +55,23 @@ static void DMA_Channel2Init(void *handle) dma_param.destWidth = DMA_TRANSWIDTH_BYTE; dma_param.srcBurst = DMA_BURST_LENGTH_1; dma_param.destBurst = DMA_BURST_LENGTH_1; - dma_param.pHandle = handle; + dma_param.pHandle = NULL; HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_TWO); } static void DMA_Init(void) { + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; - g_dmac.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.irqNumTc = IRQ_DMA_TC; - g_dmac.irqNumError = IRQ_DMA_ERR; - HAL_DMA_IRQService(&g_dmac); + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); - DMA_Channel2Init((void *)(&g_uart0)); -} - -__weak void UART0_TXDMACallback(UART_Handle *handle) -{ - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_TXDMACallback */ - /* USER CODE END UART0_TXDMACallback */ + DMA_Channel2Init(); } static void UART0_Init(void) @@ -85,7 +80,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -98,28 +92,22 @@ static void UART0_Init(void) g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart0); - g_uart0.dmaHandle = &g_dmac; - g_uart0.uartDmaTxChn = DMA_CHANNEL_TWO; - HAL_UART_RegisterCallBack(&g_uart0, UART_WRITE_DMA_FINISH, UART0_TXDMACallback); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/dma/sample_dma_mem_to_mem/readme.md b/src/application/drivers_sample/dma/sample_dma_mem_to_mem/readme.md index 1b1aed5abc6ba9070fc462c024fa7df18fa9c6a6..8ab98a45aa47db2c75a8689897de144e33a45798 100644 --- a/src/application/drivers_sample/dma/sample_dma_mem_to_mem/readme.md +++ b/src/application/drivers_sample/dma/sample_dma_mem_to_mem/readme.md @@ -7,7 +7,7 @@ **【示例配置】** + 在“SystemInit()”中配置DMA源和目的大小端、中断、配置通道相关参数进行初始化。 -+ 将搬运的源端地址和目的端地址传入“HAL_DMA_StartIT()”接口,搬运的数据长度和DMA的通道号也作为入参传递进去。。 ++ 将搬运的源端地址和目的端地址传入“HAL_DMA_StartIT()”接口,搬运的数据长度和DMA的通道号也作为入参传递进去。 + 实现“DMA_MemToMemCallBack()”中断回调函数。 @@ -15,4 +15,6 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。DMA搬运结束后,会上报中断,在中断回调中查看源目端数据是否一致。 **【注意事项】** -+ NA \ No newline at end of file ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_mem_to_per/inc/sample_dma_mem_to_per.h b/src/application/drivers_sample/dma/sample_dma_mem_to_per/inc/sample_dma_mem_to_per.h index 88883e315ddc878b458bd34f8a99be17d552b09a..0603d0a75c7e164bddff3068a6d1ef9330c4a499 100644 --- a/src/application/drivers_sample/dma/sample_dma_mem_to_per/inc/sample_dma_mem_to_per.h +++ b/src/application/drivers_sample/dma/sample_dma_mem_to_per/inc/sample_dma_mem_to_per.h @@ -26,7 +26,7 @@ #include "dma.h" #include "debug.h" -#include "interrupt.h" +#include "main.h" int DMA_MemoryToPeriphIT(void); #endif \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_mem_to_per/init/main.c b/src/application/drivers_sample/dma/sample_dma_mem_to_per/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..4d26b4415246ccc00001092392c0c0f9c4281a09 --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_mem_to_per/init/main.c @@ -0,0 +1,59 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_dma_mem_to_per.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +DMA_Handle g_dmac; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + DMA_MemoryToPeriphIT(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_mem_to_per/init/main.h b/src/application/drivers_sample/dma/sample_dma_mem_to_per/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..dbd7661adcbb6ac3601d7d576af107c6b45f4fad --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_mem_to_per/init/main.h @@ -0,0 +1,42 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "crg.h" +#include "dma.h" + +extern UART_Handle g_uart0; + +extern DMA_Handle g_dmac; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_mem_to_per/init/system_init.c b/src/application/drivers_sample/dma/sample_dma_mem_to_per/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..d31d16161cfe270a19f77c82ee9b72e1785920e9 --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_mem_to_per/init/system_init.c @@ -0,0 +1,129 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg.h" + +#define UART0_BAND_RATE 115200 +#define CLK1M_Div 25 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 0x30; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (CLK1M_Div - 1); + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void DMA_Channel3Init(void) +{ + DMA_ChannelParam dma_param; + dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; /* Dma direction is memory to peripherals. */ + dma_param.srcAddrInc = DMA_ADDR_INCREASE; + dma_param.destAddrInc = DMA_ADDR_UNALTERED; /* Destination is peripherals, address does not increase. */ + dma_param.srcPeriph = DMA_REQUEST_MEM; + dma_param.destPeriph = DMA_REQUEST_UART0_TX; + dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; + dma_param.destWidth = DMA_TRANSWIDTH_BYTE; + dma_param.srcBurst = DMA_BURST_LENGTH_1; + dma_param.destBurst = DMA_BURST_LENGTH_1; + dma_param.pHandle = &g_uart0; + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_THREE); /* Dma parameter init. */ +} + +static void DMA_Init(void) +{ + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); + g_dmac.baseAddress = DMA; + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); + IRQ_EnableN(IRQ_DMA_TC); + IRQ_EnableN(IRQ_DMA_ERR); + HAL_DMA_Init(&g_dmac); + DMA_Channel3Init(); + HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_THREE, DMA_PRIORITY_HIGHEST); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_DMA; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); + g_uart0.dmaHandle = &g_dmac; + g_uart0.uartDmaTxChn = 3; /* 3 is UART_DMA tx channel */ + HAL_UART_RegisterCallBack(&g_uart0, UART_WRITE_DMA_FINISH, (UART_CallbackType)UART0_TXDMACallback); + HAL_UART_RegisterCallBack(&g_uart0, UART_WRITE_IT_FINISH, (UART_CallbackType)UART0WriteInterruptCallback); +} + +static void IOConfig(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + + +void SystemInit(void) +{ + IOConfig(); + DMA_Init(); + UART0_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_mem_to_per/readme.md b/src/application/drivers_sample/dma/sample_dma_mem_to_per/readme.md index f2d505621ae4fbf7391abc26e744e8918007efaa..bb20e6dbf121c166daafa89015bd04200ab59322 100644 --- a/src/application/drivers_sample/dma/sample_dma_mem_to_per/readme.md +++ b/src/application/drivers_sample/dma/sample_dma_mem_to_per/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。DMA搬运结束后,会上报中断,在中断函数中打印传输完成log,并且在串口助手上显示搬运完成的数据。 **【注意事项】** -+ 如果要在串口助手上显示搬运完成的数据,要设置外设为对应的uart串口。 \ No newline at end of file ++ 如果要在串口助手上显示搬运完成的数据,要设置外设为对应的uart串口。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_mem_to_per/src/sample_dma_mem_to_per.c b/src/application/drivers_sample/dma/sample_dma_mem_to_per/src/sample_dma_mem_to_per.c index 231a0cbfd99acf51e7ee6d6fda6451d0724857a1..5de8b8938b80cf010e9238bea2317b9f995271c9 100644 --- a/src/application/drivers_sample/dma/sample_dma_mem_to_per/src/sample_dma_mem_to_per.c +++ b/src/application/drivers_sample/dma/sample_dma_mem_to_per/src/sample_dma_mem_to_per.c @@ -24,40 +24,8 @@ #include "sample_dma_mem_to_per.h" #define NUM 10 -static UART_Handle g_uartHandle; -static unsigned char g_str1[NUM] = "123456789"; -static DMA_Handle g_dmac; -static DMA_ChannelParam g_param; -/** - * @brief DMA controller initialization. - * @param None. - * @retval None. - */ -static void DMA_ControllerInit(void) -{ - g_dmac.baseAddress = DMA; - g_dmac.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.irqNumTc = IRQ_DMA_TC; - g_dmac.irqNumError = IRQ_DMA_ERR; - HAL_DMA_Init(&g_dmac); -} - -/** - * @brief DMA interrupt initialization. - * @param handle DMA handle. - * @retval None. - */ -static void DMA_InterruptInit(DMA_Handle *handle) -{ - IRQ_Enable(); - handle->irqNumTc = IRQ_DMA_TC; - handle->irqNumError = IRQ_DMA_ERR; - HAL_DMA_IRQService(handle); - IRQ_EnableN(IRQ_DMA_TC); - IRQ_EnableN(IRQ_DMA_ERR); -} +static unsigned char g_str1[NUM] = "123456789"; /** * @brief User-defined callback function for completing the transfer of memory to the peripheral. @@ -77,40 +45,20 @@ static void DMA_MemToPeriFinish(void *handle) */ int DMA_MemoryToPeriphIT(void) { - g_uartHandle.baseAddress = UART0; - g_uartHandle.baudRate = 115200; /* baud rate is 115200 */ - g_uartHandle.dataLength = UART_DATALENGTH_8BIT; - g_uartHandle.stopBits = UART_STOPBITS_ONE; - g_uartHandle.parity = UART_PARITY_NONE; - g_uartHandle.fifoMode = true; - g_uartHandle.fifoTxThr = UART_FIFOFULL_ONE_TWO; - g_uartHandle.fifoRxThr = UART_FIFOFULL_ONE_TWO; - g_uartHandle.hwFlowCtr = UART_HW_FLOWCTR_DISABLE; - HAL_UART_Init(&g_uartHandle); - + SystemInit(); DBG_PRINTF("MemoryToPeriph Begin: \r\n"); DBG_PRINTF("src_memory g_str1: %s\r\n", g_str1); unsigned int channel = 3; /* select transfer channel 3 */ - DMA_ControllerInit(); - DMA_InterruptInit(&g_dmac); + HAL_DMA_RegisterCallback(&g_dmac, DMA_CHANNEL_FINISH, channel, DMA_MemToPeriFinish); - g_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; - g_param.srcAddrInc = DMA_ADDR_INCREASE; - g_param.destAddrInc = DMA_ADDR_UNALTERED; - g_param.destPeriph = DMA_REQUEST_UART0_TX; - g_param.srcWidth = DMA_TRANSWIDTH_BYTE; - g_param.destWidth = DMA_TRANSWIDTH_BYTE; - g_param.srcBurst = DMA_BURST_LENGTH_4; - g_param.destBurst = DMA_BURST_LENGTH_4; - g_param.pHandle = &g_uartHandle; - HAL_DMA_InitChannel(&g_dmac, &g_param, channel); + unsigned int ret; - ret = HAL_DMA_StartIT(&g_dmac, (uintptr_t)(void *)g_str1, (uintptr_t)(void *)&(g_uartHandle.baseAddress->UART_DR), + ret = HAL_DMA_StartIT(&g_dmac, (uintptr_t)(void *)g_str1, (uintptr_t)(void *)&(g_uart0.baseAddress->UART_DR), 6, channel); /* The transmission length is defined as 6 */ if (ret == BASE_STATUS_ERROR) { DBG_PRINTF("HAL_DMA_StartIT: BASE_STATUS_ERROR\r\n"); } else { - g_uartHandle.baseAddress->UART_DMACR.BIT.txdmae = BASE_CFG_ENABLE; + g_uart0.baseAddress->UART_DMACR.BIT.txdmae = BASE_CFG_ENABLE; DBG_PRINTF("HAL_DMA_StartIT: BASE_STATUS_OK\r\n"); } DBG_PRINTF("End:\r\n"); diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_mem/inc/sample_dma_per_to_mem.h b/src/application/drivers_sample/dma/sample_dma_per_to_mem/inc/sample_dma_per_to_mem.h index 7265024ae80d880a2187f68c113fefc724a14066..1bbbd9a84c9d5b0443a07646d9b287f8c9404743 100644 --- a/src/application/drivers_sample/dma/sample_dma_per_to_mem/inc/sample_dma_per_to_mem.h +++ b/src/application/drivers_sample/dma/sample_dma_per_to_mem/inc/sample_dma_per_to_mem.h @@ -26,7 +26,7 @@ #include "dma.h" #include "debug.h" -#include "interrupt.h" +#include "main.h" int DMA_PeriphToMemoryIT(void); #endif \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_mem/init/main.c b/src/application/drivers_sample/dma/sample_dma_per_to_mem/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..80647198558dd73a00f4a1d45fc37a177fa9d4d7 --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_per_to_mem/init/main.c @@ -0,0 +1,59 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_dma_per_to_mem.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +DMA_Handle g_dmac; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + DMA_PeriphToMemoryIT(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_mem/init/main.h b/src/application/drivers_sample/dma/sample_dma_per_to_mem/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..dbd7661adcbb6ac3601d7d576af107c6b45f4fad --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_per_to_mem/init/main.h @@ -0,0 +1,42 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "crg.h" +#include "dma.h" + +extern UART_Handle g_uart0; + +extern DMA_Handle g_dmac; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_mem/init/system_init.c b/src/application/drivers_sample/dma/sample_dma_per_to_mem/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..7ad315dbd9cb8031c9fcd7bab718807547212b0c --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_per_to_mem/init/system_init.c @@ -0,0 +1,142 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg.h" + +#define UART0_BAND_RATE 115200 +#define CLK1M_Div 25 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 0x30; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (CLK1M_Div - 1); + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void DMA_Channel1Init(void) +{ + DMA_ChannelParam dma_param; + dma_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; /* Dma direction is memory to peripherals. */ + dma_param.srcAddrInc = DMA_ADDR_UNALTERED; /* Destination is peripherals, address does not increase. */ + dma_param.destAddrInc = DMA_ADDR_INCREASE; + dma_param.srcPeriph = DMA_REQUEST_UART0_RX; + dma_param.destPeriph = DMA_REQUEST_MEM; + dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; + dma_param.destWidth = DMA_TRANSWIDTH_BYTE; + dma_param.srcBurst = DMA_BURST_LENGTH_1; + dma_param.destBurst = DMA_BURST_LENGTH_1; + dma_param.pHandle = &g_uart0; + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ONE); /* Dma parameter init. */ +} + +static void DMA_Init(void) +{ + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); + g_dmac.baseAddress = DMA; + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); + IRQ_EnableN(IRQ_DMA_TC); + IRQ_EnableN(IRQ_DMA_ERR); + HAL_DMA_Init(&g_dmac); + DMA_Channel1Init(); + HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_ONE, DMA_PRIORITY_HIGHEST); +} + +__weak void DMA_PeriphToMemFinish(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_READ_DMA_FINISH */ + /* USER CODE END UART0_READ_DMA_FINISH */ +} + +__weak void UART0ReadInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_READ_IT_FINISH */ + /* USER CODE END UART0_READ_IT_FINISH */ +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_DMA; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE1; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE1; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); + g_uart0.dmaHandle = &g_dmac; + g_uart0.uartDmaRxChn = 1; /* 1 is UART_DMA rx channel */ + HAL_UART_RegisterCallBack(&g_uart0, UART_READ_DMA_FINISH, (UART_CallbackType)DMA_PeriphToMemFinish); + HAL_UART_RegisterCallBack(&g_uart0, UART_READ_IT_FINISH, (UART_CallbackType)UART0ReadInterruptCallback); +} + +static void IOConfig(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + DMA_Init(); + UART0_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_mem/readme.md b/src/application/drivers_sample/dma/sample_dma_per_to_mem/readme.md index 042f64d1334a9928ef2b91d1611cbcc8c6604b32..b10a28d2b1081412215cb5051723226b04141171 100644 --- a/src/application/drivers_sample/dma/sample_dma_per_to_mem/readme.md +++ b/src/application/drivers_sample/dma/sample_dma_per_to_mem/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。在串口助手上发送数据,DMA搬运结束后,会上报中断,在中断函数中打印传输完成log,查看数据是否正确。 **【注意事项】** -+ 如果要在串口助手上发送数据进行DMA搬运到内存,要设置外设为对应的uart串口。 \ No newline at end of file ++ 如果要在串口助手上发送数据进行DMA搬运到内存,要设置外设为对应的uart串口。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_mem/src/sample_dma_per_to_mem.c b/src/application/drivers_sample/dma/sample_dma_per_to_mem/src/sample_dma_per_to_mem.c index 845fe8fdc8d1bba7e8fa3f33bf2495b81fef41a8..678523dd8096c2d3026f6d8761c9a66a5bf082b4 100644 --- a/src/application/drivers_sample/dma/sample_dma_per_to_mem/src/sample_dma_per_to_mem.c +++ b/src/application/drivers_sample/dma/sample_dma_per_to_mem/src/sample_dma_per_to_mem.c @@ -24,40 +24,8 @@ #include "sample_dma_per_to_mem.h" #define NUM 10 -static UART_Handle g_uart; static unsigned char g_str2[NUM] = {0}; -static DMA_Handle g_dmac; -static DMA_ChannelParam g_param; - -/** - * @brief DMA controller initialization. - * @param None. - * @retval None. - */ -static void DMA_ControllerInit(void) -{ - g_dmac.baseAddress = DMA; - g_dmac.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.irqNumTc = IRQ_DMA_TC; - g_dmac.irqNumError = IRQ_DMA_ERR; - HAL_DMA_Init(&g_dmac); -} - -/** - * @brief DMA interrupt initialization. - * @param handle DMA handle. - * @retval None. - */ -static void DMA_InterruptInit(DMA_Handle *handle) -{ - IRQ_Enable(); - handle->irqNumTc = IRQ_DMA_TC; - handle->irqNumError = IRQ_DMA_ERR; - HAL_DMA_IRQService(handle); - IRQ_EnableN(IRQ_DMA_TC); - IRQ_EnableN(IRQ_DMA_ERR); -} +unsigned int g_channel = 1; /* select transfer channel 1 */ /** * @brief User-defined callback function for completing the transfer of peripheral to the memory. @@ -66,17 +34,18 @@ static void DMA_InterruptInit(DMA_Handle *handle) */ static void DMA_PeriphToMemFinish(void *handle) { - DMA_Handle *dmaHandle = (DMA_Handle *)handle; + UART_Handle *uart = (UART_Handle *)handle; + DMA_Handle *dmaHandle = uart->dmaHandle; DBG_PRINTF("Interrupt Finish!\r\n"); DBG_PRINTF("g_str2:%s\r\n", g_str2); - DBG_PRINTF("Process channel: %d\r\n", dmaHandle->currentChannel); + DBG_PRINTF("Process channel: %d\r\n", g_channel); unsigned int ret; - ret = HAL_DMA_StartIT(dmaHandle, (uintptr_t)(void *)&(g_uart.baseAddress->UART_DR), - (uintptr_t)(void *)g_str2, 8, dmaHandle->currentChannel); /* Transmission length is 8 */ + ret = HAL_DMA_StartIT(dmaHandle, (uintptr_t)(void *)&(g_uart0.baseAddress->UART_DR), + (uintptr_t)(void *)g_str2, 8, g_channel); /* Transmission length is 8 */ if (ret == BASE_STATUS_ERROR) { DBG_PRINTF("HAL_DMA_StartIT: BASE_STATUS_ERROR\r\n"); } else { - g_uart.baseAddress->UART_DMACR.BIT.rxdmae = BASE_CFG_ENABLE; + g_uart0.baseAddress->UART_DMACR.BIT.rxdmae = BASE_CFG_ENABLE; } } @@ -87,42 +56,18 @@ static void DMA_PeriphToMemFinish(void *handle) */ int DMA_PeriphToMemoryIT(void) { - g_uart.baseAddress = UART0; - g_uart.baudRate = 115200; /* baud rate is 115200 */ - g_uart.dataLength = UART_DATALENGTH_8BIT; - g_uart.stopBits = UART_STOPBITS_ONE; - g_uart.parity = UART_PARITY_NONE; - g_uart.fifoMode = true; - g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; - g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; - g_uart.hwFlowCtr = UART_HW_FLOWCTR_DISABLE; - g_uart.baseAddress = UART0; - HAL_UART_Init(&g_uart); - + SystemInit(); DBG_PRINTF("PeriphToMemory Begin: \r\n"); DBG_PRINTF("Please enter a string to the peripheral\r\n"); - unsigned int channel = 1; /* select transfer channel 1 */ - - DMA_ControllerInit(); - DMA_InterruptInit(&g_dmac); - HAL_DMA_RegisterCallback(&g_dmac, DMA_CHANNEL_FINISH, channel, DMA_PeriphToMemFinish); - g_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; - g_param.srcAddrInc = DMA_ADDR_UNALTERED; - g_param.destAddrInc = DMA_ADDR_INCREASE; - g_param.srcPeriph = DMA_REQUEST_UART0_RX; - g_param.srcWidth = DMA_TRANSWIDTH_BYTE; - g_param.destWidth = DMA_TRANSWIDTH_BYTE; - g_param.srcBurst = DMA_BURST_LENGTH_1; - g_param.destBurst = DMA_BURST_LENGTH_4; - g_param.pHandle = &g_dmac; - HAL_DMA_InitChannel(&g_dmac, &g_param, channel); + + HAL_DMA_RegisterCallback(&g_dmac, DMA_CHANNEL_FINISH, g_channel, DMA_PeriphToMemFinish); unsigned int ret; - ret = HAL_DMA_StartIT(&g_dmac, (uintptr_t)(void *)&(g_uart.baseAddress->UART_DR), - (uintptr_t)(void *)g_str2, 8, channel); /* The transmission length is defined as 8 */ + ret = HAL_DMA_StartIT(&g_dmac, (uintptr_t)(void *)&(g_uart0.baseAddress->UART_DR), + (uintptr_t)(void *)g_str2, 8, g_channel); /* The transmission length is defined as 8 */ if (ret == BASE_STATUS_ERROR) { DBG_PRINTF("HAL_DMA_StartIT: BASE_STATUS_ERROR\r\n"); } else { - g_uart.baseAddress->UART_DMACR.BIT.rxdmae = BASE_CFG_ENABLE; + g_uart0.baseAddress->UART_DMACR.BIT.rxdmae = BASE_CFG_ENABLE; } return 0; } \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_per/inc/sample_dma_per_to_per.h b/src/application/drivers_sample/dma/sample_dma_per_to_per/inc/sample_dma_per_to_per.h index 3c47024072c242dfb57494148ffd22781812dd3a..17beadb380e5a41610b2213c56b9dcc33488edbd 100644 --- a/src/application/drivers_sample/dma/sample_dma_per_to_per/inc/sample_dma_per_to_per.h +++ b/src/application/drivers_sample/dma/sample_dma_per_to_per/inc/sample_dma_per_to_per.h @@ -26,7 +26,7 @@ #include "dma.h" #include "debug.h" -#include "interrupt.h" +#include "main.h" int DMA_PeriphToPeriphIT(void); #endif \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_per/init/main.c b/src/application/drivers_sample/dma/sample_dma_per_to_per/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..77fa09f74dcc5a4db50b46355ebf32f93c4f3257 --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_per_to_per/init/main.c @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_dma_per_to_per.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +UART_Handle g_uart1; +DMA_Handle g_dmac; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + DMA_PeriphToPeriphIT(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_per/init/main.h b/src/application/drivers_sample/dma/sample_dma_per_to_per/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..69f71d253e434e3712eb0d40166d8560122a921e --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_per_to_per/init/main.h @@ -0,0 +1,42 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "crg.h" +#include "dma.h" + +extern UART_Handle g_uart0; +extern UART_Handle g_uart1; +extern DMA_Handle g_dmac; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_per/init/system_init.c b/src/application/drivers_sample/dma/sample_dma_per_to_per/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..48f77a0e94bf751f3baf17aa44549b3343d0ca5c --- /dev/null +++ b/src/application/drivers_sample/dma/sample_dma_per_to_per/init/system_init.c @@ -0,0 +1,174 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg.h" + +#define UART0_BAND_RATE 115200 +#define CLK1M_Div 25 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 0x30; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (CLK1M_Div - 1); + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void DMA_Channel0Init(void) +{ + DMA_ChannelParam dma_param; + dma_param.direction = DMA_PERIPH_TO_PERIPH_BY_DMAC; /* Dma direction is memory to peripherals. */ + dma_param.srcAddrInc = DMA_ADDR_UNALTERED; /* Destination is peripherals, address does not increase. */ + dma_param.destAddrInc = DMA_ADDR_UNALTERED; /* Destination is peripherals, address does not increase. */ + dma_param.srcPeriph = DMA_REQUEST_UART1_RX; + dma_param.destPeriph = DMA_REQUEST_UART0_TX; + dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; + dma_param.destWidth = DMA_TRANSWIDTH_BYTE; + dma_param.srcBurst = DMA_BURST_LENGTH_1; + dma_param.destBurst = DMA_BURST_LENGTH_1; + dma_param.pHandle = &g_dmac; + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ZERO); /* Dma parameter init. */ +} + +static void DMA_Init(void) +{ + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); + g_dmac.baseAddress = DMA; + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); + IRQ_EnableN(IRQ_DMA_TC); + IRQ_EnableN(IRQ_DMA_ERR); + HAL_DMA_Init(&g_dmac); + DMA_Channel0Init(); + HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_ZERO, DMA_PRIORITY_HIGHEST); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_DMA; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +__weak void UART1_RXDMACallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART1_READ_DMA_FINISH */ + /* USER CODE END UART1_READ_DMA_FINISH */ +} + +__weak void UART1ReadInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART1_READ_IT_FINISH */ + /* USER CODE END UART1_READ_IT_FINISH */ +} + +static void UART1_Init(void) +{ + HAL_CRG_IpEnableSet(UART1_BASE, IP_CLK_ENABLE); /* UART1 clock enable. */ + g_uart1.baseAddress = UART1; + + g_uart1.baudRate = UART1_BAND_RATE; + g_uart1.dataLength = UART_DATALENGTH_8BIT; + g_uart1.stopBits = UART_STOPBITS_ONE; + g_uart1.parity = UART_PARITY_NONE; + g_uart1.txMode = UART_MODE_BLOCKING; + g_uart1.rxMode = UART_MODE_DMA; /* UART rx use dma mode. */ + g_uart1.fifoMode = BASE_CFG_ENABLE; + g_uart1.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart1.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart1.hwFlowCtr = BASE_CFG_DISABLE; + g_uart1.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart1.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart1); /* UART parameter init. */ + g_uart1.dmaHandle = &g_dmac; + g_uart1.uartDmaRxChn = 0; /* 0 is UART_DMA rx channel */ + HAL_UART_RegisterCallBack(&g_uart1, UART_READ_DMA_FINISH, (UART_CallbackType)DMA_PeriToPeriFinish); + HAL_UART_RegisterCallBack(&g_uart1, UART_READ_IT_FINISH, (UART_CallbackType)UART1ReadInterruptCallback); +} + +static void IOConfig(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN22 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_4_AS_UART1_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_4_AS_UART1_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_4_AS_UART1_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_4_AS_UART1_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_4_AS_UART1_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN21 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_3_AS_UART1_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_3_AS_UART1_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_3_AS_UART1_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_3_AS_UART1_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_3_AS_UART1_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + DMA_Init(); + UART0_Init(); + UART1_Init(); + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_per/readme.md b/src/application/drivers_sample/dma/sample_dma_per_to_per/readme.md index b5fd1d2f7a5d8b9d09cdabe7d38e14599efca21f..77c95f89d4c46412ff475bc87abff40a0a4fe110 100644 --- a/src/application/drivers_sample/dma/sample_dma_per_to_per/readme.md +++ b/src/application/drivers_sample/dma/sample_dma_per_to_per/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。在串口助手上发送数据,DMA搬运结束后,会上报中断,在中断函数中打印传输完成log,此时在另一个串口助手上显示搬运完成的数据。 **【注意事项】** -+ 如果要在串口助手上发送数据到另一个串口助手上显示数据,要设置外设为对应的uart串口,比如其中一个串口助手连接uart tx,一个串口助手连接uart rx。 \ No newline at end of file ++ 如果要在串口助手上发送数据到另一个串口助手上显示数据,要设置外设为对应的uart串口,比如其中一个串口助手连接uart tx,一个串口助手连接uart rx。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/dma/sample_dma_per_to_per/src/sample_dma_per_to_per.c b/src/application/drivers_sample/dma/sample_dma_per_to_per/src/sample_dma_per_to_per.c index 523b36d4f466735ebd073949fcf20ebfff185497..94c890823505e5771807f1a5afd8f1375556db44 100644 --- a/src/application/drivers_sample/dma/sample_dma_per_to_per/src/sample_dma_per_to_per.c +++ b/src/application/drivers_sample/dma/sample_dma_per_to_per/src/sample_dma_per_to_per.c @@ -23,41 +23,6 @@ */ #include "sample_dma_per_to_per.h" -static UART_Handle g_uart1; -static UART_Handle g_uart0; -static DMA_Handle g_dmac; -static DMA_ChannelParam g_param; - -/** - * @brief DMA controller initialization. - * @param None. - * @retval None. - */ -static void DMA_ControllerInit(void) -{ - g_dmac.baseAddress = DMA; - g_dmac.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.irqNumTc = IRQ_DMA_TC; - g_dmac.irqNumError = IRQ_DMA_ERR; - HAL_DMA_Init(&g_dmac); -} - -/** - * @brief DMA interrupt initialization. - * @param handle DMA handle. - * @retval None. - */ -static void DMA_InterruptInit(DMA_Handle *handle) -{ - IRQ_Enable(); - handle->irqNumTc = IRQ_DMA_TC; - handle->irqNumError = IRQ_DMA_ERR; - HAL_DMA_IRQService(handle); - IRQ_EnableN(IRQ_DMA_TC); - IRQ_EnableN(IRQ_DMA_ERR); -} - /** * @brief User-defined callback function for completing the transfer of peripheral to the peripheral. * @param handle callback handle. @@ -76,44 +41,11 @@ static void DMA_PeriToPeriFinish(void *handle) */ int DMA_PeriphToPeriphIT(void) { - g_uart0.baseAddress = UART0; - g_uart0.baudRate = 115200; /* baud rate is 115200 */ - g_uart0.dataLength = UART_DATALENGTH_8BIT; - g_uart0.stopBits = UART_STOPBITS_ONE; - g_uart0.parity = UART_PARITY_NONE; - g_uart0.fifoMode = true; - g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; - g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; - g_uart0.hwFlowCtr = UART_HW_FLOWCTR_DISABLE; - HAL_UART_Init(&g_uart0); - - g_uart1.baseAddress = UART1; - g_uart1.baudRate = 115200; /* baud rate is 115200 */ - g_uart1.dataLength = UART_DATALENGTH_8BIT; - g_uart1.stopBits = UART_STOPBITS_ONE; - g_uart1.parity = UART_PARITY_NONE; - g_uart1.fifoMode = true; - g_uart1.fifoTxThr = UART_FIFOFULL_ONE_TWO; - g_uart1.fifoRxThr = UART_FIFOFULL_ONE_TWO; - g_uart1.hwFlowCtr = UART_HW_FLOWCTR_DISABLE; - HAL_UART_Init(&g_uart1); - + SystemInit(); DBG_PRINTF("PeriphToPeriph Begin: \r\n"); unsigned int channel = 0; /* select transfer channel 0 */ - DMA_ControllerInit(); - DMA_InterruptInit(&g_dmac); HAL_DMA_RegisterCallback(&g_dmac, DMA_CHANNEL_FINISH, channel, DMA_PeriToPeriFinish); - g_param.direction = DMA_PERIPH_TO_PERIPH_BY_DMAC; - g_param.srcAddrInc = DMA_ADDR_UNALTERED; - g_param.destAddrInc = DMA_ADDR_UNALTERED; - g_param.destPeriph = DMA_REQUEST_UART0_TX; - g_param.srcPeriph = DMA_REQUEST_UART1_RX; - g_param.srcWidth = DMA_TRANSWIDTH_BYTE; - g_param.destWidth = DMA_TRANSWIDTH_BYTE; - g_param.srcBurst = DMA_BURST_LENGTH_1; - g_param.destBurst = DMA_BURST_LENGTH_1; - g_param.pHandle = &g_dmac; - HAL_DMA_InitChannel(&g_dmac, &g_param, channel); + unsigned int ret; ret = HAL_DMA_StartIT(&g_dmac, (uintptr_t)(void *)&(g_uart1.baseAddress->UART_DR), (uintptr_t)(void *)&(g_uart0.baseAddress->UART_DR), 8, channel); /* Tx length is 8 */ diff --git a/src/application/drivers_sample/flash/sample_flash_blocking/init/main.h b/src/application/drivers_sample/flash/sample_flash_blocking/init/main.h index e9b54f86f96c0d381bc6b68c4680a793cc1991ad..4d9eb3456405abe0818918379a29b681c11ddf03 100644 --- a/src/application/drivers_sample/flash/sample_flash_blocking/init/main.h +++ b/src/application/drivers_sample/flash/sample_flash_blocking/init/main.h @@ -35,6 +35,11 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); diff --git a/src/application/drivers_sample/flash/sample_flash_blocking/init/system_init.c b/src/application/drivers_sample/flash/sample_flash_blocking/init/system_init.c index 12a1fff57d312469ee3866bf0a3bcf07dbc5da49..331125b24a80611352a1ea577d7378dced26bd9f 100644 --- a/src/application/drivers_sample/flash/sample_flash_blocking/init/system_init.c +++ b/src/application/drivers_sample/flash/sample_flash_blocking/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -47,7 +49,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -64,21 +65,18 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/flash/sample_flash_blocking/readme.md b/src/application/drivers_sample/flash/sample_flash_blocking/readme.md index be9fffa7a6f89c4a09050a5b7c63969e1c7e19c8..2a446fa536f6349e63a316cbf332ecac00bb95b2 100644 --- a/src/application/drivers_sample/flash/sample_flash_blocking/readme.md +++ b/src/application/drivers_sample/flash/sample_flash_blocking/readme.md @@ -1,5 +1,5 @@ # 配置FLASH以阻塞方式进行擦除、写入,通过Debug串口打印读取的操作数据 -## 关键字: FLASH, 擦除,写入,读取,阻塞方式 +## 关键字: FLASH,擦除,写入,读取,阻塞方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、FLASH控制器初始化和功能配置。通过阻塞方式对FLASH的PAGE 15区域进行擦除、写入操作,通过Debug串口打印读取的操作数据。 @@ -16,4 +16,7 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 对FLASH进行擦除和写操作时需谨慎操作,避免对存放运行程序代码的分区进行擦、写操作,否则会导致运行出错。 \ No newline at end of file ++ 对FLASH进行擦除和写操作时需谨慎操作,避免对存放运行程序代码的分区进行擦、写操作,否则会导致运行出错。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/flash/sample_flash_blocking_mode/init/main.h b/src/application/drivers_sample/flash/sample_flash_blocking_mode/init/main.h index 4d9eb3456405abe0818918379a29b681c11ddf03..6a6d33b84615709b59a3387230b51936ea108ff1 100644 --- a/src/application/drivers_sample/flash/sample_flash_blocking_mode/init/main.h +++ b/src/application/drivers_sample/flash/sample_flash_blocking_mode/init/main.h @@ -25,7 +25,9 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U diff --git a/src/application/drivers_sample/flash/sample_flash_blocking_mode/init/system_init.c b/src/application/drivers_sample/flash/sample_flash_blocking_mode/init/system_init.c index 85672d703bc55c46363b6200e5b4d3c203947c05..2eb2711c6d7df4c918562bc75184734da3bf136e 100644 --- a/src/application/drivers_sample/flash/sample_flash_blocking_mode/init/system_init.c +++ b/src/application/drivers_sample/flash/sample_flash_blocking_mode/init/system_init.c @@ -33,13 +33,14 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ - /* Initialize the clock configuration. */ if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -49,9 +50,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - /* UART-related parameter configuration. */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ @@ -72,17 +71,17 @@ static void UART0_Init(void) static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/flash/sample_flash_blocking_mode/readme.md b/src/application/drivers_sample/flash/sample_flash_blocking_mode/readme.md index 63ca3f06f9c208be4bbb7e721dd4a983da14f808..cf6a4d0924c2fb3e523c8df3ada2793aea090748 100644 --- a/src/application/drivers_sample/flash/sample_flash_blocking_mode/readme.md +++ b/src/application/drivers_sample/flash/sample_flash_blocking_mode/readme.md @@ -1,5 +1,5 @@ # 配置FLASH以阻塞方式进行擦除、写入,通过Debug串口打印读取的操作数据 -## 关键字: FLASH, 擦除,写入,读取,阻塞方式 +## 关键字: FLASH,擦除,写入,读取,阻塞方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、FLASH控制器初始化和功能配置。通过阻塞方式对FLASH的PAGE 58-61区域进行擦除、写入操作,通过Debug串口打印读取的操作数据。 @@ -16,4 +16,7 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 对FLASH进行擦除和写操作时需谨慎操作,避免对存放运行程序代码的分区进行擦、写操作,否则会导致运行出错。 \ No newline at end of file ++ 对FLASH进行擦除和写操作时需谨慎操作,避免对存放运行程序代码的分区进行擦、写操作,否则会导致运行出错。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/flash/sample_flash_interrupt/init/main.h b/src/application/drivers_sample/flash/sample_flash_interrupt/init/main.h index e9b54f86f96c0d381bc6b68c4680a793cc1991ad..4d9eb3456405abe0818918379a29b681c11ddf03 100644 --- a/src/application/drivers_sample/flash/sample_flash_interrupt/init/main.h +++ b/src/application/drivers_sample/flash/sample_flash_interrupt/init/main.h @@ -35,6 +35,11 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); diff --git a/src/application/drivers_sample/flash/sample_flash_interrupt/init/system_init.c b/src/application/drivers_sample/flash/sample_flash_interrupt/init/system_init.c index 12a1fff57d312469ee3866bf0a3bcf07dbc5da49..331125b24a80611352a1ea577d7378dced26bd9f 100644 --- a/src/application/drivers_sample/flash/sample_flash_interrupt/init/system_init.c +++ b/src/application/drivers_sample/flash/sample_flash_interrupt/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -47,7 +49,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -64,21 +65,18 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/flash/sample_flash_interrupt/readme.md b/src/application/drivers_sample/flash/sample_flash_interrupt/readme.md index 724032ac9a7c89a689287ea84b957a50cefe7a77..98f9a4d5ad895c5c5b41f339ce0a228a1f211d30 100644 --- a/src/application/drivers_sample/flash/sample_flash_interrupt/readme.md +++ b/src/application/drivers_sample/flash/sample_flash_interrupt/readme.md @@ -1,5 +1,5 @@ # 配置FLASH以中断方式进行擦除、写入,通过Debug串口打印读取操作数据 -## 关键字: FLASH, 擦除,写入,读取,中断方式 +## 关键字: FLASH,擦除,写入,读取,中断方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、FLASH控制器初始化和功能配置。通过中断方式对FLASH的PAGE 15区域进行擦除、写入,通过Debug串口打印读取的操作数据。 @@ -16,4 +16,7 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 对FLASH进行擦除和写操作时需谨慎操作,避免对存放运行程序代码的分区进行擦、写操作,否则会导致运行出错。 \ No newline at end of file ++ 对FLASH进行擦除和写操作时需谨慎操作,避免对存放运行程序代码的分区进行擦、写操作,否则会导致运行出错。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/flash/sample_flash_interrupt_mode/init/main.h b/src/application/drivers_sample/flash/sample_flash_interrupt_mode/init/main.h index 4d9eb3456405abe0818918379a29b681c11ddf03..6a6d33b84615709b59a3387230b51936ea108ff1 100644 --- a/src/application/drivers_sample/flash/sample_flash_interrupt_mode/init/main.h +++ b/src/application/drivers_sample/flash/sample_flash_interrupt_mode/init/main.h @@ -25,7 +25,9 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U diff --git a/src/application/drivers_sample/flash/sample_flash_interrupt_mode/init/system_init.c b/src/application/drivers_sample/flash/sample_flash_interrupt_mode/init/system_init.c index 76d16b56df8366cdbf94dbe0cb95118528889db7..2eb2711c6d7df4c918562bc75184734da3bf136e 100644 --- a/src/application/drivers_sample/flash/sample_flash_interrupt_mode/init/system_init.c +++ b/src/application/drivers_sample/flash/sample_flash_interrupt_mode/init/system_init.c @@ -33,12 +33,14 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; - /* Initialize the clock configuration. */ + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -48,9 +50,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - /* UART-related parameter configuration. */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ @@ -71,17 +71,17 @@ static void UART0_Init(void) static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/flash/sample_flash_interrupt_mode/readme.md b/src/application/drivers_sample/flash/sample_flash_interrupt_mode/readme.md index ab52ee138179a35221cf3270176d50e52eeb40b6..d7e0c6f8ebe6cd1a825faef2d4c271adfc38052b 100644 --- a/src/application/drivers_sample/flash/sample_flash_interrupt_mode/readme.md +++ b/src/application/drivers_sample/flash/sample_flash_interrupt_mode/readme.md @@ -1,5 +1,5 @@ # 配置FLASH以中断方式进行擦除、写入,通过Debug串口打印读取操作数据 -## 关键字: FLASH, 擦除,写入,读取,中断方式 +## 关键字: FLASH,擦除,写入,读取,中断方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、FLASH控制器初始化和功能配置。通过中断方式对FLASH的PAGE 58-61区域进行擦除、写入,通过Debug串口打印读取的操作数据。 @@ -16,4 +16,7 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 对FLASH进行擦除和写操作时需谨慎操作,避免对存放运行程序代码的分区进行擦、写操作,否则会导致运行出错。 \ No newline at end of file ++ 对FLASH进行擦除和写操作时需谨慎操作,避免对存放运行程序代码的分区进行擦、写操作,否则会导致运行出错。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_circle/init/main.c b/src/application/drivers_sample/gpio/sample_gpio_circle/init/main.c index ad37d3921d0c68cf9c1879a3a03888976c2dfe63..97fd19e1d370337c5b15c7086b27eba6def7570b 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_circle/init/main.c +++ b/src/application/drivers_sample/gpio/sample_gpio_circle/init/main.c @@ -19,19 +19,42 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "gpio_circle_sample.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ UART_Handle g_uart0; - -GPIO_Handle g_targetHandle; -GPIO_Handle g_refHandle; +GPIO_Handle g_gpio1; +GPIO_Handle g_gpio2; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ GPIO_CircleSample(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_circle/init/main.h b/src/application/drivers_sample/gpio/sample_gpio_circle/init/main.h index 98e52e3b270d841a584286e77154db725f197013..ed540ec72d4788d9529b4e23be00c05b497a8364 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_circle/init/main.h +++ b/src/application/drivers_sample/gpio/sample_gpio_circle/init/main.h @@ -36,12 +36,26 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +#define REF_PIN GPIO_PIN_0 +#define REF_HANDLE g_gpio1 +#define TARGET_PIN GPIO_PIN_0 +#define TARGET_HANDLE g_gpio2 + extern UART_Handle g_uart0; -extern GPIO_Handle g_targetHandle; -extern GPIO_Handle g_refHandle; +extern GPIO_Handle g_gpio1; +extern GPIO_Handle g_gpio2; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_circle/init/system_init.c b/src/application/drivers_sample/gpio/sample_gpio_circle/init/system_init.c index a5edf0d675bbf62c4ee9ed7a6d7d2c52d427f33b..38cdaa225e598e660aa62668a081d54bd4d1f640 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_circle/init/system_init.c +++ b/src/application/drivers_sample/gpio/sample_gpio_circle/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -43,21 +45,23 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void GPIO_Init(void) { - HAL_CRG_IpEnableSet(GPIO0_BASE, IP_CLK_ENABLE); - g_targetHandle.baseAddress = GPIO2; /* GPIO group */ - g_targetHandle.dir = GPIO_INPUT_MODE; - g_targetHandle.value = GPIO_LOW_LEVEL; - g_targetHandle.interruptMode = GPIO_INT_TYPE_NONE; - g_targetHandle.pins = GPIO_PIN_0; /* PIN in group */ - HAL_GPIO_Init(&g_targetHandle); - HAL_CRG_IpEnableSet(GPIO1_BASE, IP_CLK_ENABLE); - g_refHandle.baseAddress = GPIO1; /* GPIO group */ - g_refHandle.dir = GPIO_OUTPUT_MODE; - g_refHandle.value = GPIO_LOW_LEVEL; - g_refHandle.interruptMode = GPIO_INT_TYPE_NONE; - g_refHandle.pins = GPIO_PIN_0; /* PIN in group */ - HAL_GPIO_Init(&g_refHandle); + g_gpio1.baseAddress = GPIO1; + g_gpio1.pins = GPIO_PIN_0; + HAL_GPIO_Init(&g_gpio1); + HAL_GPIO_SetDirection(&g_gpio1, g_gpio1.pins, GPIO_INPUT_MODE); /* Set gpio direction. */ + HAL_GPIO_SetValue(&g_gpio1, g_gpio1.pins, GPIO_LOW_LEVEL); /* Set gpio pin value. */ + HAL_GPIO_SetIrqType(&g_gpio1, g_gpio1.pins, GPIO_INT_TYPE_NONE); /* Set gpio pin irp type. */ + + HAL_CRG_IpEnableSet(GPIO2_BASE, IP_CLK_ENABLE); + g_gpio2.baseAddress = GPIO2; + g_gpio2.pins = GPIO_PIN_0; + HAL_GPIO_Init(&g_gpio2); + HAL_GPIO_SetDirection(&g_gpio2, g_gpio2.pins, GPIO_INPUT_MODE); /* Set gpio direction. */ + HAL_GPIO_SetValue(&g_gpio2, g_gpio2.pins, GPIO_LOW_LEVEL); /* Set gpio pin value. */ + HAL_GPIO_SetIrqType(&g_gpio2, g_gpio2.pins, GPIO_INT_TYPE_NONE); /* Set gpio pin irp type. */ + + return; } static void UART0_Init(void) @@ -66,7 +70,7 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; @@ -82,35 +86,30 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_0.BIT.func = 0x0; /* 0x0 is GPIO0_0 */ - iconfig->iocmg_0.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_0.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_0.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_0.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_0.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_11.BIT.func = 0x0; /* 0x0 is GPIO1_0 */ - iconfig->iocmg_11.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_11.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_11.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_11.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_11.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO57_AS_GPIO1_0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO57_AS_GPIO1_0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO57_AS_GPIO1_0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO57_AS_GPIO1_0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO57_AS_GPIO1_0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO3_AS_GPIO2_0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO3_AS_GPIO2_0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO3_AS_GPIO2_0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO3_AS_GPIO2_0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO3_AS_GPIO2_0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -118,6 +117,7 @@ void SystemInit(void) IOConfig(); UART0_Init(); GPIO_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_circle/readme.md b/src/application/drivers_sample/gpio/sample_gpio_circle/readme.md index 796e8f3f23433dbd85017993a16c3807e1c7b3ef..9bcf200c94a3b121b2e773c129106b4f31959259 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_circle/readme.md +++ b/src/application/drivers_sample/gpio/sample_gpio_circle/readme.md @@ -19,4 +19,7 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 示例代码中使用GPIO两个管脚需连接在一起。 \ No newline at end of file ++ 示例代码中使用GPIO两个管脚需连接在一起。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/main.c b/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/main.c index cafa0bdc1f354f6fbd5b01ef33c5350a24560d6f..c156c3a87d056a463bcbf80cf67fc881f4a429c0 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/main.c +++ b/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/main.c @@ -19,19 +19,42 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "gpio_interrupt_sample.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ UART_Handle g_uart0; - -GPIO_Handle g_intHandle; -GPIO_Handle g_trigHandle; +GPIO_Handle g_gpio2; +GPIO_Handle g_gpio1; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ GPIO_InterruptSample(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/main.h b/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/main.h index e95bdb34e1dc0c1410240da91c032892540a36e1..770f711e14e9ccfa33b34ccdc60ef0c6f7ca6ed5 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/main.h +++ b/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/main.h @@ -36,14 +36,28 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +#define TRIG_PIN GPIO_PIN_0 +#define TRIG_HANDLE g_gpio2 +#define INT_PIN GPIO_PIN_2 +#define INT_HANDLE g_gpio1 + extern UART_Handle g_uart0; -extern GPIO_Handle g_intHandle; -extern GPIO_Handle g_trigHandle; +extern GPIO_Handle g_gpio2; +extern GPIO_Handle g_gpio1; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); void GPIO_CallBackFunc(void *param); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/system_init.c b/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/system_init.c index e8fd3a6f7d6f5bae21551ce66a812ee6fd1372be..e00883e6b75cd8227f47774e04bb5b4014bb3e49 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/system_init.c +++ b/src/application/drivers_sample/gpio/sample_gpio_interrupt/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,34 +46,38 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) __weak void GPIO_CallBackFunc(void *param) { GPIO_Handle *handle = (GPIO_Handle *)param; - /* USER CODE BEGIN GPIO_CallBackFunc */ - /* USER CODE END GPIO_CallBackFunc */ BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN GPIO_CB_ID */ + /* USER CODE END GPIO_CB_ID */ } static void GPIO_Init(void) { + /* Basic GPIO Configuration, include dierection, value, irq type. */ HAL_CRG_IpEnableSet(GPIO2_BASE, IP_CLK_ENABLE); - g_trigHandle.baseAddress = GPIO2; - g_trigHandle.dir = GPIO_OUTPUT_MODE; - g_trigHandle.value = GPIO_LOW_LEVEL; - g_trigHandle.interruptMode = GPIO_INT_TYPE_NONE; - g_trigHandle.pins = GPIO_PIN_0; - HAL_GPIO_Init(&g_trigHandle); + g_gpio2.baseAddress = GPIO2; + g_gpio2.pins = GPIO_PIN_0; + HAL_GPIO_Init(&g_gpio2); + HAL_GPIO_SetDirection(&g_gpio2, g_gpio2.pins, GPIO_OUTPUT_MODE); + HAL_GPIO_SetValue(&g_gpio2, g_gpio2.pins, GPIO_LOW_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio2, g_gpio2.pins, GPIO_INT_TYPE_NONE); + /* Basic GPIO Configuration, include dierection, value, irq type. */ HAL_CRG_IpEnableSet(GPIO1_BASE, IP_CLK_ENABLE); - g_intHandle.baseAddress = GPIO1; - g_intHandle.dir = GPIO_INPUT_MODE; - g_intHandle.value = GPIO_LOW_LEVEL; - g_intHandle.interruptMode = GPIO_INT_TYPE_HIGH_LEVEL; - g_intHandle.pins = GPIO_PIN_0; - HAL_GPIO_Init(&g_intHandle); + g_gpio1.baseAddress = GPIO1; + g_gpio1.pins = GPIO_PIN_2; + HAL_GPIO_Init(&g_gpio1); + HAL_GPIO_SetDirection(&g_gpio1, g_gpio1.pins, GPIO_INPUT_MODE); + HAL_GPIO_SetValue(&g_gpio1, g_gpio1.pins, GPIO_LOW_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio1, g_gpio1.pins, GPIO_INT_TYPE_HIGH_LEVEL); + /* Register callback functions to be defined by users. */ - HAL_GPIO_RegisterCallBack(&g_intHandle, GPIO_PIN_0, GPIO_CallBackFunc); - g_intHandle.irqNum = IRQ_GPIO1; - HAL_GPIO_IRQService(&g_intHandle); /* Associating irqNum with Callbacks */ - IRQ_SetPriority(g_intHandle.irqNum, 1); /* set gpio1 interrupt priority to 1, 1~7 */ - IRQ_EnableN(g_intHandle.irqNum); /* gpio interrupt enable */ + HAL_GPIO_RegisterCallBack(&g_gpio1, GPIO_PIN_2, GPIO_CallBackFunc); + IRQ_Register(IRQ_GPIO1, HAL_GPIO_IrqHandler, &g_gpio1); + IRQ_SetPriority(IRQ_GPIO1, 1); /* set gpio1 interrupt priority to 1, 1~7. 1 */ + IRQ_EnableN(IRQ_GPIO1); /* gpio interrupt enable */ + + return; } static void UART0_Init(void) @@ -80,7 +86,7 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; @@ -96,35 +102,30 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_11.BIT.func = 0x0; /* 0x0 is GPIO1_0 */ - iconfig->iocmg_11.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_11.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_11.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_11.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_11.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_19.BIT.func = 0x0; /* 0x0 is GPIO2_0 */ - iconfig->iocmg_19.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_19.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_19.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_19.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_19.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO3_AS_GPIO2_0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO3_AS_GPIO2_0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO3_AS_GPIO2_0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO3_AS_GPIO2_0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO3_AS_GPIO2_0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO59_AS_GPIO1_2); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO59_AS_GPIO1_2, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO59_AS_GPIO1_2, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO59_AS_GPIO1_2, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO59_AS_GPIO1_2, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -132,6 +133,7 @@ void SystemInit(void) IOConfig(); UART0_Init(); GPIO_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_interrupt/readme.md b/src/application/drivers_sample/gpio/sample_gpio_interrupt/readme.md index 21a7f2bc38158c558a5ba2da40705dbcfb7a155a..12d1e67a720577ffe19da94c0d86eb07d4572161 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_interrupt/readme.md +++ b/src/application/drivers_sample/gpio/sample_gpio_interrupt/readme.md @@ -19,4 +19,7 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 示例代码中使用GPIO两个管脚需连接在一起。 \ No newline at end of file ++ 示例代码中使用GPIO两个管脚需连接在一起。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_interrupt/src/gpio_interrupt_sample.c b/src/application/drivers_sample/gpio/sample_gpio_interrupt/src/gpio_interrupt_sample.c index c5e8077266d59d2def693ad5c0cae12f59303e8d..71822e49b04364b05d88f4871bc46a8f015529f3 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_interrupt/src/gpio_interrupt_sample.c +++ b/src/application/drivers_sample/gpio/sample_gpio_interrupt/src/gpio_interrupt_sample.c @@ -109,6 +109,7 @@ static void GPIO_InterruptTest(void) HAL_GPIO_SetValue(&TRIG_HANDLE, TRIG_PIN, GPIO_LOW_LEVEL); /* Provide rise level trig condition */ BASE_FUNC_DELAY_MS(GPIO_LEVEL_SHIFT_SAFE_TIME); HAL_GPIO_SetValue(&TRIG_HANDLE, TRIG_PIN, GPIO_HIGH_LEVEL); + BASE_FUNC_DELAY_MS(GPIO_LEVEL_SHIFT_SAFE_TIME); CheckGpioIntState(); /* Test fall level interrupt type */ DBG_PRINTF(" Test fall level interrupt type : trig GPIO -> int GPIO falling edge-------------------- "); diff --git a/src/application/drivers_sample/gpio/sample_gpio_key/init/main.c b/src/application/drivers_sample/gpio/sample_gpio_key/init/main.c index f0e073cb1a0ca33975c38f47e07a27ba968efdac..0f5e9f92232e9ed037138b6a3d35aa7c62564c89 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_key/init/main.c +++ b/src/application/drivers_sample/gpio/sample_gpio_key/init/main.c @@ -19,18 +19,41 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "gpio_key_sample.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ UART_Handle g_uart0; - -GPIO_Handle g_keyHandle; +GPIO_Handle g_gpio3; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ GPIO_KeySample(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_key/init/main.h b/src/application/drivers_sample/gpio/sample_gpio_key/init/main.h index fc21f4530a21b8217d5d3689a40718cd9357ce9c..79292245504468e2aff96320653dfe636d4f5fa7 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_key/init/main.h +++ b/src/application/drivers_sample/gpio/sample_gpio_key/init/main.h @@ -36,13 +36,25 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +#define KEY_PIN GPIO_PIN_0 +#define KEY_HANDLE g_gpio3 + extern UART_Handle g_uart0; -extern GPIO_Handle g_keyHandle; +extern GPIO_Handle g_gpio3; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); void GPIO_CallBackFunc(void *param); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_key/init/system_init.c b/src/application/drivers_sample/gpio/sample_gpio_key/init/system_init.c index 7f07ca92a0919dc9cd905e7c13c31c3ab848dbbc..f62681954df93060464d63386c8722b71b3e0b42 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_key/init/system_init.c +++ b/src/application/drivers_sample/gpio/sample_gpio_key/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,34 +46,38 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) __weak void GPIO_CallBackFunc(void *param) { GPIO_Handle *handle = (GPIO_Handle *)param; - /* USER CODE BEGIN GPIO_CallBackFunc */ - /* USER CODE END GPIO_CallBackFunc */ BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN GPIO_CB_ID */ + /* USER CODE END GPIO_CB_ID */ } static void GPIO_Init(void) { + /* Basic GPIO Configuration, include dierection, value, irq type. */ HAL_CRG_IpEnableSet(GPIO3_BASE, IP_CLK_ENABLE); - g_keyHandle.baseAddress = GPIO3; - g_keyHandle.dir = GPIO_INPUT_MODE; - g_keyHandle.value = GPIO_LOW_LEVEL; - g_keyHandle.interruptMode = GPIO_INT_TYPE_RISE_EDGE; - g_keyHandle.pins = GPIO_PIN_0; - HAL_GPIO_Init(&g_keyHandle); + g_gpio3.baseAddress = GPIO3; + g_gpio3.pins = GPIO_PIN_0; + HAL_GPIO_Init(&g_gpio3); + HAL_GPIO_SetDirection(&g_gpio3, g_gpio3.pins, GPIO_INPUT_MODE); + HAL_GPIO_SetValue(&g_gpio3, g_gpio3.pins, GPIO_LOW_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio3, g_gpio3.pins, GPIO_INT_TYPE_RISE_EDGE); + /* Register callback functions to be defined by users. */ - HAL_GPIO_RegisterCallBack(&g_keyHandle, GPIO_PIN_0, GPIO_CallBackFunc); - g_keyHandle.irqNum = IRQ_GPIO3; - HAL_GPIO_IRQService(&g_keyHandle); - IRQ_SetPriority(g_keyHandle.irqNum, 1); /* set gpio1 interrupt priority to 1, 1~7 */ - IRQ_EnableN(g_keyHandle.irqNum); /* gpio interrupt enable */ + HAL_GPIO_RegisterCallBack(&g_gpio3, GPIO_PIN_0, GPIO_CallBackFunc); + IRQ_Register(IRQ_GPIO3, HAL_GPIO_IrqHandler, &g_gpio3); + IRQ_SetPriority(IRQ_GPIO3, 1); /* set gpio1 interrupt priority to 1, 1~7. 1 */ + IRQ_EnableN(IRQ_GPIO3); /* gpio interrupt enable */ + + return; } static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); + g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; @@ -87,28 +93,24 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_27.BIT.func = 0x0; /* 0x0 is GPIO3_0 */ - iconfig->iocmg_27.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_27.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_27.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_27.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_27.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO11_AS_GPIO3_0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO11_AS_GPIO3_0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO11_AS_GPIO3_0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO11_AS_GPIO3_0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO11_AS_GPIO3_0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -116,6 +118,7 @@ void SystemInit(void) IOConfig(); UART0_Init(); GPIO_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_key/readme.md b/src/application/drivers_sample/gpio/sample_gpio_key/readme.md index 93ceff618d2d1002b231f0fc608842bc28f63717..a62ac4ae4eafc76c4d9db6694ae483535e651c22 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_key/readme.md +++ b/src/application/drivers_sample/gpio/sample_gpio_key/readme.md @@ -14,4 +14,7 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 示例代码中使用的GPIO管脚需和按键连接在一起。 \ No newline at end of file ++ 示例代码中使用的GPIO管脚需和按键连接在一起。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_led/init/main.c b/src/application/drivers_sample/gpio/sample_gpio_led/init/main.c index 923c56289d1bf528d3c4d6db1bc776d23e21b079..6c7532a26e17c97a1b24b642a5d0e91f81c19799 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_led/init/main.c +++ b/src/application/drivers_sample/gpio/sample_gpio_led/init/main.c @@ -19,18 +19,41 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "gpio_led_sample.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ UART_Handle g_uart0; - -GPIO_Handle g_ledHandle; +GPIO_Handle g_gpio5; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ GPIO_LedSample(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_led/init/main.h b/src/application/drivers_sample/gpio/sample_gpio_led/init/main.h index d871dfc85077409ba7594ddd09f8db2b71b8bed3..66ff1e238109d2047f7a87551ff7754219e1aa4d 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_led/init/main.h +++ b/src/application/drivers_sample/gpio/sample_gpio_led/init/main.h @@ -36,11 +36,23 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +#define LED_PIN GPIO_PIN_6 +#define LED_HANDLE g_gpio5 + extern UART_Handle g_uart0; -extern GPIO_Handle g_ledHandle; +extern GPIO_Handle g_gpio5; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_led/init/system_init.c b/src/application/drivers_sample/gpio/sample_gpio_led/init/system_init.c index 4b0457d1035fba109117f9f0bfed65c15727c692..fa0a5e6baff6a1a434bbc0d331b78b5fca110a18 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_led/init/system_init.c +++ b/src/application/drivers_sample/gpio/sample_gpio_led/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,13 +46,14 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void GPIO_Init(void) { HAL_CRG_IpEnableSet(GPIO5_BASE, IP_CLK_ENABLE); - g_ledHandle.baseAddress = GPIO5; /* can be config by ide */ + g_gpio5.baseAddress = GPIO5; + g_gpio5.pins = GPIO_PIN_6; + HAL_GPIO_Init(&g_gpio5); + HAL_GPIO_SetDirection(&g_gpio5, g_gpio5.pins, GPIO_OUTPUT_MODE); /* Set gpio direction. */ + HAL_GPIO_SetValue(&g_gpio5, g_gpio5.pins, GPIO_LOW_LEVEL); /* Set gpio pin value. */ + HAL_GPIO_SetIrqType(&g_gpio5, g_gpio5.pins, GPIO_INT_TYPE_NONE); /* Set gpio pin irp type. */ - g_ledHandle.dir = GPIO_OUTPUT_MODE; - g_ledHandle.value = GPIO_HIGH_LEVEL; - g_ledHandle.interruptMode = GPIO_INT_TYPE_NONE; - g_ledHandle.pins = GPIO_PIN_6; /* can be config by ide */ - HAL_GPIO_Init(&g_ledHandle); + return; } static void UART0_Init(void) @@ -59,7 +62,7 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; @@ -75,28 +78,24 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; + HAL_IOCMG_SetPinAltFuncMode(IO32_AS_GPIO5_6); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO32_AS_GPIO5_6, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO32_AS_GPIO5_6, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO32_AS_GPIO5_6, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO32_AS_GPIO5_6, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_49.BIT.func = 0x0; /* 0x0 is GPIO5_6 */ - iconfig->iocmg_49.BIT.ds = IO_DRV_LEVEL1; - iconfig->iocmg_49.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_49.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_49.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_49.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -104,6 +103,7 @@ void SystemInit(void) IOConfig(); UART0_Init(); GPIO_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/gpio/sample_gpio_led/readme.md b/src/application/drivers_sample/gpio/sample_gpio_led/readme.md index 048b5964410aba12da1c2a2be7d990c2923a3280..d703a3721cf1474d31fa3e1110aeeac4fb7d0755 100644 --- a/src/application/drivers_sample/gpio/sample_gpio_led/readme.md +++ b/src/application/drivers_sample/gpio/sample_gpio_led/readme.md @@ -9,11 +9,14 @@ + GPIO管脚初始化:调用接口"HAL_GPIO_Init()”完成对示例代码中GPIO管脚的方向、电平、中断模式配置。 -+ GPIO管脚实现对LED灯控制:对于输出管脚调用接口"HAL_GPIO_TogglePin()"实现管脚电平翻转,结合延时函数实现GPIO管脚控制LED灯每50ms亮灭状态反转一次。 ++ GPIO管脚实现对LED灯控制:对于输出管脚调用接口"HAL_GPIO_TogglePin()"实现管脚电平翻转,结合延时函数实现GPIO管脚控制LED灯每500ms亮灭状态反转一次。 **【示例效果】** -+ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中会控制GPIO管脚连接的LED每50ms进行一次亮灭,每反转一次电平Debug串口会打印一条信息。 ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中会控制GPIO管脚连接的LED每500ms进行一次亮灭,每反转一次电平Debug串口会打印一条信息。 **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 示例代码中使用的GPIO管脚需和LED灯连接在一起。 \ No newline at end of file ++ 示例代码中使用的GPIO管脚需和LED灯连接在一起。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/gpt/sample_gpt_period_interrupt/readme.md b/src/application/drivers_sample/gpt/sample_gpt_period_interrupt/readme.md index eb7814a2b25d5b29bcd325d5ce2eb6a1b4b6c001..622f0a65e5111a07e10973c4b234703231207639 100644 --- a/src/application/drivers_sample/gpt/sample_gpt_period_interrupt/readme.md +++ b/src/application/drivers_sample/gpt/sample_gpt_period_interrupt/readme.md @@ -2,23 +2,20 @@ ## 关键字: PWM, 周期中断 **【功能描述】** -+ 该GPT示例中产生连续的PWM波。 - -+ 每个PWM波输出完之后,都会产生周期中断。 ++ 该GPT示例中产生连续GPT周期中断。 **【示例配置】** -+ 示例默认输出周期为0.02s,占空比为40%的PWM波,其中周期可通过配置Period项更改,占空比可通过refA0和RefB0的参考值进行更改。 - -+ 每个PWM波输出完成之后,都会产生周期中断,调用周期中断回调函数,示例样例回调函数为“GPT2PWMPeriodOutputFinishCallBack”。 ++ 每个GPT周期计数完成之后,都会产生周期中断,调用周期中断回调函数,示例样例回调函数为“GPTPWMPeriodOutputFinishCallBack”。 **【示例效果】** -+ 在IOCMG_8输出连续方波,如果IOCMG_8上无对应外设,可通过示波器观察方波的周期和占空比。 - -+ 串口0提示GPT输出信息和中期中断回调函数输出的信息。 ++ 串口0打印GPT输出信息和中断回调函数输出的信息。 **【注意事项】** + 更改PWM的周期和占空比一般先使用“HAL_GPT_GetConfig”获取GPT的配置,再使用“HAL_GPT_Config”更改GPT的配置。 + 串口0输出提示信息。 -+ ```c输出的PWMPWM频率=工作时钟频率/((分频系数+1)*(计数周期值+1))``` \ No newline at end of file ++ ```c输出的PWMPWM频率=工作时钟频率/((分频系数+1)*(计数周期值+1))``` + ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/gpt/sample_gpt_period_interrupt/src/sample_gpt_period_interrupt.c b/src/application/drivers_sample/gpt/sample_gpt_period_interrupt/src/sample_gpt_period_interrupt.c index 2c31f328805a71de98014bf5da4c88fa6d36ddd6..23e486d440a532e55f0cbfbe58da3beb4018b9e1 100644 --- a/src/application/drivers_sample/gpt/sample_gpt_period_interrupt/src/sample_gpt_period_interrupt.c +++ b/src/application/drivers_sample/gpt/sample_gpt_period_interrupt/src/sample_gpt_period_interrupt.c @@ -29,12 +29,12 @@ * @param None. * @retval None. */ -void GPT2PWMPeriodOutputFinishCallBack(void *handle) +void GPTPWMPeriodOutputFinishCallBack(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN IRQ_GPT2_PRD_INT */ + /* USER CODE BEGIN IRQ_GPT_PRD_INT */ DBG_PRINTF("GPT period interrupt\n"); - /* USER CODE END IRQ_GPT2_PRD_INT */ + /* USER CODE END IRQ_GPT_PRD_INT */ } /** diff --git a/src/application/drivers_sample/gpt/sample_gpt_pwm_output/readme.md b/src/application/drivers_sample/gpt/sample_gpt_pwm_output/readme.md index 90349ef63716aba6b6285780e6b6e27344876422..3f47aa876cab7f79df8a93e15ab949325dbffa05 100644 --- a/src/application/drivers_sample/gpt/sample_gpt_pwm_output/readme.md +++ b/src/application/drivers_sample/gpt/sample_gpt_pwm_output/readme.md @@ -7,12 +7,12 @@ + 持续输出10s的PWM波之后,会更改PWM的周期和占空比。 **【示例配置】** -+ 示例默认输出频率50Hz,占空比为40%的PWM波,其中周期可通过配置Period项更改,占空比可通过refA0和RefB0的参考值进行更改。 ++ 示例默认输出频率300Hz,占空比为40%的PWM波,其中周期可通过配置Period项更改,占空比可通过refA0和RefB0的参考值进行更改。 + 定时器计时10s之后,通过“HAL_GPT_Config”函数,更改GPT输出PWM波的周期和占空比。 **【示例效果】** -+ 在IOCMG_8输出连续方波,如果IOCMG_8上无对应外设,可通过示波器观察方波的周期和占空比。 ++ 在配置的GPT输出管脚输出连续方波,可通过示波器观察方波的周期和占空比。 + 串口0提示GPT输出信息和更改参数的信息。 @@ -21,4 +21,7 @@ + 串口0输出提示信息。 -+ ```c输出的PWMPWM频率=工作时钟频率/((分频系数+1)*(计数周期值+1))``` \ No newline at end of file ++ ```c输出的PWMPWM频率=工作时钟频率/((分频系数+1)*(计数周期值+1))``` + ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/gpt/sample_gpt_simplerun/init/system_init.c b/src/application/drivers_sample/gpt/sample_gpt_simplerun/init/system_init.c index 70ada1e1c37dc029a76df164449230c74b1ab497..89def8c8774f8f7af015cbeb555d6c7a2da347e5 100644 --- a/src/application/drivers_sample/gpt/sample_gpt_simplerun/init/system_init.c +++ b/src/application/drivers_sample/gpt/sample_gpt_simplerun/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -34,6 +35,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -47,9 +49,9 @@ static void GPT1_Init(void) HAL_CRG_IpClkSelectSet(GPT1_BASE, CRG_PLL_NO_PREDV); g_gptHandle.baseAddress = GPT1; - g_gptHandle.period = 10000 * 1000; /* Period counter, Period = 10000us, 1000ns in 1us */ - g_gptHandle.duty = 10000 * 10 * 10; /* Duty counter, duty = 10000 / 10 us */ - g_gptHandle.pwmPolarity = BASE_CFG_ENABLE; /* Continuous output */ + g_gptHandle.period = 10000 * 1000; /* Period counter is 10000 * 1000 */ + g_gptHandle.duty = 10000 * 10 * 10; /* Duty counter is 10000 * 10 *10 */ + g_gptHandle.pwmPolarity = BASE_CFG_ENABLE; /* Set Polarity Reversal */ g_gptHandle.pwmKeep = BASE_CFG_ENABLE; /* Continuous output */ HAL_GPT_Init(&g_gptHandle); } @@ -60,7 +62,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0Handle.baseAddress = UART0; - g_uart0Handle.irqNum = IRQ_UART0; g_uart0Handle.baudRate = UART0_BAND_RATE; g_uart0Handle.dataLength = UART_DATALENGTH_8BIT; @@ -77,28 +78,26 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; + HAL_IOCMG_SetPinAltFuncMode(IO60_AS_GPT1_PWM); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO60_AS_GPT1_PWM, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO60_AS_GPT1_PWM, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO60_AS_GPT1_PWM, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO60_AS_GPT1_PWM, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_14.BIT.func = 0x2; /* 0x2 is GPT1_PWM */ - iconfig->iocmg_14.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_14.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_14.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_14.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_14.BIT.se = BASE_CFG_DISABLE; + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/gpt/sample_gpt_simplerun/readme.md b/src/application/drivers_sample/gpt/sample_gpt_simplerun/readme.md index c77b1f1cfd412461a3142725e1050577aa1faab0..0609d5202158430ef02c73809b1c3a98be1eb020 100644 --- a/src/application/drivers_sample/gpt/sample_gpt_simplerun/readme.md +++ b/src/application/drivers_sample/gpt/sample_gpt_simplerun/readme.md @@ -5,7 +5,8 @@ + 该GPT示例中产生连续的PWM波,周期和占空比可配。 **【示例配置】** -+ 该示例默认输出频率50Hz,占空比为40%的PWM波,周期和占空比均可通过“HAL_GPT_Config”进行更改。 ++ 该示例默认输出频率100Hz,占空比为90%的PWM波,经过10秒钟后输出频率200Hz,占空比为80%的PWM波, ++ 周期和占空比均可通过“HAL_GPT_Config”进行更改。 **【示例效果】** + 串口0提示GPT输出信息和更改参数的信息。 @@ -15,4 +16,9 @@ **【注意事项】** + 更改PWM的周期和占空比一般先使用“HAL_GPT_GetConfig”获取GPT的配置,再使用“HAL_GPT_Config”更改GPT的配置。 -+ 输出频率计算:```c输出的PWMPWM频率=工作时钟频率/((分频系数+1)*(计数周期值+1))``` \ No newline at end of file ++ 输出频率计算:```c输出的PWMPWM频率=工作时钟频率/((分频系数+1)*(计数周期值+1))``` ++ 需要注意的是,GPT结构体中的period成员变量单位为纳秒。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_blocking_stlm75/init/system_init.c b/src/application/drivers_sample/i2c/sample_i2c_blocking_stlm75/init/system_init.c index 898405abdc2d05257f8109539e2b29aec8428d72..63ee6ff0a9ea356a345e2738c5f4c6449e82945f 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_blocking_stlm75/init/system_init.c +++ b/src/application/drivers_sample/i2c/sample_i2c_blocking_stlm75/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -49,16 +50,14 @@ static void I2C_Init(void) HAL_CRG_IpEnableSet(I2C_BASE, IP_CLK_ENABLE); g_i2cSampleHandle.baseAddress = I2C; - g_i2cSampleHandle.irqNum = IRQ_I2C; g_i2cSampleHandle.addrMode = I2C_7_BITS; g_i2cSampleHandle.sdaHoldTime = I2C_HOLD_DURATION; g_i2cSampleHandle.freq = I2C_FREQ_SCR; - g_i2cSampleHandle.rxBuff = NULL; - g_i2cSampleHandle.txBuff = NULL; + g_i2cSampleHandle.transferBuff = NULL; g_i2cSampleHandle.ignoreAckFlag = BASE_CFG_DISABLE; - g_i2cSampleHandle.msgStopFlag = BASE_CFG_ENABLE; g_i2cSampleHandle.state = I2C_STATE_RESET; + HAL_I2C_Init(&g_i2cSampleHandle); } @@ -68,7 +67,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -85,35 +83,27 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_14.BIT.func = 0x5; /* 0x5 is I2C0_SCL */ - iconfig->iocmg_14.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_14.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_14.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_14.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_14.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_15.BIT.func = 0x5; /* 0x5 is I2C0_SDA */ - iconfig->iocmg_15.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_15.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_15.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_15.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_15.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO48_AS_I2C0_SDA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO48_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO48_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO48_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO48_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO47_AS_I2C0_SCL); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO47_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO47_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO47_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO47_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/i2c/sample_i2c_blocking_stlm75/readme.md b/src/application/drivers_sample/i2c/sample_i2c_blocking_stlm75/readme.md index 373c158ce2a1907a3ed05ffe69e2dc98b600925e..a8a417dbfc06e04a6a0a056211733aef0c474494 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_blocking_stlm75/readme.md +++ b/src/application/drivers_sample/i2c/sample_i2c_blocking_stlm75/readme.md @@ -1,5 +1,5 @@ # 配置I2C作为主机以阻塞方式进行数据的接收、发送,通过Debug串口打印读取的数据 -## 关键字: I2C, 主机,数据读取,数据发送,阻塞方式 +## 关键字: I2C,主机,数据读取,数据发送,阻塞方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、I2C控制器初始化和功能配置。通过阻塞方式与STLM75温度传感器进行数据的接收和数据的发送,通过Debug串口打印读取的温度数值。 @@ -15,4 +15,6 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ I2C必须必须对接stlm75温度传感器,否则程序无法正常运行。 \ No newline at end of file ++ I2C必须必须对接stlm75温度传感器,否则程序无法正常运行。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ IDE未集成此Sample,初始化配置请参考sample下的init文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/init/main.h b/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/init/main.h index 9eaeb40f0e81d2548089bf208270d2b8c92b757a..1d14001246e8754b04a80754004f6b09094e0086 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/init/main.h +++ b/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/init/main.h @@ -46,8 +46,8 @@ extern DMA_Handle g_dmac; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); -void Stlm75TxSampleHandle(I2C_Handle *handle); -void Stlm75RxSampleHandle(I2C_Handle *handle); -void Stlm75ErrSampleHandle(I2C_Handle *handle); +void Stlm75TxSampleHandle(void *handle); +void Stlm75RxSampleHandle(void *handle); +void Stlm75ErrSampleHandle(void *handle); #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/init/system_init.c b/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/init/system_init.c index 9a3a65a7f70bb1f112fcbeca00d84dc3e84f6987..652d44f90763358f95869b27a4027e4696e00473 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/init/system_init.c +++ b/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -44,52 +45,75 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -static void DMA_Channel2Init(void *handle) +static void DMA_Channel0Init(void *handle) { + /* Setting DMA-related parameters. */ DMA_ChannelParam dma_param; dma_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; dma_param.srcAddrInc = DMA_ADDR_UNALTERED; - dma_param.destAddrInc = DMA_ADDR_UNALTERED; + dma_param.destAddrInc = DMA_ADDR_INCREASE; dma_param.srcPeriph = DMA_REQUEST_I2C_RX; dma_param.destPeriph = DMA_REQUEST_MEM; + /* Set the moving position width. */ dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; dma_param.destWidth = DMA_TRANSWIDTH_BYTE; dma_param.srcBurst = DMA_BURST_LENGTH_1; dma_param.destBurst = DMA_BURST_LENGTH_1; dma_param.pHandle = handle; - HAL_DMA_InitChannel(&g_dmac, &dma_param, 2); /* Channel 2 */ + /* DMA Channel initialization. */ + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ZERO); +} + +static void DMA_Channel1Init(void *handle) +{ + /* Setting DMA-related parameters. */ + DMA_ChannelParam dma_param; + dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; + dma_param.srcAddrInc = DMA_ADDR_INCREASE; + dma_param.destAddrInc = DMA_ADDR_UNALTERED; + dma_param.srcPeriph = DMA_REQUEST_MEM; + dma_param.destPeriph = DMA_REQUEST_I2C_TX; + /* Set the moving position width. */ + dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; + dma_param.destWidth = DMA_TRANSWIDTH_BYTE; + dma_param.srcBurst = DMA_BURST_LENGTH_1; + dma_param.destBurst = DMA_BURST_LENGTH_1; + dma_param.pHandle = handle; + /* DMA Channel initialization. */ + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ONE); } static void DMA_Init(void) { + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; - g_dmac.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.irqNumTc = IRQ_DMA_TC; - g_dmac.irqNumError = IRQ_DMA_ERR; - HAL_DMA_IRQService(&g_dmac); + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); - DMA_Channel2Init((void *)(&g_i2cSampleHandle)); + DMA_Channel0Init((void *)(&g_i2cSampleHandle)); + DMA_Channel1Init((void *)(&g_i2cSampleHandle)); } -__weak void Stlm75TxSampleHandle(I2C_Handle *handle) +__weak void Stlm75TxSampleHandle(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN Stlm75TxSampleHandle */ /* USER CODE END Stlm75TxSampleHandle */ } -__weak void Stlm75RxSampleHandle(I2C_Handle *handle) +__weak void Stlm75RxSampleHandle(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN Stlm75RxSampleHandle */ /* USER CODE END Stlm75RxSampleHandle */ } -__weak void Stlm75ErrSampleHandle(I2C_Handle *handle) +__weak void Stlm75ErrSampleHandle(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN Stlm75ErrSampleHandle */ @@ -101,26 +125,20 @@ static void I2C_Init(void) HAL_CRG_IpEnableSet(I2C_BASE, IP_CLK_ENABLE); g_i2cSampleHandle.baseAddress = I2C; - g_i2cSampleHandle.irqNum = IRQ_I2C; - g_i2cSampleHandle.addrMode = I2C_7_BITS; g_i2cSampleHandle.sdaHoldTime = I2C_HOLD_DURATION; g_i2cSampleHandle.freq = I2C_FREQ_SCR; - g_i2cSampleHandle.rxBuff = NULL; - g_i2cSampleHandle.txBuff = NULL; + g_i2cSampleHandle.transferBuff = NULL; g_i2cSampleHandle.ignoreAckFlag = BASE_CFG_DISABLE; - g_i2cSampleHandle.msgStopFlag = BASE_CFG_ENABLE; g_i2cSampleHandle.state = I2C_STATE_RESET; - g_i2cSampleHandle.rxWaterMark = 1; /* Rx water mark is 1 */ - g_i2cSampleHandle.txWaterMark = 16; /* Tx water mark is 16 */ + g_i2cSampleHandle.rxWaterMark = 1; /* 1 is Rx Threshold configuration */ + g_i2cSampleHandle.txWaterMark = 32; /* 32 is Tx Threshold configuration */ + g_i2cSampleHandle.dmaHandle = &g_dmac; - g_i2cSampleHandle.dmaCh = 2; /* Channel is 2 */ - g_i2cSampleHandle.srcBurst = DMA_BURST_LENGTH_1; - g_i2cSampleHandle.destBurst = DMA_BURST_LENGTH_1; - g_i2cSampleHandle.srcWidth = DMA_TRANSWIDTH_BYTE; - g_i2cSampleHandle.destWidth = DMA_TRANSWIDTH_BYTE; - HAL_I2C_Init(&g_i2cSampleHandle); + g_i2cSampleHandle.rxDmaCh = 0; /* DMA Channel 0 */ + g_i2cSampleHandle.txDmaCh = 1; /* DMA Channel 1 */ + HAL_I2C_Init(&g_i2cSampleHandle); HAL_I2C_RegisterCallback(&g_i2cSampleHandle, I2C_MASTER_TX_COMPLETE_CB_ID, Stlm75TxSampleHandle); HAL_I2C_RegisterCallback(&g_i2cSampleHandle, I2C_MASTER_RX_COMPLETE_CB_ID, Stlm75RxSampleHandle); HAL_I2C_RegisterCallback(&g_i2cSampleHandle, I2C_ERROR_CB_ID, Stlm75ErrSampleHandle); @@ -132,7 +150,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -149,35 +166,27 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_66.BIT.func = 0x2; /* 0x2 is I2C0_SCL */ - iconfig->iocmg_66.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_66.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_66.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_66.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_66.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_67.BIT.func = 0x2; /* 0x2 is I2C0_SDA */ - iconfig->iocmg_67.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_67.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_67.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_67.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_67.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO47_AS_I2C0_SCL); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO47_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO47_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO47_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO47_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO48_AS_I2C0_SDA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO48_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO48_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO48_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO48_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/readme.md b/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/readme.md index fdf5d2ae3c17cd61c059315c46356ce3929413ac..96762b8bfd9e095525fdc1496b8134f0a27893b4 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/readme.md +++ b/src/application/drivers_sample/i2c/sample_i2c_dma_stlm75/readme.md @@ -1,5 +1,5 @@ # 配置I2C作为主机以DMA方式进行数据的接收、发送,通过Debug串口打印读取的数据 -## 关键字: I2C, 主机,数据读取,数据发送,DMA方式 +## 关键字: I2C,主机,数据读取,数据发送,DMA方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、I2C控制器初始化和功能配置。通过DMA方式与STLM75温度传感器进行数据的接收和数据的发送,通过Debug串口打印读取的温度数值。 @@ -15,4 +15,6 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ I2C必须必须对接stlm75温度传感器,否则程序无法正常运行。 \ No newline at end of file ++ I2C必须必须对接stlm75温度传感器,否则程序无法正常运行。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ IDE未集成此Sample,初始化配置请参考sample下的init文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/init/main.h b/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/init/main.h index 752da1c9178bcb4d2bbe54e0a809958535b01b1e..995db001003fb1e214e6b183738715d828e96ece 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/init/main.h +++ b/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/init/main.h @@ -43,8 +43,8 @@ extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); -void Stlm75TxCallbackHandle(I2C_Handle *handle); -void Stlm75RxCallbackHandle(I2C_Handle *handle); -void Stlm75ErrCallbackHandle(I2C_Handle *handle); +void Stlm75TxCallbackHandle(void *handle); +void Stlm75RxCallbackHandle(void *handle); +void Stlm75ErrCallbackHandle(void *handle); #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/init/system_init.c b/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/init/system_init.c index 0ac4197c1b0bfe992227b3189dc95cce34928d2a..2178bcaaa9cc8b73af2ad7290b212ba13d31077d 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/init/system_init.c +++ b/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -44,21 +45,21 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -__weak void Stlm75TxCallbackHandle(I2C_Handle *handle) +__weak void Stlm75TxCallbackHandle(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN Stlm75TxCallbackHandle */ /* USER CODE END Stlm75TxCallbackHandle */ } -__weak void Stlm75RxCallbackHandle(I2C_Handle *handle) +__weak void Stlm75RxCallbackHandle(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN Stlm75RxCallbackHandle */ /* USER CODE END Stlm75RxCallbackHandle */ } -__weak void Stlm75ErrCallbackHandle(I2C_Handle *handle) +__weak void Stlm75ErrCallbackHandle(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN Stlm75ErrCallbackHandle */ @@ -70,25 +71,21 @@ static void I2C_Init(void) HAL_CRG_IpEnableSet(I2C_BASE, IP_CLK_ENABLE); g_i2cSampleHandle.baseAddress = I2C; - g_i2cSampleHandle.irqNum = IRQ_I2C; - g_i2cSampleHandle.addrMode = I2C_7_BITS; g_i2cSampleHandle.sdaHoldTime = I2C_HOLD_DURATION; g_i2cSampleHandle.freq = I2C_FREQ_SCR; - g_i2cSampleHandle.rxBuff = NULL; - g_i2cSampleHandle.txBuff = NULL; + g_i2cSampleHandle.transferBuff = NULL; g_i2cSampleHandle.ignoreAckFlag = BASE_CFG_DISABLE; - g_i2cSampleHandle.msgStopFlag = BASE_CFG_ENABLE; g_i2cSampleHandle.state = I2C_STATE_RESET; - g_i2cSampleHandle.rxWaterMark = 32; /* Rx water mark is 32 */ - g_i2cSampleHandle.txWaterMark = 32; /* Tx water mark is 32 */ - HAL_I2C_Init(&g_i2cSampleHandle); + g_i2cSampleHandle.rxWaterMark = 32; /* 32 is Rx Threshold configuration */ + g_i2cSampleHandle.txWaterMark = 32; /* 32 is Tx Threshold configuration */ + HAL_I2C_Init(&g_i2cSampleHandle); HAL_I2C_RegisterCallback(&g_i2cSampleHandle, I2C_MASTER_TX_COMPLETE_CB_ID, Stlm75TxCallbackHandle); HAL_I2C_RegisterCallback(&g_i2cSampleHandle, I2C_MASTER_RX_COMPLETE_CB_ID, Stlm75RxCallbackHandle); HAL_I2C_RegisterCallback(&g_i2cSampleHandle, I2C_ERROR_CB_ID, Stlm75ErrCallbackHandle); - HAL_I2C_IRQService(&g_i2cSampleHandle); - IRQ_SetPriority(g_i2cSampleHandle.irqNum, 1); + IRQ_Register(IRQ_I2C, HAL_I2C_IrqHandler, &g_i2cSampleHandle); + IRQ_SetPriority(IRQ_I2C, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_I2C); } @@ -98,7 +95,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -115,35 +111,27 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_14.BIT.func = 0x5; /* 0x5 is I2C0_SCL */ - iconfig->iocmg_14.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_14.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_14.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_14.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_14.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_15.BIT.func = 0x5; /* 0x5 is I2C0_SDA */ - iconfig->iocmg_15.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_15.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_15.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_15.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_15.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO48_AS_I2C0_SDA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO48_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO48_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO48_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO48_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO47_AS_I2C0_SCL); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO47_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO47_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO47_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO47_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/readme.md b/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/readme.md index 2e396faeb6f5bf7da69ab30e29e6aabb826dbe3a..98bd0d099fcd4fd0585f899266ad484915c35e66 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/readme.md +++ b/src/application/drivers_sample/i2c/sample_i2c_interrupt_stlm75/readme.md @@ -1,5 +1,5 @@ # 配置I2C作为主机以中断方式进行数据的接收、发送,通过Debug串口打印读取的数据 -## 关键字: I2C, 主机,数据读取,数据发送,中断方式 +## 关键字: I2C,主机,数据读取,数据发送,中断方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、I2C控制器初始化和功能配置。通过中断方式与STLM75温度传感器进行数据的接收和数据的发送,通过Debug串口打印读取的温度数值。 @@ -15,4 +15,6 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ I2C必须必须对接stlm75温度传感器,否则程序无法正常运行。 \ No newline at end of file ++ I2C必须必须对接stlm75温度传感器,否则程序无法正常运行。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ IDE未集成此Sample,初始化配置请参考sample下的init文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/main.c b/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/main.c index c2cbf8fa6e8a8b10feb92f961674346df85d20d8..7c142c3d608614423e7a02ba2b2f5a77393e0a56 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/main.c +++ b/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/main.c @@ -24,29 +24,36 @@ #include "feature.h" #include "sample_i2c_master_blocking_at24c64.h" #include "main.h" - /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ -UART_Handle g_uart0; I2C_Handle g_i2c0; +UART_Handle g_uart0; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ I2cBlocking24c64Processing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/main.h b/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/main.h index bd646c19c05b360c313534b2b7ce31a4382306ff..ca2858d7dc1766029668519dfc89eab3839c3226 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/main.h +++ b/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/main.h @@ -26,7 +26,6 @@ #include "uart.h" #include "i2c.h" -#include "i2c_ex.h" #include "crg.h" #define IO_SPEED_FAST 0x00U @@ -42,10 +41,14 @@ #define XTAL_DRV_LEVEL2 0x01U #define XTAL_DRV_LEVEL1 0x00U -extern UART_Handle g_uart0; extern I2C_Handle g_i2c0; +extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/system_init.c b/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/system_init.c index 2b879fce22003161801111637edad088e09e479d..bad53246cffae604f1976dac453bb7807801dc94 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/system_init.c +++ b/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/init/system_init.c @@ -22,23 +22,23 @@ #include "main.h" #include "ioconfig.h" -#include "iocmg_ip.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 +#define I2C_FREQ_SCR 100000 +#define I2C_HOLD_DURATION 10 + BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { - /* Clock-related parameter configuration. */ CRG_Handle crg; crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; - /* Initialize the clock configuration. */ + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -46,21 +46,19 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -static void I2C0_Init(void) +static void I2C_Init(void) { - HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); - g_i2c0.baseAddress = I2C0; + HAL_CRG_IpEnableSet(I2C_BASE, IP_CLK_ENABLE); + + g_i2c0.baseAddress = I2C; - g_i2c0.functionMode = I2C_MODE_SELECT_MASTER_ONLY; g_i2c0.addrMode = I2C_7_BITS; - g_i2c0.sdaHoldTime = 10; /* I2C SDA hold time 10. */ - g_i2c0.freq = 400000; /* I2C SCL rate 400000 bit/s. */ + g_i2c0.sdaHoldTime = I2C_HOLD_DURATION; + g_i2c0.freq = I2C_FREQ_SCR; g_i2c0.transferBuff = NULL; - g_i2c0.ignoreAckFlag = BASE_CFG_DISABLE; - g_i2c0.handleEx.spikeFilterTime = 0; - g_i2c0.handleEx.sdaDelayTime = 0; - g_i2c0.timeout = 10000; /* The value of timeout is 10000ms; */ + g_i2c0.ignoreAckFlag = BASE_CFG_DISABLE; g_i2c0.state = I2C_STATE_RESET; + HAL_I2C_Init(&g_i2c0); } @@ -68,57 +66,55 @@ static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - /* UART-related parameter configuration. */ + g_uart0.baseAddress = UART0; - g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; - g_uart0.fifoMode = BASE_CFG_ENABLE; /* Disable uart fifo mode. */ - g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; - g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; - /* Initializing the UART0. */ HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_I2C0_SCL); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_I2C0_SDA); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO48_AS_I2C0_SDA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO48_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO48_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO48_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO48_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO47_AS_I2C0_SCL); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO47_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO47_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO47_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO47_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); UART0_Init(); - I2C0_Init(); + I2C_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/readme.md b/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/readme.md index 37c0631df71bfc0890ddfcfad6755666b4fd70d9..b69765d77a5da5ae634411ca190e3119e538ea6b 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/readme.md +++ b/src/application/drivers_sample/i2c/sample_i2c_master_blocking_at24c64/readme.md @@ -1,5 +1,5 @@ # 配置I2C作为主机以阻塞方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 -## 关键字: I2C, 主机,数据读取,数据发送,阻塞方式 +## 关键字: I2C,主机,数据读取,数据发送,阻塞方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、I2C控制器初始化和功能配置。通过阻塞方式与EEPROM(AT24C64)进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 @@ -16,4 +16,8 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 示例代码中I2C必须必须对接EEPROM(AT24C64),且保证EEPROM的7bit地址为50,否则示例代码无法正常运行。 \ No newline at end of file ++ 示例代码中I2C必须必须对接EEPROM(AT24C64),且保证EEPROM的7bit地址为0x50,否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/main.c b/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/main.c index 2ac1fa57f1c4c97b0700d2d806b8aa8d1bf60f71..99e2ed5a3efefddb6d7f1fee185739fae1191c47 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/main.c +++ b/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/main.c @@ -24,30 +24,37 @@ #include "feature.h" #include "sample_i2c_master_dma_at24c64.h" #include "main.h" - /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ -UART_Handle g_uart0; I2C_Handle g_i2c0; +UART_Handle g_uart0; DMA_Handle g_dmac; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ I2cDma24c64Processing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/main.h b/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/main.h index 9e0d9fccbcd03d5a31762f5f9d51debe238c379b..5bea77715acc3a513b284835190c6f76c57f2f1a 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/main.h +++ b/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/main.h @@ -26,7 +26,6 @@ #include "uart.h" #include "i2c.h" -#include "i2c_ex.h" #include "crg.h" #include "dma.h" @@ -43,12 +42,20 @@ #define XTAL_DRV_LEVEL2 0x01U #define XTAL_DRV_LEVEL1 0x00U -extern UART_Handle g_uart0; extern I2C_Handle g_i2c0; +extern UART_Handle g_uart0; extern DMA_Handle g_dmac; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +void I2C0TxCallback(void *handle); +void I2C0RxCallback(void *handle); +void I2C0ErrorCallback(void *handle); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/system_init.c b/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/system_init.c index dd44a7127fba36323de0d74e0f5b7fc89822b4cf..2f0c2fe7615b78f51b746d2991e2304c71a3168f 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/system_init.c +++ b/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/init/system_init.c @@ -22,23 +22,23 @@ #include "main.h" #include "ioconfig.h" -#include "iocmg_ip.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 +#define I2C_FREQ_SCR 100000 +#define I2C_HOLD_DURATION 10 + BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { - /* Clock-related parameter configuration. */ CRG_Handle crg; crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; - /* Initialize the clock configuration. */ + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -53,7 +53,7 @@ static void DMA_Channel0Init(void *handle) dma_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; dma_param.srcAddrInc = DMA_ADDR_UNALTERED; dma_param.destAddrInc = DMA_ADDR_INCREASE; - dma_param.srcPeriph = DMA_REQUEST_I2C0_RX; + dma_param.srcPeriph = DMA_REQUEST_I2C_RX; dma_param.destPeriph = DMA_REQUEST_MEM; /* Set the moving position width. */ dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; @@ -73,10 +73,10 @@ static void DMA_Channel1Init(void *handle) dma_param.srcAddrInc = DMA_ADDR_INCREASE; dma_param.destAddrInc = DMA_ADDR_UNALTERED; dma_param.srcPeriph = DMA_REQUEST_MEM; - dma_param.destPeriph = DMA_REQUEST_I2C0_TX; + dma_param.destPeriph = DMA_REQUEST_I2C_TX; /* Set the moving position width. */ - dma_param.srcWidth = DMA_TRANSWIDTH_WORD; - dma_param.destWidth = DMA_TRANSWIDTH_WORD; + dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; + dma_param.destWidth = DMA_TRANSWIDTH_BYTE; dma_param.srcBurst = DMA_BURST_LENGTH_1; dma_param.destBurst = DMA_BURST_LENGTH_1; dma_param.pHandle = handle; @@ -90,6 +90,8 @@ static void DMA_Init(void) HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; /* Configuring DMA Interrupt Parameters. */ + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); @@ -97,54 +99,50 @@ static void DMA_Init(void) HAL_DMA_Init(&g_dmac); /* Setting the Channel Priority and Initializing the Channel. */ DMA_Channel0Init((void *)(&g_i2c0)); - HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_ZERO, DMA_PRIORITY_HIGHEST); DMA_Channel1Init((void *)(&g_i2c0)); - HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_ONE, DMA_PRIORITY_HIGHEST); } __weak void I2C0TxCallback(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN I2C0TxCallback */ - /* USER CODE END I2C0TxCallback */ + /* USER CODE BEGIN I2C_MASTER_TX_COMPLETE_CB_ID */ + /* USER CODE END I2C_MASTER_TX_COMPLETE_CB_ID */ } __weak void I2C0RxCallback(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN I2C0RxCallback */ - /* USER CODE END I2C0RxCallback */ + /* USER CODE BEGIN I2C_MASTER_RX_COMPLETE_CB_ID */ + /* USER CODE END I2C_MASTER_RX_COMPLETE_CB_ID */ } __weak void I2C0ErrorCallback(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN I2C0ErrorCallback */ - /* USER CODE END I2C0ErrorCallback */ + /* USER CODE BEGIN I2C_ERROR_CB_ID */ + /* USER CODE END I2C_ERROR_CB_ID */ } -static void I2C0_Init(void) +static void I2C_Init(void) { - HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); - g_i2c0.baseAddress = I2C0; + HAL_CRG_IpEnableSet(I2C_BASE, IP_CLK_ENABLE); + + g_i2c0.baseAddress = I2C; - g_i2c0.functionMode = I2C_MODE_SELECT_MASTER_ONLY; g_i2c0.addrMode = I2C_7_BITS; - g_i2c0.sdaHoldTime = 10; /* I2C SDA hold time 10. */ - g_i2c0.freq = 400000; /* I2C SCL rate 400000 bit/s. */ + g_i2c0.sdaHoldTime = I2C_HOLD_DURATION; + g_i2c0.freq = I2C_FREQ_SCR; g_i2c0.transferBuff = NULL; - g_i2c0.ignoreAckFlag = BASE_CFG_DISABLE; - g_i2c0.handleEx.spikeFilterTime = 0; - g_i2c0.handleEx.sdaDelayTime = 0; - g_i2c0.timeout = 10000; /* The value of timeout is 10000ms; */ + g_i2c0.ignoreAckFlag = BASE_CFG_DISABLE; g_i2c0.state = I2C_STATE_RESET; - g_i2c0.rxWaterMark = 1; /* The value of rx Water mark is 1. */ - g_i2c0.txWaterMark = 12; /* The value of tx Water mark is 12. */ + g_i2c0.rxWaterMark = 1; /* 1 is Rx Threshold configuration */ + g_i2c0.txWaterMark = 32; /* 32 is Tx Threshold configuration */ + g_i2c0.dmaHandle = &g_dmac; - g_i2c0.txDmaCh = DMA_CHANNEL_ONE; - g_i2c0.rxDmaCh = DMA_CHANNEL_ZERO; - HAL_I2C_Init(&g_i2c0); + g_i2c0.rxDmaCh = 0; /* DMA Channel 0 */ + g_i2c0.txDmaCh = 1; /* DMA Channel 1 */ + HAL_I2C_Init(&g_i2c0); HAL_I2C_RegisterCallback(&g_i2c0, I2C_MASTER_TX_COMPLETE_CB_ID, I2C0TxCallback); HAL_I2C_RegisterCallback(&g_i2c0, I2C_MASTER_RX_COMPLETE_CB_ID, I2C0RxCallback); HAL_I2C_RegisterCallback(&g_i2c0, I2C_ERROR_CB_ID, I2C0ErrorCallback); @@ -157,47 +155,45 @@ static void UART0_Init(void) /* UART-related parameter configuration. */ g_uart0.baseAddress = UART0; - g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.baudRate = UART0_BAND_RATE; /* Set the UART Baud Rate. */ g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; /* Disable uart fifo mode. */ - g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; - g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; - /* Initializing the UART0. */ HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_I2C0_SCL); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_I2C0_SDA); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO47_AS_I2C0_SCL); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO47_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO47_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO47_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO47_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO48_AS_I2C0_SDA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO48_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO48_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO48_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO48_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -205,7 +201,7 @@ void SystemInit(void) IOConfig(); DMA_Init(); UART0_Init(); - I2C0_Init(); + I2C_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/readme.md b/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/readme.md index 3e011c26d3292e53ee8d8ac6e85889b5a5d823b5..d429cf95838f0e6017b908ca2a66751f8e692614 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/readme.md +++ b/src/application/drivers_sample/i2c/sample_i2c_master_dma_at24c64/readme.md @@ -1,5 +1,5 @@ # 配置I2C作为主机以DMA方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 -## 关键字: I2C, 主机,数据读取,数据发送,DMA方式 +## 关键字: I2C,主机,数据读取,数据发送,DMA方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、I2C控制器初始化和功能配置。通过中断方式与EEPROM(AT24C64)进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 @@ -16,4 +16,8 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 示例代码中I2C必须必须对接EEPROM(AT24C64),且保证EEPROM的7bit地址为50,否则示例代码无法正常运行。 \ No newline at end of file ++ 示例代码中I2C必须必须对接EEPROM(AT24C64),且保证EEPROM的7bit地址为0x50,否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/main.c b/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/main.c index cf5190300e1d1e37b0b8663bdfda8923c23c382a..0d37cfd89a34c11a15d147174bb5cd4c00b4ba9c 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/main.c +++ b/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/main.c @@ -25,27 +25,35 @@ #include "sample_i2c_master_interrupt_at24c64.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ -UART_Handle g_uart0; I2C_Handle g_i2c0; +UART_Handle g_uart0; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ I2cInterrupt24c64Processing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/main.h b/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/main.h index 340f824bdc53bffbd14e3e0e813a39439699523a..a0722b1cdfdf4c75d2f363eec29cebe73ed29a26 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/main.h +++ b/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/main.h @@ -26,7 +26,6 @@ #include "uart.h" #include "i2c.h" -#include "i2c_ex.h" #include "crg.h" #define IO_SPEED_FAST 0x00U @@ -42,8 +41,8 @@ #define XTAL_DRV_LEVEL2 0x01U #define XTAL_DRV_LEVEL1 0x00U -extern UART_Handle g_uart0; extern I2C_Handle g_i2c0; +extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); @@ -52,4 +51,8 @@ void I2C0TxCallback(void *handle); void I2C0RxCallback(void *handle); void I2C0ErrorCallback(void *handle); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/system_init.c b/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/system_init.c index bc14db3a232be377e89aebe54e5cb633cf825767..fe2c7a0788af96f6acff7eb6b8cc2bcd88960f84 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/system_init.c +++ b/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/init/system_init.c @@ -22,23 +22,23 @@ #include "main.h" #include "ioconfig.h" -#include "iocmg_ip.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 +#define I2C_FREQ_SCR 100000 +#define I2C_HOLD_DURATION 10 + BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { - /* Clock-related parameter configuration. */ CRG_Handle crg; crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; - /* Initialize the clock configuration. */ + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -49,107 +49,101 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) __weak void I2C0TxCallback(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN I2C0TxCallback */ - /* USER CODE END I2C0TxCallback */ + /* USER CODE BEGIN I2C_MASTER_TX_COMPLETE_CB_ID */ + /* USER CODE END I2C_MASTER_TX_COMPLETE_CB_ID */ } __weak void I2C0RxCallback(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN I2C0RxCallback */ - /* USER CODE END I2C0RxCallback */ + /* USER CODE BEGIN I2C_MASTER_RX_COMPLETE_CB_ID */ + /* USER CODE END I2C_MASTER_RX_COMPLETE_CB_ID */ } __weak void I2C0ErrorCallback(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN I2C0ErrorCallback */ - /* USER CODE END I2C0ErrorCallback */ + /* USER CODE BEGIN I2C_ERROR_CB_ID */ + /* USER CODE END I2C_ERROR_CB_ID */ } -static void I2C0_Init(void) +static void I2C_Init(void) { - HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); - g_i2c0.baseAddress = I2C0; + HAL_CRG_IpEnableSet(I2C_BASE, IP_CLK_ENABLE); + + g_i2c0.baseAddress = I2C; - g_i2c0.functionMode = I2C_MODE_SELECT_MASTER_ONLY; g_i2c0.addrMode = I2C_7_BITS; - g_i2c0.sdaHoldTime = 10; /* I2C SDA hold time 10. */ - g_i2c0.freq = 400000; /* I2C SCL rate 400000 bit/s. */ + g_i2c0.sdaHoldTime = I2C_HOLD_DURATION; + g_i2c0.freq = I2C_FREQ_SCR; g_i2c0.transferBuff = NULL; - g_i2c0.ignoreAckFlag = BASE_CFG_DISABLE; - g_i2c0.handleEx.spikeFilterTime = 0; - g_i2c0.handleEx.sdaDelayTime = 0; - g_i2c0.timeout = 10000; /* The value of timeout is 10000ms; */ + g_i2c0.ignoreAckFlag = BASE_CFG_DISABLE; g_i2c0.state = I2C_STATE_RESET; - g_i2c0.rxWaterMark = 1; - g_i2c0.txWaterMark = 12; /* The value of tx Water mark is 12. */ - HAL_I2C_Init(&g_i2c0); + g_i2c0.rxWaterMark = 32; /* 32 is Rx Threshold configuration */ + g_i2c0.txWaterMark = 32; /* 32 is Tx Threshold configuration */ + HAL_I2C_Init(&g_i2c0); HAL_I2C_RegisterCallback(&g_i2c0, I2C_MASTER_TX_COMPLETE_CB_ID, I2C0TxCallback); HAL_I2C_RegisterCallback(&g_i2c0, I2C_MASTER_RX_COMPLETE_CB_ID, I2C0RxCallback); HAL_I2C_RegisterCallback(&g_i2c0, I2C_ERROR_CB_ID, I2C0ErrorCallback); - /* Configuring I2C Interrupt Parameters. */ - IRQ_Register(IRQ_I2C0, HAL_I2C_IrqHandler, &g_i2c0); - IRQ_SetPriority(IRQ_I2C0, 1); - IRQ_EnableN(IRQ_I2C0); + IRQ_Register(IRQ_I2C, HAL_I2C_IrqHandler, &g_i2c0); + IRQ_SetPriority(IRQ_I2C, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_I2C); } static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - /* UART-related parameter configuration. */ + g_uart0.baseAddress = UART0; - g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; - g_uart0.fifoMode = BASE_CFG_ENABLE; /* Disable uart fifo mode. */ - g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; - g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; - /* Initializing the UART0. */ HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_I2C0_SCL); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_I2C0_SDA); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO48_AS_I2C0_SDA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO48_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO48_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO48_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO48_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO47_AS_I2C0_SCL); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO47_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO47_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO47_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO47_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); UART0_Init(); - I2C0_Init(); + I2C_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/readme.md b/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/readme.md index ce8964bcb26cb3ad9b0d1d485a7f50ad010fda23..93f1e4ef3ad675d67a0975fce5687b15f3e3164f 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/readme.md +++ b/src/application/drivers_sample/i2c/sample_i2c_master_interrupt_at24c64/readme.md @@ -1,5 +1,5 @@ # 配置I2C作为主机以中断方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 -## 关键字: I2C, 主机,数据读取,数据发送,中断方式 +## 关键字: I2C,主机,数据读取,数据发送,中断方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、I2C控制器初始化和功能配置。通过中断方式与EEPROM(AT24C64)进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 @@ -16,4 +16,8 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 示例代码中I2C必须必须对接EEPROM(AT24C64),且保证EEPROM的7bit地址为50,否则示例代码无法正常运行。 \ No newline at end of file ++ 示例代码中I2C必须必须对接EEPROM(AT24C64),且保证EEPROM的7bit地址为0x50,否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/main.c b/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/main.c index 5742fadab0a94c41972cbb6a5df6f3669a193d35..d77863cad2d248af0e775d4a1e857c8dfa195129 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/main.c +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/main.c @@ -25,27 +25,35 @@ #include "sample_i2c_slave_blocking.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ UART_Handle g_uart0; I2C_Handle g_i2c0; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ I2cSlaveBlockingProcessing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/main.h b/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/main.h index bd646c19c05b360c313534b2b7ce31a4382306ff..200c5fedaeadd1a6f924a9da5a4f646f00579828 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/main.h +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/main.h @@ -25,9 +25,11 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "i2c.h" #include "i2c_ex.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -48,4 +50,8 @@ extern I2C_Handle g_i2c0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/system_init.c b/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/system_init.c index f8b0519b0ab70d32ed7e5ea3f7134e95ecca8196..22ce5e34713c7463dde34dbddaf8fd2912deae5e 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/system_init.c +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/init/system_init.c @@ -28,17 +28,19 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { - /* Clock-related parameter configuration. */ CRG_Handle crg; crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; - /* Initialize the clock configuration. */ + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + /* 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -48,19 +50,19 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void I2C0_Init(void) { - HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); /* I2C0 clock enable. */ g_i2c0.baseAddress = I2C0; g_i2c0.functionMode = I2C_MODE_SELECT_SLAVE_ONLY; g_i2c0.addrMode = I2C_7_BITS; - g_i2c0.sdaHoldTime = 10; /* I2C SDA hold time 10. */ - g_i2c0.freq = 400000; /* I2C SCL rate 400000 bit/s. */ + g_i2c0.sdaHoldTime = 10; /* 10 is sda Hold Time */ + g_i2c0.freq = 400000; /* freqence is 400000 */ g_i2c0.transferBuff = NULL; g_i2c0.ignoreAckFlag = BASE_CFG_DISABLE; g_i2c0.handleEx.spikeFilterTime = 0; g_i2c0.handleEx.sdaDelayTime = 0; - g_i2c0.timeout = 10000; /* The value of timeout is 10000ms; */ - g_i2c0.slaveOwnAddress = 82; /* The own address of I2C is 82. */ + g_i2c0.timeout = 10000; /* 10000 is time out */ + g_i2c0.slaveOwnAddress = 82; /* 82 is own address as slave */ g_i2c0.handleEx.slaveOwnXmbAddressEnable = BASE_CFG_DISABLE; g_i2c0.handleEx.slaveOwnXmbAddress = 0; g_i2c0.generalCallMode = BASE_CFG_DISABLE; @@ -70,52 +72,49 @@ static void I2C0_Init(void) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - /* UART-related parameter configuration. */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ g_uart0.baseAddress = UART0; - g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; - g_uart0.fifoMode = BASE_CFG_ENABLE; /* Disable uart fifo mode. */ + g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; - /* Initializing the UART0. */ HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_I2C0_SCL); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_2_AS_I2C0_SCL); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_2_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_2_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_2_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_2_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_I2C0_SDA); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_3_AS_I2C0_SDA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_3_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_3_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_3_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_3_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/readme.md b/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/readme.md index 02f77b9642a4e3d8d9ec95bc0c410258d240e2d6..867c43476fc085ce4abcfe9cb54ab2921a6031a0 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/readme.md +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_blocking/readme.md @@ -1,5 +1,5 @@ # 配置I2C作为从机以阻塞方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 -## 关键字: I2C, 从机,数据读取,数据发送,阻塞方式 +## 关键字: I2C,从机,数据读取,数据发送,阻塞方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、I2C控制器初始化和功能配置。通过阻塞方式与I2C主机进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 @@ -20,4 +20,8 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 示例代码中I2C必须必须对接主机,且保证主机寻址的地址为82(7bit地址),否则示例代码无法正常运行。 \ No newline at end of file ++ 示例代码中I2C必须必须对接主机,且保证主机寻址的地址为82(7bit地址),否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/main.c b/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/main.c index 0ff74a0aa1901b3dfab1a2a6296d56858b8d263d..9f51816f2a5e7bae5a81066ca037a1406eb7b692 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/main.c +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/main.c @@ -24,30 +24,37 @@ #include "feature.h" #include "sample_i2c_slave_dma.h" #include "main.h" - /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ UART_Handle g_uart0; I2C_Handle g_i2c0; DMA_Handle g_dmac; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ I2cSlaveDmaProcessing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/main.h b/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/main.h index 9e0d9fccbcd03d5a31762f5f9d51debe238c379b..db2f588aefad794db42285c413bcf8e2fca97091 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/main.h +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/main.h @@ -25,10 +25,13 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "i2c.h" #include "i2c_ex.h" #include "crg.h" #include "dma.h" +#include "dma_ex.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -51,4 +54,12 @@ extern DMA_Handle g_dmac; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +void I2C0TxCallback(void *handle); +void I2C0RxCallback(void *handle); +void I2C0ErrorCallback(void *handle); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/system_init.c b/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/system_init.c index da15b6fa359b6c38da8b217c3f3d22d2c1e5003b..ff224e6473a9254d2ef25424f24b846fd9ecd231 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/system_init.c +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_dma/init/system_init.c @@ -28,17 +28,19 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { - /* Clock-related parameter configuration. */ CRG_Handle crg; crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; - /* Initialize the clock configuration. */ + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + /* 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -86,16 +88,13 @@ static void DMA_Channel1Init(void *handle) static void DMA_Init(void) { - /* DMA initialization. */ HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; - /* Configuring DMA Interrupt Parameters. */ IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); - /* Setting the Channel Priority and Initializing the Channel. */ DMA_Channel0Init((void *)(&g_i2c0)); HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_ZERO, DMA_PRIORITY_HIGHEST); DMA_Channel1Init((void *)(&g_i2c0)); @@ -125,30 +124,29 @@ __weak void I2C0ErrorCallback(void *handle) static void I2C0_Init(void) { - HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); /* I2C0 clock enable. */ g_i2c0.baseAddress = I2C0; g_i2c0.functionMode = I2C_MODE_SELECT_SLAVE_ONLY; g_i2c0.addrMode = I2C_7_BITS; - g_i2c0.sdaHoldTime = 10; /* I2C SDA hold time 10. */ - g_i2c0.freq = 400000; /* I2C SCL rate 400000 bit/s. */ + g_i2c0.sdaHoldTime = 10; /* 10 is sda Hold Time */ + g_i2c0.freq = 400000; /* freqence is 400000 */ g_i2c0.transferBuff = NULL; g_i2c0.ignoreAckFlag = BASE_CFG_DISABLE; g_i2c0.handleEx.spikeFilterTime = 0; g_i2c0.handleEx.sdaDelayTime = 0; - g_i2c0.timeout = 10000; /* The value of timeout is 10000ms; */ - g_i2c0.slaveOwnAddress = 82; /* The own address of I2C is 82. */ + g_i2c0.timeout = 10000; /* 10000 is time out */ + g_i2c0.slaveOwnAddress = 82; /* 82 is own address as slave */ g_i2c0.handleEx.slaveOwnXmbAddressEnable = BASE_CFG_DISABLE; g_i2c0.handleEx.slaveOwnXmbAddress = 0; g_i2c0.generalCallMode = BASE_CFG_DISABLE; g_i2c0.state = I2C_STATE_RESET; - g_i2c0.rxWaterMark = 1; /* The value of rx Water mark is 1. */ - g_i2c0.txWaterMark = 12; /* The value of tx Water mark is 12. */ + g_i2c0.rxWaterMark = 1; /* 1 is Rx Threshold configuration */ + g_i2c0.txWaterMark = 12; /* 12 is Tx Threshold configuration */ g_i2c0.dmaHandle = &g_dmac; g_i2c0.txDmaCh = DMA_CHANNEL_ONE; g_i2c0.rxDmaCh = DMA_CHANNEL_ZERO; HAL_I2C_Init(&g_i2c0); - HAL_I2C_RegisterCallback(&g_i2c0, I2C_SLAVE_TX_COMPLETE_CB_ID, I2C0TxCallback); HAL_I2C_RegisterCallback(&g_i2c0, I2C_SLAVE_RX_COMPLETE_CB_ID, I2C0RxCallback); HAL_I2C_RegisterCallback(&g_i2c0, I2C_ERROR_CB_ID, I2C0ErrorCallback); @@ -156,52 +154,49 @@ static void I2C0_Init(void) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - /* UART-related parameter configuration. */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ g_uart0.baseAddress = UART0; - g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; - g_uart0.fifoMode = BASE_CFG_ENABLE; /* Disable uart fifo mode. */ + g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; - /* Initializing the UART0. */ HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_I2C0_SCL); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_I2C0_SDA); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_2_AS_I2C0_SCL); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_2_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_2_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_2_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_2_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_3_AS_I2C0_SDA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_3_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_3_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_3_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_3_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_dma/readme.md b/src/application/drivers_sample/i2c/sample_i2c_slave_dma/readme.md index 883d89fcb6d82af75019683dbb1d945b725c761d..023c007bf75807b192fcb6e99bfc2d2f17f1e64e 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_dma/readme.md +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_dma/readme.md @@ -1,5 +1,5 @@ # 配置I2C作为从机以DMA方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 -## 关键字: I2C, 从机,数据读取,数据发送,DMA方式 +## 关键字: I2C,从机,数据读取,数据发送,DMA方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、I2C控制器初始化和功能配置。通过DMA方式与I2C主机进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 @@ -20,4 +20,8 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 示例代码中I2C必须必须对接主机,且保证主机寻址的地址为82(7bit地址),否则示例代码无法正常运行。 \ No newline at end of file ++ 示例代码中I2C必须必须对接主机,且保证主机寻址的地址为82(7bit地址),否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/main.c b/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/main.c index 0a65c2f2a7b45ce42730a03aa3d5dc7f99f58913..67202ed426c36cf3f1f52dd94001e1ff60759a5f 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/main.c +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/main.c @@ -24,29 +24,36 @@ #include "feature.h" #include "sample_i2c_slave_interrupt.h" #include "main.h" - /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ UART_Handle g_uart0; I2C_Handle g_i2c0; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ I2cSlaveInterruptProcessing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/main.h b/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/main.h index 340f824bdc53bffbd14e3e0e813a39439699523a..972ad56db7b15833e0b3a03a46201cd8c932358e 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/main.h +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/main.h @@ -25,9 +25,11 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "i2c.h" #include "i2c_ex.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -52,4 +54,8 @@ void I2C0TxCallback(void *handle); void I2C0RxCallback(void *handle); void I2C0ErrorCallback(void *handle); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/system_init.c b/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/system_init.c index db5c8a2cf43166d2cea3aa5fc1b415b226752d5b..877f1f2f11f3959b124e3cafd511d69fe2407d8c 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/system_init.c +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/init/system_init.c @@ -28,17 +28,19 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { - /* Clock-related parameter configuration. */ CRG_Handle crg; crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; - /* Initialize the clock configuration. */ + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + /* 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -69,83 +71,79 @@ __weak void I2C0ErrorCallback(void *handle) static void I2C0_Init(void) { - HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); /* I2C0 clock enable. */ g_i2c0.baseAddress = I2C0; g_i2c0.functionMode = I2C_MODE_SELECT_SLAVE_ONLY; g_i2c0.addrMode = I2C_7_BITS; - g_i2c0.sdaHoldTime = 10; /* I2C SDA hold time 10. */ - g_i2c0.freq = 400000; /* I2C SCL rate 400000 bit/s. */ + g_i2c0.sdaHoldTime = 10; /* 10 is sda Hold Time */ + g_i2c0.freq = 400000; /* freqence is 400000 */ g_i2c0.transferBuff = NULL; g_i2c0.ignoreAckFlag = BASE_CFG_DISABLE; g_i2c0.handleEx.spikeFilterTime = 0; g_i2c0.handleEx.sdaDelayTime = 0; - g_i2c0.timeout = 10000; /* The value of timeout is 10000ms; */ - g_i2c0.slaveOwnAddress = 82; /* The own address of I2C is 82. */ + g_i2c0.timeout = 10000; /* 10000 is time out */ + g_i2c0.slaveOwnAddress = 82; /* 82 is own address as slave */ g_i2c0.handleEx.slaveOwnXmbAddressEnable = BASE_CFG_DISABLE; g_i2c0.handleEx.slaveOwnXmbAddress = 0; g_i2c0.generalCallMode = BASE_CFG_DISABLE; g_i2c0.state = I2C_STATE_RESET; - g_i2c0.rxWaterMark = 1; /* The value of rx Water mark is 1. */ - g_i2c0.txWaterMark = 12; /* The value of tx Water mark is 12. */ + g_i2c0.rxWaterMark = 1; /* 1 is Rx Threshold configuration */ + g_i2c0.txWaterMark = 12; /* 12 is Tx Threshold configuration */ HAL_I2C_Init(&g_i2c0); - HAL_I2C_RegisterCallback(&g_i2c0, I2C_SLAVE_TX_COMPLETE_CB_ID, I2C0TxCallback); HAL_I2C_RegisterCallback(&g_i2c0, I2C_SLAVE_RX_COMPLETE_CB_ID, I2C0RxCallback); HAL_I2C_RegisterCallback(&g_i2c0, I2C_ERROR_CB_ID, I2C0ErrorCallback); IRQ_Register(IRQ_I2C0, HAL_I2C_IrqHandler, &g_i2c0); - IRQ_SetPriority(IRQ_I2C0, 1); + IRQ_SetPriority(IRQ_I2C0, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_I2C0); } static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - /* UART-related parameter configuration. */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ g_uart0.baseAddress = UART0; - g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; - g_uart0.fifoMode = BASE_CFG_ENABLE; /* Disable uart fifo mode. */ + g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; - /* Initializing the UART0. */ HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_I2C0_SCL); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_I2C0_SDA); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_2_AS_I2C0_SCL); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_2_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_2_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_2_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_2_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_3_AS_I2C0_SDA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_3_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_3_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_3_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_3_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/readme.md b/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/readme.md index 5ad208553317ac4408c45747dd44e11e1632cdd9..328976058a921ce0d288a89d439df62142b8e550 100644 --- a/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/readme.md +++ b/src/application/drivers_sample/i2c/sample_i2c_slave_interrupt/readme.md @@ -1,5 +1,5 @@ # 配置I2C作为从机以中断方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 -## 关键字: I2C, 从机,数据读取,数据发送,中断方式 +## 关键字: I2C,从机,数据读取,数据发送,中断方式 **【功能描述】** + 示例代码基于HAL接口完成时钟、I2C控制器初始化和功能配置。通过中断方式与I2C主机进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 @@ -20,4 +20,8 @@ **【注意事项】** + 示例代码使用UART0进行结果打印输出,需要对UART0配置。 -+ 示例代码中I2C必须必须对接主机,且保证主机寻址的地址为82(7bit地址),否则示例代码无法正常运行。 \ No newline at end of file ++ 示例代码中I2C必须必须对接主机,且保证主机寻址的地址为82(7bit地址),否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/iocmg/iolist_sample/init/main.c b/src/application/drivers_sample/iocmg/iolist_sample/init/main.c index 56b83161bf00aeaa634876288c6a368b79e9aab7..f189b40530997d4f5466fee9bdd5bb7e28720692 100644 --- a/src/application/drivers_sample/iocmg/iolist_sample/init/main.c +++ b/src/application/drivers_sample/iocmg/iolist_sample/init/main.c @@ -19,16 +19,39 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "iolist_sample.h" - -UART_Handle g_uart0; +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ IOCMG_IOListInitSample(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/iocmg/iolist_sample/init/main.h b/src/application/drivers_sample/iocmg/iolist_sample/init/main.h index 0dbdd0fd37a307cae97a56d384224aa1cccf061a..be0c1a238bd81b5ce68c8ef007a2daddebfc0551 100644 --- a/src/application/drivers_sample/iocmg/iolist_sample/init/main.h +++ b/src/application/drivers_sample/iocmg/iolist_sample/init/main.h @@ -24,8 +24,6 @@ #ifndef McuMagicTag_SYSTEM_INIT_H #define McuMagicTag_SYSTEM_INIT_H -#include "uart.h" -#include "iocmg.h" #include "crg.h" #define IO_SPEED_FAST 0x00U @@ -36,12 +34,16 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U -#define UART0_TXD_PIN IOCMG_PIN_MUX(iocmg_6, FUNC_MODE_4, 0x0000) -#define UART0_RXD_PIN IOCMG_PIN_MUX(iocmg_7, FUNC_MODE_4, 0x0000) - -extern UART_Handle g_uart0; +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/iocmg/iolist_sample/init/system_init.c b/src/application/drivers_sample/iocmg/iolist_sample/init/system_init.c index bc9691eec3c9be7ff7c87b02df29114e3dcf25ba..c593b4065d500ba448bf389b40f7f3b10678021b 100644 --- a/src/application/drivers_sample/iocmg/iolist_sample/init/system_init.c +++ b/src/application/drivers_sample/iocmg/iolist_sample/init/system_init.c @@ -21,6 +21,8 @@ */ #include "main.h" +#include "ioconfig.h" +#include "iocmg.h" BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { @@ -31,6 +33,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -38,49 +41,8 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -static void UART0_Init(void) -{ - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - - g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; - - g_uart0.baudRate = UART0_BAND_RATE; - g_uart0.dataLength = UART_DATALENGTH_8BIT; - g_uart0.stopBits = UART_STOPBITS_ONE; - g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; - g_uart0.rxMode = UART_MODE_BLOCKING; - g_uart0.fifoMode = BASE_CFG_ENABLE; - g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; - g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; - g_uart0.hwFlowCtr = BASE_CFG_DISABLE; - HAL_UART_Init(&g_uart0); -} - -static void IOCMG_Init(void) -{ - IOCMG_Handle handle = {0}; - handle.pinTypedef = UART0_RXD_PIN; /* UART0_RX pin */ - handle.pullMode = PULL_NONE; - handle.schmidtMode = SCHMIDT_ENABLE; - handle.levelShiftRate = LEVEL_SHIFT_RATE_FAST; - handle.driveRate = DRIVER_RATE_2; - HAL_IOCMG_Init(&handle); /* iocmg handle uart0_rxd init */ - - handle.pinTypedef = UART0_TXD_PIN; /* UART0_TX pin */ - handle.pullMode = PULL_NONE; - handle.schmidtMode = SCHMIDT_ENABLE; - handle.levelShiftRate = LEVEL_SHIFT_RATE_FAST; - handle.driveRate = DRIVER_RATE_2; - HAL_IOCMG_Init(&handle); /* iocmg handle uart0_txd init */ -} - void SystemInit(void) { - IOCMG_Init(); - UART0_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/iocmg/iolist_sample/readme.md b/src/application/drivers_sample/iocmg/iolist_sample/readme.md index 1793dd8bb0bdc426cbdbba46c2e1777b0282c85a..6f96d1b72485d87b0d187d0af380e4a8deb50bc7 100644 --- a/src/application/drivers_sample/iocmg/iolist_sample/readme.md +++ b/src/application/drivers_sample/iocmg/iolist_sample/readme.md @@ -11,4 +11,8 @@ + Debug串口打印配置前的iolist数据,然后打印初始化后的寄存器中的数据,判断配置的数据和预期的是否相同,同时调用HAL_IOCMG_SetXXX API接口和HAL_IOCMG_GetXXX API分别配置和获取IOCMG寄存器的数据是否符合预期。 **【注意事项】** -+ PIN NUMBER和function mode均已编码定义,在iomap中,若配置数据与定义的数据不符则配置失败返回对应的错误,已定义的pin number和function mode可在iomap.h中直接调用。 \ No newline at end of file ++ PIN NUMBER和function mode均已编码定义,在iomap中,若配置数据与定义的数据不符则配置失败返回对应的错误,已定义的pin number和function mode可在iomap.h中直接调用。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/iocmg/iolist_sample/src/iolist_sample.c b/src/application/drivers_sample/iocmg/iolist_sample/src/iolist_sample.c index 79aaac038e222b946575f41e4b42b6bde5960fd0..5e8f3e78fb253e9611c102f7905c295a1eeef45b 100644 --- a/src/application/drivers_sample/iocmg/iolist_sample/src/iolist_sample.c +++ b/src/application/drivers_sample/iocmg/iolist_sample/src/iolist_sample.c @@ -37,10 +37,10 @@ #define I2C0_SDA_PIN IOCMG_PIN_MUX(iocmg_15, FUNC_MODE_5, 0x0001) static IOCMG_Handle g_ioListTable[] = { - {UART0_TXD_PIN, PULL_BOTH, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_SLOW, DRIVER_RATE_2}, - {UART0_RXD_PIN, PULL_BOTH, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_SLOW, DRIVER_RATE_2}, - {I2C0_SCL_PIN, PULL_UP, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_FAST, DRIVER_RATE_1}, - {I2C0_SDA_PIN, PULL_UP, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_FAST, DRIVER_RATE_1}, + {UART0_TXD_PIN, PULL_BOTH, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_SLOW, DRIVER_RATE_2, {}}, + {UART0_RXD_PIN, PULL_BOTH, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_SLOW, DRIVER_RATE_2, {}}, + {I2C0_SCL_PIN, PULL_UP, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_FAST, DRIVER_RATE_1, {}}, + {I2C0_SDA_PIN, PULL_UP, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_FAST, DRIVER_RATE_1, {}}, }; const unsigned int IOLIST_SIZE = sizeof(g_ioListTable) / sizeof(g_ioListTable[0]); @@ -93,7 +93,7 @@ void IOCMG_IOListInitSample(void) /* test osc pin function */ HAL_IOCMG_SetOscClkFuncMode(BASE_CFG_ENABLE); HAL_IOCMG_SetOscClkOutputMode(BASE_CFG_ENABLE); - HAL_IOCMG_SetOscClkDriveRate(DRIVER_RATE_2); + HAL_IOCMG_SetOscClkDriveRate(OSC_CLK_DRIVER_RATE_2); /* test API */ DBG_PRINTF("\r\nOsc func mode = %d \r\n", HAL_IOCMG_GetOscClkFuncMode()); DBG_PRINTF("Osc clk output mode = %d \r\n", HAL_IOCMG_GetOscClkOutputMode()); diff --git a/src/application/drivers_sample/iocmg/sample_iocfg_list/init/main.c b/src/application/drivers_sample/iocmg/sample_iocfg_list/init/main.c index f6b262251acee05d2bd30ca2640edf8c33472198..72e0add374c457ae656957f28c3559346c052b67 100644 --- a/src/application/drivers_sample/iocmg/sample_iocfg_list/init/main.c +++ b/src/application/drivers_sample/iocmg/sample_iocfg_list/init/main.c @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -25,26 +25,34 @@ #include "sample_iocfg_list.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ UART_Handle g_uart0; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ + IOCMG_IOListInitSample(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ - IOCMG_IOListInitSample(); while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/iocmg/sample_iocfg_list/init/main.h b/src/application/drivers_sample/iocmg/sample_iocfg_list/init/main.h index 834192874f26c8828b2cf8f1692c9f50555dee79..d059d7d88546489111a34fdcd3c9e14467f4fe88 100644 --- a/src/application/drivers_sample/iocmg/sample_iocfg_list/init/main.h +++ b/src/application/drivers_sample/iocmg/sample_iocfg_list/init/main.h @@ -27,6 +27,7 @@ #include "uart.h" #include "uart_ex.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -46,4 +47,8 @@ extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/iocmg/sample_iocfg_list/init/system_init.c b/src/application/drivers_sample/iocmg/sample_iocfg_list/init/system_init.c index 1a1c721e62695b98f6c54b440bb0254308b38ab2..b0bbd474256620a65160169c46212080f75873a4 100644 --- a/src/application/drivers_sample/iocmg/sample_iocfg_list/init/system_init.c +++ b/src/application/drivers_sample/iocmg/sample_iocfg_list/init/system_init.c @@ -32,11 +32,14 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + /* 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -47,9 +50,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; @@ -67,24 +68,8 @@ static void UART0_Init(void) HAL_UART_Init(&g_uart0); } -static void IOConfig(void) -{ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ -} - void SystemInit(void) { - IOConfig(); UART0_Init(); /* USER CODE BEGIN system_init */ diff --git a/src/application/drivers_sample/iocmg/sample_iocfg_list/readme.rd b/src/application/drivers_sample/iocmg/sample_iocfg_list/readme.md similarity index 77% rename from src/application/drivers_sample/iocmg/sample_iocfg_list/readme.rd rename to src/application/drivers_sample/iocmg/sample_iocfg_list/readme.md index 1793dd8bb0bdc426cbdbba46c2e1777b0282c85a..bec4af809e152d80308e0d83fae639fb3c901b37 100644 --- a/src/application/drivers_sample/iocmg/sample_iocfg_list/readme.rd +++ b/src/application/drivers_sample/iocmg/sample_iocfg_list/readme.md @@ -11,4 +11,8 @@ + Debug串口打印配置前的iolist数据,然后打印初始化后的寄存器中的数据,判断配置的数据和预期的是否相同,同时调用HAL_IOCMG_SetXXX API接口和HAL_IOCMG_GetXXX API分别配置和获取IOCMG寄存器的数据是否符合预期。 **【注意事项】** -+ PIN NUMBER和function mode均已编码定义,在iomap中,若配置数据与定义的数据不符则配置失败返回对应的错误,已定义的pin number和function mode可在iomap.h中直接调用。 \ No newline at end of file ++ PIN NUMBER和function mode均已编码定义,在iomap中,若配置数据与定义的数据不符则配置失败返回对应的错误,已定义的pin number和function mode可在iomap.h中直接调用。 + ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/iocmg/sample_iocfg_list/src/sample_iocfg_list.c b/src/application/drivers_sample/iocmg/sample_iocfg_list/src/sample_iocfg_list.c index ce9a625f4d22c772e1b5c92b6d1f199d74cd7dca..7ae30159002e6f363105290dd1a2bd870e9c6ca7 100644 --- a/src/application/drivers_sample/iocmg/sample_iocfg_list/src/sample_iocfg_list.c +++ b/src/application/drivers_sample/iocmg/sample_iocfg_list/src/sample_iocfg_list.c @@ -30,6 +30,28 @@ #include "main.h" #include "sample_iocfg_list.h" +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || \ + defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) +/* 3066m */ + +/* for sample normalize in different chip, \ + when user use it, needn't define this macro, just need find the io pin in the iomap.h */ +#define UART0_TXD_PIN IOCMG_PIN_MUX(IOCFG_GPIO0_3, FUNC_MODE_4, 0x0a00) +#define UART0_RXD_PIN IOCMG_PIN_MUX(IOCFG_GPIO0_4, FUNC_MODE_4, 0x0a00) +#define I2C0_SCL_PIN IOCMG_PIN_MUX(IOCFG_GPIO4_1, FUNC_MODE_2, 0x0a00) +#define I2C0_SDA_PIN IOCMG_PIN_MUX(IOCFG_GPIO4_2, FUNC_MODE_2, 0x0a00) + +#define XTAL_IN_PIN IOCMG_PIN_MUX(IOCFG_GPIO0_4, FUNC_MODE_12, 0x0a00) +#define XTAL_OUT_PIN IOCMG_PIN_MUX(IOCFG_GPIO0_3, FUNC_MODE_12, 0x0a00) + +static IOCMG_Handle g_ioListTable[] = { + {UART0_TXD_PIN, PULL_NONE, SCHMIDT_DISABLE, LEVEL_SHIFT_RATE_SLOW, DRIVER_RATE_2, {}}, + {UART0_RXD_PIN, PULL_NONE, SCHMIDT_DISABLE, LEVEL_SHIFT_RATE_SLOW, DRIVER_RATE_2, {}}, + {I2C0_SCL_PIN, PULL_UP, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_FAST, DRIVER_RATE_1, {}}, + {I2C0_SDA_PIN, PULL_UP, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_FAST, DRIVER_RATE_1, {}}, +}; +#else +/* 3061m */ /* for sample normalize in different chip, \ when user use it, needn't define this macro, just need find the io pin in the iomap.h */ #define UART0_TXD_PIN IOCMG_PIN_MUX(IOCFG_GPIO0_3, FUNC_MODE_3, 0x0230) @@ -38,14 +60,49 @@ #define I2C0_SDA_PIN IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_1, 0x0220) static IOCMG_Handle g_ioListTable[] = { - {UART0_TXD_PIN, PULL_NONE, SCHMIDT_DISABLE, LEVEL_SHIFT_RATE_SLOW, DRIVER_RATE_2}, - {UART0_RXD_PIN, PULL_NONE, SCHMIDT_DISABLE, LEVEL_SHIFT_RATE_SLOW, DRIVER_RATE_2}, - {I2C0_SCL_PIN, PULL_UP, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_FAST, DRIVER_RATE_1}, - {I2C0_SDA_PIN, PULL_UP, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_FAST, DRIVER_RATE_1}, + {UART0_TXD_PIN, PULL_NONE, SCHMIDT_DISABLE, LEVEL_SHIFT_RATE_SLOW, DRIVER_RATE_2, {}}, + {UART0_RXD_PIN, PULL_NONE, SCHMIDT_DISABLE, LEVEL_SHIFT_RATE_SLOW, DRIVER_RATE_2, {}}, + {I2C0_SCL_PIN, PULL_UP, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_FAST, DRIVER_RATE_1, {}}, + {I2C0_SDA_PIN, PULL_UP, SCHMIDT_ENABLE, LEVEL_SHIFT_RATE_FAST, DRIVER_RATE_1, {}}, }; - +#endif const unsigned int IOLIST_SIZE = sizeof(g_ioListTable) / sizeof(g_ioListTable[0]); +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || \ + defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) +/** + * @brief Config and update crystal oscillator functions, it needs external crystal oscillator. + * @param None + * @retval None. + */ +static void IOCMG_OscFunc(void) +{ + /* The external crystal oscillator conflicts with UART0. */ + /* After OSC enabled, the DBG_PRINT function cannot be used. */ + HAL_IOCMG_SetPinAltFuncMode(XTAL_IN_PIN); // func + HAL_IOCMG_SetPinPullMode(XTAL_IN_PIN, PULL_NONE); // pd, pu + HAL_IOCMG_SetPinSchmidtMode(XTAL_IN_PIN, SCHMIDT_DISABLE); // se + HAL_IOCMG_SetPinLevelShiftRate(XTAL_IN_PIN, LEVEL_SHIFT_RATE_SLOW); // sr + HAL_IOCMG_SetPinDriveRate(XTAL_IN_PIN, DRIVER_RATE_2); // ds + + HAL_IOCMG_SetPinAltFuncMode(XTAL_OUT_PIN); // func + HAL_IOCMG_SetPinPullMode(XTAL_OUT_PIN, PULL_NONE); // pd, pu + HAL_IOCMG_SetPinSchmidtMode(XTAL_OUT_PIN, SCHMIDT_DISABLE); // se + HAL_IOCMG_SetPinLevelShiftRate(XTAL_OUT_PIN, LEVEL_SHIFT_RATE_SLOW); // sr + HAL_IOCMG_SetPinDriveRate(XTAL_OUT_PIN, DRIVER_RATE_2); // ds + + /* test osc pin function */ + HAL_IOCMG_SetOscClkFuncMode(BASE_CFG_ENABLE); + HAL_IOCMG_SetOscClkOutputMode(BASE_CFG_ENABLE); + HAL_IOCMG_SetOscClkDriveRate(OSC_CLK_DRIVER_RATE_2); + /* test API */ + DBG_PRINTF("\r\nOsc func mode = %d \r\n", HAL_IOCMG_GetOscClkFuncMode()); + DBG_PRINTF("Osc clk output mode = %d \r\n", HAL_IOCMG_GetOscClkOutputMode()); + DBG_PRINTF("Osc drive rate = %d \r\n", HAL_IOCMG_GetOscClkDriveRate()); + BASE_FUNC_DELAY_MS(1000U); /* delay 1s */ +} +#endif + /** * @brief Init IOLIST by HAL_IOCMG_Init API. * @param None @@ -53,6 +110,7 @@ const unsigned int IOLIST_SIZE = sizeof(g_ioListTable) / sizeof(g_ioListTable[0] */ void IOCMG_IOListInitSample(void) { + SystemInit(); /* init method 1 */ HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); @@ -71,6 +129,7 @@ void IOCMG_IOListInitSample(void) DBG_PRINTF("Level Shift Rate = %d \r\n", HAL_IOCMG_GetPinLevelShiftRate(g_ioListTable[index].pinTypedef)); DBG_PRINTF("Schmidt Mode = %d \r\n", HAL_IOCMG_GetPinSchmidtMode(g_ioListTable[index].pinTypedef)); DBG_PRINTF("Drive Rate = %d \r\n", HAL_IOCMG_GetPinDriveRate(g_ioListTable[index].pinTypedef)); + BASE_FUNC_DELAY_MS(10); /* 10: Prevents the printing rate of the serial port from being too high. */ } @@ -90,17 +149,13 @@ void IOCMG_IOListInitSample(void) DBG_PRINTF("Level Shift Rate = %d \r\n", HAL_IOCMG_GetPinLevelShiftRate(g_ioListTable[index].pinTypedef)); DBG_PRINTF("Schmidt Mode = %d \r\n", HAL_IOCMG_GetPinSchmidtMode(g_ioListTable[index].pinTypedef)); DBG_PRINTF("Drive Rate = %d \r\n", HAL_IOCMG_GetPinDriveRate(g_ioListTable[index].pinTypedef)); - BASE_FUNC_DELAY_MS(10); /* 10 : Prevents the printing rate of the serial port from being too high. */ + BASE_FUNC_DELAY_MS(100); /* 100 : Prevents the printing rate of the serial port from being too high. */ } - - /* test osc pin function */ - HAL_IOCMG_SetOscClkFuncMode(BASE_CFG_ENABLE); - HAL_IOCMG_SetOscClkOutputMode(BASE_CFG_ENABLE); - HAL_IOCMG_SetOscClkDriveRate(DRIVER_RATE_2); - /* test API */ - DBG_PRINTF("\r\nOsc func mode = %d \r\n", HAL_IOCMG_GetOscClkFuncMode()); - DBG_PRINTF("Osc clk output mode = %d \r\n", HAL_IOCMG_GetOscClkOutputMode()); - DBG_PRINTF("Osc drive rate = %d \r\n", HAL_IOCMG_GetOscClkDriveRate()); - BASE_FUNC_DELAY_MS(1000U); /* delay 1s */ +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || \ + defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + /* The external crystal oscillator conflicts with UART0. */ + /* After OSC enabled, the DBG_PRINT function cannot be used. */ + IOCMG_OscFunc(); +#endif } } diff --git a/src/application/drivers_sample/pga/sample_pga/init/main.c b/src/application/drivers_sample/pga/sample_pga/init/main.c index cd2fe885dbd54744253b4633800557a85ca18dfc..84924f9324f8b395ed409187ad94ae9c18c1eb0d 100644 --- a/src/application/drivers_sample/pga/sample_pga/init/main.c +++ b/src/application/drivers_sample/pga/sample_pga/init/main.c @@ -19,15 +19,39 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" #include "main.h" - +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ PGA_Handle g_pga; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ SystemInit(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga/init/main.h b/src/application/drivers_sample/pga/sample_pga/init/main.h index 7dd948b29c931b74c5440406684708e7029c2df6..c519e7ab848a793e55c9d3dbdd5ef42d1dd353bf 100644 --- a/src/application/drivers_sample/pga/sample_pga/init/main.h +++ b/src/application/drivers_sample/pga/sample_pga/init/main.h @@ -35,9 +35,18 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern PGA_Handle g_pga; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga/init/system_init.c b/src/application/drivers_sample/pga/sample_pga/init/system_init.c index 6afdfc728b8e4e77c6e907f0123ccfb11b4a74d0..9563ac8a125b8bf3b12e00b6b797d468ce5e235a 100644 --- a/src/application/drivers_sample/pga/sample_pga/init/system_init.c +++ b/src/application/drivers_sample/pga/sample_pga/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { @@ -32,6 +33,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -41,41 +43,36 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void PGA0_Init(void) { - HAL_CRG_IpEnableSet(PGA0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(PGA0_BASE, IP_CLK_ENABLE); /* Enbale PGA ip */ - g_pga.baseAddress = PGA0_BASE; - g_pga.enable = BASE_CFG_ENABLE; - g_pga.extLoopbackEn = BASE_CFG_DISABLE; - g_pga.pgaMux = PGA_INTER_RES_VI0; /* use Internal resistance */ - g_pga.gain = PGA_GAIN_2X; /* Gain value: 2 */ + g_pga.baseAddress = PGA0_BASE; /* Base address */ + g_pga.externalResistorMode = BASE_CFG_ENABLE; /* Enable external resisitance */ + g_pga.handleEx.pgaMux = PGA_INTER_RES_VI0; + g_pga.gain = PGA_GAIN_2X; HAL_PGA_Init(&g_pga); + DCL_PGA_EnableOut(g_pga.baseAddress); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_40.BIT.func = 0x8; /* 0x8 is PGA0_ANA_EXT */ - iconfig->iocmg_40.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_40.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_40.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_40.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_40.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO21_AS_PGA0_ANA_P0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO21_AS_PGA0_ANA_P0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO21_AS_PGA0_ANA_P0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO21_AS_PGA0_ANA_P0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO21_AS_PGA0_ANA_P0, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_39.BIT.func = 0x9; /* 0x9 is PGA0_ANA_N */ - iconfig->iocmg_39.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_39.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_39.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_39.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_39.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO22_AS_PGA0_ANA_N0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO22_AS_PGA0_ANA_N0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO22_AS_PGA0_ANA_N0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO22_AS_PGA0_ANA_N0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO22_AS_PGA0_ANA_N0, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_38.BIT.func = 0x9; /* 0x9 is PGA0_ANA_P */ - iconfig->iocmg_38.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_38.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_38.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_38.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_38.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO23_AS_PGA0_ANA_EXT0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO23_AS_PGA0_ANA_EXT0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO23_AS_PGA0_ANA_EXT0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO23_AS_PGA0_ANA_EXT0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO23_AS_PGA0_ANA_EXT0, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/pga/sample_pga/readme.md b/src/application/drivers_sample/pga/sample_pga/readme.md index dc1f94adab672b1e9beadf4d38653d1c58b2ded8..0d542492d5e33af63cb4b18d16c5a0f6b3c4f2ef 100644 --- a/src/application/drivers_sample/pga/sample_pga/readme.md +++ b/src/application/drivers_sample/pga/sample_pga/readme.md @@ -11,4 +11,8 @@ + 在IOCMG_38输入正端信号,在IOCMG_39输入负端信号,在IOCMG_40输出放大后的信号。 **【注意事项】** -+ 增益可编程为x2, x4, x8, x16。 \ No newline at end of file ++ 增益可编程为x2, x4, x8, x16。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_external_resistor/inc/sample_pga_result_sampling.h b/src/application/drivers_sample/pga/sample_pga_external_resistor/inc/sample_pga_result_sampling.h new file mode 100644 index 0000000000000000000000000000000000000000..ea4867a413448760ba9716965fe5177f2546c4a8 --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_external_resistor/inc/sample_pga_result_sampling.h @@ -0,0 +1,31 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_pga_result_sampling.h + * @author MCU Driver Team + * @brief pga sample module. + * @details This file provides users with sample code to help use pga function. + */ +#ifndef SAMPLE_PGA_RESULT_SAMPLING_H +#define SAMPLE_PGA_RESULT_SAMPLING_H + +#include "debug.h" +#include "adc.h" +#include "main.h" + +void PGA_ReultSampling(void); +#endif \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_external_resistor/init/main.c b/src/application/drivers_sample/pga/sample_pga_external_resistor/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..db8accac49063177f9e0d5b97661c90cb87766e4 --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_external_resistor/init/main.c @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +#include "sample_pga_result_sampling.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +PGA_Handle g_pga0; +UART_Handle g_uart0; +ADC_Handle g_adc0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + PGA_ReultSampling(); + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_external_resistor/init/main.h b/src/application/drivers_sample/pga/sample_pga_external_resistor/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..255496aa2c05d321991e7ab9869dfafa1693ee25 --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_external_resistor/init/main.h @@ -0,0 +1,59 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "adc.h" +#include "adc_ex.h" +#include "uart.h" +#include "uart_ex.h" +#include "pga.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern PGA_Handle g_pga0; +extern UART_Handle g_uart0; +extern ADC_Handle g_adc0; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_external_resistor/init/system_init.c b/src/application/drivers_sample/pga/sample_pga_external_resistor/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..68573dfa631b3cf573fb5b9488eb7ede983ac94f --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_external_resistor/init/system_init.c @@ -0,0 +1,143 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void ADC0_Init(void) +{ + HAL_CRG_IpEnableSet(ADC0_BASE, IP_CLK_ENABLE); /* Clock enable */ + HAL_CRG_IpClkSelectSet(ADC0_BASE, CRG_ADC_CLK_ASYN_PLL_DIV); + HAL_CRG_IpClkDivSet(ADC0_BASE, CRG_ADC_DIV_1); + + g_adc0.baseAddress = ADC0; + g_adc0.socPriority = ADC_PRIMODE_ALL_ROUND; + + HAL_ADC_Init(&g_adc0); + + SOC_Param socParam = {0}; + socParam.adcInput = ADC_CH_ADCINA0; /* PGA0_OUT(ADC AIN0) */ + socParam.sampleTotalTime = ADC_SOCSAMPLE_5CLK; /* adc sample total time 5 adc_clk */ + socParam.trigSource = ADC_TRIGSOC_SOFT; + socParam.continueMode = BASE_CFG_DISABLE; + socParam.finishMode = ADC_SOCFINISH_NONE; + HAL_ADC_ConfigureSoc(&g_adc0, ADC_SOC_NUM0, &socParam); +} + +static void PGA0_Init(void) +{ + HAL_CRG_IpEnableSet(PGA0_BASE, IP_CLK_ENABLE); /* Clock enable */ + + g_pga0.baseAddress = PGA0_BASE; /* Base address */ + g_pga0.externalResistorMode = BASE_CFG_ENABLE; + g_pga0.handleEx.extCapCompensation = PGA_EXT_COMPENSATION_3X; + g_pga0.handleEx.vinChannel = PGA_CH_VIN0; + HAL_PGA_Init(&g_pga0); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; /* Band rate: 115200 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; /* Length 8bit */ + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + /* Config PIN21 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_3_AS_PGA0_ANA_P0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_3_AS_PGA0_ANA_P0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_3_AS_PGA0_ANA_P0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_3_AS_PGA0_ANA_P0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_3_AS_PGA0_ANA_P0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN22 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_4_AS_PGA0_ANA_N0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_4_AS_PGA0_ANA_N0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_4_AS_PGA0_ANA_N0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_4_AS_PGA0_ANA_N0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_4_AS_PGA0_ANA_N0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN23 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_PGA0_ANA_EXT0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_PGA0_ANA_EXT0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_PGA0_ANA_EXT0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_PGA0_ANA_EXT0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_PGA0_ANA_EXT0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + ADC0_Init(); + PGA0_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_external_resistor/readme.md b/src/application/drivers_sample/pga/sample_pga_external_resistor/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..9f86b5f8c609f98e9a1b4e9d478508a31b3a811e --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_external_resistor/readme.md @@ -0,0 +1,26 @@ +# 运放的基本使用 - 基于低压生态板,外部电阻模式的增益放大 +## 关键字: 外部电阻模式 + +**【功能描述】** ++ 外部电阻模式下,对输入信号进行放大。 + ++ PGA通过外部电阻放大,输出到PGA_OUT,与N端形成负反馈。 + ++ 外部电阻放大倍数为3.03倍 + ++ 在没有任何输入的情况下,ADC采样得到的值为1.65V的偏置电压。 + +**【示例配置】** ++ 本示例中使用了PGA的外部电阻模式,电源输入搭配N/P端,通过外部电阻放大输出到PGA_OUT,并通过ADC将最后采样结果输出。 + ++ 本示例中采用外部电阻模式, 增益放大值为3.03。 + +**【示例效果】** ++ PGA的运放结果会通过ADC的采样进行输出,并通过串口0将结果输出。 + +**【注意事项】** ++ 外部电阻模式,依赖外部电阻,灵活可调增益。 + ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_external_resistor/src/sample_pga_result_sampling.c b/src/application/drivers_sample/pga/sample_pga_external_resistor/src/sample_pga_result_sampling.c new file mode 100644 index 0000000000000000000000000000000000000000..26ad99d1716f3bfcf2e727a364556d66c10b4c25 --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_external_resistor/src/sample_pga_result_sampling.c @@ -0,0 +1,52 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_pga_result_sampling.c + * @author MCU Driver Team + * @brief pga sample module. + * @details (1) In this example, the external resistor mode of the PGA is used,the PGA is amplified by 3.03 times, + * and the last sampled result is output through the ADC. + * (2) the external resistor mode is used, and the gain magnification value is 3.03. + */ + +#include "sample_pga_result_sampling.h" + +/** + * @brief The PGA amplifies the voltage and uses the ADC to sample the output of the PGA. + * @param None. + * @retval None. + */ +void PGA_ReultSampling(void) +{ + SystemInit(); + DBG_PRINTF("The PGA amplifies the output and uses the ADC to sample the result.\r\n"); + + /* Configure ADC software triggering. */ + HAL_ADC_SoftTrigSample(&g_adc0, ADC_SOC_NUM1); + BASE_FUNC_DELAY_MS(15); /* delay 15 ms */ + if (HAL_ADC_CheckSocFinish(&g_adc0, ADC_SOC_NUM1) == BASE_STATUS_ERROR) { + DBG_PRINTF("ADC sampling error output.\r\n"); + return; + } + /* Software trigger ADC sampling */ + unsigned int ret = HAL_ADC_GetConvResult(&g_adc0, ADC_SOC_NUM1); + DBG_PRINTF("Sampling completed, result: %x\r\n", ret); + float voltage = (float)ret / (float)4096 * 3.3f; /* 4096 and 3.3 are for Sample Value Conversion */ + DBG_PRINTF("Real Output voltage of the PGA: %fV\r\n", voltage); + DBG_PRINTF("Theoretical Output voltage of the PGA: 1.65V\r\n"); + return; +} \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/main.c b/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/main.c index 3e64c92291a311908bc5df3f1be681f93fc1e108..4c533fd414c463ed0dc2fb07cc97fe53983e3a94 100644 --- a/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/main.c +++ b/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/main.c @@ -19,16 +19,39 @@ * @author MCU Driver Team * @brief Main program body. */ + #include "typedefs.h" #include "feature.h" #include "main.h" - +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ PGA_Handle g_pgaExt; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ SystemInit(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/main.h b/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/main.h index 103838e0dc42bda7716eb0d9a04ca50d88746d6d..d7b763eaa5fc5560b27f50826fb93ed74316534b 100644 --- a/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/main.h +++ b/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/main.h @@ -35,9 +35,18 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern PGA_Handle g_pgaExt; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/system_init.c b/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/system_init.c index ab82f453a137854c79a112fb9371b704b6404d50..fed392ece7200b07dc36d9e315ce41d57e1f72a3 100644 --- a/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/system_init.c +++ b/src/application/drivers_sample/pga/sample_pga_extra_resistor/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { @@ -32,6 +33,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -41,41 +43,37 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void PGA1_Init(void) { - HAL_CRG_IpEnableSet(PGA1_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(PGA1_BASE, IP_CLK_ENABLE); /* Enbale PGA ip */ - g_pgaExt.baseAddress = PGA1_BASE; /* pga1 */ - g_pgaExt.enable = BASE_CFG_ENABLE; - g_pgaExt.extLoopbackEn = BASE_CFG_DISABLE; - g_pgaExt.pgaMux = PGA_EXT_RES_VI0; /* use external resistor */ + g_pgaExt.baseAddress = PGA1_BASE; /* Base address */ + g_pgaExt.externalResistorMode = BASE_CFG_ENABLE; /* Enable external resisitance */ + g_pgaExt.handleEx.pgaMux = PGA_EXT_RES_VI0; g_pgaExt.gain = PGA_GAIN_1X; HAL_PGA_Init(&g_pgaExt); + DCL_PGA_EnableOut(g_pgaExt.baseAddress); + DCL_PGA_EnableExtOut(g_pgaExt.baseAddress); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_22.BIT.func = 0x9; /* 0x9 is PGA1_ANA_P */ - iconfig->iocmg_22.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_22.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_22.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_22.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_22.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO6_AS_PGA1_ANA_P0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO6_AS_PGA1_ANA_P0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO6_AS_PGA1_ANA_P0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO6_AS_PGA1_ANA_P0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO6_AS_PGA1_ANA_P0, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_23.BIT.func = 0x9; /* 0x9 is PGA1_ANA_N */ - iconfig->iocmg_23.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_23.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_23.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_23.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_23.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO7_AS_PGA1_ANA_N0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO7_AS_PGA1_ANA_N0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO7_AS_PGA1_ANA_N0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO7_AS_PGA1_ANA_N0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO7_AS_PGA1_ANA_N0, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_24.BIT.func = 0x8; /* 0x8 is PGA1_ANA_EXT */ - iconfig->iocmg_24.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_24.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_24.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_24.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_24.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO8_AS_PGA1_ANA_EXT0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO8_AS_PGA1_ANA_EXT0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO8_AS_PGA1_ANA_EXT0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO8_AS_PGA1_ANA_EXT0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO8_AS_PGA1_ANA_EXT0, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/pga/sample_pga_extra_resistor/readme.md b/src/application/drivers_sample/pga/sample_pga_extra_resistor/readme.md index faffe87d611fecc6a6cbd2eb0df2df7357966eba..c39e1c6e365f56f6a02035ce8bf0ab60af03dd4d 100644 --- a/src/application/drivers_sample/pga/sample_pga_extra_resistor/readme.md +++ b/src/application/drivers_sample/pga/sample_pga_extra_resistor/readme.md @@ -11,4 +11,8 @@ + 在IOCMG_22输入正端信号,在IOCMG_23输入负端信号,在IOCMG_24输出放大后的信号。 **【注意事项】** -+ 外部电阻模式,依赖外部电阻,灵活可调增益。 \ No newline at end of file ++ 外部电阻模式,依赖外部电阻,灵活可调增益。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_internal_resistor/inc/sample_pga_result_sampling.h b/src/application/drivers_sample/pga/sample_pga_internal_resistor/inc/sample_pga_result_sampling.h new file mode 100644 index 0000000000000000000000000000000000000000..ea4867a413448760ba9716965fe5177f2546c4a8 --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_internal_resistor/inc/sample_pga_result_sampling.h @@ -0,0 +1,31 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_pga_result_sampling.h + * @author MCU Driver Team + * @brief pga sample module. + * @details This file provides users with sample code to help use pga function. + */ +#ifndef SAMPLE_PGA_RESULT_SAMPLING_H +#define SAMPLE_PGA_RESULT_SAMPLING_H + +#include "debug.h" +#include "adc.h" +#include "main.h" + +void PGA_ReultSampling(void); +#endif \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_internal_resistor/init/main.c b/src/application/drivers_sample/pga/sample_pga_internal_resistor/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..db8accac49063177f9e0d5b97661c90cb87766e4 --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_internal_resistor/init/main.c @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +#include "sample_pga_result_sampling.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +PGA_Handle g_pga0; +UART_Handle g_uart0; +ADC_Handle g_adc0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + PGA_ReultSampling(); + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_internal_resistor/init/main.h b/src/application/drivers_sample/pga/sample_pga_internal_resistor/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..255496aa2c05d321991e7ab9869dfafa1693ee25 --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_internal_resistor/init/main.h @@ -0,0 +1,59 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "adc.h" +#include "adc_ex.h" +#include "uart.h" +#include "uart_ex.h" +#include "pga.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern PGA_Handle g_pga0; +extern UART_Handle g_uart0; +extern ADC_Handle g_adc0; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_internal_resistor/init/system_init.c b/src/application/drivers_sample/pga/sample_pga_internal_resistor/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..7f56cadfde8b0c8070a8f327bfffe62500033ccb --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_internal_resistor/init/system_init.c @@ -0,0 +1,137 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void ADC0_Init(void) +{ + HAL_CRG_IpEnableSet(ADC0_BASE, IP_CLK_ENABLE); /* Clock enable */ + HAL_CRG_IpClkSelectSet(ADC0_BASE, CRG_ADC_CLK_ASYN_PLL_DIV); + HAL_CRG_IpClkDivSet(ADC0_BASE, CRG_ADC_DIV_1); + + g_adc0.baseAddress = ADC0; + g_adc0.socPriority = ADC_PRIMODE_ALL_ROUND; + + HAL_ADC_Init(&g_adc0); + + SOC_Param socParam = {0}; + socParam.adcInput = ADC_CH_ADCINA0; /* PGA0_OUT(ADC AIN0) */ + socParam.sampleTotalTime = ADC_SOCSAMPLE_5CLK; /* adc sample total time 5 adc_clk */ + socParam.trigSource = ADC_TRIGSOC_SOFT; + socParam.continueMode = BASE_CFG_DISABLE; + socParam.finishMode = ADC_SOCFINISH_NONE; + HAL_ADC_ConfigureSoc(&g_adc0, ADC_SOC_NUM0, &socParam); +} + +static void PGA0_Init(void) +{ + HAL_CRG_IpEnableSet(PGA0_BASE, IP_CLK_ENABLE); /* Clock enable */ + + g_pga0.baseAddress = PGA0_BASE; /* Base address */ + g_pga0.externalResistorMode = BASE_CFG_DISABLE; + g_pga0.gain = PGA_GAIN_2X; + g_pga0.handleEx.vinChannel = PGA_CH_VIN0; + HAL_PGA_Init(&g_pga0); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; /* Band rate: 115200 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; /* Length 8bit */ + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + /* Config PIN21 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_3_AS_PGA0_ANA_P0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_3_AS_PGA0_ANA_P0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_3_AS_PGA0_ANA_P0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_3_AS_PGA0_ANA_P0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_3_AS_PGA0_ANA_P0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN22 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_4_AS_PGA0_ANA_N0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_4_AS_PGA0_ANA_N0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_4_AS_PGA0_ANA_N0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_4_AS_PGA0_ANA_N0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_4_AS_PGA0_ANA_N0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + ADC0_Init(); + PGA0_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_internal_resistor/readme.md b/src/application/drivers_sample/pga/sample_pga_internal_resistor/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..c5c7f68ecb4486c12aa692bb0e131497f28b22aa --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_internal_resistor/readme.md @@ -0,0 +1,22 @@ +# 运放的基本使用 - 基于低压生态板,ADC采样PGA的输出电压 +## 关键字: PGA放大电压 + +**【功能描述】** ++ 内部电阻模式下,PGA对输入电压放大,并使用ADC采样PGA的输出电压。 + ++ PGA的P端输入为409mV,N端输入为0,通过内部电阻放大,输出到PGA_OUT。 + +**【示例配置】** ++ 本示例中使用了PGA的内部电阻模式,电压输出到PGA端,通过PGA进行2倍的放大,并通过ADC将最后采样结果输出。 + ++ 本示例中采用内部电阻模式, 增益放大值为X2倍,增益值可在PGA模块的配置界面中进行更改,其对应的设置选项为“g_pga.gain”。 + +**【示例效果】** ++ PGA的运放结果会通过ADC的采样进行输出,并通过串口0将结果输出。 + +**【注意事项】** ++ 增益可编程为x2, x4, x8, x16。 + ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_internal_resistor/src/sample_pga_result_sampling.c b/src/application/drivers_sample/pga/sample_pga_internal_resistor/src/sample_pga_result_sampling.c new file mode 100644 index 0000000000000000000000000000000000000000..0b5e0d8bd6883d058da3d83cefa9072814694bee --- /dev/null +++ b/src/application/drivers_sample/pga/sample_pga_internal_resistor/src/sample_pga_result_sampling.c @@ -0,0 +1,64 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_pga_result_sampling.c + * @author MCU Driver Team + * @brief pga sample module. + * @details (1) In this example, the internal resistor mode of the PGA is used. The voltage of PGA_N and PGA_P + * are 0mV 410mV, the PGA is amplified by 2 times, and the last sampled result is output through the ADC. + * (2) the internal resistor mode is used, and the gain magnification value is X2. + * The gain value can be changed on the PGA module configuration interface. + */ + +#include "sample_pga_result_sampling.h" + +/** + * @brief The PGA amplifies the voltage and uses the ADC to sample the output of the PGA. + * @param None. + * @retval None. + */ +void PGA_ReultSampling(void) +{ + SystemInit(); + DBG_PRINTF("The PGA amplifies the output and uses the ADC to sample the result.\r\n"); + /* Configure ADC software triggering. */ + HAL_ADC_SoftTrigSample(&g_adc0, ADC_SOC_NUM1); + BASE_FUNC_DELAY_MS(10); /* delay 10 ms */ + if (HAL_ADC_CheckSocFinish(&g_adc0, ADC_SOC_NUM1) == BASE_STATUS_ERROR) { + DBG_PRINTF("ADC sampling error output.\r\n"); + return; + } + /* Software trigger ADC sampling */ + unsigned int ret = HAL_ADC_GetConvResult(&g_adc0, ADC_SOC_NUM1); + + DBG_PRINTF("Sampling completed, result: %x\r\n", ret); + float voltage = (float)ret / (float)4096 * 3.3f; /* 4096 and 3.3 are for Sample Value Conversion */ + DBG_PRINTF("Output voltage of the PGA: %fV\r\n", voltage); + + /* Calc amplify factor. */ + float ampfy = 2.0f; /* 2 is basic amplify factors. */ + unsigned int gain = g_pga0.gain; + while (gain > 0) { + ampfy *= 2.0f; /* 2 is factors. */ + gain--; + }; + /* Calc output voltage, 0.409 is input voltage. */ + float output = 0.409f * ampfy; + DBG_PRINTF("Theoretical Output voltage of the PGA: %fV\r\n", output); + + return; +} \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_result_sampling/init/main.c b/src/application/drivers_sample/pga/sample_pga_result_sampling/init/main.c index baca48b079708056cb4208bb2604db0ad21d7b21..e6219e1fc7b9b78f3b3ab747ebb5b8aacbfcb128 100644 --- a/src/application/drivers_sample/pga/sample_pga_result_sampling/init/main.c +++ b/src/application/drivers_sample/pga/sample_pga_result_sampling/init/main.c @@ -25,28 +25,36 @@ #include "sample_pga_result_sampling.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ -PGA_Handle g_pga0; -UART_Handle g_uart0; -ADC_Handle g_adc; +PGA_Handle g_pga0; +UART_Handle g_uart0; +ADC_Handle g_adc; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ PGA_ReultSampling(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_result_sampling/init/main.h b/src/application/drivers_sample/pga/sample_pga_result_sampling/init/main.h index c9708177117c1b5225957b844a189ad3a3808a1b..05c54852e92d116c7aac033b0cc67a0c1a692558 100644 --- a/src/application/drivers_sample/pga/sample_pga_result_sampling/init/main.h +++ b/src/application/drivers_sample/pga/sample_pga_result_sampling/init/main.h @@ -24,13 +24,13 @@ #ifndef McuMagicTag_SYSTEM_INIT_H #define McuMagicTag_SYSTEM_INIT_H +#include "adc.h" +#include "adc_ex.h" #include "uart.h" #include "uart_ex.h" -#include "dac.h" #include "pga.h" #include "crg.h" #include "iocmg.h" -#include "adc.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -45,10 +45,15 @@ #define XTAL_DRV_LEVEL2 0x01U #define XTAL_DRV_LEVEL1 0x00U +extern PGA_Handle g_pga0; extern UART_Handle g_uart0; extern ADC_Handle g_adc; -extern PGA_Handle g_pga0; + BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_result_sampling/init/system_init.c b/src/application/drivers_sample/pga/sample_pga_result_sampling/init/system_init.c index 7060c137b9bee15607eec4754a068f2a96d3ab2d..86687c88c2174808f6e3b2866b69e3ebee7e73c0 100644 --- a/src/application/drivers_sample/pga/sample_pga_result_sampling/init/system_init.c +++ b/src/application/drivers_sample/pga/sample_pga_result_sampling/init/system_init.c @@ -28,76 +28,78 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { - BASE_FUNC_ASSERT_PARAM(coreClkSelect != NULL); - CRG_Handle crg; crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; - crg.pllFbDiv = 0x30; /* PLL loop divider ratio = 0x30 */ crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = 0; /* Inner clock HOSC select. */ - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; /* Set the 1MHz clock select. */ - crg.handleEx.clk1MDiv = 0x29; /* Default frequency divider of the 1 MHz clock = 0x29 */ + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + /* 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { - return BASE_STATUS_ERROR; /* CRG init error. */ + return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; return BASE_STATUS_OK; } +static void ADC0_Init(void) +{ + HAL_CRG_IpEnableSet(ADC0_BASE, IP_CLK_ENABLE); /* ADC clock configure. */ + HAL_CRG_IpClkSelectSet(ADC0_BASE, CRG_ADC_CLK_ASYN_PLL_DIV); + HAL_CRG_IpClkDivSet(ADC0_BASE, CRG_ADC_DIV_1); + + g_adc.baseAddress = ADC0; + g_adc.socPriority = ADC_PRIMODE_ALL_ROUND; + + HAL_ADC_Init(&g_adc); /* ADC init configure. */ + + SOC_Param socParam = {0}; + socParam.adcInput = ADC_CH_ADCINA0; /* PGA0_OUT(ADC AIN0) */ + socParam.sampleTotalTime = ADC_SOCSAMPLE_5CLK; /* adc sample total time 5 adc_clk */ + socParam.trigSource = ADC_TRIGSOC_SOFT; + socParam.continueMode = BASE_CFG_DISABLE; + socParam.finishMode = ADC_SOCFINISH_NONE; + HAL_ADC_ConfigureSoc(&g_adc, ADC_SOC_NUM1, &socParam); /* SOC configure. */ +} + static void PGA0_Init(void) { HAL_CRG_IpEnableSet(PGA0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(PGA0_BASE, 0); g_pga0.baseAddress = PGA0_BASE; - g_pga0.gain = PGA_GAIN_2X; /* PGA gain value. */ - g_pga0.externalResistorMode = BASE_CFG_DISABLE; /* Inner resistor mode. */ + g_pga0.gain = PGA_GAIN_2X; /* PGA gain value. */ + g_pga0.externalResistorMode = BASE_CFG_DISABLE; /* Inner resistor mode. */ HAL_PGA_Init(&g_pga0); } static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ g_uart0.baseAddress = UART0; + g_uart0.baudRate = UART0_BAND_RATE; - g_uart0.dataLength = UART_DATALENGTH_8BIT; /* Word length 8 bit. */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; /* Word length 8 bit. */ g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; /* UART blocking mode. */ + g_uart0.txMode = UART_MODE_BLOCKING; /* UART blocking mode. */ g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; - g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; /* UART FIFO depth. */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; /* UART FIFO depth. */ g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; - g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; /* Oversamping 16x. */ + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; /* Oversamping 16x. */ g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_7_AS_PGA0_OUT); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_7_AS_PGA0_OUT, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_7_AS_PGA0_OUT, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_7_AS_PGA0_OUT, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_7_AS_PGA0_OUT, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_6_AS_PGA0_N0); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_6_AS_PGA0_N0, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_6_AS_PGA0_N0, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_6_AS_PGA0_N0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_6_AS_PGA0_N0, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_5_AS_PGA0_P0); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_5_AS_PGA0_P0, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_5_AS_PGA0_P0, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_5_AS_PGA0_P0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_5_AS_PGA0_P0, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ @@ -109,27 +111,18 @@ static void IOConfig(void) HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ -} + HAL_IOCMG_SetPinAltFuncMode(GPIO2_6_AS_PGA0_N0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_6_AS_PGA0_N0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_6_AS_PGA0_N0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_6_AS_PGA0_N0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_6_AS_PGA0_N0, DRIVER_RATE_2); /* Output signal edge fast/slow */ -static void ADC0_Init(void) -{ - HAL_CRG_IpEnableSet(ADC0_BASE, IP_CLK_ENABLE); /* ADC clock configure. */ - HAL_CRG_IpClkSelectSet(ADC0_BASE, CRG_ADC_CLK_ASYN_PLL_DIV); - HAL_CRG_IpClkDivSet(ADC0_BASE, CRG_ADC_DIV_2); - - g_adc.baseAddress = ADC0; - g_adc.socPriority = ADC_PRIMODE_ALL_ROUND; - - HAL_ADC_Init(&g_adc); /* ADC init configure. */ - - SOC_Param socParam = {0}; - socParam.adcInput = ADC_CH_ADCINA0; /* PIN47(ADC AIN2) */ - socParam.sampleTotalTime = ADC_SOCSAMPLE_5CLK; /* adc sample total time 5 adc_clk */ - socParam.trigSource = ADC_TRIGSOC_SOFT; - socParam.continueMode = BASE_CFG_DISABLE; - socParam.finishMode = ADC_SOCFINISH_NONE; - HAL_ADC_ConfigureSoc(&g_adc, ADC_SOC_NUM1, &socParam); /* SOC configure. */ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_5_AS_PGA0_P0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_5_AS_PGA0_P0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_5_AS_PGA0_P0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_5_AS_PGA0_P0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_5_AS_PGA0_P0, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -138,6 +131,7 @@ void SystemInit(void) UART0_Init(); ADC0_Init(); PGA0_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/pga/sample_pga_result_sampling/readme.md b/src/application/drivers_sample/pga/sample_pga_result_sampling/readme.md index 916ae67dae5e644a0390e3089d916d45ce796834..373a0eadf7967615a4abdd4269edfc534efc7720 100644 --- a/src/application/drivers_sample/pga/sample_pga_result_sampling/readme.md +++ b/src/application/drivers_sample/pga/sample_pga_result_sampling/readme.md @@ -13,4 +13,8 @@ + PGA的运放结果会通过ADC的采样进行输出,并通过串口0将结果输出。 **【注意事项】** -+ 增益可编程为x2, x4, x8, x16。 \ No newline at end of file ++ 增益可编程为x2, x4, x8, x16。 + ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/arch/include/nos_cpu_external.h b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/inc/sample_pmc_iwdg_wakeup.h similarity index 72% rename from src/middleware/hisilicon/nostask/arch/include/nos_cpu_external.h rename to src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/inc/sample_pmc_iwdg_wakeup.h index ed556f680f2b4253dfb81deb9c94fda54e27a1b6..7520e8141d21d48a524710b752d3e3d5b166db41 100644 --- a/src/middleware/hisilicon/nostask/arch/include/nos_cpu_external.h +++ b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/inc/sample_pmc_iwdg_wakeup.h @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -14,18 +14,17 @@ * 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.WISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * @file nos_cpu_external.h + * @file sample_pmc_iwdg_wakeup.h + * @author MCU Driver Team + * @brief Header file containing functions prototypes of PMC module's IWDG wakeup function sample. */ -#ifndef NOS_CPU_EXTERNAL_H -#define NOS_CPU_EXTERNAL_H +#ifndef McuMagicTag_SAMPLE_PMC_IWDG_WAKEUP_H +#define McuMagicTag_SAMPLE_PMC_IWDG_WAKEUP_H -#include "os_asm_cpu_riscv_external.h" -#include "os_cpu_riscv_external.h" -#include "os_cpu_riscv.h" +#include "main.h" -extern void OsFirstTimeSwitch(void); -extern void *OsTskContextInit(unsigned int taskId, unsigned int stackSize, uintptr_t *topStack, uintptr_t funcTskEntry); -extern void OsTskContextGet(uintptr_t saveAddr, struct TskContext *context); +void PmcIwdgSample(void); -#endif /* NOS_CPU_EXTERNAL_H */ +#endif /* McuMagicTag_SAMPLE_PMC_IWDG_WAKEUP_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/init/main.c b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..44b47a1799fc20b068f0a6ab38b8de491f0e6e02 --- /dev/null +++ b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/init/main.c @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_pmc_iwdg_wakeup.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +PMC_Handle g_pmc; +UART_Handle g_uart0; +IWDG_Handle g_iwdg; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + PmcIwdgSample(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/init/main.h b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..2f4f31f64772a9a29122ed46748a9b93e31855fb --- /dev/null +++ b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/init/main.h @@ -0,0 +1,58 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "pmc.h" +#include "crg.h" +#include "iocmg.h" +#include "iwdg.h" +#include "iwdg_ex.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern IWDG_Handle g_iwdg; +extern PMC_Handle g_pmc; +extern UART_Handle g_uart0; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/init/system_init.c b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..8bb1aa364ccacceb88d6b030ee46eb3a7b7632ba --- /dev/null +++ b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/init/system_init.c @@ -0,0 +1,117 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void IWDG_Init(void) +{ + HAL_CRG_IpEnableSet(IWDG_BASE, IP_CLK_ENABLE); /* IWDG clock enable. */ + g_iwdg.baseAddress = IWDG; + + g_iwdg.timeValue = 1000; /* 1000 is time value */ + g_iwdg.timeType = IWDG_TIME_UNIT_MS; + g_iwdg.freqDivValue = IWDG_FREQ_DIV_128; + g_iwdg.enableIT = BASE_CFG_SET; + g_iwdg.handleEx.windowValue = 500; /* 500 is windows time value, unit: ms */ + HAL_IWDG_Init(&g_iwdg); + HAL_IWDG_EnableWindowModeEx(&g_iwdg); +} + +static void PMC_Init(void) +{ + HAL_CRG_IpEnableSet(PMC_BASE, IP_CLK_ENABLE); + g_pmc.baseAddress = PMC_BASE; + g_pmc.wakeupSrc = PMC_WAKEUP_IWDG; /* Enable iwdg wakeup. */ + g_pmc.pvdEnable = BASE_CFG_DISABLE; + HAL_PMC_Init(&g_pmc); /* Init PMC. */ +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_DMA; + g_uart0.rxMode = UART_MODE_INTERRUPT; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + IWDG_Init(); + PMC_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/readme.md b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..4e33479ea5a7a22a2ca46ad63ec8fcaaa8c2e92c --- /dev/null +++ b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/readme.md @@ -0,0 +1,23 @@ +# 配置PMC模块的IWDG唤醒功能,实现对深度睡眠芯片的唤醒 +## 关键字: PMC,IWDG唤醒 + +**【功能描述】** ++ 示例代码基于HAL接口完成时钟、PMC控制器、IWDG模块初始化和功能配置。通过IWDG唤醒方式实现对深度睡眠芯片唤醒,唤醒后程序将重新执行。 + +**【示例配置】** + ++ PMC初始化:调用接口"HAL_PMC_Init()”完成对示例代码中PMC的基地址、唤醒模式(IWDG唤醒)。 + ++ IWDG初始化:调用接口"HAL_IWDG_Init()"完成对示例代码中IWDG的定时周期等参数配置。 + ++ 操作PMC模块进行IWDG唤醒:在完成PMC初始化操作以后,调用"HAL_IWDG_Start()"启动IWDG计时,随后调用"HAL_PMC_EnterDeepSleepMode()"实现芯片进入深度睡眠模式;在经过设定的IWDG定时周期后,芯片会唤醒程序复位重新运行。 + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中在芯片进入深度睡眠后一段时间后被IWDG唤醒,唤醒后程序会重新执行。 + +**【注意事项】** ++ 使用IWDG唤醒功能必须配置info_rgn1.iwdg_deepsleep为0,否则IWDG在深睡眠模式下无法工作。 ++ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/src/sample_pmc_iwdg_wakeup.c b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/src/sample_pmc_iwdg_wakeup.c new file mode 100644 index 0000000000000000000000000000000000000000..9f02a8cdaef09abdadeb430a317b28205208e705 --- /dev/null +++ b/src/application/drivers_sample/pmc/sample_pmc_iwdg_wakeup/src/sample_pmc_iwdg_wakeup.c @@ -0,0 +1,45 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_pmc_iwdg_wakeup.c + * @author MCU Driver Team + * @brief APT module sample of HAL API. + * This file provides some configuration example of PMC module's IWDG WAKEUP. + */ +#include "debug.h" +#include "sample_pmc_iwdg_wakeup.h" + +#define DELAY_TIME_FOR_PRINTF 500 + +/** + * @brief PVD sample. + * @retval None. + */ +void PmcIwdgSample(void) +{ + SystemInit(); + DBG_PRINTF("PMC Module example iwdg wakeup!\r\n"); + BASE_FUNC_DELAY_MS(DELAY_TIME_FOR_PRINTF); + + DBG_PRINTF("statrt iwdg and wait wakeup\r\n"); + HAL_IWDG_Start(&g_iwdg); /* iwdg start */ + + DBG_PRINTF("Enter deepsleep mode!\r\n"); + BASE_FUNC_DELAY_MS(DELAY_TIME_FOR_PRINTF); + HAL_PMC_EnterDeepSleepMode(&g_pmc); + DBG_PRINTF("Error printf this sentence!\r\n"); +} \ No newline at end of file diff --git a/src/application/drivers_sample/pmc/sample_pmc_pvd/init/main.h b/src/application/drivers_sample/pmc/sample_pmc_pvd/init/main.h index 98ce0dcebedcb99562f2bea21aaa3f663ed89d65..9f7a6c2406da02869f4ddaadf17eb4ebd82c5538 100644 --- a/src/application/drivers_sample/pmc/sample_pmc_pvd/init/main.h +++ b/src/application/drivers_sample/pmc/sample_pmc_pvd/init/main.h @@ -25,8 +25,10 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "pmc.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -36,6 +38,11 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern PMC_Handle g_pmc; extern UART_Handle g_uart0; diff --git a/src/application/drivers_sample/pmc/sample_pmc_pvd/init/system_init.c b/src/application/drivers_sample/pmc/sample_pmc_pvd/init/system_init.c index 052a15af5bfe6dcfab714cc731ed81bac2ce110e..0db4ea8b925269630b1b363830f78970a803de61 100644 --- a/src/application/drivers_sample/pmc/sample_pmc_pvd/init/system_init.c +++ b/src/application/drivers_sample/pmc/sample_pmc_pvd/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg_ip.h" #define UART0_BAND_RATE 115200 @@ -31,9 +32,14 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -51,31 +57,22 @@ __weak void PMC_PvdCallback(void *handle) static void PMC_Init(void) { HAL_CRG_IpEnableSet(PMC_BASE, IP_CLK_ENABLE); - g_pmc.baseAddress = PMC_BASE; - g_pmc.irqNumPvd = IRQ_PVD; - - g_pmc.wakeupSrc = PMC_WAKEUP_CNT; /* wakeup from timer */ - g_pmc.wakeupActMode = PMC_WAKEUP_ACT_UP_EDGE; /* wake up at up edge */ - g_pmc.wakeupTime = 0; - g_pmc.pvdEnable = BASE_CFG_ENABLE; /* enable pvd function */ - g_pmc.pvdThrehold = PMC_PVD_THRED_LEVEL5; /* falling edge 2.58V. */ - g_pmc.pvdInterruptCallback = PMC_PvdCallback; - HAL_PMC_Init(&g_pmc); - - HAL_PMC_IRQService(&g_pmc); - - IRQ_SetPriority(g_pmc.irqNumPvd, 1); - IRQ_EnableN(g_pmc.irqNumPvd); + g_pmc.wakeupSrc = PMC_WAKEUP_2; /* Set wakeup io is wakeup2 */ + g_pmc.wakeupActMode = PMC_WAKEUP_ACT_UP_EDGE; + g_pmc.pvdEnable = BASE_CFG_ENABLE; + g_pmc.pvdThreshold = PMC_PVD_THRED_LEVEL2; + HAL_PMC_Init(&g_pmc); /* PMC init function. */ + HAL_PMC_RegisterCallback(&g_pmc, PMC_PVD_INT_ID, PMC_PvdCallback); + IRQ_Register(IRQ_PVD, HAL_PMC_IrqHandler, &g_pmc); + IRQ_SetPriority(IRQ_PVD, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_PVD); } static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -84,29 +81,33 @@ static void UART0_Init(void) g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; - g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; - g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(GPIO3_3_AS_WAKEUP2); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_3_AS_WAKEUP2, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_3_AS_WAKEUP2, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_3_AS_WAKEUP2, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_3_AS_WAKEUP2, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/pmc/sample_pmc_pvd/readme.md b/src/application/drivers_sample/pmc/sample_pmc_pvd/readme.md index 51afde02c22c7d86cf2d89097eb93f1d8dc79fff..a65e5213285bab62ecad29b10442c3a9b23b12f5 100644 --- a/src/application/drivers_sample/pmc/sample_pmc_pvd/readme.md +++ b/src/application/drivers_sample/pmc/sample_pmc_pvd/readme.md @@ -1,5 +1,5 @@ # 配置PMC模块的PVD功能,实现对VDD电压的监测 -## 关键字: PMC, PVD,中断, 电压监测 +## 关键字: PMC,PVD,中断,电压监测 **【功能描述】** + 示例代码基于HAL接口完成时钟、PMC控制器初始化和功能配置。通过PVD实现对VDD电压的监测,PVD中断发生时Debug串口打印相关提示信息。 @@ -14,4 +14,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中在监测到VDD电压高于或低于设定的PVD阈值时,会产生PVD中断并通过Debug串口打印"PVD happen!"提示信息。 **【注意事项】** -+ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 \ No newline at end of file ++ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/pmc/sample_pmc_wakeup/init/main.h b/src/application/drivers_sample/pmc/sample_pmc_wakeup/init/main.h index 5ee36c60c17edd41ba95b85fcc6ea81100d6068d..60ae5c40b58f89efab303f27d8e2e76d360f5578 100644 --- a/src/application/drivers_sample/pmc/sample_pmc_wakeup/init/main.h +++ b/src/application/drivers_sample/pmc/sample_pmc_wakeup/init/main.h @@ -25,8 +25,10 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "pmc.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -36,6 +38,11 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern PMC_Handle g_pmc; extern UART_Handle g_uart0; diff --git a/src/application/drivers_sample/pmc/sample_pmc_wakeup/init/system_init.c b/src/application/drivers_sample/pmc/sample_pmc_wakeup/init/system_init.c index f33aa44ef646eef2f7462b9772c70ef1cbfc8066..25d3ab2a5e7ce4bf85e4ccaa9ee19a29b60c82b4 100644 --- a/src/application/drivers_sample/pmc/sample_pmc_wakeup/init/system_init.c +++ b/src/application/drivers_sample/pmc/sample_pmc_wakeup/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg_ip.h" #define UART0_BAND_RATE 115200 @@ -31,9 +32,14 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -44,25 +50,17 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void PMC_Init(void) { HAL_CRG_IpEnableSet(PMC_BASE, IP_CLK_ENABLE); - g_pmc.baseAddress = PMC_BASE; - g_pmc.irqNumPvd = IRQ_PVD; - - g_pmc.wakeupSrc = PMC_WAKEUP_CNT; /* wakeup from timer */ - g_pmc.wakeupActMode = PMC_WAKEUP_ACT_UP_EDGE; /* wakeup at up edge */ - g_pmc.wakeupTime = 9600; /* 9600: wakeup after about 3s */ - g_pmc.pvdEnable = BASE_CFG_DISABLE; /* disable PVD */ - g_pmc.pvdThreshold = PMC_PVD_THRED_LEVEL2; + g_pmc.wakeupSrc = PMC_WAKEUP_CNT; /* Set cnt32 as wakeup mode. */ + g_pmc.wakeupTime = 100000; /* Wakeup time, 100000 count about 3.125s */ + g_pmc.pvdEnable = BASE_CFG_DISABLE; HAL_PMC_Init(&g_pmc); } static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -71,29 +69,27 @@ static void UART0_Init(void) g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; - g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; - g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/pmc/sample_pmc_wakeup/readme.md b/src/application/drivers_sample/pmc/sample_pmc_wakeup/readme.md index 5a0aad8987267b36b50233b9c15750215c34da0b..e4339829c257f73f21ce94faa81a748b5341fb8e 100644 --- a/src/application/drivers_sample/pmc/sample_pmc_wakeup/readme.md +++ b/src/application/drivers_sample/pmc/sample_pmc_wakeup/readme.md @@ -1,5 +1,5 @@ # 配置PMC模块的定时唤醒功能,实现对深度睡眠芯片的唤醒 -## 关键字: PMC, 定时唤醒 +## 关键字: PMC,定时唤醒 **【功能描述】** + 示例代码基于HAL接口完成时钟、PMC控制器初始化和功能配置。通过定时唤醒方式实现对深度睡眠芯片唤醒,唤醒后Debug串口打印相关提示信息。 @@ -8,10 +8,13 @@ + PMC初始化:调用接口"HAL_PMC_Init()”完成对示例代码中PMC的基地址、唤醒模式(包括定时唤醒、管脚唤醒)、唤醒时间配置。 -+ 操作PMC模块进行定时唤醒:在完成PMC初始化操作以后,调用"HAL_PMC_EnterDeepSleepMode()"实现芯片进入深入睡眠模式;在经过设定的唤醒时间后,芯片会唤醒程序复位重新运行,调用"HAL_PMC_GetWakeupType()"获取芯片是从何种模式唤醒,当从深度睡眠中定时唤醒时Debug串口会打印"wakeup from deepsleep."提示信息。 ++ 操作PMC模块进行定时唤醒:在完成PMC初始化操作以后,调用"HAL_PMC_EnterDeepSleepMode()"实现芯片进入深度睡眠模式;在经过设定的唤醒时间后,芯片会唤醒程序复位重新运行,调用"HAL_PMC_GetWakeupType()"获取芯片是从何种模式唤醒,当从深度睡眠中定时唤醒时Debug串口会打印"wakeup from deepsleep."提示信息。 **【示例效果】** + 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中在芯片进入深度睡眠后一段时间定时唤醒,通过Debug串口打印"wakeup from deepsleep."提示信息。 **【注意事项】** -+ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 \ No newline at end of file ++ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/qdm/sample_qdm_m/init/system_init.c b/src/application/drivers_sample/qdm/sample_qdm_m/init/system_init.c index ceea344894db2249d650f2cc9f6323bee67e52f6..663ffb402d7a655d0aec35e95c2b013f43fa1d1d 100644 --- a/src/application/drivers_sample/qdm/sample_qdm_m/init/system_init.c +++ b/src/application/drivers_sample/qdm/sample_qdm_m/init/system_init.c @@ -20,16 +20,15 @@ * @brief This file contains driver init functions. */ -#include "debug.h" #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 #define QDM_MOTOR_LINE_NUMBER 1000 #define QDM_INPUT_FILTER_VALUE 0 -#define QDM_INPUT_PALORITY 0x0 /**< bit0~2: A B Z phase, bit value: 0--direct input, 1--invert input */ -#define INTERUPT_ENABLE_BITS 0x304 +#define QDM_INPUT_PALORITY 0x0 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { @@ -40,6 +39,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -47,18 +47,74 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -__weak void QDM_PTUCycleCallback(QDM_Handle *handle) +__weak void PtuCycleTrgCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_TSU_CYCLE */ + /* USER CODE END QDM_TSU_CYCLE */ +} + +__weak void SpeedLoseCallback(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN QDMPTUCycleCallback */ - /* USER CODE END QDMPTUCycleCallback */ + /* USER CODE BEGIN QDM_SPEED_LOSE */ + /* USER CODE END QDM_SPEED_LOSE */ } -__weak void QDM_SpeedLoseCallback(QDM_Handle *handle) +__weak void ZIndexLockedCallBack(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN QDM_SpeedLose */ - /* USER CODE END QDM_SpeedLose */ + /* USER CODE BEGIN QDM_INDEX_LOCKED */ + /* USER CODE END QDM_INDEX_LOCKED */ +} + +__weak void PositionCompareMatchCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_POS_MATCH */ + /* USER CODE END QDM_POS_MATCH */ +} + +__weak void PositionCompareReadyCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_POS_READY */ + /* USER CODE END QDM_POS_READY */ +} + +__weak void PositionCounterOverflowCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_POS_CNT_OVERFLOW */ + /* USER CODE END QDM_POS_CNT_OVERFLOW */ +} + +__weak void PositionCounterUnderflowCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE QDM_POS_CNT_UNDERFLOW */ + /* USER CODE QDM_POS_CNT_UNDERFLOW */ +} + +__weak void OrthogonalDirectionChangeCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_DIR_CHANGE */ + /* USER CODE END QDM_DIR_CHANGE */ +} + +__weak void OrthogonalPhaseErrorCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE QDM_PHASE_ERROR */ + /* USER CODE QDM_PHASE_ERROR */ +} + +__weak void PositionCounterErrorCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_POS_CNT_ERROR */ + /* USER CODE END QDM_POS_CNT_ERROR */ } static void QDM_Init(void) @@ -66,7 +122,7 @@ static void QDM_Init(void) HAL_CRG_IpEnableSet(QDM0_BASE, IP_CLK_ENABLE); g_qdmHandle.baseAddress = QDM0_BASE; - g_qdmHandle.irqNum = IRQ_QDM0; + /* emulation config */ g_qdmHandle.emuMode = QDM_EMULATION_MODE_STOP_IMMEDIATELY; /* input config */ @@ -77,30 +133,52 @@ static void QDM_Init(void) g_qdmHandle.ctrlConfig.swap = QDM_SWAP_DISABLE; g_qdmHandle.ctrlConfig.ptuMode = QDM_PTU_MODE_CYCLE; /* filter config */ - g_qdmHandle.inputFilter.qdmAFilterLevel = 0; /* filter level */ - g_qdmHandle.inputFilter.qdmBFilterLevel = 0; /* filter level */ - g_qdmHandle.inputFilter.qdmZFilterLevel = 0; /* filter level */ + g_qdmHandle.inputFilter.qdmAFilterLevel = 0; + g_qdmHandle.inputFilter.qdmBFilterLevel = 0; + g_qdmHandle.inputFilter.qdmZFilterLevel = 0; /* other config */ + g_qdmHandle.lock_mode = QDM_LOCK_RESERVE; g_qdmHandle.pcntMode = QDM_PCNT_MODE_BY_DIR; g_qdmHandle.pcntRstMode = QDM_PCNT_RST_BY_PTU; g_qdmHandle.pcntIdxInitMode = QDM_IDX_INIT_DISABLE; - g_qdmHandle.qcMax = 0xffffffff; /* 0xffffffff: QDM TSU Counter Maximum Value */ + g_qdmHandle.qcMax = 4294967295; /* 4294967295 is max count */ g_qdmHandle.subModeEn = true; - g_qdmHandle.tsuPrescaler = 0; /* 0: TSU prescaler */ - g_qdmHandle.cevtPrescaler = 0; /* 0: cevt prescaler */ - g_qdmHandle.posMax = 0xffffffff; /* 0xffffffff: QDM PPU Position Counter Maximum Value */ + g_qdmHandle.tsuPrescaler = 0; + g_qdmHandle.cevtPrescaler = QDM_CEVT_PRESCALER_DIVI1; + g_qdmHandle.posMax = 4294967295; /* 4294967295 is max count */ g_qdmHandle.posInit = 0; - g_qdmHandle.period = 200000000; /* 200000000: QDM PTU Period Value */ + + g_qdmHandle.period = 25000000; /* 25000000 is count period */ g_qdmHandle.motorLineNum = 1000; /* 1000: line number */ - g_qdmHandle.interruptEn = INTERUPT_ENABLE_BITS; - - HAL_QDM_Init(&g_qdmHandle); - HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_TSU_CYCLE, QDM_PTUCycleCallback); - HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_SPEED_LOSE, QDM_SpeedLoseCallback); + g_qdmHandle.interruptEn = QDM_INT_POS_CNT_ERROR | + QDM_INT_PHASE_ERROR | + QDM_INT_WATCHDOG | + QDM_INT_DIR_CHANGE | + QDM_INT_UNDERFLOW | + QDM_INT_OVERFLOW | + QDM_INT_POS_COMP_READY | + QDM_INT_POS_COMP_MATCH | + QDM_INT_INDEX_EVNT_LATCH | + QDM_INT_UNIT_TIME_OUT; - HAL_QDM_IRQService(&g_qdmHandle); - IRQ_SetPriority(g_qdmHandle.irqNum, 1); - IRQ_EnableN(g_qdmHandle.irqNum); + HAL_QDM_Init(&g_qdmHandle); + /* Register PTU cycle Callback */ + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_TSU_CYCLE, PtuCycleTrgCallback); + /* Register Speed lose Callback */ + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_SPEED_LOSE, SpeedLoseCallback); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_INDEX_LOCKED, ZIndexLockedCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_POS_MATCH, PositionCompareMatchCallBack); + /* Register Positon Ready Callback */ + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_POS_READY, PositionCompareReadyCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_POS_CNT_OVERFLOW, PositionCounterOverflowCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_POS_CNT_UNDERFLOW, PositionCounterUnderflowCallBack); + /* Register Direction change Callback */ + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_DIR_CHANGE, OrthogonalDirectionChangeCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_PHASE_ERROR, OrthogonalPhaseErrorCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_POS_CNT_ERROR, PositionCounterErrorCallBack); + IRQ_Register(IRQ_QDM0, HAL_QDM_IrqHandler, &g_qdmHandle); + IRQ_SetPriority(IRQ_QDM0, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_QDM0); /* Enable IRQ */ } static void UART0_Init(void) @@ -109,7 +187,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -126,42 +203,36 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_11.BIT.func = 0x1; /* 0x1 is QDM_A */ - iconfig->iocmg_11.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_11.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_11.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_11.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_11.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_12.BIT.func = 0x1; /* 0x1 is QDM_B */ - iconfig->iocmg_12.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_12.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_12.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_12.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_12.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_17.BIT.func = 0x1; /* 0x1 is QDM_INDEX */ - iconfig->iocmg_17.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_17.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_17.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_17.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_17.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO57_AS_QDM_A); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO57_AS_QDM_A, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO57_AS_QDM_A, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO57_AS_QDM_A, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO57_AS_QDM_A, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO58_AS_QDM_B); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO58_AS_QDM_B, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO58_AS_QDM_B, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO58_AS_QDM_B, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO58_AS_QDM_B, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO1_AS_QDM_INDEX); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO1_AS_QDM_INDEX, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO1_AS_QDM_INDEX, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO1_AS_QDM_INDEX, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO1_AS_QDM_INDEX, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/qdm/sample_qdm_m/readme.md b/src/application/drivers_sample/qdm/sample_qdm_m/readme.md index 4ef61a3c7afedd4298810c4bc6efa80ee0e483cf..565f817237b1a6a0f14a8c16fb85f17cbae5e017 100644 --- a/src/application/drivers_sample/qdm/sample_qdm_m/readme.md +++ b/src/application/drivers_sample/qdm/sample_qdm_m/readme.md @@ -3,6 +3,7 @@ **【功能描述】** + 通过获取电机编码器QDM的相关信息,使用M法进行计算电机实时转速 ++ M法测量给定时间区间(测量周期T)的转动角度Δx = x(t+T) - x(t),通过V=Δx/T计算出测量周期内的平均转速。当测量周期T趋近于0时,平均转速V取极限为瞬时转速。 **【示例配置】** + QDM控制配置:解码模式decoderMode,极性选择polarity,正交分解resolution、触发锁存模式trgLockMode,A/B相互换swap,PTU单元周期模式ptuMode @@ -22,3 +23,7 @@ **【注意事项】** + 需要转动电机才能进行测量实时转速 + ++ 此示例init文件夹下的工程初始化配置基于3065HRPIRZ芯片工程生成。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 diff --git a/src/application/drivers_sample/qdm/sample_qdm_mt/init/system_init.c b/src/application/drivers_sample/qdm/sample_qdm_mt/init/system_init.c index b74d4febdbeffd609208319480b2690045bb2a0d..e805a0ff57bca739f8d30182cc0e7d659c87dfd9 100644 --- a/src/application/drivers_sample/qdm/sample_qdm_mt/init/system_init.c +++ b/src/application/drivers_sample/qdm/sample_qdm_mt/init/system_init.c @@ -22,13 +22,13 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 #define QDM_MOTOR_LINE_NUMBER 1000 #define QDM_INPUT_FILTER_VALUE 0 -#define QDM_INPUT_PALORITY 0x0 /**< bit0~2: A B Z phase, bit value: 0--direct input, 1--invert input */ -#define INTERUPT_ENABLE_BITS 0x304 +#define QDM_INPUT_PALORITY 0x0 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { @@ -39,6 +39,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -46,40 +47,138 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -static void QDM_Init(void) +__weak void PtuCycleTrgCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_TSU_CYCLE */ + /* USER CODE END QDM_TSU_CYCLE */ +} + +__weak void SpeedLoseCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_SPEED_LOSE */ + /* USER CODE END QDM_SPEED_LOSE */ +} + +__weak void ZIndexLockedCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_INDEX_LOCKED */ + /* USER CODE END QDM_INDEX_LOCKED */ +} + +__weak void PositionCompareMatchCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_POS_MATCH */ + /* USER CODE END QDM_POS_MATCH */ +} + +__weak void PositionCompareReadyCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_POS_READY */ + /* USER CODE END QDM_POS_READY */ +} + +__weak void PositionCounterOverflowCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_POS_CNT_OVERFLOW */ + /* USER CODE END QDM_POS_CNT_OVERFLOW */ +} + +__weak void PositionCounterUnderflowCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE QDM_POS_CNT_UNDERFLOW */ + /* USER CODE QDM_POS_CNT_UNDERFLOW */ +} + +__weak void OrthogonalDirectionChangeCallBack(void *handle) { - HAL_CRG_IpEnableSet(QDM0_BASE, IP_CLK_ENABLE); + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_DIR_CHANGE */ + /* USER CODE END QDM_DIR_CHANGE */ +} +__weak void OrthogonalPhaseErrorCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE QDM_PHASE_ERROR */ + /* USER CODE QDM_PHASE_ERROR */ +} + +__weak void PositionCounterErrorCallBack(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM_POS_CNT_ERROR */ + /* USER CODE END QDM_POS_CNT_ERROR */ +} + +static void QDM_Init(void) +{ + HAL_CRG_IpEnableSet(QDM0_BASE, IP_CLK_ENABLE); /* IP enable. */ g_qdmHandle.baseAddress = QDM0_BASE; - g_qdmHandle.irqNum = IRQ_QDM0; /* emulation config */ g_qdmHandle.emuMode = QDM_EMULATION_MODE_STOP_IMMEDIATELY; /* input config */ g_qdmHandle.ctrlConfig.decoderMode = QDM_QUADRATURE_COUNT; + + g_qdmHandle.motorLineNum = 1000; /* 1000: line number */ + + g_qdmHandle.inputFilter.qdmAFilterLevel = 0; + g_qdmHandle.inputFilter.qdmBFilterLevel = 0; + g_qdmHandle.inputFilter.qdmZFilterLevel = 0; g_qdmHandle.ctrlConfig.polarity = 0; - g_qdmHandle.ctrlConfig.resolution = QDM_4X_RESOLUTION; - g_qdmHandle.ctrlConfig.trgLockMode = QDM_TRG_BY_CYCLE; g_qdmHandle.ctrlConfig.swap = QDM_SWAP_DISABLE; - g_qdmHandle.ctrlConfig.ptuMode = QDM_PTU_MODE_CYCLE; - /* filter config */ - g_qdmHandle.inputFilter.qdmAFilterLevel = 0; /* filter level */ - g_qdmHandle.inputFilter.qdmBFilterLevel = 0; /* filter level */ - g_qdmHandle.inputFilter.qdmZFilterLevel = 0; /* filter level */ - /* other config */ + g_qdmHandle.ctrlConfig.resolution = QDM_4X_RESOLUTION; + g_qdmHandle.pcntMode = QDM_PCNT_MODE_BY_DIR; g_qdmHandle.pcntRstMode = QDM_PCNT_RST_AUTO; + g_qdmHandle.posInit = 0; g_qdmHandle.pcntIdxInitMode = QDM_IDX_INIT_DISABLE; - g_qdmHandle.qcMax = 0xffffffff; /* 0xffffffff: QDM TSU Counter Maximum Value */ + g_qdmHandle.lock_mode = QDM_LOCK_RESERVE; + g_qdmHandle.posMax = 4294967295; /* 4294967295 is max count */ + + g_qdmHandle.tsuPrescaler = 8; /* 8 is tsu prescaler */ + g_qdmHandle.cevtPrescaler = QDM_CEVT_PRESCALER_DIVI2048; + g_qdmHandle.qcMax = 4294967295; /* 4294967295 is max count */ + + g_qdmHandle.ctrlConfig.ptuMode = QDM_PTU_MODE_CYCLE; + g_qdmHandle.period = 25000000; /* 25000000 is period count */ + g_qdmHandle.ctrlConfig.trgLockMode = QDM_TRG_BY_CYCLE; g_qdmHandle.subModeEn = true; - g_qdmHandle.tsuPrescaler = 8; /* 8: TSU prescaler */ - g_qdmHandle.cevtPrescaler = 11; /* 11: cevt prescaler */ - g_qdmHandle.posMax = 0xffffffff; /* 0xffffffff: QDM PPU Position Counter Maximum Value */ - g_qdmHandle.posInit = 0; - g_qdmHandle.period = 200000000; /* 200000000: QDM PTU Period Value */ - g_qdmHandle.motorLineNum = 1000; /* 1000: line number */ - HAL_QDM_Init(&g_qdmHandle); + g_qdmHandle.interruptEn = QDM_INT_POS_CNT_ERROR | + QDM_INT_PHASE_ERROR | + QDM_INT_WATCHDOG | + QDM_INT_DIR_CHANGE | + QDM_INT_UNDERFLOW | + QDM_INT_OVERFLOW | + QDM_INT_POS_COMP_READY | + QDM_INT_POS_COMP_MATCH | + QDM_INT_INDEX_EVNT_LATCH | + QDM_INT_UNIT_TIME_OUT; + + HAL_QDM_Init(&g_qdmHandle); /* Init QDM. */ + + /* Register callback function. */ + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_TSU_CYCLE, PtuCycleTrgCallback); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_SPEED_LOSE, SpeedLoseCallback); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_INDEX_LOCKED, ZIndexLockedCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_POS_MATCH, PositionCompareMatchCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_POS_READY, PositionCompareReadyCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_POS_CNT_OVERFLOW, PositionCounterOverflowCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_POS_CNT_UNDERFLOW, PositionCounterUnderflowCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_DIR_CHANGE, OrthogonalDirectionChangeCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_PHASE_ERROR, OrthogonalPhaseErrorCallBack); + HAL_QDM_RegisterCallback(&g_qdmHandle, QDM_POS_CNT_ERROR, PositionCounterErrorCallBack); + IRQ_Register(IRQ_QDM0, HAL_QDM_IrqHandler, &g_qdmHandle); + IRQ_SetPriority(IRQ_QDM0, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_QDM0); } static void UART0_Init(void) @@ -88,7 +187,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -105,42 +203,32 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_11.BIT.func = 0x1; /* 0x1 is QDM_A */ - iconfig->iocmg_11.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_11.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_11.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_11.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_11.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_12.BIT.func = 0x1; /* 0x1 is QDM_B */ - iconfig->iocmg_12.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_12.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_12.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_12.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_12.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_17.BIT.func = 0x1; /* 0x1 is QDM_INDEX */ - iconfig->iocmg_17.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_17.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_17.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_17.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_17.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO57_AS_QDM_A); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO57_AS_QDM_A, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO57_AS_QDM_A, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO57_AS_QDM_A, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO57_AS_QDM_A, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO58_AS_QDM_B); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO58_AS_QDM_B, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO58_AS_QDM_B, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO58_AS_QDM_B, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO58_AS_QDM_B, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO1_AS_QDM_INDEX); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO1_AS_QDM_INDEX, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO1_AS_QDM_INDEX, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO1_AS_QDM_INDEX, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO1_AS_QDM_INDEX, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/qdm/sample_qdm_mt/readme.md b/src/application/drivers_sample/qdm/sample_qdm_mt/readme.md index df64b9079fc7f9260f99a324c37e47bb700537b7..89c6eeacf05d71865b87930cf705b6185971ef76 100644 --- a/src/application/drivers_sample/qdm/sample_qdm_mt/readme.md +++ b/src/application/drivers_sample/qdm/sample_qdm_mt/readme.md @@ -1,13 +1,19 @@ -# mcs_65demo +# MT法测量电机实时转速 +## 关键字: QDM, 电机,MT法 **【功能描述】** -+ 基于AD105HDMA VER.A单板的双FOC应用 ++ 通过获取电机编码器QDM的相关信息,使用MT法进行计算电机实时转速 ++ MT法测量在给定码盘旋转区间mX,转动消耗的时间Δt,通过V=mX/Δt计算出码盘在mX区间内的平均转速。当mX趋近于0,平均转速V取极限为瞬时转速。 **【环境要求】** -+ 所用单板电源改制为演示用的24V低压,双电机均选用深圳杰美康机电的42JSF630AS-1000 ++ 所用单板电源改制为演示用的24V低压,配套电机选用杰美康机电42JSF630AS-1000型号 -**【IDE配置方法】** -+ chipConfig中的sample栏目里面选中Motorcontrolsystem示例,然后点击生成代码即可 +**【示例效果】** ++ 串口打印出电机实时的转速值大小 **【注意事项】** -+ AD105HDMA VER.A单板本身为高压板,需要将供电改成24V低压 ++ 需要转动电机才能进行测量实时转速 + ++ 此示例init文件夹下的工程初始化配置基于3065HRPIRZ芯片工程生成。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_blocking/inc/sample_smbus_master_blocking_at24c64.h b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/inc/sample_smbus_master_blocking_at24c64.h new file mode 100644 index 0000000000000000000000000000000000000000..4bd3b681fabdaa2fd94bc6f85ebfa86e3952fd50 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/inc/sample_smbus_master_blocking_at24c64.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_master_blocking_at24c64.c + * @author MCU Driver Team + * @brief Sample for SMBUS module blocking as master. + * @details This sample demonstrates how to use the SMBUS master blocking interface to read and write the EEPROM. + * To use this sample, the SMBUS interface must be connected to the AT24C64 EEPROM chip. + */ +#ifndef McuMagicTag_SAMPLE_SMBUS_MASTER_BLOCKING_AT24C64_H +#define McuMagicTag_SAMPLE_SMBUS_MASTER_BLOCKING_AT24C64_H + +void SMBusBlocking24c64Processing(void); + +#endif /* #ifndef McuMagicTag_SAMPLE_SMBUS_MASTER_BLOCKING_AT24C64_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_blocking/init/main.c b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..a1d4d8e6fc5c917cbd040a8db7929831037bd53c --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/init/main.c @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_smbus_master_blocking_at24c64.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +SMBUS_Handle g_smbus; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + SMBusBlocking24c64Processing(); + /* USER CODE BEGIN 3 */ + + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_blocking/init/main.h b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..4f6feddf216b30fb8c8e5aedb9b9cce39ce583f0 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/init/main.h @@ -0,0 +1,53 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "smbus.h" +#include "smbus_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern SMBUS_Handle g_smbus; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_blocking/init/system_init.c b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..016a289d7ecbc50dcafb78ad4bbdeceea681e26b --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/init/system_init.c @@ -0,0 +1,72 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +static void SMBUS_Init(void) +{ + HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); + g_smbus.baseAddress = I2C0; + g_smbus.functionMode = SMBUS_MODE_SELECT_MASTER_ONLY; + g_smbus.addrMode = SMBUS_7_BITS; + g_smbus.sdaHoldTime = 10; /* 10: sad hold time. */ + g_smbus.freq = 400000; /* 400000: i2c speed. */ + g_smbus.transferBuff = NULL; + g_smbus.ignoreAckFlag = BASE_CFG_DISABLE; + g_smbus.handleEx.spikeFilterTime = 0; + g_smbus.handleEx.sdaDelayTime = 0; + g_smbus.timeout = 10000; /* 10000: timeout, unit: ms. */ + g_smbus.state = SMBUS_STATE_RESET; + HAL_SMBUS_Init(&g_smbus); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + g_uart0.baseAddress = UART0; /* UART-related parameter configuration. */ + g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; /* Enable uart fifo mode. */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); /* Initializing the UART0. */ +} + +void SystemInit(void) +{ + UART0_Init(); + SMBUS_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_blocking/readme.md b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..9c5eeac0e79061115f3ad3f6a5dc7d3b660399f9 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/readme.md @@ -0,0 +1,23 @@ +# 配置SMBus作为主机以阻塞方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 +## 关键字: SMBus,主机,数据读取,数据发送,阻塞方式 + +**【功能描述】** ++ 示例代码基于HAL接口完成时钟、SMBus控制器初始化和功能配置。通过阻塞方式与EEPROM(AT24C64)进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 + +**【示例配置】** ++ SMBus控制器选择:选择SMBus实现与EEPROM的数据接收和发送。 + ++ SMBus初始化:调用接口"HAL_SMBUS_Init()”完成对示例代码中SMBus的基地址、主从模式、寻址模式(7bit寻址或10bit寻址)、通讯速率等参数进行配置。 + ++ 操作SMBus写入和读取EEPROM的内容:通过调用 "HAL_SMBUS_MasterWriteBlocking()"接口以阻塞方式向EEPROM目标内存地址写入数据;通过调用"HAL_SMBUS_MasterReadBlocking()"接口以阻塞方式实现从EEPROM的目标地址中接收数据。 + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中会通过SMBus以阻塞方式向EEPROM写入和读取写入的内容,Debug串口打印SMBus与EEPROM进行通信交互的结果信息,当写入和读取的数据一致时Debug串口打印"SMBUS Data Success";当写入和读取的数据不一致时Debug串口打印错误信息。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 示例代码中SMBus必须必须对接EEPROM(AT24C64),且保证EEPROM的7bit地址为0x50,否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_blocking/src/sample_smbus_master_blocking_at24c64.c b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/src/sample_smbus_master_blocking_at24c64.c new file mode 100644 index 0000000000000000000000000000000000000000..5d34bc83a628425e8be0eba6592d89478c483334 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_blocking/src/sample_smbus_master_blocking_at24c64.c @@ -0,0 +1,216 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_master_blocking_at24c64.c + * @author MCU Driver Team + * @brief Sample for SMBUS module blocking as master. + * @details This sample demonstrates how to use the SMBUS master blocking interface to read and write the EEPROM. + * To use this sample, the SMBUS interface must be connected to the AT24C64 EEPROM chip. + */ +#include "main.h" +#include "debug.h" +#include "sample_smbus_master_blocking_at24c64.h" + +#define DEV_24C64_ADDRESS_WRITE 0xA0 +#define DEV_24C64_ADDRESS_READ 0xA1 +#define SMBUS_SAMPLE_24C64_OPT_LEN 8 +#define SMBUS_SAMPLE_24C64_OPT_START_ADDR 0x0 +#define SMBUS_SAMPLE_24C64_DATA_OFFSET 2 +#define SMBUS_SAMPLE_24C64_PAGE_SIZE 32 +#define SMBUS_SAMPLE_24C64_ADDR_SIZE 2 +#define SMBUS_SAMPLE_24C64_OPT_ONCE_LEN 255 +#define SMBUS_SAMPLE_24C64_ADDRESS_POS 8 +#define SMBUS_SAMPLE_24C64_ADDRESS_MASK 0xFF + +#define SMBUS_SAMPLE_24C64_TEST_NUM 200 +#define SMBUS_SAMPLE_MAX_TIMEOUT 10000 + +/** + * @brief Copy data. + * @param destBuffer dest buffer. + * @param srcBuffer source buffer. + * @param len Number of the data to be copy. + * @retval None. + */ +static void CopyData(unsigned char *destBuffer, unsigned char *srcBuffer, unsigned int len) +{ + for (unsigned int i = 0; i < len; i++) { + destBuffer[i] = srcBuffer[i]; /* Copy the srcBuffer data to the destBuffer. */ + } +} + +/** + * @brief Read data from eeprom. + * @param addr The memory address of eeprom. + * @param buffer Address of buff to be receive data. + * @param len Number of the data to be read. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType Sample24c64ReadData(unsigned int addr, unsigned char *buffer, unsigned int len) +{ + BASE_StatusType ret = BASE_STATUS_OK; + /* Define variables for internal use. */ + unsigned char tempAddr[SMBUS_SAMPLE_24C64_ADDR_SIZE]; + unsigned int currentLen = len; + unsigned int currentAddr = addr; + unsigned int tempReadLen; + unsigned char *tempBuffer = buffer; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; + /* Start read data from the 24c64 eeprom. */ + while (1) { + if (currentLen == 0) { + break; + } + /* Set the memory address of eeprom. */ + tempAddr[0] = (currentAddr >> SMBUS_SAMPLE_24C64_ADDRESS_POS) & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + tempAddr[1] = currentAddr & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + + tempReadLen = currentLen; + if (currentLen > SMBUS_SAMPLE_24C64_OPT_ONCE_LEN) { + tempReadLen = SMBUS_SAMPLE_24C64_OPT_ONCE_LEN; + } + /* Send the memory address of eeprom. */ + dataBuffer.data = tempAddr; + dataBuffer.dataSize = SMBUS_SAMPLE_24C64_ADDR_SIZE; + /* Configuring the SMBUS Transmission Frame Format. */ + frameOpt = SMBUS_FRAME_FIRST | SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE; + ret = HAL_SMBUS_MasterWriteBlocking(&g_smbus, DEV_24C64_ADDRESS_WRITE, dataBuffer, + SMBUS_SAMPLE_MAX_TIMEOUT, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + /* Read data from eeprom. */ + dataBuffer.data = tempBuffer; + dataBuffer.dataSize = tempReadLen; + /* Configuring the SMBUS Transmission Frame Format. */ + frameOpt = SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_MasterReadBlocking(&g_smbus, DEV_24C64_ADDRESS_READ, dataBuffer, + SMBUS_SAMPLE_MAX_TIMEOUT, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + /* Updata the destAddress, srcAddress and len. */ + currentAddr += tempReadLen; + currentLen -= tempReadLen; + tempBuffer += tempReadLen; + } + return ret; +} + +/** + * @brief Read data from eeprom. + * @param addr The memory address of eeprom. + * @param buffer Address of buff to be send. + * @param len Number of the data to be send. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType Sample24c64WriteData(unsigned int addr, unsigned char *buffer, unsigned int len) +{ + unsigned char tempWrite[SMBUS_SAMPLE_24C64_PAGE_SIZE + SMBUS_SAMPLE_24C64_ADDR_SIZE]; + unsigned int currentLen = len; + unsigned int currentAddr = addr; + unsigned int tempWriteLen; + unsigned char *tempBuffer = buffer; + BASE_StatusType ret = BASE_STATUS_OK; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; /* Frame structure for controlling SMBUS transmission */ + + /* Start send data to eeprom. */ + while (1) { + if (currentLen == 0) { + break; + } + tempWriteLen = SMBUS_SAMPLE_24C64_PAGE_SIZE - (currentAddr % SMBUS_SAMPLE_24C64_PAGE_SIZE); + if (tempWriteLen > currentLen) { + tempWriteLen = currentLen; + } + /* Set the memory address of eeprom. */ + tempWrite[0] = (currentAddr >> SMBUS_SAMPLE_24C64_ADDRESS_POS) & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + tempWrite[1] = currentAddr & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + CopyData(&tempWrite[SMBUS_SAMPLE_24C64_ADDR_SIZE], tempBuffer, tempWriteLen); + /* Send data to eeprom. */ + dataBuffer.data = tempWrite; + dataBuffer.dataSize = tempWriteLen + SMBUS_SAMPLE_24C64_ADDR_SIZE; + /* Configuring the SMBUS Transmission Frame Format. */ + frameOpt = SMBUS_FRAME_FIRST | SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_MasterWriteBlocking(&g_smbus, DEV_24C64_ADDRESS_WRITE, dataBuffer, + SMBUS_SAMPLE_MAX_TIMEOUT, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail!,ret:%d\r\n", __LINE__, ret); + break; + } + /* Updata the destAddress, srcAddress and len. */ + currentAddr += tempWriteLen; + currentLen -= tempWriteLen; + tempBuffer += tempWriteLen; + } + return ret; +} + +/** + * @brief Send and receive data with the 24c64 eeprom in interrupt mode as master. + * @retval None. + */ +void SMBusBlocking24c64Processing(void) +{ + BASE_StatusType ret; + unsigned int i; + unsigned int dataFlag; + unsigned char tempWriteBuff[SMBUS_SAMPLE_24C64_OPT_LEN] = {0}; + unsigned int successCnt = 0; + + SystemInit(); + DBG_PRINTF("SMBus Blocking 24C64 Start\r\n"); + for (i = 0; i < SMBUS_SAMPLE_24C64_OPT_LEN; i++) { + tempWriteBuff[i] = 0x5A; /* The written data. */ + } + BASE_FUNC_DELAY_MS(20); /* Delay 20 ms. */ + for (int j = 0; j < SMBUS_SAMPLE_24C64_TEST_NUM; j++) { + unsigned char tempReadBuff[SMBUS_SAMPLE_24C64_OPT_LEN] = {0}; + /* Write 24c64 data */ + ret = Sample24c64WriteData(SMBUS_SAMPLE_24C64_OPT_START_ADDR, tempWriteBuff, SMBUS_SAMPLE_24C64_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail,ret:%d\r\n", __LINE__, ret); + } + BASE_FUNC_DELAY_MS(20); /* Delay 20 ms. */ + /* Read 24c64 data */ + ret = Sample24c64ReadData(SMBUS_SAMPLE_24C64_OPT_START_ADDR, tempReadBuff, SMBUS_SAMPLE_24C64_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail,ret:%d\r\n", __LINE__, ret); + } + BASE_FUNC_DELAY_MS(20); /* Delay 20 ms. */ + /* Compare read and write data */ + dataFlag = 0; + for (i = 0; i < SMBUS_SAMPLE_24C64_OPT_LEN; i++) { + if (tempReadBuff[i] != tempWriteBuff[i]) { + DBG_PRINTF("SMBUS Data error! offset[%d]\r\nReadData:0x%x\r\nWriteData:0x%x\r\n", i, + tempReadBuff[i], tempWriteBuff[i]); + dataFlag = 1; + break; + } + } + /* The read data is exactly the same as the written data. */ + if (dataFlag == 0) { + successCnt++; + DBG_PRINTF("SMBUS Data Success\r\n"); + } + } + DBG_PRINTF("SMBUS sample End!\r\nsuccessCnt:%d\r\n", successCnt); +} \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_dma/inc/sample_smbus_master_dma_at24c64.h b/src/application/drivers_sample/smbus/sample_smbus_master_dma/inc/sample_smbus_master_dma_at24c64.h new file mode 100644 index 0000000000000000000000000000000000000000..9e4a6b7022dcbd38506df77e66f99c13ba203a57 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_dma/inc/sample_smbus_master_dma_at24c64.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_master_dma_at24c64.c + * @author MCU Driver Team + * @brief Sample for SMBUS module dma as master. + * @details This sample demonstrates how to use the SMBUS master DMA interface to read and write the EEPROM. + * To use this sample, the SMBUS interface must be connected to the AT24C64 EEPROM chip. + */ +#ifndef McuMagicTag_SAMPLE_SMBUS_MASTER_DAM_AT24C64_H +#define McuMagicTag_SAMPLE_SMBUS_MASTER_DAM_AT24C64_H + +void SMBusDma24c64Processing(void); + +#endif /* #ifndef McuMagicTag_SAMPLE_SMBUS_MASTER_DAM_AT24C64_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_dma/init/main.c b/src/application/drivers_sample/smbus/sample_smbus_master_dma/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..26fdcd30c72956d280d09b696bc1d92a348719fe --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_dma/init/main.c @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ +#include "typedefs.h" +#include "feature.h" +#include "sample_smbus_master_dma_at24c64.h" +#include "main.h" + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +SMBUS_Handle g_smbus; +DMA_Handle g_dmac; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + SMBusDma24c64Processing(); + /* USER CODE BEGIN 3 */ + + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_dma/init/main.h b/src/application/drivers_sample/smbus/sample_smbus_master_dma/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..dec6e87ef6d0711f783cd6cfbf38f750e0845221 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_dma/init/main.h @@ -0,0 +1,62 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "smbus.h" +#include "smbus_ex.h" +#include "crg.h" +#include "dma.h" +#include "dma_ex.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern SMBUS_Handle g_smbus; + +extern DMA_Handle g_dmac; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +void SMBusTxCallback(void *handle); +void SMBusRxCallback(void *handle); +void SMBusSendStopCallback(void *handle); +void SMBusErrorCallback(void *handle); + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_dma/init/system_init.c b/src/application/drivers_sample/smbus/sample_smbus_master_dma/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..27d00a7df18c9162282c72d7b8984df43b67bbb7 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_dma/init/system_init.c @@ -0,0 +1,158 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +static void DMA_Channel0Init(void *handle) +{ + DMA_ChannelParam dma_param; /* Setting DMA-related parameters. */ + dma_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; + dma_param.srcAddrInc = DMA_ADDR_UNALTERED; + dma_param.destAddrInc = DMA_ADDR_INCREASE; + dma_param.srcPeriph = DMA_REQUEST_I2C_RX; + dma_param.destPeriph = DMA_REQUEST_MEM; + dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; /* Set the moving position width. */ + dma_param.destWidth = DMA_TRANSWIDTH_BYTE; + dma_param.srcBurst = DMA_BURST_LENGTH_1; + dma_param.destBurst = DMA_BURST_LENGTH_1; + dma_param.pHandle = handle; + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ZERO); /* DMA Channel initialization. */ +} + +static void DMA_Channel1Init(void *handle) +{ + DMA_ChannelParam dma_param; /* Setting DMA-related parameters. */ + dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; + dma_param.srcAddrInc = DMA_ADDR_INCREASE; + dma_param.destAddrInc = DMA_ADDR_UNALTERED; + dma_param.srcPeriph = DMA_REQUEST_MEM; + dma_param.destPeriph = DMA_REQUEST_I2C_TX; + dma_param.srcWidth = DMA_TRANSWIDTH_WORD; /* Set the moving position width. */ + dma_param.destWidth = DMA_TRANSWIDTH_WORD; + dma_param.srcBurst = DMA_BURST_LENGTH_1; + dma_param.destBurst = DMA_BURST_LENGTH_1; + dma_param.pHandle = handle; + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ONE); /* DMA Channel initialization. */ +} + +static void DMA_Init(void) +{ + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); + g_dmac.baseAddress = DMA; + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); + IRQ_EnableN(IRQ_DMA_TC); + IRQ_EnableN(IRQ_DMA_ERR); + HAL_DMA_Init(&g_dmac); + DMA_Channel0Init((void *)(&g_smbus)); + HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_ZERO, DMA_PRIORITY_HIGHEST); + DMA_Channel1Init((void *)(&g_smbus)); + HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_ONE, DMA_PRIORITY_HIGHEST); +} + +__weak void SMBusTxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0TxCallback */ + /* USER CODE END I2C0TxCallback */ +} + +__weak void SMBusRxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0RxCallback */ + /* USER CODE END I2C0RxCallback */ +} + +__weak void SMBusSendStopCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0ErrorCallback */ + /* USER CODE END I2C0ErrorCallback */ +} + +__weak void SMBusErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0ErrorCallback */ + /* USER CODE END I2C0ErrorCallback */ +} + +static void SMBUS_Init(void) +{ + HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); + + g_smbus.baseAddress = I2C0; + g_smbus.functionMode = SMBUS_MODE_SELECT_MASTER_ONLY; + g_smbus.addrMode = SMBUS_7_BITS; + g_smbus.sdaHoldTime = 10; /* 10: sad hold time. */ + g_smbus.freq = 400000; /* 400000: i2c speed. */ + g_smbus.transferBuff = NULL; + g_smbus.ignoreAckFlag = BASE_CFG_DISABLE; + g_smbus.handleEx.spikeFilterTime = 0; + g_smbus.handleEx.sdaDelayTime = 0; + g_smbus.timeout = 10000; /* 10000: timeout, unit: ms. */ + g_smbus.state = SMBUS_STATE_RESET; + g_smbus.rxWaterMark = 1; /* 1:Set the rx watermark. */ + g_smbus.txWaterMark = 12; /* 12:Set the tx watermark. */ + g_smbus.dmaHandle = &g_dmac; + g_smbus.txDmaCh = DMA_CHANNEL_ONE; + g_smbus.rxDmaCh = DMA_CHANNEL_ZERO; + HAL_SMBUS_Init(&g_smbus); + /* Registering Callback Function */ + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_MASTER_TX_COMPLETE_CB_ID, SMBusTxCallback); + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_MASTER_RX_COMPLETE_CB_ID, SMBusRxCallback); + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_MSTAER_SEND_STOP_COMPLETE_CB_ID, SMBusSendStopCallback); + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_ERROR_CB_ID, SMBusErrorCallback); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + g_uart0.baseAddress = UART0; /* UART-related parameter configuration. */ + g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; /* Enable uart fifo mode. */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); /* Initializing the UART0. */ +} + +void SystemInit(void) +{ + DMA_Init(); + UART0_Init(); + SMBUS_Init(); + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_dma/readme.md b/src/application/drivers_sample/smbus/sample_smbus_master_dma/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..3da2669eb58c6aa25c159da11d250b8c662a532b --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_dma/readme.md @@ -0,0 +1,23 @@ +# 配置SMBus作为主机以DMA方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 +## 关键字: SMBus,主机,数据读取,数据发送,DMA方式 + +**【功能描述】** ++ 示例代码基于HAL接口完成时钟、SMBus控制器初始化和功能配置。通过中断方式与EEPROM(AT24C64)进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 + +**【示例配置】** ++ SMBus控制器选择:选择SMBus实现与EEPROM的数据接收和发送。 + ++ SMBus初始化:调用接口"HAL_SMBUS_Init()”完成对示例代码中SMBus的基地址、主从模式、寻址模式(7bit寻址或10bit寻址)、通讯速率、DMA通道等参数进行配置。调用"HAL_SMBUS_RegisterCallback()"接口注册收发完成、传输错误时的回调函数。 + ++ 操作SMBus写入和读取EEPROM的内容:通过调用 "HAL_SMBUS_MasterWriteDMA()"接口以DMA方式向EEPROM目标内存地址写入数据;通过调用"HAL_SMBUS_MasterReadDMA()"接口以DMA方式实现从EEPROM的目标地址中接收数据。 + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中会通过SMBus以DMA方式向EEPROM写入和读取写入的内容,Debug串口打印SMBus与EEPROM进行通信交互的结果信息,当写入和读取的数据一致时Debug串口打印"SMBUS Data Success";当写入和读取的数据不一致时Debug串口打印错误信息。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 示例代码中SMBus必须必须对接EEPROM(AT24C64),且保证EEPROM的7bit地址为0x50,否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_dma/src/sample_smbus_master_dma_at24c64.c b/src/application/drivers_sample/smbus/sample_smbus_master_dma/src/sample_smbus_master_dma_at24c64.c new file mode 100644 index 0000000000000000000000000000000000000000..f9c016846acaca7bfc619cbdd732369982bab1ad --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_dma/src/sample_smbus_master_dma_at24c64.c @@ -0,0 +1,314 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_master_dma_at24c64.c + * @author MCU Driver Team + * @brief Sample for SMBUS module dma as master. + * @details This sample demonstrates how to use the SMBUS master DMA interface to read and write the EEPROM. + * To use this sample, the SMBUS interface must be connected to the AT24C64 EEPROM chip. + */ +#include "dma.h" +#include "main.h" +#include "debug.h" +#include "sample_smbus_master_dma_at24c64.h" + +#define DEV_24C64_ADDRESS_WRITE 0xA0 +#define DEV_24C64_ADDRESS_READ 0xA1 +#define SMBUS_SAMPLE_24C64_OPT_LEN 8 +#define SMBUS_SAMPLE_24C64_OPT_START_ADDR 0x0 +#define SMBUS_SAMPLE_24C64_DATA_OFFSET 2 +#define SMBUS_SAMPLE_24C64_PAGE_SIZE 32 +#define SMBUS_SAMPLE_24C64_ADDR_SIZE 2 +#define SMBUS_SAMPLE_24C64_OPT_ONCE_LEN 255 + +#define SMBUS_SAMPLE_24C64_ADDRESS_POS 8 +#define SMBUS_SAMPLE_24C64_ADDRESS_MASK 0xFF + +#define SMBUS_SAMPLE_24C64_TEST_NUM 100 + +static volatile int g_txDoneFlag = BASE_CFG_UNSET; +static volatile int g_rxDoneFlag = BASE_CFG_UNSET; +static volatile int g_stopDoneFlag = BASE_CFG_UNSET; +static volatile int g_errorFlag = BASE_CFG_UNSET; + +/** + * @brief SMBUS dma sample tx callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusTxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_txDoneFlag = BASE_CFG_SET; +} + +/** + * @brief SMBUS dma sample rx callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusRxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_rxDoneFlag = BASE_CFG_SET; +} + + +/** + * @brief SMBUS dma sample send stop frame callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusSendStopCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_stopDoneFlag = BASE_CFG_SET; +} + +/** + * @brief SMBUS dma sample Error callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_errorFlag = BASE_CFG_SET; +} + +/** + * @brief Copy data. + * @param destBuffer dest buffer. + * @param srcBuffer source buffer. + * @param len Number of the data to be copy. + * @retval None. + */ +static void CopyData(unsigned char *destBuffer, unsigned char *srcBuffer, unsigned int len) +{ + for (unsigned int i = 0; i < len; i++) { + destBuffer[i] = srcBuffer[i]; + } +} + +/** + * @brief Write the memory address of 24c64 eeprom. + * @param addrBuffer The memory address of eeprom. + * @param length The length of data buffer. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType Write24c64MemoryAddress(unsigned char *addrBuffer, unsigned int length) +{ + BASE_StatusType ret = BASE_STATUS_OK; + unsigned char *tempAddr = addrBuffer; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; + /* Write the memory address to AT24c64 eeprom. */ + dataBuffer.data = tempAddr; + dataBuffer.dataSize = length; + /* Configuring the SMBUS Transmission Frame Format. */ + frameOpt = SMBUS_FRAME_FIRST | SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE; + ret = HAL_SMBUS_MasterWriteDMA(&g_smbus, DEV_24C64_ADDRESS_WRITE, dataBuffer, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + /* Waiting for write completion or failure */ + while (!(g_txDoneFlag || g_errorFlag)) { + ; + } + g_txDoneFlag = BASE_CFG_UNSET; + g_stopDoneFlag = BASE_CFG_UNSET; + if (g_errorFlag == BASE_CFG_SET) { + g_errorFlag = BASE_CFG_UNSET; /* Reset g_errorFlag. */ + DBG_PRINTF("LINE:%d,Read Data Fail\r\n", __LINE__); + return BASE_STATUS_ERROR; + } + return ret; +} + +/** + * @brief Read data from the 24c64 eeprom. + * @param addr The memory address of eeprom. + * @param buffer Address of buff to be receive data. + * @param len Number of the data to be read. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType Sample24c64ReadData(unsigned int addr, unsigned char *buffer, unsigned int len) +{ + BASE_StatusType ret = BASE_STATUS_OK; /* Transfer success and failure status. */ + unsigned char tempAddr[SMBUS_SAMPLE_24C64_ADDR_SIZE]; + unsigned int currentLen = len; + unsigned int currentAddr = addr; + unsigned int tempReadLen; + unsigned char *tempBuffer = buffer; + SMBUS_DataBuffer dataBuffer; /* SMBUS Transfer buffer. */ + unsigned int frameOpt; + /* Start read data to eeprom. */ + while (1) { + if (currentLen == 0) { + break; + } + /* Set the memory address of eeprom. */ + tempAddr[0] = (currentAddr >> SMBUS_SAMPLE_24C64_ADDRESS_POS) & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + tempAddr[1] = currentAddr & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + tempReadLen = currentLen; + if (currentLen > SMBUS_SAMPLE_24C64_OPT_ONCE_LEN) { + tempReadLen = SMBUS_SAMPLE_24C64_OPT_ONCE_LEN; + } + BASE_FUNC_DELAY_MS(5); /* Delay 5 ms. */ + ret = Write24c64MemoryAddress(tempAddr, SMBUS_SAMPLE_24C64_ADDR_SIZE); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + dataBuffer.data = tempBuffer; + dataBuffer.dataSize = tempReadLen; + /* Configuring the SMBUS Transmission Frame Format. */ + frameOpt = SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_MasterReadDMA(&g_smbus, DEV_24C64_ADDRESS_READ, dataBuffer, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + /* Waiting for read completion or failure */ + while (!(g_stopDoneFlag || g_errorFlag)) { + ; + } + g_stopDoneFlag = BASE_CFG_UNSET; + g_rxDoneFlag = BASE_CFG_UNSET; + if (g_errorFlag == BASE_CFG_SET) { + DBG_PRINTF("LINE:%d,Read Data Fail\r\n", __LINE__); + g_errorFlag = BASE_CFG_UNSET; + return BASE_STATUS_ERROR; + } + /* Updata the destAddress, srcAddress and len. */ + currentAddr += tempReadLen; + currentLen -= tempReadLen; + tempBuffer += tempReadLen; + } + + return ret; +} + +/** + * @brief Send data to the 24c64 eeprom. + * @param addr The memory address of eeprom. + * @param buffer Address of buff to be send. + * @param len Number of the data to be send. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType Sample24c64WriteData(unsigned int addr, unsigned char *buffer, unsigned int len) +{ + unsigned char tempWrite[SMBUS_SAMPLE_24C64_PAGE_SIZE + SMBUS_SAMPLE_24C64_ADDR_SIZE]; + unsigned int currentLen = len; + unsigned int currentAddr = addr; + unsigned int tempWriteLen; + unsigned char *tempBuffer = buffer; + BASE_StatusType ret = BASE_STATUS_OK; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; + /* Start send data to eeprom. */ + while (1) { + if (currentLen == 0) { + break; + } + tempWriteLen = SMBUS_SAMPLE_24C64_PAGE_SIZE - (currentAddr % SMBUS_SAMPLE_24C64_PAGE_SIZE); + if (tempWriteLen > currentLen) { + tempWriteLen = currentLen; + } + /* Set the memory address of eeprom. */ + tempWrite[0] = (currentAddr >> SMBUS_SAMPLE_24C64_ADDRESS_POS) & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + tempWrite[1] = currentAddr & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + CopyData(&tempWrite[SMBUS_SAMPLE_24C64_ADDR_SIZE], tempBuffer, tempWriteLen); + BASE_FUNC_DELAY_MS(5); /* Delay 5 ms. */ + /* Send data to eeprom. */ + dataBuffer.data = tempWrite; + dataBuffer.dataSize = tempWriteLen + SMBUS_SAMPLE_24C64_ADDR_SIZE; + /* Configuring the SMBUS Transmission Frame Format. */ + frameOpt = SMBUS_FRAME_FIRST | SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_MasterWriteDMA(&g_smbus, DEV_24C64_ADDRESS_WRITE, dataBuffer, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail!,ret:%d\r\n", __LINE__, ret); + break; + } + /* Waiting for read completion or failure */ + while (!(g_stopDoneFlag || g_errorFlag)) { + ; + } + g_stopDoneFlag = BASE_CFG_UNSET; + g_txDoneFlag = BASE_CFG_UNSET; + if (g_errorFlag == BASE_CFG_SET) { + DBG_PRINTF("LINE:%d,Read Data Fail\r\n", __LINE__); + g_errorFlag = BASE_CFG_UNSET; + return BASE_STATUS_ERROR; + } + /* Updata the destAddress, srcAddress and len. */ + currentAddr += tempWriteLen; + tempBuffer += tempWriteLen; + currentLen -= tempWriteLen; + } + return ret; +} + +/** + * @brief Send and receive data with the 24c64 eeprom in dma mode as master. + * @retval None. + */ +void SMBusDma24c64Processing(void) +{ + BASE_StatusType ret; + unsigned int dataFlag; + unsigned char tempWriteBuff[SMBUS_SAMPLE_24C64_OPT_LEN] = {0}; + unsigned int successCnt = 0; + + SystemInit(); + DBG_PRINTF("SMBUs Dma 24C64 Start\r\n"); + for (unsigned int i = 0; i < SMBUS_SAMPLE_24C64_OPT_LEN; i++) { + tempWriteBuff[i] = 0x5A; /* The written data. */ + } + + for (int j = 0; j < SMBUS_SAMPLE_24C64_TEST_NUM; j++) { + unsigned char tempReadBuff[SMBUS_SAMPLE_24C64_OPT_LEN] = {0}; + /* Write 24c64 data */ + ret = Sample24c64WriteData(SMBUS_SAMPLE_24C64_OPT_START_ADDR, tempWriteBuff, SMBUS_SAMPLE_24C64_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail!,ret:%d\r\n", __LINE__, ret); + } + /* Read 24c64 data */ + ret = Sample24c64ReadData(SMBUS_SAMPLE_24C64_OPT_START_ADDR, tempReadBuff, SMBUS_SAMPLE_24C64_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + } + /* Compare read and write data */ + dataFlag = 0; + for (unsigned int i = 0; i < SMBUS_SAMPLE_24C64_OPT_LEN - 1; i++) { + if (tempReadBuff[i] != tempWriteBuff[i]) { + DBG_PRINTF("SMBUS Data error! offset[%d]\r\nReadData:0x%x\r\nWriteData:0x%x\r\n", i, tempReadBuff[i], + tempWriteBuff[i]); + dataFlag = 1; + break; + } + } + + /* The read data is exactly the same as the written data. */ + if (dataFlag == 0) { + successCnt++; + DBG_PRINTF("SMBUS Data Success\r\n"); + } + } + DBG_PRINTF("SMBUS sample End!\r\nsuccessCnt:%d\r\n", successCnt); +} \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_it/inc/sample_smbus_master_interrupt_at24c64.h b/src/application/drivers_sample/smbus/sample_smbus_master_it/inc/sample_smbus_master_interrupt_at24c64.h new file mode 100644 index 0000000000000000000000000000000000000000..4ee518818cccdaf27f0805b2d1666f340addae57 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_it/inc/sample_smbus_master_interrupt_at24c64.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_master_interrupt_at24c64.c + * @author MCU Driver Team + * @brief Sample for SMBUS module interrupt as master. + * @details This sample demonstrates how to use the SMBUS master interrupt interface to read and write the EEPROM. + * To use this sample, the SMBUS interface must be connected to the AT24C64 EEPROM chip. + */ +#ifndef McuMagicTag_SAMPLE_SMBUS_MASTER_INTERRUPT_AT24C64_H +#define McuMagicTag_SAMPLE_SMBUS_MASTER_INTERRUPT_AT24C64_H + +void SMBusInterrupt24c64Processing(void); + +#endif /* #ifndef McuMagicTag_SAMPLE_SMBUS_MASTER_INTERRUPT_AT24C64_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_it/init/main.c b/src/application/drivers_sample/smbus/sample_smbus_master_it/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..98799a36059c8e3a16e2b612094c80a56c0f8a07 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_it/init/main.c @@ -0,0 +1,59 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ +#include "typedefs.h" +#include "feature.h" +#include "sample_smbus_master_interrupt_at24c64.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +SMBUS_Handle g_smbus; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + SMBusInterrupt24c64Processing(); + /* USER CODE BEGIN 3 */ + + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_it/init/main.h b/src/application/drivers_sample/smbus/sample_smbus_master_it/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..e5d9421557cb2f0cc83b2e55dfe4ad40ef595227 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_it/init/main.h @@ -0,0 +1,58 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "smbus.h" +#include "smbus_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern SMBUS_Handle g_smbus; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +void SMBusTxCallback(void *handle); +void SMBusRxCallback(void *handle); +void SMBusErrorCallback(void *handle); +void SMBusSendStopCallback(void *handle); + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_it/init/system_init.c b/src/application/drivers_sample/smbus/sample_smbus_master_it/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..034d410635150865181cfd45ee27e3101ec72a80 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_it/init/system_init.c @@ -0,0 +1,111 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +__weak void SMBusTxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0TxCallback */ + /* USER CODE END I2C0TxCallback */ +} + +__weak void SMBusRxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0RxCallback */ + /* USER CODE END I2C0RxCallback */ +} + +__weak void SMBusSendStopCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0RxCallback */ + /* USER CODE END I2C0RxCallback */ +} + +__weak void SMBusErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0ErrorCallback */ + /* USER CODE END I2C0ErrorCallback */ +} + +static void SMBUS_Init(void) +{ + HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); + + g_smbus.baseAddress = I2C0; + g_smbus.functionMode = SMBUS_MODE_SELECT_MASTER_ONLY; + g_smbus.addrMode = SMBUS_7_BITS; + g_smbus.sdaHoldTime = 10; /* 10: sad hold time. */ + g_smbus.freq = 400000; /* 400000: i2c speed. */ + g_smbus.transferBuff = NULL; + g_smbus.ignoreAckFlag = BASE_CFG_DISABLE; + g_smbus.handleEx.spikeFilterTime = 0; + g_smbus.handleEx.sdaDelayTime = 0; + g_smbus.timeout = 10000; /* 10000: timeout, unit: ms. */ + g_smbus.state = SMBUS_STATE_RESET; + g_smbus.rxWaterMark = 1; /* 1:Set the rx watermark. */ + g_smbus.txWaterMark = 12; /* 12:Set the tx watermark. */ + HAL_SMBUS_Init(&g_smbus); + /* Registering Callback Function */ + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_MASTER_TX_COMPLETE_CB_ID, SMBusTxCallback); + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_MASTER_RX_COMPLETE_CB_ID, SMBusRxCallback); + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_MSTAER_SEND_STOP_COMPLETE_CB_ID, SMBusSendStopCallback); + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_ERROR_CB_ID, SMBusErrorCallback); + IRQ_Register(IRQ_I2C0, HAL_SMBUS_IrqHandler, &g_smbus); + IRQ_SetPriority(IRQ_I2C0, 1); + IRQ_EnableN(IRQ_I2C0); /* Enable interrupt. */ +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + g_uart0.baseAddress = UART0; /* UART-related parameter configuration. */ + g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; /* Enable uart fifo mode. */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); /* Initializing the UART0. */ +} + +void SystemInit(void) +{ + UART0_Init(); + SMBUS_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_it/readme.md b/src/application/drivers_sample/smbus/sample_smbus_master_it/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..0290a34884fb63b204f8f63cb93a3922e813f07b --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_it/readme.md @@ -0,0 +1,23 @@ +# 配置SMBus作为主机以中断方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 +## 关键字: SMBus,主机,数据读取,数据发送,中断方式 + +**【功能描述】** ++ 示例代码基于HAL接口完成时钟、SMBus控制器初始化和功能配置。通过中断方式与EEPROM(AT24C64)进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 + +**【示例配置】** ++ SMBus控制器选择:选择SMBus实现与EEPROM的数据接收和发送。 + ++ SMBus初始化:调用接口"HAL_SMBUS_Init()”完成对示例代码中I2C的基地址、主从模式、寻址模式(7bit寻址或10bit寻址)、通讯速率等参数进行配置。调用"HAL_SMBUS_RegisterCallback()"接口注册中断回调函数,并使能相关中断配置。 + ++ 操作SMBus写入和读取EEPROM的内容:通过调用 "HAL_SMBUS_MasterWriteIT()"接口以中断方式向EEPROM目标内存地址写入数据;通过调用"HAL_SMBUS_MasterReadIT()"接口以中断方式实现从EEPROM的目标地址中接收数据。 + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中会通过SMBus以中断方式向EEPROM写入和读取写入的内容,Debug串口打印SMBus与EEPROM进行通信交互的结果信息,当写入和读取的数据一致时Debug串口打印"SMBUS Data Success";当写入和读取的数据不一致时Debug串口打印错误信息。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 示例代码中SMBus必须必须对接EEPROM(AT24C64),且保证EEPROM的7bit地址为0x50,否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_master_it/src/sample_smbus_master_interrupt_at24c64.c b/src/application/drivers_sample/smbus/sample_smbus_master_it/src/sample_smbus_master_interrupt_at24c64.c new file mode 100644 index 0000000000000000000000000000000000000000..a3d0ec7273692eb886dac3df8f932f3022948ad4 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_master_it/src/sample_smbus_master_interrupt_at24c64.c @@ -0,0 +1,318 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_master_interrupt_at24c64.c + * @author MCU Driver Team + * @brief Sample for SMBUS module interrupt as master. + * @details This sample demonstrates how to use the SMBUS master interrupt interface to read and write the EEPROM. + * To use this sample, the SMBUS interface must be connected to the AT24C64 EEPROM chip. + */ +#include "main.h" +#include "debug.h" +#include "sample_smbus_master_interrupt_at24c64.h" + +#define DEV_24C64_ADDRESS_WRITE 0xA0 +#define DEV_24C64_ADDRESS_READ 0xA1 +#define SMBUS_SAMPLE_24C64_OPT_LEN 8 +#define SMBUS_SAMPLE_24C64_OPT_START_ADDR 0x0 +#define SMBUS_SAMPLE_24C64_DATA_OFFSET 2 +#define SMBUS_SAMPLE_24C64_PAGE_SIZE 32 +#define SMBUS_SAMPLE_24C64_ADDR_SIZE 2 +#define SMBUS_SAMPLE_24C64_OPT_ONCE_LEN 255 +#define SMBUS_SAMPLE_24C64_ADDRESS_POS 8 +#define SMBUS_SAMPLE_24C64_ADDRESS_MASK 0xFF + +#define SMBUS_SAMPLE_24C64_TEST_NUM 100 + +static volatile int g_txDoneFlag = BASE_CFG_UNSET; +static volatile int g_rxDoneFlag = BASE_CFG_UNSET; +static volatile int g_stopDoneFlag = BASE_CFG_UNSET; +static volatile int g_errorFlag = BASE_CFG_UNSET; + +/** + * @brief SMBUS interrupt sample tx callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusTxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_txDoneFlag = BASE_CFG_SET; +} + +/** + * @brief SMBUS interrupt sample rx callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusRxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_rxDoneFlag = BASE_CFG_SET; +} + +/** + * @brief SMBUS interrupt sample send stop frame callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusSendStopCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_stopDoneFlag = BASE_CFG_SET; +} + +/** + * @brief SMBUS interrupt sample Error callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_errorFlag = BASE_CFG_SET; +} + +/** + * @brief Copy data. + * @param destBuffer dest buffer. + * @param srcBuffer source buffer. + * @param len Number of the data to be copy. + * @retval None. + */ +static void CopyData(unsigned char *destBuffer, unsigned char *srcBuffer, unsigned int len) +{ + for (unsigned int i = 0; i < len; i++) { + destBuffer[i] = srcBuffer[i]; + } +} + +/** + * @brief Write the memory address of 24c64 eeprom. + * @param addrBuffer The memory address of eeprom. + * @param length The length of data buffer. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType Write24c64MemoryAddress(unsigned char *addrBuffer, unsigned int length) +{ + BASE_StatusType ret = BASE_STATUS_OK; + unsigned char *tempAddr = addrBuffer; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; + /* Write the memory address to 24c64 eeprom. */ + dataBuffer.data = tempAddr; + dataBuffer.dataSize = length; + frameOpt = SMBUS_FRAME_FIRST | SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE; + ret = HAL_SMBUS_MasterWriteIT(&g_smbus, DEV_24C64_ADDRESS_WRITE, dataBuffer, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + + /* Waiting for write completion or failure */ + while (!(g_txDoneFlag || g_errorFlag)) { + ; + } + g_txDoneFlag = BASE_CFG_UNSET; + if (g_errorFlag == BASE_CFG_SET || g_stopDoneFlag == BASE_CFG_SET) { + g_errorFlag = BASE_CFG_UNSET; /* Reset g_errorFlag. */ + g_stopDoneFlag = BASE_CFG_UNSET; /* Reset g_stopDoneFlag. */ + DBG_PRINTF("LINE:%d,Read Data Fail\r\n", __LINE__); + return BASE_STATUS_ERROR; + } + return ret; +} + +/** + * @brief Read data from the 24c64 eeprom. + * @param addr The memory address of eeprom. + * @param buffer Address of buff to be receive data. + * @param len Number of the data to be read. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType Sample24c64ReadData(unsigned int addr, unsigned char *buffer, unsigned int len) +{ + BASE_StatusType ret = BASE_STATUS_OK; /* Transfer success and failure status. */ + unsigned char tempAddr[SMBUS_SAMPLE_24C64_ADDR_SIZE]; + unsigned int currentLen = len; + unsigned int currentAddr = addr; + unsigned int tempReadLen; + unsigned char *tempBuffer = buffer; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; /* Frame structure for controlling SMBUS transmission */ + + /* Start read data from the 24c64 eeprom. */ + while (1) { + if (currentLen == 0) { + break; + } + + /* Set the memory address of eeprom. */ + tempAddr[0] = (currentAddr >> SMBUS_SAMPLE_24C64_ADDRESS_POS) & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + tempAddr[1] = currentAddr & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + + tempReadLen = currentLen; + if (currentLen > SMBUS_SAMPLE_24C64_OPT_ONCE_LEN) { + tempReadLen = SMBUS_SAMPLE_24C64_OPT_ONCE_LEN; + } + + ret = Write24c64MemoryAddress(tempAddr, SMBUS_SAMPLE_24C64_ADDR_SIZE); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + dataBuffer.data = tempBuffer; + dataBuffer.dataSize = tempReadLen; + frameOpt = SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_MasterReadIT(&g_smbus, DEV_24C64_ADDRESS_READ, dataBuffer, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + + /* Waiting for read completion or failure */ + while (!(g_stopDoneFlag || g_errorFlag)) { + ; + } + g_stopDoneFlag = BASE_CFG_UNSET; + g_rxDoneFlag = BASE_CFG_UNSET; + if (g_errorFlag == BASE_CFG_SET) { + g_errorFlag = BASE_CFG_UNSET; /* Reset g_errorFlag. */ + DBG_PRINTF("LINE:%d,Read Data Fail\r\n", __LINE__); + return BASE_STATUS_ERROR; + } + /* Updata the destAddress, srcAddress and len. */ + currentAddr += tempReadLen; + currentLen -= tempReadLen; + tempBuffer += tempReadLen; + } + return ret; +} + +/** + * @brief Send data to the 24c64 eeprom. + * @param addr The memory address of eeprom. + * @param buffer Address of buff to be send. + * @param len Number of the data to be send. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType Sample24c64WriteData(unsigned int addr, unsigned char *buffer, unsigned int len) +{ + unsigned char tempWrite[SMBUS_SAMPLE_24C64_PAGE_SIZE + SMBUS_SAMPLE_24C64_ADDR_SIZE]; + unsigned int currentLen = len; + unsigned int currentAddr = addr; + unsigned int tempWriteLen; + unsigned char *tempBuffer = buffer; + BASE_StatusType ret = BASE_STATUS_OK; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; + + /* Start send data to eeprom. */ + while (1) { + if (currentLen == 0) { + break; + } + tempWriteLen = SMBUS_SAMPLE_24C64_PAGE_SIZE - (currentAddr % SMBUS_SAMPLE_24C64_PAGE_SIZE); + if (tempWriteLen > currentLen) { + tempWriteLen = currentLen; + } + /* Set the memory address of eeprom. */ + tempWrite[0] = (currentAddr >> SMBUS_SAMPLE_24C64_ADDRESS_POS) & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + tempWrite[1] = currentAddr & SMBUS_SAMPLE_24C64_ADDRESS_MASK; + CopyData(&tempWrite[SMBUS_SAMPLE_24C64_ADDR_SIZE], tempBuffer, tempWriteLen); + /* Send data to eeprom. */ + dataBuffer.data = tempWrite; + dataBuffer.dataSize = tempWriteLen + SMBUS_SAMPLE_24C64_ADDR_SIZE; + frameOpt = SMBUS_FRAME_FIRST | SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_MasterWriteIT(&g_smbus, DEV_24C64_ADDRESS_WRITE, dataBuffer, frameOpt); + BASE_FUNC_DELAY_MS(20); /* Delay 20 ms. */ + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail!,ret:%d\r\n", __LINE__, ret); + break; + } + + /* Waiting for write completion or failure */ + while (!(g_stopDoneFlag || g_errorFlag)) { + ; + } + g_stopDoneFlag = BASE_CFG_UNSET; + g_txDoneFlag = BASE_CFG_UNSET; + if (g_errorFlag == BASE_CFG_SET) { + g_errorFlag = BASE_CFG_UNSET; /* Reset g_errorFlag. */ + DBG_PRINTF("LINE:%d,Write Data Fail\r\n", __LINE__); + return BASE_STATUS_ERROR; + } + /* Updata the destAddress, srcAddress and len. */ + currentAddr += tempWriteLen; + currentLen -= tempWriteLen; + tempBuffer += tempWriteLen; + } + return ret; +} + +/** + * @brief Send and receive data with the 24c64 eeprom in interrupt mode as master. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +void SMBusInterrupt24c64Processing(void) +{ + BASE_StatusType ret; + unsigned int i; + unsigned int dataFlag; + unsigned char tempWriteBuff[SMBUS_SAMPLE_24C64_OPT_LEN] = {0}; + unsigned int successCnt = 0; + + SystemInit(); + DBG_PRINTF("SMBUS Interrupt AT24C64 Start\r\n"); + for (i = 0; i < SMBUS_SAMPLE_24C64_OPT_LEN; i++) { + tempWriteBuff[i] = 0x5A; /* The written data. */ + } + + for (int j = 0; j < SMBUS_SAMPLE_24C64_TEST_NUM; j++) { + unsigned char tempReadBuff[SMBUS_SAMPLE_24C64_OPT_LEN] = {0}; + + /* Write 24c64 data */ + ret = Sample24c64WriteData(SMBUS_SAMPLE_24C64_OPT_START_ADDR, tempWriteBuff, SMBUS_SAMPLE_24C64_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail,ret:%d\r\n", __LINE__, ret); + } + + /* Read 24c64 data */ + ret = Sample24c64ReadData(SMBUS_SAMPLE_24C64_OPT_START_ADDR, tempReadBuff, SMBUS_SAMPLE_24C64_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail,ret:%d\r\n", __LINE__, ret); + } + + /* Compare read and write data */ + dataFlag = 0; + for (i = 0; i < SMBUS_SAMPLE_24C64_OPT_LEN; i++) { + if (tempReadBuff[i] != tempWriteBuff[i]) { + DBG_PRINTF("SMBUS Data error! offset[%d]\r\nReadData:0x%x\r\nWriteData:0x%x\r\n", i, + tempReadBuff[i], tempWriteBuff[i]); + dataFlag = 1; + break; + } + } + + /* The read data is exactly the same as the written data. */ + if (dataFlag == 0) { + successCnt++; + DBG_PRINTF("SMBUS Data Success\r\n"); + } + } + DBG_PRINTF("SMBUS sample End!\r\nsuccessCnt:%d\r\n", successCnt); +} \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/inc/sample_smbus_slave_blocking.h b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/inc/sample_smbus_slave_blocking.h new file mode 100644 index 0000000000000000000000000000000000000000..ad35eaaebd81bd662d3603824e9a287e491691f5 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/inc/sample_smbus_slave_blocking.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_slave_blocking.h + * @author MCU Driver Team + * @brief Sample for SMBUS module blocking as slave. + * @details This sample demonstrates how to use the SMBUS slave blocking interface to read and write with SMBUS slave. + * To use this sample, the SMBUS interface must be connected to the SMBUS slave. + */ +#ifndef McuMagicTag_SAMPLE_SMBUS_SLAVE_BLOCKING_H +#define McuMagicTag_SAMPLE_SMBUS_SLAVE_BLOCKING_H + +void SMBusSlaveBlockingProcessing(void); + +#endif /* #ifndef McuMagicTag_SAMPLE_SMBUS_SLAVE_BLOCKING_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/init/main.c b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..7a9d8b1133dadc0f7151b4b4f93cdfccf8ef7e36 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/init/main.c @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_smbus_slave_blocking.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +SMBUS_Handle g_smbus; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + SMBusSlaveBlockingProcessing(); + /* USER CODE BEGIN 3 */ + + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/init/main.h b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..4f6feddf216b30fb8c8e5aedb9b9cce39ce583f0 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/init/main.h @@ -0,0 +1,53 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "smbus.h" +#include "smbus_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern SMBUS_Handle g_smbus; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/init/system_init.c b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..2212a5739bf79f671515249baddb995f15f9fc6e --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/init/system_init.c @@ -0,0 +1,76 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +static void SMBUS_Init(void) +{ + HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); + g_smbus.baseAddress = I2C0; + g_smbus.functionMode = SMBUS_MODE_SELECT_SLAVE_ONLY; + g_smbus.addrMode = SMBUS_7_BITS; + g_smbus.sdaHoldTime = 10; /* 10: sad hold time. */ + g_smbus.freq = 400000; /* 400000: i2c speed. */ + g_smbus.transferBuff = NULL; + g_smbus.ignoreAckFlag = BASE_CFG_DISABLE; + g_smbus.handleEx.spikeFilterTime = 0; + g_smbus.handleEx.sdaDelayTime = 0; + g_smbus.timeout = 10000; /* 10000: timeout, unit: ms. */ + g_smbus.slaveOwnAddress = 82; /* 82: slave own address. */ + g_smbus.handleEx.slaveOwnXmbAddressEnable = BASE_CFG_DISABLE; + g_smbus.handleEx.slaveOwnXmbAddress = 0; + g_smbus.generalCallMode = BASE_CFG_DISABLE; + g_smbus.state = SMBUS_STATE_RESET; + HAL_SMBUS_Init(&g_smbus); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + g_uart0.baseAddress = UART0; /* UART-related parameter configuration. */ + g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; /* Enable uart fifo mode. */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); /* Initializing the UART0. */ +} + +void SystemInit(void) +{ + UART0_Init(); + SMBUS_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/readme.md b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..f5d35d704f0190f6b77ce5ff1bc087605fbbfbe5 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/readme.md @@ -0,0 +1,27 @@ +# 配置SMBus作为从机以阻塞方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 +## 关键字: SMBus,从机,数据读取,数据发送,阻塞方式 + +**【功能描述】** ++ 示例代码基于HAL接口完成时钟、SMBus控制器初始化和功能配置。通过阻塞方式与SMBus主机进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 + +**【示例配置】** ++ SMBus控制器选择:选择SMBus作为从机实现与SMBus主机的数据接收和发送。 + ++ SMBus初始化:调用接口"HAL_SMBUS_Init()”完成对示例代码中SMBus的基地址、主从模式、寻址模式(7bit寻址或10bit寻址)、自身地址、通讯速率等参数进行配置。 + ++ 操作SMBus与主机进行数据的发送和接收:
+ 1. 示例代码中首先循环等待SMBus主机发送一个"0x3A"的开始标志帧,当接收到此帧后进入与SMBus主机的数据发送和接收的交互;
+ 2. 调用"HAL_SMBUS_SlaveWriteBlocking()"接口以阻塞方式向SMBus主机发送数据;
+ 3. 调用"HAL_SMBUS_SlaveReadBlocking()"接口以阻塞方式实现从SMBus主机接收数据;
+ 4. 比较步骤2和步骤3发送和接收的数据是否一致,如果接收和发送的数据一致,则Debug串口打印"SMBUS Data Success"信息,不一致时打印错误信息。 + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中会通过SMBus以阻塞方式与主机进行数据的接收和发送,Debug串口打印SMBus与主机进行通信交互的结果信息,当发送和接收的数据一致时Debug串口打印"SMBUS Data Success";当接收和发送的数据不一致时Debug串口打印错误信息。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 示例代码中SMBus必须必须对接主机,且保证主机寻址的地址为82(7bit地址),否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/src/sample_smbus_slave_blocking.c b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/src/sample_smbus_slave_blocking.c new file mode 100644 index 0000000000000000000000000000000000000000..2812bdbe58e20120dcfe63c947ec6eded8561b13 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_blocking/src/sample_smbus_slave_blocking.c @@ -0,0 +1,157 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_slave_blocking.c + * @author MCU Driver Team + * @brief Sample for SMBUS module blocking as slave. + * @details This sample demonstrates how to use the SMBUS slave blocking interface to read and write with SMBUS slave. + * To use this sample, the SMBUS interface must be connected to the SMBUS slave. + */ +#include "main.h" +#include "debug.h" +#include "sample_smbus_slave_blocking.h" + +#define SMBUS_SAMPLE_SLAVE_OPT_LEN 8 +#define SMBUS_TEST_START_FLAG 0x3A +#define SMBUS_SAMPLE_SLAVE_TEST_NUM 500 +#define SMBUS_SAMPLE_MAX_TIMEOUT 10000 + +/** + * @brief Read data from master. + * @param buffer Address of buff to be receive data. + * @param len Number of the data to be read. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType SampleSlaveBlockingReadData(unsigned char *buffer, unsigned int len) +{ + BASE_StatusType ret = BASE_STATUS_OK; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; + unsigned int currentLen = len; + unsigned char *tempBuffer = buffer; + + if (currentLen == 0) { /* Number of illegal transmissions. */ + return ret; + } + /* Read data from the master. */ + dataBuffer.data = tempBuffer; + dataBuffer.dataSize = currentLen; + /* Configuring the SMBUS Transmission Frame Format. */ + frameOpt = SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_SlaveReadBlocking(&g_smbus, dataBuffer, SMBUS_SAMPLE_MAX_TIMEOUT, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + + return ret; +} + +/** + * @brief Send data to the master in blocking mode. + * @param buffer Address of buff to be send. + * @param len Number of the data to be send. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType SampleSlaveBlockingWriteData(unsigned char *buffer, unsigned int len) +{ + BASE_StatusType ret = BASE_STATUS_OK; + unsigned int currentLen = len; + unsigned char *tempBuffer = buffer; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; /* Frame structure for controlling SMBUS transmission */ + if (currentLen == 0) { /* Number of illegal transmissions. */ + return ret; + } + /* Send data to the master. */ + dataBuffer.data = tempBuffer; + dataBuffer.dataSize = currentLen; + /* Configuring the SMBUS Transmission Frame Format. */ + frameOpt = SMBUS_FRAME_FIRST | SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_SlaveWriteBlocking(&g_smbus, dataBuffer, SMBUS_SAMPLE_MAX_TIMEOUT, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail!,ret:%d\r\n", __LINE__, ret); + return ret; + } + + return ret; +} + +/** + * @brief Send and receive data in blocking mode as slave. + * @retval None. + */ +void SMBusSlaveBlockingProcessing(void) +{ + BASE_StatusType ret; + unsigned int i; + unsigned int dataFlag; + unsigned char tempWriteBuff[SMBUS_SAMPLE_SLAVE_OPT_LEN] = {0}; + unsigned int successCnt = 0; + unsigned char testStart = 0; + + SystemInit(); + DBG_PRINTF("SMBUS Slave Blocking Sample Start\r\n"); + for (i = 0; i < SMBUS_SAMPLE_SLAVE_OPT_LEN; i++) { + tempWriteBuff[i] = 0x4A; /* The written data. */ + } + + /* Waiting for the start signal from the master */ + DBG_PRINTF("Waiting Master Start......\r\n"); + while (true) { + SampleSlaveBlockingReadData(&testStart, 1); + if (testStart == SMBUS_TEST_START_FLAG) { + DBG_PRINTF("Master wait done\r\n"); + break; + } + } + + /* Start to send and receive test data. */ + for (int j = 0; j < SMBUS_SAMPLE_SLAVE_TEST_NUM; j++) { + unsigned char tempReadBuff[SMBUS_SAMPLE_SLAVE_OPT_LEN] = {0}; + + /* Write data to master */ + ret = SampleSlaveBlockingWriteData(tempWriteBuff, SMBUS_SAMPLE_SLAVE_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail,ret:%d\r\n", __LINE__, ret); + } + + /* Read data from master */ + ret = SampleSlaveBlockingReadData(tempReadBuff, SMBUS_SAMPLE_SLAVE_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + } + + /* Compare read and write data */ + dataFlag = 0; + for (i = 0; i < SMBUS_SAMPLE_SLAVE_OPT_LEN; i++) { + if (tempReadBuff[i] != tempWriteBuff[i]) { + DBG_PRINTF("SMBUS Data error! offset[%d]\r\nReadData:0x%x\r\nWriteData:0x%x\r\n", i, + tempReadBuff[i], tempWriteBuff[i]); + dataFlag = 1; + break; + } + } + + /* The read data is exactly the same as the written data. */ + if (dataFlag == 0) { + successCnt++; + DBG_PRINTF("SMBUS Data Success\r\n"); + } + } + DBG_PRINTF("SMBUS sample End!\r\nsuccessCnt:%d\r\n", successCnt); +} \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_dma/inc/sample_smbus_slave_dma.h b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/inc/sample_smbus_slave_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..cad84647d6b1a68abeb3ab96e2951a3c54c92a2f --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/inc/sample_smbus_slave_dma.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_slave_dma.c + * @author MCU Driver Team + * @brief Sample for SMBUS module dma as slave. + * @details This sample demonstrates how to use the SMBUS slave DMA interface to read and write with SMBUS slave. + * To use this sample, the SMBUS interface must be connected to the SMBUS slave. + */ +#ifndef McuMagicTag_SAMPLE_SMBUS_SLAVE_DMA_H +#define McuMagicTag_SAMPLE_SMBUS_SLAVE_DMA_H + +void SMBusSlaveDmaProcessing(void); + +#endif /* #ifndef McuMagicTag_SAMPLE_SMBUS_SLAVE_DMA_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_dma/init/main.c b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..7878a3cafb039cab6735d72b799ec13e7b38354d --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/init/main.c @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_smbus_slave_dma.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +SMBUS_Handle g_smbus; +DMA_Handle g_dmac; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + SMBusSlaveDmaProcessing(); + /* USER CODE BEGIN 3 */ + + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_dma/init/main.h b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..8d70246ae03cb590e441821f9ad38474105d7cfe --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/init/main.h @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "smbus.h" +#include "smbus_ex.h" +#include "crg.h" +#include "dma.h" +#include "dma_ex.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern SMBUS_Handle g_smbus; +extern DMA_Handle g_dmac; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +void SMBusTxCallback(void *handle); +void SMBusRxCallback(void *handle); +void SMBusStopCallback(void *handle); +void SMBusErrorCallback(void *handle); + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_dma/init/system_init.c b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..bd54faf6c1c6679baf60279c71db526510c7ea6d --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/init/system_init.c @@ -0,0 +1,161 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +static void DMA_Channel0Init(void *handle) +{ + DMA_ChannelParam dma_param; /* Setting DMA-related parameters. */ + dma_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; + dma_param.srcAddrInc = DMA_ADDR_UNALTERED; + dma_param.destAddrInc = DMA_ADDR_INCREASE; + dma_param.srcPeriph = DMA_REQUEST_I2C_RX; + dma_param.destPeriph = DMA_REQUEST_MEM; + dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; /* Set the moving position width. */ + dma_param.destWidth = DMA_TRANSWIDTH_BYTE; + dma_param.srcBurst = DMA_BURST_LENGTH_1; + dma_param.destBurst = DMA_BURST_LENGTH_1; + dma_param.pHandle = handle; + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ZERO); /* DMA Channel initialization. */ +} + +static void DMA_Channel1Init(void *handle) +{ + DMA_ChannelParam dma_param; /* Setting DMA-related parameters. */ + dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; + dma_param.srcAddrInc = DMA_ADDR_INCREASE; + dma_param.destAddrInc = DMA_ADDR_UNALTERED; + dma_param.srcPeriph = DMA_REQUEST_MEM; + dma_param.destPeriph = DMA_REQUEST_I2C_TX; + dma_param.srcWidth = DMA_TRANSWIDTH_WORD; /* Set the moving position width. */ + dma_param.destWidth = DMA_TRANSWIDTH_WORD; + dma_param.srcBurst = DMA_BURST_LENGTH_1; + dma_param.destBurst = DMA_BURST_LENGTH_1; + dma_param.pHandle = handle; + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ONE); /* DMA Channel initialization. */ +} + +static void DMA_Init(void) +{ + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); + g_dmac.baseAddress = DMA; + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); + IRQ_EnableN(IRQ_DMA_TC); + IRQ_EnableN(IRQ_DMA_ERR); + HAL_DMA_Init(&g_dmac); + DMA_Channel0Init((void *)(&g_smbus)); + HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_ZERO, DMA_PRIORITY_HIGHEST); + DMA_Channel1Init((void *)(&g_smbus)); + HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_ONE, DMA_PRIORITY_HIGHEST); +} + +__weak void SMBusTxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0TxCallback */ + /* USER CODE END I2C0TxCallback */ +} + +__weak void SMBusRxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0RxCallback */ + /* USER CODE END I2C0RxCallback */ +} + +__weak void SMBusStopCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0RxCallback */ + /* USER CODE END I2C0RxCallback */ +} + +__weak void SMBusErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0ErrorCallback */ + /* USER CODE END I2C0ErrorCallback */ +} + +static void SMBUS_Init(void) +{ + HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); + g_smbus.baseAddress = I2C0; + g_smbus.functionMode = SMBUS_MODE_SELECT_SLAVE_ONLY; + g_smbus.addrMode = SMBUS_7_BITS; + g_smbus.sdaHoldTime = 10; /* 10: sad hold time. */ + g_smbus.freq = 400000; /* 400000: i2c speed. */ + g_smbus.transferBuff = NULL; + g_smbus.ignoreAckFlag = BASE_CFG_DISABLE; + g_smbus.handleEx.spikeFilterTime = 0; + g_smbus.handleEx.sdaDelayTime = 0; + g_smbus.timeout = 10000; /* 10000: timeout, unit: ms. */ + g_smbus.slaveOwnAddress = 82; /* 82: slave own address. */ + g_smbus.handleEx.slaveOwnXmbAddressEnable = BASE_CFG_DISABLE; + g_smbus.handleEx.slaveOwnXmbAddress = 0; + g_smbus.generalCallMode = BASE_CFG_DISABLE; + g_smbus.state = SMBUS_STATE_RESET; + g_smbus.rxWaterMark = 1; /* 1:Set the rx watermark. */ + g_smbus.txWaterMark = 12; /* 12:Set the tx watermark. */ + g_smbus.dmaHandle = &g_dmac; + g_smbus.txDmaCh = DMA_CHANNEL_ONE; + g_smbus.rxDmaCh = DMA_CHANNEL_ZERO; + HAL_SMBUS_Init(&g_smbus); + /* Registering Callback Function */ + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_SLAVE_TX_COMPLETE_CB_ID, SMBusTxCallback); + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_SLAVE_RX_COMPLETE_CB_ID, SMBusRxCallback); + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_SLAVE_DETECTED_STOP_COMPLETE_CB_ID, SMBusStopCallback); + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_ERROR_CB_ID, SMBusErrorCallback); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + g_uart0.baseAddress = UART0; /* UART-related parameter configuration. */ + g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; /* Enable uart fifo mode. */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); /* Initializing the UART0. */ +} + +void SystemInit(void) +{ + DMA_Init(); + UART0_Init(); + SMBUS_Init(); + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_dma/readme.md b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..56e5c104f4e895c8927c69f383704eafe4c490c5 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/readme.md @@ -0,0 +1,27 @@ +# 配置SMBus作为从机以DMA方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 +## 关键字: SMBus,从机,数据读取,数据发送,DMA方式 + +**【功能描述】** ++ 示例代码基于HAL接口完成时钟、SMBus控制器初始化和功能配置。通过DMA方式与SMBus主机进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 + +**【示例配置】** ++ SMBus控制器选择:选择SMBus作为从机实现与SMBus主机的数据接收和发送。 + ++ SMBus初始化:调用接口"HAL_SMBUS_Init()”完成对示例代码中SMBUS的基地址、主从模式、寻址模式(7bit寻址或10bit寻址)、自身地址、接收水线和发送水线、通讯速率等参数进行配置。调用"HAL_SMBUS_RegisterCallback()"接口注册收发完成、传输错误时的回调函数。 + ++ 操作SMBus与主机进行数据的发送和接收:
+ 1. 示例代码中首先循环等待SMBus主机发送一个"0x3A"的开始标志帧,当接收到此帧后进入与SMBus主机的数据发送和接收的交互;
+ 2. 调用"HAL_SMBUS_SlaveWriteDMA()"接口以DMA方式向SMBus主机发送数据;
+ 3. 调用"HAL_SMBUS_SlaveReadDMA()"接口以DMA方式实现从SMBus主机接收数据;
+ 4. 比较步骤2和步骤3发送和接收的数据是否一致,如果接收和发送的数据一致,则Debug串口打印"SMBUS Data Success"信息,不一致时打印错误信息。 + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中会通过SMBus以DMA方式与主机进行数据的接收和发送,Debug串口打印SMBus与主机进行通信交互的结果信息,当发送和接收的数据一致时Debug串口打印"SMBUS Data Success";当接收和发送的数据不一致时Debug串口打印错误信息。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 示例代码中SMBus必须必须对接主机,且保证主机寻址的地址为82(7bit地址),否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_dma/src/sample_smbus_slave_dma.c b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/src/sample_smbus_slave_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..d2edbe927361231abd4f8d2f1891b4d8ff87cd7d --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_dma/src/sample_smbus_slave_dma.c @@ -0,0 +1,235 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_slave_dma.c + * @author MCU Driver Team + * @brief Sample for SMBUS module dma as slave. + * @details This sample demonstrates how to use the SMBUS slave DMA interface to read and write with SMBUS slave. + * To use this sample, the SMBUS interface must be connected to the SMBUS slave. + */ +#include "main.h" +#include "debug.h" +#include "sample_smbus_slave_dma.h" + +#define SMBUS_SAMPLE_SLAVE_OPT_LEN 8 +#define SMBUS_TEST_START_FLAG 0x3A + +#define SMBUS_SAMPLE_SLAVE_TEST_NUM 500 + +static volatile int g_txDoneFlag = BASE_CFG_UNSET; +static volatile int g_rxDoneFlag = BASE_CFG_UNSET; +static volatile int g_stopDoneFlag = BASE_CFG_UNSET; +static volatile int g_errorFlag = BASE_CFG_UNSET; + +/** + * @brief SMBUS interrupt sample tx callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusTxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + DBG_PRINTF("Tx callback\r\n"); + g_txDoneFlag = BASE_CFG_SET; +} + +/** + * @brief SMBUS interrupt sample rx callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusRxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + DBG_PRINTF("Rx callback\r\n"); + g_rxDoneFlag = BASE_CFG_SET; +} + +/** + * @brief SMBUS interrupt sample send stop frame callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusStopCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + DBG_PRINTF("stop callback\r\n"); + g_stopDoneFlag = BASE_CFG_SET; +} + +/** + * @brief SMBUS interrupt sample Error callback handle. + * @param handle SMBUS handle. + * @retval None. + */ +void SMBusErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + DBG_PRINTF("Error callback\r\n"); + g_errorFlag = BASE_CFG_SET; +} + +/** + * @brief Read data from master in dma. + * @param buffer Address of buff to be receive data. + * @param len Number of the data to be read. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType SampleSlaveDmaReadData(unsigned char *buffer, unsigned int len) +{ + BASE_StatusType ret = BASE_STATUS_OK; + unsigned int currentLen = len; + unsigned char *tempBuffer = buffer; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; + + if (currentLen == 0) { /* Number of illegal transmissions. */ + return ret; + } + + /* Read data from the master. */ + dataBuffer.data = tempBuffer; + dataBuffer.dataSize = currentLen; + /* Configuring the SMBUS Transmission Frame Format. */ + frameOpt = SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_SlaveReadDMA(&g_smbus, dataBuffer, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + /* Waiting for read completion or failure */ + while (!(g_stopDoneFlag || g_errorFlag)) { + ; + } + g_rxDoneFlag = BASE_CFG_UNSET; + g_stopDoneFlag = BASE_CFG_UNSET; + if (g_errorFlag == BASE_CFG_SET) { + DBG_PRINTF("LINE:%d,Read Data Fail\r\n", __LINE__); + g_errorFlag = BASE_CFG_UNSET; + return BASE_STATUS_ERROR; + } + + return ret; +} + +/** + * @brief Send data to the master in dma. + * @param buffer Address of buff to be send. + * @param len Number of the data to be send. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType SampleSlaveDmaWriteData(unsigned char *buffer, unsigned int len) +{ + BASE_StatusType ret = BASE_STATUS_OK; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; + unsigned int currentLen = len; + unsigned char *tempBuffer = buffer; + + if (currentLen == 0) { /* Number of illegal transmissions. */ + return ret; + } + + /* Send data to the master. */ + dataBuffer.data = tempBuffer; + dataBuffer.dataSize = currentLen; + /* Configuring the SMBUS Transmission Frame Format. */ + frameOpt = SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_SlaveWriteDMA(&g_smbus, dataBuffer, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail!,ret:%d\r\n", __LINE__, ret); + return ret; + } + /* Waiting for read completion or failure */ + while (!(g_stopDoneFlag || g_errorFlag)) { + ; + } + g_txDoneFlag = BASE_CFG_UNSET; + g_stopDoneFlag = BASE_CFG_UNSET; + if (g_errorFlag == BASE_CFG_SET) { + g_errorFlag = BASE_CFG_UNSET; + DBG_PRINTF("LINE:%d,Read Data Fail\r\n", __LINE__); + return BASE_STATUS_ERROR; + } + + return ret; +} + +/** + * @brief Send and receive data in dma mode as slave. + * @retval None. + */ +void SMBusSlaveDmaProcessing(void) +{ + BASE_StatusType ret; + unsigned int i; + unsigned int dataFlag; + unsigned char tempWriteBuff[SMBUS_SAMPLE_SLAVE_OPT_LEN] = {0}; + unsigned int successCnt = 0; + unsigned char testStart = 0; + + SystemInit(); + DBG_PRINTF("SMBUS Slave Dma Sample Start\r\n"); + for (i = 0; i < SMBUS_SAMPLE_SLAVE_OPT_LEN; i++) { + tempWriteBuff[i] = 0x4A; /* The written data. */ + } + /* Waiting for the start signal from the master */ + DBG_PRINTF("Waiting Master Start......\r\n"); + while (true) { + SampleSlaveDmaReadData(&testStart, 1); + if (testStart == SMBUS_TEST_START_FLAG) { + DBG_PRINTF("Master wait done\r\n"); + break; + } + } + + /* Start to send and receive test data. */ + for (int j = 0; j < SMBUS_SAMPLE_SLAVE_TEST_NUM; j++) { + unsigned char tempReadBuff[SMBUS_SAMPLE_SLAVE_OPT_LEN] = {0}; + + /* Write data to master */ + ret = SampleSlaveDmaWriteData(tempWriteBuff, SMBUS_SAMPLE_SLAVE_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail,ret:%d\r\n", __LINE__, ret); + } + + /* Read data from master */ + ret = SampleSlaveDmaReadData(tempReadBuff, SMBUS_SAMPLE_SLAVE_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + } + + BASE_FUNC_DELAY_MS(10); /* Delay 10 ms. */ + /* Compare read and write data */ + dataFlag = 0; + for (i = 0; i < SMBUS_SAMPLE_SLAVE_OPT_LEN; i++) { + if (tempReadBuff[i] != tempWriteBuff[i]) { + DBG_PRINTF("SMBUS Data error! offset[%d]\r\nReadData:0x%x\r\nWriteData:0x%x\r\n", i, + tempReadBuff[i], tempWriteBuff[i]); + dataFlag = 1; + break; + } + } + + /* The read data is exactly the same as the written data. */ + if (dataFlag == 0) { + successCnt++; + DBG_PRINTF("SMBUS Data Success\r\n"); + } + } + DBG_PRINTF("SMBUS sample End!\r\nsuccessCnt:%d\r\n", successCnt); +} \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_it/inc/sample_smbus_slave_interrupt.h b/src/application/drivers_sample/smbus/sample_smbus_slave_it/inc/sample_smbus_slave_interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..998fcc3284f31345cb2029dedbd15eb93be4d2d6 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_it/inc/sample_smbus_slave_interrupt.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_slave_interrupt.c + * @author MCU Driver Team + * @brief Sample for SMBUS module interrupt as slave. + * @details This sample demonstrates how to use the SMBUS slave interrupt interface to read and write with SMBUS slave. + * To use this sample, the SMBUS interface must be connected to the SMBUS slave. + */ +#ifndef McuMagicTag_SAMPLE_SMBUS_SLAVE_INTERRUPT_H +#define McuMagicTag_SAMPLE_SMBUS_SLAVE_INTERRUPT_H + +void SMBusSlaveInterruptProcessing(void); + +#endif /* #ifndef McuMagicTag_SAMPLE_SMBUS_SLAVE_INTERRUPT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_it/init/main.c b/src/application/drivers_sample/smbus/sample_smbus_slave_it/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..e0f5104434efadf3892c9160bbaddb4057399048 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_it/init/main.c @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_smbus_slave_interrupt.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +SMBUS_Handle g_smbus; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + SMBusSlaveInterruptProcessing(); + /* USER CODE BEGIN 3 */ + + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_it/init/main.h b/src/application/drivers_sample/smbus/sample_smbus_slave_it/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..e6b221e08b3e7489fb3f0805dec8e81a65288564 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_it/init/main.h @@ -0,0 +1,58 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "smbus.h" +#include "smbus_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern SMBUS_Handle g_smbus; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +void SMBusTxCallback(void *handle); +void SMBusRxCallback(void *handle); +void SMBusStopCallback(void *handle); +void SMBusErrorCallback(void *handle); + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_it/init/system_init.c b/src/application/drivers_sample/smbus/sample_smbus_slave_it/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..f858b723cc9bd824674f872bbb454111828b4684 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_it/init/system_init.c @@ -0,0 +1,107 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +__weak void SMBusTxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0TxCallback */ + /* USER CODE END I2C0TxCallback */ +} + +__weak void SMBusRxCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0RxCallback */ + /* USER CODE END I2C0RxCallback */ +} + +__weak void SMBusErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN I2C0ErrorCallback */ + /* USER CODE END I2C0ErrorCallback */ +} + +static void SMBUS_Init(void) +{ + HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); + + g_smbus.baseAddress = I2C0; + g_smbus.functionMode = SMBUS_MODE_SELECT_SLAVE_ONLY; + g_smbus.addrMode = SMBUS_7_BITS; + g_smbus.sdaHoldTime = 10; /* 10: sad hold time. */ + g_smbus.freq = 400000; /* 400000: i2c speed. */ + g_smbus.transferBuff = NULL; + g_smbus.ignoreAckFlag = BASE_CFG_DISABLE; + g_smbus.handleEx.spikeFilterTime = 0; + g_smbus.handleEx.sdaDelayTime = 0; + g_smbus.timeout = 10000; /* 10000: timeout, unit: ms. */ + g_smbus.slaveOwnAddress = 82; /* 82: slave own address. */ + g_smbus.handleEx.slaveOwnXmbAddressEnable = BASE_CFG_DISABLE; + g_smbus.handleEx.slaveOwnXmbAddress = 0; + g_smbus.generalCallMode = BASE_CFG_DISABLE; + g_smbus.state = SMBUS_STATE_RESET; + g_smbus.rxWaterMark = 1; /* 1:Set the rx watermark. */ + g_smbus.txWaterMark = 12; /* 12:Set the tx watermark. */ + HAL_SMBUS_Init(&g_smbus); + /* Registering Callback Function */ + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_SLAVE_TX_COMPLETE_CB_ID, SMBusTxCallback); + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_SLAVE_RX_COMPLETE_CB_ID, SMBusRxCallback); + HAL_SMBUS_RegisterCallback(&g_smbus, SMBUS_ERROR_CB_ID, SMBusErrorCallback); + IRQ_Register(IRQ_I2C0, HAL_SMBUS_IrqHandler, &g_smbus); + IRQ_SetPriority(IRQ_I2C0, 1); + IRQ_EnableN(IRQ_I2C0); /* Enable interrupt. */ +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + g_uart0.baseAddress = UART0; /* UART-related parameter configuration. */ + g_uart0.baudRate = UART0_BAND_RATE; /* Setting the UART Baud Rate. */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; /* Enable uart fifo mode. */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); /* Initializing the UART0. */ +} + +void SystemInit(void) +{ + UART0_Init(); + SMBUS_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_it/readme.md b/src/application/drivers_sample/smbus/sample_smbus_slave_it/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..9c4ce600e355f607a9f772d7764219b5f88ef2a1 --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_it/readme.md @@ -0,0 +1,27 @@ +# 配置SMBus作为从机以中断方式进行数据的接收、发送,通过Debug串口打印数据收发的结果 +## 关键字: SMBus,从机,数据读取,数据发送,中断方式 + +**【功能描述】** ++ 示例代码基于HAL接口完成时钟、SMBus控制器初始化和功能配置。通过中断方式与SMBus主机进行数据的接收和数据的发送,通过Debug串口打印数据收发成功或失败的信息。 + +**【示例配置】** ++ SMBus控制器选择:选择SMBus作为从机实现与SMBus主机的数据接收和发送。 + ++ SMBus初始化:调用接口"HAL_SMBUS_Init()”完成对示例代码中SMBus的基地址、主从模式、寻址模式(7bit寻址或10bit寻址)、自身地址、接收水线和发送水线、通讯速率等参数进行配置。调用"HAL_SMBUS_RegisterCallback()"接口注册中断回调函数,并使能相关中断配置。 + ++ 操作SMBus与主机进行数据的发送和接收:
+ 1. 示例代码中首先循环等待SMBus主机发送一个"0x3A"的开始标志帧,当接收到此帧后进入与SMBus主机的数据发送和接收的交互;
+ 2. 调用"HAL_SMBUS_SlaveWriteIT()"接口以中断方式向SMBus主机发送数据;
+ 3. 调用"HAL_SMBUS_SlaveReadIT()"接口以中断方式实现从SMBus主机接收数据;
+ 4. 比较步骤2和步骤3发送和接收的数据是否一致,如果接收和发送的数据一致,则Debug串口打印"SMBUS Data Success"信息,不一致时打印错误信息。 + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中会通过SMBus以中断方式与主机进行数据的接收和发送,Debug串口打印SMBus与主机进行通信交互的结果信息,当发送和接收的数据一致时Debug串口打印"SMBUS Data Success";当接收和发送的数据不一致时Debug串口打印错误信息。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0配置。 ++ 示例代码中SMBus必须必须对接主机,且保证主机寻址的地址为82(7bit地址),否则示例代码无法正常运行。 + ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/smbus/sample_smbus_slave_it/src/sample_smbus_slave_interrupt.c b/src/application/drivers_sample/smbus/sample_smbus_slave_it/src/sample_smbus_slave_interrupt.c new file mode 100644 index 0000000000000000000000000000000000000000..5ec6dc15ba9a50f1ceb7fa9256f3efeb3a6f938e --- /dev/null +++ b/src/application/drivers_sample/smbus/sample_smbus_slave_it/src/sample_smbus_slave_interrupt.c @@ -0,0 +1,227 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_smbus_slave_interrupt.c + * @author MCU Driver Team + * @brief Sample for SMBUS module interrupt as slave. + * @details This sample demonstrates how to use the SMBUS slave interrupt interface to read and write with SMBUS slave. + * To use this sample, the SMBUS interface must be connected to the SMBUS slave. + */ +#include "main.h" +#include "debug.h" +#include "sample_smbus_slave_interrupt.h" + +#define SMBUS_SAMPLE_SLAVE_OPT_LEN 8 +#define SMBUS_TEST_START_FLAG 0x3A + +#define SMBUS_SAMPLE_SLAVE_TEST_NUM 500 + +static volatile int g_txDoneFlag = BASE_CFG_UNSET; +static volatile int g_rxDoneFlag = BASE_CFG_UNSET; +static volatile int g_stopDoneFlag = BASE_CFG_UNSET; +static volatile int g_errorFlag = BASE_CFG_UNSET; + +/** + * @brief I2c interrupt sample tx callback handle. + * @param handle I2c handle. + * @retval None. + */ +void SMBusTxCallback(void *handle) +{ + DBG_PRINTF("SampleSMBusTxDone\r\n"); + BASE_FUNC_UNUSED(handle); + g_txDoneFlag = BASE_CFG_SET; +} + +/** + * @brief I2c interrupt sample rx callback handle. + * @param handle I2c handle. + * @retval None. + */ +void SMBusRxCallback(void *handle) +{ + DBG_PRINTF("SampleSMBusRxDone\r\n"); + BASE_FUNC_UNUSED(handle); + g_rxDoneFlag = BASE_CFG_SET; +} + +/** + * @brief I2c interrupt sample rx callback handle. + * @param handle I2c handle. + * @retval None. + */ +void SMBusStopCallback(void *handle) +{ + DBG_PRINTF("SMBusStopCallback\r\n"); + BASE_FUNC_UNUSED(handle); + g_stopDoneFlag = BASE_CFG_SET; +} + +/** + * @brief I2c interrupt sample Error callback handle. + * @param handle I2c handle. + * @retval None. + */ +void SMBusErrorCallback(void *handle) +{ + DBG_PRINTF("SampleSMBusError\r\n"); + BASE_FUNC_UNUSED(handle); + g_errorFlag = BASE_CFG_SET; +} + +/** + * @brief Read data from master in interrupt. + * @param buffer Address of buff to be receive data. + * @param len Number of the data to be read. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType SampleSlaveInterruptReadData(unsigned char *buffer, unsigned int len) +{ + BASE_StatusType ret = BASE_STATUS_OK; /* Transfer success and failure status. */ + unsigned int currentLen = len; + unsigned char *tempBuffer = buffer; + + if (currentLen == 0) { /* Number of illegal transmissions. */ + return ret; + } + /* Read data from the master. */ + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; + dataBuffer.data = tempBuffer; + dataBuffer.dataSize = currentLen; + frameOpt = SMBUS_FRAME_FIRST | SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_SlaveReadIT(&g_smbus, dataBuffer, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + /* Waiting for read completion or failure */ + while (!(g_rxDoneFlag || g_errorFlag)) { + ; + } + g_rxDoneFlag = BASE_CFG_UNSET; + if (g_errorFlag == BASE_CFG_SET) { + g_errorFlag = BASE_CFG_UNSET; + DBG_PRINTF("LINE:%d,Read Data Fail\r\n", __LINE__); + return BASE_STATUS_ERROR; + } + + return ret; +} + +/** + * @brief Send data to the master in interrupt. + * @param buffer Address of buff to be send. + * @param len Number of the data to be send. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType SampleSlaveInterruptWriteData(unsigned char *buffer, unsigned int len) +{ + BASE_StatusType ret = BASE_STATUS_OK; /* Transfer success and failure status. */ + unsigned int currentLen = len; + unsigned char *tempBuffer = buffer; + SMBUS_DataBuffer dataBuffer; + unsigned int frameOpt; /* Frame structure for controlling SMBUS transmission. */ + if (currentLen == 0) { + return ret; + } + /* Send data to the master. */ + dataBuffer.data = tempBuffer; + dataBuffer.dataSize = currentLen; + frameOpt = SMBUS_FRAME_FIRST | SMBUS_FRAME_START | SMBUS_FRAME_MIDDLE | SMBUS_FRAME_STOP; + ret = HAL_SMBUS_SlaveWriteIT(&g_smbus, dataBuffer, frameOpt); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail!,ret:%d\r\n", __LINE__, ret); + return ret; + } + /* Waiting for write completion or failure */ + while (!(g_txDoneFlag || g_errorFlag)) { + ; + } + g_txDoneFlag = BASE_CFG_UNSET; + if (g_errorFlag == BASE_CFG_SET) { + g_errorFlag = BASE_CFG_UNSET; + DBG_PRINTF("LINE:%d,Write Data Fail\r\n", __LINE__); + return BASE_STATUS_ERROR; + } + + return ret; +} + +/** + * @brief Send and receive data in interrupt mode as slave. + * @retval None. + */ +void SMBusSlaveInterruptProcessing(void) +{ + BASE_StatusType ret; + unsigned int i; + unsigned int dataFlag; + unsigned char tempWriteBuff[SMBUS_SAMPLE_SLAVE_OPT_LEN] = {0}; + unsigned int successCnt = 0; + unsigned char testStart = 0; + + SystemInit(); + DBG_PRINTF("SMBUS Slave Interrupt Sample Start\r\n"); + for (i = 0; i < SMBUS_SAMPLE_SLAVE_OPT_LEN; i++) { + tempWriteBuff[i] = 0x4A; /* The written data. */ + } + /* Waiting for the start signal from the master */ + DBG_PRINTF("Waiting Master Start......\r\n"); + while (true) { + SampleSlaveInterruptReadData(&testStart, 1); + if (testStart == SMBUS_TEST_START_FLAG) { + DBG_PRINTF("Master wait done\r\n"); + break; + } + } + /* Start to send and receive test data. */ + for (int j = 0; j < SMBUS_SAMPLE_SLAVE_TEST_NUM; j++) { + unsigned char tempReadBuff[SMBUS_SAMPLE_SLAVE_OPT_LEN] = {0}; + + /* Write data to master */ + ret = SampleSlaveInterruptWriteData(tempWriteBuff, SMBUS_SAMPLE_SLAVE_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Write Data Fail,ret:%d\r\n", __LINE__, ret); + } + + /* Read data from master */ + ret = SampleSlaveInterruptReadData(tempReadBuff, SMBUS_SAMPLE_SLAVE_OPT_LEN); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + } + + BASE_FUNC_DELAY_MS(5); /* Delay 5 ms. */ + /* Compare read and write data */ + dataFlag = 0; + for (i = 0; i < SMBUS_SAMPLE_SLAVE_OPT_LEN; i++) { + if (tempReadBuff[i] != tempWriteBuff[i]) { + DBG_PRINTF("SMBUS Data error! offset[%d]\r\nReadData:0x%x\r\nWriteData:0x%x\r\n", i, + tempReadBuff[i], tempWriteBuff[i]); + dataFlag = 1; + break; + } + } + + /* The read data is exactly the same as the written data. */ + if (dataFlag == 0) { + successCnt++; + DBG_PRINTF("SMBUS Data Success\r\n"); + } + } + DBG_PRINTF("SMBUS sample End!\r\nsuccessCnt:%d\r\n", successCnt); +} \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_blocking_kta7953/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_blocking_kta7953/init/system_init.c index 4050da8e376883f1d729103cccb017611be8c1b4..0b01e01db6b5a6f97cedb305f243e3eef44de5f3 100644 --- a/src/application/drivers_sample/spi/sample_spi_blocking_kta7953/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_blocking_kta7953/init/system_init.c @@ -50,7 +50,6 @@ static void SPI_Init(void) HAL_CRG_IpClkSelectSet(SPI_BASE, CRG_PLL_NO_PREDV); g_spiSampleHandle.baseAddress = SPI; - g_spiSampleHandle.irqNum = IRQ_SPI; g_spiSampleHandle.mode = HAL_SPI_MASTER; g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; @@ -83,7 +82,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; diff --git a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/main.c b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/main.c index 9a8240a8abadd5603f4a9878d7b468d952dca140..57be007f5a59f06a8f4fa9aa5ffa9a63f19933eb 100644 --- a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/main.c +++ b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/main.c @@ -22,29 +22,38 @@ #include "typedefs.h" #include "feature.h" +#include "sample_spi_blocking_w25q32.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ UART_Handle g_uart0; SPI_Handle g_spiSampleHandle; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ W25Q32BlockingSampleProcessing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/main.h b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/main.h index f2ff5b487d052e8bdaab746cc6a38ca2c3ba5751..8f83557e573d81b81186d0e0ccfdad46695a4d19 100644 --- a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/main.h +++ b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/main.h @@ -25,8 +25,11 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "spi.h" +#include "spi_ex.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -47,4 +50,8 @@ extern SPI_Handle g_spiSampleHandle; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/system_init.c index ad52532caec6b1b84970c0bb01bc1d653907b04e..48e15d27c9b36c96bcd0781312ed894649f5f32a 100644 --- a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/init/system_init.c @@ -27,21 +27,23 @@ #define UART0_BAND_RATE 115200 #define SPI1_FREQ_SCR 2 -#define SPI1_FREQ_CPSDVSR 10 +#define SPI1_FREQ_CPSDVSR 50 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; - crg.baseAddress = CRG; /* crg baseaddress */ + crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + /* The 1 MHz freq is equal to the clock frequency / (clk_1m_div + 1). 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* CRG init */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; @@ -50,22 +52,21 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void SPI1_Init(void) { - HAL_CRG_IpEnableSet(SPI1_BASE, IP_CLK_ENABLE); - + HAL_CRG_IpEnableSet(SPI1_BASE, IP_CLK_ENABLE); /* SPI1 clock enable. */ g_spiSampleHandle.baseAddress = SPI1; g_spiSampleHandle.mode = HAL_SPI_MASTER; /* spi master */ g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_CALLBACK; g_spiSampleHandle.xFerMode = HAL_XFER_MODE_BLOCKING; g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; /* spi ploarity is 0 */ - g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_1; + g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_0; g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; /* motorola frame format */ g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_8BIT; g_spiSampleHandle.freqScr = SPI1_FREQ_SCR; g_spiSampleHandle.freqCpsdvsr = SPI1_FREQ_CPSDVSR; g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; - g_spiSampleHandle.waitVal = 127; /* microwire wait time 127 */ + g_spiSampleHandle.waitVal = 127; /* 127 is microwire wait time */ g_spiSampleHandle.rxBuff = NULL; g_spiSampleHandle.txBuff = NULL; g_spiSampleHandle.transferSize = 0; @@ -82,18 +83,17 @@ static void SPI1_Init(void) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - - g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; - g_uart0.dataLength = UART_DATALENGTH_8BIT; /* data length 8 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; /* blocking mode */ + g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; - g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; /* fifo size 8 */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; @@ -103,47 +103,47 @@ static void UART0_Init(void) static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_SPI1_CLK); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_SPI1_CLK, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_SPI1_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_SPI1_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_SPI1_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO1_4_AS_SPI1_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO1_4_AS_SPI1_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO1_4_AS_SPI1_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO1_4_AS_SPI1_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO1_4_AS_SPI1_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO3_0_AS_SPI1_CSN1); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO3_0_AS_SPI1_CSN1, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO3_0_AS_SPI1_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO3_0_AS_SPI1_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO3_0_AS_SPI1_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO1_3_AS_SPI1_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO1_3_AS_SPI1_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO1_3_AS_SPI1_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO1_3_AS_SPI1_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO1_3_AS_SPI1_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_SPI1_CSN0); /* Check function selection */ HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_SPI1_CSN0, PULL_NONE); /* Pull-up and pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_SPI1_CSN0, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_SPI1_CSN0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_SPI1_CSN0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_0_AS_SPI1_CLK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_0_AS_SPI1_CLK, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_0_AS_SPI1_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_0_AS_SPI1_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_0_AS_SPI1_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_2_AS_SPI1_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_2_AS_SPI1_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_2_AS_SPI1_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_2_AS_SPI1_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_2_AS_SPI1_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_1_AS_SPI1_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_1_AS_SPI1_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_1_AS_SPI1_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_1_AS_SPI1_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_1_AS_SPI1_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_3_AS_SPI1_CSN1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_3_AS_SPI1_CSN1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_3_AS_SPI1_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_3_AS_SPI1_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_3_AS_SPI1_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/readme.md b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/readme.md index 76b7715d51a4b82b0256b90719a503404210efcf..fd224a19b8ddbf58e9c2a8a77d2b22f4b8ac1679 100644 --- a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/readme.md +++ b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32/readme.md @@ -18,3 +18,6 @@ **【注意事项】** + 使用此示例代码必须外接flash芯片w25q32。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/main.c b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/main.c index b1190ef85c48a03387b32bfb2dc3605e31c0563d..6ad91464ed7b7ce84f98383b60fe1405a46bcf63 100644 --- a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/main.c +++ b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/main.c @@ -25,27 +25,35 @@ #include "sample_spi_blocking_w25q32_internal.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ SPI_Handle g_spiSampleHandle; UART_Handle g_uart0; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ W25Q32BlockingSampleProcessing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/main.h b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/main.h index 4b520d3650f25024e7db505925f17e3e743dc4df..8c57f6fd5f8e49569ff5e761a8597ad5979d2b43 100644 --- a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/main.h +++ b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/main.h @@ -47,4 +47,8 @@ extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/system_init.c index 53603017faffed806c9f2fe4788db7abbc587bd6..c8e39bf3a5e5049eb79506d14fedc48306665f30 100644 --- a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/init/system_init.c @@ -39,7 +39,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* CRG init */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; @@ -53,29 +53,30 @@ static void SPI_Init(void) g_spiSampleHandle.baseAddress = SPI; - g_spiSampleHandle.mode = HAL_SPI_MASTER; /* spi master */ + g_spiSampleHandle.mode = HAL_SPI_MASTER; g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; g_spiSampleHandle.xFerMode = HAL_XFER_MODE_BLOCKING; - g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; /* spi ploarity is 0 */ + g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_1; g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; - g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; /* motorola frame format */ + g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_8BIT; g_spiSampleHandle.freqScr = SPI_FREQ_SCR; g_spiSampleHandle.freqCpsdvsr = SPI_FREQ_CPSDVSR; g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; - g_spiSampleHandle.waitVal = 127; /* microwire wait time 127 */ + g_spiSampleHandle.waitVal = 127; /* 127 is microwire wait time */ g_spiSampleHandle.rxBuff = NULL; g_spiSampleHandle.txBuff = NULL; g_spiSampleHandle.transferSize = 0; - g_spiSampleHandle.txCount = 0; /* transfer count */ + g_spiSampleHandle.txCount = 0; g_spiSampleHandle.rxCount = 0; g_spiSampleHandle.state = HAL_SPI_STATE_RESET; g_spiSampleHandle.rxIntSize = SPI_RX_INTERRUPT_SIZE_1; - g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; /* tx interrupt size */ + g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; g_spiSampleHandle.rxDMABurstSize = SPI_RX_DMA_BURST_SIZE_1; g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; HAL_SPI_Init(&g_spiSampleHandle); + HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_0); } static void UART0_Init(void) @@ -83,13 +84,13 @@ static void UART0_Init(void) HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ + g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; - g_uart0.dataLength = UART_DATALENGTH_8BIT; /* data length 8 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; /* blocking mode */ + g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; diff --git a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/readme.md b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/readme.md index 76b7715d51a4b82b0256b90719a503404210efcf..15f08b4b06085d8c275ffe3d05328dcf114e0d41 100644 --- a/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/readme.md +++ b/src/application/drivers_sample/spi/sample_spi_blocking_w25q32_internal/readme.md @@ -18,3 +18,6 @@ **【注意事项】** + 使用此示例代码必须外接flash芯片w25q32。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 diff --git a/src/application/drivers_sample/spi/sample_spi_dma_kta7953/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_dma_kta7953/init/system_init.c index 1e3c7ad3077e65facd234e2162de818e6780c256..13473b67d8dea9175f826cbda385b8c2cb017e44 100644 --- a/src/application/drivers_sample/spi/sample_spi_dma_kta7953/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_dma_kta7953/init/system_init.c @@ -78,12 +78,12 @@ static void DMA_Channel2Init(void *handle) static void DMA_Init(void) { + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; g_dmac.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; g_dmac.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.irqNumTc = IRQ_DMA_TC; - g_dmac.irqNumError = IRQ_DMA_ERR; - HAL_DMA_IRQService(&g_dmac); + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); @@ -133,7 +133,6 @@ static void SPI_Init(void) HAL_CRG_IpClkSelectSet(SPI_BASE, CRG_PLL_NO_PREDV); g_spiSampleHandle.baseAddress = SPI; - g_spiSampleHandle.irqNum = IRQ_SPI; g_spiSampleHandle.mode = HAL_SPI_MASTER; g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; @@ -175,7 +174,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; diff --git a/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/main.c b/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/main.c index 60492effb7e044f18ae6de7a4d647ac2216ee054..b254228e2e979403f700dd81f14709de3359f303 100644 --- a/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/main.c +++ b/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/main.c @@ -22,30 +22,39 @@ #include "typedefs.h" #include "feature.h" +#include "sample_spi_dma_w25q32.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ UART_Handle g_uart0; SPI_Handle g_spiSampleHandle; DMA_Handle g_dmac; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ W25Q32DmaSampleProcessing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/main.h b/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/main.h index 0159263ea1d89f9cc3a975caef0aaebcd4f39ce3..2ee44f86c40dff0081b99710f5f0a91e95570ace 100644 --- a/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/main.h +++ b/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/main.h @@ -25,9 +25,13 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "spi.h" +#include "spi_ex.h" #include "crg.h" #include "dma.h" +#include "dma_ex.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -56,4 +60,8 @@ void TxRxSampleCallbackHandle(void *handle); void ErrorSampleCallbackHandle(void *handle); void SPICsCallback(void *handle); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/system_init.c index da38c36f05360a9e0081f2de0fca096f140fb578..611654e9fde84cbeb8e4286f3a4f80c7e07db9dd 100644 --- a/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_dma_w25q32/init/system_init.c @@ -27,21 +27,23 @@ #define UART0_BAND_RATE 115200 #define SPI1_FREQ_SCR 2 -#define SPI1_FREQ_CPSDVSR 10 +#define SPI1_FREQ_CPSDVSR 50 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; - crg.baseAddress = CRG; /* crg baseaddress */ + crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + /* The 1 MHz freq is equal to the clock frequency / (clk_1m_div + 1). 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* CRG init */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; @@ -67,7 +69,7 @@ static void DMA_Channel0Init(void *handle) static void DMA_Channel1Init(void *handle) { DMA_ChannelParam dma_param; - dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; /* memory to periph */ + dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; /* periph to memory */ dma_param.srcAddrInc = DMA_ADDR_INCREASE; dma_param.destAddrInc = DMA_ADDR_UNALTERED; dma_param.srcPeriph = DMA_REQUEST_MEM; @@ -82,8 +84,8 @@ static void DMA_Channel1Init(void *handle) static void DMA_Init(void) { - HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); - g_dmac.baseAddress = DMA; /* dma baseaddress */ + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); /* dma baseaddress */ + g_dmac.baseAddress = DMA; IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); @@ -132,22 +134,21 @@ __weak void SPICsCallback(void *handle) static void SPI1_Init(void) { - HAL_CRG_IpEnableSet(SPI1_BASE, IP_CLK_ENABLE); - + HAL_CRG_IpEnableSet(SPI1_BASE, IP_CLK_ENABLE); /* SPI1 clock enable. */ g_spiSampleHandle.baseAddress = SPI1; g_spiSampleHandle.mode = HAL_SPI_MASTER; /* spi master */ g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_CALLBACK; g_spiSampleHandle.xFerMode = HAL_XFER_MODE_DMA; g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; /* spi ploarity is 0 */ - g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_1; + g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_0; g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; /* motorola frame format */ g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_8BIT; g_spiSampleHandle.freqScr = SPI1_FREQ_SCR; g_spiSampleHandle.freqCpsdvsr = SPI1_FREQ_CPSDVSR; g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; - g_spiSampleHandle.waitVal = 127; /* mircowire wait time 127 */ + g_spiSampleHandle.waitVal = 127; /* 127 is microwire wait time */ g_spiSampleHandle.rxBuff = NULL; g_spiSampleHandle.txBuff = NULL; g_spiSampleHandle.transferSize = 0; @@ -160,10 +161,9 @@ static void SPI1_Init(void) g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; g_spiSampleHandle.dmaHandle = &g_dmac; g_spiSampleHandle.txDmaCh = DMA_CHANNEL_ONE; - g_spiSampleHandle.rxDmaCh = DMA_CHANNEL_ZERO; /* dma rx channel is 0 */ + g_spiSampleHandle.rxDmaCh = DMA_CHANNEL_ZERO; HAL_SPI_Init(&g_spiSampleHandle); - /* spi register callback */ HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_TX_COMPLETE_CB_ID, TxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_RX_COMPLETE_CB_ID, RxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_TX_RX_COMPLETE_CB_ID, TxRxSampleCallbackHandle); @@ -174,18 +174,17 @@ static void SPI1_Init(void) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - - g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; - g_uart0.dataLength = UART_DATALENGTH_8BIT; /* data length 8 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; /* blocking mode */ + g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; - g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; /* fifo size 8 */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; @@ -195,47 +194,47 @@ static void UART0_Init(void) static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_SPI1_CLK); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_SPI1_CLK, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_SPI1_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_SPI1_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_SPI1_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO1_4_AS_SPI1_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO1_4_AS_SPI1_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO1_4_AS_SPI1_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO1_4_AS_SPI1_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO1_4_AS_SPI1_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO3_0_AS_SPI1_CSN1); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO3_0_AS_SPI1_CSN1, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO3_0_AS_SPI1_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO3_0_AS_SPI1_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO3_0_AS_SPI1_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO1_3_AS_SPI1_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO1_3_AS_SPI1_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO1_3_AS_SPI1_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO1_3_AS_SPI1_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO1_3_AS_SPI1_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_SPI1_CSN0); /* Check function selection */ HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_SPI1_CSN0, PULL_NONE); /* Pull-up and pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_SPI1_CSN0, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_SPI1_CSN0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_SPI1_CSN0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_0_AS_SPI1_CLK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_0_AS_SPI1_CLK, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_0_AS_SPI1_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_0_AS_SPI1_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_0_AS_SPI1_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_2_AS_SPI1_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_2_AS_SPI1_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_2_AS_SPI1_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_2_AS_SPI1_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_2_AS_SPI1_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_1_AS_SPI1_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_1_AS_SPI1_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_1_AS_SPI1_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_1_AS_SPI1_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_1_AS_SPI1_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_3_AS_SPI1_CSN1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_3_AS_SPI1_CSN1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_3_AS_SPI1_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_3_AS_SPI1_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_3_AS_SPI1_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/spi/sample_spi_dma_w25q32/readme.md b/src/application/drivers_sample/spi/sample_spi_dma_w25q32/readme.md index 058bb69ddf052dd06462e4c7914d6fe77efa4502..f6d9be7a70195283eea0abe1ea3d781e9d64922d 100644 --- a/src/application/drivers_sample/spi/sample_spi_dma_w25q32/readme.md +++ b/src/application/drivers_sample/spi/sample_spi_dma_w25q32/readme.md @@ -17,4 +17,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。当每次DMA搬运完成会进入回调函数打印log,串口打印写入的120个数据和读取的120个数据,如果写入和读取的数据是相同则打印data correct,否则打印data err。 **【注意事项】** -+ 使用此示例代码必须外接flash芯片w25q32。 \ No newline at end of file ++ 使用此示例代码必须外接flash芯片w25q32。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/main.c b/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/main.c index 65d342632c51204bcc6e649c18bc97165daaf319..84022336675097d679c90d6d5f60d2044e0ae744 100644 --- a/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/main.c +++ b/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/main.c @@ -25,28 +25,36 @@ #include "sample_spi_dma_w25q32_internal.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ SPI_Handle g_spiSampleHandle; UART_Handle g_uart0; DMA_Handle g_dmac; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ W25Q32DmaSampleProcessing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/main.h b/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/main.h index ad884564e6d052d7804f84c6aee68b536b1a526b..b53891c8bca97ea4ab009542acd4d9b84c242c8d 100644 --- a/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/main.h +++ b/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/main.h @@ -56,4 +56,8 @@ void TxRxSampleCallbackHandle(void *handle); void ErrorSampleCallbackHandle(void *handle); void SPICsCallback(void *handle); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/system_init.c index dde02376475da8d82f9db81590ab924f72ba3dd3..124acd87c4fd6fb624f9013690f319bc055cd0f5 100644 --- a/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/init/system_init.c @@ -39,7 +39,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* CRG init */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; @@ -65,11 +65,11 @@ static void DMA_Channel1Init(void *handle) static void DMA_Channel0Init(void *handle) { DMA_ChannelParam dma_param; - dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; /* memory to periph */ + dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; /* periph to memory */ dma_param.srcAddrInc = DMA_ADDR_INCREASE; dma_param.destAddrInc = DMA_ADDR_UNALTERED; dma_param.srcPeriph = DMA_REQUEST_MEM; - dma_param.destPeriph = DMA_REQUEST_SPI_TX; /* srcperiph is spi1_tx */ + dma_param.destPeriph = DMA_REQUEST_SPI_TX; /* srcperiph is spi1_rx */ dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; dma_param.destWidth = DMA_TRANSWIDTH_BYTE; dma_param.srcBurst = DMA_BURST_LENGTH_1; @@ -80,8 +80,8 @@ static void DMA_Channel0Init(void *handle) static void DMA_Init(void) { - HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); - g_dmac.baseAddress = DMA; /* dma baseaddress */ + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); /* dma baseaddress */ + g_dmac.baseAddress = DMA; g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); @@ -136,33 +136,34 @@ static void SPI_Init(void) g_spiSampleHandle.baseAddress = SPI; - g_spiSampleHandle.mode = HAL_SPI_MASTER; /* spi master */ + g_spiSampleHandle.mode = HAL_SPI_MASTER; g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; g_spiSampleHandle.xFerMode = HAL_XFER_MODE_DMA; - g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; /* spi ploarity is 0 */ + g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_1; g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; - g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; /* motorola frame format */ + g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_8BIT; g_spiSampleHandle.freqScr = SPI_FREQ_SCR; g_spiSampleHandle.freqCpsdvsr = SPI_FREQ_CPSDVSR; g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; - g_spiSampleHandle.waitVal = 127; /* mircowire wait time 127 */ + g_spiSampleHandle.waitVal = 127; /* 127 is microwire wait time */ g_spiSampleHandle.rxBuff = NULL; g_spiSampleHandle.txBuff = NULL; g_spiSampleHandle.transferSize = 0; - g_spiSampleHandle.txCount = 0; /* transfer count */ + g_spiSampleHandle.txCount = 0; g_spiSampleHandle.rxCount = 0; g_spiSampleHandle.state = HAL_SPI_STATE_RESET; g_spiSampleHandle.rxIntSize = SPI_RX_INTERRUPT_SIZE_1; - g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; /* tx interrupt size */ + g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; g_spiSampleHandle.rxDMABurstSize = SPI_RX_DMA_BURST_SIZE_1; g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; g_spiSampleHandle.dmaHandle = &g_dmac; g_spiSampleHandle.txDmaCh = 0; /* DMA Channel 0 */ g_spiSampleHandle.rxDmaCh = 1; /* DMA Channel 1 */ HAL_SPI_Init(&g_spiSampleHandle); - /* spi register callback */ + HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_0); + HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_TX_COMPLETE_CB_ID, TxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_RX_COMPLETE_CB_ID, RxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_TX_RX_COMPLETE_CB_ID, TxRxSampleCallbackHandle); @@ -175,13 +176,13 @@ static void UART0_Init(void) HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ + g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; - g_uart0.dataLength = UART_DATALENGTH_8BIT; /* data length 8 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; /* blocking mode */ + g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; diff --git a/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/readme.md b/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/readme.md index 058bb69ddf052dd06462e4c7914d6fe77efa4502..e7df6d0d8e968ea01cd99bf052565b0b2395e2e6 100644 --- a/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/readme.md +++ b/src/application/drivers_sample/spi/sample_spi_dma_w25q32_internal/readme.md @@ -17,4 +17,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。当每次DMA搬运完成会进入回调函数打印log,串口打印写入的120个数据和读取的120个数据,如果写入和读取的数据是相同则打印data correct,否则打印data err。 **【注意事项】** -+ 使用此示例代码必须外接flash芯片w25q32。 \ No newline at end of file ++ 使用此示例代码必须外接flash芯片w25q32。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_interrupt_kta7953/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_interrupt_kta7953/init/system_init.c index 8fab4175975f4f3f550475974138891b01c3c325..c79a3a96221315355ff35c44bcc5c2f74c149164 100644 --- a/src/application/drivers_sample/spi/sample_spi_interrupt_kta7953/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_interrupt_kta7953/init/system_init.c @@ -85,7 +85,6 @@ static void SPI_Init(void) HAL_CRG_IpClkSelectSet(SPI_BASE, CRG_PLL_NO_PREDV); g_spiSampleHandle.baseAddress = SPI; - g_spiSampleHandle.irqNum = IRQ_SPI; g_spiSampleHandle.mode = HAL_SPI_MASTER; g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; @@ -110,15 +109,16 @@ static void SPI_Init(void) g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; HAL_SPI_Init(&g_spiSampleHandle); + HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_0); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_TX_COMPLETE_CB_ID, TxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_RX_COMPLETE_CB_ID, RxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_TX_RX_COMPLETE_CB_ID, TxRxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_ERROR_CB_ID, ErrorSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_CS_CB_ID, SPICsCallback); - HAL_SPI_IRQService(&g_spiSampleHandle); - IRQ_SetPriority(g_spiSampleHandle.irqNum, 1); - IRQ_EnableN(g_spiSampleHandle.irqNum); + IRQ_Register(IRQ_SPI, HAL_SPI_IrqHandler, &g_spiSampleHandle); + IRQ_SetPriority(IRQ_SPI, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_SPI); } static void UART0_Init(void) @@ -127,7 +127,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; diff --git a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/main.c b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/main.c index 0c5f30bcfe36f809772b145b7dac355987f7b15c..885112b011553ed888d88ca5ffb757654239af81 100644 --- a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/main.c +++ b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/main.c @@ -22,29 +22,38 @@ #include "typedefs.h" #include "feature.h" +#include "sample_spi_interrupt_w25q32.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ UART_Handle g_uart0; SPI_Handle g_spiSampleHandle; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ W25Q32InterruptSampleProcessing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/main.h b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/main.h index 5d6cae904ce2d0921b26dc8b5388ddce32fd7c36..82d13d74ea38d4a000fe3792bb3e16f3ff7f0bdf 100644 --- a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/main.h +++ b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/main.h @@ -25,8 +25,11 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "spi.h" +#include "spi_ex.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -53,4 +56,8 @@ void TxRxSampleCallbackHandle(void *handle); void ErrorSampleCallbackHandle(void *handle); void SPICsCallback(void *handle); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/system_init.c index 7d18f1ec0eaf94790bec24be9f4c7e2a8abc0dda..822fb1c6ed67c340fc50b1fd4fdc143fe93f596b 100644 --- a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/init/system_init.c @@ -27,21 +27,23 @@ #define UART0_BAND_RATE 115200 #define SPI1_FREQ_SCR 2 -#define SPI1_FREQ_CPSDVSR 10 +#define SPI1_FREQ_CPSDVSR 50 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; - crg.baseAddress = CRG; /* crg baseaddress */ + crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + /* The 1 MHz freq is equal to the clock frequency / (clk_1m_div + 1). 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* CRG init */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; @@ -85,22 +87,21 @@ __weak void SPICsCallback(void *handle) static void SPI1_Init(void) { - HAL_CRG_IpEnableSet(SPI1_BASE, IP_CLK_ENABLE); - + HAL_CRG_IpEnableSet(SPI1_BASE, IP_CLK_ENABLE); /* SPI1 clock enable. */ g_spiSampleHandle.baseAddress = SPI1; g_spiSampleHandle.mode = HAL_SPI_MASTER; /* spi master */ g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_CALLBACK; g_spiSampleHandle.xFerMode = HAL_XFER_MODE_INTERRUPTS; g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; /* spi ploarity is 0 */ - g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_1; + g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_0; g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; /* motorola frame format */ g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_8BIT; g_spiSampleHandle.freqScr = SPI1_FREQ_SCR; g_spiSampleHandle.freqCpsdvsr = SPI1_FREQ_CPSDVSR; g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; - g_spiSampleHandle.waitVal = 127; /* mircowire wait time 127 */ + g_spiSampleHandle.waitVal = 127; /* 127 is microwire wait time */ g_spiSampleHandle.rxBuff = NULL; g_spiSampleHandle.txBuff = NULL; g_spiSampleHandle.transferSize = 0; @@ -113,33 +114,30 @@ static void SPI1_Init(void) g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; HAL_SPI_Init(&g_spiSampleHandle); - /* spi register callback */ HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_TX_COMPLETE_CB_ID, TxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_RX_COMPLETE_CB_ID, RxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_TX_RX_COMPLETE_CB_ID, TxRxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_ERROR_CB_ID, ErrorSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_CS_CB_ID, SPICsCallback); - /* spi interrupt setting */ IRQ_Register(IRQ_SPI1, HAL_SPI_IrqHandler, &g_spiSampleHandle); - IRQ_SetPriority(IRQ_SPI1, 1); + IRQ_SetPriority(IRQ_SPI1, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_SPI1); HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_1); } static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - - g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; - g_uart0.dataLength = UART_DATALENGTH_8BIT; /* data length 8 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; /* blocking mode */ + g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; - g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; /* fifo size 8 */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; @@ -149,47 +147,47 @@ static void UART0_Init(void) static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_SPI1_CLK); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_SPI1_CLK, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_SPI1_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_SPI1_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_SPI1_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO1_4_AS_SPI1_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO1_4_AS_SPI1_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO1_4_AS_SPI1_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO1_4_AS_SPI1_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO1_4_AS_SPI1_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO3_0_AS_SPI1_CSN1); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO3_0_AS_SPI1_CSN1, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO3_0_AS_SPI1_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO3_0_AS_SPI1_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO3_0_AS_SPI1_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO1_3_AS_SPI1_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO1_3_AS_SPI1_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO1_3_AS_SPI1_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO1_3_AS_SPI1_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO1_3_AS_SPI1_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_SPI1_CSN0); /* Check function selection */ HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_SPI1_CSN0, PULL_NONE); /* Pull-up and pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_SPI1_CSN0, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_SPI1_CSN0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_SPI1_CSN0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_0_AS_SPI1_CLK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_0_AS_SPI1_CLK, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_0_AS_SPI1_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_0_AS_SPI1_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_0_AS_SPI1_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_2_AS_SPI1_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_2_AS_SPI1_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_2_AS_SPI1_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_2_AS_SPI1_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_2_AS_SPI1_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_1_AS_SPI1_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_1_AS_SPI1_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_1_AS_SPI1_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_1_AS_SPI1_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_1_AS_SPI1_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_3_AS_SPI1_CSN1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_3_AS_SPI1_CSN1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_3_AS_SPI1_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_3_AS_SPI1_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_3_AS_SPI1_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/readme.md b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/readme.md index 9206fbbb1c41a48a65d4ae87c09565a8abd8a48c..1f4e5f1a60f16370d3f68b9d8f4d1b228f0800b8 100644 --- a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/readme.md +++ b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32/readme.md @@ -17,4 +17,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。当每次产生中断会进入回调函数打印log,串口打印写入的120个数据和读取的120个数据,如果写入和读取的数据是相同则打印data correct,否则打印data err。 **【注意事项】** -+ 使用此示例代码必须外接flash芯片w25q32。 \ No newline at end of file ++ 使用此示例代码必须外接flash芯片w25q32。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/main.c b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/main.c index f03009588ece0dfd85bba4e582266eb836178c59..fca1d114a705d749bcf522e82ed80fa34c8e8f49 100644 --- a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/main.c +++ b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/main.c @@ -25,27 +25,35 @@ #include "sample_spi_interrupt_w25q32_internal.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ SPI_Handle g_spiSampleHandle; UART_Handle g_uart0; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ W25Q32InterruptSampleProcessing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/main.h b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/main.h index 45a93ed2df9edfffbd843f3fffcb283279440bc8..696bbb4c16b7eaa9e95459b59c29782456497f9e 100644 --- a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/main.h +++ b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/main.h @@ -53,4 +53,8 @@ void TxRxSampleCallbackHandle(void *handle); void ErrorSampleCallbackHandle(void *handle); void SPICsCallback(void *handle); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/system_init.c index 21a60100a423dd81a63c26d99eda103c391e9f0c..4beea484ca980a2ed7dbed83153cc516dfd04c76 100644 --- a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/init/system_init.c @@ -39,7 +39,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* CRG init */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; @@ -88,39 +88,38 @@ static void SPI_Init(void) g_spiSampleHandle.baseAddress = SPI; - g_spiSampleHandle.mode = HAL_SPI_MASTER; /* spi master */ + g_spiSampleHandle.mode = HAL_SPI_MASTER; g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; g_spiSampleHandle.xFerMode = HAL_XFER_MODE_INTERRUPTS; - g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; /* spi ploarity is 0 */ + g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_1; g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; - g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; /* motorola frame format */ + g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_8BIT; g_spiSampleHandle.freqScr = SPI_FREQ_SCR; g_spiSampleHandle.freqCpsdvsr = SPI_FREQ_CPSDVSR; g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; - g_spiSampleHandle.waitVal = 127; /* mircowire wait time 127 */ + g_spiSampleHandle.waitVal = 127; /* 127 is microwire wait time */ g_spiSampleHandle.rxBuff = NULL; g_spiSampleHandle.txBuff = NULL; g_spiSampleHandle.transferSize = 0; - g_spiSampleHandle.txCount = 0; /* transfer count */ + g_spiSampleHandle.txCount = 0; g_spiSampleHandle.rxCount = 0; g_spiSampleHandle.state = HAL_SPI_STATE_RESET; g_spiSampleHandle.rxIntSize = SPI_RX_INTERRUPT_SIZE_1; - g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; /* tx interrupt size */ + g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; g_spiSampleHandle.rxDMABurstSize = SPI_RX_DMA_BURST_SIZE_1; g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; HAL_SPI_Init(&g_spiSampleHandle); + HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_0); - /* spi register callback */ HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_TX_COMPLETE_CB_ID, TxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_RX_COMPLETE_CB_ID, RxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_TX_RX_COMPLETE_CB_ID, TxRxSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_ERROR_CB_ID, ErrorSampleCallbackHandle); HAL_SPI_RegisterCallback(&g_spiSampleHandle, SPI_CS_CB_ID, SPICsCallback); - /* spi interrupt setting */ IRQ_Register(IRQ_SPI, HAL_SPI_IrqHandler, &g_spiSampleHandle); - IRQ_SetPriority(IRQ_SPI, 1); + IRQ_SetPriority(IRQ_SPI, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_SPI); } @@ -129,13 +128,13 @@ static void UART0_Init(void) HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ + g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; - g_uart0.dataLength = UART_DATALENGTH_8BIT; /* data length 8 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; /* blocking mode */ + g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; diff --git a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/readme.md b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/readme.md index 9206fbbb1c41a48a65d4ae87c09565a8abd8a48c..ed8cd333e4677afaa9364707f420237c92a1d1b2 100644 --- a/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/readme.md +++ b/src/application/drivers_sample/spi/sample_spi_interrupt_w25q32_internal/readme.md @@ -17,4 +17,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。当每次产生中断会进入回调函数打印log,串口打印写入的120个数据和读取的120个数据,如果写入和读取的数据是相同则打印data correct,否则打印data err。 **【注意事项】** -+ 使用此示例代码必须外接flash芯片w25q32。 \ No newline at end of file ++ 使用此示例代码必须外接flash芯片w25q32。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_master/init/main.c b/src/application/drivers_sample/spi/sample_spi_master/init/main.c index f35db22775e34480d61cfe12bc779809a8d3d4ec..1b8d84382678ebdedf938e182102472c7ee536be 100644 --- a/src/application/drivers_sample/spi/sample_spi_master/init/main.c +++ b/src/application/drivers_sample/spi/sample_spi_master/init/main.c @@ -22,29 +22,38 @@ #include "typedefs.h" #include "feature.h" +#include "sample_spi_master.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ -UART_Handle g_uart0; SPI_Handle g_spiSampleHandle; +UART_Handle g_uart0; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ MasterTestSampleProcessing(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_master/init/main.h b/src/application/drivers_sample/spi/sample_spi_master/init/main.h index f2ff5b487d052e8bdaab746cc6a38ca2c3ba5751..8c57f6fd5f8e49569ff5e761a8597ad5979d2b43 100644 --- a/src/application/drivers_sample/spi/sample_spi_master/init/main.h +++ b/src/application/drivers_sample/spi/sample_spi_master/init/main.h @@ -41,10 +41,14 @@ #define XTAL_DRV_LEVEL2 0x01U #define XTAL_DRV_LEVEL1 0x00U -extern UART_Handle g_uart0; extern SPI_Handle g_spiSampleHandle; +extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_master/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_master/init/system_init.c index 009044a72e426b1b453fd664a34b111bcc7bd84c..a1ee24b9443ce8c83cea4773e2918bce09992858 100644 --- a/src/application/drivers_sample/spi/sample_spi_master/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_master/init/system_init.c @@ -22,135 +22,136 @@ #include "main.h" #include "ioconfig.h" -#include "iocmg_ip.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 -#define SPI1_FREQ_SCR 2 -#define SPI1_FREQ_CPSDVSR 10 +#define SPI_FREQ_SCR 2 +#define SPI_FREQ_CPSDVSR 10 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; - crg.baseAddress = CRG; /* crg baseaddress */ + crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* CRG init */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; return BASE_STATUS_OK; } -static void SPI1_Init(void) +static void SPI_Init(void) { - HAL_CRG_IpEnableSet(SPI1_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(SPI_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(SPI_BASE, CRG_PLL_NO_PREDV); - g_spiSampleHandle.baseAddress = SPI1; + g_spiSampleHandle.baseAddress = SPI; - g_spiSampleHandle.mode = HAL_SPI_MASTER; /* spi master */ + g_spiSampleHandle.mode = HAL_SPI_MASTER; g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; g_spiSampleHandle.xFerMode = HAL_XFER_MODE_BLOCKING; - g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; /* spi ploarity is 0 */ + g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_0; g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; - g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; /* motorola frame format */ + g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_16BIT; - g_spiSampleHandle.freqScr = SPI1_FREQ_SCR; - g_spiSampleHandle.freqCpsdvsr = SPI1_FREQ_CPSDVSR; + g_spiSampleHandle.freqScr = SPI_FREQ_SCR; + g_spiSampleHandle.freqCpsdvsr = SPI_FREQ_CPSDVSR; g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; - g_spiSampleHandle.waitVal = 127; /* mircowire wait time 127 */ + g_spiSampleHandle.waitVal = 127; /* 127 is microwire wait time */ g_spiSampleHandle.rxBuff = NULL; g_spiSampleHandle.txBuff = NULL; g_spiSampleHandle.transferSize = 0; - g_spiSampleHandle.txCount = 0; /* transfer count */ + g_spiSampleHandle.txCount = 0; g_spiSampleHandle.rxCount = 0; g_spiSampleHandle.state = HAL_SPI_STATE_RESET; g_spiSampleHandle.rxIntSize = SPI_RX_INTERRUPT_SIZE_1; - g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; /* tx interrupt size */ + g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; g_spiSampleHandle.rxDMABurstSize = SPI_RX_DMA_BURST_SIZE_1; g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; HAL_SPI_Init(&g_spiSampleHandle); - HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_1); + HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_0); } static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ + g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; - g_uart0.dataLength = UART_DATALENGTH_8BIT; /* data length 8 */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; /* blocking mode */ + g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; - g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; /* fifo size 8 */ - g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; - g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_SPI1_CLK); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_SPI1_CLK, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_SPI1_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_SPI1_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_SPI1_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO1_3_AS_SPI1_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO1_3_AS_SPI1_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO1_3_AS_SPI1_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO1_3_AS_SPI1_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO1_3_AS_SPI1_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO1_4_AS_SPI1_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO1_4_AS_SPI1_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO1_4_AS_SPI1_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO1_4_AS_SPI1_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO1_4_AS_SPI1_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_SPI1_CSN0); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_SPI1_CSN0, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_SPI1_CSN0, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_SPI1_CSN0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_SPI1_CSN0, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO3_0_AS_SPI1_CSN1); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO3_0_AS_SPI1_CSN1, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO3_0_AS_SPI1_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO3_0_AS_SPI1_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO3_0_AS_SPI1_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; + HAL_IOCMG_SetPinAltFuncMode(IO6_AS_SSP0_CLK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO6_AS_SSP0_CLK, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO6_AS_SSP0_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO6_AS_SSP0_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO6_AS_SSP0_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO3_AS_SSP0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO3_AS_SSP0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO3_AS_SSP0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO3_AS_SSP0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO3_AS_SSP0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO4_AS_SSP0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO4_AS_SSP0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO4_AS_SSP0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO4_AS_SSP0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO4_AS_SSP0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO2_AS_SSP0_CSN0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO2_AS_SSP0_CSN0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO2_AS_SSP0_CSN0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO2_AS_SSP0_CSN0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO2_AS_SSP0_CSN0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_SSP0_CSN1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_SSP0_CSN1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_SSP0_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_SSP0_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_SSP0_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); UART0_Init(); - SPI1_Init(); + SPI_Init(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ diff --git a/src/application/drivers_sample/spi/sample_spi_master/readme.md b/src/application/drivers_sample/spi/sample_spi_master/readme.md index 7cbffc8edaef95fe7b4161e2ae1b37cb396fab62..2ad25bb493a23f51c8e17ee723ffd52e2340a23d 100644 --- a/src/application/drivers_sample/spi/sample_spi_master/readme.md +++ b/src/application/drivers_sample/spi/sample_spi_master/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码通过串口不断打印主机接收到的数据、发送的数据。 **【注意事项】** -+ 使用此示例代码必须对接spi_slave一起使用,使用两个设备一个做master一个做slave。 \ No newline at end of file ++ 使用此示例代码必须对接spi_slave一起使用,使用两个设备一个做master一个做slave。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_master_3wires/inc/sample_spi_master_3wires.h b/src/application/drivers_sample/spi/sample_spi_master_3wires/inc/sample_spi_master_3wires.h new file mode 100644 index 0000000000000000000000000000000000000000..f309f36b31ec6e11a6b0f79e41c10724d5780c50 --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_master_3wires/inc/sample_spi_master_3wires.h @@ -0,0 +1,28 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_spi_master_3wires.h + * @author MCU Driver Team + * @brief SPI module driver. + * @details This file provides sample code for users to help use + * the functionalities of the SPI. + */ +#ifndef McuMagicTag_SAMPLE_SPI_MASTER_THREE_WIRES_H +#define McuMagicTag_SAMPLE_SPI_MASTER_THREE_WIRES_H + +void MasterThreeWiresTestSampleProcessing(void); +#endif \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_master_3wires/init/main.c b/src/application/drivers_sample/spi/sample_spi_master_3wires/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..7a6a2ef5bc72a4f3a8f0f2dea906b1542705159f --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_master_3wires/init/main.c @@ -0,0 +1,51 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_spi_master_3wires.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +SPI_Handle g_spiSampleHandle; +/* USER CODE BEGIN 1 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* USER CODE END 2 */ + MasterThreeWiresTestSampleProcessing(); + /* USER CODE BEGIN 3 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_master_3wires/init/main.h b/src/application/drivers_sample/spi/sample_spi_master_3wires/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..4bf391fab3f228412ea97d0ff413ff74bb65b6b8 --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_master_3wires/init/main.h @@ -0,0 +1,53 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "spi.h" +#include "spi_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern SPI_Handle g_spiSampleHandle; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_master_3wires/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_master_3wires/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..fcf97821e11bf7c8c57a672017a314bf1fd7b655 --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_master_3wires/init/system_init.c @@ -0,0 +1,162 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg.h" + +#define UART0_BAND_RATE 115200 +#define CLK1M_Div 25 + +#define SPI0_FREQ_SCR 2 +#define SPI0_FREQ_CPSDVSR 50 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 0x30; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (CLK1M_Div - 1); + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void SPI0_Init(void) +{ + HAL_CRG_IpEnableSet(SPI0_BASE, IP_CLK_ENABLE); /* Enable SPI clock. */ + + g_spiSampleHandle.baseAddress = SPI0; + g_spiSampleHandle.mode = HAL_SPI_MASTER; + g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; + g_spiSampleHandle.xFerMode = HAL_XFER_MODE_BLOCKING; + g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; /* Set Polarity and Phase. */ + g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_0; + g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; + g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; /* Set motorola mode. */ + g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_16BIT; + g_spiSampleHandle.freqScr = SPI0_FREQ_SCR; + g_spiSampleHandle.freqCpsdvsr = SPI0_FREQ_CPSDVSR; + g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; + g_spiSampleHandle.waitVal = 127; /* 127: Waiting time between receiving and sending. */ + g_spiSampleHandle.rxBuff = NULL; + g_spiSampleHandle.txBuff = NULL; + g_spiSampleHandle.transferSize = 0; + g_spiSampleHandle.txCount = 0; + g_spiSampleHandle.rxCount = 0; /* The count of transferred data. */ + g_spiSampleHandle.state = HAL_SPI_STATE_RESET; + g_spiSampleHandle.rxIntSize = SPI_RX_INTERRUPT_SIZE_1; + g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; + g_spiSampleHandle.rxDMABurstSize = SPI_RX_DMA_BURST_SIZE_1; /* DMA brust bit width */ + g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; + g_spiSampleHandle.handleEx.line = SPI_DATA_1LINE; + HAL_SPI_Init(&g_spiSampleHandle); /* Init SPI */ + HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_0); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; + /* Config PIN6 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_SPI0_CLK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_SPI0_CLK, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_SPI0_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_SPI0_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_SPI0_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN3 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_0_AS_SPI0_MOSI); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_0_AS_SPI0_MOSI, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_0_AS_SPI0_MOSI, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_0_AS_SPI0_MOSI, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_0_AS_SPI0_MOSI, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN4 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_1_AS_SPI0_MISO); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_1_AS_SPI0_MISO, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_1_AS_SPI0_MISO, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_1_AS_SPI0_MISO, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_1_AS_SPI0_MISO, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN2 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO1_7_AS_SPI0_CSN0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO1_7_AS_SPI0_CSN0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO1_7_AS_SPI0_CSN0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO1_7_AS_SPI0_CSN0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO1_7_AS_SPI0_CSN0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN5 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_SPI0_CSN1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_SPI0_CSN1, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_SPI0_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_SPI0_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_SPI0_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + SPI0_Init(); + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_master_3wires/readme.md b/src/application/drivers_sample/spi/sample_spi_master_3wires/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..df4ee6285682ac9044298aada8e4b5f782e22070 --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_master_3wires/readme.md @@ -0,0 +1,22 @@ +# SPI使用阻塞方式进行三线主从通信,此示例代码作为主机使用 +## 关键字: SPI, 阻塞, 主机,三线 + +**【功能描述】** ++ 示例代码基于HAL接口完成时钟、SPI控制器初始化和功能配置。主机读从机数据或者向从机发送数据。 + +**【示例配置】** ++ 在"SystemInit()”接口中配置SPI时钟极性、时钟相位、帧格式等参数。 + ++ 定义数组,数组中存放主机需要发送的数据。 + ++ 首先主机调用“HAL_SPI_WriteBlocking()”向从机发送10个数据,之后调用“HAL_SPI_ReadBlocking()”读10个数据,不断循环。 + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码通过串口不断打印主机接收到的数据、发送的数据。 + +**【注意事项】** ++ 使用此示例代码必须对接spi_slave一起使用,使用两个设备一个做master一个做slave。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 三线方式通信时主机的mosi线接从机的miso线。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_master_3wires/src/sample_spi_master_3wires.c b/src/application/drivers_sample/spi/sample_spi_master_3wires/src/sample_spi_master_3wires.c new file mode 100644 index 0000000000000000000000000000000000000000..93c6e0b26374eb3066f62d2e68f77bc2fabc6df0 --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_master_3wires/src/sample_spi_master_3wires.c @@ -0,0 +1,84 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_spi_master_3wires.c + * @author MCU Driver Team + * @brief Sample for SPI Module Master. + * @details This example demonstrates using the HAL interface in 3-wire master mode. This example uses blocking mode. + * This example must be connected to a three-wire slave device. + * This example sends 0x1105, 0x1c20, 0x1183, 0x1285, 0x1240, 0x12c0, and 0x1340 in polling mode. + * Print the received data through the serial port. + */ +#include "main.h" +#include "spi.h" +#include "debug.h" +#include "sample_spi_master_3wires.h" + +#define USER_TIMEOUT 0x400 + +#define MASTER_READ_TESE +#define MASTER_WRITE_TESE + +#define MASTER_3WIRES_MODE_SET_CH0 0x01 +#define MASTER_3WIRES_MODE_SET_CH1 0x02 +#define MASTER_3WIRES_MODE_SET_CH2 0x03 +#define MASTER_3WIRES_MODE_SET_CH3 0x04 +#define MASTER_3WIRES_MODE_SET_CH4 0x05 +#define MASTER_3WIRES_MODE_SET_CH5 0x06 +#define MASTER_3WIRES_MODE_SET_CH6 0x07 + +#define MAX_TIMEOUT_VAL 5000 + +/** + * @brief Spi master three wires sample processing. + * @param None. + * @retval None. + */ +void MasterThreeWiresTestSampleProcessing(void) +{ + unsigned short tempWdata[] = { + MASTER_3WIRES_MODE_SET_CH0, + MASTER_3WIRES_MODE_SET_CH1, + MASTER_3WIRES_MODE_SET_CH2, + MASTER_3WIRES_MODE_SET_CH3, + MASTER_3WIRES_MODE_SET_CH4, + MASTER_3WIRES_MODE_SET_CH5, + MASTER_3WIRES_MODE_SET_CH6, + MASTER_3WIRES_MODE_SET_CH2, + MASTER_3WIRES_MODE_SET_CH3, + MASTER_3WIRES_MODE_SET_CH4 + }; + unsigned short tempRdata[10] = {0}; + SystemInit(); + while (1) { +#ifdef MASTER_WRITE_TESE + for (int i = 0; i < 10; i++) { /* Print the test data for 10 times. */ + DBG_PRINTF("Master 3wires tempWdata[%d] = 0x%x \r\n", i, tempWdata[i]); + BASE_FUNC_DELAY_MS(10); /* Delay: 10 ms */ + } + HAL_SPI_WriteBlocking(&g_spiSampleHandle, (unsigned char *)tempWdata, sizeof(tempWdata), MAX_TIMEOUT_VAL); + BASE_FUNC_DELAY_MS(300); /* Delay: 300 ms */ +#endif +#ifdef MASTER_READ_TESE + HAL_SPI_ReadBlocking(&g_spiSampleHandle, (unsigned char *)tempRdata, sizeof(tempRdata), MAX_TIMEOUT_VAL); + for (int i = 0; i < 10; i++) { /* Print the test data for 10 times. */ + DBG_PRINTF("Master 3wires tempRdata[%d] = 0x%x \r\n", i, tempRdata[i]); + BASE_FUNC_DELAY_MS(10); /* Delay: 10 ms */ + } +#endif + } +} diff --git a/src/application/drivers_sample/spi/sample_spi_microwire_master/init/main.c b/src/application/drivers_sample/spi/sample_spi_microwire_master/init/main.c index aaeaa52e0d6058b9b5d144a822d02efb856adbdd..6fe798a50b218713ea4a2e001452600d2842c1cc 100644 --- a/src/application/drivers_sample/spi/sample_spi_microwire_master/init/main.c +++ b/src/application/drivers_sample/spi/sample_spi_microwire_master/init/main.c @@ -19,16 +19,41 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "sample_spi_microwire_master.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ SPI_Handle g_spiSampleHandle; +UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ MicroWireMasterTestSampleProcessing(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_microwire_master/init/main.h b/src/application/drivers_sample/spi/sample_spi_microwire_master/init/main.h index 9a1c681923864acb96fc6513b892f4e0b880c310..8c57f6fd5f8e49569ff5e761a8597ad5979d2b43 100644 --- a/src/application/drivers_sample/spi/sample_spi_microwire_master/init/main.h +++ b/src/application/drivers_sample/spi/sample_spi_microwire_master/init/main.h @@ -24,6 +24,7 @@ #ifndef McuMagicTag_SYSTEM_INIT_H #define McuMagicTag_SYSTEM_INIT_H +#include "uart.h" #include "spi.h" #include "crg.h" @@ -35,9 +36,19 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern SPI_Handle g_spiSampleHandle; +extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_microwire_master/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_microwire_master/init/system_init.c index 70b9fbd99190afae47c29cad7b7e44308315b341..aa0a82db3e403d3f89a55e5c845d461976c4a074 100644 --- a/src/application/drivers_sample/spi/sample_spi_microwire_master/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_microwire_master/init/system_init.c @@ -22,6 +22,9 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" + +#define UART0_BAND_RATE 115200 #define SPI_FREQ_SCR 2 #define SPI_FREQ_CPSDVSR 10 @@ -35,6 +38,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -48,19 +52,19 @@ static void SPI_Init(void) HAL_CRG_IpClkSelectSet(SPI_BASE, CRG_PLL_NO_PREDV); g_spiSampleHandle.baseAddress = SPI; - g_spiSampleHandle.irqNum = IRQ_SPI; g_spiSampleHandle.mode = HAL_SPI_MASTER; g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; g_spiSampleHandle.xFerMode = HAL_XFER_MODE_BLOCKING; - g_spiSampleHandle.clkPolarity = 0; - g_spiSampleHandle.clkPhase = 0; + g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; + g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_0; g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MICROWIRE; g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_8BIT; g_spiSampleHandle.freqScr = SPI_FREQ_SCR; g_spiSampleHandle.freqCpsdvsr = SPI_FREQ_CPSDVSR; - g_spiSampleHandle.waitVal = 127; /* Wait time is 127 clock */ + g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; + g_spiSampleHandle.waitVal = 127; /* 127 is microwire wait time */ g_spiSampleHandle.rxBuff = NULL; g_spiSampleHandle.txBuff = NULL; g_spiSampleHandle.transferSize = 0; @@ -71,53 +75,82 @@ static void SPI_Init(void) g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; g_spiSampleHandle.rxDMABurstSize = SPI_RX_DMA_BURST_SIZE_1; g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; - HAL_SPI_Init(&g_spiSampleHandle); + HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_0); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); + + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_22.BIT.func = 0x5; /* 0x5 is SPI_CLK */ - iconfig->iocmg_22.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_22.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_22.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_22.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_22.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_18.BIT.func = 0x5; /* 0x5 is SPI_CSN0 */ - iconfig->iocmg_18.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_18.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_18.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_18.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_18.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_21.BIT.func = 0x5; /* 0x5 is SPI_CSN1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_20.BIT.func = 0x5; /* 0x5 is SPI_RXD */ - iconfig->iocmg_20.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_20.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_20.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_20.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_20.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_19.BIT.func = 0x5; /* 0x5 is SPI_TXD */ - iconfig->iocmg_19.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_19.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_19.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_19.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_19.BIT.se = BASE_CFG_DISABLE; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; + HAL_IOCMG_SetPinAltFuncMode(IO6_AS_SSP0_CLK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO6_AS_SSP0_CLK, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO6_AS_SSP0_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO6_AS_SSP0_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO6_AS_SSP0_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO3_AS_SSP0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO3_AS_SSP0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO3_AS_SSP0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO3_AS_SSP0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO3_AS_SSP0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO4_AS_SSP0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO4_AS_SSP0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO4_AS_SSP0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO4_AS_SSP0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO4_AS_SSP0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO2_AS_SSP0_CSN0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO2_AS_SSP0_CSN0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO2_AS_SSP0_CSN0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO2_AS_SSP0_CSN0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO2_AS_SSP0_CSN0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_SSP0_CSN1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_SSP0_CSN1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_SSP0_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_SSP0_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_SSP0_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); + UART0_Init(); SPI_Init(); /* USER CODE BEGIN system_init */ diff --git a/src/application/drivers_sample/spi/sample_spi_microwire_master/readme.md b/src/application/drivers_sample/spi/sample_spi_microwire_master/readme.md index 77708a895c14f5f12320aa045e45a221198b9ef7..4d4fdc2e5a0e974edd7ee8aeece739cac2d42119 100644 --- a/src/application/drivers_sample/spi/sample_spi_microwire_master/readme.md +++ b/src/application/drivers_sample/spi/sample_spi_microwire_master/readme.md @@ -23,4 +23,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码通过串口打印主机发送的数据和接收到的数据。 **【注意事项】** -+ 此示例必须配合sample_spi_microwire_slave一起使用,使用两个设备一个做master一个做slave。 \ No newline at end of file ++ 此示例必须配合sample_spi_microwire_slave一起使用,使用两个设备一个做master一个做slave。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/main.c b/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/main.c index 45d94ea933c7f0c33952371972441ecdd2605d8c..5d83656cc9e3e78d6e899e5e7a524d2fd12475c9 100644 --- a/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/main.c +++ b/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/main.c @@ -19,17 +19,41 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "sample_spi_microwire_slave.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ SPI_Handle g_spiSampleHandle; UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ MicroWireSlaveTestSampleProcessing(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/main.h b/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/main.h index 8467e01ce3375efb0190b5f72d28e1071792573e..8c57f6fd5f8e49569ff5e761a8597ad5979d2b43 100644 --- a/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/main.h +++ b/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/main.h @@ -36,11 +36,19 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U -extern SPI_Handle g_spiSampleHandle; +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U +extern SPI_Handle g_spiSampleHandle; extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/system_init.c index 773a34d97811917b721e5d98fa587b13c4ebc622..8d71f196ec5d005fb5e5cae81c34d5e3e93aa71d 100644 --- a/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_microwire_slave/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -37,6 +38,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -50,19 +52,19 @@ static void SPI_Init(void) HAL_CRG_IpClkSelectSet(SPI_BASE, CRG_PLL_NO_PREDV); g_spiSampleHandle.baseAddress = SPI; - g_spiSampleHandle.irqNum = IRQ_SPI; g_spiSampleHandle.mode = HAL_SPI_SLAVE; g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; g_spiSampleHandle.xFerMode = HAL_XFER_MODE_BLOCKING; - g_spiSampleHandle.clkPolarity = 0; - g_spiSampleHandle.clkPhase = 0; + g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; + g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_0; g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MICROWIRE; g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_8BIT; g_spiSampleHandle.freqScr = SPI_FREQ_SCR; g_spiSampleHandle.freqCpsdvsr = SPI_FREQ_CPSDVSR; - g_spiSampleHandle.waitVal = 127; /* Wait time is 127 clock */ + g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; + g_spiSampleHandle.waitVal = 127; /* 127 is microwire wait time */ g_spiSampleHandle.rxBuff = NULL; g_spiSampleHandle.txBuff = NULL; g_spiSampleHandle.transferSize = 0; @@ -73,8 +75,8 @@ static void SPI_Init(void) g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; g_spiSampleHandle.rxDMABurstSize = SPI_RX_DMA_BURST_SIZE_1; g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; - HAL_SPI_Init(&g_spiSampleHandle); + HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_0); } static void UART0_Init(void) @@ -83,7 +85,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -100,56 +101,50 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_22.BIT.func = 0x5; /* 0x5 is SPI_CLK */ - iconfig->iocmg_22.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_22.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_22.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_22.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_22.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_18.BIT.func = 0x5; /* 0x5 is SPI_CSN0 */ - iconfig->iocmg_18.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_18.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_18.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_18.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_18.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_21.BIT.func = 0x5; /* 0x5 is SPI_CSN1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_20.BIT.func = 0x5; /* 0x5 is SPI_RXD */ - iconfig->iocmg_20.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_20.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_20.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_20.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_20.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_19.BIT.func = 0x5; /* 0x5 is SPI_TXD */ - iconfig->iocmg_19.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_19.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_19.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_19.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_19.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; + HAL_IOCMG_SetPinAltFuncMode(IO6_AS_SSP0_CLK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO6_AS_SSP0_CLK, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO6_AS_SSP0_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO6_AS_SSP0_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO6_AS_SSP0_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO3_AS_SSP0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO3_AS_SSP0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO3_AS_SSP0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO3_AS_SSP0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO3_AS_SSP0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO4_AS_SSP0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO4_AS_SSP0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO4_AS_SSP0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO4_AS_SSP0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO4_AS_SSP0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO2_AS_SSP0_CSN0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO2_AS_SSP0_CSN0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO2_AS_SSP0_CSN0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO2_AS_SSP0_CSN0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO2_AS_SSP0_CSN0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_SSP0_CSN1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_SSP0_CSN1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_SSP0_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_SSP0_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_SSP0_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/spi/sample_spi_microwire_slave/readme.md b/src/application/drivers_sample/spi/sample_spi_microwire_slave/readme.md index 4d4a8a0069bc5a68ed2d34a1609b380f70195f53..524a59ad1e8060ffab4eba850e192718944debe8 100644 --- a/src/application/drivers_sample/spi/sample_spi_microwire_slave/readme.md +++ b/src/application/drivers_sample/spi/sample_spi_microwire_slave/readme.md @@ -23,4 +23,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码通过串口不断打印从机接收到的数据。 **【注意事项】** -+ 此示例必须配合sample_spi_microwire_master一起使用,使用两个设备一个做master一个做slave。 \ No newline at end of file ++ 此示例必须配合sample_spi_microwire_master一起使用,使用两个设备一个做master一个做slave。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_slave/init/main.c b/src/application/drivers_sample/spi/sample_spi_slave/init/main.c index 7ca5712ac6ce63d0840f77f371a798f1b4c1fe63..def716db3c0c3058499423bc1e75f5bce62f38f6 100644 --- a/src/application/drivers_sample/spi/sample_spi_slave/init/main.c +++ b/src/application/drivers_sample/spi/sample_spi_slave/init/main.c @@ -19,17 +19,41 @@ * @author MCU Driver Team * @brief Main program body. */ + +#include "typedefs.h" #include "feature.h" -#include "main.h" #include "sample_spi_slave.h" - +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ SPI_Handle g_spiSampleHandle; UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ int main(void) { + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ SlaveTestSampleProcessing(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ return BASE_STATUS_OK; -} \ No newline at end of file +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_slave/init/main.h b/src/application/drivers_sample/spi/sample_spi_slave/init/main.h index 8467e01ce3375efb0190b5f72d28e1071792573e..8c57f6fd5f8e49569ff5e761a8597ad5979d2b43 100644 --- a/src/application/drivers_sample/spi/sample_spi_slave/init/main.h +++ b/src/application/drivers_sample/spi/sample_spi_slave/init/main.h @@ -36,11 +36,19 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U -extern SPI_Handle g_spiSampleHandle; +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U +extern SPI_Handle g_spiSampleHandle; extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_slave/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_slave/init/system_init.c index 7b573b09c5580b398e0262e24e6a013464b27c50..994f5756c89208fe593ca88790fa043105faba7e 100644 --- a/src/application/drivers_sample/spi/sample_spi_slave/init/system_init.c +++ b/src/application/drivers_sample/spi/sample_spi_slave/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -37,6 +38,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } @@ -50,19 +52,19 @@ static void SPI_Init(void) HAL_CRG_IpClkSelectSet(SPI_BASE, CRG_PLL_NO_PREDV); g_spiSampleHandle.baseAddress = SPI; - g_spiSampleHandle.irqNum = IRQ_SPI; g_spiSampleHandle.mode = HAL_SPI_SLAVE; g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; g_spiSampleHandle.xFerMode = HAL_XFER_MODE_BLOCKING; - g_spiSampleHandle.clkPolarity = 0; - g_spiSampleHandle.clkPhase = 0; + g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; + g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_0; g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_16BIT; g_spiSampleHandle.freqScr = SPI_FREQ_SCR; g_spiSampleHandle.freqCpsdvsr = SPI_FREQ_CPSDVSR; - g_spiSampleHandle.waitVal = 127; /* Wait time is 127 clock */ + g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; + g_spiSampleHandle.waitVal = 127; /* 127 is microwire wait time */ g_spiSampleHandle.rxBuff = NULL; g_spiSampleHandle.txBuff = NULL; g_spiSampleHandle.transferSize = 0; @@ -73,8 +75,8 @@ static void SPI_Init(void) g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; g_spiSampleHandle.rxDMABurstSize = SPI_RX_DMA_BURST_SIZE_1; g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; - HAL_SPI_Init(&g_spiSampleHandle); + HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_0); } static void UART0_Init(void) @@ -83,7 +85,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -100,56 +101,50 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_22.BIT.func = 0x5; /* 0x5 is SPI_CLK */ - iconfig->iocmg_22.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_22.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_22.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_22.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_22.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_18.BIT.func = 0x5; /* 0x5 is SPI_CSN0 */ - iconfig->iocmg_18.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_18.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_18.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_18.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_18.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_21.BIT.func = 0x5; /* 0x5 is SPI_CSN1 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_20.BIT.func = 0x5; /* 0x5 is SPI_RXD */ - iconfig->iocmg_20.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_20.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_20.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_20.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_20.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_19.BIT.func = 0x5; /* 0x5 is SPI_TXD */ - iconfig->iocmg_19.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_19.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_19.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_19.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_19.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; + HAL_IOCMG_SetPinAltFuncMode(IO6_AS_SSP0_CLK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO6_AS_SSP0_CLK, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO6_AS_SSP0_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO6_AS_SSP0_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO6_AS_SSP0_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO3_AS_SSP0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO3_AS_SSP0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO3_AS_SSP0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO3_AS_SSP0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO3_AS_SSP0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO4_AS_SSP0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO4_AS_SSP0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO4_AS_SSP0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO4_AS_SSP0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO4_AS_SSP0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO2_AS_SSP0_CSN0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO2_AS_SSP0_CSN0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO2_AS_SSP0_CSN0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO2_AS_SSP0_CSN0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO2_AS_SSP0_CSN0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_SSP0_CSN1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_SSP0_CSN1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_SSP0_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_SSP0_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_SSP0_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/spi/sample_spi_slave/readme.md b/src/application/drivers_sample/spi/sample_spi_slave/readme.md index 1fdf39cdf00a3ab5298fdda3283f5237347091a5..fb4cf8baeb80a1629edd4e1b5a2d535e59309ec3 100644 --- a/src/application/drivers_sample/spi/sample_spi_slave/readme.md +++ b/src/application/drivers_sample/spi/sample_spi_slave/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码通过串口不断打印从机接收到的数据、发送的数据。 **【注意事项】** -+ 使用此示例代码必须对接master设备。 \ No newline at end of file ++ 使用此示例代码必须对接master设备。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_slave_3wires/inc/sample_spi_slave_3wires.h b/src/application/drivers_sample/spi/sample_spi_slave_3wires/inc/sample_spi_slave_3wires.h new file mode 100644 index 0000000000000000000000000000000000000000..5a7d95aace02632f1379780bb7b106e017181745 --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_slave_3wires/inc/sample_spi_slave_3wires.h @@ -0,0 +1,28 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_spi_slave_3wires.h + * @author MCU Driver Team + * @brief SPI module driver. + * @details This file provides sample code for users to help use + * the functionalities of the SPI. + */ +#ifndef McuMagicTag_SAMPLE_SPI_SLAVE_THREE_WIRES_H +#define McuMagicTag_SAMPLE_SPI_SLAVE_THREE_WIRES_H + +void SlaveThreeWiresTestSampleProcessing(void); +#endif \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_slave_3wires/init/main.c b/src/application/drivers_sample/spi/sample_spi_slave_3wires/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..80908fd8767c2b1e04cb8e220e8d38465f1d5dd3 --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_slave_3wires/init/main.c @@ -0,0 +1,51 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_spi_slave_3wires.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +SPI_Handle g_spiSampleHandle; +/* USER CODE BEGIN 1 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* USER CODE END 2 */ + SlaveThreeWiresTestSampleProcessing(); + /* USER CODE BEGIN 3 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_slave_3wires/init/main.h b/src/application/drivers_sample/spi/sample_spi_slave_3wires/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..4bf391fab3f228412ea97d0ff413ff74bb65b6b8 --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_slave_3wires/init/main.h @@ -0,0 +1,53 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "spi.h" +#include "spi_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern SPI_Handle g_spiSampleHandle; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_slave_3wires/init/system_init.c b/src/application/drivers_sample/spi/sample_spi_slave_3wires/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..e39ad7500c6d3e78cd3dbc7663e40b4a56f85411 --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_slave_3wires/init/system_init.c @@ -0,0 +1,162 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg.h" + +#define UART0_BAND_RATE 115200 +#define CLK1M_Div 25 + +#define SPI0_FREQ_SCR 2 +#define SPI0_FREQ_CPSDVSR 20 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 0x30; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (CLK1M_Div - 1); + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void SPI0_Init(void) +{ + HAL_CRG_IpEnableSet(SPI0_BASE, IP_CLK_ENABLE); /* Enable SPI clock. */ + + g_spiSampleHandle.baseAddress = SPI0; + g_spiSampleHandle.mode = HAL_SPI_SLAVE; + g_spiSampleHandle.csMode = SPI_CHIP_SELECT_MODE_INTERNAL; + g_spiSampleHandle.xFerMode = HAL_XFER_MODE_BLOCKING; + g_spiSampleHandle.clkPolarity = HAL_SPI_CLKPOL_0; /* Set Polarity and Phase. */ + g_spiSampleHandle.clkPhase = HAL_SPI_CLKPHA_0; + g_spiSampleHandle.endian = HAL_SPI_BIG_ENDIAN; + g_spiSampleHandle.frameFormat = HAL_SPI_MODE_MOTOROLA; /* Set motorola mode. */ + g_spiSampleHandle.dataWidth = SPI_DATA_WIDTH_16BIT; + g_spiSampleHandle.freqScr = SPI0_FREQ_SCR; + g_spiSampleHandle.freqCpsdvsr = SPI0_FREQ_CPSDVSR; + g_spiSampleHandle.waitEn = BASE_CFG_DISABLE; + g_spiSampleHandle.waitVal = 127; /* 127: Waiting time between receiving and sending. */ + g_spiSampleHandle.rxBuff = NULL; + g_spiSampleHandle.txBuff = NULL; + g_spiSampleHandle.transferSize = 0; + g_spiSampleHandle.txCount = 0; + g_spiSampleHandle.rxCount = 0; /* The count of transferred data. */ + g_spiSampleHandle.state = HAL_SPI_STATE_RESET; + g_spiSampleHandle.rxIntSize = SPI_RX_INTERRUPT_SIZE_1; + g_spiSampleHandle.txIntSize = SPI_TX_INTERRUPT_SIZE_1; + g_spiSampleHandle.rxDMABurstSize = SPI_RX_DMA_BURST_SIZE_1; /* DMA brust bit width */ + g_spiSampleHandle.txDMABurstSize = SPI_TX_DMA_BURST_SIZE_1; + g_spiSampleHandle.handleEx.line = SPI_DATA_1LINE; + HAL_SPI_ChipSelectChannelSet(&g_spiSampleHandle, SPI_CHIP_SELECT_CHANNEL_0); + HAL_SPI_Init(&g_spiSampleHandle); /* Init SPI */ +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN6 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_SPI0_CLK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_SPI0_CLK, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_SPI0_CLK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_SPI0_CLK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_SPI0_CLK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN3 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_0_AS_SPI0_MOSI); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_0_AS_SPI0_MOSI, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_0_AS_SPI0_MOSI, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_0_AS_SPI0_MOSI, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_0_AS_SPI0_MOSI, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN4 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_1_AS_SPI0_MISO); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_1_AS_SPI0_MISO, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_1_AS_SPI0_MISO, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_1_AS_SPI0_MISO, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_1_AS_SPI0_MISO, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN2 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO1_7_AS_SPI0_CSN0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO1_7_AS_SPI0_CSN0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO1_7_AS_SPI0_CSN0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO1_7_AS_SPI0_CSN0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO1_7_AS_SPI0_CSN0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN5 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_SPI0_CSN1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_SPI0_CSN1, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_SPI0_CSN1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_SPI0_CSN1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_SPI0_CSN1, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + SPI0_Init(); + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_slave_3wires/readme.md b/src/application/drivers_sample/spi/sample_spi_slave_3wires/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..1be0d0a4afd98b5066cd1acc2c87cd45e604ec9d --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_slave_3wires/readme.md @@ -0,0 +1,22 @@ +# SPI使用阻塞方式进行三线式主从通信,此示例代码作为从机使用 +## 关键字: SPI, 阻塞, 从机,三线 + +**【功能描述】** ++ 示例代码基于HAL接口完成时钟、SPI控制器初始化和功能配置。从机读主机数据或者向主机发送数据。 + +**【示例配置】** ++ 在"SystemInit()”接口中配置SPI时钟极性、时钟相位、帧格式等参数。 + ++ 定义数组,数组中存放从机需要发送的数据。 + ++ 首先从机调用“HAL_SPI_ReadBlocking()”读取主机发过来的10个数据,之后调用“HAL_SPI_WriteBlocking()”写10个数据,不断循环。 + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码通过串口不断打印从机接收到的数据、发送的数据。 + +**【注意事项】** ++ 使用此示例代码必须对接master设备。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 三线通信时主机mosi线接从机miso线。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/spi/sample_spi_slave_3wires/src/sample_spi_slave_3wires.c b/src/application/drivers_sample/spi/sample_spi_slave_3wires/src/sample_spi_slave_3wires.c new file mode 100644 index 0000000000000000000000000000000000000000..3a510857343a3ad998bcee0f5a5014e625359867 --- /dev/null +++ b/src/application/drivers_sample/spi/sample_spi_slave_3wires/src/sample_spi_slave_3wires.c @@ -0,0 +1,89 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_spi_slave_3wires.c + * @author MCU Driver Team + * @brief Sample for SPI Module slave. + * @details This example demonstrates using the HAL interface in 3-wire slave mode. This example uses blocking mode. + * This example must be connected to a three-wire master device. + * This example sends 0x1105, 0x1c20, 0x1183, 0x1285, 0x1240, 0x12c0, and 0x1340 in polling mode. + * Print the received data through the serial port. + */ +#include "main.h" +#include "spi.h" +#include "debug.h" +#include "sample_spi_slave_3wires.h" + +#define USER_TIMEOUT 0x400 + +#define SLAVE_READ_TESE +#define SLAVE_WRITE_TESE + +#define SLAVE_3WIRES_MODE_SET_CH0 0x1105 +#define SLAVE_3WIRES_MODE_SET_CH1 0x1c20 +#define SLAVE_3WIRES_MODE_SET_CH2 0x1183 +#define SLAVE_3WIRES_MODE_SET_CH3 0x1285 +#define SLAVE_3WIRES_MODE_SET_CH4 0x1240 +#define SLAVE_3WIRES_MODE_SET_CH5 0x12C0 +#define SLAVE_3WIRES_MODE_SET_CH6 0x1340 + +#define MAX_TIMEOUT_VAL 5000 + +/** + * @brief Spi slave three wires sample processing. + * @param None. + * @retval None. + */ +void SlaveThreeWiresTestSampleProcessing(void) +{ + unsigned short tempRdata[10] = {0}; + SystemInit(); + BASE_StatusType ret; + unsigned short tempWdata[] = { + SLAVE_3WIRES_MODE_SET_CH0, + SLAVE_3WIRES_MODE_SET_CH1, + SLAVE_3WIRES_MODE_SET_CH2, + SLAVE_3WIRES_MODE_SET_CH3, + SLAVE_3WIRES_MODE_SET_CH4, + SLAVE_3WIRES_MODE_SET_CH5, + SLAVE_3WIRES_MODE_SET_CH6, + SLAVE_3WIRES_MODE_SET_CH2, + SLAVE_3WIRES_MODE_SET_CH3, + SLAVE_3WIRES_MODE_SET_CH4 + }; + while (1) { +#ifdef SLAVE_READ_TESE + /* Slave read data. */ + ret = HAL_SPI_ReadBlocking(&g_spiSampleHandle, (unsigned char *)tempRdata, sizeof(tempRdata), MAX_TIMEOUT_VAL); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("Slave 3wires read failed\r\n"); + } + for (int i = 0; i < 10; i++) { /* Print the test data for 10 times. */ + DBG_PRINTF("Slave 3wires tempRdata[%d] = 0x%x \r\n", i, tempRdata[i]); + BASE_FUNC_DELAY_MS(10); /* Delay: 10 ms */ + } +#endif +#ifdef SLAVE_WRITE_TESE + for (int i = 0; i < 10; i++) { /* Print the test data for 10 times. */ + DBG_PRINTF("Slave 3wires tempWdata[%d] = 0x%x \r\n", i, tempWdata[i]); + BASE_FUNC_DELAY_MS(10); /* Delay: 10 ms */ + } + /* Slave write data. */ + HAL_SPI_WriteBlocking(&g_spiSampleHandle, (unsigned char *)tempWdata, sizeof(tempWdata), MAX_TIMEOUT_VAL); +#endif + } +} diff --git a/src/application/drivers_sample/timer/sample_timer_interrupt/init/main.h b/src/application/drivers_sample/timer/sample_timer_interrupt/init/main.h index 8a102586d28be30ead6c84fd067b1ecf89eb6fcb..c1929c9ed79c6f31f41461f22ca07290967d2a5e 100644 --- a/src/application/drivers_sample/timer/sample_timer_interrupt/init/main.h +++ b/src/application/drivers_sample/timer/sample_timer_interrupt/init/main.h @@ -29,6 +29,7 @@ #include "timer.h" #include "timer_ex.h" #include "crg.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U diff --git a/src/application/drivers_sample/timer/sample_timer_interrupt/init/system_init.c b/src/application/drivers_sample/timer/sample_timer_interrupt/init/system_init.c index 6dc29e61258341949232164236c50bb542467e12..4a65243ca6ff8a413e650ba84031bd088a53b03b 100644 --- a/src/application/drivers_sample/timer/sample_timer_interrupt/init/system_init.c +++ b/src/application/drivers_sample/timer/sample_timer_interrupt/init/system_init.c @@ -22,7 +22,7 @@ #include "main.h" #include "ioconfig.h" -#include "iocmg.h" +#include "iocmg_ip.h" #define UART0_BAND_RATE 115200 @@ -34,9 +34,11 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 48; /* PLL Multiplier 48 */ crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -54,9 +56,8 @@ __weak void TIMER0_InterruptProcess(void *handle) static void TIMER0_Init(void) { - HAL_CRG_IpEnableSet(TIMER0_BASE, IP_CLK_ENABLE); - - unsigned int load = HAL_CRG_GetIpFreq((void *)TIMER0) / 1000000u * 1000000; + HAL_CRG_IpEnableSet(TIMER0_BASE, IP_CLK_ENABLE); /* TIMER0 clock enable. */ + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER0) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 1000000; g_timerHandle.baseAddress = TIMER0; g_timerHandle.load = load - 1; /* Set timer value immediately */ @@ -71,15 +72,14 @@ static void TIMER0_Init(void) IRQ_Register(IRQ_TIMER0, HAL_TIMER_IrqHandler, &g_timerHandle); HAL_TIMER_RegisterCallback(&g_timerHandle, TIMER_PERIOD_FIN, TIMER0_InterruptProcess); - IRQ_SetPriority(IRQ_TIMER0, 1); + IRQ_SetPriority(IRQ_TIMER0, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_TIMER0); } static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ g_uart0Handle.baseAddress = UART0; g_uart0Handle.baudRate = UART0_BAND_RATE; @@ -99,17 +99,17 @@ static void UART0_Init(void) static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/timer/sample_timer_interrupt/readme.md b/src/application/drivers_sample/timer/sample_timer_interrupt/readme.md index 613a6bda8596ddd2a4c7cb8b2b5ed74c57ac902e..aeb6109e1840113631dc29df6f58612f5a38469e 100644 --- a/src/application/drivers_sample/timer/sample_timer_interrupt/readme.md +++ b/src/application/drivers_sample/timer/sample_timer_interrupt/readme.md @@ -1,5 +1,5 @@ # 周期为1秒的定时器 -## 关键字: TIMER, 定时器周期 +## 关键字: TIMER,定时器周期 **【功能描述】** + 该示例中TIMER每秒产生一个中断,同时定义了一个中断处理函数,该中断处理函数完成串口输出。 @@ -15,4 +15,7 @@ + 中断处理函数按照Timer设置周期执行, 在串口上每秒或者0.5秒打印字符串"In Interrupt"。 **【注意事项】** -+ 串口0输出提示信息。 \ No newline at end of file ++ 串口0输出提示信息。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/tsensor/sample_tsensor/inc/sample_tsensor.h b/src/application/drivers_sample/tsensor/sample_tsensor/inc/sample_tsensor.h index 48f59c16156dc67ce7ae49bf561a933613478c96..b9a252e1051dbf4e317d85cb2e19e3467836ebad 100644 --- a/src/application/drivers_sample/tsensor/sample_tsensor/inc/sample_tsensor.h +++ b/src/application/drivers_sample/tsensor/sample_tsensor/inc/sample_tsensor.h @@ -28,5 +28,6 @@ #include "debug.h" #include "tsensor.h" +void TSENSOR_Init(void); void TSENSOR_GetAveTemp(void); #endif \ No newline at end of file diff --git a/src/application/drivers_sample/tsensor/sample_tsensor/init/main.c b/src/application/drivers_sample/tsensor/sample_tsensor/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..0fc89fd64e3ada56d5d5d6294dbb6670b5f5643a --- /dev/null +++ b/src/application/drivers_sample/tsensor/sample_tsensor/init/main.c @@ -0,0 +1,58 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "sample_tsensor.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + TSENSOR_Init(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/tsensor/sample_tsensor/init/main.h b/src/application/drivers_sample/tsensor/sample_tsensor/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..d059d7d88546489111a34fdcd3c9e14467f4fe88 --- /dev/null +++ b/src/application/drivers_sample/tsensor/sample_tsensor/init/main.h @@ -0,0 +1,54 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/tsensor/sample_tsensor/init/system_init.c b/src/application/drivers_sample/tsensor/sample_tsensor/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..e92ce4f4fd1dd0d42e490beb04b659f0d577d790 --- /dev/null +++ b/src/application/drivers_sample/tsensor/sample_tsensor/init/system_init.c @@ -0,0 +1,91 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/tsensor/sample_tsensor/readme.md b/src/application/drivers_sample/tsensor/sample_tsensor/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..7f709aa53988b73776d9631eadd9dc138f4d5712 --- /dev/null +++ b/src/application/drivers_sample/tsensor/sample_tsensor/readme.md @@ -0,0 +1,13 @@ +# 获取芯片温度 + +**【功能描述】** ++ 利用ADC内置的TSENEOR模块,对器件结温进行采集,示例返回为摄氏度。 ++ 示例代码中配置如下: ++ (1)示例中连续采样16次后,算出平均温度。 ++ (2)示例中TSENSOR,使用ADC1_SOC15进行配置和采样。 + +**【环境要求】** ++ 所有单板电源改制为演示用的12V低压。 + +**【IDE配置方法】** ++ chipConfig中的Sample栏目里面选中Tsensor Get Temperature示例,然后点击生成代码即可。 \ No newline at end of file diff --git a/src/application/drivers_sample/tsensor/sample_tsensor/readme.txt b/src/application/drivers_sample/tsensor/sample_tsensor/readme.txt deleted file mode 100644 index 9e29727822a2edf5a3e080629c40c6ec0377f844..0000000000000000000000000000000000000000 --- a/src/application/drivers_sample/tsensor/sample_tsensor/readme.txt +++ /dev/null @@ -1,6 +0,0 @@ -“sample_tsensor”示例代码提供示例功能: -利用ADC内置的TSENEOR模块,对器件结温进行采集,示例返回为摄氏度。 - -示例代码中配置如下: -(1)示例中连续采样16次后,算出平均温度 -(2)示例中TSENSOR,使用ADC1_SOC15进行配置和采样 \ No newline at end of file diff --git a/src/application/drivers_sample/tsensor/sample_tsensor/src/sample_tsensor.c b/src/application/drivers_sample/tsensor/sample_tsensor/src/sample_tsensor.c index 82ec4c01116ddd919c6c7a740d0f1da36362473f..0e7702bbb1a7e7d240209eadc2a4c8b32ba97b3c 100644 --- a/src/application/drivers_sample/tsensor/sample_tsensor/src/sample_tsensor.c +++ b/src/application/drivers_sample/tsensor/sample_tsensor/src/sample_tsensor.c @@ -21,9 +21,26 @@ * @details This file provides sample to get temperature of mcu by using tsensor. */ #include "sample_tsensor.h" +#include "main.h" #define SAMPLE_COUNT 16 +/** + * @brief Tsensor module initial. + * @param None. + * @retval None. + */ +void TSENSOR_Init(void) +{ + SystemInit(); + HAL_TSENSOR_Init(); + while (1) { + TSENSOR_GetAveTemp(); + } +} + + +float g_aveTemp; /** * @brief Tsensor samples 16 times, takes the average value, and converts the average value to degrees Celsius. * @param None. @@ -31,18 +48,15 @@ */ void TSENSOR_GetAveTemp(void) { - DBG_UartPrintInit(BAUDRATE); float total = 0; float ret; - float aveTemp; - HAL_TSENSOR_Init(); /* Tsensor cyclic sampling */ for (int i = 0; i < SAMPLE_COUNT; ++i) { ret = HAL_TSENSOR_GetTemperature(); total += ret; } /* Converting the sampled average value of the test sensor to temperature */ - aveTemp = total / SAMPLE_COUNT; - DBG_PRINTF("Tsensor Average temperature: %f\r\n", aveTemp); - return; + g_aveTemp = total / SAMPLE_COUNT; + DBG_PRINTF("Tsensor Average temperature: %f\r\n", g_aveTemp); + BASE_FUNC_DELAY_S(1); } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_baud_detect/readme.md b/src/application/drivers_sample/uart/sample_uart_baud_detect/readme.md index 65f48e6abd17ed31d6a22d7921d494bb7d029cac..ca458ae2e39cd26bb7030c6ef758dcf4fae7e995 100644 --- a/src/application/drivers_sample/uart/sample_uart_baud_detect/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_baud_detect/readme.md @@ -1,19 +1,21 @@ # UART波特率自检 -## 关键字: UART, 波特率自检 +## 关键字: UART, 波特率自检 **【功能描述】** + 能够识别总线上的波特率,并自动配置UART的波特率。 **【示例配置】** -+ 特定字符发送:若要检测波特率,需要向串口发送大写字符“Z”,代码中有成功检测标志"baudCheck", 可以依据检测成功标志,实现后续逻辑。 ++ 特定字符发送:若要检测波特率,需要向串口发送大写字符“Z(3061M系列芯片)”或者“7F(3066M系列芯片)”,代码中有成功检测标志"baudCheck", 可以依据检测成功标志,实现后续逻辑。 + 波特率检测中断:波特率检测成功之后,会调用波特率检测成功函数"UART_BaudDetectCallBack_Ok", 用户可以使用"HAL_UART_RegisterCallBack"进行更改。 **【示例效果】** -+ 向串口0发送大写字符"Z",如果串口输出“UART_BaudDetectCallBack_Ok”字符,则代表波特率检测成功。 ++ 向串口发送大写字符“Z(3061M系列芯片)”或者“0x7F(3066M系列芯片)”,如果串口输出“UART_BaudDetectCallBack_Ok”字符,则代表波特率检测成功。 **【注意事项】** + 串口波特率不一致时,需要先完成波特率的检测。 -+ 需要向串口发送特定字符“Z”,才能触发波特率检测。 \ No newline at end of file ++ 需要向串口发送特定字符“Z”,才能触发波特率检测。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_blocking_rx/inc/sample_uart_blocking_rx.h b/src/application/drivers_sample/uart/sample_uart_blocking_rx/inc/sample_uart_blocking_rx.h index 6fefb509976ed24f2b05b0029885968e0b7dd3e3..8a0986ebb251478f424cadb3cd9db8952cc136ac 100644 --- a/src/application/drivers_sample/uart/sample_uart_blocking_rx/inc/sample_uart_blocking_rx.h +++ b/src/application/drivers_sample/uart/sample_uart_blocking_rx/inc/sample_uart_blocking_rx.h @@ -31,5 +31,5 @@ #include "interrupt.h" #include "main.h" -void UART_BlcokingRX(void); +void UART_BlockingRX(void); #endif \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_blocking_rx/init/main.c b/src/application/drivers_sample/uart/sample_uart_blocking_rx/init/main.c index 1ce0ab892143df558657d7c66a09337eb29ae3ce..25365c7e9e59df9988923f956776536a57578011 100644 --- a/src/application/drivers_sample/uart/sample_uart_blocking_rx/init/main.c +++ b/src/application/drivers_sample/uart/sample_uart_blocking_rx/init/main.c @@ -27,7 +27,7 @@ UART_Handle g_uart; int main(void) { - UART_BlcokingRX(); + UART_BlockingRX(); while (1) { } return BASE_STATUS_OK; diff --git a/src/application/drivers_sample/uart/sample_uart_blocking_rx/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_blocking_rx/init/system_init.c index dbefea54e5bac42951a4fdca7c72aa3c8dc4bff8..c0ebde5394a06e6c7381c141cad6c0537d5e072e 100644 --- a/src/application/drivers_sample/uart/sample_uart_blocking_rx/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_blocking_rx/init/system_init.c @@ -30,13 +30,11 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; crg.baseAddress = CRG; - crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_XTAL; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = 0; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -48,6 +46,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -58,33 +57,33 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_BLOCKING; g_uart.rxMode = UART_MODE_BLOCKING; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); UART0_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_blocking_rx/readme.md b/src/application/drivers_sample/uart/sample_uart_blocking_rx/readme.md index 8574d79292d947251886b81625c5461d465d7246..c418ee25c0dbbc3d1fc068f281470bb4552ff0c3 100644 --- a/src/application/drivers_sample/uart/sample_uart_blocking_rx/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_blocking_rx/readme.md @@ -1,5 +1,5 @@ # UART阻塞模式接收数据 -## 关键字: UART, 阻塞模式接收 +## 关键字: UART, 阻塞模式接收 **【功能描述】** + 在阻塞下模式下,阻塞一段时间等待UART接收数据,接收到的数据从预设置的缓存中读取。 @@ -20,4 +20,7 @@ BASE_STATUS_TIMEOUT,表示在规定时间内,未能完成数据接收;其 + 向串口0发送数据,串口0会将接收的数据打印,若超过设定的超时时间未接收到数据会打印“Receive time out!”。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_blocking_rx/src/sample_uart_blocking_rx.c b/src/application/drivers_sample/uart/sample_uart_blocking_rx/src/sample_uart_blocking_rx.c index a33f20741992843e1e52e5cf4df6d94632284878..fa90323a974b8fc39e971228a58d87864da62a9c 100644 --- a/src/application/drivers_sample/uart/sample_uart_blocking_rx/src/sample_uart_blocking_rx.c +++ b/src/application/drivers_sample/uart/sample_uart_blocking_rx/src/sample_uart_blocking_rx.c @@ -34,7 +34,7 @@ * @param None. * @retval None. */ -void UART_BlcokingRX(void) +void UART_BlockingRX(void) { SystemInit(); unsigned char rxStr[20] = {0}; /* rxStr[20], Receive memory address */ diff --git a/src/application/drivers_sample/uart/sample_uart_blocking_tx/inc/sample_uart_blocking_tx.h b/src/application/drivers_sample/uart/sample_uart_blocking_tx/inc/sample_uart_blocking_tx.h index ba885e50e7287b0c7c6c57b7cb47c2dd8b6724d3..eb83b39cf1e1306cb699de0b864043fd66a5d7f7 100644 --- a/src/application/drivers_sample/uart/sample_uart_blocking_tx/inc/sample_uart_blocking_tx.h +++ b/src/application/drivers_sample/uart/sample_uart_blocking_tx/inc/sample_uart_blocking_tx.h @@ -31,5 +31,5 @@ #include "interrupt.h" #include "main.h" -void UART_BlcokingTX(void); +void UART_BlockingTX(void); #endif \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_blocking_tx/init/main.c b/src/application/drivers_sample/uart/sample_uart_blocking_tx/init/main.c index c97ce182c42e383de73f2663b1196b0c50ce2b94..0638f183185ee8bd4586d9991a842990403187dc 100644 --- a/src/application/drivers_sample/uart/sample_uart_blocking_tx/init/main.c +++ b/src/application/drivers_sample/uart/sample_uart_blocking_tx/init/main.c @@ -27,7 +27,7 @@ UART_Handle g_uart; int main(void) { - UART_BlcokingTX(); + UART_BlockingTX(); while (1) { } return BASE_STATUS_OK; diff --git a/src/application/drivers_sample/uart/sample_uart_blocking_tx/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_blocking_tx/init/system_init.c index 231b06da90e373d4301c4c63907106fb1d5e7fa7..c0ebde5394a06e6c7381c141cad6c0537d5e072e 100644 --- a/src/application/drivers_sample/uart/sample_uart_blocking_tx/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_blocking_tx/init/system_init.c @@ -30,13 +30,11 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; crg.baseAddress = CRG; - crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_XTAL; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = 0; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -48,6 +46,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -58,27 +57,26 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_BLOCKING; g_uart.rxMode = UART_MODE_BLOCKING; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/uart/sample_uart_blocking_tx/readme.md b/src/application/drivers_sample/uart/sample_uart_blocking_tx/readme.md index 82676acd8bc337e40c75e11fbf9f476408ad0743..5ba05084ebccfc3573918dd15b45ec6c9498c390 100644 --- a/src/application/drivers_sample/uart/sample_uart_blocking_tx/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_blocking_tx/readme.md @@ -1,5 +1,5 @@ # UART阻塞模式发送数据 -## 关键字: UART, 阻塞模式发送 +## 关键字: UART, 阻塞模式发送 **【功能描述】** + 在阻塞下模式下,阻塞一段时间等待UART发送数据。 @@ -19,4 +19,7 @@ + 串口0发送数据,若在超时时长内发送数据,则打印“Send success!”,若发送超时则打印“Send time out!”, 发送错误,打印“Send verification error!”。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_blocking_tx/src/sample_uart_blocking_tx.c b/src/application/drivers_sample/uart/sample_uart_blocking_tx/src/sample_uart_blocking_tx.c index d42307c4e1a4a3bb3ae458b762e52ac6f48eec0e..f548ac1a177aecf2368c5eac615969ce27636c00 100644 --- a/src/application/drivers_sample/uart/sample_uart_blocking_tx/src/sample_uart_blocking_tx.c +++ b/src/application/drivers_sample/uart/sample_uart_blocking_tx/src/sample_uart_blocking_tx.c @@ -36,7 +36,7 @@ * @param None. * @retval None. */ -void UART_BlcokingTX(void) +void UART_BlockingTX(void) { SystemInit(); DBG_PRINTF("TX: UART Init finish\r\n"); diff --git a/src/application/drivers_sample/uart/sample_uart_character_match/readme.md b/src/application/drivers_sample/uart/sample_uart_character_match/readme.md index 493a30b0cba285e1e396fbdcb8aa9ea4f00b2f8d..654aa15448914317e050ccf47957dcdf27db5928 100644 --- a/src/application/drivers_sample/uart/sample_uart_character_match/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_character_match/readme.md @@ -1,5 +1,5 @@ # UART检测特定字符 -## 关键字: UART, 特定字符检测 +## 关键字: UART,特定字符检测 **【功能描述】** + UART检测特定字符,检测到特定字符,会触发检测成功回调函数。 @@ -13,4 +13,7 @@ + 向串口0发送大写字符"123Acharactermatch",如果串口输出“Match character success”字符,则代表检测到字符“A”。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 + ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_dma_rx/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_dma_rx/init/system_init.c index 3f7049d9d280ca970ce5c99d7dbdb6f76e059373..80cfec2ed94a5abb93f13d52cd7dd7375f2beb67 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_rx/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_dma_rx/init/system_init.c @@ -22,7 +22,7 @@ #include "main.h" #include "ioconfig.h" -#include "iocmg_ip.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -32,11 +32,9 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 48; /* PLL Multiplier 48 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -65,20 +63,15 @@ static void DMA_Init(void) { HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); - DMA_Channel2Init((void *)(&g_uart)); - HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_TWO, DMA_PRIORITY_MEDIUM); -} -__weak void UART0InterruptErrorCallback(void *handle) -{ - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ - /* USER CODE END UART0_TRNS_IT_ERROR */ + DMA_Channel2Init((void *)(&g_uart)); } __weak void DMA_Channel2CallBack(void *handle) @@ -91,6 +84,7 @@ __weak void DMA_Channel2CallBack(void *handle) static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -101,35 +95,29 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_BLOCKING; g_uart.rxMode = UART_MODE_DMA; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); - HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); - - IRQ_Register(IRQ_UART0, HAL_UART_IrqHandler, &g_uart); - IRQ_SetPriority(IRQ_UART0, 1); - IRQ_EnableN(IRQ_UART0); g_uart.dmaHandle = &g_dmac; - g_uart.uartDmaRxChn = 2; /* DMA channel is 2. */ + g_uart.uartDmaRxChn = 2; /* 2 is UART_DMA rx channel */ HAL_UART_RegisterCallBack(&g_uart, UART_READ_DMA_FINISH, DMA_Channel2CallBack); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -137,6 +125,7 @@ void SystemInit(void) IOConfig(); DMA_Init(); UART0_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_dma_rx/readme.md b/src/application/drivers_sample/uart/sample_uart_dma_rx/readme.md index 3c3cec867bf76145700f686645154096d8274b32..d0d548f9cd43841dce3732ac563c90a5ebf854ac 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_rx/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_dma_rx/readme.md @@ -1,5 +1,5 @@ # UART-DMA模式接收数据 -## 关键字: UART, DMA模式接收 +## 关键字: UART, DMA模式接收 **【功能描述】** + 在UART DMA模式下,通过DMA将接收的数据搬运到指定的内存空间。 @@ -19,4 +19,7 @@ + 向串口0发送数据,串口0会将接收的数据打印。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/init/system_init.c index 56391d3f793875c044e0878d88d600ba1b2e1b70..80cfec2ed94a5abb93f13d52cd7dd7375f2beb67 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/init/system_init.c @@ -32,11 +32,9 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 48; /* PLL Multiplier 48 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -65,13 +63,15 @@ static void DMA_Init(void) { HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); + DMA_Channel2Init((void *)(&g_uart)); - HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_TWO, DMA_PRIORITY_MEDIUM); } __weak void DMA_Channel2CallBack(void *handle) @@ -84,6 +84,7 @@ __weak void DMA_Channel2CallBack(void *handle) static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -94,31 +95,29 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_BLOCKING; g_uart.rxMode = UART_MODE_DMA; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); - g_uart.dmaHandle = &g_dmac; - g_uart.uartDmaRxChn = 2; /* DMA channel is 2. */ + g_uart.uartDmaRxChn = 2; /* 2 is UART_DMA rx channel */ HAL_UART_RegisterCallBack(&g_uart, UART_READ_DMA_FINISH, DMA_Channel2CallBack); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -126,6 +125,7 @@ void SystemInit(void) IOConfig(); DMA_Init(); UART0_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/readme.md b/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/readme.md index 7391320f518225bb152461b70dbaabed62cd50fc..ac4ab6ccda619d64fe87842e4b4c0f307eeb8403 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/readme.md @@ -1,5 +1,5 @@ # UART-DMA模式循环接收数据 -## 关键字: UART, DMA循环接收 +## 关键字: UART, DMA循环接收 **【功能描述】** + 在UART DMA模式下,当UART接收数据完成后,DMA接收到UART的搬运请求,将数据循环搬运到预设置的内存中, 当预设置的内存写满之后, @@ -18,4 +18,7 @@ + 不断向串口0发送数据,串口0会打印出接收的数据,并将数据储存到预设的内存中,当预设置的内存写满之后,会从内存的起始地址开始写。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/src/sample_uart_dma_rx_cyclically_stored.c b/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/src/sample_uart_dma_rx_cyclically_stored.c index b18e889b13533e4f8c2e3c9f555a3723798a85bd..f1d99e556670cf1044d22f2fadaf36d233bf7fbb 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/src/sample_uart_dma_rx_cyclically_stored.c +++ b/src/application/drivers_sample/uart/sample_uart_dma_rx_cyclically_stored/src/sample_uart_dma_rx_cyclically_stored.c @@ -48,7 +48,7 @@ int UART_DMA_RxCyclicallyStored(void) HAL_UART_ReadDMAAndCyclicallyStored(&g_uart, g_buf, &g_Node, BUF_LEN); while (1) { - /* Obtains the destination address written by the DAM */ + /* Obtains the destination address written by the DMA */ g_pointWrite = HAL_UART_ReadDMAGetPos(&g_uart); /* Print data if read pointer is inconsistent with write pointer */ diff --git a/src/application/drivers_sample/uart/sample_uart_dma_tx/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_dma_tx/init/system_init.c index 98ba5e617694a289e3bef82c3acaa703020601eb..ecf5f0781b1835ac50115ac124812692f06aab1e 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_tx/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_dma_tx/init/system_init.c @@ -22,7 +22,6 @@ #include "main.h" #include "ioconfig.h" -#include "iocmg_ip.h" #include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -33,11 +32,9 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 48; /* PLL Multiplier 48 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -66,20 +63,15 @@ static void DMA_Init(void) { HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); - DMA_Channel3Init((void *)(&g_uart)); - HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_THREE, DMA_PRIORITY_LOW); -} -__weak void UART0InterruptErrorCallback(void *handle) -{ - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ - /* USER CODE END UART0_TRNS_IT_ERROR */ + DMA_Channel3Init((void *)(&g_uart)); } __weak void DMA_Channel3CallBack(void *handle) @@ -92,6 +84,7 @@ __weak void DMA_Channel3CallBack(void *handle) static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -102,35 +95,29 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_DMA; g_uart.rxMode = UART_MODE_BLOCKING; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); - HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); - - IRQ_Register(IRQ_UART0, HAL_UART_IrqHandler, &g_uart); - IRQ_SetPriority(IRQ_UART0, 1); - IRQ_EnableN(IRQ_UART0); g_uart.dmaHandle = &g_dmac; - g_uart.uartDmaTxChn = 3; /* Rx Dma Channel is 3. */ + g_uart.uartDmaTxChn = 3; /* 3 is dma tx chanel */ HAL_UART_RegisterCallBack(&g_uart, UART_WRITE_DMA_FINISH, DMA_Channel3CallBack); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/uart/sample_uart_dma_tx/readme.md b/src/application/drivers_sample/uart/sample_uart_dma_tx/readme.md index 1b61cb366884c8c4d963a6d058c92e7e24e0f077..29d4d6ec005e7ddcce0eb79e668ee12b84952eb1 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_tx/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_dma_tx/readme.md @@ -1,5 +1,5 @@ # UART-DMA模式发送数据 -## 关键字: UART, DMA模式发送 +## 关键字: UART, DMA模式发送 **【功能描述】** + 在UART DMA模式下,DMA接收到UART的搬运请求,将待发送的数据从内存中直接搬运到UART直接发送。 @@ -19,4 +19,7 @@ + DMA搬运结束后,会上报中断,可以在DMA中断回调函数中加上标志位进行判断是否完成。若发送完成,串口0会打印“write_finish”字符。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/init/system_init.c index a17817354d9e00b0c2403177f8f53c826c043cdf..8059068da668a2d987c32fd0c65a11f1a8a1c8ea 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/init/system_init.c @@ -32,11 +32,9 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 48; /* PLL Multiplier 48 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -45,51 +43,52 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -static void DMA_Channel3Init(void *handle) +static void DMA_Channel2Init(void *handle) { DMA_ChannelParam dma_param; - dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; - dma_param.srcAddrInc = DMA_ADDR_INCREASE; - dma_param.destAddrInc = DMA_ADDR_UNALTERED; - dma_param.srcPeriph = DMA_REQUEST_MEM; - dma_param.destPeriph = DMA_REQUEST_UART0_TX; + dma_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; + dma_param.srcAddrInc = DMA_ADDR_UNALTERED; + dma_param.destAddrInc = DMA_ADDR_INCREASE; + dma_param.srcPeriph = DMA_REQUEST_UART0_RX; + dma_param.destPeriph = DMA_REQUEST_MEM; dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; dma_param.destWidth = DMA_TRANSWIDTH_BYTE; dma_param.srcBurst = DMA_BURST_LENGTH_1; dma_param.destBurst = DMA_BURST_LENGTH_1; dma_param.pHandle = handle; - HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_THREE); + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_TWO); } -static void DMA_Channel2Init(void *handle) +static void DMA_Channel3Init(void *handle) { DMA_ChannelParam dma_param; - dma_param.direction = DMA_PERIPH_TO_MEMORY_BY_DMAC; - dma_param.srcAddrInc = DMA_ADDR_UNALTERED; - dma_param.destAddrInc = DMA_ADDR_INCREASE; - dma_param.srcPeriph = DMA_REQUEST_UART0_RX; - dma_param.destPeriph = DMA_REQUEST_MEM; + dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; + dma_param.srcAddrInc = DMA_ADDR_INCREASE; + dma_param.destAddrInc = DMA_ADDR_UNALTERED; + dma_param.srcPeriph = DMA_REQUEST_MEM; + dma_param.destPeriph = DMA_REQUEST_UART0_TX; dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; dma_param.destWidth = DMA_TRANSWIDTH_BYTE; dma_param.srcBurst = DMA_BURST_LENGTH_1; dma_param.destBurst = DMA_BURST_LENGTH_1; dma_param.pHandle = handle; - HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_TWO); + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_THREE); } static void DMA_Init(void) { HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); - DMA_Channel3Init((void *)(&g_uart)); - HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_THREE, DMA_PRIORITY_LOW); + DMA_Channel2Init((void *)(&g_uart)); - HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_TWO, DMA_PRIORITY_MEDIUM); + DMA_Channel3Init((void *)(&g_uart)); } __weak void DMA_Channel3CallBack(void *handle) @@ -109,6 +108,7 @@ __weak void DMA_Channel2CallBack(void *handle) static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -119,33 +119,31 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_DMA; g_uart.rxMode = UART_MODE_DMA; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); - g_uart.dmaHandle = &g_dmac; - g_uart.uartDmaTxChn = 3; /* Rx Dma Channel is 3. */ + g_uart.uartDmaTxChn = 3; /* 3 is dma tx chanel */ HAL_UART_RegisterCallBack(&g_uart, UART_WRITE_DMA_FINISH, DMA_Channel3CallBack); - g_uart.uartDmaRxChn = 2; /* DMA channel is 2. */ + g_uart.uartDmaRxChn = 2; /* 2 is UART_DMA rx channel */ HAL_UART_RegisterCallBack(&g_uart, UART_READ_DMA_FINISH, DMA_Channel2CallBack); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -153,6 +151,7 @@ void SystemInit(void) IOConfig(); DMA_Init(); UART0_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/readme.md b/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/readme.md index edef7c1d16db968b45ed232fec8e7df44abfae09..ed5d995a673d52300b737f32fc3bfd53f8537ded 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/readme.md @@ -1,5 +1,5 @@ # UART-Tx和Rx在DMA模式下同时收发数据 -## 关键字: UART, Tx_DMA_Rx_INT收发数据 +## 关键字: UART, Tx_DMA_Rx_INT收发数据 **【功能描述】** + UART_DMA全双工收发数据,UART_DMA写的过程中,可以进行UART_DMA读。 @@ -19,4 +19,7 @@ + 示例程序会不断的进行UART_DMA发送、接收,实现UART_DMA写的过程中,可以进行UART_DMA读。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/src/sample_uart_dma_tx_dma_rx_simultaneously.c b/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/src/sample_uart_dma_tx_dma_rx_simultaneously.c index 39deeeb42902d9b358d9b10918388a4279ba48e3..8d14338cee86bf8ae315cf4ed569457914e3ebf2 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/src/sample_uart_dma_tx_dma_rx_simultaneously.c +++ b/src/application/drivers_sample/uart/sample_uart_dma_tx_dma_rx_simultaneously/src/sample_uart_dma_tx_dma_rx_simultaneously.c @@ -31,7 +31,6 @@ #define DMA_RX_DATA_LENGTH 10 #define DMA_TX_DATA_LENGTH 15 -#define NEED_REQUIRE_TIME 30 static unsigned char g_txDMAStr[DMA_TX_DATA_LENGTH] = "123456789012345"; /* The transmit data length is 15 */ static unsigned char g_rxDMAStr[DMA_RX_DATA_LENGTH] = {0}; /* The receive data length is 10 */ @@ -106,8 +105,6 @@ void UART_DMATxAndRxSimultaneously(void) /* DMA read: Length of the received data must be equal to the DMA_RX_DATA_LENGTH */ HAL_UART_ReadDMA(&g_uart, g_rxDMAStr, DMA_RX_DATA_LENGTH); } - /* Add a deletion delay as required */ - BASE_FUNC_DELAY_MS(NEED_REQUIRE_TIME); } return; } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/init/system_init.c index 67df918fcff657594b26acc5a8281446f0236e66..5a787f91ef0407bfb36d0a6224deba67bec67fd4 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/init/system_init.c @@ -32,11 +32,9 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 48; /* PLL Multiplier 48 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -65,20 +63,22 @@ static void DMA_Init(void) { HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); + DMA_Channel3Init((void *)(&g_uart)); - HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_THREE, DMA_PRIORITY_LOW); } -__weak void UART0InterruptErrorCallback(void *handle) +__weak void UART0WriteInterruptCallback(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ - /* USER CODE END UART0_TRNS_IT_ERROR */ + /* USER CODE BEGIN UART0_WRITE_IT_FINISH */ + /* USER CODE END UART0_WRITE_IT_FINISH */ } __weak void ReadCallBack(void *handle) @@ -88,6 +88,13 @@ __weak void ReadCallBack(void *handle) /* USER CODE END UART0_READ_IT_FINISH */ } +__weak void UART0InterruptErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ + /* USER CODE END UART0_TRNS_IT_ERROR */ +} + __weak void DMA_Channel3CallBack(void *handle) { BASE_FUNC_UNUSED(handle); @@ -98,6 +105,7 @@ __weak void DMA_Channel3CallBack(void *handle) static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -108,36 +116,35 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_DMA; g_uart.rxMode = UART_MODE_INTERRUPT; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); - HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); + HAL_UART_RegisterCallBack(&g_uart, UART_WRITE_IT_FINISH, UART0WriteInterruptCallback); HAL_UART_RegisterCallBack(&g_uart, UART_READ_IT_FINISH, ReadCallBack); - + HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); IRQ_Register(IRQ_UART0, HAL_UART_IrqHandler, &g_uart); - IRQ_SetPriority(IRQ_UART0, 1); + IRQ_SetPriority(IRQ_UART0, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_UART0); g_uart.dmaHandle = &g_dmac; - g_uart.uartDmaTxChn = 3; /* Rx Dma Channel is 3. */ + g_uart.uartDmaTxChn = 3; /* 3 is dma tx chanel */ HAL_UART_RegisterCallBack(&g_uart, UART_WRITE_DMA_FINISH, DMA_Channel3CallBack); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -145,6 +152,7 @@ void SystemInit(void) IOConfig(); DMA_Init(); UART0_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/readme.md b/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/readme.md index acb2b0f97b1dd6277aa4ccc16a6fe6e15c4df984..0093b6febbe9e599a658acc7769e4efc8ab4b0d0 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/readme.md @@ -1,5 +1,5 @@ # UART-Tx在DMA模式下发送数据Rx在中断模式下接收数据 -## 关键字: UART, Tx_DMA_Rx_INT收发数据 +## 关键字: UART, Tx_DMA_Rx_INT收发数据 **【功能描述】** + UART全双工收发数据,实现中断和UART_DAM全双工收发数据,UART_DMA写的过程中,可以进行中断读。 @@ -19,4 +19,7 @@ + 示例程序会不断的进行UART_DMA发送、中断接收数据,实现UART_DMA发送的过程中,可以进行中断接收数据。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/src/sample_uart_dma_tx_int_rx_simultaneously.c b/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/src/sample_uart_dma_tx_int_rx_simultaneously.c index 890da75ca34d120dd73573ba9a594cbdfac91d68..722d4a2a96d3df95a51c3f33b4b75685229cd7c0 100644 --- a/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/src/sample_uart_dma_tx_int_rx_simultaneously.c +++ b/src/application/drivers_sample/uart/sample_uart_dma_tx_int_rx_simultaneously/src/sample_uart_dma_tx_int_rx_simultaneously.c @@ -32,7 +32,6 @@ #define RX_DATA_LENGTH 10 #define TX_DATA_LENGTH 15 -#define REQUIRE_TIME 30 static unsigned char g_txStr[TX_DATA_LENGTH] = "123456789012345"; /* The transmit data length is 15 */ static unsigned char g_rxStr[RX_DATA_LENGTH] = {0}; /* The receive data length is 10 */ @@ -109,7 +108,6 @@ void UART_DMATxAndINTRxSimultaneously(void) /* UART IT read: Length of the received data must be equal to the RX_DATA_LENGTH */ HAL_UART_ReadIT(&g_uart, g_rxStr, RX_DATA_LENGTH); } - BASE_FUNC_DELAY_MS(REQUIRE_TIME); /* Add a deletion delay as required */ } return; } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/init/system_init.c index 20675e47cb8657a97982408169fe79e304e99478..584997114199a0a6731df567bde74c69b8668909 100644 --- a/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/init/system_init.c @@ -32,11 +32,9 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 48; /* PLL Multiplier 48 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -65,27 +63,36 @@ static void DMA_Init(void) { HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); + DMA_Channel2Init((void *)(&g_uart)); - HAL_DMA_SetChannelPriorityEx(&g_dmac, DMA_CHANNEL_TWO, DMA_PRIORITY_MEDIUM); } -__weak void UART0InterruptErrorCallback(void *handle) +__weak void WriteCallBack(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ - /* USER CODE END UART0_TRNS_IT_ERROR */ + /* USER CODE BEGIN UART0_WRITE_IT_FINISH */ + /* USER CODE END UART0_WRITE_IT_FINISH */ } -__weak void WriteCallBack(void *handle) +__weak void UART0ReadInterruptCallback(void *handle) { BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_WRITE_IT_FINISH */ - /* USER CODE END UART0_WRITE_IT_FINISH */ + /* USER CODE BEGIN UART0_READ_IT_FINISH */ + /* USER CODE END UART0_READ_IT_FINISH */ +} + +__weak void UART0InterruptErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ + /* USER CODE END UART0_TRNS_IT_ERROR */ } __weak void DMA_Channel2CallBack(void *handle) @@ -98,6 +105,7 @@ __weak void DMA_Channel2CallBack(void *handle) static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -108,36 +116,35 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_INTERRUPT; g_uart.rxMode = UART_MODE_DMA; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); - HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); HAL_UART_RegisterCallBack(&g_uart, UART_WRITE_IT_FINISH, WriteCallBack); - + HAL_UART_RegisterCallBack(&g_uart, UART_READ_IT_FINISH, UART0ReadInterruptCallback); + HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); IRQ_Register(IRQ_UART0, HAL_UART_IrqHandler, &g_uart); - IRQ_SetPriority(IRQ_UART0, 1); + IRQ_SetPriority(IRQ_UART0, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_UART0); g_uart.dmaHandle = &g_dmac; - g_uart.uartDmaRxChn = 2; /* DMA channel is 2. */ + g_uart.uartDmaRxChn = 2; /* 2 is UART_DMA rx channel */ HAL_UART_RegisterCallBack(&g_uart, UART_READ_DMA_FINISH, DMA_Channel2CallBack); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -145,6 +152,7 @@ void SystemInit(void) IOConfig(); DMA_Init(); UART0_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/readme.md b/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/readme.md index f682c1b565b35cf5f889a64c6d257da3a8814416..ba774ab538d9f2e4789da03a8891ea621842f72c 100644 --- a/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/readme.md @@ -1,5 +1,5 @@ # UART-Tx在中断模式下发送数据Rx在DMA模式下接收数据 -## 关键字: UART, Tx_INT_Rx_DMA收发数据 +## 关键字: UART, Tx_INT_Rx_DMA收发数据 **【功能描述】** + UART全双工收发数据,实现中断和UART_DAM全双工收发数据,中断写的过程中,可以进行UART_DMA读。 @@ -19,4 +19,7 @@ + 示例程序会不断的进行中断发送、UART_DMA接收,实现中断写的过程中,可以进行UART_DMA读。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/src/sample_uart_int_tx_dma_rx_simultaneously.c b/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/src/sample_uart_int_tx_dma_rx_simultaneously.c index 92ef41045e8d975f9124b9f306e09699c92e3896..8ba93998693cd11d91c67dba7d01a7e203aa9955 100644 --- a/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/src/sample_uart_int_tx_dma_rx_simultaneously.c +++ b/src/application/drivers_sample/uart/sample_uart_int_tx_dma_rx_simultaneously/src/sample_uart_int_tx_dma_rx_simultaneously.c @@ -32,7 +32,6 @@ #define RX_IT_DMA_DATA_LENGTH 10 #define TX_IT_DMA_DATA_LENGTH 15 -#define IT_DMA_REQUIRE_TIME 30 static unsigned char g_txITDMAStr[TX_IT_DMA_DATA_LENGTH] = "123456789012345"; /* The transmit data length is 15 */ static unsigned char g_rxITDMAStr[RX_IT_DMA_DATA_LENGTH] = {0}; /* The receive data length is 10 */ @@ -109,7 +108,6 @@ void UART_INTTxAndDMARxSimultaneously(void) /* DMA read: Length of the received data must be equal to the RX_IT_DMA_DATA_LENGTH */ HAL_UART_ReadDMA(&g_uart, g_rxITDMAStr, RX_IT_DMA_DATA_LENGTH); } - BASE_FUNC_DELAY_MS(IT_DMA_REQUIRE_TIME); /* Add a deletion delay as required */ } return; } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_int_tx_int_rx_simultaneously/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_int_tx_int_rx_simultaneously/init/system_init.c index b5e8bb2c9776b22729fd184d4212d08b6bd22ff9..5dbf4a16cb01c46b5c3bd46433cf64accd11ed49 100644 --- a/src/application/drivers_sample/uart/sample_uart_int_tx_int_rx_simultaneously/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_int_tx_int_rx_simultaneously/init/system_init.c @@ -32,11 +32,9 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 48; /* PLL Multiplier 48 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -45,13 +43,6 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -__weak void UART0InterruptErrorCallback(void *handle) -{ - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ - /* USER CODE END UART0_TRNS_IT_ERROR */ -} - __weak void WriteCallBack(void *handle) { BASE_FUNC_UNUSED(handle); @@ -66,9 +57,17 @@ __weak void ReadCallBack(void *handle) /* USER CODE END UART0_READ_IT_FINISH */ } +__weak void UART0InterruptErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ + /* USER CODE END UART0_TRNS_IT_ERROR */ +} + static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -79,40 +78,39 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_INTERRUPT; g_uart.rxMode = UART_MODE_INTERRUPT; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); - HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); HAL_UART_RegisterCallBack(&g_uart, UART_WRITE_IT_FINISH, WriteCallBack); HAL_UART_RegisterCallBack(&g_uart, UART_READ_IT_FINISH, ReadCallBack); - + HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); IRQ_Register(IRQ_UART0, HAL_UART_IrqHandler, &g_uart); - IRQ_SetPriority(IRQ_UART0, 1); + IRQ_SetPriority(IRQ_UART0, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_UART0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); UART0_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_int_tx_int_rx_simultaneously/readme.md b/src/application/drivers_sample/uart/sample_uart_int_tx_int_rx_simultaneously/readme.md index 3c0d4116edd47f0c35e412ff75524cc1c1244fe9..c806243d82e434080854c685e6a4e52731be914e 100644 --- a/src/application/drivers_sample/uart/sample_uart_int_tx_int_rx_simultaneously/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_int_tx_int_rx_simultaneously/readme.md @@ -1,5 +1,5 @@ # UART-Tx和Rx在中断模式下收发数据 -## 关键字: UART, Tx_INT_Rx_INT收发数据 +## 关键字: UART, Tx_INT_Rx_INT收发数据 **【功能描述】** + UART全双工收发数据,实现UART全双工中断收发数据,中断写的过程中,可以进行中断读。 @@ -19,4 +19,7 @@ + 示例程序会不断的进行中断发送、接收,实现中断写的过程中,可以进行中断读。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_interrupt_rx/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_interrupt_rx/init/system_init.c index 8654f721affce411951181d2596c6a8e720d01d6..6f762ab24f343cc1aad9bcfc48c9893f53058a37 100644 --- a/src/application/drivers_sample/uart/sample_uart_interrupt_rx/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_interrupt_rx/init/system_init.c @@ -32,11 +32,9 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 48; /* PLL Multiplier 48 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -45,13 +43,6 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -__weak void UART0InterruptErrorCallback(void *handle) -{ - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ - /* USER CODE END UART0_TRNS_IT_ERROR */ -} - __weak void UART0WriteInterruptCallback(void *handle) { BASE_FUNC_UNUSED(handle); @@ -66,9 +57,17 @@ __weak void ReadFinish(void *handle) /* USER CODE END UART0_READ_IT_FINISH */ } +__weak void UART0InterruptErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ + /* USER CODE END UART0_TRNS_IT_ERROR */ +} + static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -79,34 +78,32 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_INTERRUPT; g_uart.rxMode = UART_MODE_INTERRUPT; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); - HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); HAL_UART_RegisterCallBack(&g_uart, UART_WRITE_IT_FINISH, UART0WriteInterruptCallback); HAL_UART_RegisterCallBack(&g_uart, UART_READ_IT_FINISH, ReadFinish); - + HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); IRQ_Register(IRQ_UART0, HAL_UART_IrqHandler, &g_uart); - IRQ_SetPriority(IRQ_UART0, 1); + IRQ_SetPriority(IRQ_UART0, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_UART0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/uart/sample_uart_interrupt_rx/readme.md b/src/application/drivers_sample/uart/sample_uart_interrupt_rx/readme.md index f7b47e89df0e27b7825926044682a48a3279433b..30ac193afd5b5a73c4b9cab0b7971c0bbabb2c1e 100644 --- a/src/application/drivers_sample/uart/sample_uart_interrupt_rx/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_interrupt_rx/readme.md @@ -1,5 +1,5 @@ # UART-中断模式接收数据 -## 关键字: UART, 中断模式接收 +## 关键字: UART, 中断模式接收 **【功能描述】** + UART以中断模式接收数据,数据接收完成将触发中断回调。 @@ -19,4 +19,7 @@ + UART完成接收后,会上报中断,可以在UART中断回调函数中从预设值的缓存中读到接收的数据。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_interrupt_tx/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_interrupt_tx/init/system_init.c index d5668746c668df198c0f2924ce2f037b5bd27ea0..68a2ef90ba9028be68bfc81861bd1210fc46943d 100644 --- a/src/application/drivers_sample/uart/sample_uart_interrupt_tx/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_interrupt_tx/init/system_init.c @@ -32,11 +32,9 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 48; /* PLL Multiplier 48 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -45,13 +43,6 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -__weak void UART0InterruptErrorCallback(void *handle) -{ - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ - /* USER CODE END UART0_TRNS_IT_ERROR */ -} - __weak void WriteFinish(void *handle) { BASE_FUNC_UNUSED(handle); @@ -66,9 +57,17 @@ __weak void UART0ReadInterruptCallback(void *handle) /* USER CODE END UART0_READ_IT_FINISH */ } +__weak void UART0InterruptErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ + /* USER CODE END UART0_TRNS_IT_ERROR */ +} + static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -79,40 +78,39 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_INTERRUPT; g_uart.rxMode = UART_MODE_INTERRUPT; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); - HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); HAL_UART_RegisterCallBack(&g_uart, UART_WRITE_IT_FINISH, WriteFinish); HAL_UART_RegisterCallBack(&g_uart, UART_READ_IT_FINISH, UART0ReadInterruptCallback); - + HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); IRQ_Register(IRQ_UART0, HAL_UART_IrqHandler, &g_uart); - IRQ_SetPriority(IRQ_UART0, 1); + IRQ_SetPriority(IRQ_UART0, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_UART0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); UART0_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_interrupt_tx/readme.md b/src/application/drivers_sample/uart/sample_uart_interrupt_tx/readme.md index 935b41429205d3ebfb9e29ab1c2493d36719deb0..c77ee4e2331bdd1c524ea79cab3e497631f458d1 100644 --- a/src/application/drivers_sample/uart/sample_uart_interrupt_tx/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_interrupt_tx/readme.md @@ -1,5 +1,5 @@ # UART-中断模式发送数据 -## 关键字: UART, 中断模式发送 +## 关键字: UART, 中断模式发送 **【功能描述】** + UART以中断模式发送数据,数据发送完成将触发中断回调。 @@ -17,4 +17,7 @@ + UART搬运结束后,会上报中断,可以在UART中断回调函数中加上标志位进行判断是否完成。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_interrupt_tx_after_rx/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_interrupt_tx_after_rx/init/system_init.c index b5e8bb2c9776b22729fd184d4212d08b6bd22ff9..5dbf4a16cb01c46b5c3bd46433cf64accd11ed49 100644 --- a/src/application/drivers_sample/uart/sample_uart_interrupt_tx_after_rx/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_interrupt_tx_after_rx/init/system_init.c @@ -32,11 +32,9 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 48; /* PLL Multiplier 48 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_2; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -45,13 +43,6 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) return BASE_STATUS_OK; } -__weak void UART0InterruptErrorCallback(void *handle) -{ - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ - /* USER CODE END UART0_TRNS_IT_ERROR */ -} - __weak void WriteCallBack(void *handle) { BASE_FUNC_UNUSED(handle); @@ -66,9 +57,17 @@ __weak void ReadCallBack(void *handle) /* USER CODE END UART0_READ_IT_FINISH */ } +__weak void UART0InterruptErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ + /* USER CODE END UART0_TRNS_IT_ERROR */ +} + static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart.baseAddress = UART0; @@ -79,40 +78,39 @@ static void UART0_Init(void) g_uart.txMode = UART_MODE_INTERRUPT; g_uart.rxMode = UART_MODE_INTERRUPT; g_uart.fifoMode = BASE_CFG_ENABLE; - g_uart.fifoTxThr = UART_FIFODEPTH_SIZE8; - g_uart.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart.hwFlowCtr = BASE_CFG_DISABLE; - g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; - g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart); - HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); HAL_UART_RegisterCallBack(&g_uart, UART_WRITE_IT_FINISH, WriteCallBack); HAL_UART_RegisterCallBack(&g_uart, UART_READ_IT_FINISH, ReadCallBack); - + HAL_UART_RegisterCallBack(&g_uart, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); IRQ_Register(IRQ_UART0, HAL_UART_IrqHandler, &g_uart); - IRQ_SetPriority(IRQ_UART0, 1); + IRQ_SetPriority(IRQ_UART0, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_UART0); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { IOConfig(); UART0_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_interrupt_tx_after_rx/readme.md b/src/application/drivers_sample/uart/sample_uart_interrupt_tx_after_rx/readme.md index 14690b45098585b50571dd0cb972b9e4fa3629bb..9e1caf7a879b96c0b408d44fcfa5082d5e51a013 100644 --- a/src/application/drivers_sample/uart/sample_uart_interrupt_tx_after_rx/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_interrupt_tx_after_rx/readme.md @@ -1,5 +1,5 @@ # UART-中断模式下环回发送数据 -## 关键字: UART, 中断模式环回发送 +## 关键字: UART, 中断模式环回发送 **【功能描述】** + 在中断模式下,当UART接收到对端发送数据时,又将刚接收到的数据发送到对端,整个过程接收和发送均会触发UART中断。 @@ -19,4 +19,7 @@ + 向串口0发送数据, 串口0会发送刚刚接收到的字符。 **【注意事项】** -+ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 \ No newline at end of file ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/inc/sample_uart_single_hardwire_communication.h b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/inc/sample_uart_single_hardwire_communication.h new file mode 100644 index 0000000000000000000000000000000000000000..899e04d69438f3abfa72141e7daa6d7b5cab451a --- /dev/null +++ b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/inc/sample_uart_single_hardwire_communication.h @@ -0,0 +1,37 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_uart_single_hardwire_communication.h + * @author MCU Driver Team + * @brief uart sample module. + * @details This file provides sample code for users to help use + * the single hardwire transmission of the UART in interrupt mode. + */ + +#ifndef SAMPLE_UART_SINGLE_HARDWIRE_COMMUNICATION +#define SAMPLE_UART_SINGLE_HARDWIRE_COMMUNICATION + +#include "uart.h" +#include "uart_ex.h" +#include "debug.h" +#include "interrupt.h" +#include "main.h" + +/* Function declaration */ +void UART_SingleHardWireCommunication(void); + +#endif \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/init/main.c b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..bc62a1ca25bafcd3bcfeeb1c0aa4e67ff6587c09 --- /dev/null +++ b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/init/main.c @@ -0,0 +1,50 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +#include "sample_uart_single_hardwire_communication.h" +/* USER CODE BEGIN 0 */ +/* USER CODE END 0 */ +UART_Handle g_uart; +/* USER CODE BEGIN 1 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* USER CODE END 2 */ + UART_SingleHardWireCommunication(); + /* USER CODE BEGIN 3 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/init/main.h b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..c92fcad5f0aae95f3b15293b35d2976c32fa2d1c --- /dev/null +++ b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/init/main.h @@ -0,0 +1,54 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..d5e8e3d5434488c83eb44ff30da8b14b00989919 --- /dev/null +++ b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/init/system_init.c @@ -0,0 +1,106 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_3; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_4; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock + frequency / (clk_1m_div + 1). 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart.baseAddress = UART0; + + g_uart.baudRate = UART0_BAND_RATE; + g_uart.dataLength = UART_DATALENGTH_8BIT; + g_uart.stopBits = UART_STOPBITS_ONE; + g_uart.parity = UART_PARITY_NONE; + g_uart.txMode = UART_MODE_BLOCKING; + g_uart.rxMode = UART_MODE_BLOCKING; + g_uart.fifoMode = BASE_CFG_ENABLE; + g_uart.fifoTxThr = UART_FIFODEPTH_SIZE4; + g_uart.fifoRxThr = UART_FIFODEPTH_SIZE4; + g_uart.hwFlowCtr = BASE_CFG_DISABLE; + g_uart.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart); +} + +static void IOConfig(void) +{ + /* Config PIN49 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_0_AS_JTAG_TCK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_0_AS_JTAG_TCK, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_0_AS_JTAG_TCK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_0_AS_JTAG_TCK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_0_AS_JTAG_TCK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN50 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_1_AS_JTAG_TMS); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_1_AS_JTAG_TMS, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_1_AS_JTAG_TMS, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_1_AS_JTAG_TMS, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_1_AS_JTAG_TMS, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/readme.md b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..365555d5d0ae8b6e3254767534c672f05d21c051 --- /dev/null +++ b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/readme.md @@ -0,0 +1,17 @@ +# UART-MCU单线通信 +## 关键字: UART, 单线通信 + +**【功能描述】** ++ UART单线通信,例程使用UART0的TX接口,通过该接口接受上位机发送过来的数据并将接收的数据打印至上位机,从而实现在单线上的数据接收和发送。 + +**【示例效果】** ++ 运行样例之后,查看串口0的信息,UART0会循环的发送和接收数据。 + +**【注意事项】** ++ 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 + ++ 此sample适用于单线实现UART的通讯功能,此时UART为半双工工作模式。 + ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 diff --git a/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/src/sample_uart_single_hardwire_communication.c b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/src/sample_uart_single_hardwire_communication.c new file mode 100644 index 0000000000000000000000000000000000000000..5b793c92b19be728135609a38bf8994030326d94 --- /dev/null +++ b/src/application/drivers_sample/uart/sample_uart_single_hardwire_communication/src/sample_uart_single_hardwire_communication.c @@ -0,0 +1,49 @@ + /** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_uart_single_wire_communication.c + * @author MCU Driver Team + * @brief uart sample module. + * @details In single-line communication, one line is used to achieve the TX and RX of the UART. + */ +#include "sample_uart_single_hardwire_communication.h" +#define BLOCKING_TIME 2000 + +/** + * @brief UART Tx and Rx simultaneously. + * @param None. + * @retval None. + */ +void UART_SingleHardWireCommunication(void) +{ + SystemInit(); + HAL_UART_SetLineModeEx(&g_uart, 1); /* 0:Full Duplex; 1:Hardwire half Duplex */ + unsigned char rxStr[20] = {0}; /* rxStr[20], Receive memory address */ + DBG_PRINTF(" UART single hardwire mode Init finish\r\n"); + unsigned int retRx; + while (1) { + BASE_FUNC_DELAY_MS(100); /* Wait 100 ms */ + retRx = HAL_UART_ReadBlocking(&g_uart, rxStr, 5, BLOCKING_TIME); /* 5 is data length, 2000 is timeout limit */ + if (retRx == BASE_STATUS_OK) { + DBG_PRINTF("Receive success: %s \r\n", rxStr); + } else if (retRx == BASE_STATUS_TIMEOUT) { + DBG_PRINTF("Receive time out!\r\n"); + } else { + DBG_PRINTF("Receive verification error!\r\n"); + } + } +} \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_single_wire_communication/init/system_init.c b/src/application/drivers_sample/uart/sample_uart_single_wire_communication/init/system_init.c index a844db244a0b41a42c1f70ee0b3d4f27cb672345..9011374ce863d12380624c9e503ed1c4faf8d571 100644 --- a/src/application/drivers_sample/uart/sample_uart_single_wire_communication/init/system_init.c +++ b/src/application/drivers_sample/uart/sample_uart_single_wire_communication/init/system_init.c @@ -22,10 +22,11 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 -#define UART1_BAND_RATE 800 -#define UART2_BAND_RATE 800 +#define UART1_BAND_RATE 115200 +#define UART2_BAND_RATE 115200 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { @@ -36,90 +37,80 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; - /* USER CODE BEGIN CRG ITCallBackFunc */ - /* USER CODE END CRG ITCallBackFunc */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; - /* USER CODE BEGIN crg system_init */ - /* USER CODE END crg system_init */ return BASE_STATUS_OK; } __weak void TIMER2CallbackFunction(void *handle) { - HAL_TIMER_IrqClear((TIMER_Handle *)handle); + DCL_TIMER_IrqClear((TIMER_RegStruct *)handle); /* USER CODE BEGIN TIMER2 ITCallBackFunc */ /* USER CODE END TIMER2 ITCallBackFunc */ } + static void TIMER2_Init(void) { - unsigned int load = HAL_CRG_GetIpFreq((void *)TIMER2) / 1000000u * 500; /* 500us timer counting period. */ + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER2) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 500; HAL_CRG_IpEnableSet(TIMER2_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(TIMER2_BASE, CRG_PLL_NO_PREDV); g_timer2.baseAddress = TIMER2; - g_timer2.irqNum = IRQ_TIMER2; - /* USER CODE BEGIN timer2 system_init */ - /* USER CODE END timer2 system_init */ + g_timer2.load = load - 1; /* Set timer value immediately */ g_timer2.bgLoad = load - 1; /* Set timer value */ g_timer2.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ g_timer2.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ g_timer2.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ - g_timer2.dmaAdcSingleReqEnable = BASE_CFG_DISABLE; - g_timer2.dmaBurstReqEnable = BASE_CFG_DISABLE; + g_timer2.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer2.dmaReqEnable = BASE_CFG_DISABLE; g_timer2.interruptEn = BASE_CFG_ENABLE; HAL_TIMER_Init(&g_timer2); - /* USER CODE BEGIN timer2 system_init */ - /* USER CODE END timer2 system_init */ - HAL_TIMER_RegisterCallback(&g_timer2, TIMER2CallbackFunction); /* Timer callback funtion register. */ - IRQ_SetPriority(g_timer2.irqNum, 1); - IRQ_EnableN(g_timer2.irqNum); + IRQ_Register(IRQ_TIMER2, HAL_TIMER_IrqHandler, &g_timer2); + HAL_TIMER_RegisterCallback(&g_timer2, TIMER_PERIOD_FIN, TIMER2CallbackFunction); + IRQ_SetPriority(IRQ_TIMER2, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER2); } static void UART0_Init(void) { HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - /* USER CODE BEGIN uart0 system_init */ - /* USER CODE END uart0 system_init */ + g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; - /* USER CODE BEGIN uart0 system_init */ - /* USER CODE END uart0 system_init */ + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; g_uart0.txMode = UART_MODE_BLOCKING; g_uart0.rxMode = UART_MODE_BLOCKING; - g_uart0.fifoMode = BASE_CFG_ENABLE; /* FIFO enable. */ + g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart0); - /* USER CODE BEGIN uart0 system_init */ - /* USER CODE END uart0 system_init */ } -__weak void UART1WriteInterruptCallback(UART_Handle *handle) +__weak void UART1WriteInterruptCallback(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN UART1_WRITE_IT_FINISH */ /* USER CODE END UART1_WRITE_IT_FINISH */ } -__weak void UART1ReadInterruptCallback(UART_Handle *handle) +__weak void UART1ReadInterruptCallback(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN UART1_READ_IT_FINISH */ /* USER CODE END UART1_READ_IT_FINISH */ } -__weak void UART1InterruptErrorCallback(UART_Handle *handle) +__weak void UART1InterruptErrorCallback(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN UART1_TRNS_IT_ERROR */ @@ -130,46 +121,47 @@ static void UART1_Init(void) { HAL_CRG_IpEnableSet(UART1_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(UART1_BASE, CRG_PLL_NO_PREDV); - /* USER CODE BEGIN uart1 system_init */ - /* USER CODE END uart1 system_init */ + /* Config uart param */ g_uart1.baseAddress = UART1; - g_uart1.irqNum = IRQ_UART1; - g_uart1.baudRate = UART1_BAND_RATE; /* Baud rate setting. */ + g_uart1.baudRate = UART1_BAND_RATE; /* Set baud rate is 115200 */ g_uart1.dataLength = UART_DATALENGTH_8BIT; g_uart1.stopBits = UART_STOPBITS_ONE; g_uart1.parity = UART_PARITY_NONE; + /* Set tx mode */ g_uart1.txMode = UART_MODE_INTERRUPT; + /* Set rx mode */ g_uart1.rxMode = UART_MODE_INTERRUPT; - g_uart1.fifoMode = BASE_CFG_DISABLE; /* FIFO disable. */ + g_uart1.fifoMode = BASE_CFG_DISABLE; g_uart1.fifoTxThr = UART_FIFOFULL_ONE_TWO; g_uart1.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart1.hwFlowCtr = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart1); - /* UART1 user callback register. */ + /* Config tx mode interupt */ HAL_UART_RegisterCallBack(&g_uart1, UART_WRITE_IT_FINISH, UART1WriteInterruptCallback); + /* Config rx mode interupt */ HAL_UART_RegisterCallBack(&g_uart1, UART_READ_IT_FINISH, UART1ReadInterruptCallback); HAL_UART_RegisterCallBack(&g_uart1, UART_TRNS_IT_ERROR, UART1InterruptErrorCallback); - HAL_UART_IRQService(&g_uart1); /* Interrupt Enable */ - IRQ_SetPriority(g_uart1.irqNum, 1); - IRQ_EnableN(g_uart1.irqNum); + IRQ_Register(IRQ_UART1, HAL_UART_IrqHandler, &g_uart1); + IRQ_SetPriority(IRQ_UART1, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_UART1); } -__weak void UART2WriteInterruptCallback(UART_Handle *handle) +__weak void UART2WriteInterruptCallback(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN UART2_WRITE_IT_FINISH */ /* USER CODE END UART2_WRITE_IT_FINISH */ } -__weak void UART2ReadInterruptCallback(UART_Handle *handle) +__weak void UART2ReadInterruptCallback(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN UART2_READ_IT_FINISH */ /* USER CODE END UART2_READ_IT_FINISH */ } -__weak void UART2InterruptErrorCallback(UART_Handle *handle) +__weak void UART2InterruptErrorCallback(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN UART2_TRNS_IT_ERROR */ @@ -180,80 +172,72 @@ static void UART2_Init(void) { HAL_CRG_IpEnableSet(UART2_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(UART2_BASE, CRG_PLL_NO_PREDV); - /* USER CODE BEGIN uart2 system_init */ - /* USER CODE END uart3 system_init */ + /* Config uart param */ g_uart2.baseAddress = UART2; - g_uart2.irqNum = IRQ_UART2; - g_uart2.baudRate = UART2_BAND_RATE; + g_uart2.baudRate = UART2_BAND_RATE; /* Set baud rate is 115200 */ g_uart2.dataLength = UART_DATALENGTH_8BIT; g_uart2.stopBits = UART_STOPBITS_ONE; g_uart2.parity = UART_PARITY_NONE; + /* Set tx mode */ g_uart2.txMode = UART_MODE_INTERRUPT; + /* Set rx mode */ g_uart2.rxMode = UART_MODE_INTERRUPT; - g_uart2.fifoMode = BASE_CFG_DISABLE; /* FIFO disable. */ + g_uart2.fifoMode = BASE_CFG_DISABLE; g_uart2.fifoTxThr = UART_FIFOFULL_ONE_TWO; g_uart2.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart2.hwFlowCtr = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart2); - /* UART2 user callback register */ + /* Config tx mode interupt */ HAL_UART_RegisterCallBack(&g_uart2, UART_WRITE_IT_FINISH, UART2WriteInterruptCallback); + /* Config rx mode interupt */ HAL_UART_RegisterCallBack(&g_uart2, UART_READ_IT_FINISH, UART2ReadInterruptCallback); HAL_UART_RegisterCallBack(&g_uart2, UART_TRNS_IT_ERROR, UART2InterruptErrorCallback); - /* USER CODE BEGIN uart2 system_init */ - /* USER CODE END uart2 system_init */ - HAL_UART_IRQService(&g_uart2); - IRQ_SetPriority(g_uart2.irqNum, 1); - IRQ_EnableN(g_uart2.irqNum); + IRQ_Register(IRQ_UART2, HAL_UART_IrqHandler, &g_uart2); + IRQ_SetPriority(IRQ_UART2, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_UART2); } -void IOConfig(void) +static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; /* Handle of ioconfig. */ SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_15.BIT.func = 0x4; /* 0x4 is UART1_TXD */ - iconfig->iocmg_15.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_15.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_15.BIT.pu = BASE_CFG_ENABLE; /* Pull-up resistor of UART1_Tx. */ - iconfig->iocmg_15.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_15.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_14.BIT.func = 0x4; /* 0x4 is UART1_RXD */ - iconfig->iocmg_14.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_14.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_14.BIT.pu = BASE_CFG_ENABLE; /* Pull-up resistor of UART1_Rx. */ - iconfig->iocmg_14.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_14.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_51.BIT.func = 0x3; /* 0x3 is UART2_TXD */ - iconfig->iocmg_51.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_51.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_51.BIT.pu = BASE_CFG_ENABLE; /* Pull-up resistor of UART1_Tx. */ - iconfig->iocmg_51.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_51.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_52.BIT.func = 0x3; /* 0x3 is UART2_RXD */ - iconfig->iocmg_52.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_52.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_52.BIT.pu = BASE_CFG_ENABLE; /* Pull-up resistor of UART2_Rx. */ - iconfig->iocmg_52.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_52.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO36_AS_UART2_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO36_AS_UART2_TXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO36_AS_UART2_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO36_AS_UART2_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO36_AS_UART2_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO37_AS_UART2_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO37_AS_UART2_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO37_AS_UART2_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO37_AS_UART2_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO37_AS_UART2_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO61_AS_UART1_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO61_AS_UART1_TXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO61_AS_UART1_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO61_AS_UART1_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO61_AS_UART1_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO60_AS_UART1_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO60_AS_UART1_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO60_AS_UART1_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO60_AS_UART1_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO60_AS_UART1_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) @@ -263,6 +247,7 @@ void SystemInit(void) UART1_Init(); UART2_Init(); TIMER2_Init(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/drivers_sample/uart/sample_uart_single_wire_communication/readme.md b/src/application/drivers_sample/uart/sample_uart_single_wire_communication/readme.md index 52ac5060c25103247c69212aca1fd268a7ec70e0..2b5459519b3546fb3366024b00c4ab6b072d6053 100644 --- a/src/application/drivers_sample/uart/sample_uart_single_wire_communication/readme.md +++ b/src/application/drivers_sample/uart/sample_uart_single_wire_communication/readme.md @@ -1,5 +1,5 @@ # UART-单线通信 -## 关键字: UART, 单线通信 +## 关键字: UART, 单线通信 **【功能描述】** + UART单线通信,使用一根线连接UART1和UART2的TX和RX,UART通过不断的切换接收和发送功能,从而实现在单线上的数据接收和发送。 @@ -25,4 +25,8 @@ **【注意事项】** + 串口通信的波特率,校验位等配置需保持一致,可以通过UART配置界面进行更改。 -+ 此sample适用于单线实现UART的通讯功能,此时UART为半双工工作模式。 \ No newline at end of file ++ 此sample适用于单线实现UART的通讯功能,此时UART为半双工工作模式。 + ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 diff --git a/src/application/drivers_sample/wdg/sample_iwdg_refresh/init/main.h b/src/application/drivers_sample/wdg/sample_iwdg_refresh/init/main.h index e063f5a7c3e94e10a41e24deac0d24c880bb46e2..8bd318b02cd2b978808833eeba08a145f97ca1aa 100644 --- a/src/application/drivers_sample/wdg/sample_iwdg_refresh/init/main.h +++ b/src/application/drivers_sample/wdg/sample_iwdg_refresh/init/main.h @@ -50,8 +50,6 @@ extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); -void IWDGCallbackFunction(void *handle); - /* USER CODE BEGIN 0 */ /* USER CODE */ /* USER CODE END 0 */ diff --git a/src/application/drivers_sample/wdg/sample_iwdg_refresh/init/system_init.c b/src/application/drivers_sample/wdg/sample_iwdg_refresh/init/system_init.c index 8ab0bc96e16515cd60048b34faa03a5303611ca2..225a4c59e7ea0e2181a012c9b4c31506526cff8e 100644 --- a/src/application/drivers_sample/wdg/sample_iwdg_refresh/init/system_init.c +++ b/src/application/drivers_sample/wdg/sample_iwdg_refresh/init/system_init.c @@ -36,9 +36,9 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.pllPostDiv = CRG_PLL_POSTDIV_2; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; - crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.clk1MDiv = (25 - 1); /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). 25 is - the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -49,7 +49,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ @@ -60,7 +60,7 @@ static void UART0_Init(void) g_uart0.txMode = UART_MODE_BLOCKING; /* blocking mode */ g_uart0.rxMode = UART_MODE_BLOCKING; g_uart0.fifoMode = BASE_CFG_ENABLE; - g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; /* fifo size 8 */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; /* fifo size 8 */ g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; @@ -68,16 +68,9 @@ static void UART0_Init(void) HAL_UART_Init(&g_uart0); } -__weak void IWDGCallbackFunction(void *handle) -{ - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN IWDG Callback */ - /* USER CODE END IWDG Callback */ -} - static void IWDG_Init(void) { - HAL_CRG_IpEnableSet(IWDG_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(IWDG_BASE, IP_CLK_ENABLE); /* IWDG clock enable. */ g_iwdg.baseAddress = IWDG; g_iwdg.timeValue = 1000; /* 1000 is time value */ g_iwdg.timeType = IWDG_TIME_UNIT_MS; diff --git a/src/application/drivers_sample/wdg/sample_iwdg_refresh/readme.md b/src/application/drivers_sample/wdg/sample_iwdg_refresh/readme.md index 615c26644f4fdb04c8ec30ba7f93916579445f21..ab0ec0be97b981be53cd346c37a4cdc27388bde8 100644 --- a/src/application/drivers_sample/wdg/sample_iwdg_refresh/readme.md +++ b/src/application/drivers_sample/wdg/sample_iwdg_refresh/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。串口打印testlog,如果喂狗生效,则不产生复位。否则系统复位,程序重新运行,循环往复。 **【注意事项】** -+ 在计数递减到窗口值前喂狗或计数到0没喂狗,均会产生复位操作。 \ No newline at end of file ++ 在计数递减到窗口值前喂狗或计数到0没喂狗,均会产生复位操作。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/wdg/sample_iwdg_reset/init/main.c b/src/application/drivers_sample/wdg/sample_iwdg_reset/init/main.c index a4147b1a459e4d391abac8d594b278b37914967d..d9a7892356eec87ba4f7f62400f31d942192eb1c 100644 --- a/src/application/drivers_sample/wdg/sample_iwdg_reset/init/main.c +++ b/src/application/drivers_sample/wdg/sample_iwdg_reset/init/main.c @@ -26,7 +26,7 @@ #include "main.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ -WDG_Handle g_iwdg; +IWDG_Handle g_iwdg; UART_Handle g_uart0; /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/src/application/drivers_sample/wdg/sample_iwdg_reset/init/main.h b/src/application/drivers_sample/wdg/sample_iwdg_reset/init/main.h index ef63367b0a147151bb939dd6559714472ee4d4a8..d973e66267caa6608e9d50633da1b43e59dc19a8 100644 --- a/src/application/drivers_sample/wdg/sample_iwdg_reset/init/main.h +++ b/src/application/drivers_sample/wdg/sample_iwdg_reset/init/main.h @@ -26,7 +26,7 @@ #include "uart.h" #include "crg.h" -#include "wdg.h" +#include "iwdg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U @@ -36,7 +36,12 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U -extern WDG_Handle g_iwdg; +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern IWDG_Handle g_iwdg; extern UART_Handle g_uart0; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); diff --git a/src/application/drivers_sample/wdg/sample_iwdg_reset/init/system_init.c b/src/application/drivers_sample/wdg/sample_iwdg_reset/init/system_init.c index bdeb90b4d7748650462b379d649931f45306aeb2..2cd532e11865bd9f86a14c2d02f6e903638b7a24 100644 --- a/src/application/drivers_sample/wdg/sample_iwdg_reset/init/system_init.c +++ b/src/application/drivers_sample/wdg/sample_iwdg_reset/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -47,7 +48,6 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; @@ -75,37 +75,32 @@ static void IWDG_Init(void) HAL_CRG_IpClkSelectSet(IWDG_BASE, CRG_PLL_NO_PREDV); g_iwdg.baseAddress = IWDG; - g_iwdg.irqNum = IRQ_IWDG; - g_iwdg.loadValue = 2000; /* 2000 is load value */ - g_iwdg.timeType = WDG_TIME_UNIT_MS; - g_iwdg.enableIT = BASE_CFG_DISABLE; - g_iwdg.enableRST = BASE_CFG_ENABLE; - HAL_WDG_Init(&g_iwdg); + g_iwdg.timeValue = 2000; /* 2000 is time value */ + g_iwdg.timeType = IWDG_TIME_UNIT_MS; + g_iwdg.enableIT = BASE_CFG_ENABLE; + HAL_IWDG_Init(&g_iwdg); - HAL_WDG_RegisterCallback(&g_iwdg, IwdgITCallBackFunc); /* Registering callback functions */ - HAL_WDG_IRQService(&g_iwdg); - IRQ_SetPriority(g_iwdg.irqNum, 1); - IRQ_EnableN(g_iwdg.irqNum); + HAL_IWDG_RegisterCallback(&g_iwdg, IwdgITCallBackFunc); + IRQ_Register(IRQ_IWDG, HAL_IWDG_IrqHandler, &g_iwdg); + IRQ_SetPriority(IRQ_IWDG, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_IWDG); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) { diff --git a/src/application/drivers_sample/wdg/sample_iwdg_reset/readme.md b/src/application/drivers_sample/wdg/sample_iwdg_reset/readme.md index 18d2e51eb7683e85e5aacfc2d612177178f71b45..6a454e13179b3ee79e1b8c6687f975c9d542ddd2 100644 --- a/src/application/drivers_sample/wdg/sample_iwdg_reset/readme.md +++ b/src/application/drivers_sample/wdg/sample_iwdg_reset/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。串口打印testlog,中断触发后打印中断log,如果在中断中调用喂狗操作,则不产生复位。否则第二次触发中断则系统复位,程序重新运行,循环往复。 **【注意事项】** -+ 若想不复位,可在第一次计数清零触发中断时喂狗,为喂狗窗口,该版IP实际超时复位时间为两倍计数值,第二次计数清零才复位。用户可在回调函数中清中断,清中断系统自动喂狗,导致复位功能失效,可降规作为timer使用。 \ No newline at end of file ++ 若想不复位,可在第一次计数清零触发中断时喂狗,为喂狗窗口,该版IP实际超时复位时间为两倍计数值,第二次计数清零才复位。用户可在回调函数中清中断,清中断系统自动喂狗,导致复位功能失效,可降规作为timer使用。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/wdg/sample_wdg_reset/init/main.h b/src/application/drivers_sample/wdg/sample_wdg_reset/init/main.h index c0bd46ff633b658a776663baf33e88653fd38cfe..8787fccf3df6c30692ac6bfb73338f59bbf4afa6 100644 --- a/src/application/drivers_sample/wdg/sample_wdg_reset/init/main.h +++ b/src/application/drivers_sample/wdg/sample_wdg_reset/init/main.h @@ -36,6 +36,11 @@ #define IO_DRV_LEVEL2 0x02U #define IO_DRV_LEVEL1 0x03U +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + extern WDG_Handle g_resetWdgHandler; extern UART_Handle g_uart0; diff --git a/src/application/drivers_sample/wdg/sample_wdg_reset/init/system_init.c b/src/application/drivers_sample/wdg/sample_wdg_reset/init/system_init.c index da647597df01e7774d0014840a190a7e5fdb0fc4..bf9f4d69d3cfb5abbe4334709cb511591d92377f 100644 --- a/src/application/drivers_sample/wdg/sample_wdg_reset/init/system_init.c +++ b/src/application/drivers_sample/wdg/sample_wdg_reset/init/system_init.c @@ -22,6 +22,7 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" #define UART0_BAND_RATE 115200 @@ -47,7 +48,7 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; + g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; @@ -70,40 +71,35 @@ __weak void WDG_CallbackFunc(void *handle) static void WDG_Init(void) { - HAL_CRG_IpEnableSet(WDG_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(WDG_BASE, IP_CLK_ENABLE); /* WDG Clock enable */ HAL_CRG_IpClkSelectSet(WDG_BASE, CRG_PLL_NO_PREDV); g_resetWdgHandler.baseAddress = WDG; - g_resetWdgHandler.irqNum = IRQ_WDG; - g_resetWdgHandler.loadValue = 2000; /* 2000: Interrupt Trigger Time */ + g_resetWdgHandler.timeValue = 2000; /* 2000 is time value */ g_resetWdgHandler.timeType = WDG_TIME_UNIT_MS; g_resetWdgHandler.enableIT = BASE_CFG_ENABLE; - g_resetWdgHandler.enableRST = BASE_CFG_ENABLE; HAL_WDG_Init(&g_resetWdgHandler); - /* Register callback functions to be defined by users. */ + HAL_WDG_RegisterCallback(&g_resetWdgHandler, WDG_CallbackFunc); - HAL_WDG_IRQService(&g_resetWdgHandler); - IRQ_SetPriority(g_resetWdgHandler.irqNum, 1); /* set gpio1 interrupt priority to 1, 1~7 */ - IRQ_EnableN(g_resetWdgHandler.irqNum); + IRQ_Register(IRQ_WDG, HAL_WDG_IrqHandler, &g_resetWdgHandler); + IRQ_SetPriority(IRQ_WDG, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_WDG); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/wdg/sample_wdg_reset/readme.md b/src/application/drivers_sample/wdg/sample_wdg_reset/readme.md index e583c6c8eca3a1c94333f22f036575545389f3be..c6f8638df0151ac66e1cd6991c34402f9dc21440 100644 --- a/src/application/drivers_sample/wdg/sample_wdg_reset/readme.md +++ b/src/application/drivers_sample/wdg/sample_wdg_reset/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。串口打印testlog,中断触发后打印中断log,如果在中断中调用喂狗操作,则不产生复位。否则第二次触发中断则系统复位,程序重新运行,循环往复。 **【注意事项】** -+ 若想不复位,可在第一次计数清零触发中断时喂狗,为喂狗窗口,该版IP实际超时复位时间为两倍计数值,第二次计数清零才复位。用户可在回调函数中清中断,清中断系统自动喂狗,导致复位功能失效,可降规作为timer使用。 \ No newline at end of file ++ 若想不复位,可在第一次计数清零触发中断时喂狗,为喂狗窗口,该版IP实际超时复位时间为两倍计数值,第二次计数清零才复位。用户可在回调函数中清中断,清中断系统自动喂狗,导致复位功能失效,可降规作为timer使用。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/main.c b/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/main.c index 432f16cf5e66ec8959ed36a97dab9fdfb264753b..3d8254aa4c10a9561c4bc969386dce372e9fa58b 100644 --- a/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/main.c +++ b/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/main.c @@ -22,6 +22,7 @@ #include "typedefs.h" #include "feature.h" +#include "sample_wwdg_refresh.h" #include "main.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ diff --git a/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/main.h b/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/main.h index 56ff9600a1f89bc365d8bce094fa01653beee0da..39b4ff8ef8d8e4135e645ffd361eabe12d042e84 100644 --- a/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/main.h +++ b/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/main.h @@ -25,8 +25,11 @@ #define McuMagicTag_SYSTEM_INIT_H #include "uart.h" +#include "uart_ex.h" #include "crg.h" #include "wwdg.h" +#include "wwdg_ex.h" +#include "iocmg.h" #define IO_SPEED_FAST 0x00U #define IO_SPEED_SLOW 0x01U diff --git a/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/system_init.c b/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/system_init.c index a692bc4c8f2d07de3b2b59d872ac15acb793e151..87b349e38c4b8794f12a228bb125ebebd060de16 100644 --- a/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/system_init.c +++ b/src/application/drivers_sample/wdg/sample_wwdg_refresh/init/system_init.c @@ -29,14 +29,16 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; - crg.baseAddress = CRG; /* crg baseaddress */ + crg.baseAddress = CRG; crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; crg.pllPreDiv = CRG_PLL_PREDIV_4; - crg.pllFbDiv = 32; /* PLL Multiplier 32 */ - crg.pllPostDiv = CRG_PLL_POSTDIV_1; - crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; - crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_1; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* CRG init */ return BASE_STATUS_ERROR; @@ -47,9 +49,8 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); - - g_uart0.baseAddress = UART0; /* uart0 baseaaddress */ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; g_uart0.baudRate = UART0_BAND_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; /* data length 8 */ @@ -75,14 +76,13 @@ __weak void WWDGCallbackFunction(void *handle) static void WWDG_Init(void) { - HAL_CRG_IpEnableSet(WWDG_BASE, IP_CLK_ENABLE); - + HAL_CRG_IpEnableSet(WWDG_BASE, IP_CLK_ENABLE); /* WWDG clock enable. */ g_wwdg.baseAddress = WWDG; g_wwdg.timeValue = 2000; /* wwdg time value 2000 */ g_wwdg.timeType = WWDG_TIME_UNIT_MS; g_wwdg.enableIT = BASE_CFG_ENABLE; - g_wwdg.freqDivValue = WWDG_FREQ_DIV_1024; + g_wwdg.freqDivValue = WWDG_FREQ_DIV_8192; g_wwdg.windowValue = 100; /* wwdg window value 100 */ HAL_WWDG_EnableWindowModeEx(&g_wwdg); HAL_WWDG_Init(&g_wwdg); @@ -90,23 +90,23 @@ static void WWDG_Init(void) /* wwdg interrput setting */ HAL_WWDG_RegisterCallback(&g_wwdg, WWDGCallbackFunction); IRQ_Register(IRQ_WWDG, HAL_WWDG_IrqHandler, &g_wwdg); - IRQ_SetPriority(IRQ_WWDG, 1); + IRQ_SetPriority(IRQ_WWDG, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_WWDG); } static void IOConfig(void) { - HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ - HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ } void SystemInit(void) diff --git a/src/application/drivers_sample/wdg/sample_wwdg_refresh/readme.md b/src/application/drivers_sample/wdg/sample_wwdg_refresh/readme.md index 3a3e7364d5621f4dc2a5c5c363376c7d52563f30..463fd9142411129b1f2fc21b968a0bd033ead608 100644 --- a/src/application/drivers_sample/wdg/sample_wwdg_refresh/readme.md +++ b/src/application/drivers_sample/wdg/sample_wwdg_refresh/readme.md @@ -15,4 +15,7 @@ + 当用户烧录编译后的示例代码后,初始化和配置完成后。串口打印testlog,中断触发后打印中断log,如果在中断中调用喂狗操作,则不产生复位。否则系统复位,程序重新运行,循环往复。 **【注意事项】** -+ 若想不复位,可在第一次计数到窗口值触发中断时喂狗,为喂狗窗口。用户可在回调函数中清中断,清中断系统自动喂狗,导致复位功能失效,可降规作为timer使用。 \ No newline at end of file ++ 若想不复位,可在第一次计数到窗口值触发中断时喂狗,为喂狗窗口。用户可在回调函数中清中断,清中断系统自动喂狗,导致复位功能失效,可降规作为timer使用。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_entry/function_safety_entry.c b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_entry/function_safety_entry.c new file mode 100644 index 0000000000000000000000000000000000000000..68eed9a9b4030730e4621f8386de9a314e40023b --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_entry/function_safety_entry.c @@ -0,0 +1,54 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_startup.c + * @author MCU Driver Team + * @brief function safety startup module. + * @details function safety startup interface implementation. + */ +#include "debug.h" +#include "main.h" +#include "function_safety_init.h" +#include "function_safety_startup.h" +#include "function_safety_runtime.h" +#include "function_safety_entry.h" + +/** + * @brief Excute function safety entry. + * @param None. + * @retval None. + */ +void FunctionSafetyEntry(void) +{ + SystemInit(); + DBG_PRINTF("*** Function Safety Startup Process Begin *** \r\n"); + FunctionSafetyStartupProcess(); + DBG_PRINTF("*** Function Safety Startup Process End*** \r\n"); + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + DBG_PRINTF("\r\n*** Function Safety Runtime Process Begin *** \r\n"); + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + HAL_WWDG_Refresh(g_diagnoseMonitor.wwdgHandle); + HAL_IWDG_Refresh(g_diagnoseMonitor.iwdgHandle); + FunctionSafetyRuntimeProcess(); + BASE_FUNC_DELAY_MS(50); /* 50 : delay time 50ms */ + /* USER CODE END 4 */ + } +} \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/arch/include/nos_306x_adapter.h b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_entry/function_safety_entry.h similarity index 84% rename from src/middleware/hisilicon/nostask/arch/include/nos_306x_adapter.h rename to src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_entry/function_safety_entry.h index 82d407149363423a8b5da4c12fece9b044192e5e..deebe3735cbf24e2f003c05d5e8341d63cc3477f 100644 --- a/src/middleware/hisilicon/nostask/arch/include/nos_306x_adapter.h +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_entry/function_safety_entry.h @@ -15,16 +15,15 @@ * 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. - * @file nos_306x_adapter.h + * @file function_safety_entry.h + * @author MCU Driver Team + * @brief function safety entry module. + * @details function safety entry interface declaration. */ -#ifndef NOS_306X_ADAPTER_H -#define NOS_306X_ADAPTER_H -#define CIPRI 0x7ED -#define PRITHD 0xBFE -#define TICK_IRQ_EN_BASE 0xBE0 -#define TICK_IRQ_EN_NUM 0x8 +#ifndef FUNCTION_SAFETY_ENTRY_H +#define FUNCTION_SAFETY_ENTRY_H -#define NOS_TASK_SWITCH_MAGIC_NUM 0xACBCCCDC +void FunctionSafetyEntry(void); #endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_init/function_safety_config.h b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_init/function_safety_config.h new file mode 100644 index 0000000000000000000000000000000000000000..ad6f5666182594901a90b65f592f9dc36a27274e --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_init/function_safety_config.h @@ -0,0 +1,49 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_config.h + * @author MCU Driver Team + * @brief This file contains the config of function safety + */ + +#ifndef FUNCTION_SAFETY_CONFIG_H +#define FUNCTION_SAFETY_CONFIG_H +/* ---------------------------------------- INCLUDE ----------------------------------- */ +/* ----------------------------------------PROCESS------------------------------------ */ +#define USE_FUNCTION_SAFETY_BENCHMARK +#define USE_FUNCTION_SAFETY_REPORT +/* ----------------------------------------RAM Test------------------------------------ */ +/* Parameters are used during the RAM test, performed using March-C Algorithm */ +#define BCKGRND_PATTERN 0x00000000U +#define INV_BCKGRND_PATTERN 0xFFFFFFFFU + +/* Constants necessary for execution initial March test */ +#define STARTUP_RAM_START ((unsigned int *)0x04000000U) +#define STARTUP_RAM_END ((unsigned int *)0x04008000U) + +/* Constants necessary for execution of transparent run time March tests */ +#define RUNTIME_RAM_START ((unsigned int *)0x04000000U) +#define RUNTIME_RAM_END ((unsigned int *)0x04008000U) + +/* ------------------------------------------ROM Test------------------------------------ */ +/* CRC checks the ROM region result */ +#define ROM_START ((unsigned int *)0x03000000U) +#define FLASH_BLOCK_SIZE_IN_WORD 4 +#define EFLASH_ECC_INT_ENABLE_VALUE 0x000C0000 +/* ------------------------------------------AIO Test------------------------------------ */ + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_init/function_safety_init.c b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_init/function_safety_init.c new file mode 100644 index 0000000000000000000000000000000000000000..a6380089e86c9429dd500314929bdc6e51de7ad1 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_init/function_safety_init.c @@ -0,0 +1,565 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_init.c + * @author MCU Driver Team + * @brief function safety library adapter layer init. + * @details function safety library adapter layer init interface. + */ +#include "main.h" +#include "debug.h" +#include "function_safety_config.h" +#include "function_safety_init.h" + +CORE_DiagnoseHandle g_diagnoseCore = {0}; +ANA_DiagnoseHandle g_diagnoseAna = {0}; +CLOCK_DiagnoseHandle g_diagnoseClock = {0}; +COMPUTE_DiagnoseHandle g_diagnoseCompute = {0}; +DIO_DiagnoseHandle g_diagnoseDio = {0}; +MONITOR_DiagnoseHandle g_diagnoseMonitor = {0}; +RAM_DiagnoseHandle g_diagnoseRam = {0}; +ROM_DiagnoseHandle g_diagnoseRom = {0}; +TIMERS_DiagnoseHandle g_diagnoseTimers = {0}; +CONNECT_DiagnoseHandle g_diagnoseConnect = {0}; +/*--------------------------------- analog diagnose enviroment init ----------------------------------------*/ +/** + * @brief ANA subsysterm's adc0 accuracy diagnose init. + * @param None. + * @retval None. + */ +void ANA_DiagnoseAdc0AccuracyInit(void) +{ + g_diagnoseAna.adcHandle = &DIAGNOSE_ADC0_HANDLE; + g_diagnoseAna.dacHandleRef = &g_dac0; /* dac output to adc */ + g_diagnoseAna.socx = DIAGNOSE_ADC0_SOC; + g_diagnoseAna.adcMaxRange = 4096; /* 4096 : max range of adc */ + g_diagnoseAna.dacMaxRange = 1024; /* 1024 : max range of dac */ + g_diagnoseAna.errRangePercent = 100; /* 100: adc value error range */ + DCL_ADC_SOCxSelectChannel(g_diagnoseAna.adcHandle->baseAddress, g_diagnoseAna.socx, DIAGNOSE_ADC0_CHANNEL); +} +/*--------------------------------- clock diagnose enviroment init ----------------------------------------*/ +/** + * @brief CLock subsysterm's systerm clock single accuracy diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseSysClockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's hosc clock single accuracy diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseHoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's losc clock single accuracy diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseLoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_LOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_0; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's tcxo clock accuracy single diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseTcxoCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_TCXO; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's systerm clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseSysClockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's hosc clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseHoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's losc clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseLoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_LOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_0; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's tcxo clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseTcxoCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_TCXO; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's pll ref clock accuracy single diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnosePllRefCLockStopInit(void) +{ + g_diagnoseClock.cfdHandle = &g_cfd; + g_diagnoseClock.cfdHandle->interruptType = CFD_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 100; /* 100: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 50; /* 50: cfd windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); + HAL_CFD_Stop(g_diagnoseClock.cfdHandle); /* stop cfd monitor clock stop */ + BASE_FUNC_DELAY_US(200); /* 200: wait cfd stable */ + CLOCK_CfdWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + IRQ_Unregister(IRQ_CFD); + IRQ_Register(IRQ_CFD, HAL_CFD_IrqHandler, g_diagnoseClock.cfdHandle); + IRQ_SetPriority(IRQ_CFD, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_CFD); + HAL_CFD_Init(g_diagnoseClock.cfdHandle); + HAL_CFD_Start(g_diagnoseClock.cfdHandle); /* start cfd monitor clock stop */ +} +/** + * @brief CLock subsysterm's pll ref clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnosePllRefCLockStopInit(void) +{ + g_diagnoseClock.cfdHandle = &g_cfd; + g_diagnoseClock.cfdHandle->interruptType = CFD_INT_PLL_REF_CLOCK_STOP_MASK; + g_diagnoseClock.errRangePercent = 50; /* 50: cfd windows value error range */ + HAL_CFD_Stop(g_diagnoseClock.cfdHandle); /* stop cfd monitor clock stop */ + BASE_FUNC_DELAY_US(200); /* 200: wait cfd stable */ + CLOCK_CfdWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + IRQ_Unregister(IRQ_CFD); + IRQ_Register(IRQ_CFD, HAL_CFD_IrqHandler, g_diagnoseClock.cfdHandle); + IRQ_SetPriority(IRQ_CFD, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_CFD); + HAL_CFD_Init(g_diagnoseClock.cfdHandle); + HAL_CFD_Start(g_diagnoseClock.cfdHandle); /* start cfd monitor clock stop */ + BASE_FUNC_DELAY_US(200); /* 200: wait clock stabilization */ +} +/*--------------------------------- compute diagnose enviroment init ----------------------------------------*/ +/** + * @brief Compute subsysterm's crc32 calculate correct diagnose init. + * @param None. + * @retval None. + */ +void COMPUTE_DiagnoseCrcInit(void) +{ + g_diagnoseCompute.crcHandle = &g_crc; + g_diagnoseCompute.inputTestData = 0xADDAA55A; /* 0xADDAA55A: input test data */ + g_diagnoseCompute.inputDataSize = 4; /* 4: 32bit width */ + g_diagnoseCompute.outputRefData = 0x89F75D91; /* 0x89F75D91: output ref data */ +} +/*--------------------------------- monitor diagnose enviroment init ----------------------------------------*/ +/** + * @brief Monitor subsysterm's wdg reset function diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseWdgResetInit(void) +{ + g_diagnoseMonitor.wwdgHandle = &g_wwdg; + g_diagnoseMonitor.startupResetTimeUs = 100; /* 100: wdg startup reset time interval */ + HAL_WWDG_Stop(g_diagnoseMonitor.wwdgHandle); /* stop wdg */ + DCL_WWDG_SetFreqDivValue(g_diagnoseMonitor.wwdgHandle->baseAddress, WWDG_FREQ_DIV_NONE); + HAL_WWDG_SetTimeValue(g_diagnoseMonitor.wwdgHandle, g_diagnoseMonitor.startupResetTimeUs, WWDG_TIME_UNIT_US); +} + +/** + * @brief Monitor subsysterm's wdg program stuck diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseWdgProgramStuckInit(void) +{ + g_diagnoseMonitor.wwdgHandle = &g_wwdg; + g_diagnoseMonitor.startupResetTimeUs = 1000000; /* 1000000: wdg runtime reset time interval */ + HAL_WWDG_Stop(g_diagnoseMonitor.wwdgHandle); /* stop wdg */ + DCL_WWDG_SetFreqDivValue(g_diagnoseMonitor.wwdgHandle->baseAddress, WWDG_FREQ_DIV_8192); + HAL_WWDG_SetTimeValue(g_diagnoseMonitor.wwdgHandle, g_diagnoseMonitor.startupResetTimeUs, WWDG_TIME_UNIT_US); + HAL_WWDG_Start(g_diagnoseMonitor.wwdgHandle); +} +/** + * @brief Monitor subsysterm's iwdg reset function diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseIwdgResetInit(void) +{ + g_diagnoseMonitor.iwdgHandle = &g_iwdg; + g_diagnoseMonitor.startupResetTimeUs = 100; /* 100: iwdg startup reset time interval */ + HAL_IWDG_Stop(g_diagnoseMonitor.iwdgHandle); /* stop iwdg */ + DCL_IWDG_SetFreqDivValue(g_diagnoseMonitor.iwdgHandle->baseAddress, IWDG_FREQ_DIV_NONE); + HAL_IWDG_SetTimeValue(g_diagnoseMonitor.iwdgHandle, g_diagnoseMonitor.startupResetTimeUs, IWDG_TIME_UNIT_US); +} + +/** + * @brief Monitor subsysterm's iwdg program stuck diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseIwdgProgramStuckInit(void) +{ + g_diagnoseMonitor.iwdgHandle = &g_iwdg; + g_diagnoseMonitor.startupResetTimeUs = 1000000; /* 1000000: iwdg runtime reset time interval */ + HAL_IWDG_Stop(g_diagnoseMonitor.iwdgHandle); /* stop iwdg */ + DCL_IWDG_SetFreqDivValue(g_diagnoseMonitor.iwdgHandle->baseAddress, IWDG_FREQ_DIV_256); + HAL_IWDG_SetTimeValue(g_diagnoseMonitor.iwdgHandle, g_diagnoseMonitor.startupResetTimeUs, IWDG_TIME_UNIT_US); + HAL_IWDG_Start(g_diagnoseMonitor.iwdgHandle); +} +/** + * @brief Monitor subsysterm's pmc voltage low power diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnosePmcLowPowerInit(void) +{ + g_diagnoseMonitor.pmcHandle = &g_pmc; /* monitor of pmc */ +} +/** + * @brief Monitor subsysterm's tsensor over temperature diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseTsensorOverTemperatureInit(void) +{ + g_diagnoseMonitor.overTemperatureValue = 90; /* 90: over temperature value */ + HAL_TSENSOR_Init(); +} +/*--------------------------------- ram diagnose enviroment init ----------------------------------------*/ +/** + * @brief Ram subsysterm's startup diagnose init. + * @param None. + * @retval None. + */ +void RAM_DiagnoseStartupInit(void) +{ + g_diagnoseRam.sramStartAddr = STARTUP_RAM_START; /* ram start address */ + g_diagnoseRam.sramCurrentAddr = STARTUP_RAM_START; /* rom current address */ + g_diagnoseRam.sramCurrentAddrInv = (unsigned int *)(~(unsigned int)(void*)g_diagnoseRam.sramCurrentAddr); + g_diagnoseRam.sramEndAddr = STARTUP_RAM_END; + g_diagnoseRam.sramPattern = BCKGRND_PATTERN; +} +/** + * @brief Ram subsysterm's runtime diagnose init. + * @param None. + * @retval None. + */ +void RAM_DiagnoseRuntimeInit(void) +{ + g_diagnoseRam.sramStartAddr = RUNTIME_RAM_START; /* ram start address */ + g_diagnoseRam.sramCurrentAddr = RUNTIME_RAM_START; /* rom current address */ + g_diagnoseRam.sramCurrentAddrInv = (unsigned int *)(~(unsigned int)(void*)g_diagnoseRam.sramCurrentAddr); + g_diagnoseRam.sramEndAddr = RUNTIME_RAM_END; + g_diagnoseRam.sramPattern = BCKGRND_PATTERN; +} +/*--------------------------------- rom diagnose enviroment init ----------------------------------------*/ +/** + * @brief Rom subsysterm's intgrity diagnose init. + * @param None. + * @retval None. + */ +void ROM_DiagnoseIntegrityInit(void) +{ + g_diagnoseRom.crcHandle = &g_crc; + g_diagnoseRom.startAddr = ROM_START; /* rom start address */ + g_diagnoseRom.indexPointer = ROM_START; /* rom end address */ + g_diagnoseRom.indexPointerInv = (unsigned int *)(~(unsigned int)(void*)ROM_START); + g_diagnoseRom.flashBlockSizeInWords = FLASH_BLOCK_SIZE_IN_WORD; +} +/** + * @brief Rom subsysterm's flash ecc diagnose init. + * @param None. + * @retval None. + */ +void ROM_DiagnoseFlashEccInit(void) +{ + g_diagnoseRom.flashBase = EFC; /* ecc function in eflash reg */ + g_diagnoseRom.eccIntRegVal = EFLASH_ECC_INT_ENABLE_VALUE; +} +/*--------------------------------- timers diagnose enviroment init ----------------------------------------*/ +/** + * @brief Timers subsysterm's timer0 interrupt interval diagnose init. + * @param None. + * @retval None. + */ +void TIMERS_DiagnoseTimer0InterruptIntervalInit(void) +{ + g_diagnoseTimers.timerHandle = &g_timer0; + g_diagnoseTimers.setTimeUs = 1000; /* 1000: timer interval */ + g_diagnoseTimers.errRangeUs = 1; /* 1: 1us error range */ + g_diagnoseTimers.timerHandle->load = (HAL_CRG_GetIpFreq((void *)TIMER0) / 1000000u) * g_diagnoseTimers.setTimeUs; + g_diagnoseTimers.timerHandle->bgLoad = g_diagnoseTimers.timerHandle->load; + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_LOAD); /* config load time */ + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_BGLOAD); /* config bgload time */ + g_diagnoseTimers.pretimeCycle = BASE_FUNC_GetTick(); + HAL_TIMER_Start(g_diagnoseTimers.timerHandle); + BASE_FUNC_DELAY_US(1500); /* 1500 : wait timer interrupt */ +} +/** + * @brief Timers subsysterm's timer1 interrupt interval diagnose init. + * @param None. + * @retval None. + */ +void TIMERS_DiagnoseTimer1InterruptIntervalInit(void) +{ + g_diagnoseTimers.timerHandle = &g_timer1; + g_diagnoseTimers.setTimeUs = 1000; /* 1000: timer interval */ + g_diagnoseTimers.errRangeUs = 1; /* 1: 1us error range */ + g_diagnoseTimers.timerHandle->load = (HAL_CRG_GetIpFreq((void *)TIMER1) / 1000000u) * g_diagnoseTimers.setTimeUs; + g_diagnoseTimers.timerHandle->bgLoad = g_diagnoseTimers.timerHandle->load; + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_LOAD); /* config load time */ + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_BGLOAD); /* config bgload time */ + g_diagnoseTimers.pretimeCycle = BASE_FUNC_GetTick(); + HAL_TIMER_Start(g_diagnoseTimers.timerHandle); + BASE_FUNC_DELAY_US(1500); /* 1500 : wait timer interrupt */ +} +/** + * @brief Timers subsysterm's timer2 interrupt interval diagnose init. + * @param None. + * @retval None. + */ +void TIMERS_DiagnoseTimer2InterruptIntervalInit(void) +{ + g_diagnoseTimers.timerHandle = &g_timer2; + g_diagnoseTimers.setTimeUs = 1000; /* 1000: timer interval */ + g_diagnoseTimers.errRangeUs = 1; /* 1: 1us error range */ + g_diagnoseTimers.timerHandle->load = (HAL_CRG_GetIpFreq((void *)TIMER2) / 1000000u) * g_diagnoseTimers.setTimeUs; + g_diagnoseTimers.timerHandle->bgLoad = g_diagnoseTimers.timerHandle->load; + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_LOAD); /* config load time */ + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_BGLOAD); /* config bgload time */ + g_diagnoseTimers.pretimeCycle = BASE_FUNC_GetTick(); + HAL_TIMER_Start(g_diagnoseTimers.timerHandle); + BASE_FUNC_DELAY_US(1500); /* 1500 : wait timer interrupt */ +} +/*--------------------------------- irq diagnose enviroment init ----------------------------------------*/ +/** + * @brief CFD check end callback function. + * @param handle @ref CFD_Handle. + * @retval None. + */ +void CFDCheckEndCallback(CFD_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cfdIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cfdClockCount = DCL_CFD_GetCntValue(g_diagnoseClock.cfdHandle->baseAddress); + HAL_CFD_Stop(g_diagnoseClock.cfdHandle); +} +/** + * @brief CFD clock stop callback function. + * @param handle @ref CFD_Handle. + * @retval None. + */ +void CFDClockStopCallback(CFD_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cfdIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cfdClockCount = DCL_CFD_GetCntValue(g_diagnoseClock.cfdHandle->baseAddress); +} +/** + * @brief CMM check end callback function. + * @param handle @ref CMM_Handle. + * @retval None. + */ +void CMMCheckEndCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cmmIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cmmClockCount = DCL_CMM_GetCntValue(g_diagnoseClock.cmmHandle->baseAddress); + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); +} +/** + * @brief CMM frequency error callback function. + * @param handle @ref CMM_Handle. + * @retval None. + */ +void CMMFreqErrorCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cmmIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cmmClockCount = DCL_CMM_GetCntValue(g_diagnoseClock.cmmHandle->baseAddress); +} +/** + * @brief PMC low poer callback function. + * @param handle @ref PMC_Handle. + * @retval None. + */ +void PMCPVDInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseMonitor.pmcIrqFlag = true; /* set irq flag */ +} + +/** + * @brief Timer0 interrupt callback function. + * @param handle @ref Timer_Handle. + * @retval None. + */ +void TIMER0CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseTimers.timerIrqFlag =true; /* set irq flag */ + g_diagnoseTimers.currenttimeCycle = BASE_FUNC_GetTick(); + /* duration cycle calculate */ + unsigned int durationCycle = (g_diagnoseTimers.currenttimeCycle > g_diagnoseTimers.pretimeCycle) ? \ + (g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle) : \ + (SYSTICK_MAX_VALUE + g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle + 1); + g_diagnoseTimers.durationUs = durationCycle / HAL_CRG_GetCoreClkFreq() / CRG_FREQ_1MHz; + g_diagnoseTimers.pretimeCycle = g_diagnoseTimers.currenttimeCycle; /* prepare for next calculate */ +} +/** + * @brief Timer1 interrupt callback function. + * @param handle @ref Timer_Handle. + * @retval None. + */ +void TIMER1CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseTimers.timerIrqFlag =true; /* set irq flag */ + g_diagnoseTimers.currenttimeCycle = BASE_FUNC_GetTick(); + /* duration cycle calculate */ + unsigned int durationCycle = (g_diagnoseTimers.currenttimeCycle > g_diagnoseTimers.pretimeCycle) ? \ + (g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle) : \ + (SYSTICK_MAX_VALUE + g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle + 1); + g_diagnoseTimers.durationUs = durationCycle / HAL_CRG_GetCoreClkFreq() / CRG_FREQ_1MHz; + g_diagnoseTimers.pretimeCycle = g_diagnoseTimers.currenttimeCycle; /* prepare for next calculate */ +} +/** + * @brief Timer2 interrupt callback function. + * @param handle @ref Timer_Handle. + * @retval None. + */ +void TIMER2CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseTimers.timerIrqFlag =true; /* set irq flag */ + g_diagnoseTimers.currenttimeCycle = BASE_FUNC_GetTick(); + /* duration cycle calculate */ + unsigned int durationCycle = (g_diagnoseTimers.currenttimeCycle > g_diagnoseTimers.pretimeCycle) ? \ + (g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle) : \ + (SYSTICK_MAX_VALUE + g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle + 1); + g_diagnoseTimers.durationUs = durationCycle / HAL_CRG_GetCoreClkFreq() / CRG_FREQ_1MHz; + g_diagnoseTimers.pretimeCycle = g_diagnoseTimers.currenttimeCycle; /* prepare for next calculate */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_init/function_safety_init.h b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_init/function_safety_init.h new file mode 100644 index 0000000000000000000000000000000000000000..69d57938f77f4c000480f713809edf9a1f014705 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_init/function_safety_init.h @@ -0,0 +1,67 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_init.h + * @author MCU Driver Team + * @brief function safety library adapter layer init. + * @details function safety library adapter layer init + */ + +#ifndef FUNCTION_SAFETY_INIT_H +#define FUNCTION_SAFETY_INIT_H + +#include "function_safety_mcu.h" +#include "function_safety_config.h" + +extern CORE_DiagnoseHandle g_diagnoseCore; +extern ANA_DiagnoseHandle g_diagnoseAna; +extern CLOCK_DiagnoseHandle g_diagnoseClock; +extern COMPUTE_DiagnoseHandle g_diagnoseCompute; +extern DIO_DiagnoseHandle g_diagnoseDio; +extern MONITOR_DiagnoseHandle g_diagnoseMonitor; +extern RAM_DiagnoseHandle g_diagnoseRam; +extern ROM_DiagnoseHandle g_diagnoseRom; +extern TIMERS_DiagnoseHandle g_diagnoseTimers; +extern CONNECT_DiagnoseHandle g_diagnoseConnect; + +void ANA_DiagnoseAdc0AccuracyInit(void); +void CLOCK_SingleDiagnoseSysClockAccuracyInit(void); +void CLOCK_SingleDiagnoseHoscCLockAccuracyInit(void); +void CLOCK_SingleDiagnoseLoscCLockAccuracyInit(void); +void CLOCK_SingleDiagnoseTcxoCLockAccuracyInit(void); +void CLOCK_ContinueDiagnoseSysClockAccuracyInit(void); +void CLOCK_ContinueDiagnoseHoscCLockAccuracyInit(void); +void CLOCK_ContinueDiagnoseLoscCLockAccuracyInit(void); +void CLOCK_ContinueDiagnoseTcxoCLockAccuracyInit(void); +void CLOCK_SingleDiagnosePllRefCLockStopInit(void); +void CLOCK_ContinueDiagnosePllRefCLockStopInit(void); +void COMPUTE_DiagnoseCrcInit(void); +void MONITOR_DiagnoseWdgResetInit(void); +void MONITOR_DiagnoseWdgProgramStuckInit(void); +void MONITOR_DiagnoseIwdgResetInit(void); +void MONITOR_DiagnoseIwdgProgramStuckInit(void); +void MONITOR_DiagnosePmcLowPowerInit(void); +void MONITOR_DiagnoseTsensorOverTemperatureInit(void); +void RAM_DiagnoseStartupInit(void); +void RAM_DiagnoseRuntimeInit(void); +void ROM_DiagnoseIntegrityInit(void); +void ROM_DiagnoseFlashEccInit(void); +void TIMERS_DiagnoseTimer0InterruptIntervalInit(void); +void TIMERS_DiagnoseTimer1InterruptIntervalInit(void); +void TIMERS_DiagnoseTimer2InterruptIntervalInit(void); + +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/include/nos_list_external.h b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_report/function_safety_report.c similarity index 33% rename from src/middleware/hisilicon/nostask/kernel/include/nos_list_external.h rename to src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_report/function_safety_report.c index 3f3b7a406cd7768a69fcd988829a11454f92abea..583f23d9742f980ad9d4d6043aee0be4b01e7ecd 100644 --- a/src/middleware/hisilicon/nostask/kernel/include/nos_list_external.h +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_report/function_safety_report.c @@ -15,95 +15,75 @@ * 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. - * @file nos_list_external.h + * @file function_safety_report.c + * @author MCU Driver Team + * @brief function safety report module. + * @details function safety report interface implementation. */ -#ifndef NOS_LIST_EXTERNAL_H -#define NOS_LIST_EXTERNAL_H -#include "os_typedef.h" - -struct TagListObject { - struct TagListObject *prev; - struct TagListObject *next; -}; - -/* - * @ingroup SREList - * 初始化链表(链表重用时的初始化) - * - * @param head [IN] 链表头结点的地址(The address of the head of a list ) - */ -#define OS_LIST_INIT(head) \ - do { \ - (head)->prev = (head); \ - (head)->next = (head); \ - } while (0) - -#define LIST_OBJECT_INIT(object) { \ - &(object), &(object) \ - } - -#define LIST_OBJECT(object) (struct TagListObject (object) = LIST_OBJECT_INIT(object)) - -#define OS_LIST_FIRST(object) ((object)->next) - -/* list action low level add */ -INLINE void ListLowLevelAdd(struct TagListObject *newNode, struct TagListObject *prev, - struct TagListObject *next) +#include "function_safety_report.h" +#include "debug.h" +#include "iocmg.h" +/** + * @brief rigister soft irq callback and prioerity , callback param. + * @param handlerFunc irq callback function. + * @param priority irq priority. + * @param param irq callback param. + * @retval None. + */ +void RegisterReportFailEventHandler(IRQ_PROC_FUNC handlerFunc, unsigned int priority, void *param) { - newNode->next = next; - newNode->prev = prev; - next->prev = newNode; - prev->next = newNode; + IRQ_DisableN(IRQ_SOFTWARE); + IRQ_Unregister(IRQ_SOFTWARE); /* unregister soft irq */ + IRQ_Register(IRQ_SOFTWARE, handlerFunc, param); /* register soft irq callback and param */ + IRQ_SetPriority(IRQ_SOFTWARE, priority); /* set soft irq priority */ + IRQ_EnableN(IRQ_SOFTWARE); } - -/* list action add */ -INLINE void ListAdd(struct TagListObject *newNode, struct TagListObject *listObject) +/** + * @brief soft irq callback of report fail event. + * @param param irq callback param. + * @retval None. + */ +void ReportFailEventLogBySoftIrq(void *param) { - ListLowLevelAdd(newNode, listObject, listObject->next); + BASE_FUNC_UNUSED(param); + DCL_SYSCTRL_ClearSoftInterrupt(); /* clear soft irq */ + IRQ_ClearN(IRQ_SOFTWARE); + IRQ_Disable(); + FunctionSafetyState failEvent = STATE_LoadFailEvent(); /* load fail event */ + DBG_PRINTF("Fail Event Info : FailEvent[0x%x], Subsysterm [%d], Module [%d], Feature [%d], Failtype [%d]\r\n", \ + failEvent, failEvent.BIT.subsysterm, failEvent.BIT.moudule, failEvent.BIT.feature, failEvent.BIT.faultType); } -/* list action tail add */ -INLINE void ListTailAdd(struct TagListObject *newNode, struct TagListObject *listObject) -{ - ListLowLevelAdd(newNode, listObject->prev, listObject); -} -/* list action lowel delete */ -INLINE void ListLowLevelDelete(struct TagListObject *prevNode, struct TagListObject *nextNode) +/** + * @brief Excute function safety process and return state. + * @param state @ref FunctionSafetyState. + * @param processTime @ref ProcessTimeCycle. + * @retval None. + */ +void FunctionSafetyProcessPrint(FunctionSafetyState state, ProcessTimeCycle processTime) { - if (prevNode == NULL || nextNode == NULL) { + if (!processTime.timeCycleRecordSwitch) { return; } - - nextNode->prev = prevNode; - prevNode->next = nextNode; -} - -/* list action delete */ -INLINE void ListDelete(struct TagListObject *node) -{ - ListLowLevelDelete(node->prev, node->next); - - node->next = NULL; - node->prev = NULL; -} - -/* list action empty */ -INLINE bool ListEmpty(const struct TagListObject *listObject) -{ - return (bool)(listObject->next == listObject); -} - -#define OFFSET_OF_FIELD(type, field) ((uintptr_t)((uintptr_t)(&((type *)0x10)->field) - (uintptr_t)0x10)) - -#define COMPLEX_OF(ptr, type, field) ((type *)((uintptr_t)(ptr) - OFFSET_OF_FIELD(type, field))) - -/* 根据成员地址得到控制块首地址, ptr成员地址, type控制块结构, field成员名 */ -#define LIST_COMPONENT(ptrOfList, typeOfList, fieldOfList) COMPLEX_OF(ptrOfList, typeOfList, fieldOfList) - -#define LIST_FOR_EACH(posOfList, listObject, typeOfList, field) \ - for ((posOfList) = LIST_COMPONENT((listObject)->next, typeOfList, field); &(posOfList)->field != (listObject); \ - (posOfList) = LIST_COMPONENT((posOfList)->field.next, typeOfList, field)) - -#endif /* NOS_LIST_EXTERNAL_H */ + if (state.BIT.result == RESULT_FAIL) { /* result fail judgement */ + DBG_PRINTF("\r\nFAIL info : State[0x%x], Subsysterm[%d], Module[%d], Feature[%d], Failtype[%d] \ + \r\n DiagnoseCycle[%d], FailSafeCycle[%d], FaultPredictCycle[%d]\r\n", \ + state, state.BIT.subsysterm, state.BIT.moudule, state.BIT.feature, state.BIT.faultType, \ + processTime.diagnoseTimeCycle, processTime.failSafeTimeCycle, processTime.faultPredictTimeCycle); + } else { + if (state.BIT.result == RESULT_SUCCESS) { /* result success judgement */ + DBG_PRINTF("\r\nSUCCESS info : State [0x%x], Subsysterm [%d], Module [%d], Feature [%d] \ + \r\n DiagnoseCycle[%d], FailSafeCycle[%d], FaultPredictCycle[%d]\r\n", \ + state, state.BIT.subsysterm, state.BIT.moudule, state.BIT.feature,\ + processTime.diagnoseTimeCycle, processTime.failSafeTimeCycle, processTime.faultPredictTimeCycle); + } + if (state.BIT.result == RESULT_IS_RUNNING) { /* result ongoing judgement */ + DBG_PRINTF("\r\nRUNNING info : State [0x%x], Subsysterm [%d], Module [%d], Feature [%d] \ + \r\n DiagnoseCycle[%d], FailSafeCycle[%d], FaultPredictCycle[%d]\r\n", \ + state, state.BIT.subsysterm, state.BIT.moudule, state.BIT.feature,\ + processTime.diagnoseTimeCycle, processTime.failSafeTimeCycle, processTime.faultPredictTimeCycle); + } + } +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_report/function_safety_report.h b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_report/function_safety_report.h new file mode 100644 index 0000000000000000000000000000000000000000..ecbe454705446846726f3a4568565be3056fa8a4 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_report/function_safety_report.h @@ -0,0 +1,43 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_report.h + * @author MCU Driver Team + * @brief function safety report module. + * @details function safety report interface declaration. + */ + +#ifndef FUNCTION_SAFETY_REPORT_H +#define FUNCTION_SAFETY_REPORT_H + +#include "function_safety_mcu.h" + +/** + * @brief Triggle soft irq send fail event. + * @param None. + * @retval None. + */ +static inline void TriggerSoftIrqSendFailEvent(void) +{ + return DCL_SYSCTRL_GenerateSoftInterrupt(); +} + +void RegisterReportFailEventHandler(IRQ_PROC_FUNC handlerFunc, unsigned int priority, void *param); +void ReportFailEventLogBySoftIrq(void *param); +void FunctionSafetyProcessPrint(FunctionSafetyState state, ProcessTimeCycle processTime); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_runtime/function_safety_runtime.c b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_runtime/function_safety_runtime.c new file mode 100644 index 0000000000000000000000000000000000000000..3a2713c02a004ecc3ec1e8c4c5f09ff871a25c62 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_runtime/function_safety_runtime.c @@ -0,0 +1,109 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_runtime.c + * @author MCU Driver Team + * @brief function safety runtime module. + * @details function safety runtime interface implementation. + */ +#include "main.h" +#include "function_safety_init.h" +#include "function_safety_process.h" +#include "function_safety_report.h" +#include "function_safety_runtime.h" + +FunctionSafetyProcessHandle g_fuSaRuntimeProcess[] = { + { + .diagnoseFunc = CORE_DiagnoseCpuStatus, /* cpu status diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = CORE_DiagnoseCpuGeneralRegister, /* cpu general register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = CORE_DiagnosePcRegister, /* cpu pc register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_RUNTIME + }, + { + .handleConfigFunc = RAM_DiagnoseRuntimeInit, /* ram step diagnose */ + .diagnoseFunc = RAM_DiagnoseSramByMarchAlgorithm, + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = RAM_DiagnoseSramByParityCheck, /* ram parity diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = RAM_DiagnoseStackOverflow, /* ram stack overflow diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_RUNTIME + }, +#if defined(CRC) + { + .handleConfigFunc = ROM_DiagnoseIntegrityInit, /* rom intergrity diagnose */ + .diagnoseFunc = ROM_DiagnoseIntegrity, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_RUNTIME + }, +#endif +#if defined(EFC) + { + .handleConfigFunc = ROM_DiagnoseFlashEccInit, /* flash ecc diagnose */ + .diagnoseFunc = ROM_DiagnoseFlashEcc, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_RUNTIME + }, +#endif +}; +/* runtime function safety iterm size */ +const unsigned int RUNTIME_PROCESS_ARRAY_SIZE = sizeof(g_fuSaRuntimeProcess) / sizeof(g_fuSaRuntimeProcess[0]); + +/** + * @brief Excute run time function safety iterm. + * @param None. + * @retval None. + */ +void FunctionSafetyRuntimeProcess(void) +{ + FunctionSafetyState state = {0}; + ProcessTimeCycle processTime = {0}; + processTime.timeCycleRecordSwitch = true; + /* excute runtime function safety iterm one by one */ + for (unsigned int i = 0; i < RUNTIME_PROCESS_ARRAY_SIZE; ++i) { + state = FunctionSafetyProcess(&g_fuSaRuntimeProcess[i], &processTime); + if (state.BIT.result == RESULT_FAIL) { + TriggerSoftIrqSendFailEvent(); /* trigger soft interrupt to notify application */ + } + if (processTime.timeCycleRecordSwitch) { + FunctionSafetyProcessPrint(state, processTime); + } + } +} \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/nos_sys_init.c b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_runtime/function_safety_runtime.h similarity index 81% rename from src/middleware/hisilicon/nostask/kernel/nos_sys_init.c rename to src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_runtime/function_safety_runtime.h index 7433fac828c48c0a43d903656639caff86da03d7..45ae4296064abe98d3e7ba319fae2e3881b62298 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_sys_init.c +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_runtime/function_safety_runtime.h @@ -15,24 +15,15 @@ * 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. - * @file nos_sys_init.c + * @file function_safety_runtime.h + * @author MCU Driver Team + * @brief function safety runtime module. + * @details function safety runtime interface declaration. */ -#include "nos_sys_external.h" -GetTickFunc g_sreGetTickFunc; +#ifndef FUNCTION_SAFETY_RUNTIME_H +#define FUNCTION_SAFETY_RUNTIME_H -void NOS_SetNosParam(GetTickFunc func) -{ - /* set GetTickFunc */ - g_sreGetTickFunc = func; -} +void FunctionSafetyRuntimeProcess(void); -unsigned long long NOS_GetCurTick(void) -{ - if (g_sreGetTickFunc == NULL) { - return 0; - } - - /* execution GetTickFunc */ - return g_sreGetTickFunc(); -} \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_startup/function_safety_startup.c b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_startup/function_safety_startup.c new file mode 100644 index 0000000000000000000000000000000000000000..abdaea321dc1bec84fd7e4956d7a3a40e6f6ba75 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_startup/function_safety_startup.c @@ -0,0 +1,205 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_startup.c + * @author MCU Driver Team + * @brief function safety startup module. + * @details function safety startup interface implementation. + */ +#include "main.h" +#include "function_safety_init.h" +#include "function_safety_process.h" +#include "function_safety_report.h" +#include "function_safety_startup.h" + +FunctionSafetyProcessHandle g_fuSaStartupProcess[] = { + { + .diagnoseFunc = CORE_DiagnoseCpuStatus, /* cpu status diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = CORE_DiagnoseCpuGeneralRegister, /* cpu general register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = CORE_DiagnoseCpuSoftwareIrq, /* cpu soft irq diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = CORE_DiagnosePcRegister, /* cpu pc register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = RAM_DiagnoseStartupInit, /* ram marchx diagnose */ + .diagnoseFunc = RAM_DiagnoseSramByMarchAlgorithm, + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = RAM_DiagnoseSramByParityCheck, /* ram parity diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = RAM_DiagnoseStackOverflow, /* ram stack overflow diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = CLOCK_SingleDiagnoseSysClockAccuracyInit, /* systerm clock single diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_SingleDiagnoseHoscCLockAccuracyInit, /* hosc clock single diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_SingleDiagnoseLoscCLockAccuracyInit, /* losc clock single diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_ContinueDiagnoseSysClockAccuracyInit, /* systerm clock continue diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = COMPUTE_DiagnoseCrcInit, /* crc calculate correct diagnose */ + .diagnoseFunc = COMPUTE_DiagnoseCrcAlgorithmCorrect, + .failSafeFunc = COMPUTE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCompute, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = ROM_DiagnoseIntegrityInit, /* rom integrity diagnose */ + .diagnoseFunc = ROM_DiagnoseIntegrity, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = ROM_DiagnoseFlashEccInit, /* rom flash ecc diagnose */ + .diagnoseFunc = ROM_DiagnoseFlashEcc, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = TIMERS_DiagnoseTimer0InterruptIntervalInit, /* timer0 interrupt interval diagnose */ + .diagnoseFunc = TIMERS_DiagnoseInterruptIntervalAccuracy, + .failSafeFunc = TIMERS_FailSafeHandler, + .diagnoseHandle = &g_diagnoseTimers, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = TIMERS_DiagnoseTimer1InterruptIntervalInit, /* timer1 interrupt interval diagnose */ + .diagnoseFunc = TIMERS_DiagnoseInterruptIntervalAccuracy, + .failSafeFunc = TIMERS_FailSafeHandler, + .diagnoseHandle = &g_diagnoseTimers, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = TIMERS_DiagnoseTimer2InterruptIntervalInit, /* timer2 interrupt interval diagnose */ + .diagnoseFunc = TIMERS_DiagnoseInterruptIntervalAccuracy, + .failSafeFunc = TIMERS_FailSafeHandler, + .diagnoseHandle = &g_diagnoseTimers, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = ANA_DiagnoseAdc0AccuracyInit, /* adc0 accuracy diagnose */ + .diagnoseFunc = ANA_DiagnoseAdcSampleAccuracy, + .failSafeFunc = ANA_FailSafeHandler, + .diagnoseHandle = &g_diagnoseAna, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = MONITOR_DiagnosePmcLowPowerInit, /* pmc low power diagnose */ + .diagnoseFunc = MONITOR_DiagnosePowerLowLevelByPmc, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + }, + { + .handleConfigFunc = MONITOR_DiagnoseTsensorOverTemperatureInit, /* tsensor over temperature diagnose */ + .diagnoseFunc = MONITOR_DiagnoseOverTemperatureByTsensor, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + }, + { + .handleConfigFunc = MONITOR_DiagnoseWdgProgramStuckInit, /* wdg program stuck diagnose */ + .diagnoseFunc = MONITOR_DiagnoseProgramStuckByWdg, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + }, + { + .handleConfigFunc = MONITOR_DiagnoseIwdgProgramStuckInit, /* iwdg program stuck diagnose */ + .diagnoseFunc = MONITOR_DiagnoseProgramStuckByIwdg, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + } +}; +/* startup function safety iterm size */ +const unsigned int STARTUP_PROCESS_ARRAY_SIZE = sizeof(g_fuSaStartupProcess) / sizeof(g_fuSaStartupProcess[0]); + +/** + * @brief Excute startup function safety iterm. + * @param None. + * @retval None. + */ +void FunctionSafetyStartupProcess(void) +{ + FunctionSafetyState state = {0}; + ProcessTimeCycle processTime = {0}; + processTime.timeCycleRecordSwitch = true; + /* excute startup function safety iterm one by one */ + for (unsigned int i = 0; i < STARTUP_PROCESS_ARRAY_SIZE; ++i) { + state = FunctionSafetyProcess(&g_fuSaStartupProcess[i], &processTime); + if (state.BIT.moudule == MODULE_CPU_SOFT_INTTERRUPT && state.BIT.subsysterm == SUBSYS_CORE) { + RegisterReportFailEventHandler(ReportFailEventLogBySoftIrq, 3, NULL); /* 3: interrupt priority */ + } + if (i >= 3 && state.BIT.result == RESULT_FAIL) { /* 3 : wait soft interrupt enable and register callback */ + TriggerSoftIrqSendFailEvent(); /* trigger soft interrupt to notify application */ + } + if (processTime.timeCycleRecordSwitch) { + FunctionSafetyProcessPrint(state, processTime); + } + } +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_startup/function_safety_startup.h b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_startup/function_safety_startup.h new file mode 100644 index 0000000000000000000000000000000000000000..d2caa12619089a1068fa06b2550bdf7b65f8a0a2 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/function_safety_startup/function_safety_startup.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_startup.h + * @author MCU Driver Team + * @brief function safety startup module. + * @details function safety startup interface declaration. + */ + +#ifndef FUNCTION_SAFETY_STARTUP_H +#define FUNCTION_SAFETY_STARTUP_H + +void FunctionSafetyStartupProcess(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/feature.h b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/feature.h new file mode 100644 index 0000000000000000000000000000000000000000..d8b5fac4d9357a1e117bbef0f43eb49253a7ba20 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/feature.h @@ -0,0 +1,120 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file feature.h + * @author MCU Driver Team + * @brief This file contains macro configurations related to the project. This file is generated by the IDE tool. + */ + +#ifndef McuMagicTag_FEATURE_H +#define McuMagicTag_FEATURE_H + +/* Macro definitions --------------------------------------------------------- */ +#define CHIP_3061MNPICA MACRO_ENABLE + +#define MACRO_ENABLE 1 +#define MACRO_DISABLE 0 + +/* Macro switch */ +#define BASE_DEFINE_USE_ASSERT MACRO_ENABLE +#ifndef FLASH_CRC_CONFIG +#define FLASH_CRC_CONFIG +#endif /* #ifndef FLASH_CRC_CONFIG */ +#define BASE_MATH_SINCOS_MIDDLE_TABLE MACRO_ENABLE /**< This macro is used to control the table type when the + BASE_MATH_GetSinCos() queries the table. When the value of + this macro is MACRO_ENABLE, the error value obtained by the + BASE_MATH_GetSinCos() is relatively small, and the return + value of the function may be greater than or less than the + actual value. When the value of this macro is MACRO_DISABLE, + the error value obtained by the BASE_MATH_GetSinCos() is + relatively large. However, in the range [0°, 180°) and + [180°, 360°), the return value of the function is either + greater than or less than the actual value. */ + +#define MCS_PARAM_CHECK MACRO_ENABLE +#define APT_PARAM_CHECK MACRO_ENABLE +#define ADC_PARAM_CHECK MACRO_ENABLE +#define CAPM_PARAM_CHECK MACRO_ENABLE +#define CRG_PARAM_CHECK MACRO_ENABLE +#define I2C_PARAM_CHECK MACRO_ENABLE +#define UART_PARAM_CHECK MACRO_ENABLE +#define SPI_PARAM_CHECK MACRO_ENABLE +#define TIMER_PARAM_CHECK MACRO_ENABLE +#define IWDG_PARAM_CHECK MACRO_ENABLE +#define WWDG_PARAM_CHECK MACRO_ENABLE +#define GPIO_PARAM_CHECK MACRO_ENABLE +#define GPT_PARAM_CHECK MACRO_ENABLE +#define DMA_PARAM_CHECK MACRO_ENABLE +#define CRC_PARAM_CHECK MACRO_ENABLE +#define CFD_PARAM_CHECK MACRO_ENABLE +#define CMM_PARAM_CHECK MACRO_ENABLE +#define CAN_PARAM_CHECK MACRO_ENABLE +#define FLASH_PARAM_CHECK MACRO_ENABLE +#define PMC_PARAM_CHECK MACRO_ENABLE +#define ACMP_PARAM_CHECK MACRO_ENABLE +#define DAC_PARAM_CHECK MACRO_ENABLE +#define PGA_PARAM_CHECK MACRO_ENABLE +#define USER_MODE_ENABLE MACRO_ENABLE +#define IOCMG_PARAM_CHECK MACRO_ENABLE +#define QDM_PARAM_CHECK MACRO_ENABLE + +/* Peripheral module macro switch--------------------------------------------- */ +#define BOARD_DIM_NUM 1 /**< Number of dimming handle arrays. */ + +#define BOARD_KEY_NUM 10 /**< Number of key handle arrays. */ +#define BOARD_KEY_PRESS_ON GPIO_HIGH_LEVEL /**< GPIO status corresponding to long press valid. */ +#define BOARD_KEY_PRESS_OFF GPIO_LOW_LEVEL /**< GPIO status corresponding to short press valid. */ + +#define BOARD_LED_SEG_NUM 4 /**< Number of segments. */ +#define BOARD_LED_SEGMENT_ON GPIO_HIGH_LEVEL /**< GPIO level status corresponding to valid segments. */ +#define BOARD_LED_SEGMENT_OFF GPIO_LOW_LEVEL /**< GPIO level status corresponding to invalid segments. */ + +#define BOARD_MKEY_SCHEME_NUMBER BOARD_MKEY_SCHEME_NUMBER_ONE /**< Define the scheme to be adopted. */ +#define BOARD_MKEY_OUT_NUM 4 /**< Number of GPIO pins used as output during scanning. */ +#define BOARD_MKEY_IN_NUM 4 /**< Number of GPIO pins used as input during scanning. */ +#define BOARD_MKEY_OUT_PIN_VALID GPIO_LOW_LEVEL /**< GPIO level status corresponding to the valid \ + status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_OUT_PIN_INVALID GPIO_HIGH_LEVEL /**< GPIO level status corresponding to the \ + invalid status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_VALID GPIO_LOW_LEVEL /**< Indicates the GPIO level corresponding to the \ + valid status of the input GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_INVALID GPIO_HIGH_LEVEL /**< Indicates the GPIO level corresponding to the \ + invalid status of the input GPIO in the key matrix. */ + +#define BOARD_PULSES_NUM 2 /**< Number of pulse handles. */ + +#define BASE_DEFINE_SLIPAVERAGE_NUM 2 /**< Sliding average array length. */ + +#define LISTNODE_MAX 20 + +#define BASE_DEFINE_DMA_QUICKSTART + +#define XTRAIL_FREQ 30000000U + +#define DBG_USE_NO_PRINTF 0U +#define DBG_USE_UART_PRINTF 1U + +#define DBG_PRINTF_USE DBG_USE_UART_PRINTF +#if (DBG_PRINTF_USE == DBG_USE_UART_PRINTF) +#define DBG_PRINTF_UART_PORT UART0 +#endif + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_FEATURE_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/main.c b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..a28e917be93a84a24e5fe2629b7e8dcdbf3fd940 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/main.c @@ -0,0 +1,66 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +#include "function_safety_entry.h" +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +CFD_Handle g_cfd; +CMM_Handle g_cmm; +CRC_Handle g_crc; +PMC_Handle g_pmc; +WWDG_Handle g_wwdg; +DAC_Handle g_dac0; +TIMER_Handle g_timer0; +TIMER_Handle g_timer1; +TIMER_Handle g_timer2; +UART_Handle g_uart0; +ADC_Handle g_adc0; +IWDG_Handle g_iwdg; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + FunctionSafetyEntry(); + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/main.h b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..61dd88c81d84702ba3e79e9804f6f2c2cc08a2ae --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/main.h @@ -0,0 +1,95 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "adc.h" +#include "adc_ex.h" +#include "uart.h" +#include "uart_ex.h" +#include "crc.h" +#include "cfd.h" +#include "cmm.h" +#include "dac.h" +#include "timer.h" +#include "timer_ex.h" +#include "pmc.h" +#include "crg.h" +#include "iwdg.h" +#include "iwdg_ex.h" +#include "wwdg.h" +#include "wwdg_ex.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +#define DIAGNOSE_ADC0_HANDLE g_adc0 +#define DIAGNOSE_ADC0_SOC ADC_SOC_NUM0 +#define DIAGNOSE_ADC0_CHANNEL ADC_CH_ADCINA17 + +extern CFD_Handle g_cfd; +extern CMM_Handle g_cmm; +extern CRC_Handle g_crc; +extern DAC_Handle g_dac0; +extern PMC_Handle g_pmc; +extern WWDG_Handle g_wwdg; +extern IWDG_Handle g_iwdg; +extern TIMER_Handle g_timer0; +extern TIMER_Handle g_timer1; +extern TIMER_Handle g_timer2; +extern UART_Handle g_uart0; +extern ADC_Handle g_adc0; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +void PMCPVDInterruptCallback(void *handle); +void CFDCheckEndCallback(CFD_Handle *handle); +void CFDClockStopCallback(CFD_Handle *handle); +void CMMCounterOverFlowCallback(CMM_Handle *handle); +void CMMCheckEndCallback(CMM_Handle *handle); +void CMMFreqErrorCallback(CMM_Handle *handle); +void TIMER0CallbackFunction(void *handle); +void TIMER0_DMAOverFlow_InterruptProcess(void *handle); +void TIMER1CallbackFunction(void *handle); +void TIMER1_DMAOverFlow_InterruptProcess(void *handle); +void TIMER2CallbackFunction(void *handle); +void TIMER2_DMAOverFlow_InterruptProcess(void *handle); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/system_init.c b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..5de901bfd04b40eaee6364b47fdaf26ddc8058e5 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/init/system_init.c @@ -0,0 +1,348 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; /* crg baseaddr */ + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). 25 is the div of the clk_1m in CLOCK. */ + crg.handleEx.clk1MDiv = (25 - 1); + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void ADC0_Init(void) +{ + HAL_CRG_IpEnableSet(ADC0_BASE, IP_CLK_ENABLE); /* ADC IP Enable */ + HAL_CRG_IpClkSelectSet(ADC0_BASE, CRG_ADC_CLK_ASYN_PLL_DIV); + HAL_CRG_IpClkDivSet(ADC0_BASE, CRG_ADC_DIV_1); + + g_adc0.baseAddress = ADC0; /* adc0 */ + g_adc0.socPriority = ADC_PRIMODE_ALL_ROUND; + + HAL_ADC_Init(&g_adc0); + + SOC_Param socParam = {0}; + socParam.adcInput = ADC_CH_ADCINA17; /* DAC_OUT(ADC AIN17) */ + socParam.sampleTotalTime = ADC_SOCSAMPLE_500CLK; /* adc sample total time 500 adc_clk */ + socParam.trigSource = ADC_TRIGSOC_SOFT; + socParam.continueMode = BASE_CFG_DISABLE; + socParam.finishMode = ADC_SOCFINISH_NONE; + HAL_ADC_ConfigureSoc(&g_adc0, ADC_SOC_NUM0, &socParam); /* config soc */ +} + +__weak void CFDCheckEndCallback(CFD_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN CFD_INT_CHECK_END_MASK */ + /* USER CODE END CFD_INT_CHECK_END_MASK */ +} + +__weak void CFDClockStopCallback(CFD_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN CFD_INT_PLL_REF_CLOCK_STOP_MASK */ + /* USER CODE END CFD_INT_PLL_REF_CLOCK_STOP_MASK */ +} + +static BASE_StatusType CFD_Init(void) +{ + HAL_CRG_IpEnableSet(CFD_BASE, IP_CLK_ENABLE); + + g_cfd.baseAddress = CFD; + g_cfd.upperBound = 20; /* 20: windows upbound */ + g_cfd.interruptType = CFD_INT_PLL_REF_CLOCK_STOP_MASK; /* pll ref clock stop error interrupt */ + + HAL_CFD_RegisterCallback(&g_cfd, CFD_INT_CHECK_END_MASK, (CFD_CallBackFuncType)CFDCheckEndCallback); + HAL_CFD_RegisterCallback(&g_cfd, CFD_INT_PLL_REF_CLOCK_STOP_MASK, (CFD_CallBackFuncType)CFDClockStopCallback); + + IRQ_Register(IRQ_CFD, HAL_CFD_IrqHandler, &g_cfd); + IRQ_SetPriority(IRQ_CFD, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_CFD); + return HAL_CFD_Init(&g_cfd); +} + +__weak void CMMCounterOverFlowCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN CMM_INT_COUNTER_OVERFLOW_MASK */ + /* USER CODE END CMM_INT_COUNTER_OVERFLOW_MASK */ +} + +__weak void CMMCheckEndCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN CMM_INT_CHECK_END_MASK */ + /* USER CODE END CMM_INT_CHECK_END_MASK */ +} + +__weak void CMMFreqErrorCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN CMM_INT_FREQ_ERR_MASK */ + /* USER CODE END CMM_INT_FREQ_ERR_MASK */ +} + +static BASE_StatusType CMM_Init(void) +{ + HAL_CRG_IpEnableSet(CMM_BASE, IP_CLK_ENABLE); + + g_cmm.baseAddress = CMM; + g_cmm.targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; /* target clock 8192 division */ + g_cmm.refFreqDivision = CMM_REF_FREQ_DIV_32; /* ref clock 32 division */ + g_cmm.targetClockSource = CMM_TARGET_CLK_HOSC; + g_cmm.refClockSource = CMM_REF_CLK_LOSC; + g_cmm.upperBound = 65535; /* 65535: upbound limit */ + g_cmm.lowerBound = 0; + g_cmm.interruptType = CMM_INT_FREQ_ERR_MASK; /* clock frequency error interrupt */ + + HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_COUNTER_OVERFLOW_MASK, (CMM_CallBackFuncType)CMMCounterOverFlowCallback); + HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_CHECK_END_MASK, (CMM_CallBackFuncType)CMMCheckEndCallback); + HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_FREQ_ERR_MASK, (CMM_CallBackFuncType)CMMFreqErrorCallback); + IRQ_Register(IRQ_CMM, HAL_CMM_IrqHandler, &g_cmm); + IRQ_SetPriority(IRQ_CMM, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_CMM); + return HAL_CMM_Init(&g_cmm); +} + +static void CRC_Init(void) +{ + HAL_CRG_IpEnableSet(CRC_BASE, IP_CLK_ENABLE); + + g_crc.baseAddress = CRC; /* crc baseAddr */ + + g_crc.inputDataFormat = CRC_MODE_BIT8; + g_crc.handleEx.algoMode = CRC32; /* crc32 algorythm */ + HAL_CRC_Init(&g_crc); +} + +static void DAC0_Init(void) +{ + HAL_CRG_IpEnableSet(DAC0_BASE, IP_CLK_ENABLE); /* DAC0 clock enable. */ + + g_dac0.baseAddress = DAC0; + g_dac0.dacValue = 512; /* 512 : half vdda */ + HAL_DAC_Init(&g_dac0); +} + +__weak void PMCPVDInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN PMC Callback */ + /* USER CODE END PMC Callback */ +} + +static void PMC_Init(void) +{ + HAL_CRG_IpEnableSet(PMC_BASE, IP_CLK_ENABLE); + g_pmc.baseAddress = PMC_BASE; + g_pmc.wakeupSrc = PMC_WAKEUP_NONE; + g_pmc.pvdEnable = BASE_CFG_ENABLE; /* enable volatege monitor */ + g_pmc.pvdThreshold = PMC_PVD_THRED_LEVEL7; /* pvd level 7 */ + HAL_PMC_Init(&g_pmc); + HAL_PMC_RegisterCallback(&g_pmc, PMC_PVD_INT_ID, PMCPVDInterruptCallback); + IRQ_Register(IRQ_PVD, HAL_PMC_IrqHandler, &g_pmc); + IRQ_SetPriority(IRQ_PVD, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_PVD); +} + +__weak void TIMER0CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN TIMER0CallbackFunction */ + /* USER CODE END TIMER0CallbackFunction */ +} + +static void TIMER0_Init(void) +{ + HAL_CRG_IpEnableSet(TIMER0_BASE, IP_CLK_ENABLE); /* TIMER0 clock enable. */ + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER0) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 100; + + g_timer0.baseAddress = TIMER0; + g_timer0.load = load - 1; /* Set timer value immediately */ + g_timer0.bgLoad = load - 1; /* Set timer value */ + g_timer0.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ + g_timer0.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ + g_timer0.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer0.interruptEn = BASE_CFG_ENABLE; + g_timer0.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer0.dmaReqEnable = BASE_CFG_DISABLE; + HAL_TIMER_Init(&g_timer0); + IRQ_Register(IRQ_TIMER0, HAL_TIMER_IrqHandler, &g_timer0); + + HAL_TIMER_RegisterCallback(&g_timer0, TIMER_PERIOD_FIN, TIMER0CallbackFunction); + IRQ_SetPriority(IRQ_TIMER0, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER0); +} + +__weak void TIMER1CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN TIMER1CallbackFunction */ + /* USER CODE END TIMER1CallbackFunction */ +} + +static void TIMER1_Init(void) +{ + HAL_CRG_IpEnableSet(TIMER1_BASE, IP_CLK_ENABLE); /* TIMER1 clock enable. */ + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER1) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 100; + + g_timer1.baseAddress = TIMER1; + g_timer1.load = load - 1; /* Set timer value immediately */ + g_timer1.bgLoad = load - 1; /* Set timer value */ + g_timer1.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ + g_timer1.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ + g_timer1.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer1.interruptEn = BASE_CFG_ENABLE; + g_timer1.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer1.dmaReqEnable = BASE_CFG_DISABLE; + HAL_TIMER_Init(&g_timer1); + IRQ_Register(IRQ_TIMER1, HAL_TIMER_IrqHandler, &g_timer1); + + HAL_TIMER_RegisterCallback(&g_timer1, TIMER_PERIOD_FIN, TIMER1CallbackFunction); + IRQ_SetPriority(IRQ_TIMER1, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER1); +} + +__weak void TIMER2CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN TIMER2CallbackFunction */ + /* USER CODE END TIMER2CallbackFunction */ +} + +static void TIMER2_Init(void) +{ + HAL_CRG_IpEnableSet(TIMER2_BASE, IP_CLK_ENABLE); /* TIMER2 clock enable. */ + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER2) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 100; + + g_timer2.baseAddress = TIMER2; + g_timer2.load = load - 1; /* Set timer value immediately */ + g_timer2.bgLoad = load - 1; /* Set timer value */ + g_timer2.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ + g_timer2.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ + g_timer2.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer2.interruptEn = BASE_CFG_ENABLE; + g_timer2.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer2.dmaReqEnable = BASE_CFG_DISABLE; + HAL_TIMER_Init(&g_timer2); + IRQ_Register(IRQ_TIMER2, HAL_TIMER_IrqHandler, &g_timer2); + + HAL_TIMER_RegisterCallback(&g_timer2, TIMER_PERIOD_FIN, TIMER2CallbackFunction); + IRQ_SetPriority(IRQ_TIMER2, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER2); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; /* baud rate */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; /* no parity */ + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; /* fifo enable */ + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void WWDG_Init(void) +{ + HAL_CRG_IpEnableSet(WWDG_BASE, IP_CLK_ENABLE); /* WWDG clock enable. */ + g_wwdg.baseAddress = WWDG; + + g_wwdg.timeValue = 1000000; /* 1000000 is time value */ + g_wwdg.timeType = WWDG_TIME_UNIT_US; + g_wwdg.enableIT = BASE_CFG_DISABLE; + g_wwdg.freqDivValue = WWDG_FREQ_DIV_NONE; + HAL_WWDG_Init(&g_wwdg); +} + +static void IWDG_Init(void) +{ + HAL_CRG_IpEnableSet(IWDG_BASE, IP_CLK_ENABLE); /* IWDG clock enable. */ + g_iwdg.baseAddress = IWDG; + + g_iwdg.timeValue = 100000; /* 100000 is time value */ + g_iwdg.timeType = IWDG_TIME_UNIT_US; + g_iwdg.freqDivValue = IWDG_FREQ_DIV_256; + HAL_IWDG_Init(&g_iwdg); +} + +static void IOConfig(void) +{ + /* Config PIN39 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN40 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); /* ioconfig init */ + UART0_Init(); + ADC0_Init(); + CRC_Init(); + CMM_Init(); + CFD_Init(); + DAC0_Init(); + PMC_Init(); + TIMER0_Init(); + TIMER1_Init(); + TIMER2_Init(); + IWDG_Init(); /* iwdg init */ + WWDG_Init(); /* wwdg init */ + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3061m/readme.md b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..2b9a1ffd226d86890286aeda4c18d825f300055b --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3061m/readme.md @@ -0,0 +1,42 @@ +# MCU芯片功能安全classb参考示例 +## 关键字: IEC60730,ClassB,启动诊断,运行时诊断,最小诊断单元process配置,时间性能测量,表驱动 + +**【功能描述】** ++ function_safety功能安全库中间件通过对功能安全处理流程进行抽象,提炼出用户侧最小配置单元function_safety_process, 应用侧基于表驱动的方式进行启动和运行时诊断处理,用户只需实例配置启动和运行时的诊断流程process,即可自动完成新增process处理流程注册到启动和运行时的处理流程中,用户只需根据具体项目需求选择功能安全库提供的诊断接口和配置对应的初始化配置即可。function_safety_init初始化相关接口是基于功能安全各子系统handle句柄的相关配置,是底层驱动和function_safety中间件之间的适配层,generatecode是基于IDE配置生成的芯片初始化配置代码,是底层驱动和芯片之间的适配层。功能安全中间件处理流程提供了诊断前备份功能和诊断后恢复功能,需要用户根据实际项目封装对应的接口,通过process配置注册到对应的函数指针上即可完成无损诊断,用户根据实际工程应用配置底层驱动初始化代码,诊断前调用备份函数备份工程应用的初始化配置,诊断后恢复功能应用的初始化配置,不影响用户实际应用的初始化配置,便于用户工程应用的配置集成。 + +**【示例配置】** ++ contexBackupFunc 上下文备份配置(可选):通过上下文备份可以实现实际应用的无损诊断,用于诊断前备份用户通过IDE配置生成的实际工程应用底层驱动配置。 + ++ handleConfigFunc 功能安全适配层初始化配置(可选):用于配置各子系统诊断函数所需的初始化配置,该适配层可完成底层驱动配置的修改和上层诊断指标的设定。 + ++ diagnoseFunc 诊断函数配置(可选):功能安全诊断接口,用户可选择function_safety中间件提供的各子系统诊断接口,也可自行封装对应的诊断接口。 + ++ failSafeFunc 失效安全函数配置(可选):基于诊断结果实施失效安全配置,该示例中为了便于演示,默认配置均为while(1)死循环的方式定住程序。该函数为__weak函数,用户可自定义进行钩子函数挂载。 + ++ faultPredictFunc 故障预测函数配置(可选):该功能function_safety安全包暂未提供,主要用于诊断正常的前提下进行故障预测。 + ++ contexResumeFunc 上下文恢复配置(可选):诊断后上下文配置恢复函数,诊断完成后恢复工程应用的底层驱动配置。示例中暂未提供,用户可根据实际项目进行配置封装接口。 + ++ contexHandle 上下文备份恢复参数句柄(可选):上下文备份和恢复的句柄指针,可用户指向备份区。 + ++ diagnoseHandle 诊断参数句柄(可选):诊断函数入参,用户可按照结构体定义进行配置。 + ++ failSafeHandle 失效安全参数句柄(可选):失效安全函数入参,用户可按照结构体定义进行配置。 + ++ faultPredictHandle 故障预测参数句柄(可选):故障预测函数入参,用户可按照结构体定义进行配置。 + ++ moment 诊断时刻参数句柄(可选):故障预测函数入参,用户可按照结构体定义进行配置。 + ++ timeCycleRecordSwitch 时间cycle测量开关(可选):默认不开,用户可配置是否开启,用于记录打印处理流程中各阶段的耗时以及状态。 + + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,通过串口可以看到启动和运行时处理流程process的诊断信息,包含功能安全状态码,状态码的含义可以参照FunctionSafetyState结构体的位定义,每个子系统的模块和特性在对应头文件中右定义,通过功能安全状态码能了解当前诊断的子系统和模块以及特性的诊断结果和时间性能。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 ++ 此示例init文件夹下的工程初始化配置是基于3061MNPICA芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 ++ 必须勾选上工程配置菜单中的“生成CRC”选项,ROM测试会用到,否则ROM完整性诊断会报异常,且不可通过仿真模式进行烧录,否则会缺少bin文件末尾的CRC校验码、 ++ 如果诊断出看门狗复位异常时想消除该异常,则目标板需要重新上下电,否则会一直检测到看门狗复位异常。 \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_entry/function_safety_entry.c b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_entry/function_safety_entry.c new file mode 100644 index 0000000000000000000000000000000000000000..b0b518c345ffc4a2e2fe03bd32a4f4c3a0f1696c --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_entry/function_safety_entry.c @@ -0,0 +1,54 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_startup.c + * @author MCU Driver Team + * @brief function safety startup module. + * @details function safety startup interface implementation. + */ +#include "debug.h" +#include "main.h" +#include "function_safety_init.h" +#include "function_safety_startup.h" +#include "function_safety_runtime.h" +#include "function_safety_entry.h" + +/** + * @brief Excute function safety entry. + * @param None. + * @retval None. + */ +void FunctionSafetyEntry(void) +{ + SystemInit(); + DBG_PRINTF("*** Function Safety Startup Process Begin *** \r\n"); + FunctionSafetyStartupProcess(); + DBG_PRINTF("*** Function Safety Startup Process End*** \r\n"); + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + DBG_PRINTF("\r\n*** Function Safety Runtime Process Begin *** \r\n"); + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + FunctionSafetyRuntimeProcess(); + HAL_WWDG_Refresh(g_diagnoseMonitor.wwdgHandle); + HAL_IWDG_Refresh(g_diagnoseMonitor.iwdgHandle); + BASE_FUNC_DELAY_MS(50); /* 50 : delay time 50ms */ + /* USER CODE END 4 */ + } +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_entry/function_safety_entry.h b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_entry/function_safety_entry.h new file mode 100644 index 0000000000000000000000000000000000000000..56c7d2a5691036f302f36cee0ab554342ff16472 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_entry/function_safety_entry.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_entry.h + * @author MCU Driver Team + * @brief function safety entry module. + * @details function safety entry interface declaration. + */ + +#ifndef FUNCTION_SAFETY_ENTRY_H +#define FUNCTION_SAFETY_ENTRY_H + +void FunctionSafetyEntry(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_init/function_safety_config.h b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_init/function_safety_config.h new file mode 100644 index 0000000000000000000000000000000000000000..cf485f05807385f082f881da20c6370090603e41 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_init/function_safety_config.h @@ -0,0 +1,47 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_config.h + * @author MCU Driver Team + * @brief This file contains the config of function safety + */ + +#ifndef FUNCTION_SAFETY_CONFIG_H +#define FUNCTION_SAFETY_CONFIG_H +/* ---------------------------------------- INCLUDE ----------------------------------- */ +/* ----------------------------------------PROCESS------------------------------------ */ +/* ----------------------------------------RAM Test------------------------------------ */ +/* Parameters are used during the RAM test, performed using March-C Algorithm */ +#define BCKGRND_PATTERN 0x00000000U +#define INV_BCKGRND_PATTERN 0xFFFFFFFFU + +/* Constants necessary for execution initial March test */ +#define STARTUP_RAM_START ((unsigned int *)0x02000000U) +#define STARTUP_RAM_END ((unsigned int *)0x02010000U) + +/* Constants necessary for execution of transparent run time March tests */ +#define RUNTIME_RAM_START ((unsigned int *)0x02000000U) +#define RUNTIME_RAM_END ((unsigned int *)0x02010000U) + +/* ------------------------------------------ROM Test------------------------------------ */ +/* CRC checks the ROM region result */ +#define ROM_START ((unsigned int *)0x03000000U) +#define FLASH_BLOCK_SIZE_IN_WORD 4 +#define EFLASH_ECC_INT_ENABLE_VALUE 0x000C0000 +/* ------------------------------------------AIO Test------------------------------------ */ + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_init/function_safety_init.c b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_init/function_safety_init.c new file mode 100644 index 0000000000000000000000000000000000000000..8cbcee462d2b29582a3da59345e248ecfad0f939 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_init/function_safety_init.c @@ -0,0 +1,569 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_init.c + * @author MCU Driver Team + * @brief function safety library adapter layer init. + * @details function safety library adapter layer init interface. + */ +#include "main.h" +#include "function_safety_config.h" +#include "function_safety_init.h" + +CORE_DiagnoseHandle g_diagnoseCore = {0}; +ANA_DiagnoseHandle g_diagnoseAna = {0}; +CLOCK_DiagnoseHandle g_diagnoseClock = {0}; +COMPUTE_DiagnoseHandle g_diagnoseCompute = {0}; +DIO_DiagnoseHandle g_diagnoseDio = {0}; +MONITOR_DiagnoseHandle g_diagnoseMonitor = {0}; +RAM_DiagnoseHandle g_diagnoseRam = {0}; +ROM_DiagnoseHandle g_diagnoseRom = {0}; +TIMERS_DiagnoseHandle g_diagnoseTimers = {0}; +CONNECT_DiagnoseHandle g_diagnoseConnect = {0}; +/*--------------------------------- analog diagnose enviroment init ----------------------------------------*/ +/** + * @brief ANA subsysterm's adc1 accuracy diagnose init. + * @param None. + * @retval None. + */ +void ANA_DiagnoseAdc1AccuracyInit(void) +{ + g_diagnoseAna.adcHandle = &DIAGNOSE_ADC1_HANDLE; + g_diagnoseAna.dacHandleRef = &g_dac1; /* dac output to adc */ + g_diagnoseAna.socx = DIAGNOSE_ADC1_SOC; + g_diagnoseAna.adcMaxRange = 4096; /* 4096 : max range of adc */ + g_diagnoseAna.dacMaxRange = 256; /* 256 : max range of dac */ + g_diagnoseAna.errRangePercent = 100; /* 100: adc value error range */ + DCL_ADC_SOCxSelectChannel(g_diagnoseAna.adcHandle->baseAddress, g_diagnoseAna.socx, DIAGNOSE_ADC1_CHANNEL); +} +/** + * @brief ANA subsysterm's adc2 accuracy diagnose init. + * @param None. + * @retval None. + */ +void ANA_DiagnoseAdc2AccuracyInit(void) +{ + g_diagnoseAna.adcHandle = &DIAGNOSE_ADC2_HANDLE; + g_diagnoseAna.dacHandleRef = &g_dac2; /* dac output to adc */ + g_diagnoseAna.socx = DIAGNOSE_ADC2_SOC; + g_diagnoseAna.adcMaxRange = 4096; /* 4096 : max range of adc */ + g_diagnoseAna.dacMaxRange = 256; /* 256 : max range of dac */ + g_diagnoseAna.errRangePercent = 100; /* 100: adc value error range */ + DCL_ADC_SOCxSelectChannel(g_diagnoseAna.adcHandle->baseAddress, g_diagnoseAna.socx, DIAGNOSE_ADC2_CHANNEL); +} +/*--------------------------------- clock diagnose enviroment init ----------------------------------------*/ +/** + * @brief CLock subsysterm's systerm clock single accuracy diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseSysClockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's hosc clock single accuracy diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseHoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's losc clock single accuracy diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseLoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_LOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_0; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's tcxo clock accuracy single diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseTcxoCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_TCXO; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's systerm clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseSysClockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's hosc clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseHoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's losc clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseLoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_LOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_0; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's tcxo clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseTcxoCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_TCXO; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's pll ref clock accuracy single diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnosePllRefCLockStopInit(void) +{ + g_diagnoseClock.cfdHandle = &g_cfd; + g_diagnoseClock.cfdHandle->interruptType = CFD_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 1000; /* 1000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cfd windows value error range */ + HAL_CFD_Stop(g_diagnoseClock.cfdHandle); /* stop cfd monitor clock stop */ + BASE_FUNC_DELAY_US(200); /* 200: wait cfd stable */ + CLOCK_CfdWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CFD_Init(g_diagnoseClock.cfdHandle); + HAL_CFD_Start(g_diagnoseClock.cfdHandle); /* start cfd monitor clock stop */ +} +/** + * @brief CLock subsysterm's pll ref clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnosePllRefCLockStopInit(void) +{ + g_diagnoseClock.cfdHandle = &g_cfd; + g_diagnoseClock.cfdHandle->interruptType = CFD_INT_PLL_REF_CLOCK_STOP_MASK; + g_diagnoseClock.errRangePercent = 50; /* 50: cfd windows value error range */ + HAL_CFD_Stop(g_diagnoseClock.cfdHandle); /* stop cfd monitor clock stop */ + BASE_FUNC_DELAY_US(200); /* 200: wait cfd stable */ + CLOCK_CfdWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CFD_Init(g_diagnoseClock.cfdHandle); + HAL_CFD_Start(g_diagnoseClock.cfdHandle); /* start cfd monitor clock stop */ + BASE_FUNC_DELAY_US(200); /* 200 : wait clock stabilization */ +} +/*--------------------------------- compute diagnose enviroment init ----------------------------------------*/ +/** + * @brief Compute subsysterm's crc32 calculate correct diagnose init. + * @param None. + * @retval None. + */ +void COMPUTE_DiagnoseCrcInit(void) +{ + g_diagnoseCompute.crcHandle = &g_crc; + g_diagnoseCompute.inputTestData = 0xADDAA55A; /* 0xADDAA55A: input test data */ + g_diagnoseCompute.inputDataSize = 4; /* 4: 32bit width */ + g_diagnoseCompute.outputRefData = 0x89F75D91; /* 0x89F75D91: output ref data */ +} +/*--------------------------------- monitor diagnose enviroment init ----------------------------------------*/ +/** + * @brief Monitor subsysterm's wdg reset function diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseWdgResetInit(void) +{ + g_diagnoseMonitor.wwdgHandle = &g_wwdg; + g_diagnoseMonitor.startupResetTimeUs = 100; /* 100: wdg startup reset time interval */ + HAL_WWDG_Stop(g_diagnoseMonitor.wwdgHandle); /* stop wdg */ + DCL_WWDG_SetFreqDivValue(g_diagnoseMonitor.wwdgHandle->baseAddress, WWDG_FREQ_DIV_4); + HAL_WWDG_SetTimeValue(g_diagnoseMonitor.wwdgHandle, g_diagnoseMonitor.startupResetTimeUs, WWDG_TIME_UNIT_US); +} + +/** + * @brief Monitor subsysterm's wdg program stuck diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseWdgProgramStuckInit(void) +{ + g_diagnoseMonitor.wwdgHandle = &g_wwdg; + g_diagnoseMonitor.startupResetTimeUs = 1000000; /* 1000000: wdg runtime reset time interval */ + HAL_WWDG_Stop(g_diagnoseMonitor.wwdgHandle); /* stop wdg */ + DCL_WWDG_SetFreqDivValue(g_diagnoseMonitor.wwdgHandle->baseAddress, WWDG_FREQ_DIV_8192); + HAL_WWDG_SetTimeValue(g_diagnoseMonitor.wwdgHandle, g_diagnoseMonitor.startupResetTimeUs, WWDG_TIME_UNIT_US); + HAL_WWDG_Start(g_diagnoseMonitor.wwdgHandle); +} +/** + * @brief Monitor subsysterm's iwdg reset function diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseIwdgResetInit(void) +{ + g_diagnoseMonitor.iwdgHandle = &g_iwdg; + g_diagnoseMonitor.startupResetTimeUs = 100; /* 100: iwdg startup reset time interval */ + HAL_IWDG_Stop(g_diagnoseMonitor.iwdgHandle); /* stop iwdg */ + DCL_IWDG_SetFreqDivValue(g_diagnoseMonitor.iwdgHandle->baseAddress, IWDG_FREQ_DIV_4); + HAL_IWDG_SetTimeValue(g_diagnoseMonitor.iwdgHandle, g_diagnoseMonitor.startupResetTimeUs, IWDG_TIME_UNIT_US); +} + +/** + * @brief Monitor subsysterm's iwdg program stuck diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseIwdgProgramStuckInit(void) +{ + g_diagnoseMonitor.iwdgHandle = &g_iwdg; + g_diagnoseMonitor.startupResetTimeUs = 1000000; /* 1000000: iwdg runtime reset time interval */ + HAL_IWDG_Stop(g_diagnoseMonitor.iwdgHandle); /* stop iwdg */ + DCL_IWDG_SetFreqDivValue(g_diagnoseMonitor.iwdgHandle->baseAddress, IWDG_FREQ_DIV_256); + HAL_IWDG_SetTimeValue(g_diagnoseMonitor.iwdgHandle, g_diagnoseMonitor.startupResetTimeUs, IWDG_TIME_UNIT_US); + HAL_IWDG_Start(g_diagnoseMonitor.iwdgHandle); +} +/** + * @brief Monitor subsysterm's pmc voltage low power diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnosePmcLowPowerInit(void) +{ + g_diagnoseMonitor.pmcHandle = &g_pmc; /* monitor of pmc */ +} +/** + * @brief Monitor subsysterm's tsensor over temperature diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseTsensorOverTemperatureInit(void) +{ + g_diagnoseMonitor.overTemperatureValue = 90; /* 90: over temperature value */ + HAL_TSENSOR_Init(); +} +/*--------------------------------- ram diagnose enviroment init ----------------------------------------*/ +/** + * @brief Ram subsysterm's startup diagnose init. + * @param None. + * @retval None. + */ +void RAM_DiagnoseStartupInit(void) +{ + g_diagnoseRam.sramStartAddr = STARTUP_RAM_START; /* ram start address */ + g_diagnoseRam.sramCurrentAddr = STARTUP_RAM_START; /* rom current address */ + g_diagnoseRam.sramCurrentAddrInv = (unsigned int *)(~(unsigned int)(void*)g_diagnoseRam.sramCurrentAddr); + g_diagnoseRam.sramEndAddr = STARTUP_RAM_END; + g_diagnoseRam.sramPattern = BCKGRND_PATTERN; +} +/** + * @brief Ram subsysterm's runtime diagnose init. + * @param None. + * @retval None. + */ +void RAM_DiagnoseRuntimeInit(void) +{ + g_diagnoseRam.sramStartAddr = RUNTIME_RAM_START; /* ram start address */ + g_diagnoseRam.sramCurrentAddr = RUNTIME_RAM_START; /* rom current address */ + g_diagnoseRam.sramCurrentAddrInv = (unsigned int *)(~(unsigned int)(void*)g_diagnoseRam.sramCurrentAddr); + g_diagnoseRam.sramEndAddr = RUNTIME_RAM_END; + g_diagnoseRam.sramPattern = BCKGRND_PATTERN; +} +/*--------------------------------- rom diagnose enviroment init ----------------------------------------*/ +/** + * @brief Rom subsysterm's intgrity diagnose init. + * @param None. + * @retval None. + */ +void ROM_DiagnoseIntegrityInit(void) +{ + g_diagnoseRom.crcHandle = &g_crc; + g_diagnoseRom.startAddr = ROM_START; /* rom start address */ + g_diagnoseRom.indexPointer = ROM_START; /* rom end address */ + g_diagnoseRom.indexPointerInv = (unsigned int *)(~(unsigned int)(void*)ROM_START); + g_diagnoseRom.flashBlockSizeInWords = FLASH_BLOCK_SIZE_IN_WORD; +} +/** + * @brief Rom subsysterm's flash ecc diagnose init. + * @param None. + * @retval None. + */ +void ROM_DiagnoseFlashEccInit(void) +{ + g_diagnoseRom.flashBase = EFC; /* ecc function in eflash reg */ + g_diagnoseRom.eccIntRegVal = EFLASH_ECC_INT_ENABLE_VALUE; +} +/*--------------------------------- timers diagnose enviroment init ----------------------------------------*/ +/** + * @brief Timers subsysterm's timer0 interrupt interval diagnose init. + * @param None. + * @retval None. + */ +void TIMERS_DiagnoseTimer0InterruptIntervalInit(void) +{ + g_diagnoseTimers.timerHandle = &g_timer0; + g_diagnoseTimers.setTimeUs = 1000; /* 1000: timer interval */ + g_diagnoseTimers.errRangeUs = 1; /* 1: 1us error range */ + g_diagnoseTimers.timerHandle->load = (HAL_CRG_GetIpFreq((void *)TIMER0) / 1000000u) * g_diagnoseTimers.setTimeUs; + g_diagnoseTimers.timerHandle->bgLoad = g_diagnoseTimers.timerHandle->load; + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_LOAD); /* config load time */ + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_BGLOAD); /* config bgload time */ + g_diagnoseTimers.pretimeCycle = BASE_FUNC_GetTick(); + HAL_TIMER_Start(g_diagnoseTimers.timerHandle); + BASE_FUNC_DELAY_US(1500); /* 1500 : wait timer interrupt */ +} +/** + * @brief Timers subsysterm's timer1 interrupt interval diagnose init. + * @param None. + * @retval None. + */ +void TIMERS_DiagnoseTimer1InterruptIntervalInit(void) +{ + g_diagnoseTimers.timerHandle = &g_timer1; + g_diagnoseTimers.setTimeUs = 1000; /* 1000: timer interval */ + g_diagnoseTimers.errRangeUs = 1; /* 1: 1us error range */ + g_diagnoseTimers.timerHandle->load = (HAL_CRG_GetIpFreq((void *)TIMER1) / 1000000u) * g_diagnoseTimers.setTimeUs; + g_diagnoseTimers.timerHandle->bgLoad = g_diagnoseTimers.timerHandle->load; + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_LOAD); /* config load time */ + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_BGLOAD); /* config bgload time */ + g_diagnoseTimers.pretimeCycle = BASE_FUNC_GetTick(); + HAL_TIMER_Start(g_diagnoseTimers.timerHandle); + BASE_FUNC_DELAY_US(1500); /* 1500 : wait timer interrupt */ +} +/** + * @brief Timers subsysterm's timer2 interrupt interval diagnose init. + * @param None. + * @retval None. + */ +void TIMERS_DiagnoseTimer2InterruptIntervalInit(void) +{ + g_diagnoseTimers.timerHandle = &g_timer2; + g_diagnoseTimers.setTimeUs = 1000; /* 1000: timer interval */ + g_diagnoseTimers.errRangeUs = 1; /* 1: 1us error range */ + g_diagnoseTimers.timerHandle->load = (HAL_CRG_GetIpFreq((void *)TIMER2) / 1000000u) * g_diagnoseTimers.setTimeUs; + g_diagnoseTimers.timerHandle->bgLoad = g_diagnoseTimers.timerHandle->load; + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_LOAD); /* config load time */ + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_BGLOAD); /* config bgload time */ + g_diagnoseTimers.pretimeCycle = BASE_FUNC_GetTick(); + HAL_TIMER_Start(g_diagnoseTimers.timerHandle); + BASE_FUNC_DELAY_US(1500); /* 1500 : wait timer interrupt */ +} +/*--------------------------------- irq diagnose enviroment init ----------------------------------------*/ +/** + * @brief CFD check end callback function. + * @param handle @ref CFD_Handle. + * @retval None. + */ +void CFDCheckEndCallback(CFD_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cfdIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cfdClockCount = DCL_CFD_GetCntValue(g_diagnoseClock.cfdHandle->baseAddress); + HAL_CFD_Stop(g_diagnoseClock.cfdHandle); +} +/** + * @brief CFD clock stop callback function. + * @param handle @ref CFD_Handle. + * @retval None. + */ +void CFDClockStopCallback(CFD_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cfdIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cfdClockCount = DCL_CFD_GetCntValue(g_diagnoseClock.cfdHandle->baseAddress); +} +/** + * @brief CMM check end callback function. + * @param handle @ref CMM_Handle. + * @retval None. + */ +void CMMCheckEndCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cmmIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cmmClockCount = DCL_CMM_GetCntValue(g_diagnoseClock.cmmHandle->baseAddress); + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); +} +/** + * @brief CMM frequency error callback function. + * @param handle @ref CMM_Handle. + * @retval None. + */ +void CMMFreqErrorCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cmmIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cmmClockCount = DCL_CMM_GetCntValue(g_diagnoseClock.cmmHandle->baseAddress); +} +/** + * @brief PMC low poer callback function. + * @param handle @ref PMC_Handle. + * @retval None. + */ +void PMCPVDInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseMonitor.pmcIrqFlag = true; /* set irq flag */ +} +/** + * @brief Timer0 interrupt callback function. + * @param handle @ref Timer_Handle. + * @retval None. + */ +void TIMER0CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseTimers.timerIrqFlag =true; /* set irq flag */ + g_diagnoseTimers.currenttimeCycle = BASE_FUNC_GetTick(); + /* duration cycle calculate */ + unsigned int durationCycle = (g_diagnoseTimers.currenttimeCycle > g_diagnoseTimers.pretimeCycle) ? \ + (g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle) : \ + (SYSTICK_MAX_VALUE + g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle + 1); + g_diagnoseTimers.durationUs = durationCycle / HAL_CRG_GetCoreClkFreq() / CRG_FREQ_1MHz; + g_diagnoseTimers.pretimeCycle = g_diagnoseTimers.currenttimeCycle; /* prepare for next calculate */ +} +/** + * @brief Timer1 interrupt callback function. + * @param handle @ref Timer_Handle. + * @retval None. + */ +void TIMER1CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseTimers.timerIrqFlag =true; /* set irq flag */ + g_diagnoseTimers.currenttimeCycle = BASE_FUNC_GetTick(); + /* duration cycle calculate */ + unsigned int durationCycle = (g_diagnoseTimers.currenttimeCycle > g_diagnoseTimers.pretimeCycle) ? \ + (g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle) : \ + (SYSTICK_MAX_VALUE + g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle + 1); + g_diagnoseTimers.durationUs = durationCycle / HAL_CRG_GetCoreClkFreq() / CRG_FREQ_1MHz; + g_diagnoseTimers.pretimeCycle = g_diagnoseTimers.currenttimeCycle; /* prepare for next calculate */ +} +/** + * @brief Timer2 interrupt callback function. + * @param handle @ref Timer_Handle. + * @retval None. + */ +void TIMER2CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseTimers.timerIrqFlag =true; /* set irq flag */ + g_diagnoseTimers.currenttimeCycle = BASE_FUNC_GetTick(); + /* duration cycle calculate */ + unsigned int durationCycle = (g_diagnoseTimers.currenttimeCycle > g_diagnoseTimers.pretimeCycle) ? \ + (g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle) : \ + (SYSTICK_MAX_VALUE + g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle + 1); + g_diagnoseTimers.durationUs = durationCycle / HAL_CRG_GetCoreClkFreq() / CRG_FREQ_1MHz; + g_diagnoseTimers.pretimeCycle = g_diagnoseTimers.currenttimeCycle; /* prepare for next calculate */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_init/function_safety_init.h b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_init/function_safety_init.h new file mode 100644 index 0000000000000000000000000000000000000000..a6af870abc16c5d9229d93cf84dddb1bf5b2b04c --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_init/function_safety_init.h @@ -0,0 +1,69 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_init.h + * @author MCU Driver Team + * @brief function safety library adapter layer init. + * @details function safety library adapter layer init + */ + +#ifndef FUNCTION_SAFETY_INIT_H +#define FUNCTION_SAFETY_INIT_H + +#include "function_safety_mcu.h" +#include "function_safety_config.h" + +extern CORE_DiagnoseHandle g_diagnoseCore; +extern ANA_DiagnoseHandle g_diagnoseAna; +extern CLOCK_DiagnoseHandle g_diagnoseClock; +extern COMPUTE_DiagnoseHandle g_diagnoseCompute; +extern DIO_DiagnoseHandle g_diagnoseDio; +extern MONITOR_DiagnoseHandle g_diagnoseMonitor; +extern RAM_DiagnoseHandle g_diagnoseRam; +extern ROM_DiagnoseHandle g_diagnoseRom; +extern TIMERS_DiagnoseHandle g_diagnoseTimers; +extern CONNECT_DiagnoseHandle g_diagnoseConnect; + +void ANA_DiagnoseAdc0AccuracyInit(void); +void ANA_DiagnoseAdc1AccuracyInit(void); +void ANA_DiagnoseAdc2AccuracyInit(void); +void CLOCK_SingleDiagnoseSysClockAccuracyInit(void); +void CLOCK_SingleDiagnoseHoscCLockAccuracyInit(void); +void CLOCK_SingleDiagnoseLoscCLockAccuracyInit(void); +void CLOCK_SingleDiagnoseTcxoCLockAccuracyInit(void); +void CLOCK_ContinueDiagnoseSysClockAccuracyInit(void); +void CLOCK_ContinueDiagnoseHoscCLockAccuracyInit(void); +void CLOCK_ContinueDiagnoseLoscCLockAccuracyInit(void); +void CLOCK_ContinueDiagnoseTcxoCLockAccuracyInit(void); +void CLOCK_SingleDiagnosePllRefCLockStopInit(void); +void CLOCK_ContinueDiagnosePllRefCLockStopInit(void); +void COMPUTE_DiagnoseCrcInit(void); +void MONITOR_DiagnoseWdgResetInit(void); +void MONITOR_DiagnoseWdgProgramStuckInit(void); +void MONITOR_DiagnoseIwdgResetInit(void); +void MONITOR_DiagnoseIwdgProgramStuckInit(void); +void MONITOR_DiagnosePmcLowPowerInit(void); +void MONITOR_DiagnoseTsensorOverTemperatureInit(void); +void RAM_DiagnoseStartupInit(void); +void RAM_DiagnoseRuntimeInit(void); +void ROM_DiagnoseIntegrityInit(void); +void ROM_DiagnoseFlashEccInit(void); +void TIMERS_DiagnoseTimer0InterruptIntervalInit(void); +void TIMERS_DiagnoseTimer1InterruptIntervalInit(void); +void TIMERS_DiagnoseTimer2InterruptIntervalInit(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_report/function_safety_report.c b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_report/function_safety_report.c new file mode 100644 index 0000000000000000000000000000000000000000..8bebf8cfd46ba102377de7338b2ddd0615bfd49b --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_report/function_safety_report.c @@ -0,0 +1,88 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_report.c + * @author MCU Driver Team + * @brief function safety report module. + * @details function safety report interface implementation. + */ + +#include "function_safety_report.h" +#include "debug.h" +#include "iocmg.h" +/** + * @brief rigister soft irq callback and prioerity , callback param. + * @param handlerFunc irq callback function. + * @param priority irq priority. + * @param param irq callback param. + * @retval None. + */ +void RegisterReportFailEventHandler(IRQ_PROC_FUNC handlerFunc, unsigned int priority, void *param) +{ + IRQ_DisableN(IRQ_SOFTWARE); + IRQ_Unregister(IRQ_SOFTWARE); /* unregister soft irq */ + IRQ_Register(IRQ_SOFTWARE, handlerFunc, param); /* register soft irq callback and param */ + IRQ_SetPriority(IRQ_SOFTWARE, priority); /* set soft irq priority */ + IRQ_EnableN(IRQ_SOFTWARE); +} +/** + * @brief soft irq callback of report fail event. + * @param param irq callback param. + * @retval None. + */ +void ReportFailEventLogBySoftIrq(void *param) +{ + BASE_FUNC_UNUSED(param); + DCL_SYSCTRL_ClearSoftInterrupt(); /* clear soft irq */ + IRQ_ClearN(IRQ_SOFTWARE); + IRQ_Disable(); + FunctionSafetyState failEvent = STATE_LoadFailEvent(); /* load fail event */ + DBG_PRINTF("Fail Event Info : FailEvent[0x%x], Subsysterm [%d], Module [%d], Feature [%d], Failtype [%d]\r\n", \ + failEvent, failEvent.BIT.subsysterm, failEvent.BIT.moudule, failEvent.BIT.feature, failEvent.BIT.faultType); +} + +/** + * @brief Excute function safety process and return state. + * @param state @ref FunctionSafetyState. + * @param processTime @ref ProcessTimeCycle. + * @retval None. + */ +void FunctionSafetyProcessPrint(FunctionSafetyState state, ProcessTimeCycle processTime) +{ + if (!processTime.timeCycleRecordSwitch) { + return; + } + if (state.BIT.result == RESULT_FAIL) { /* result fail judgement */ + DBG_PRINTF("\r\nFAIL info : State[0x%x], Subsysterm[%d], Module[%d], Feature[%d], Failtype[%d] \ + \r\n DiagnoseCycle[%d], FailSafeCycle[%d], FaultPredictCycle[%d]\r\n", \ + state, state.BIT.subsysterm, state.BIT.moudule, state.BIT.feature, state.BIT.faultType, \ + processTime.diagnoseTimeCycle, processTime.failSafeTimeCycle, processTime.faultPredictTimeCycle); + } else { + if (state.BIT.result == RESULT_SUCCESS) { /* result success judgement */ + DBG_PRINTF("\r\nSUCCESS info : State [0x%x], Subsysterm [%d], Module [%d], Feature [%d] \ + \r\n DiagnoseCycle[%d], FailSafeCycle[%d], FaultPredictCycle[%d]\r\n", \ + state, state.BIT.subsysterm, state.BIT.moudule, state.BIT.feature,\ + processTime.diagnoseTimeCycle, processTime.failSafeTimeCycle, processTime.faultPredictTimeCycle); + } + if (state.BIT.result == RESULT_IS_RUNNING) { /* result ongoing judgement */ + DBG_PRINTF("\r\nRUNNING info : State [0x%x], Subsysterm [%d], Module [%d], Feature [%d] \ + \r\n DiagnoseCycle[%d], FailSafeCycle[%d], FaultPredictCycle[%d]\r\n", \ + state, state.BIT.subsysterm, state.BIT.moudule, state.BIT.feature,\ + processTime.diagnoseTimeCycle, processTime.failSafeTimeCycle, processTime.faultPredictTimeCycle); + } + } +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_report/function_safety_report.h b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_report/function_safety_report.h new file mode 100644 index 0000000000000000000000000000000000000000..76f5cafc504554c025f446ccd58126128fcc91d2 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_report/function_safety_report.h @@ -0,0 +1,43 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_report.h + * @author MCU Driver Team + * @brief function safety report module. + * @details function safety report interface declaration. + */ + +#ifndef FUNCTION_SAFETY_REPORT_H +#define FUNCTION_SAFETY_REPORT_H + +#include "function_safety_mcu.h" + +/** + * @brief Triggle soft irq send fail event. + * @param None. + * @retval None. + */ +static inline void TriggerSoftIrqSendFailEvent(void) +{ + return DCL_SYSCTRL_GenerateSoftInterrupt(); +} + +void RegisterReportFailEventHandler(IRQ_PROC_FUNC handlerFunc, unsigned int priority, void *param); +void ReportFailEventLogBySoftIrq(void *param); +void FunctionSafetyProcessPrint(FunctionSafetyState state, ProcessTimeCycle processTime); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_runtime/function_safety_runtime.c b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_runtime/function_safety_runtime.c new file mode 100644 index 0000000000000000000000000000000000000000..1d62415828449e1ba3d803b5833b4a7f235c076d --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_runtime/function_safety_runtime.c @@ -0,0 +1,105 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_runtime.c + * @author MCU Driver Team + * @brief function safety runtime module. + * @details function safety runtime interface implementation. + */ +#include "main.h" +#include "function_safety_init.h" +#include "function_safety_process.h" +#include "function_safety_report.h" +#include "function_safety_runtime.h" + +FunctionSafetyProcessHandle g_fuSaRuntimeProcess[] = { + { + .diagnoseFunc = CORE_DiagnoseCpuStatus, /* cpu status diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = CORE_DiagnoseCpuGeneralRegister, /* cpu general register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = CORE_DiagnosePcRegister, /* cpu pc register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_RUNTIME + }, + { + .handleConfigFunc = RAM_DiagnoseRuntimeInit, /* ram step diagnose */ + .diagnoseFunc = RAM_DiagnoseSramByMarchAlgorithm, + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = RAM_DiagnoseSramByParityCheck, /* ram parity diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = RAM_DiagnoseStackOverflow, /* ram stack overflow diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_RUNTIME + }, + { + .handleConfigFunc = ROM_DiagnoseIntegrityInit, /* rom intergrity diagnose */ + .diagnoseFunc = ROM_DiagnoseIntegrity, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_RUNTIME + }, + { + .handleConfigFunc = ROM_DiagnoseFlashEccInit, /* flash ecc diagnose */ + .diagnoseFunc = ROM_DiagnoseFlashEcc, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_RUNTIME + } +}; +/* runtime function safety iterm size */ +const unsigned int RUNTIME_PROCESS_ARRAY_SIZE = sizeof(g_fuSaRuntimeProcess) / sizeof(g_fuSaRuntimeProcess[0]); + +/** + * @brief Excute run time function safety iterm. + * @param None. + * @retval None. + */ +void FunctionSafetyRuntimeProcess(void) +{ + FunctionSafetyState state = {0}; + ProcessTimeCycle processTime = {0}; + processTime.timeCycleRecordSwitch = true; + /* excute runtime function safety iterm one by one */ + for (unsigned int i = 0; i < RUNTIME_PROCESS_ARRAY_SIZE; ++i) { + state = FunctionSafetyProcess(&g_fuSaRuntimeProcess[i], &processTime); + if (state.BIT.result == RESULT_FAIL) { + TriggerSoftIrqSendFailEvent(); /* trigger soft interrupt to notify application */ + } + if (processTime.timeCycleRecordSwitch) { + FunctionSafetyProcessPrint(state, processTime); + } + } +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_runtime/function_safety_runtime.h b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_runtime/function_safety_runtime.h new file mode 100644 index 0000000000000000000000000000000000000000..0b3ce9787a9726c65ef1b45062e75b2a4a2c7a6c --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_runtime/function_safety_runtime.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_runtime.h + * @author MCU Driver Team + * @brief function safety runtime module. + * @details function safety runtime interface declaration. + */ + +#ifndef FUNCTION_SAFETY_RUNTIME_H +#define FUNCTION_SAFETY_RUNTIME_H + +void FunctionSafetyRuntimeProcess(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_startup/function_safety_startup.c b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_startup/function_safety_startup.c new file mode 100644 index 0000000000000000000000000000000000000000..1456be9e3804724cc71f0cbd5747899f2974bb9e --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_startup/function_safety_startup.c @@ -0,0 +1,226 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_startup.c + * @author MCU Driver Team + * @brief function safety startup module. + * @details function safety startup interface implementation. + */ +#include "main.h" +#include "function_safety_init.h" +#include "function_safety_process.h" +#include "function_safety_report.h" +#include "function_safety_startup.h" + +FunctionSafetyProcessHandle g_fuSaStartupProcess[] = { + { + .diagnoseFunc = CORE_DiagnoseCpuStatus, /* cpu status diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = CORE_DiagnoseCpuGeneralRegister, /* cpu general register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = CORE_DiagnoseCpuSoftwareIrq, /* cpu soft irq diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = CORE_DiagnosePcRegister, /* cpu pc register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = RAM_DiagnoseStartupInit, /* ram marchx diagnose */ + .diagnoseFunc = RAM_DiagnoseSramByMarchAlgorithm, + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = RAM_DiagnoseSramByParityCheck, /* ram parity diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = RAM_DiagnoseStackOverflow, /* ram stack overflow diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = CLOCK_SingleDiagnoseSysClockAccuracyInit, /* systerm clock single diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_SingleDiagnoseHoscCLockAccuracyInit, /* hosc clock single diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_SingleDiagnoseLoscCLockAccuracyInit, /* losc clock single diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_ContinueDiagnoseSysClockAccuracyInit, /* systerm clock continue diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_SingleDiagnosePllRefCLockStopInit, /* pll ref clock single diagnose */ + .diagnoseFunc = CLOCK_CfdDiagnosePllRefClockStop, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_ContinueDiagnosePllRefCLockStopInit, /* pll ref clock continue diagnose */ + .diagnoseFunc = CLOCK_CfdDiagnosePllRefClockStop, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = COMPUTE_DiagnoseCrcInit, /* crc calculate correct diagnose */ + .diagnoseFunc = COMPUTE_DiagnoseCrcAlgorithmCorrect, + .failSafeFunc = COMPUTE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCompute, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = ROM_DiagnoseIntegrityInit, /* rom integrity diagnose */ + .diagnoseFunc = ROM_DiagnoseIntegrity, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = ROM_DiagnoseFlashEccInit, /* rom flash ecc diagnose */ + .diagnoseFunc = ROM_DiagnoseFlashEcc, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = MONITOR_DiagnoseWdgProgramStuckInit, /* wdg program stuck diagnose */ + .diagnoseFunc = MONITOR_DiagnoseProgramStuckByWdg, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + }, + { + .handleConfigFunc = MONITOR_DiagnoseIwdgProgramStuckInit, /* iwdg program stuck diagnose */ + .diagnoseFunc = MONITOR_DiagnoseProgramStuckByIwdg, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + }, + { + .handleConfigFunc = MONITOR_DiagnosePmcLowPowerInit, /* pmc low power diagnose */ + .diagnoseFunc = MONITOR_DiagnosePowerLowLevelByPmc, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + }, + { + .handleConfigFunc = MONITOR_DiagnoseTsensorOverTemperatureInit, /* tsensor over temperature diagnose */ + .diagnoseFunc = MONITOR_DiagnoseOverTemperatureByTsensor, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + }, + { + .handleConfigFunc = TIMERS_DiagnoseTimer0InterruptIntervalInit, /* timer0 interrupt interval diagnose */ + .diagnoseFunc = TIMERS_DiagnoseInterruptIntervalAccuracy, + .failSafeFunc = TIMERS_FailSafeHandler, + .diagnoseHandle = &g_diagnoseTimers, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = TIMERS_DiagnoseTimer1InterruptIntervalInit, /* timer1 interrupt interval diagnose */ + .diagnoseFunc = TIMERS_DiagnoseInterruptIntervalAccuracy, + .failSafeFunc = TIMERS_FailSafeHandler, + .diagnoseHandle = &g_diagnoseTimers, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = TIMERS_DiagnoseTimer2InterruptIntervalInit, /* timer2 interrupt interval diagnose */ + .diagnoseFunc = TIMERS_DiagnoseInterruptIntervalAccuracy, + .failSafeFunc = TIMERS_FailSafeHandler, + .diagnoseHandle = &g_diagnoseTimers, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = ANA_DiagnoseAdc1AccuracyInit, /* adc1 accuracy diagnose */ + .diagnoseFunc = ANA_DiagnoseAdcSampleAccuracy, + .failSafeFunc = ANA_FailSafeHandler, + .diagnoseHandle = &g_diagnoseAna, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = ANA_DiagnoseAdc2AccuracyInit, /* adc2 accuracy diagnose */ + .diagnoseFunc = ANA_DiagnoseAdcSampleAccuracy, + .failSafeFunc = ANA_FailSafeHandler, + .diagnoseHandle = &g_diagnoseAna, + .moment = MOMENT_STARTUP + } +}; +/* startup function safety iterm size */ +const unsigned int STARTUP_PROCESS_ARRAY_SIZE = sizeof(g_fuSaStartupProcess) / sizeof(g_fuSaStartupProcess[0]); + +/** + * @brief Excute startup function safety iterm. + * @param None. + * @retval None. + */ +void FunctionSafetyStartupProcess(void) +{ + FunctionSafetyState state = {0}; + ProcessTimeCycle processTime = {0}; + processTime.timeCycleRecordSwitch = true; + /* excute startup function safety iterm one by one */ + for (unsigned int i = 0; i < STARTUP_PROCESS_ARRAY_SIZE; ++i) { + state = FunctionSafetyProcess(&g_fuSaStartupProcess[i], &processTime); + if (state.BIT.moudule == MODULE_CPU_SOFT_INTTERRUPT && state.BIT.subsysterm == SUBSYS_CORE) { + RegisterReportFailEventHandler(ReportFailEventLogBySoftIrq, 3, NULL); /* 3: interrupt priority */ + } + if (i >= 3 && state.BIT.result == RESULT_FAIL) { /* 3 : wait soft interrupt enable and register callback */ + TriggerSoftIrqSendFailEvent(); /* trigger soft interrupt to notify application */ + } + if (processTime.timeCycleRecordSwitch) { + FunctionSafetyProcessPrint(state, processTime); + } + } +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_startup/function_safety_startup.h b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_startup/function_safety_startup.h new file mode 100644 index 0000000000000000000000000000000000000000..b53c092a2241b644ceb988a85777145fcbe8a930 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/function_safety_startup/function_safety_startup.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_startup.h + * @author MCU Driver Team + * @brief function safety startup module. + * @details function safety startup interface declaration. + */ + +#ifndef FUNCTION_SAFETY_STARTUP_H +#define FUNCTION_SAFETY_STARTUP_H + +void FunctionSafetyStartupProcess(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_3066m/readme.md b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..d9fc75ab0e2cd8a1b1bd6766e0f0ea4eebb9a217 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_3066m/readme.md @@ -0,0 +1,42 @@ +# MCU芯片功能安全classb参考示例 +## 关键字: IEC60730,ClassB,启动诊断,运行时诊断,最小诊断单元process配置,时间性能测量,表驱动 + +**【功能描述】** ++ function_safety功能安全库中间件通过对功能安全处理流程进行抽象,提炼出用户侧最小配置单元function_safety_process, 应用侧基于表驱动的方式进行启动和运行时诊断处理,用户只需实例配置启动和运行时的诊断流程process,即可自动完成新增process处理流程注册到启动和运行时的处理流程中,用户只需根据具体项目需求选择功能安全库提供的诊断接口和配置对应的初始化配置即可。function_safety_init初始化相关接口是基于功能安全各子系统handle句柄的相关配置,是底层驱动和function_safety中间件之间的适配层,generatecode是基于IDE配置生成的芯片初始化配置代码,是底层驱动和芯片之间的适配层。功能安全中间件处理流程提供了诊断前备份功能和诊断后恢复功能,需要用户根据实际项目封装对应的接口,通过process配置注册到对应的函数指针上即可完成无损诊断,用户根据实际工程应用配置底层驱动初始化代码,诊断前调用备份函数备份工程应用的初始化配置,诊断后恢复功能应用的初始化配置,不影响用户实际应用的初始化配置,便于用户工程应用的配置集成。 + +**【示例配置】** ++ contexBackupFunc 上下文备份配置(可选):通过上下文备份可以实现实际应用的无损诊断,用于诊断前备份用户通过IDE配置生成的实际工程应用底层驱动配置。 + ++ handleConfigFunc 功能安全适配层初始化配置(可选):用于配置各子系统诊断函数所需的初始化配置,该适配层可完成底层驱动配置的修改和上层诊断指标的设定。 + ++ diagnoseFunc 诊断函数配置(可选):功能安全诊断接口,用户可选择function_safety中间件提供的各子系统诊断接口,也可自行封装对应的诊断接口。 + ++ failSafeFunc 失效安全函数配置(可选):基于诊断结果实施失效安全配置,该示例中为了便于演示,默认配置均为while(1)死循环的方式定住程序。该函数为__weak函数,用户可自定义进行钩子函数挂载。 + ++ faultPredictFunc 故障预测函数配置(可选):该功能function_safety安全包暂未提供,主要用于诊断正常的前提下进行故障预测。 + ++ contexResumeFunc 上下文恢复配置(可选):诊断后上下文配置恢复函数,诊断完成后恢复工程应用的底层驱动配置。示例中暂未提供,用户可根据实际项目进行配置封装接口。 + ++ contexHandle 上下文备份恢复参数句柄(可选):上下文备份和恢复的句柄指针,可用户指向备份区。 + ++ diagnoseHandle 诊断参数句柄(可选):诊断函数入参,用户可按照结构体定义进行配置。 + ++ failSafeHandle 失效安全参数句柄(可选):失效安全函数入参,用户可按照结构体定义进行配置。 + ++ faultPredictHandle 故障预测参数句柄(可选):故障预测函数入参,用户可按照结构体定义进行配置。 + ++ moment 诊断时刻参数句柄(可选):故障预测函数入参,用户可按照结构体定义进行配置。 + ++ timeCycleRecordSwitch 时间cycle测量开关(可选):默认不开,用户可配置是否开启,用于记录打印处理流程中各阶段的耗时以及状态。 + + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,通过串口可以看到启动和运行时处理流程process的诊断信息,包含功能安全状态码,状态码的含义可以参照FunctionSafetyState结构体的位定义,每个子系统的模块和特性在对应头文件中右定义,通过功能安全状态码能了解当前诊断的子系统和模块以及特性的诊断结果和时间性能。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPIRH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 ++ 必须勾选上工程配置菜单中的“生成CRC”选项,ROM测试会用到,否则ROM完整性诊断会报异常,且不可通过仿真模式进行烧录,否则会缺少bin文件末尾的CRC校验码、 ++ 如果诊断出看门狗复位异常时想消除该异常,则目标板需要重新上下电,否则会一直检测到看门狗复位异常。 \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/config/nos_config.h b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_entry/function_safety_entry.c similarity index 58% rename from src/middleware/hisilicon/nostask/config/nos_config.h rename to src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_entry/function_safety_entry.c index e52417b30acfdc6cc2fe6c4729e0a2114e9ed9d4..3d86ef61fb9f6d65ef42168b9ff66a57fd941eb7 100644 --- a/src/middleware/hisilicon/nostask/config/nos_config.h +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_entry/function_safety_entry.c @@ -15,36 +15,40 @@ * 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. - * @file nos_config.h + * @file function_safety_startup.c + * @author MCU Driver Team + * @brief function safety startup module. + * @details function safety startup interface implementation. */ -#ifndef NOS_CONFIG_H -#define NOS_CONFIG_H +#include "debug.h" +#include "main.h" +#include "function_safety_init.h" +#include "function_safety_startup.h" +#include "function_safety_runtime.h" +#include "function_safety_entry.h" -#include "nos_buildef.h" -#include "nos_typedef.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif -#endif - -/* ***************************** 配置任务模块 ******************************* */ -/* 任务模块裁剪开关 */ -#define OS_INCLUDE_TASK YES -/* 最大支持的任务数,软中断和任务最大共支持254个 */ -#define OS_TSK_MAX_SUPPORT_NUM 5 -/* 缺省的任务栈大小 */ -#define OS_TSK_DEFAULT_STACK_SIZE 0x200 -/* IDLE任务栈的大小 */ -#define OS_TSK_IDLE_STACK_SIZE 0x150 -/* 任务栈初始化魔术字,默认是0xCA,只支持配置一个字节 */ -#define OS_TSK_STACK_MAGIC_WORD 0xCACACACA - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cpluscplus */ -#endif /* __cpluscplus */ - -#endif /* NOS_CONFIG_H */ +/** + * @brief Excute function safety entry. + * @param None. + * @retval None. + */ +void FunctionSafetyEntry(void) +{ + SystemInit(); + DBG_PRINTF("*** Function Safety Startup Process Begin *** \r\n"); + FunctionSafetyStartupProcess(); + DBG_PRINTF("*** Function Safety Startup Process End*** \r\n"); + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + DBG_PRINTF("\r\n*** Function Safety Runtime Process Begin *** \r\n"); + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + FunctionSafetyRuntimeProcess(); + HAL_WDG_Refresh(g_diagnoseMonitor.wdgHandle); + HAL_IWDG_Refresh(g_diagnoseMonitor.iwdgHandle); + BASE_FUNC_DELAY_MS(50); /* 50 : delay time 50ms */ + /* USER CODE END 4 */ + } +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_entry/function_safety_entry.h b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_entry/function_safety_entry.h new file mode 100644 index 0000000000000000000000000000000000000000..deebe3735cbf24e2f003c05d5e8341d63cc3477f --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_entry/function_safety_entry.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_entry.h + * @author MCU Driver Team + * @brief function safety entry module. + * @details function safety entry interface declaration. + */ + +#ifndef FUNCTION_SAFETY_ENTRY_H +#define FUNCTION_SAFETY_ENTRY_H + +void FunctionSafetyEntry(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_init/function_safety_config.h b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_init/function_safety_config.h new file mode 100644 index 0000000000000000000000000000000000000000..987beab9dfab99e231322ac0f85f7382007c193c --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_init/function_safety_config.h @@ -0,0 +1,47 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_config.h + * @author MCU Driver Team + * @brief This file contains the config of function safety + */ + +#ifndef FUNCTION_SAFETY_CONFIG_H +#define FUNCTION_SAFETY_CONFIG_H +/* ---------------------------------------- INCLUDE ----------------------------------- */ +/* ----------------------------------------PROCESS------------------------------------ */ +/* ----------------------------------------RAM Test------------------------------------ */ +/* Parameters are used during the RAM test, performed using March-C Algorithm */ +#define BCKGRND_PATTERN 0x00000000U +#define INV_BCKGRND_PATTERN 0xFFFFFFFFU + +/* Constants necessary for execution initial March test */ +#define STARTUP_RAM_START ((unsigned int *)0x04000000U) +#define STARTUP_RAM_END ((unsigned int *)0x04004000U) + +/* Constants necessary for execution of transparent run time March tests */ +#define RUNTIME_RAM_START ((unsigned int *)0x04000000U) +#define RUNTIME_RAM_END ((unsigned int *)0x04004000U) + +/* ------------------------------------------ROM Test------------------------------------ */ +/* CRC checks the ROM region result */ +#define ROM_START ((unsigned int *)0x03000000U) +#define FLASH_BLOCK_SIZE_IN_WORD 4 +#define EFLASH_ECC_INT_ENABLE_VALUE 0x000C0000 +/* ------------------------------------------AIO Test------------------------------------ */ + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_init/function_safety_init.c b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_init/function_safety_init.c new file mode 100644 index 0000000000000000000000000000000000000000..c945c2806837e18974cd7de28fe8596e9bb91454 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_init/function_safety_init.c @@ -0,0 +1,565 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_init.c + * @author MCU Driver Team + * @brief function safety library adapter layer init. + * @details function safety library adapter layer init interface. + */ +#include "main.h" +#include "function_safety_config.h" +#include "function_safety_init.h" + +CORE_DiagnoseHandle g_diagnoseCore = {0}; +ANA_DiagnoseHandle g_diagnoseAna = {0}; +CLOCK_DiagnoseHandle g_diagnoseClock = {0}; +COMPUTE_DiagnoseHandle g_diagnoseCompute = {0}; +DIO_DiagnoseHandle g_diagnoseDio = {0}; +MONITOR_DiagnoseHandle g_diagnoseMonitor = {0}; +RAM_DiagnoseHandle g_diagnoseRam = {0}; +ROM_DiagnoseHandle g_diagnoseRom = {0}; +TIMERS_DiagnoseHandle g_diagnoseTimers = {0}; +CONNECT_DiagnoseHandle g_diagnoseConnect = {0}; +/*--------------------------------- analog diagnose enviroment init ----------------------------------------*/ +/** + * @brief ANA subsysterm's adc1 accuracy diagnose init. + * @param None. + * @retval None. + */ +void ANA_DiagnoseAdc1AccuracyInit(void) +{ + g_diagnoseAna.adcHandle = &DIAGNOSE_ADC1_HANDLE; + g_diagnoseAna.dacHandleRef = &g_dac1; /* dac output to adc */ + g_diagnoseAna.socx = DIAGNOSE_ADC1_SOC; + g_diagnoseAna.adcMaxRange = 4096; /* 4096 : max range of adc */ + g_diagnoseAna.dacMaxRange = 256; /* 256 : max range of dac */ + g_diagnoseAna.errRangePercent = 100; /* 100: adc value error range */ + DCL_ADC_SOCxSelectChannel(g_diagnoseAna.adcHandle->baseAddress, g_diagnoseAna.socx, DIAGNOSE_ADC1_CHANNEL); +} +/** + * @brief ANA subsysterm's adc2 accuracy diagnose init. + * @param None. + * @retval None. + */ +void ANA_DiagnoseAdc2AccuracyInit(void) +{ + g_diagnoseAna.adcHandle = &DIAGNOSE_ADC2_HANDLE; + g_diagnoseAna.dacHandleRef = &g_dac2; /* dac output to adc */ + g_diagnoseAna.socx = DIAGNOSE_ADC2_SOC; + g_diagnoseAna.adcMaxRange = 4096; /* 4096 : max range of adc */ + g_diagnoseAna.dacMaxRange = 256; /* 256 : max range of dac */ + g_diagnoseAna.errRangePercent = 100; /* 100: adc value error range */ + DCL_ADC_SOCxSelectChannel(g_diagnoseAna.adcHandle->baseAddress, g_diagnoseAna.socx, DIAGNOSE_ADC2_CHANNEL); +} +/*--------------------------------- clock diagnose enviroment init ----------------------------------------*/ +/** + * @brief CLock subsysterm's systerm clock single accuracy diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseSysClockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's hosc clock single accuracy diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseHoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's losc clock single accuracy diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseLoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_LOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_0; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's tcxo clock accuracy single diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnoseTcxoCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_TCXO; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 2000; /* 2000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's systerm clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseSysClockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's hosc clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseHoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_HOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HS_SYS; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's losc clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseLoscCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_LOSC; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_0; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's tcxo clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnoseTcxoCLockAccuracyInit(void) +{ + g_diagnoseClock.cmmHandle = &g_cmm; + g_diagnoseClock.cmmHandle->targetClockSource = CMM_TARGET_CLK_TCXO; + g_diagnoseClock.cmmHandle->targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; + g_diagnoseClock.cmmHandle->refClockSource = CMM_REF_CLK_HOSC; + g_diagnoseClock.cmmHandle->refFreqDivision = CMM_REF_FREQ_DIV_32; + g_diagnoseClock.cmmHandle->interruptType = CMM_INT_FREQ_ERR_MASK; + g_diagnoseClock.errRangePercent = 10; /* 10: cmm windows value error range */ + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); /* stop cmm monitor clock frequency */ + BASE_FUNC_DELAY_US(200); /* 200: wait cmm stable */ + CLOCK_CmmWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CMM_Init(g_diagnoseClock.cmmHandle); + HAL_CMM_Start(g_diagnoseClock.cmmHandle); /* start cmm monitor clock frequency */ +} +/** + * @brief CLock subsysterm's pll ref clock accuracy single diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_SingleDiagnosePllRefCLockStopInit(void) +{ + g_diagnoseClock.cfdHandle = &g_cfd; + g_diagnoseClock.cfdHandle->interruptType = CFD_INT_CHECK_END_MASK; + g_diagnoseClock.checkEndDelayTimeUs = 1000; /* 1000: wait check end interrupt */ + g_diagnoseClock.errRangePercent = 10; /* 10: cfd windows value error range */ + HAL_CFD_Stop(g_diagnoseClock.cfdHandle); /* stop cfd monitor clock stop */ + BASE_FUNC_DELAY_US(200); /* 200: wait cfd stable */ + CLOCK_CfdWindowsBoundCalculate(&g_diagnoseClock, MOMENT_STARTUP); /* calculate windows bound with error range */ + HAL_CFD_Init(g_diagnoseClock.cfdHandle); + HAL_CFD_Start(g_diagnoseClock.cfdHandle); /* start cfd monitor clock stop */ +} +/** + * @brief CLock subsysterm's pll ref clock accuracy continue diagnose init. + * @param None. + * @retval None. + */ +void CLOCK_ContinueDiagnosePllRefCLockStopInit(void) +{ + g_diagnoseClock.cfdHandle = &g_cfd; + g_diagnoseClock.cfdHandle->interruptType = CFD_INT_PLL_REF_CLOCK_STOP_MASK; + g_diagnoseClock.errRangePercent = 50; /* 50: cfd windows value error range */ + HAL_CFD_Stop(g_diagnoseClock.cfdHandle); /* stop cfd monitor clock stop */ + BASE_FUNC_DELAY_US(200); /* 200: wait cfd stable */ + CLOCK_CfdWindowsBoundCalculate(&g_diagnoseClock, MOMENT_RUNTIME); /* calculate windows bound with error range */ + HAL_CFD_Init(g_diagnoseClock.cfdHandle); + HAL_CFD_Start(g_diagnoseClock.cfdHandle); /* start cfd monitor clock stop */ + BASE_FUNC_DELAY_US(200); /* 200 : wait clock stabilization */ +} +/*--------------------------------- compute diagnose enviroment init ----------------------------------------*/ +/** + * @brief Compute subsysterm's crc32 calculate correct diagnose init. + * @param None. + * @retval None. + */ +void COMPUTE_DiagnoseCrcInit(void) +{ + g_diagnoseCompute.crcHandle = &g_crc; + g_diagnoseCompute.inputTestData = 0xADDAA55A; /* 0xADDAA55A: input test data */ + g_diagnoseCompute.inputDataSize = 4; /* 4: 32bit width */ + g_diagnoseCompute.outputRefData = 0x89F75D91; /* 0x89F75D91: output ref data */ +} +/*--------------------------------- monitor diagnose enviroment init ----------------------------------------*/ +/** + * @brief Monitor subsysterm's wdg reset function diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseWdgResetInit(void) +{ + g_diagnoseMonitor.wdgHandle = &g_wdg; + g_diagnoseMonitor.startupResetTimeUs = 100; /* 100: wdg startup reset time interval */ + HAL_WDG_Stop(g_diagnoseMonitor.wdgHandle); /* stop wdg */ + HAL_WDG_SetTimeValue(g_diagnoseMonitor.wdgHandle, g_diagnoseMonitor.startupResetTimeUs, WDG_TIME_UNIT_US); +} + +/** + * @brief Monitor subsysterm's wdg program stuck diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseWdgProgramStuckInit(void) +{ + g_diagnoseMonitor.wdgHandle = &g_wdg; + g_diagnoseMonitor.startupResetTimeUs = 1000000; /* 1000000: wdg runtime reset time interval */ + HAL_WDG_Stop(g_diagnoseMonitor.wdgHandle); /* stop wdg */ + HAL_WDG_SetTimeValue(g_diagnoseMonitor.wdgHandle, g_diagnoseMonitor.startupResetTimeUs, WDG_TIME_UNIT_US); + HAL_WDG_Start(g_diagnoseMonitor.wdgHandle); +} +/** + * @brief Monitor subsysterm's iwdg reset function diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseIwdgResetInit(void) +{ + g_diagnoseMonitor.iwdgHandle = &g_iwdg; + g_diagnoseMonitor.startupResetTimeUs = 100; /* 100: iwdg startup reset time interval */ + HAL_IWDG_Stop(g_diagnoseMonitor.iwdgHandle); /* stop iwdg */ + HAL_IWDG_SetTimeValue(g_diagnoseMonitor.iwdgHandle, g_diagnoseMonitor.startupResetTimeUs, IWDG_TIME_UNIT_US); +} + +/** + * @brief Monitor subsysterm's iwdg program stuck diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseIwdgProgramStuckInit(void) +{ + g_diagnoseMonitor.iwdgHandle = &g_iwdg; + g_diagnoseMonitor.startupResetTimeUs = 1000000; /* 1000000: iwdg runtime reset time interval */ + HAL_IWDG_Stop(g_diagnoseMonitor.iwdgHandle); /* stop iwdg */ + HAL_IWDG_SetTimeValue(g_diagnoseMonitor.iwdgHandle, g_diagnoseMonitor.startupResetTimeUs, IWDG_TIME_UNIT_US); + HAL_IWDG_Start(g_diagnoseMonitor.iwdgHandle); +} +/** + * @brief Monitor subsysterm's pmc voltage low power diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnosePmcLowPowerInit(void) +{ + g_diagnoseMonitor.pmcHandle = &g_pmc; /* monitor of pmc */ +} +/** + * @brief Monitor subsysterm's tsensor over temperature diagnose init. + * @param None. + * @retval None. + */ +void MONITOR_DiagnoseTsensorOverTemperatureInit(void) +{ + g_diagnoseMonitor.overTemperatureValue = 90; /* 90: over temperature value */ + HAL_TSENSOR_Init(); +} +/*--------------------------------- ram diagnose enviroment init ----------------------------------------*/ +/** + * @brief Ram subsysterm's startup diagnose init. + * @param None. + * @retval None. + */ +void RAM_DiagnoseStartupInit(void) +{ + g_diagnoseRam.sramStartAddr = STARTUP_RAM_START; /* ram start address */ + g_diagnoseRam.sramCurrentAddr = STARTUP_RAM_START; /* rom current address */ + g_diagnoseRam.sramCurrentAddrInv = (unsigned int *)(~(unsigned int)(void*)g_diagnoseRam.sramCurrentAddr); + g_diagnoseRam.sramEndAddr = STARTUP_RAM_END; + g_diagnoseRam.sramPattern = BCKGRND_PATTERN; +} +/** + * @brief Ram subsysterm's runtime diagnose init. + * @param None. + * @retval None. + */ +void RAM_DiagnoseRuntimeInit(void) +{ + g_diagnoseRam.sramStartAddr = RUNTIME_RAM_START; /* ram start address */ + g_diagnoseRam.sramCurrentAddr = RUNTIME_RAM_START; /* rom current address */ + g_diagnoseRam.sramCurrentAddrInv = (unsigned int *)(~(unsigned int)(void*)g_diagnoseRam.sramCurrentAddr); + g_diagnoseRam.sramEndAddr = RUNTIME_RAM_END; + g_diagnoseRam.sramPattern = BCKGRND_PATTERN; +} +/*--------------------------------- rom diagnose enviroment init ----------------------------------------*/ +/** + * @brief Rom subsysterm's intgrity diagnose init. + * @param None. + * @retval None. + */ +void ROM_DiagnoseIntegrityInit(void) +{ + g_diagnoseRom.crcHandle = &g_crc; + g_diagnoseRom.startAddr = ROM_START; /* rom start address */ + g_diagnoseRom.indexPointer = ROM_START; /* rom end address */ + g_diagnoseRom.indexPointerInv = (unsigned int *)(~(unsigned int)(void*)ROM_START); + g_diagnoseRom.flashBlockSizeInWords = FLASH_BLOCK_SIZE_IN_WORD; +} +/** + * @brief Rom subsysterm's flash ecc diagnose init. + * @param None. + * @retval None. + */ +void ROM_DiagnoseFlashEccInit(void) +{ + g_diagnoseRom.flashBase = EFC; /* ecc function in eflash reg */ + g_diagnoseRom.eccIntRegVal = EFLASH_ECC_INT_ENABLE_VALUE; +} +/*--------------------------------- timers diagnose enviroment init ----------------------------------------*/ +/** + * @brief Timers subsysterm's timer0 interrupt interval diagnose init. + * @param None. + * @retval None. + */ +void TIMERS_DiagnoseTimer0InterruptIntervalInit(void) +{ + g_diagnoseTimers.timerHandle = &g_timer0; + g_diagnoseTimers.setTimeUs = 1000; /* 1000: timer interval */ + g_diagnoseTimers.errRangeUs = 1; /* 1: 1us error range */ + g_diagnoseTimers.timerHandle->load = (HAL_CRG_GetIpFreq((void *)TIMER0) / 1000000u) * g_diagnoseTimers.setTimeUs; + g_diagnoseTimers.timerHandle->bgLoad = g_diagnoseTimers.timerHandle->load; + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_LOAD); /* config load time */ + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_BGLOAD); /* config bgload time */ + g_diagnoseTimers.pretimeCycle = BASE_FUNC_GetTick(); + HAL_TIMER_Start(g_diagnoseTimers.timerHandle); + BASE_FUNC_DELAY_US(1500); /* 1500 : wait timer interrupt */ +} +/** + * @brief Timers subsysterm's timer1 interrupt interval diagnose init. + * @param None. + * @retval None. + */ +void TIMERS_DiagnoseTimer1InterruptIntervalInit(void) +{ + g_diagnoseTimers.timerHandle = &g_timer1; + g_diagnoseTimers.setTimeUs = 1000; /* 1000: timer interval */ + g_diagnoseTimers.errRangeUs = 1; /* 1: 1us error range */ + g_diagnoseTimers.timerHandle->load = (HAL_CRG_GetIpFreq((void *)TIMER1) / 1000000u) * g_diagnoseTimers.setTimeUs; + g_diagnoseTimers.timerHandle->bgLoad = g_diagnoseTimers.timerHandle->load; + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_LOAD); /* config load time */ + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_BGLOAD); /* config bgload time */ + g_diagnoseTimers.pretimeCycle = BASE_FUNC_GetTick(); + HAL_TIMER_Start(g_diagnoseTimers.timerHandle); + BASE_FUNC_DELAY_US(1500); /* 1500 : wait timer interrupt */ +} +/** + * @brief Timers subsysterm's timer2 interrupt interval diagnose init. + * @param None. + * @retval None. + */ +void TIMERS_DiagnoseTimer2InterruptIntervalInit(void) +{ + g_diagnoseTimers.timerHandle = &g_timer2; + g_diagnoseTimers.setTimeUs = 1000; /* 1000: timer interval */ + g_diagnoseTimers.errRangeUs = 1; /* 1: 1us error range */ + g_diagnoseTimers.timerHandle->load = (HAL_CRG_GetIpFreq((void *)TIMER2) / 1000000u) * g_diagnoseTimers.setTimeUs; + g_diagnoseTimers.timerHandle->bgLoad = g_diagnoseTimers.timerHandle->load; + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_LOAD); /* config load time */ + HAL_TIMER_Config(g_diagnoseTimers.timerHandle, TIMER_CFG_BGLOAD); /* config bgload time */ + g_diagnoseTimers.pretimeCycle = BASE_FUNC_GetTick(); + HAL_TIMER_Start(g_diagnoseTimers.timerHandle); + BASE_FUNC_DELAY_US(1500); /* 1500 : wait timer interrupt */ +} +/*--------------------------------- irq diagnose enviroment init ----------------------------------------*/ +/** + * @brief CFD check end callback function. + * @param handle @ref CFD_Handle. + * @retval None. + */ +void CFDCheckEndCallback(CFD_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cfdIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cfdClockCount = DCL_CFD_GetCntValue(g_diagnoseClock.cfdHandle->baseAddress); + HAL_CFD_Stop(g_diagnoseClock.cfdHandle); +} +/** + * @brief CFD clock stop callback function. + * @param handle @ref CFD_Handle. + * @retval None. + */ +void CFDClockStopCallback(CFD_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cfdIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cfdClockCount = DCL_CFD_GetCntValue(g_diagnoseClock.cfdHandle->baseAddress); +} +/** + * @brief CMM check end callback function. + * @param handle @ref CMM_Handle. + * @retval None. + */ +void CMMCheckEndCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cmmIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cmmClockCount = DCL_CMM_GetCntValue(g_diagnoseClock.cmmHandle->baseAddress); + HAL_CMM_Stop(g_diagnoseClock.cmmHandle); +} +/** + * @brief CMM frequency error callback function. + * @param handle @ref CMM_Handle. + * @retval None. + */ +void CMMFreqErrorCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseClock.cmmIrqFlag = true; /* set irq flag */ + g_diagnoseClock.cmmClockCount = DCL_CMM_GetCntValue(g_diagnoseClock.cmmHandle->baseAddress); +} +/** + * @brief PMC low poer callback function. + * @param handle @ref PMC_Handle. + * @retval None. + */ +void PMCPVDInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseMonitor.pmcIrqFlag = true; /* set irq flag */ +} +/** + * @brief Timer0 interrupt callback function. + * @param handle @ref Timer_Handle. + * @retval None. + */ +void TIMER0CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseTimers.timerIrqFlag =true; /* set irq flag */ + g_diagnoseTimers.currenttimeCycle = BASE_FUNC_GetTick(); + /* duration cycle calculate */ + unsigned int durationCycle = (g_diagnoseTimers.currenttimeCycle > g_diagnoseTimers.pretimeCycle) ? \ + (g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle) : \ + (SYSTICK_MAX_VALUE + g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle + 1); + g_diagnoseTimers.durationUs = durationCycle / HAL_CRG_GetCoreClkFreq() / CRG_FREQ_1MHz; + g_diagnoseTimers.pretimeCycle = g_diagnoseTimers.currenttimeCycle; /* prepare for next calculate */ +} +/** + * @brief Timer1 interrupt callback function. + * @param handle @ref Timer_Handle. + * @retval None. + */ +void TIMER1CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseTimers.timerIrqFlag =true; /* set irq flag */ + g_diagnoseTimers.currenttimeCycle = BASE_FUNC_GetTick(); + /* duration cycle calculate */ + unsigned int durationCycle = (g_diagnoseTimers.currenttimeCycle > g_diagnoseTimers.pretimeCycle) ? \ + (g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle) : \ + (SYSTICK_MAX_VALUE + g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle + 1); + g_diagnoseTimers.durationUs = durationCycle / HAL_CRG_GetCoreClkFreq() / CRG_FREQ_1MHz; + g_diagnoseTimers.pretimeCycle = g_diagnoseTimers.currenttimeCycle; /* prepare for next calculate */ +} +/** + * @brief Timer2 interrupt callback function. + * @param handle @ref Timer_Handle. + * @retval None. + */ +void TIMER2CallbackFunction(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_diagnoseTimers.timerIrqFlag =true; /* set irq flag */ + g_diagnoseTimers.currenttimeCycle = BASE_FUNC_GetTick(); + /* duration cycle calculate */ + unsigned int durationCycle = (g_diagnoseTimers.currenttimeCycle > g_diagnoseTimers.pretimeCycle) ? \ + (g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle) : \ + (SYSTICK_MAX_VALUE + g_diagnoseTimers.currenttimeCycle - g_diagnoseTimers.pretimeCycle + 1); + g_diagnoseTimers.durationUs = durationCycle / HAL_CRG_GetCoreClkFreq() / CRG_FREQ_1MHz; + g_diagnoseTimers.pretimeCycle = g_diagnoseTimers.currenttimeCycle; /* prepare for next calculate */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_init/function_safety_init.h b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_init/function_safety_init.h new file mode 100644 index 0000000000000000000000000000000000000000..f3db302af35ce4a951e567f7e4e3aa0d9c87395b --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_init/function_safety_init.h @@ -0,0 +1,69 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_init.h + * @author MCU Driver Team + * @brief function safety library adapter layer init. + * @details function safety library adapter layer init + */ + +#ifndef FUNCTION_SAFETY_INIT_H +#define FUNCTION_SAFETY_INIT_H + +#include "function_safety_mcu.h" +#include "function_safety_config.h" + +extern CORE_DiagnoseHandle g_diagnoseCore; +extern ANA_DiagnoseHandle g_diagnoseAna; +extern CLOCK_DiagnoseHandle g_diagnoseClock; +extern COMPUTE_DiagnoseHandle g_diagnoseCompute; +extern DIO_DiagnoseHandle g_diagnoseDio; +extern MONITOR_DiagnoseHandle g_diagnoseMonitor; +extern RAM_DiagnoseHandle g_diagnoseRam; +extern ROM_DiagnoseHandle g_diagnoseRom; +extern TIMERS_DiagnoseHandle g_diagnoseTimers; +extern CONNECT_DiagnoseHandle g_diagnoseConnect; + +void ANA_DiagnoseAdc0AccuracyInit(void); +void ANA_DiagnoseAdc1AccuracyInit(void); +void ANA_DiagnoseAdc2AccuracyInit(void); +void CLOCK_SingleDiagnoseSysClockAccuracyInit(void); +void CLOCK_SingleDiagnoseHoscCLockAccuracyInit(void); +void CLOCK_SingleDiagnoseLoscCLockAccuracyInit(void); +void CLOCK_SingleDiagnoseTcxoCLockAccuracyInit(void); +void CLOCK_ContinueDiagnoseSysClockAccuracyInit(void); +void CLOCK_ContinueDiagnoseHoscCLockAccuracyInit(void); +void CLOCK_ContinueDiagnoseLoscCLockAccuracyInit(void); +void CLOCK_ContinueDiagnoseTcxoCLockAccuracyInit(void); +void CLOCK_SingleDiagnosePllRefCLockStopInit(void); +void CLOCK_ContinueDiagnosePllRefCLockStopInit(void); +void COMPUTE_DiagnoseCrcInit(void); +void MONITOR_DiagnoseWdgResetInit(void); +void MONITOR_DiagnoseWdgProgramStuckInit(void); +void MONITOR_DiagnoseIwdgResetInit(void); +void MONITOR_DiagnoseIwdgProgramStuckInit(void); +void MONITOR_DiagnosePmcLowPowerInit(void); +void MONITOR_DiagnoseTsensorOverTemperatureInit(void); +void RAM_DiagnoseStartupInit(void); +void RAM_DiagnoseRuntimeInit(void); +void ROM_DiagnoseIntegrityInit(void); +void ROM_DiagnoseFlashEccInit(void); +void TIMERS_DiagnoseTimer0InterruptIntervalInit(void); +void TIMERS_DiagnoseTimer1InterruptIntervalInit(void); +void TIMERS_DiagnoseTimer2InterruptIntervalInit(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_report/function_safety_report.c b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_report/function_safety_report.c new file mode 100644 index 0000000000000000000000000000000000000000..5838fd41f2bd3bc3e23c3570d968de0b71ffacbe --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_report/function_safety_report.c @@ -0,0 +1,88 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_report.c + * @author MCU Driver Team + * @brief function safety report module. + * @details function safety report interface implementation. + */ + +#include "function_safety_report.h" +#include "debug.h" +#include "iocmg.h" +/** + * @brief rigister soft irq callback and prioerity , callback param. + * @param handlerFunc irq callback function. + * @param priority irq priority. + * @param param irq callback param. + * @retval None. + */ +void RegisterReportFailEventHandler(IRQ_PROC_FUNC handlerFunc, unsigned int priority, void *param) +{ + IRQ_DisableN(IRQ_SOFTWARE); + IRQ_Unregister(IRQ_SOFTWARE); /* unregister soft irq */ + IRQ_Register(IRQ_SOFTWARE, handlerFunc, param); /* register soft irq callback and param */ + IRQ_SetPriority(IRQ_SOFTWARE, priority); /* set soft irq priority */ + IRQ_EnableN(IRQ_SOFTWARE); +} +/** + * @brief soft irq callback of report fail event. + * @param param irq callback param. + * @retval None. + */ +void ReportFailEventLogBySoftIrq(void *param) +{ + BASE_FUNC_UNUSED(param); + DCL_SYSCTRL_ClearSoftInterrupt(); /* clear soft irq */ + IRQ_ClearN(IRQ_SOFTWARE); + IRQ_Disable(); + FunctionSafetyState failEvent = STATE_LoadFailEvent(); /* load fail event */ + DBG_PRINTF("Fail Event Info : FailEvent[0x%x], Subsysterm [%d], Module [%d], Feature [%d], Failtype [%d]\r\n", \ + failEvent, failEvent.BIT.subsysterm, failEvent.BIT.moudule, failEvent.BIT.feature, failEvent.BIT.faultType); +} + +/** + * @brief Excute function safety process and return state. + * @param state @ref FunctionSafetyState. + * @param processTime @ref ProcessTimeCycle. + * @retval None. + */ +void FunctionSafetyProcessPrint(FunctionSafetyState state, ProcessTimeCycle processTime) +{ + if (!processTime.timeCycleRecordSwitch) { + return; + } + if (state.BIT.result == RESULT_FAIL) { /* result fail judgement */ + DBG_PRINTF("\r\nFAIL info : State[0x%x], Subsysterm[%d], Module[%d], Feature[%d], Failtype[%d] \ + \r\n DiagnoseCycle[%d], FailSafeCycle[%d], FaultPredictCycle[%d]\r\n", \ + state, state.BIT.subsysterm, state.BIT.moudule, state.BIT.feature, state.BIT.faultType, \ + processTime.diagnoseTimeCycle, processTime.failSafeTimeCycle, processTime.faultPredictTimeCycle); + } else { + if (state.BIT.result == RESULT_SUCCESS) { /* result success judgement */ + DBG_PRINTF("\r\nSUCCESS info : State [0x%x], Subsysterm [%d], Module [%d], Feature [%d] \ + \r\n DiagnoseCycle[%d], FailSafeCycle[%d], FaultPredictCycle[%d]\r\n", \ + state, state.BIT.subsysterm, state.BIT.moudule, state.BIT.feature,\ + processTime.diagnoseTimeCycle, processTime.failSafeTimeCycle, processTime.faultPredictTimeCycle); + } + if (state.BIT.result == RESULT_IS_RUNNING) { /* result ongoing judgement */ + DBG_PRINTF("\r\nRUNNING info : State [0x%x], Subsysterm [%d], Module [%d], Feature [%d] \ + \r\n DiagnoseCycle[%d], FailSafeCycle[%d], FaultPredictCycle[%d]\r\n", \ + state, state.BIT.subsysterm, state.BIT.moudule, state.BIT.feature,\ + processTime.diagnoseTimeCycle, processTime.failSafeTimeCycle, processTime.faultPredictTimeCycle); + } + } +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_report/function_safety_report.h b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_report/function_safety_report.h new file mode 100644 index 0000000000000000000000000000000000000000..ecbe454705446846726f3a4568565be3056fa8a4 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_report/function_safety_report.h @@ -0,0 +1,43 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_report.h + * @author MCU Driver Team + * @brief function safety report module. + * @details function safety report interface declaration. + */ + +#ifndef FUNCTION_SAFETY_REPORT_H +#define FUNCTION_SAFETY_REPORT_H + +#include "function_safety_mcu.h" + +/** + * @brief Triggle soft irq send fail event. + * @param None. + * @retval None. + */ +static inline void TriggerSoftIrqSendFailEvent(void) +{ + return DCL_SYSCTRL_GenerateSoftInterrupt(); +} + +void RegisterReportFailEventHandler(IRQ_PROC_FUNC handlerFunc, unsigned int priority, void *param); +void ReportFailEventLogBySoftIrq(void *param); +void FunctionSafetyProcessPrint(FunctionSafetyState state, ProcessTimeCycle processTime); + +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/include/common/os_sched.h b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_runtime/function_safety_runtime.c similarity index 32% rename from src/middleware/hisilicon/nostask/include/common/os_sched.h rename to src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_runtime/function_safety_runtime.c index ecda0b7098d139b1c836c2935c5aa0c404bf32cd..dce70670c0330ea15738cf3ffba30a7ba6d0f9cf 100644 --- a/src/middleware/hisilicon/nostask/include/common/os_sched.h +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_runtime/function_safety_runtime.c @@ -15,107 +15,91 @@ * 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. - * @file os_sched.h + * @file function_safety_runtime.c + * @author MCU Driver Team + * @brief function safety runtime module. + * @details function safety runtime interface implementation. */ -#ifndef OS_SCHED_H -#define OS_SCHED_H +#include "main.h" +#include "function_safety_init.h" +#include "function_safety_process.h" +#include "function_safety_report.h" +#include "function_safety_runtime.h" -#include "os_errno.h" -#include "os_module.h" +FunctionSafetyProcessHandle g_fuSaRuntimeProcess[] = { + { + .diagnoseFunc = CORE_DiagnoseCpuStatus, /* cpu status diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = CORE_DiagnoseCpuGeneralRegister, /* cpu general register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = CORE_DiagnosePcRegister, /* cpu pc register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_RUNTIME + }, + { + .handleConfigFunc = RAM_DiagnoseRuntimeInit, /* ram step diagnose */ + .diagnoseFunc = RAM_DiagnoseSramByMarchAlgorithm, + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = RAM_DiagnoseSramByParityCheck, /* ram parity diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_RUNTIME + }, + { + .diagnoseFunc = RAM_DiagnoseStackOverflow, /* ram stack overflow diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_RUNTIME + }, + { + .handleConfigFunc = ROM_DiagnoseIntegrityInit, /* rom intergrity diagnose */ + .diagnoseFunc = ROM_DiagnoseIntegrity, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_RUNTIME + }, + { + .handleConfigFunc = ROM_DiagnoseFlashEccInit, /* flash ecc diagnose */ + .diagnoseFunc = ROM_DiagnoseFlashEcc, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_RUNTIME + } +}; +/* runtime function safety iterm size */ +const unsigned int RUNTIME_PROCESS_ARRAY_SIZE = sizeof(g_fuSaRuntimeProcess) / sizeof(g_fuSaRuntimeProcess[0]); -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -/* - * 调度模块的错误码定义。 - */ -/* - * @ingroup OS_sched - * 调度错误码:调度域配置参数非法。 - * - * 值: 0x02004c01 - * - * 解决方案: 检查调度域配置参数的数组指针非空时配置的个数是否为0或者超过上限核数。 - */ -#define OS_ERRNO_SCHED_DOMAIN_CONFIG_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SCHED, 0x01) - -/* - * @ingroup OS_sched - * 调度错误码:调度域申请内存失败。 - * - * 值: 0x02004c02 - * - * 解决方案: 检查是否配置的调度组数目过大,或者增加内存分区的大小。 - */ -#define OS_ERRNO_SCHED_NO_MEMORY OS_ERRNO_BUILD_ERROR(OS_MID_SCHED, 0x02) - -/* - * @ingroup OS_sched - * 调度错误码:调度域参数里的核掩码为0。 - * - * 值: 0x02004c03 - * - * 解决方案: 检查配置的调度核掩码是否正确,不能全为0. - */ -#define OS_ERRNO_SCHED_DOMAIN_INFO_COREMASK_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SCHED, 0x03) - -/* - * @ingroup OS_sched - * 调度错误码:调度域参数里的调度类型不正确。 - * - * 值: 0x02004c04 - * - * 解决方案: 检查配置的调度类型请参照OsScheduleType. - */ -#define OS_ERRNO_SCHED_DOMAIN_SCHED_TYPE_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SCHED, 0x04) - -/* - * @ingroup OS_sched - * 调度错误码:调度核掩码不连续。 - * - * 值: 0x02004c05 - * - * 解决方案: 检查配置的调度核掩码是否正确,核号必须连续,充分利用核在硬件上的共享资源。 - */ -#define OS_ERRNO_SCHED_DOMAIN_CORE_MASK_NOT_CONTINUED OS_ERRNO_BUILD_ERROR(OS_MID_SCHED, 0x05) - -/* - * @ingroup OS_sched - * 调度错误码:调度核掩码间有交叉。 - * - * 值: 0x02004c06 - * - * 解决方案: 检查配置的调度域间的核掩码是否有交叉。 - */ -#define OS_ERRNO_SCHED_DOMAIN_CORE_MASK_CROSSED OS_ERRNO_BUILD_ERROR(OS_MID_SCHED, 0x06) - -/* - * @ingroup OS_sched - * 调度错误码:指针参数为空。 - * - * 值: 0x02004c07 - * - * 解决方案: 检查参数指针是否为NUL。 - */ -#define OS_ERRNO_SCHED_DOMAIN_INPUT_PTR_NULL OS_ERRNO_BUILD_ERROR(OS_MID_SCHED, 0x07) - -/* - * @ingroup OS_sched - * 调度错误码:获取调度域信息时个数为0 - * - * 值: 0x02004c08 - * - * 解决方案: 检查获取调度域信息时个数是否为0 - */ -#define OS_ERRNO_SCHED_DOMAIN_INFO_NUM_INVLID OS_ERRNO_BUILD_ERROR(OS_MID_SCHED, 0x08) - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* OS_SCHED_H */ +/** + * @brief Excute run time function safety iterm. + * @param None. + * @retval None. + */ +void FunctionSafetyRuntimeProcess(void) +{ + FunctionSafetyState state = {0}; + ProcessTimeCycle processTime = {0}; + processTime.timeCycleRecordSwitch = true; + /* excute runtime function safety iterm one by one */ + for (unsigned int i = 0; i < RUNTIME_PROCESS_ARRAY_SIZE; ++i) { + state = FunctionSafetyProcess(&g_fuSaRuntimeProcess[i], &processTime); + if (state.BIT.result == RESULT_FAIL) { + TriggerSoftIrqSendFailEvent(); /* trigger soft interrupt to notify application */ + } + if (processTime.timeCycleRecordSwitch) { + FunctionSafetyProcessPrint(state, processTime); + } + } +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_runtime/function_safety_runtime.h b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_runtime/function_safety_runtime.h new file mode 100644 index 0000000000000000000000000000000000000000..45ae4296064abe98d3e7ba319fae2e3881b62298 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_runtime/function_safety_runtime.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_runtime.h + * @author MCU Driver Team + * @brief function safety runtime module. + * @details function safety runtime interface declaration. + */ + +#ifndef FUNCTION_SAFETY_RUNTIME_H +#define FUNCTION_SAFETY_RUNTIME_H + +void FunctionSafetyRuntimeProcess(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_startup/function_safety_startup.c b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_startup/function_safety_startup.c new file mode 100644 index 0000000000000000000000000000000000000000..ea9ba62cdeac0ef43996e40ef4b75be44050e993 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_startup/function_safety_startup.c @@ -0,0 +1,226 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_startup.c + * @author MCU Driver Team + * @brief function safety startup module. + * @details function safety startup interface implementation. + */ +#include "main.h" +#include "function_safety_init.h" +#include "function_safety_process.h" +#include "function_safety_report.h" +#include "function_safety_startup.h" + +FunctionSafetyProcessHandle g_fuSaStartupProcess[] = { + { + .diagnoseFunc = CORE_DiagnoseCpuStatus, /* cpu status diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = CORE_DiagnoseCpuGeneralRegister, /* cpu general register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = CORE_DiagnoseCpuSoftwareIrq, /* cpu soft irq diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = CORE_DiagnosePcRegister, /* cpu pc register diagnose */ + .failSafeFunc = CORE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCore, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = RAM_DiagnoseStartupInit, /* ram marchx diagnose */ + .diagnoseFunc = RAM_DiagnoseSramByMarchAlgorithm, + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = RAM_DiagnoseSramByParityCheck, /* ram parity diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_STARTUP + }, + { + .diagnoseFunc = RAM_DiagnoseStackOverflow, /* ram stack overflow diagnose */ + .failSafeFunc = RAM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRam, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = CLOCK_SingleDiagnoseSysClockAccuracyInit, /* systerm clock single diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_SingleDiagnoseHoscCLockAccuracyInit, /* hosc clock single diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_SingleDiagnoseLoscCLockAccuracyInit, /* losc clock single diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_ContinueDiagnoseSysClockAccuracyInit, /* systerm clock continue diagnose */ + .diagnoseFunc = CLOCK_CmmDiagnoseAccuracy, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_SingleDiagnosePllRefCLockStopInit, /* pll ref clock single diagnose */ + .diagnoseFunc = CLOCK_CfdDiagnosePllRefClockStop, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = CLOCK_ContinueDiagnosePllRefCLockStopInit, /* pll ref clock continue diagnose */ + .diagnoseFunc = CLOCK_CfdDiagnosePllRefClockStop, + .failSafeFunc = CLOCK_FailSafeHandler, + .diagnoseHandle = &g_diagnoseClock, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = COMPUTE_DiagnoseCrcInit, /* crc calculate correct diagnose */ + .diagnoseFunc = COMPUTE_DiagnoseCrcAlgorithmCorrect, + .failSafeFunc = COMPUTE_FailSafeHandler, + .diagnoseHandle = &g_diagnoseCompute, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = ROM_DiagnoseIntegrityInit, /* rom integrity diagnose */ + .diagnoseFunc = ROM_DiagnoseIntegrity, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = ROM_DiagnoseFlashEccInit, /* rom flash ecc diagnose */ + .diagnoseFunc = ROM_DiagnoseFlashEcc, + .failSafeFunc = ROM_FailSafeHandler, + .diagnoseHandle = &g_diagnoseRom, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = MONITOR_DiagnoseWdgProgramStuckInit, /* wdg program stuck diagnose */ + .diagnoseFunc = MONITOR_DiagnoseProgramStuckByWdg, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + }, + { + .handleConfigFunc = MONITOR_DiagnoseIwdgProgramStuckInit, /* iwdg program stuck diagnose */ + .diagnoseFunc = MONITOR_DiagnoseProgramStuckByIwdg, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + }, + { + .handleConfigFunc = MONITOR_DiagnosePmcLowPowerInit, /* pmc low power diagnose */ + .diagnoseFunc = MONITOR_DiagnosePowerLowLevelByPmc, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + }, + { + .handleConfigFunc = MONITOR_DiagnoseTsensorOverTemperatureInit, /* tsensor over temperature diagnose */ + .diagnoseFunc = MONITOR_DiagnoseOverTemperatureByTsensor, + .failSafeFunc = MONITOR_FailSafeHandler, + .diagnoseHandle = &g_diagnoseMonitor, + .moment = MOMENT_ALLTIME + }, + { + .handleConfigFunc = TIMERS_DiagnoseTimer0InterruptIntervalInit, /* timer0 interrupt interval diagnose */ + .diagnoseFunc = TIMERS_DiagnoseInterruptIntervalAccuracy, + .failSafeFunc = TIMERS_FailSafeHandler, + .diagnoseHandle = &g_diagnoseTimers, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = TIMERS_DiagnoseTimer1InterruptIntervalInit, /* timer1 interrupt interval diagnose */ + .diagnoseFunc = TIMERS_DiagnoseInterruptIntervalAccuracy, + .failSafeFunc = TIMERS_FailSafeHandler, + .diagnoseHandle = &g_diagnoseTimers, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = TIMERS_DiagnoseTimer2InterruptIntervalInit, /* timer2 interrupt interval diagnose */ + .diagnoseFunc = TIMERS_DiagnoseInterruptIntervalAccuracy, + .failSafeFunc = TIMERS_FailSafeHandler, + .diagnoseHandle = &g_diagnoseTimers, + .moment = MOMENT_IRQ + }, + { + .handleConfigFunc = ANA_DiagnoseAdc1AccuracyInit, /* adc1 accuracy diagnose */ + .diagnoseFunc = ANA_DiagnoseAdcSampleAccuracy, + .failSafeFunc = ANA_FailSafeHandler, + .diagnoseHandle = &g_diagnoseAna, + .moment = MOMENT_STARTUP + }, + { + .handleConfigFunc = ANA_DiagnoseAdc2AccuracyInit, /* adc2 accuracy diagnose */ + .diagnoseFunc = ANA_DiagnoseAdcSampleAccuracy, + .failSafeFunc = ANA_FailSafeHandler, + .diagnoseHandle = &g_diagnoseAna, + .moment = MOMENT_STARTUP + } +}; +/* startup function safety iterm size */ +const unsigned int STARTUP_PROCESS_ARRAY_SIZE = sizeof(g_fuSaStartupProcess) / sizeof(g_fuSaStartupProcess[0]); + +/** + * @brief Excute startup function safety iterm. + * @param None. + * @retval None. + */ +void FunctionSafetyStartupProcess(void) +{ + FunctionSafetyState state = {0}; + ProcessTimeCycle processTime = {0}; + processTime.timeCycleRecordSwitch = true; + /* excute startup function safety iterm one by one */ + for (unsigned int i = 0; i < STARTUP_PROCESS_ARRAY_SIZE; ++i) { + state = FunctionSafetyProcess(&g_fuSaStartupProcess[i], &processTime); + if (state.BIT.moudule == MODULE_CPU_SOFT_INTTERRUPT && state.BIT.subsysterm == SUBSYS_CORE) { + RegisterReportFailEventHandler(ReportFailEventLogBySoftIrq, 3, NULL); /* 3: interrupt priority */ + } + if (i >= 3 && state.BIT.result == RESULT_FAIL) { /* 3 : wait soft interrupt enable and register callback */ + TriggerSoftIrqSendFailEvent(); /* trigger soft interrupt to notify application */ + } + if (processTime.timeCycleRecordSwitch) { + FunctionSafetyProcessPrint(state, processTime); + } + } +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_startup/function_safety_startup.h b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_startup/function_safety_startup.h new file mode 100644 index 0000000000000000000000000000000000000000..d2caa12619089a1068fa06b2550bdf7b65f8a0a2 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/function_safety_startup/function_safety_startup.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_startup.h + * @author MCU Driver Team + * @brief function safety startup module. + * @details function safety startup interface declaration. + */ + +#ifndef FUNCTION_SAFETY_STARTUP_H +#define FUNCTION_SAFETY_STARTUP_H + +void FunctionSafetyStartupProcess(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/feature.h b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/feature.h new file mode 100644 index 0000000000000000000000000000000000000000..d3c2b74f3c70aead49a02fefb0eafdecab4416dc --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/feature.h @@ -0,0 +1,89 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file feature.h + * @author MCU Driver Team + * @brief This file contains macro configurations related to the project. This file is generated by the IDE tool. + */ + +#ifndef McuMagicTag_FEATURE_H +#define McuMagicTag_FEATURE_H + +/* Macro definitions --------------------------------------------------------- */ +#define CHIP_3065HRPIRZ MACRO_ENABLE + +#define MACRO_ENABLE 1 +#define MACRO_DISABLE 0 + +/* Macro switch */ +#define BASE_DEFINE_USE_ASSERT MACRO_ENABLE +#ifndef FLASH_CRC_CONFIG +#define FLASH_CRC_CONFIG +#endif /* #ifndef FLASH_CRC_CONFIG */ +#define BASE_MATH_SINCOS_MIDDLE_TABLE MACRO_ENABLE /**< This macro is used to control the table type when the + BASE_MATH_GetSinCos() queries the table. When the value of + this macro is MACRO_ENABLE, the error value obtained by the + BASE_MATH_GetSinCos() is relatively small, and the return + value of the function may be greater than or less than the + actual value. When the value of this macro is MACRO_DISABLE, + the error value obtained by the BASE_MATH_GetSinCos() is + relatively large. However, in the range [0°, 180°) and + [180°, 360°), the return value of the function is either + greater than or less than the actual value. */ + +/* Peripheral module macro switch--------------------------------------------- */ +#define BOARD_DIM_NUM 1 /**< Number of dimming handle arrays. */ + +#define BOARD_KEY_NUM 10 /**< Number of key handle arrays. */ +#define BOARD_KEY_PRESS_ON GPIO_HIGH_LEVEL /**< GPIO status corresponding to long press valid. */ +#define BOARD_KEY_PRESS_OFF GPIO_LOW_LEVEL /**< GPIO status corresponding to short press valid. */ + +#define BOARD_LED_SEG_NUM 4 /**< Number of segments. */ +#define BOARD_LED_SEGMENT_ON GPIO_HIGH_LEVEL /**< GPIO level status corresponding to valid segments. */ +#define BOARD_LED_SEGMENT_OFF GPIO_LOW_LEVEL /**< GPIO level status corresponding to invalid segments. */ + +#define BOARD_MKEY_SCHEME_NUMBER BOARD_MKEY_SCHEME_NUMBER_ONE /**< Define the scheme to be adopted. */ +#define BOARD_MKEY_OUT_NUM 4 /**< Number of GPIO pins used as output during scanning. */ +#define BOARD_MKEY_IN_NUM 4 /**< Number of GPIO pins used as input during scanning. */ +#define BOARD_MKEY_OUT_PIN_VALID GPIO_LOW_LEVEL /**< GPIO level status corresponding to the valid \ + status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_OUT_PIN_INVALID GPIO_HIGH_LEVEL /**< GPIO level status corresponding to the \ + invalid status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_VALID GPIO_LOW_LEVEL /**< Indicates the GPIO level corresponding to the \ + valid status of the input GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_INVALID GPIO_HIGH_LEVEL /**< Indicates the GPIO level corresponding to the \ + invalid status of the input GPIO in the key matrix. */ + +#define BOARD_PULSES_NUM 2 /**< Number of pulse handles. */ + +#define BASE_DEFINE_SLIPAVERAGE_NUM 2 /**< Sliding average array length. */ + +#define LISTNODE_MAX 20 + +#define BASE_DEFINE_DMA_QUICKSTART + +#define XTRAIL_FREQ 30000000U + +#define DBG_USE_NO_PRINTF 0U +#define DBG_USE_UART_PRINTF 1U + +#define DBG_PRINTF_USE DBG_USE_UART_PRINTF +#if (DBG_PRINTF_USE == DBG_USE_UART_PRINTF) +#define DBG_PRINTF_UART_PORT UART0 +#endif + +#endif /* McuMagicTag_FEATURE_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/main.c b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..1aafd778f144e87c017ff3a06ac05321b30e36df --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/main.c @@ -0,0 +1,70 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +#include "function_safety_entry.h" +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +CFD_Handle g_cfd; +CMM_Handle g_cmm; +CRC_Handle g_crc; +PMC_Handle g_pmc; +IWDG_Handle g_iwdg; +WDG_Handle g_wdg; +DAC_Handle g_dac0; +DAC_Handle g_dac1; +DAC_Handle g_dac2; +TIMER_Handle g_timer0; +TIMER_Handle g_timer1; +TIMER_Handle g_timer2; +UART_Handle g_uart0; +ADC_Handle g_adc0; +ADC_Handle g_adc1; +ADC_Handle g_adc2; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + FunctionSafetyEntry(); + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/main.h b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..3514e8dfc7a0606172f6c837a958a9711f0cd331 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/main.h @@ -0,0 +1,96 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "adc.h" +#include "adc_ex.h" +#include "uart.h" +#include "crc.h" +#include "cfd.h" +#include "cmm.h" +#include "dac.h" +#include "dac_ex.h" +#include "timer.h" +#include "pmc.h" +#include "crg.h" +#include "wdg.h" +#include "iwdg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +#define DIAGNOSE_ADC0_HANDLE g_adc0 +#define DIAGNOSE_ADC0_SOC ADC_SOC_NUM0 +#define DIAGNOSE_ADC0_CHANNEL ADC_CH_ADCINB7 + +#define DIAGNOSE_ADC1_HANDLE g_adc1 +#define DIAGNOSE_ADC1_SOC ADC_SOC_NUM0 +#define DIAGNOSE_ADC1_CHANNEL ADC_CH_ADCINB7 + +#define DIAGNOSE_ADC2_HANDLE g_adc2 +#define DIAGNOSE_ADC2_SOC ADC_SOC_NUM0 +#define DIAGNOSE_ADC2_CHANNEL ADC_CH_ADCINB7 + +extern CFD_Handle g_cfd; +extern CMM_Handle g_cmm; +extern CRC_Handle g_crc; +extern DAC_Handle g_dac0; +extern DAC_Handle g_dac1; +extern DAC_Handle g_dac2; +extern PMC_Handle g_pmc; +extern IWDG_Handle g_iwdg; +extern WDG_Handle g_wdg; +extern TIMER_Handle g_timer0; +extern TIMER_Handle g_timer1; +extern TIMER_Handle g_timer2; +extern UART_Handle g_uart0; +extern ADC_Handle g_adc0; +extern ADC_Handle g_adc1; +extern ADC_Handle g_adc2; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +void PMCPVDInterruptCallback(void *handle); +void CFDCheckEndCallback(CFD_Handle *handle); +void CFDClockStopCallback(CFD_Handle *handle); +void CMMCounterOverFlowCallback(CMM_Handle *handle); +void CMMCheckEndCallback(CMM_Handle *handle); +void CMMFreqErrorCallback(CMM_Handle *handle); +void TIMER0CallbackFunction(void *handle); +void TIMER1CallbackFunction(void *handle); +void TIMER2CallbackFunction(void *handle); + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/system_init.c b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..f078cc3e8c3460c103751e36e6c73b290ed80357 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/init/system_init.c @@ -0,0 +1,380 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* crg init */ + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void ADC1_Init(void) +{ + HAL_CRG_IpEnableSet(ADC1_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(ADC1_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); + HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); + + g_adc1.baseAddress = ADC1; + g_adc1.socPriority = ADC_PRIMODE_ALL_ROUND; + g_adc1.handleEx.vrefBuf = ADC_VREF_2P5V; + HAL_ADC_Init(&g_adc1); + SOC_Param socParam = {0}; + socParam.adcInput = ADC_CH_ADCINB7; /* DAC1_OUT(ADC INB7) */ + socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ + socParam.sampleTotalTime = 127; /* adc sample total time 127 adc_clk */ + socParam.softTrigSource = ADC_TRIGSOC_SOFT; /* soft trigger adc sample */ + socParam.intTrigSource = ADC_TRIGSOC_NONEINT; + socParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; + socParam.finishMode = ADC_SOCFINISH_NONE; + HAL_ADC_ConfigureSoc(&g_adc1, ADC_SOC_NUM0, &socParam); /* config soc */ +} + +static void ADC2_Init(void) +{ + HAL_CRG_IpEnableSet(ADC2_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(ADC2_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); + HAL_CRG_IpClkDivSet(ADC2_BASE, CRG_ADC_DIV_5); + + g_adc2.baseAddress = ADC2; + g_adc2.socPriority = ADC_PRIMODE_ALL_ROUND; + g_adc2.handleEx.vrefBuf = ADC_VREF_2P5V; + HAL_ADC_Init(&g_adc2); + SOC_Param socParam = {0}; + socParam.adcInput = ADC_CH_ADCINB7; /* DAC2_OUT(ADC INB7) */ + socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ + socParam.sampleTotalTime = 127; /* adc sample total time 127 adc_clk */ + socParam.softTrigSource = ADC_TRIGSOC_SOFT; /* soft trigger adc sample */ + socParam.intTrigSource = ADC_TRIGSOC_NONEINT; + socParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; + socParam.finishMode = ADC_SOCFINISH_NONE; + HAL_ADC_ConfigureSoc(&g_adc2, ADC_SOC_NUM0, &socParam); /* config soc */ +} + +__weak void CFDCheckEndCallback(CFD_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN CFD_INT_CHECK_END_MASK */ + /* USER CODE END CFD_INT_CHECK_END_MASK */ +} + +__weak void CFDClockStopCallback(CFD_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN CFD_INT_PLL_REF_CLOCK_STOP_MASK */ + /* USER CODE END CFD_INT_PLL_REF_CLOCK_STOP_MASK */ +} + +static BASE_StatusType CFD_Init(void) +{ + g_cfd.baseAddress = CFD; + g_cfd.upperBound = 2; /* 2: windows upbound */ + g_cfd.interruptType = CFD_INT_PLL_REF_CLOCK_STOP_MASK; /* pll ref clock stop error interrupt */ + + HAL_CFD_RegisterCallback(&g_cfd, CFD_INT_CHECK_END_MASK, (CFD_CallBackFuncType)CFDCheckEndCallback); + HAL_CFD_RegisterCallback(&g_cfd, CFD_INT_PLL_REF_CLOCK_STOP_MASK, (CFD_CallBackFuncType)CFDClockStopCallback); + + IRQ_Register(IRQ_CFD, HAL_CFD_IrqHandler, &g_cfd); /* register cfd irq callback */ + IRQ_SetPriority(IRQ_CFD, 1); /* interrupt priority */ + IRQ_EnableN(IRQ_CFD); + return HAL_CFD_Init(&g_cfd); +} + +__weak void CMMCounterOverFlowCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN CMM_INT_COUNTER_OVERFLOW_MASK */ + /* USER CODE END CMM_INT_COUNTER_OVERFLOW_MASK */ +} + +__weak void CMMCheckEndCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN CMM_INT_CHECK_END_MASK */ + /* USER CODE END CMM_INT_CHECK_END_MASK */ +} + +__weak void CMMFreqErrorCallback(CMM_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN CMM_INT_FREQ_ERR_MASK */ + /* USER CODE END CMM_INT_FREQ_ERR_MASK */ +} + +static BASE_StatusType CMM_Init(void) +{ + g_cmm.baseAddress = CMM; + g_cmm.mode = CMM_TRIGGER_RISE; + g_cmm.targetFreqDivision = CMM_TARGET_FREQ_DIV_8192; /* target clock 8192 division */ + g_cmm.refFreqDivision = CMM_REF_FREQ_DIV_32; /* ref clock 32 division */ + g_cmm.targetClockSource = CMM_TARGET_CLK_HOSC; + g_cmm.refClockSource = CMM_REF_CLK_LOSC; + g_cmm.upperBound = 65535; /* 65535: upbound limit */ + g_cmm.lowerBound = 0; + g_cmm.interruptType = CMM_INT_FREQ_ERR_MASK; /* clock frequency error interrupt */ + + HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_COUNTER_OVERFLOW_MASK, (CMM_CallBackFuncType)CMMCounterOverFlowCallback); + HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_CHECK_END_MASK, (CMM_CallBackFuncType)CMMCheckEndCallback); + HAL_CMM_RegisterCallback(&g_cmm, CMM_INT_FREQ_ERR_MASK, (CMM_CallBackFuncType)CMMFreqErrorCallback); + IRQ_Register(IRQ_CMM, HAL_CMM_IrqHandler, &g_cmm); + IRQ_SetPriority(IRQ_CMM, 1); /* interrupt priority */ + IRQ_EnableN(IRQ_CMM); + return HAL_CMM_Init(&g_cmm); +} + +static void CRC_Init(void) +{ + HAL_CRG_IpEnableSet(CRC_BASE, IP_CLK_ENABLE); + + g_crc.baseAddress = CRC; + g_crc.handleEx.algoMode = CRC32; /* crc32 algorythm */ + g_crc.handleEx.timeout = 0; + g_crc.handleEx.enableIT = BASE_CFG_DISABLE; + g_crc.handleEx.enableErrInject = BASE_CFG_DISABLE; + g_crc.inputDataFormat = CRC_MODE_BIT8; /* input data bitwidth */ + HAL_CRC_Init(&g_crc); +} + +static void DAC1_Init(void) +{ + HAL_CRG_IpEnableSet(DAC1_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkDivSet(DAC1_BASE, CRG_DAC_DIV_4); + + g_dac1.baseAddress = DAC1_BASE; + g_dac1.dacValue = 128; /* 128: DAC Value */ + g_dac1.handleEx.sineMode = BASE_CFG_UNSET; + HAL_DAC_Init(&g_dac1); /* dac init */ +} + +static void DAC2_Init(void) +{ + HAL_CRG_IpEnableSet(DAC2_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkDivSet(DAC2_BASE, CRG_DAC_DIV_4); + + g_dac2.baseAddress = DAC2_BASE; + g_dac2.dacValue = 128; /* 128: DAC Value */ + g_dac2.handleEx.sineMode = BASE_CFG_UNSET; + HAL_DAC_Init(&g_dac2); /* dac init */ +} + +__weak void PMCPVDInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN PMC Callback */ + /* USER CODE END PMC Callback */ +} + +static void PMC_Init(void) +{ + HAL_CRG_IpEnableSet(PMC_BASE, IP_CLK_ENABLE); + g_pmc.baseAddress = PMC_BASE; + g_pmc.wakeupSrc = PMC_WAKEUP_0; /* wakeup source from low power mode */ + g_pmc.wakeupActMode = PMC_WAKEUP_ACT_UP_EDGE; + g_pmc.pvdEnable = BASE_CFG_ENABLE; /* enable volatege monitor */ + g_pmc.pvdThreshold = PMC_PVD_THRED_LEVEL7; /* pvd level 7 */ + HAL_PMC_Init(&g_pmc); + HAL_PMC_RegisterCallback(&g_pmc, PMC_PVD_INT_ID, PMCPVDInterruptCallback); + IRQ_Register(IRQ_PVD, HAL_PMC_IrqHandler, &g_pmc); + IRQ_SetPriority(IRQ_PVD, 1); /* interrupt priority */ + IRQ_EnableN(IRQ_PVD); +} + +__weak void TIMER0CallbackFunction(void *handle) +{ + DCL_TIMER_IrqClear((TIMER_RegStruct *)handle); + /* USER CODE BEGIN TIMER0 ITCallBackFunc */ + /* USER CODE END TIMER0 ITCallBackFunc */ +} + +static void TIMER0_Init(void) +{ + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER0) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 100; + HAL_CRG_IpEnableSet(TIMER0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(TIMER0_BASE, CRG_PLL_NO_PREDV); + g_timer0.baseAddress = TIMER0; + g_timer0.load = load - 1; /* Set timer value immediately */ + g_timer0.bgLoad = load - 1; /* Set timer value */ + g_timer0.mode = TIMER_MODE_RUN_ONTSHOT; /* Run in period mode */ + g_timer0.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ + g_timer0.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer0.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer0.dmaReqEnable = BASE_CFG_DISABLE; + g_timer0.interruptEn = BASE_CFG_ENABLE; + HAL_TIMER_Init(&g_timer0); + IRQ_Register(IRQ_TIMER0, HAL_TIMER_IrqHandler, &g_timer0); + HAL_TIMER_RegisterCallback(&g_timer0, TIMER_PERIOD_FIN, TIMER0CallbackFunction); + IRQ_SetPriority(IRQ_TIMER0, 1); /* interrupt priority */ + IRQ_EnableN(IRQ_TIMER0); +} + +__weak void TIMER1CallbackFunction(void *handle) +{ + DCL_TIMER_IrqClear((TIMER_RegStruct *)handle); + /* USER CODE BEGIN TIMER1 ITCallBackFunc */ + /* USER CODE END TIMER1 ITCallBackFunc */ +} + +static void TIMER1_Init(void) +{ + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER1) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 100; + HAL_CRG_IpEnableSet(TIMER1_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(TIMER1_BASE, CRG_PLL_NO_PREDV); + g_timer1.baseAddress = TIMER1; + g_timer1.load = load - 1; /* Set timer value immediately */ + g_timer1.bgLoad = load - 1; /* Set timer value */ + g_timer1.mode = TIMER_MODE_RUN_ONTSHOT; /* Run in period mode */ + g_timer1.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ + g_timer1.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer1.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer1.dmaReqEnable = BASE_CFG_DISABLE; + g_timer1.interruptEn = BASE_CFG_ENABLE; + HAL_TIMER_Init(&g_timer1); + IRQ_Register(IRQ_TIMER1, HAL_TIMER_IrqHandler, &g_timer1); + HAL_TIMER_RegisterCallback(&g_timer1, TIMER_PERIOD_FIN, TIMER1CallbackFunction); + IRQ_SetPriority(IRQ_TIMER1, 1); /* interrupt priority */ + IRQ_EnableN(IRQ_TIMER1); +} + +__weak void TIMER2CallbackFunction(void *handle) +{ + DCL_TIMER_IrqClear((TIMER_RegStruct *)handle); + /* USER CODE BEGIN TIMER2 ITCallBackFunc */ + /* USER CODE END TIMER2 ITCallBackFunc */ +} + +static void TIMER2_Init(void) +{ + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER2) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 100; + + HAL_CRG_IpEnableSet(TIMER2_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(TIMER2_BASE, CRG_PLL_NO_PREDV); + g_timer2.baseAddress = TIMER2; + g_timer2.load = load - 1; /* Set timer value immediately */ + g_timer2.bgLoad = load - 1; /* Set timer value */ + g_timer2.mode = TIMER_MODE_RUN_ONTSHOT; /* Run in period mode */ + g_timer2.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ + g_timer2.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer2.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer2.dmaReqEnable = BASE_CFG_DISABLE; + g_timer2.interruptEn = BASE_CFG_ENABLE; + HAL_TIMER_Init(&g_timer2); + IRQ_Register(IRQ_TIMER2, HAL_TIMER_IrqHandler, &g_timer2); + HAL_TIMER_RegisterCallback(&g_timer2, TIMER_PERIOD_FIN, TIMER2CallbackFunction); + IRQ_SetPriority(IRQ_TIMER2, 1); /* interrupt priority */ + IRQ_EnableN(IRQ_TIMER2); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); + g_uart0.baseAddress = UART0; + g_uart0.baudRate = UART0_BAND_RATE; /* baud rate */ + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; /* no parity */ + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; /* fifo enable */ + g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void WDG_Init(void) +{ + HAL_CRG_IpEnableSet(WDG_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(WDG_BASE, CRG_PLL_NO_PREDV); + g_wdg.baseAddress = WDG; + g_wdg.timeValue = 1000000; /* 1000000 : wdg reset interval 1000000us */ + g_wdg.timeType = WDG_TIME_UNIT_US; + g_wdg.enableIT = BASE_CFG_DISABLE; + HAL_WDG_Init(&g_wdg); /* wdg init */ +} + +static void IWDG_Init(void) +{ + HAL_CRG_IpEnableSet(IWDG_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(IWDG_BASE, CRG_PLL_NO_PREDV); + g_iwdg.baseAddress = IWDG; + g_iwdg.timeValue = 1000000; /* 1000000 : iwdg reset interval 1000000us */ + g_iwdg.timeType = IWDG_TIME_UNIT_US; + g_iwdg.enableIT = BASE_CFG_DISABLE; + HAL_IWDG_Init(&g_iwdg); /* iwdg init */ +} + +static void IOConfig(void) +{ + SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; + SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + /* system init */ + IOConfig(); /* ioconfig init */ + UART0_Init(); + ADC1_Init(); + ADC2_Init(); + CRC_Init(); + CMM_Init(); + CFD_Init(); + DAC1_Init(); + DAC2_Init(); + PMC_Init(); + TIMER0_Init(); + TIMER1_Init(); + TIMER2_Init(); + IWDG_Init(); /* iwdg init */ + WDG_Init(); /* wdg init */ + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/function_safety/iec60730_classb_306xh/readme.md b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..e3593d921367d7e354ef45f2c5ee229183f54d96 --- /dev/null +++ b/src/application/middleware_sample/function_safety/iec60730_classb_306xh/readme.md @@ -0,0 +1,42 @@ +# MCU芯片功能安全classb参考示例 +## 关键字: IEC60730,ClassB,启动诊断,运行时诊断,最小诊断单元process配置,时间性能测量,表驱动 + +**【功能描述】** ++ function_safety功能安全库中间件通过对功能安全处理流程进行抽象,提炼出用户侧最小配置单元function_safety_process, 应用侧基于表驱动的方式进行启动和运行时诊断处理,用户只需实例配置启动和运行时的诊断流程process,即可自动完成新增process处理流程注册到启动和运行时的处理流程中,用户只需根据具体项目需求选择功能安全库提供的诊断接口和配置对应的初始化配置即可。function_safety_init初始化相关接口是基于功能安全各子系统handle句柄的相关配置,是底层驱动和function_safety中间件之间的适配层,generatecode是基于IDE配置生成的芯片初始化配置代码,是底层驱动和芯片之间的适配层。功能安全中间件处理流程提供了诊断前备份功能和诊断后恢复功能,需要用户根据实际项目封装对应的接口,通过process配置注册到对应的函数指针上即可完成无损诊断,用户根据实际工程应用配置底层驱动初始化代码,诊断前调用备份函数备份工程应用的初始化配置,诊断后恢复功能应用的初始化配置,不影响用户实际应用的初始化配置,便于用户工程应用的配置集成。 + +**【示例配置】** ++ contexBackupFunc 上下文备份配置(可选):通过上下文备份可以实现实际应用的无损诊断,用于诊断前备份用户通过IDE配置生成的实际工程应用底层驱动配置。 + ++ handleConfigFunc 功能安全适配层初始化配置(可选):用于配置各子系统诊断函数所需的初始化配置,该适配层可完成底层驱动配置的修改和上层诊断指标的设定。 + ++ diagnoseFunc 诊断函数配置(可选):功能安全诊断接口,用户可选择function_safety中间件提供的各子系统诊断接口,也可自行封装对应的诊断接口。 + ++ failSafeFunc 失效安全函数配置(可选):基于诊断结果实施失效安全配置,该示例中为了便于演示,默认配置均为while(1)死循环的方式定住程序。该函数为__weak函数,用户可自定义进行钩子函数挂载。 + ++ faultPredictFunc 故障预测函数配置(可选):该功能function_safety安全包暂未提供,主要用于诊断正常的前提下进行故障预测。 + ++ contexResumeFunc 上下文恢复配置(可选):诊断后上下文配置恢复函数,诊断完成后恢复工程应用的底层驱动配置。示例中暂未提供,用户可根据实际项目进行配置封装接口。 + ++ contexHandle 上下文备份恢复参数句柄(可选):上下文备份和恢复的句柄指针,可用户指向备份区。 + ++ diagnoseHandle 诊断参数句柄(可选):诊断函数入参,用户可按照结构体定义进行配置。 + ++ failSafeHandle 失效安全参数句柄(可选):失效安全函数入参,用户可按照结构体定义进行配置。 + ++ faultPredictHandle 故障预测参数句柄(可选):故障预测函数入参,用户可按照结构体定义进行配置。 + ++ moment 诊断时刻参数句柄(可选):故障预测函数入参,用户可按照结构体定义进行配置。 + ++ timeCycleRecordSwitch 时间cycle测量开关(可选):默认不开,用户可配置是否开启,用于记录打印处理流程中各阶段的耗时以及状态。 + + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,通过串口可以看到启动和运行时处理流程process的诊断信息,包含功能安全状态码,状态码的含义可以参照FunctionSafetyState结构体的位定义,每个子系统的模块和特性在对应头文件中右定义,通过功能安全状态码能了解当前诊断的子系统和模块以及特性的诊断结果和时间性能。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 ++ 必须勾选上工程配置菜单中的“生成CRC”选项,ROM测试会用到,否则ROM完整性诊断会报异常,且不可通过仿真模式进行烧录,否则会缺少bin文件末尾的CRC校验码、 ++ 如果诊断出看门狗复位异常时想消除该异常,则目标板需要重新上下电,否则会一直检测到看门狗复位异常。 \ No newline at end of file diff --git a/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/idh_rom_code_lib/idh_ram_data_copy.h b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/idh_rom_code_lib/idh_ram_data_copy.h new file mode 100644 index 0000000000000000000000000000000000000000..3edb1d261f627a2ac5ff5b374bd472d54c1bbbb7 --- /dev/null +++ b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/idh_rom_code_lib/idh_ram_data_copy.h @@ -0,0 +1,52 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file idh_ram_data_copy.h + * @author MCU Driver Team + * @brief This file provides sample code for OEM help IDH move data from flash to sram. + */ + +#ifndef McuMagicTag_IDH_RAM_DATA_COPY_H +#define McuMagicTag_IDH_RAM_DATA_COPY_H + +#define LOAD_ARRAY_LENGTH 1 + +extern unsigned char g_idhSramDataStartAddr[LOAD_ARRAY_LENGTH]; +extern unsigned char g_idhSramDataSrcAddr[LOAD_ARRAY_LENGTH]; +extern unsigned char g_idhSramDataEndAddr[LOAD_ARRAY_LENGTH]; + +/** + * @brief Copy idh data to sram. + * @param None. + * @retval None. + */ +static inline void CopyIdhDataToSram(void) +{ + unsigned char *targetAddr; + unsigned char *srcAddr; + + targetAddr = g_idhSramDataStartAddr; /* Get the address of sram */ + srcAddr = g_idhSramDataSrcAddr; + + while (targetAddr < g_idhSramDataEndAddr) { + *targetAddr = *srcAddr; + targetAddr++; + srcAddr++; + } +} + +#endif /* McuMagicTag_IDH_RAM_DATA_COPY_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/idh_rom_code_lib/sample_idh_rom_code.h b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/idh_rom_code_lib/sample_idh_rom_code.h new file mode 100644 index 0000000000000000000000000000000000000000..59ae6426aa69bc50c55fd5dfd26daa94ca8de3e6 --- /dev/null +++ b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/idh_rom_code_lib/sample_idh_rom_code.h @@ -0,0 +1,109 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_idh_rom_code.h + * @author MCU Driver Team + * @brief This file provides sample code for IDH provide api for oem. + */ + +#ifndef McuMagicTag_SAMPLE_IDH_ROM_CODE_H +#define McuMagicTag_SAMPLE_IDH_ROM_CODE_H + +#include +#include "flash.h" +#include "timer.h" + +#define FIXED_OPERATOR_SRAM __attribute__((section(".fixoperator_sram"))) +#define RAM_CODE __attribute__((section(".text.sram"))) +typedef void (* IRQ_PROC_FUNC)(void *arg); + +/* Definition of the interrupt HAL function pointer. */ +typedef unsigned int (*IRQ_ENABLEN)(unsigned int irqNum); +typedef unsigned int (*IRQ_REGISTER)(unsigned int irqNum, IRQ_PROC_FUNC func, void *arg); +typedef unsigned int (*IRQ_SETPRIORITY)(unsigned int irqNum, unsigned int priority); + +/* Definition of the flash HAL function pointer. */ +typedef BASE_StatusType (*FLASH_INIT)(FLASH_Handle *handle); +typedef BASE_StatusType (*FLASH_DEINIT)(FLASH_Handle *handle); +typedef BASE_StatusType (*FLASH_READ)(FLASH_Handle *handle, unsigned int srcAddr, unsigned int readLen, + unsigned char *dataBuff, unsigned int buffLen); +typedef BASE_StatusType (*FLASH_WRITE_BLOCKING)(FLASH_Handle *handle, unsigned int srcAddr, unsigned int destAddr, + unsigned int srcLen); +typedef BASE_StatusType (*FLASH_ERASE_BLOCKING)(FLASH_Handle *handle, FLASH_EraseMode eraseMode, + FLASH_SectorAddr startAddr, unsigned int eraseNum); + +/* Definition of the Timer HAL function pointer. */ +typedef BASE_StatusType (*TIMER_INIT)(TIMER_Handle *handle); +typedef void (*TIMER_DEINIT)(TIMER_Handle *handle); +typedef void (*TIMER_START)(TIMER_Handle *handle); +typedef void (*TIMER_STOP)(TIMER_Handle *handle); +typedef void (*TIMER_IRQHANDLER)(void *handle); +typedef BASE_StatusType (*TIMER_CALLBACK)(TIMER_Handle *handle, TIMER_InterruptType typeID, + TIMER_CallBackFunc callBackFunc); + +/* Macro definitions ---------------------------------------------------------*/ +typedef enum { + CALACULATE_ADD = 0, + CALACULATE_SUB = 1, + CALACULATE_MUL = 2, + CALACULATE_DIV = 3, +} CalculateType; + +typedef struct { + IRQ_ENABLEN irqEnableCb; + IRQ_REGISTER irqRegisterCb; + IRQ_SETPRIORITY irqSetpriorityCb; +} FIXED_OPERATOR_IrqCallback; + +typedef struct { + FLASH_INIT flashInitCb; + FLASH_DEINIT flashDeinitCb; + FLASH_READ flashReadCb; + FLASH_WRITE_BLOCKING flashWriteBlockingCb; + FLASH_ERASE_BLOCKING flashEraseBlockingCb; +} FIXED_OPERATOR_FlashCallback; + +typedef struct { + TIMER_INIT timerInitCb; + TIMER_DEINIT timerDeinitCb; + TIMER_START timerStartCb; + TIMER_STOP timerStopCb; + TIMER_IRQHANDLER timerIrqHandlerCb; + TIMER_CALLBACK timerCallbackCb; +} FIXED_OPERATOR_TimerCallback; + +/* Register API structure -----------------------------------------------------------------*/ +void REGISTER_IRQ_CALLBACK(FIXED_OPERATOR_IrqCallback *callback); +void REGISTER_FLASH_CALLBACK(FIXED_OPERATOR_FlashCallback *callback); +void REGISTER_TIMER_CALLBACK(FIXED_OPERATOR_TimerCallback *callback); + +/* Fixed operator API structure -----------------------------------------------------------------*/ +uint32_t FIXED_OPERATOR_FlashInit(FLASH_Handle *handle); +uint32_t FIXED_OPERATOR_FlashDeInit(FLASH_Handle *handle); + +int32_t FIXED_OPERATOR_TimerInit(TIMER_Handle *handle, uint32_t irqNum, uint32_t priority, TIMER_InterruptType typeID, + TIMER_CallBackFunc userCallback); +int32_t FIXED_OPERATOR_TimerDeInit(TIMER_Handle *handle); + +int32_t FIXED_OPERATOR_Calculate(int32_t data1, int32_t data2, CalculateType type); +int32_t RAM_CODE FIXED_OPERATOR_CalculateSRAM(int32_t data1, int32_t data2, CalculateType type); +int32_t FIXED_OPERATOR_StoreStart(TIMER_Handle *handle); +int32_t FIXED_OPERATOR_StoreStop(TIMER_Handle *handle); +int32_t FIXED_OPERATOR_Store(FLASH_Handle *handle, uint32_t data, uint32_t optPageAddr, uint32_t len); +int32_t RAM_CODE FIXED_OPERATOR_StoreSRAM(FLASH_Handle *handle, uint32_t data, uint32_t optPageAddr, uint32_t len); + +#endif /* McuMagicTag_SAMPLE_IDH_ROM_CODE_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/init/main.c b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..dc3c3de8e16dbffe1150709b7b67857f4ff1fd00 --- /dev/null +++ b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/init/main.c @@ -0,0 +1,58 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +#include "oem_call_idh_rom_code.h" +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +/* USER CODE BEGIN 1 */ +UART_Handle g_uart0; +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + RomServiceProcess(); + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/init/main.h b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..3f5354ea75d0390d8ebdc1d44381b802b338e882 --- /dev/null +++ b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/init/main.h @@ -0,0 +1,55 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +#include "flash.h" +#include "crg.h" +#include "uart.h" +#include "uart_ex.h" +#include "iocmg.h" + +extern UART_Handle g_uart0; + +void SystemInit(void); +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/init/system_init.c b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..d46d90f6d45c5ceb7f9f871dfe43d67e6daf0f29 --- /dev/null +++ b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/init/system_init.c @@ -0,0 +1,91 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "crg.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_DMA; + g_uart0.rxMode = UART_MODE_INTERRUPT; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/oem_call_idh_rom_code/oem_call_idh_rom_code.c b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/oem_call_idh_rom_code/oem_call_idh_rom_code.c new file mode 100644 index 0000000000000000000000000000000000000000..a2db682d9c0a47c4b69f1b6d51f9883e02ad0b48 --- /dev/null +++ b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/oem_call_idh_rom_code/oem_call_idh_rom_code.c @@ -0,0 +1,198 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file oem_call_idh_rom_code.c + * @author MCU Driver Team + * @brief This file provides sample code for OEM calls IDH ROM-ized code. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "debug.h" +#include "oem_call_idh_rom_code.h" + +static FLASH_Handle g_flashHandle; +static TIMER_Handle g_timerHandle; + +#define TEST_CLC_NUM1 3 +#define TEST_CLC_NUM2 8 + +#define STORE_COUNT 5 + +#define FLASH_STORE_WORD 0xAB +#define FLASH_OPERATE_ADDR FLASH_PAGE_58 +#define FLASH_OPERATE_LENGTH 1024 + +#define TIMER_DELAY_MS 1000000 + +#define ODD_JUDGE_MASK 0x01 + +static unsigned int g_storeCountFlag = 0; + +/** + * @brief Timer callback function. + * @param handle TIMER handle. + * @retval None. + */ +static void UserTimer0Callback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + unsigned char dataBuff[FLASH_OPERATE_LENGTH + 1] = {0}; + + g_storeCountFlag++; + if (g_storeCountFlag > STORE_COUNT) { + FIXED_OPERATOR_StoreStop(&g_timerHandle); + DBG_PRINTF("Sample finish\r\n"); + return; + } + /* Odd numbers call RAM functions, even numbers call ROM functions. */ + if (g_storeCountFlag & ODD_JUDGE_MASK) { + FIXED_OPERATOR_StoreSRAM(&g_flashHandle, (FLASH_STORE_WORD + g_storeCountFlag), FLASH_OPERATE_ADDR, + FLASH_OPERATE_LENGTH); /* Store data to flash used function running sram. */ + DBG_PRINTF("FIXED_OPERATOR_StoreSRAM finish, data: %x\r\n", (FLASH_STORE_WORD + g_storeCountFlag)); + } else { + FIXED_OPERATOR_Store(&g_flashHandle, (FLASH_STORE_WORD + g_storeCountFlag), FLASH_OPERATE_ADDR, + FLASH_OPERATE_LENGTH); /* Store data to flash used function running flash. */ + DBG_PRINTF("FIXED_OPERATOR_Store finish, data: %x\r\n", (FLASH_STORE_WORD + g_storeCountFlag)); + } + + /* Perform the read operation. */ + HAL_FLASH_Read(&g_flashHandle, FLASH_OPERATE_ADDR, FLASH_OPERATE_LENGTH, + dataBuff, FLASH_OPERATE_LENGTH); + /* Check Data Correctness */ + for (unsigned int i = 0; i < FLASH_OPERATE_LENGTH; i++) { + if (dataBuff[i] != (FLASH_STORE_WORD + g_storeCountFlag)) { + DBG_PRINTF("Store flash fail, index:%d, data: %x\r\n ", dataBuff[i]); + return; + } + } + + DBG_PRINTF("Store flash success, data: %x\r\n ", dataBuff[0]); +} + +/** + * @brief Registers the callback function of the HAL interrupt service. + * @param None. + * @retval None. + */ +static void RegisterIrqApi(void) +{ + FIXED_OPERATOR_IrqCallback irqApi; + irqApi.irqEnableCb = IRQ_EnableN; + irqApi.irqRegisterCb = IRQ_Register; + irqApi.irqSetpriorityCb = IRQ_SetPriority; + + REGISTER_IRQ_CALLBACK(&irqApi); /* Invoke idh function. */ +} + +/** + * @brief Registers the callback function of the HAL flash functions. + * @param None. + * @retval None. + */ +static void RegisterFlashApi(void) +{ + FIXED_OPERATOR_FlashCallback flashApi; + flashApi.flashInitCb = HAL_FLASH_Init; + flashApi.flashDeinitCb = HAL_FLASH_DeInit; + flashApi.flashReadCb = HAL_FLASH_Read; + flashApi.flashWriteBlockingCb = HAL_FLASH_WriteBlocking; + flashApi.flashEraseBlockingCb = HAL_FLASH_EraseBlocking; + + REGISTER_FLASH_CALLBACK(&flashApi); /* Invoke idh function. */ +} + +/** + * @brief Registers the callback function of the HAL timer functions. + * @param None. + * @retval None. + */ +static void RegisterTimerApi(void) +{ + FIXED_OPERATOR_TimerCallback timerApi; + timerApi.timerInitCb = HAL_TIMER_Init; + timerApi.timerDeinitCb = HAL_TIMER_DeInit; + timerApi.timerStartCb = HAL_TIMER_Start; + timerApi.timerStopCb = HAL_TIMER_Stop; + timerApi.timerCallbackCb = HAL_TIMER_RegisterCallback; + timerApi.timerIrqHandlerCb = HAL_TIMER_IrqHandler; + REGISTER_TIMER_CALLBACK(&timerApi); /* Invoke idh function. */ +} + +/** + * @brief Init flash module. + * @param None. + * @retval None. + */ +static void InitFlash(void) +{ + HAL_CRG_IpEnableSet(EFC_BASE, IP_CLK_ENABLE); /* TIMER0 clock enable. */ + g_flashHandle.baseAddress = EFC; + g_flashHandle.peMode = FLASH_PE_OP_BLOCK; + FIXED_OPERATOR_FlashInit(&g_flashHandle); + DBG_PRINTF("FIXED_OPERATOR_FlashInit\r\n"); +} + +/** + * @brief Init timer module. + * @param None. + * @retval None. + */ +static void InitTimerIt(void) +{ + HAL_CRG_IpEnableSet(TIMER0_BASE, IP_CLK_ENABLE); /* TIMER0 clock enable. */ + unsigned int loadData = + (HAL_CRG_GetIpFreq((void *)TIMER0) / (1u << (TIMERPRESCALER_NO_DIV * 0x4)) / TIMER_DELAY_MS) * TIMER_DELAY_MS; + g_timerHandle.baseAddress = TIMER0; + g_timerHandle.load = loadData - 1; /* Set timer value immediately */ + g_timerHandle.bgLoad = loadData - 1; /* Set timer value */ + g_timerHandle.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ + g_timerHandle.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ + g_timerHandle.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timerHandle.interruptEn = BASE_CFG_ENABLE; + g_timerHandle.adcSocReqEnable = BASE_CFG_DISABLE; + g_timerHandle.dmaReqEnable = BASE_CFG_DISABLE; + FIXED_OPERATOR_TimerInit(&g_timerHandle, IRQ_TIMER0, 0x01, TIMER_PERIOD_FIN, UserTimer0Callback); + DBG_PRINTF("FIXED_OPERATOR_TimerInit\r\n"); +} + +/** + * @brief OEM Sample Code Execution. + * @param None. + * @retval None. + */ +void RomServiceProcess(void) +{ + SystemInit(); + CopyIdhDataToSram(); /* Help IDH move data from flash to sram */ + + /* Register HAL function to idh. */ + RegisterIrqApi(); + RegisterFlashApi(); + RegisterTimerApi(); + + InitFlash(); /* Init idh used module. */ + InitTimerIt(); + + /* Invoke the four arithmetic operations in flash. */ + int ret = FIXED_OPERATOR_Calculate(TEST_CLC_NUM1, TEST_CLC_NUM2, CALACULATE_MUL); + DBG_PRINTF("fixed_operator_calculate %d * %d = %d\r\n", TEST_CLC_NUM1, TEST_CLC_NUM2, ret); + /* Invoke the four arithmetic operations in sram. */ + ret = FIXED_OPERATOR_CalculateSRAM(TEST_CLC_NUM1, TEST_CLC_NUM2, CALACULATE_MUL); + DBG_PRINTF("fixed_operator_calculate SRAM %d * %d = %d\r\n", TEST_CLC_NUM1, TEST_CLC_NUM2, ret); + /* Start Scheduled Storage Task. */ + FIXED_OPERATOR_StoreStart(&g_timerHandle); +} \ No newline at end of file diff --git a/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/oem_call_idh_rom_code/oem_call_idh_rom_code.h b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/oem_call_idh_rom_code/oem_call_idh_rom_code.h new file mode 100644 index 0000000000000000000000000000000000000000..e6949a36f241337e727c150632a77dc8e6243148 --- /dev/null +++ b/src/application/middleware_sample/idh_sample/sample_oem_call_idh_rom_code/oem_call_idh_rom_code/oem_call_idh_rom_code.h @@ -0,0 +1,32 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file oem_call_idh_rom_code.h + * @author MCU Driver Team + * @brief This file provides sample code for OEM calls IDH ROM-ized code. + */ +#ifndef McuMagicTag_OEM_CALL_IDH_ROM_CODE_H +#define McuMagicTag_OEM_CALL_IDH_ROM_CODE_H + +#include "main.h" +#include "flash.h" +#include "idh_ram_data_copy.h" +#include "sample_idh_rom_code.h" + +void RomServiceProcess(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/mcs_65demo/application/mcs_motor_process.c b/src/application/middleware_sample/mcs_65demo/application/mcs_motor_process.c index bac9027da2cbc98172417e22b6015ecf27d1c0e1..a1c2f26f9b38d286b18ebdb43dbf16d691e8220f 100644 --- a/src/application/middleware_sample/mcs_65demo/application/mcs_motor_process.c +++ b/src/application/middleware_sample/mcs_65demo/application/mcs_motor_process.c @@ -34,34 +34,36 @@ /* Motor parameters */ /* Np, Rs, Ld, Lq, Psif, J, Nmax, Currmax, PPMR, zShift */ static MOTOR_Param g_motorParamCp = { - MOTOR_PARAM_NP, - MOTOR_PARAM_RS, - MOTOR_PARAM_LD, - MOTOR_PARAM_LQ, - MOTOR_PARAM_LS, - MOTOR_PARAM_PSIF, - MOTOR_PARAM_JS, - MOTOR_PARAM_MAX_SPD, - MOTOR_PARAM_MAX_CURR, - MOTOR_PARAM_MAX_TRQ, - MOTOR_PARAM_ENCODER_PPMR, - MOTOR_PARAM_ENCODER_ZSHIFT + .mtrNp = MOTOR_PARAM_NP, + .mtrRs = MOTOR_PARAM_RS, + .mtrLd = MOTOR_PARAM_LD, + .mtrLq = MOTOR_PARAM_LQ, + .mtrLs = MOTOR_PARAM_LS, + .mtrPsif = MOTOR_PARAM_PSIF, + .mtrJ = MOTOR_PARAM_JS, + .maxElecSpd = MOTOR_PARAM_MAX_SPD, + .maxCurr = MOTOR_PARAM_MAX_CURR, + .maxTrq = MOTOR_PARAM_MAX_TRQ, + .mtrPPMR = MOTOR_PARAM_ENCODER_PPMR, + .zShift = MOTOR_PARAM_ENCODER_ZSHIFT, + .busVolt = INV_VOLTAGE_BUS }; /* Np, Rs, Ld, Lq, Psif, J, Nmax, Currmax, PPMR, zShift */ static MOTOR_Param g_motorParamFan = { - MOTOR_PARAM_NP, - MOTOR_PARAM_RS, - MOTOR_PARAM_LD, - MOTOR_PARAM_LQ, - MOTOR_PARAM_LS, - MOTOR_PARAM_PSIF, - MOTOR_PARAM_JS, - MOTOR_PARAM_MAX_SPD, - MOTOR_PARAM_MAX_CURR, - MOTOR_PARAM_MAX_TRQ, - MOTOR_PARAM_ENCODER_PPMR, - MOTOR_PARAM_ENCODER_ZSHIFT + .mtrNp = MOTOR_PARAM_NP, + .mtrRs = MOTOR_PARAM_RS, + .mtrLd = MOTOR_PARAM_LD, + .mtrLq = MOTOR_PARAM_LQ, + .mtrLs = MOTOR_PARAM_LS, + .mtrPsif = MOTOR_PARAM_PSIF, + .mtrJ = MOTOR_PARAM_JS, + .maxElecSpd = MOTOR_PARAM_MAX_SPD, + .maxCurr = MOTOR_PARAM_MAX_CURR, + .maxTrq = MOTOR_PARAM_MAX_TRQ, + .mtrPPMR = MOTOR_PARAM_ENCODER_PPMR, + .zShift = MOTOR_PARAM_ENCODER_ZSHIFT, + .busVolt = INV_VOLTAGE_BUS }; static APT_RegStruct *g_aptCp[PHASE_MAX_NUM] = {APT_U_CP, APT_V_CP, APT_W_CP}; @@ -101,7 +103,7 @@ static void FOSMO_InitWrapper(FOSMO_Handle *fosmo, float ts) .fcLpf = FOSMO_SPD_CUTOFF_FREQ, .pllBdw = FOSMO_PLL_BDW, }; - FOSMO_Init(fosmo, fosmoParam, g_motorParamCp, ts); + FOSMO_Init(fosmo, fosmoParam, &g_motorParamCp, ts); } /** @@ -195,7 +197,7 @@ static void FOSMO_InitWrapperFan(FOSMO_Handle *fosmo, float ts) .fcLpf = FOSMO_SPD_CUTOFF_FREQ_FAN, .pllBdw = FOSMO_PLL_BDW_FAN, }; - FOSMO_Init(fosmo, fosmoParam, g_motorParamFan, ts); + FOSMO_Init(fosmo, fosmoParam, &g_motorParamFan, ts); } /** @@ -841,10 +843,6 @@ void Timer1ITCallBack(void *param) OverTempProtProcess(); } -/* global variables for variable trace */ -volatile float g_mc_u, g_mc_v, g_mc_w; -volatile float g_fan_u, g_fan_v, g_fan_w; -volatile float g_currLoopExeTime; /** * @brief The carrier ISR wrapper function, entry for both compressor and fan. * @param aptHandle The APT handle. @@ -852,21 +850,12 @@ volatile float g_currLoopExeTime; */ void APT3TimerCallback(void *aptHandle) { - unsigned int start = SYSTICK_GetTimeStampUs(); MCS_ASSERT_PARAM(aptHandle != NULL); /* the carrierprocess of comp */ MCS_CarrierProcess(&g_mc); - g_mc_u = g_mc.iuvw.u; - g_mc_v = g_mc.iuvw.v; - g_mc_w = g_mc.iuvw.w; - /* the carrierprocess of fan */ MCS_CarrierProcess(&g_fan); - g_fan_u = g_fan.iuvw.u; - g_fan_v = g_fan.iuvw.v; - g_fan_w = g_fan.iuvw.w; BASE_FUNC_UNUSED(aptHandle); - g_currLoopExeTime = (float)(SYSTICK_GetTimeStampUs() - start); } /** @@ -893,7 +882,7 @@ int MotorMain(void) BASE_FUNC_DELAY_S(PTC_RELAY_DELAY); /* Open PTC relay */ - HAL_GPIO_SetValue(&g_gpio2, GPIO_PIN_0, GPIO_HIGH_LEVEL); + HAL_GPIO_SetValue(&PW_ON_HANDLE, PW_ON_PIN, GPIO_HIGH_LEVEL); BASE_FUNC_DELAY_S(MOTOR_START_DELAY); /* Starting motor. */ @@ -904,9 +893,9 @@ int MotorMain(void) if (g_mc.msTickCnt - tickCnt500Ms >= tickNum500Ms) { if (SysIsError(&g_mc.statusReg) != true && SysIsError(&g_fan.statusReg) != true) { /* The LED blinks when no status is not error. */ - HAL_GPIO_TogglePin(&g_gpio0, GPIO_PIN_5); + HAL_GPIO_TogglePin(&LED_HANDLE, LED_PIN); } else { - HAL_GPIO_SetValue(&g_gpio0, GPIO_PIN_5, GPIO_LOW_LEVEL); + HAL_GPIO_SetValue(&LED_HANDLE, LED_PIN, GPIO_LOW_LEVEL); } tickCnt500Ms = g_mc.msTickCnt; } diff --git a/src/application/middleware_sample/mcs_65demo/application/mcs_user_config.h b/src/application/middleware_sample/mcs_65demo/application/mcs_user_config.h index 1f4c8ecaaf98292ea03815dd16aa9094df9888e5..fc7aeec355dad409979a44004cd2b8c0486dfc5c 100644 --- a/src/application/middleware_sample/mcs_65demo/application/mcs_user_config.h +++ b/src/application/middleware_sample/mcs_65demo/application/mcs_user_config.h @@ -63,15 +63,17 @@ #define MOTOR_PARAM_ENCODER_ZSHIFT (1) /* Pulse Z shift. */ /* ----------------------------PI parameters ----------------------------------- */ -#define CURR_KP (0.07414f) -#define CURR_KI (1200.0f) +#define CURR_KP (0.07414f) /* Current loop Kp of compressor. */ +#define CURR_KI (1200.0f) /* Current loop Ki of compressor. */ +/* Current loop PID output lower limit of compressor. */ #define CURR_LOWERLIM (-INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.95f) +/* Current loop PID output upper limit of compressor. */ #define CURR_UPPERLIM (INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.95f) -#define SPD_KP (0.05f) -#define SPD_KI (0.5f) -#define SPD_LOWERLIM (-MOTOR_PARAM_MAX_CURR) -#define SPD_UPPERLIM (MOTOR_PARAM_MAX_CURR) +#define SPD_KP (0.01f) /* Speed loop Kp. */ +#define SPD_KI (0.5f) /* Speed loop Ki. */ +#define SPD_LOWERLIM (-MOTOR_PARAM_MAX_CURR) /* Speed loop PID output lower limit. */ +#define SPD_UPPERLIM (MOTOR_PARAM_MAX_CURR) /* Speed loop PID output upper limit. */ /** Duty of sample window, the real time is 0.06*50us = 3us. */ #define SAMPLE_WINDOW_DUTY 0.06f @@ -80,7 +82,7 @@ #define SAMPLE_POINT_SHIFT 0.008f /* SMO */ -#define FOSMO_GAIN (8.0f) +#define FOSMO_GAIN (8.0f) /* SMO gain of compressor motor control. */ #define FOSMO_LAMBDA (2.0f) /* SMO coefficient of cut-off frequency, its value = lambda * we */ #define FOSMO_EMF_CUTOFF_FREQ (2.0f) /* SMO back emf cutoff frequency. */ #define FOSMO_SPD_CUTOFF_FREQ (30.0f) /* SMO speed cutoff frequency. of speed filter. */ @@ -89,7 +91,12 @@ /* User Command */ #define CTRL_IF_CURR_AMP_A 1.0f /* IF control current amplitude */ /* 0.008055 Sampling resistance20 Ohm Sampling resistance 100mOhm 0.001611f */ -#define ADC_CURR_COFFI_CP 0.001611f +#if defined CHIP_3065HRPIRZ || defined CHIP_3065ARPIRZ +#define ADC_CURR_COFFI_CP 0.001611f /* 3.3/4096/5/0.1 = 0.001611, 5 is PGA magnification factor. */ +#else +#define ADC_CURR_COFFI_CP 0.008055f /* 3.3/4096/5/0.02 = 0.008055, 5 is PGA magnification factor. */ +#endif + #define USER_TARGET_SPD_HZ (100.0f) /* Parentheses are used to enter negative instructions */ #define USER_SWITCH_SPDBEGIN_HZ 51.0f /* Start of handover interval */ #define USER_SWITCH_SPDEND_HZ 52.0f /* End of handover period */ @@ -113,18 +120,20 @@ #define MOTOR_PARAM_ENCODER_ZSHIFT_FAN (1) /* Pulse Z shift. */ /* ----------------------------PI parameters ----------------------------------- */ -#define CURR_KP_FAN (0.07414f) -#define CURR_KI_FAN (1200.0f) +#define CURR_KP_FAN (0.07414f) /* Current loop Kp of fan. */ +#define CURR_KI_FAN (1200.0f) /* Current loop Ki of fan. */ +/* Current loop PID output lower limit of fan. */ #define CURR_LOWERLIM_FAN (-INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.92f) +/* Current loop PID output upper limit of fan. */ #define CURR_UPPERLIM_FAN (INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.92f) -#define SPD_KP_FAN (0.05f) -#define SPD_KI_FAN (0.5f) -#define SPD_LOWERLIM_FAN (-MOTOR_PARAM_MAX_CURR) -#define SPD_UPPERLIM_FAN (MOTOR_PARAM_MAX_CURR) +#define SPD_KP_FAN (0.01f) /* Speed loop Kp. */ +#define SPD_KI_FAN (0.5f) /* Speed loop Ki. */ +#define SPD_LOWERLIM_FAN (-MOTOR_PARAM_MAX_CURR) /* Speed loop PID output lower limit. */ +#define SPD_UPPERLIM_FAN (MOTOR_PARAM_MAX_CURR) /* Speed loop PID output upper limit. */ /* SMO */ -#define FOSMO_GAIN_FAN (8.0f) +#define FOSMO_GAIN_FAN (8.0f) /* SMO gain */ #define FOSMO_LAMBDA_FAN (2.0f) /* SMO coefficient of cut-off frequency, its value = lambda * we */ #define FOSMO_EMF_CUTOFF_FREQ_FAN (2.0f) /* SMO back emf cutoff frequency. */ #define FOSMO_SPD_CUTOFF_FREQ_FAN (30.0f) /* SMO speed cutoff frequency. of speed filter. */ @@ -133,7 +142,7 @@ #define CTRL_IF_CURR_AMP_A_FAN 0.8f /* IF control current amplitude */ /* 0.008055 Sampling resistance20 Ohm Sampling resistance 100mOhm 0.001611f */ -#define ADC_CURR_COFFI_FAN 0.001611f +#define ADC_CURR_COFFI_FAN 0.001611f /* 3.3/4096/5/0.1 = 0.001611, 5 is PGA magnification factor. */ #define USER_TARGET_SPD_HZ_FAN (100.0f) /* Parentheses are used to enter negative instructions */ #define USER_SWITCH_SPDBEGIN_HZ_FAN 50.0f /* Start of handover interval, Positive number only */ diff --git a/src/application/middleware_sample/mcs_65demo/readme.md b/src/application/middleware_sample/mcs_65demo/readme.md index b89fd868c261eaf730a7c88ac69ee6cc53ab55c4..1a39ca2274994578b200857b5ceadacbb4b9f625 100644 --- a/src/application/middleware_sample/mcs_65demo/readme.md +++ b/src/application/middleware_sample/mcs_65demo/readme.md @@ -10,4 +10,5 @@ + chipConfig中的sample栏目里面选中Motorcontrolsystem示例,然后点击生成代码即可 **【注意事项】** -+ 供电电源24V \ No newline at end of file ++ 供电电源24V ++ 需在IDE的“工程”->“工程配置”->"编译优化等级"中将优化等级设为O3,否则可能会由于计算资源不够导致电机控制失败。 \ No newline at end of file diff --git a/src/application/middleware_sample/mcs_65ldemo/application/mcs_motor_process.c b/src/application/middleware_sample/mcs_65ldemo/application/mcs_motor_process.c index c73007cc402e0b2749be441a8beb0765e3b3d6f3..eeb2a8f7f10de6fe88d2fb7d5ba24a61a098e780 100644 --- a/src/application/middleware_sample/mcs_65ldemo/application/mcs_motor_process.c +++ b/src/application/middleware_sample/mcs_65ldemo/application/mcs_motor_process.c @@ -38,18 +38,19 @@ void ISR_OverCurrProt(void *aptHandle); /* Motor parameters */ /* Np, Rs, Ld, Lq, Psif, J, Nmax, Currmax, PPMR, zShift */ static MOTOR_Param g_motorParam = { - MOTOR_PARAM_NP, - MOTOR_PARAM_RS, - MOTOR_PARAM_LD, - MOTOR_PARAM_LQ, - MOTOR_PARAM_LS, - MOTOR_PARAM_PSIF, - MOTOR_PARAM_JS, - MOTOR_PARAM_MAX_SPD, - MOTOR_PARAM_MAX_CURR, - MOTOR_PARAM_MAX_TRQ, - MOTOR_PARAM_ENCODER_PPMR, - MOTOR_PARAM_ENCODER_ZSHIFT + .mtrNp = MOTOR_PARAM_NP, + .mtrRs = MOTOR_PARAM_RS, + .mtrLd = MOTOR_PARAM_LD, + .mtrLq = MOTOR_PARAM_LQ, + .mtrLs = MOTOR_PARAM_LS, + .mtrPsif = MOTOR_PARAM_PSIF, + .mtrJ = MOTOR_PARAM_JS, + .maxElecSpd = MOTOR_PARAM_MAX_SPD, + .maxCurr = MOTOR_PARAM_MAX_CURR, + .maxTrq = MOTOR_PARAM_MAX_TRQ, + .mtrPPMR = MOTOR_PARAM_ENCODER_PPMR, + .zShift = MOTOR_PARAM_ENCODER_ZSHIFT, + .busVolt = INV_VOLTAGE_BUS }; static APT_RegStruct *g_aptCp[PHASE_MAX_NUM] = {APT_U_CP, APT_V_CP, APT_W_CP}; @@ -88,7 +89,7 @@ static void FOSMO_InitWrapper(FOSMO_Handle *fosmo, float ts) .fcLpf = FOSMO_SPD_CUTOFF_FREQ, .pllBdw = FOSMO_PLL_BDW, }; - FOSMO_Init(fosmo, fosmoParam, g_motorParam, ts); + FOSMO_Init(fosmo, fosmoParam, &g_motorParam, ts); } /** diff --git a/src/application/middleware_sample/mcs_65ldemo/application/mcs_user_config.h b/src/application/middleware_sample/mcs_65ldemo/application/mcs_user_config.h index 54c3f5aa5a984623f73184eed778efe8dc117829..03e0734a1f4f78f865dd9d4e7c1ac9fefe70f2a8 100644 --- a/src/application/middleware_sample/mcs_65ldemo/application/mcs_user_config.h +++ b/src/application/middleware_sample/mcs_65ldemo/application/mcs_user_config.h @@ -60,15 +60,17 @@ #define MOTOR_PARAM_ENCODER_ZSHIFT (1) /* Pulse Z shift. */ /* ----------------------------PI parameters----------------------------------- */ -#define CURR_KP (0.07414f) -#define CURR_KI (1200.0f) +#define CURR_KP (0.07414f) /* Current loop Kp. */ +#define CURR_KI (1200.0f) /* Current loop Ki. */ +/* Current loop PID output lower limit. */ #define CURR_LOWERLIM (-INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.92f) +/* Current loop PID output upper limit. */ #define CURR_UPPERLIM (INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.92f) -#define SPD_KP (0.05f) -#define SPD_KI (0.5f) -#define SPD_LOWERLIM (-MOTOR_PARAM_MAX_CURR) -#define SPD_UPPERLIM (MOTOR_PARAM_MAX_CURR) +#define SPD_KP (0.01f) /* Speed loop Kp. */ +#define SPD_KI (0.5f) /* Speed loop Ki. */ +#define SPD_LOWERLIM (-MOTOR_PARAM_MAX_CURR) /* Speed loop PID output lower limit. */ +#define SPD_UPPERLIM (MOTOR_PARAM_MAX_CURR) /* Speed loop PID output upper limit. */ /** Duty of sample window, the real time is 0.06 *100us / 2 = 3us. */ #define SAMPLE_WINDOW_DUTY 0.06f diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/app_config/mcs_chip_config.h b/src/application/middleware_sample/mcs_hall_bldc_1shunt/app_config/mcs_chip_config.h index 8c8e7f5681cb5c08c10039a664bb6ee088ad3d7d..278206ad6726b948f04b26fe2d71621951631762 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/app_config/mcs_chip_config.h +++ b/src/application/middleware_sample/mcs_hall_bldc_1shunt/app_config/mcs_chip_config.h @@ -25,7 +25,9 @@ #include "feature.h" -#ifdef CHIP_3061MNPICA +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNNIKA) || defined (CHIP_3061MNPIC8) || defined(CHIP_3061MNNIC8) || \ + defined (CHIP_3061MNPIK8) || defined (CHIP_3061MNNIK8) /* 3061m */ #define ADC_U_HANDLE g_adc0 // ibus #define ADC_U_SOC_NUM ADC_SOC_NUM0 @@ -46,7 +48,8 @@ #define LED2_PIN GPIO_PIN_3 #endif -#if defined CHIP_3065HRPIRZ || defined CHIP_3065ARPIRZ +#if defined CHIP_3065HRPIRZ || defined CHIP_3065ARPIRZ || defined CHIP_3066MNPIRH || \ + defined CHIP_3065PNPIRH || defined CHIP_3065PNPIRE || defined CHIP_3065PNPIRA /* 3065h */ #define ADC_U_HANDLE g_adc0 // ibus #define ADC_U_SOC_NUM ADC_SOC_NUM0 diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/app_config/mcs_user_config.h b/src/application/middleware_sample/mcs_hall_bldc_1shunt/app_config/mcs_user_config.h index d12a6d285860d69df6d14834134e15002ec60071..278b20f921f932759e8c9c953b14f504da5adab7 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/app_config/mcs_user_config.h +++ b/src/application/middleware_sample/mcs_hall_bldc_1shunt/app_config/mcs_user_config.h @@ -75,25 +75,31 @@ #define ADC_TRIMVALUE_MIN 1820.0 #define ADC_TRIMVALUE_MAX 2280.0 -#define HALL_PHASESHIFT 3.1415926f +#define HALL_DIR 1 #define HALL_ANGLE_PLL_BDW 50.0f #define HALL_SPD_FILTER_FC 5.0f -/* Motor protection */ -#define OVER_CURR_AMP_THRESHOLD 4.0f -#define OVER_CURR_TIME_THRESHOLD 0.5f +/* Protection */ +#define OVD_MAX_VOLT_V (28.0f) +#define OVD_REC_VOLT_V (26.0f) +#define LVD_MIN_VOLT_V (20.0f) +#define LVD_REC_VOLT_V (22.0f) +#define VOLT_DET_WINDOW_S (0.5f) /* 0.5s */ +#define VOLT_REC_WINDOW_S (1.0f) /* 1.0s */ -#define OVER_TEMP_AMP_THRESHOLD 40.0f -#define OVER_TEMP_TIME_THRESHOLD 2.0f +#define OTD_MAX_TEMP_MTR (120.0f) /* 120 degrees Celsius */ +#define OTD_MAX_TEMP_BRD (40.0f) /* 80 degrees Celsius */ +#define OTD_MTR_WINDOW_S (1.0f) /* 1.0s */ +#define OTD_BRD_WINDOW_S (1.0f) /* 1.0s */ -#define OVER_VOLT_AMP_THRESHOLD 26.0f -#define OVER_VOLT_TIME_THRESHOLD 2.0f +#define OCD_MAX_CURR_A (4.0f) +#define OCD_WINDOW_S (0.001f) -#define LOWER_VOLT_AMP_THRESHOLD 22.0f -#define LOWER_VOLT_TIME_THRESHOLD 2.0f +#define STD_LOSESPD_LOWER_HZ (10.0f) /**/ +#define STD_LOSESPD_UPPER_HZ (2.0f * USER_MAX_SPD_HZ) /* 2 * maxSpeed */ +#define STD_DET_WINDOW_S (1.0f) -#define STALL_CURR_THRESHOLD 2.0f -#define STALL_SPEED_THRESHOLD 10.0f -#define STALL_TIME_THRESHOLD 1.0f +#define OPD_MIN_CURR_A (0.02f) +#define OPD_WINDOW_S (1.0f) #endif \ No newline at end of file diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/application/mcs_motor_process.c b/src/application/middleware_sample/mcs_hall_bldc_1shunt/application/mcs_motor_process.c index d78f09d92f4b804846d2dace7f2b4ff1049d4ac6..76cb319d787b8ca78b58509c9674a6b04105358b 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/application/mcs_motor_process.c +++ b/src/application/middleware_sample/mcs_hall_bldc_1shunt/application/mcs_motor_process.c @@ -54,13 +54,6 @@ #define HALL_VALUE_5 5 #define HALL_VALUE_6 6 -#define SECTOR1 1 -#define SECTOR2 2 -#define SECTOR3 3 -#define SECTOR4 4 -#define SECTOR5 5 -#define SECTOR6 6 - #define US_PER_MS 1000 #define APT_FULL_DUTY 1.0f /*------------------------------- Param Definition -----------------------------------------------*/ @@ -76,204 +69,135 @@ static HALL_Handle g_hall; /*------------------------------- Function Definition -----------------------------------------------*/ /** - * @brief Get the encoder speed and angle. - * @param speed electricity speed. - * @param angle electricity angle. - * @retval None. - */ -static void GetHallAngSpd(float* speed, float* angle) -{ - static TrigVal localTrigVal; - /* QDM uses algorithm-driven acquisition speed and angle */ - HALL_AngSpdCalcExec(&g_hall); - - TrigCalc(&localTrigVal, g_hall.angle); - PLL_Exec(&g_mc.hallAnglePll, localTrigVal.sin, localTrigVal.cos); - - *speed = FOLPF_Exec(&g_mc.hallSpdFilter, g_hall.spd); - *angle = g_mc.hallAnglePll.angle; -} - - -/** - * @brief Configure three kinds of APT action, H_PWM_L_ON mode. - * @param aptAddr APT base address. - * @param aptAct The APT action. + * @brief Receive hall signal. + * @retval Hall value. */ -static void SIXSTEP_ForcePwmOut(APT_RegStruct* aptAddr, APT_Act aptAct) +static unsigned int GetHallValue(void) { - switch (aptAct) { - case APT_CHA_PWM_CHB_LOW: - /* Channel A: 0 means not force output enable, channel A output PWM. */ - DCL_APT_DisableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A); - /* Channel B: 1 means force output enable. */ - DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B); - /* Channel B: 2 means channel B force output LOW due to the A_H_B_L invert. */ - DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B, APT_PWM_OUT_ALWAYS_HIGH); - break; +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNNIKA) || defined (CHIP_3061MNPIC8) || defined(CHIP_3061MNNIC8) || \ + defined (CHIP_3061MNPIK8) || defined (CHIP_3061MNNIK8) + /* Get three hall values. */ + unsigned int h1 = HAL_CAPM_GetCrtEdge(&g_capm2) & 0x01; + unsigned int h2 = HAL_CAPM_GetCrtEdge(&g_capm1) & 0x01; + unsigned int h3 = HAL_CAPM_GetCrtEdge(&g_capm0) & 0x01; +#endif - case APT_CHA_LOW_CHB_HIGH: - /* Channel A: 1 means force output enable. */ - /* Channel A: 1 means channel A force output LOW. */ - DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A); - DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A, APT_PWM_OUT_ALWAYS_LOW); - /* Channel B: 1 means force output enable. */ - /* Channel B: 1 means channel A force output HIGH due to the A_H_B_L invert. */ - DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B); - DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B, APT_PWM_OUT_ALWAYS_LOW); - break; +#if defined (CHIP_3065HRPIRZ) || defined (CHIP_3065ARPIRZ) + /* Get three hall values. */ + unsigned int h1 = HAL_CAPM_GetCrtEdge(&g_capm1) & 0x01; + unsigned int h2 = HAL_CAPM_GetCrtEdge(&g_capm0) & 0x01; + unsigned int h3 = HAL_CAPM_GetCrtEdge(&g_capm2) & 0x01; +#endif - case APT_CHA_LOW_CHB_LOW: - /* Channel A: 1 means force output enable. */ - /* Channel A: 1 means channel A force output LOW. */ - DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A); - DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A, APT_PWM_OUT_ALWAYS_LOW); - /* Channel B: 1 means force output enable. */ - /* Channel B: 2 means channel A force output LOW due to the A_H_B_L invert. */ - DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B); - DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B, APT_PWM_OUT_ALWAYS_HIGH); - break; - default: - break; - } -} +#if defined CHIP_3066MNPIRH || defined CHIP_3065PNPIRH || defined CHIP_3065PNPIRE || defined CHIP_3065PNPIRA + /* Get three hall values. */ + unsigned int h1 = HAL_CAPM_GetCrtEdge(&g_capm2) & 0x01; + unsigned int h2 = HAL_CAPM_GetCrtEdge(&g_capm0) & 0x01; + unsigned int h3 = HAL_CAPM_GetCrtEdge(&g_capm1) & 0x01; +#endif -/** - * @brief Configure the APT action mode for six sectors. - * @param aptUvw APT base address of U V W. - * @param sector Sector. - */ -static void SIXSTEP_AptConfig(APT_RegStruct **aptUvw, unsigned int sector) -{ - APT_RegStruct *aptU = aptUvw[0]; - APT_RegStruct *aptV = aptUvw[1]; - APT_RegStruct *aptW = aptUvw[2]; /* index 2. */ - switch (sector) { - case SECTOR1: /* A+, C- */ - SIXSTEP_ForcePwmOut(aptU, APT_CHA_PWM_CHB_LOW); - SIXSTEP_ForcePwmOut(aptV, APT_CHA_LOW_CHB_LOW); - SIXSTEP_ForcePwmOut(aptW, APT_CHA_LOW_CHB_HIGH); - break; - case SECTOR2: /* B+, C- */ - SIXSTEP_ForcePwmOut(aptU, APT_CHA_LOW_CHB_LOW); - SIXSTEP_ForcePwmOut(aptV, APT_CHA_PWM_CHB_LOW); - SIXSTEP_ForcePwmOut(aptW, APT_CHA_LOW_CHB_HIGH); - break; - case SECTOR3: /* B+, A- */ - SIXSTEP_ForcePwmOut(aptU, APT_CHA_LOW_CHB_HIGH); - SIXSTEP_ForcePwmOut(aptV, APT_CHA_PWM_CHB_LOW); - SIXSTEP_ForcePwmOut(aptW, APT_CHA_LOW_CHB_LOW); - break; - case SECTOR4: /* C+, A- */ - SIXSTEP_ForcePwmOut(aptU, APT_CHA_LOW_CHB_HIGH); - SIXSTEP_ForcePwmOut(aptV, APT_CHA_LOW_CHB_LOW); - SIXSTEP_ForcePwmOut(aptW, APT_CHA_PWM_CHB_LOW); - break; - case SECTOR5: /* C+, B- */ - SIXSTEP_ForcePwmOut(aptU, APT_CHA_LOW_CHB_LOW); - SIXSTEP_ForcePwmOut(aptV, APT_CHA_LOW_CHB_HIGH); - SIXSTEP_ForcePwmOut(aptW, APT_CHA_PWM_CHB_LOW); - break; - case SECTOR6: /* A+, B- */ - SIXSTEP_ForcePwmOut(aptU, APT_CHA_PWM_CHB_LOW); - SIXSTEP_ForcePwmOut(aptV, APT_CHA_LOW_CHB_HIGH); - SIXSTEP_ForcePwmOut(aptW, APT_CHA_LOW_CHB_LOW); - break; - default: - break; - } + /* Terminal connection sequence: WVU-+ --> H3H2H1-+ */ + unsigned int retValue = (h1 << 2) + (h2 << 1) + (h3 << 0); + return retValue; } + /** * @brief CW: Matching sector corresponding to the hall value. * @param hallValue Sum of hallC << 2, hallB << 1 and hallA << 1. - * @param sector Generate pwm sector. + * @retval Motor sector. */ -static void MatchCw(unsigned int hallValue, unsigned int *sector) +static HALL_SECTOR MatchCw(unsigned int hallValue) { + HALL_SECTOR sector = SECTOR1; switch (hallValue) { case HALL_VALUE_3: /* B+, A- */ - *sector = SECTOR3; + sector = SECTOR3; break; case HALL_VALUE_2: /* B+, C- */ - *sector = SECTOR2; + sector = SECTOR2; break; case HALL_VALUE_6: /* A+, C- */ - *sector = SECTOR1; + sector = SECTOR1; break; case HALL_VALUE_4: /* A+, B- */ - *sector = SECTOR6; + sector = SECTOR6; break; case HALL_VALUE_5: /* C+, B- */ - *sector = SECTOR5; + sector = SECTOR5; break; case HALL_VALUE_1: /* C+, A- */ - *sector = SECTOR4; + sector = SECTOR4; break; default: break; } + return sector; } /** * @brief CCW: Matching sector corresponding to the hall value. * @param hallValue Sum of hallC << 2, hallB << 1 and hallA << 1. - * @param sector Generate pwm sector. + * @retval Motor sector. */ -static void MatchCcw(unsigned int hallValue, unsigned int *sector) +static HALL_SECTOR MatchCcw(unsigned int hallValue) { + HALL_SECTOR sector = SECTOR1; switch (hallValue) { case HALL_VALUE_3: /* A+, B- */ - *sector = SECTOR6; + sector = SECTOR6; break; case HALL_VALUE_2: /* C+, B- */ - *sector = SECTOR5; + sector = SECTOR5; break; case HALL_VALUE_6: /* C+, A- */ - *sector = SECTOR4; + sector = SECTOR4; break; case HALL_VALUE_4: /* B+, A- */ - *sector = SECTOR3; + sector = SECTOR3; break; case HALL_VALUE_5: /* B+, C- */ - *sector = SECTOR2; + sector = SECTOR2; break; case HALL_VALUE_1: /* A+, C- */ - *sector = SECTOR1; + sector = SECTOR1; break; default: break; } + return sector; } /** * @brief Matching sector corresponding to the hall value. * @param hallValue Sum of hallC << 2, hallB << 1 and hallA << 1. - * @param sector Generate pwm sector. - * @param dir Rotate direction. + * @retval Motor sector. */ -static void SIXSTEP_Match(unsigned int hallValue, unsigned int *sector, int dir) +static HALL_SECTOR SectorMatch(unsigned int hallValue) { + int dir = g_hall.dir; if (dir == 1) { /* Clock Wise rotation: sector increase direction. */ - MatchCw(hallValue, sector); + return MatchCw(hallValue); } else if (dir == -1) { /* Counter Clock Wise rotation: sector decrease direction. */ - MatchCcw(hallValue, sector); + return MatchCcw(hallValue); + } else { + return SECTOR1; } } - /** * @brief Set pwm duty. * @param aptUvw APT base address of U V W. @@ -281,12 +205,12 @@ static void SIXSTEP_Match(unsigned int hallValue, unsigned int *sector, int dir) * @param duty Pwm duty: 0 ~ 1. * @retval None. */ -static void SIXSTEP_SetPwmDuty(APT_RegStruct **aptUvw, unsigned short maxDutyCnt, float duty) +static void SetPwmDuty(APT_RegStruct **aptUvw, unsigned short maxDutyCnt, float duty) { MCS_ASSERT_PARAM(aptUvw != NULL); MCS_ASSERT_PARAM(duty >= 0.0f); MCS_ASSERT_PARAM(duty <= 1.0f); - unsigned short dutyCnt = (unsigned short)Clamp((float)maxDutyCnt * (1.0f - duty), (float)maxDutyCnt, 1.0f); + unsigned short dutyCnt = (unsigned short)Clamp((float)maxDutyCnt * (1.0f - duty), (float)maxDutyCnt, 0.0f); /* Set three phase duty. */ for (int i = 0; i < PHASE_MAX_NUM; i++) { APT_RegStruct *aptx = aptUvw[i]; @@ -295,49 +219,6 @@ static void SIXSTEP_SetPwmDuty(APT_RegStruct **aptUvw, unsigned short maxDutyCnt } } - -/** - * @brief Config the master APT. - * @param aptx The master APT handle. - * @retval None. - */ -static void AptMasterSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - /* Config the master APT. */ - HAL_APT_MasterSyncInit(aptx, APT_SYNC_OUT_ON_CNTR_ZERO); -} - -/** - * @brief Config the slave APT. - * @param aptx The slave APT handle. - * @retval None. - */ -static void AptSalveSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - APT_SlaveSyncIn slave; - /* Config the slave APT. */ - slave.divPhase = 0; - slave.cntPhase = 0; - slave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; - slave.syncInSrc = APT_SYNC_IN_SRC; - slave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; - HAL_APT_SlaveSyncInit(aptx, &slave); -} - -/** - * @brief Configuring Master and Slave APTs. - * @retval None. - */ -static void AptMasterSalveSet(void) -{ - /* motor fan APT master/slave synchronization */ - AptMasterSet(&g_apt0); - AptSalveSet(&g_apt1); - AptSalveSet(&g_apt2); -} - /** * @brief Initialzer of system tick. * @param mtrCtrl Motor control struct handle. @@ -370,6 +251,26 @@ static void SpdCtrlInit(MTRCTRL_Handle *mtrCtrl, float ts) mtrCtrl->spdPi.ts = ts; } +/** + * @brief Initialzer of under and over voltage fault detection. + * @param uovd Under and over voltage struct handle. + * @param ts Speed control period (s). + * @retval None. + */ +static void FP_UOVD_InitWrapper(FP_UOVD_Handle *uovd, float ts) +{ + /* Parameter init. */ + /* Include under and over voltage detection parameter. */ + FP_UOVD_Param param = { + .overProThr = OVD_MAX_VOLT_V, + .overRecThr = OVD_REC_VOLT_V, + .underProThr = LVD_MIN_VOLT_V, + .underRecThr = LVD_REC_VOLT_V, + .detWindow = VOLT_DET_WINDOW_S, + .recWindow = VOLT_REC_WINDOW_S, + }; + FP_UOVD_Init(uovd, ¶m, ts); +} /** * @brief Init motor control task. @@ -377,20 +278,29 @@ static void SpdCtrlInit(MTRCTRL_Handle *mtrCtrl, float ts) */ static void TSK_InitCp(void) { - g_mc.dir = 1; g_mc.stateMachine = FSM_IDLE; - g_mc.aptMaxcntCmp = g_apt0.waveform.timerPeriod; + g_mc.aptMaxCntCmp = g_apt0.waveform.timerPeriod; + g_mc.hall = &g_hall; RMG_Init(&g_mc.spdRmg, CTRL_SYSTICK_PERIOD, USER_SPD_SLOPE); /* Init speed slope */ + MtrParamInit(&g_mc.mtrParam, g_motorParam); + TimerTickInit(&g_mc); + SpdCtrlInit(&g_mc, CTRL_SYSTICK_PERIOD); /* Init speed controller */ - HALL_Init(&g_hall, HALL_PHASESHIFT, CTRL_CURR_PERIOD); - PLL_Init(&g_mc.hallAnglePll, CTRL_CURR_PERIOD, HALL_ANGLE_PLL_BDW); - FOLPF_Init(&g_mc.hallSpdFilter, CTRL_CURR_PERIOD, HALL_SPD_FILTER_FC); + HALL_Init(&g_hall, HALL_DIR, HALL_ANGLE_PLL_BDW, HALL_SPD_FILTER_FC, CTRL_CURR_PERIOD); /* Protection. */ - FaultDetect_Init(&g_mc.faultDet); + FP_UOVD_InitWrapper(&g_mc.uovd, CTRL_SYSTICK_PERIOD); + + FP_OTD_Init(&g_mc.otd, OTD_MAX_TEMP_MTR, OTD_MAX_TEMP_BRD, OTD_MTR_WINDOW_S, OTD_BRD_WINDOW_S, CTRL_SYSTICK_PERIOD); + + FP_OCD_Init(&g_mc.ocd, OCD_MAX_CURR_A, OCD_WINDOW_S, CTRL_CURR_PERIOD); + + FP_STD_Init(&g_mc.std, STD_LOSESPD_LOWER_HZ, STD_LOSESPD_UPPER_HZ, STD_DET_WINDOW_S, CTRL_CURR_PERIOD); + + FP_OPD_Init(&g_mc.opd, OPD_MIN_CURR_A, OPD_WINDOW_S, CTRL_CURR_PERIOD); } /** @@ -406,12 +316,23 @@ static void ClearBeforeStartup(MTRCTRL_Handle *mtrCtrl) mtrCtrl->pwmDuty = 0.0f; /* Clear the history value of speed slope control */ RMG_Clear(&mtrCtrl->spdRmg); + PID_Clear(&mtrCtrl->spdPi); - PLL_Clear(&mtrCtrl->hallAnglePll); - FOLPF_Clear(&mtrCtrl->hallSpdFilter); + HALL_Clear(&g_hall); /* Clear protection history value. */ - FaultDetect_Clear(&mtrCtrl->faultDet); + + Fault_Clear(&mtrCtrl->faultStatus); + + FP_UOVD_Clear(&mtrCtrl->uovd); + + FP_OTD_Clear(&mtrCtrl->otd); + + FP_OCD_Clear(&mtrCtrl->ocd); + + FP_STD_Clear(&mtrCtrl->std); + + FP_OPD_Clear(&mtrCtrl->opd); } @@ -466,6 +387,24 @@ static void MotorPwmOutputDisable(volatile APT_RegStruct **aptAddr) } } +static void FualtDetCarr(void) +{ + if (g_mc.stateMachine == FSM_RUN) { + /* Over current det. */ + FP_OCD_Exec(&g_mc.ocd, &g_mc.faultStatus, g_mc.iuvw); + /* Open phase det. */ + FP_OPD_Exec(&g_mc.opd, &g_mc.faultStatus, g_mc.iuvw); + /* Stall det. */ + FP_STD_Exec(&g_mc.std, &g_mc.faultStatus, g_mc.hall->timer, g_mc.spdFbk); + } + /* Fault judgement. */ + if (g_mc.stateMachine == FSM_RUN || g_mc.stateMachine == FSM_STARTUP) { + if (g_mc.faultStatus.all) { + g_mc.stateMachine = FSM_FAULT; + } + } +} + /** * @brief Pre-processing of motor status. @@ -544,7 +483,7 @@ static void CheckSysCmdStart(MTRCTRL_Handle *mtrCtrl, volatile APT_RegStruct **a mtrCtrl->sysTickCnt = 0; *stateMachine = FSM_CAP_CHARGE; /* Preparation for charging the bootstrap capacitor. */ - AptTurnOnLowSidePwm(aptAddr, mtrCtrl->aptMaxcntCmp); + AptTurnOnLowSidePwm(aptAddr, mtrCtrl->aptMaxCntCmp); /* Out put pwm */ MotorPwmOutputEnable(aptAddr); } @@ -616,9 +555,7 @@ static void TSK_SystickIsr(MTRCTRL_Handle *mtrCtrl, APT_RegStruct **aptAddr) MotorPwmOutputDisable(aptAddr); /* Clear run state. */ SysRunningClr(statusReg); - mtrCtrl->hallSpeed = 0.0f; mtrCtrl->spdFbk = 0.0f; - mtrCtrl->hallAxisAngle = 0.0f; *stateMachine = FSM_IDLE; break; @@ -644,26 +581,6 @@ static void readCurrBiasCb(IBIAS_Handle *iuvwAdcBias) } -/** - * @brief Read the ADC current sampling value. - * @retval None. - */ -static void ReadBusCurrCb(float *idc) -{ - /* when current is zero, the adc1 value is adc0Compensate/adc1Compensate value */ - float adcVal = (float)HAL_ADC_GetConvResult(&ADC_U_HANDLE, ADC_U_SOC_NUM); - *idc = (adcVal - (float)g_mc.iuvwAdcBias.iBusAdcBias) * ADC_CURR_COFFI; -} - -/** - * @brief Read the ADC volate sampling value. - * @retval None. - */ -static void ReadBusVoltCb(float *udc) -{ - *udc = (float)HAL_ADC_GetConvResult(&ADC_UDC_HANDLE, ADC_UDC_SOC_NUM) * ADC_VOLT_COFFI; -} - /** * @brief Temprature table. * @param tempResisValue Temperature sensor resistance. @@ -671,7 +588,7 @@ static void ReadBusVoltCb(float *udc) */ static float TempTable(float tempResisValue) { - float boardTemp = 25.0f; /* Normal temp is 25 */ + float boardTemp = 0.0f; /* Temperatures between 15 and 30. */ if (tempResisValue > TEMP_RES_30 && tempResisValue <= TEMP_RES_15) { boardTemp = TEMP_15 + (TEMP_30 - TEMP_15) * (TEMP_RES_15 - tempResisValue) / (TEMP_RES_15 - TEMP_RES_30); @@ -713,8 +630,15 @@ void MotorStatemachineCallBack(void *param) TIMER_ASSERT_PARAM(timer->baseAddress != NULL); /* Clear timer interrupt. */ DCL_TIMER_IrqClear(timer->baseAddress); + /* Get board temperature. */ ReadBoardTemp(); TSK_SystickIsr(&g_mc, g_aptAddr); + if (g_mc.stateMachine == FSM_RUN) { + /* Over and under voltage det. */ + FP_UOVD_Exec(&g_mc.uovd, &g_mc.faultStatus, g_mc.udc); + /* Over temperature det. */ + FP_OTD_Exec(&g_mc.otd, &g_mc.faultStatus, 0.0f, g_mc.powerBoardTemp); + } } /** @@ -766,7 +690,7 @@ static void MotorBlockageProtect(void) MotorPwmOutputDisable(g_aptAddr); /* Status setting error */ SysErrorSet(&g_mc.statusReg); - g_hall.spd = 0.0f; + g_hall.spdEst = 0.0f; } } @@ -789,33 +713,11 @@ void MotorSysErrCallback(void *para) SysErrorSet(&g_mc.statusReg); g_mc.stateMachine = FSM_FAULT; DBG_PRINTF("APT error! \r\n"); + g_mc.faultStatus.Bit.hardOverCurFault = 1; HAL_GPIO_SetValue(&LED2_HANDLE, LED2_PIN, GPIO_LOW_LEVEL); BASE_FUNC_UNUSED(handle); } -/** - * @brief Receive hall signal. - * @retval None. - */ -static unsigned int GetHallValue(void) -{ -#ifdef CHIP_3061MNPICA - /* Get three hall values. */ - unsigned int hallA = HAL_CAPM_GetCrtEdge(&g_capm0) & 0x01; - unsigned int hallB = HAL_CAPM_GetCrtEdge(&g_capm1) & 0x01; - unsigned int hallC = HAL_CAPM_GetCrtEdge(&g_capm2) & 0x01; -#endif - -#if defined CHIP_3065HRPIRZ || defined CHIP_3065ARPIRZ - /* Get three hall values. */ - unsigned int hallA = HAL_CAPM_GetCrtEdge(&g_capm2) & 0x01; - unsigned int hallB = HAL_CAPM_GetCrtEdge(&g_capm0) & 0x01; - unsigned int hallC = HAL_CAPM_GetCrtEdge(&g_capm1) & 0x01; -#endif - /* WVU-+ --> H3H2H1-+ */ - unsigned int retValue = (hallC << 2) + (hallB << 1) + (hallA << 0); - return retValue; -} /** * @brief Init motor controller's data structure. @@ -823,16 +725,73 @@ static unsigned int GetHallValue(void) */ static void InitSoftware(void) { - /* MCU peripheral configuration function used for initial motor control */ - g_mc.getHallAngSpd = GetHallAngSpd; /* Callback function for obtaining the encoder speed angle. */ - g_hall.getHallValue = GetHallValue; - g_mc.readCurrBiasCb = readCurrBiasCb; - g_mc.readBusVoltCb = ReadBusVoltCb; - g_mc.readBusCurrCb = ReadBusCurrCb; /* Initializing motor Control Tasks */ TSK_InitCp(); } +/** + * @brief Read the ADC current sampling value. + * @param iuvw Three-phase current. + * @retval None. + */ +static void ReadCurrUvw(UvwAxis *iuvw, HALL_SECTOR sector) +{ + MCS_ASSERT_PARAM(iuvw != NULL); + /* Sample point is set to pwm falling edge left offset by 100. */ + float point = g_mc.aptMaxCntCmp * (1.0f - g_mc.pwmDuty) + 100.0f; /* Point shift is 100. */ + unsigned short samplePoint = (unsigned short)Clamp(point, g_mc.aptMaxCntCmp - 1.0f, 1.0f); + DCL_APT_SetCounterCompare(g_apt0.baseAddress, APT_COMPARE_REFERENCE_A, samplePoint); + float iBusAbs = Abs(((float)HAL_ADC_GetConvResult(&ADC_U_HANDLE, ADC_U_SOC_NUM) + - g_mc.iuvwAdcBias.iBusAdcBias) * ADC_CURR_COFFI); + float iu, iv, iw; + /* Calc uvw phase current according to sector. */ + switch (sector) { + case SECTOR1: /* A+C- */ + iu = iBusAbs; + iv = 0.0f; + iw = -iBusAbs; + break; + + case SECTOR2: /* B+C- */ + iu = 0.0f; + iv = iBusAbs; + iw = -iBusAbs; + break; + + case SECTOR3: /* B+A- */ + iu = -iBusAbs; + iv = iBusAbs; + iw = 0.0f; + break; + + case SECTOR4: /* C+A- */ + iu = -iBusAbs; + iv = 0.0f; + iw = iBusAbs; + break; + + case SECTOR5: /* C+B- */ + iu = 0.0f; + iv = -iBusAbs; + iw = iBusAbs; + break; + + case SECTOR6: /* A+B- */ + iu = iBusAbs; + iv = -iBusAbs; + iw = 0.0f; + break; + + default: + iu = 0.0f; + iv = 0.0f; + iw = 0.0f; + break; + } + iuvw->u = iu; + iuvw->v = iv; + iuvw->w = iw; +} /** * @brief The carrier ISR wrapper function. @@ -842,33 +801,27 @@ static void InitSoftware(void) void MotorCarrierProcessCallback(void *aptHandle) { BASE_FUNC_UNUSED(aptHandle); - g_mc.readBusVoltCb(&g_mc.udc); - g_mc.readBusCurrCb(&g_mc.idc); /* Calculate hall sector. */ - HALL_InformationUpdate(&g_hall); - GetHallAngSpd(&g_mc.hallSpeed, &g_mc.hallAxisAngle); - SIXSTEP_Match(GetHallValue(), &g_mc.sector, g_mc.dir); - /* Get feedback speed. */ - g_mc.spdFbk = g_mc.hallSpeed; - - SIXSTEP_SetPwmDuty(g_aptAddr, g_mc.aptMaxcntCmp, g_mc.pwmDuty); + HALL_SECTOR sector = SectorMatch(GetHallValue()); + HALL_Exec(&g_hall, sector); + g_mc.spdFbk = g_hall.spdEst; if (g_mc.stateMachine == FSM_OFFSET_CALIB) { - g_mc.readCurrBiasCb(&g_mc.iuvwAdcBias); + readCurrBiasCb(&g_mc.iuvwAdcBias); } if (g_mc.stateMachine == FSM_RUN) { - SIXSTEP_AptConfig(g_aptAddr, g_mc.sector); + SIXSTEP_AptConfig(g_aptAddr, sector); /* Stall fault detection. */ + SetPwmDuty(g_aptAddr, g_mc.aptMaxCntCmp, g_mc.pwmDuty); MotorBlockageProtect(); } /* Fault detection. */ if (g_mc.stateMachine == FSM_STARTUP || g_mc.stateMachine == FSM_RUN) { - bool motorStatus = FaultDetect_Exec(&g_mc.faultDet, g_mc.idc, g_mc.powerBoardTemp, g_mc.udc, g_mc.spdFbk); - if (motorStatus) { - g_mc.stateMachine = FSM_FAULT; - } + FualtDetCarr(); } + g_mc.udc = (float)HAL_ADC_GetConvResult(&ADC_UDC_HANDLE, ADC_UDC_SOC_NUM) * ADC_VOLT_COFFI; + ReadCurrUvw(&g_mc.iuvw, sector); } @@ -937,7 +890,6 @@ int MotorMain(void) HAL_TIMER_Start(&g_timer0); HAL_TIMER_Start(&g_timer1); - AptMasterSalveSet(); /* Disable PWM output before startup. */ MotorPwmOutputDisable(g_aptAddr); diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/application/mcs_motor_process.h b/src/application/middleware_sample/mcs_hall_bldc_1shunt/application/mcs_motor_process.h index a1e90fbc3ed9ea72d19c90c1419161ab7eee5640..0688b55614c727c1d1a571222f92911183aa3838 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/application/mcs_motor_process.h +++ b/src/application/middleware_sample/mcs_hall_bldc_1shunt/application/mcs_motor_process.h @@ -40,12 +40,6 @@ typedef enum { KEY_UP = 1, } KEY_State; -typedef enum { - APT_CHA_PWM_CHB_LOW, - APT_CHA_LOW_CHB_HIGH, - APT_CHA_LOW_CHB_LOW -} APT_Act; - int MotorMain(void); #endif \ No newline at end of file diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/common/mcs_carrier.h b/src/application/middleware_sample/mcs_hall_bldc_1shunt/common/mcs_carrier.h index 01e7c0401af7529bc9376550904cca2b01b6e7fe..1a8a9ef5bab917b792a49b020d678ec975533331 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/common/mcs_carrier.h +++ b/src/application/middleware_sample/mcs_hall_bldc_1shunt/common/mcs_carrier.h @@ -33,7 +33,8 @@ #include "apt.h" #include "mcs_adcCalibr.h" #include "mcs_fsm.h" -#include "mcs_fault_detection.h" +#include "mcs_sensor_hall.h" +#include "fault_det.h" typedef struct { unsigned int iuAdcBias; /* iu adc temperature calibration */ @@ -42,12 +43,6 @@ typedef struct { unsigned int iBusAdcBias; /* ibus adc temperature calibration */ } IBIAS_Handle; /* Current Bias */ -typedef void (*MCS_GetHallAngSpd)(float *speed, float *angle); -typedef void (*MCS_AdcCalibrCurrUvwCb)(IBIAS_Handle *adcCalibrCurrUvw); -typedef void (*MCS_ReadBusCurrCb)(float *idc); -typedef void (*MCS_ReadBusVoltCb)(float *udc); - - /** * @brief Sampling mode. */ @@ -64,17 +59,14 @@ typedef struct { float spdRef; /**< Command value after speed ramp management */ float spdFbk; /**< Feedback speed */ float currCtrlPeriod; /**< current loop control period */ - unsigned short aptMaxcntCmp; /**< Apt Maximum Comparison Count */ - + unsigned short aptMaxCntCmp; /**< Apt Maximum Comparison Count */ + + UvwAxis iuvw; float idc; /**< Bus current. */ float udc; /**< Bus voltage. */ float powerBoardTemp; /**< Power boart surface temperature */ float pwmDuty; /**< pwm duty. */ - float hallSpeed; /* Filtered speed of the hall sensor. */ - float hallAxisAngle; /* Filtered angle of the hall sensor. */ - unsigned int sector; - int dir; unsigned short sysTickCnt; /**< System Timer Tick Count */ unsigned short capChargeTickNum; /**< Bootstrap Capacitor Charge Tick Count */ @@ -88,17 +80,16 @@ typedef struct { RMG_Handle spdRmg; /**< Ramp management struct for the speed controller input reference */ PID_Handle spdPi; /**< Speed PI controller. */ - MCS_GetHallAngSpd getHallAngSpd; /**< Get the angle and speed of the hall. */ - PLL_Handle hallAnglePll; /**< Hall angle phase-locked loop. */ - FOFLT_Handle hallSpdFilter; /**< Hall speed filter. */ - FAULT_DET_Handle faultDet; - + HALL_Handle *hall; ADC_CALIBR_Handle adcCalibr; /**< adc calibration */ IBIAS_Handle iuvwAdcBias; /**< Phase current ADC calibration handle. */ - MCS_AdcCalibrCurrUvwCb readCurrBiasCb; /**< Phase current ADC calibration function pointer. */ - - MCS_ReadBusCurrCb readBusCurrCb; - MCS_ReadBusVoltCb readBusVoltCb; + + FAULT_Status faultStatus; + FP_OCD_Handle ocd; + FP_UOVD_Handle uovd; + FP_OTD_Handle otd; + FP_STD_Handle std; + FP_OPD_Handle opd; } MTRCTRL_Handle; void MCS_CarrierProcess(MTRCTRL_Handle *mtrCtrl); diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/func/fault_det.c b/src/application/middleware_sample/mcs_hall_bldc_1shunt/func/fault_det.c new file mode 100644 index 0000000000000000000000000000000000000000..054c84d0f3e9f62bb8a2d481a8e86a0cb1fc6ce5 --- /dev/null +++ b/src/application/middleware_sample/mcs_hall_bldc_1shunt/func/fault_det.c @@ -0,0 +1,406 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file fault_det.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of fault detection. + * Include open phase, statll, over current, under voltage, interturn. + */ + + +#include "fault_det.h" +#include "mcs_math.h" + + +/** + * @brief Clear fault status. + * @param faultStatus Pointer of fault status handle. + * @retval None. + */ +void Fault_Clear(FAULT_Status *faultStatus) +{ + faultStatus->all = 0; +} + + +/** + * @brief Initialize overcurrent detection. + * @param ocd Pointer of OCD handle. + * @param overCurrThr Software overcurrent protection threshold (A). + * @param detWindow Overcurrent detection duration (s). + * @param ts Control period. + * @retval None. + */ +void FP_OCD_Init(FP_OCD_Handle *ocd, float overCurrThr, float detWindow, float ts) +{ + MCS_ASSERT_PARAM(ocd != NULL); + ocd->ts = ts; + /* Software overcurrent protection threshold. */ + ocd->overCurrThr = overCurrThr; + ocd->detWindow = detWindow; +} + +/** + * @brief Perform software overcurrent detection. + * @param ocd Pointer of OCD handle. + * @param faultStatus Pointer of FaultStatus struct. + * @param iuvw Three-phase current. + * @retval None. + */ +void FP_OCD_Exec(FP_OCD_Handle *ocd, FAULT_Status *faultStatus, UvwAxis iuvw) +{ + MCS_ASSERT_PARAM(ocd != NULL); + /* The absolute value of the three-phase current is used. */ + float iuAbs = Abs(iuvw.u); + float ivAbs = Abs(iuvw.v); + float iwAbs = Abs(iuvw.w); + float overCurrThr = ocd->overCurrThr; + /* Threshold judgement. */ + if (iuAbs > overCurrThr || ivAbs > overCurrThr || iwAbs > overCurrThr) { + ocd->timer += ocd->ts; + if (ocd->timer > ocd->detWindow) { + faultStatus->Bit.softOverCurFault = 1; + ocd->timer = 0.0f; + } + } else { + /* Continuous overcurrent is not met, and the timer is cleared. */ + ocd->timer = 0.0f; + } +} + +/** + * @brief Clear ocd history value. + * @param ocd Pointer of OCD handle. + * @retval None. + */ +void FP_OCD_Clear(FP_OCD_Handle *ocd) +{ + ocd->timer = 0.0f; +} + + +/** + * @brief Initialize under/over voltage detection. + * @param uovdHandle Pointer of HSF_UOVD_Handle. + * @param uovdInit Pointer of HSF_UOVD_Param. + * @param ts Control period. + * @retval None. + */ +void FP_UOVD_Init(FP_UOVD_Handle *uovdHandle, FP_UOVD_Param *uovdInit, float ts) +{ + uovdHandle->ts = ts; + /* Overvoltage protection Value */ + uovdHandle->overProThr = uovdInit->overProThr; + /* Overvoltage protection Recovery Value */ + uovdHandle->overRecThr = uovdInit->overRecThr; + /* Undervoltage protection value */ + uovdHandle->underProThr = uovdInit->underProThr; + /* Undervoltage protection Recovery Value */ + uovdHandle->underRecThr = uovdInit->underRecThr; + /* Protection Detect Filter Count */ + uovdHandle->proTicks = (unsigned int)(uovdInit->detWindow / ts); + /* Protection Recovery Detect Filter Count */ + uovdHandle->recTicks = (unsigned int)(uovdInit->recWindow / ts); +} + +/** + * @brief Perform under/over voltage detection. + * @param uovdHandle Pointer of under/over voltage detection struct handle. + * @param faultStatus Pointer of FaultStatus. + * @param busVolt DC bus voltage. + * @retval None. + */ +void FP_UOVD_Exec(FP_UOVD_Handle *uovdHandle, FAULT_Status *faultStatus, float busVolt) +{ + float overProThr = uovdHandle->overProThr; + float underProThr = uovdHandle->underProThr; + unsigned int proTicks = uovdHandle->proTicks; + + if (busVolt > overProThr) { + /* Overvoltage protection filter count */ + uovdHandle->overVolCnt++; + uovdHandle->underVolCnt = 0; + } else if (busVolt < underProThr) { + /* Undervoltage protection filter count */ + uovdHandle->underVolCnt++; + uovdHandle->overVolCnt = 0; + } else { + uovdHandle->overVolCnt = 0; + uovdHandle->underVolCnt = 0; + } + + if (uovdHandle->overVolCnt > proTicks) { + /* Overvoltage protection conditions are met */ + faultStatus->Bit.overVoltFault = 1; + uovdHandle->overVolCnt = 0; + } else if (uovdHandle->underVolCnt > proTicks) { + /* Undervoltage protection conditions are met */ + faultStatus->Bit.underVoltFault = 1; + uovdHandle->underVolCnt = 0; + } +} + +/** + * @brief Perform under/over voltage recovery. + * @param uovdHandle Pointer of under/over voltage detection struct handle. + * @param faultStatus Pointer of FaultStatus. + * @param busVolt DC bus voltage. + * @retval None. + */ +void FP_UOVR_Exec(FP_UOVD_Handle *uovdHandle, FAULT_Status *faultStatus, float busVolt) +{ + float overRecThr = uovdHandle->overRecThr; + float underRecThr = uovdHandle->underRecThr; + unsigned int recTicks = uovdHandle->recTicks; + + if (faultStatus->Bit.overVoltFault) { + if (busVolt < overRecThr) { + /* Overvoltage Protection Recovery Filter Count */ + uovdHandle->overVolCnt++; + } else { + uovdHandle->overVolCnt = 0; + } + + if (uovdHandle->overVolCnt > recTicks) { + faultStatus->Bit.overVoltFault = 0; + /* Overvoltage protection Recovery conditions are met */ + uovdHandle->recoveryFlag = 1; + } + } else if (faultStatus->Bit.underVoltFault) { + if (busVolt > underRecThr) { + /* Undervoltage Protection Recovery Filter Count */ + uovdHandle->underVolCnt++; + } else { + uovdHandle->underVolCnt = 0; + } + + if (uovdHandle->underVolCnt > recTicks) { + faultStatus->Bit.underVoltFault = 0; + /* Undervoltage protection Recovery conditions are met */ + uovdHandle->recoveryFlag = 1; + } + } +} + +/** + * @brief Clear historical values of under/over voltage detection. + * @param uovdHandle Under/over voltage detection struct handle. + * @retval None. + */ +void FP_UOVD_Clear(FP_UOVD_Handle *uovdHandle) +{ + /* Clear the count value and flag bit */ + uovdHandle->overVolCnt = 0; + uovdHandle->underVolCnt = 0; + uovdHandle->recoveryFlag = 0; +} + +/** + * @brief Initialize over temperature detection of board and motor. + * @param otd Pointer of over temperature detection struct handle. + * @param mtrTempThr Motor overtemperature threshold. + * @param brdTempThr Board overtemperature threshold. + * @param mtrDetWindow Detection duration (s). + * @param brdDetWindow Detection duration (s). + * @param ts: Control period. + * @retval None. + */ +void FP_OTD_Init(FP_OTD_Handle *otd, float mtrTempThr, float brdTempThr, + float mtrDetWindow, float brdDetWindow, float ts) +{ + otd->ts = ts; + otd->mtrTempThr = mtrTempThr; + otd->brdTempThr = brdTempThr; + /* Detet window. */ + otd->mtrDetWindow = mtrDetWindow; + otd->brdDetWindow = brdDetWindow; +} + +/** + * @brief Perform over temperature detection. + * @param otd Pointer of over temperature detection struct handle. + * @param faultStatus Pointer of FaultStatus. + * @param mtrTemp Motor temperature. + * @param brdTemp Board temperature. + * @retval None. + */ +void FP_OTD_Exec(FP_OTD_Handle *otd, FAULT_Status *faultStatus, float mtrTemp, float brdTemp) +{ + /* Protect motor when the motor over temperature exceed a certain time. */ + if (mtrTemp > otd->mtrTempThr) { + otd->mtrTimer += otd->ts; + if (otd->mtrTimer > otd->mtrDetWindow) { + faultStatus->Bit.mtrOverTempFault = 1; + otd->mtrTimer = 0.0f; + } + } else { + /* Clear timer. */ + otd->mtrTimer = 0.0f; + } + /* Protect board when the board temperature exceed a certain time. */ + if (brdTemp > otd->brdTempThr) { + otd->brdTimer += otd->ts; + if (otd->brdTimer > otd->brdDetWindow) { + faultStatus->Bit.brdOverTempFault = 1; + otd->brdTimer = 0.0f; + } + } else { + /* Clear timer. */ + otd->brdTimer = 0.0f; + } +} + +/** + * @brief Clear historical values of over temperature detection. + * @param otd Over temperature detection struct handle. + * @retval None. + */ +void FP_OTD_Clear(FP_OTD_Handle *otd) +{ + otd->mtrTimer = 0.0f; + otd->brdTimer = 0.0f; +} + +/** + * @brief Initialize motor stall detection. + * @param std Pointer of stall detection struct handle. + * @param spdLowerLim Minimum speed threshold. + * @param spdUpperLim Maximum speed threshold. + * @param detWindow Detection duration (s). + * @param ts: Control period. + * @retval None. + */ +void FP_STD_Init(FP_STD_Handle *std, float spdLowerLim, float spdUpperLim, float detWindow, float ts) +{ + std->ts = ts; + std->detWindow = detWindow; + std->spdLowerLim = spdLowerLim; + std->spdUpperLim = spdUpperLim; +} + +/** + * @brief Perform motor stall detection. + * @param std Pointer of over temperature detection struct handle. + * @param faultStatus Pointer of FaultStatus. + * @param hallSecTimer Rotor time in sectors. + * @param spdFbk Speed feedback. + * @retval None. + */ +void FP_STD_Exec(FP_STD_Handle *std, FAULT_Status *faultStatus, float hallSecTimer, float spdFbk) +{ + /* Time out detection. */ + if (hallSecTimer > std->detWindow) { + std->timeOutFlag = 1; + } + /* Lose speed detection. */ + if (spdFbk < std->spdLowerLim || spdFbk > std->spdUpperLim) { + std->timer += std->ts; + if (std->timer > std->detWindow) { + std->loseSpdFlag = 1; + std->timer = 0.0f; + } + } else { + std->timer = 0.0f; + } + /* Motor stall detection. */ + if (std->timeOutFlag || std->loseSpdFlag) { + faultStatus->Bit.stallFault = 1; + } +} + +/** + * @brief Clear historical values of stall detection. + * @param otd Motor stall detection struct handle. + * @retval None. + */ +void FP_STD_Clear(FP_STD_Handle *std) +{ + std->loseSpdFlag = 0; + std->timeOutFlag = 0; + std->timer = 0.0f; +} + +/** + * @brief Initialize open phase detection. + * @param opd Pointer of open phase detection struct handle. + * @param opdCurrThr Minimum open phase current (A). + * @param detWindow Detection duration (s). + * @param ts: Control period. + * @retval None. + */ +void FP_OPD_Init(FP_OPD_Handle *opd, float opdCurrThr, float detWindow, float ts) +{ + opd->opdCurrThr = opdCurrThr; + opd->detWindow = detWindow; + opd->ts = ts; +} + +/** + * @brief Perform motor open phase detection. + * @param opd Pointer of open phase detection struct handle. + * @param faultStatus Pointer of FaultStatus. + * @param iuvw Current of uvw phase. + * @retval None. + */ +void FP_OPD_Exec(FP_OPD_Handle *opd, FAULT_Status *faultStatus, UvwAxis iuvw) +{ + /* Calc integral threshold for open-phase current. */ + float integralThr = opd->opdCurrThr * opd->detWindow; + + if (opd->timer < opd->detWindow) { + /* Calculate the integral value of the absolute value of the three-phase current. */ + opd->iuAbsIntegral += (Abs(iuvw.u) * opd->ts); + opd->ivAbsIntegral += (Abs(iuvw.v) * opd->ts); + opd->iwAbsIntegral += (Abs(iuvw.w) * opd->ts); + } else { + /* Open phase detection of phase u. */ + if (opd->iuAbsIntegral < integralThr) { + faultStatus->Bit.openPhaseFault_U = 1; + faultStatus->Bit.openPhaseFault = 1; + } + /* Open phase detection of phase V. */ + if (opd->ivAbsIntegral < integralThr) { + faultStatus->Bit.openPhaseFault_V = 1; + faultStatus->Bit.openPhaseFault = 1; + } + /* Open phase detection of phase W. */ + if (opd->iwAbsIntegral < integralThr) { + faultStatus->Bit.openPhaseFault_W = 1; + faultStatus->Bit.openPhaseFault = 1; + } + opd->iuAbsIntegral = 0.0f; + opd->ivAbsIntegral = 0.0f; + opd->iwAbsIntegral = 0.0f; + opd->timer = 0.0f; + } + /* Time Accumulation. */ + opd->timer += opd->ts; +} + +/** + * @brief Clear historical values of open phase detection. + * @param opd Pointer of open phase detection struct handle. + * @retval None. + */ +void FP_OPD_Clear(FP_OPD_Handle *opd) +{ + opd->iuAbsIntegral = 0.0f; + opd->ivAbsIntegral = 0.0f; + opd->iwAbsIntegral = 0.0f; + opd->timer = 0.0f; +} + diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/func/fault_det.h b/src/application/middleware_sample/mcs_hall_bldc_1shunt/func/fault_det.h new file mode 100644 index 0000000000000000000000000000000000000000..57398691b91b28f07a46b68b7aa278861119865c --- /dev/null +++ b/src/application/middleware_sample/mcs_hall_bldc_1shunt/func/fault_det.h @@ -0,0 +1,164 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file fault_det.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of fault detection. + * Include open phase, statll, over current, under voltage, interturn. + */ + +#ifndef McuMagicTag_FAULT_DET_H +#define McuMagicTag_FAULT_DET_H + +#include "mcs_typedef.h" +#include "mcs_assert.h" + +/** + * @brief System fault status definations.硬件电流/软件电流/欠压/过压/过温/缺相/堵转 + */ +typedef union { + unsigned short all; + struct { + unsigned short hardOverCurFault : 1; // indicates over-current fault + unsigned short softOverCurFault : 1; // indicates over-current fault + unsigned short stallFault : 1; // indicates rotor stall fault + unsigned short overVoltFault : 1; // indicates over-voltage fault + unsigned short underVoltFault : 1; // indicates under-voltage fault + unsigned short mtrOverTempFault : 1; // indicates motor over-temperature fault + unsigned short brdOverTempFault : 1; // indicates board over-temperature fault + unsigned short openPhaseFault : 1; // indicates open-phase fault in two or three phases + unsigned short openPhaseFault_U : 1; // indicates phase U open-phase fault + unsigned short openPhaseFault_V : 1; // indicates phase V open-phase fault + unsigned short openPhaseFault_W : 1; // indicates phase W open-phase fault + } Bit; +} FAULT_Status; + +void Fault_Clear(FAULT_Status *faultStatus); + +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief OCD_Handle Struct. + */ +typedef struct { + float ts; + float overCurrThr; // Software overcurrent value (A) + + float detWindow; + float timer; +} FP_OCD_Handle; + +void FP_OCD_Init(FP_OCD_Handle *ocd, float overCurrThr, float detWindow, float ts); +void FP_OCD_Exec(FP_OCD_Handle *ocd, FAULT_Status *faultStatus, UvwAxis iuvw); +void FP_OCD_Clear(FP_OCD_Handle *ocd); + +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief UOVD_Handle Struct. + */ +typedef struct { + float ts; + float overProThr; // over-voltage protection value + float overRecThr; // over-voltage recovery value + float underProThr; // under-voltage protection value + float underRecThr; // under-voltage recovery value + + unsigned int proTicks; // ticks of under/over-voltage protection + unsigned int recTicks; // ticks of under/over-voltage recovery + + unsigned int overVolCnt; // over voltage protection/recovery counter + unsigned int underVolCnt; // under voltage protection/recovery counter + unsigned char recoveryFlag; // +} FP_UOVD_Handle; + +typedef struct { + float overProThr; // over-voltage protection value + float overRecThr; // over-voltage recovery value + float underProThr; // under-voltage protection value + float underRecThr; // under-voltage recovery value + float detWindow; // response time of under/over-voltage protection (s) + float recWindow; // response time of under/over-voltage recovery (s) +} FP_UOVD_Param; + +void FP_UOVD_Init(FP_UOVD_Handle *uovdHandle, FP_UOVD_Param *uovdInit, float ts); +void FP_UOVD_Exec(FP_UOVD_Handle *uovdHandle, FAULT_Status *faultStatus, float busVolt); +void FP_UOVR_Exec(FP_UOVD_Handle *uovdHandle, FAULT_Status *faultStatus, float busVolt); +void FP_UOVD_Clear(FP_UOVD_Handle *uovdHandle); + +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief UOVD_Handle Struct. + */ +typedef struct { + float ts; + + float mtrTempThr; + float brdTempThr; + + float mtrDetWindow; + float brdDetWindow; + + float mtrTimer; + float brdTimer; +} FP_OTD_Handle; + +void FP_OTD_Init(FP_OTD_Handle *otd, float mtrTempThr, float brdTempThr, + float mtrDetWindow, float brdDetWindow, float ts); +void FP_OTD_Exec(FP_OTD_Handle *otd, FAULT_Status *faultStatus, float mtrTemp, float brdTemp); +void FP_OTD_Clear(FP_OTD_Handle *otd); + +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief UOVD_Handle Struct. + * 两种情景 + * (1)原地不动,timer累加,可用timer判据; + * (2)原地震荡,timer变化,可用失速判据:速度在时速区间内,超过xx时间。 + */ +typedef struct { + float ts; + float detWindow; + float spdLowerLim; + float spdUpperLim; + + float timer; + char loseSpdFlag; + char timeOutFlag; +} FP_STD_Handle; + +void FP_STD_Init(FP_STD_Handle *std, float spdLowerLim, float spdUpperLim, float detWindow, float ts); +void FP_STD_Exec(FP_STD_Handle *std, FAULT_Status *faultStatus, float timer, float spdFbk); +void FP_STD_Clear(FP_STD_Handle *std); + +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief UOVD_Handle Struct. + */ +typedef struct { + float ts; + float opdCurrThr; // 缺相电流,理论为0 + float detWindow; + + float iuAbsIntegral; + float ivAbsIntegral; + float iwAbsIntegral; + float timer; +} FP_OPD_Handle; + +void FP_OPD_Init(FP_OPD_Handle *opd, float opdCurrThr, float detWindow, float ts); +void FP_OPD_Exec(FP_OPD_Handle *opd, FAULT_Status *faultStatus, UvwAxis iuvw); +void FP_OPD_Clear(FP_OPD_Handle *opd); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/hall/mcs_sensor_hall.c b/src/application/middleware_sample/mcs_hall_bldc_1shunt/hall/mcs_sensor_hall.c index 6849513128ab6546edaadd0b33f8e575f40df7d0..0a7e96aea62a39b32f51e83032d279d7cafe0e5c 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/hall/mcs_sensor_hall.c +++ b/src/application/middleware_sample/mcs_hall_bldc_1shunt/hall/mcs_sensor_hall.c @@ -1,5 +1,5 @@ /** - * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -22,218 +22,382 @@ #include "mcs_sensor_hall.h" #include "mcs_assert.h" -#include "mcs_math.h" #include "mcs_math_const.h" +#include "mcs_math.h" + +#define HALL_INSTALL_CALIBRATION_ENABLE (1) -/* Hall sector. */ -#define SECTOR_ONE 1U -#define SECTOR_TWO 2U -#define SECTOR_THREE 3U -#define SECTOR_FOUR 4U -#define SECTOR_FIVE 5U -#define SECTOR_SIX 6U +#define EANGLE0 (0.0f) +#define EANGLE30 (0.5235988f) +#define EANGLE60 (1.0471976f) +#define EANGLE90 (1.5707963f) +#define EANGLE120 (2.0943951f) +#define EANGLE150 (2.6179939f) +#define EANGLE180 (3.1415927f) +#define EANGLE210 (-2.6179939f) +#define EANGLE240 (-2.0943951f) +#define EANGLE270 (-1.5707963f) +#define EANGLE300 (-1.0471976f) +#define EANGLE330 (-0.5235988f) /** - * @brief Hall sensor initialization interface. - * @param handle Hall sensor handle. - * @param phaseShift Hall sensor synchronous electrical angle. - * @param ts Execution period. - * @retval None. - */ -void HALL_Init(HALL_Handle *handle, float phaseShift, float ts) + * @brief + */ +typedef enum { + APT_CHA_PWM_CHB_LOW, + APT_CHA_LOW_CHB_HIGH, + APT_CHA_LOW_CHB_LOW +} SIXSTEP_AptAct; + +/** + * @brief Configure three kinds of APT action, H_PWM_L_ON mode. + * @param aptAddr APT base address. + * @param aptAct The APT action. + */ +static void SIXSTEP_ForcePwmOut(APT_RegStruct* aptAddr, SIXSTEP_AptAct aptAct) { - /* Verifying Parameters. */ - MCS_ASSERT_PARAM(handle != NULL); - handle->ts = ts; - /* Init timer. */ - handle->timer = 0.0f; - /* Initializing hall sector. */ - handle->sec = HALL_SectorCalc(handle->getHallValue()); - handle->secLast = HALL_SectorCalc(handle->getHallValue()); - handle->durationLast1 = 0.0f; - handle->durationLast2 = 0.0f; - handle->durationLast3 = 0.0f; - handle->durationAvg = 0.0f; - /* Initialization direction. */ - handle->dir = HALL_DIR_CW; - /* Initialize the basic angle based on the sector. */ - if (handle->sec) { - handle->angleStartPoint = (float)(handle->sec - 1) * ONE_PI_DIV_THREE; // S16_60_PHASE_SHIFT - } else { - handle->angleStartPoint = 0; + switch (aptAct) { + case APT_CHA_PWM_CHB_LOW: + /* Channel A: 0 means not force output enable, channel A output PWM. */ + DCL_APT_DisableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A); + /* Channel B: 1 means force output enable. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B); + /* Channel B: 2 means channel B force output LOW due to the A_H_B_L invert. */ + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + + case APT_CHA_LOW_CHB_HIGH: + /* Channel A: 1 means force output enable. */ + /* Channel A: 1 means channel A force output LOW. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A); + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + /* Channel B: 1 means force output enable. */ + /* Channel B: 1 means channel A force output HIGH due to the A_H_B_L invert. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B); + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_LOW); + break; + + case APT_CHA_LOW_CHB_LOW: + /* Channel A: 1 means force output enable. */ + /* Channel A: 1 means channel A force output LOW. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A); + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); + /* Channel B: 1 means force output enable. */ + /* Channel B: 2 means channel A force output LOW due to the A_H_B_L invert. */ + DCL_APT_EnableSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B); + DCL_APT_SetSwContPWMAction(aptAddr, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); + break; + default: + break; } - handle->angleComp = 0.0f; - handle->phaseShift = phaseShift; - handle->angle = handle->angleStartPoint; - handle->spd = 0.0f; - handle->firstEdgeFilterFlag = 0; } /** - * @brief Obtain sector based on the 120 degree Installation. - * @param hallValue Hall sensor value. - * @retval None. - */ -static unsigned int HALL_InstallDegree120(unsigned int hallValue) + * @brief Configure the APT action mode for six sectors. + * @param aptUvw APT base address of U V W. + * @param sector Sector. + */ +void SIXSTEP_AptConfig(APT_RegStruct **aptUvw, HALL_SECTOR sector) { - if (hallValue == 5) { /* Hall value 5 : HALL_A = 1, HALL_B = 0, HALL_C = 1 */ - return SECTOR_ONE; - } else if (hallValue == 4) { /* Hall value 4 : HALL_A = 1, HALL_B = 0, HALL_C = 0 */ - return SECTOR_TWO; - } else if (hallValue == 6) { /* Hall value 6 : HALL_A = 1, HALL_B = 1, HALL_C = 0 */ - return SECTOR_THREE; - } else if (hallValue == 2) { /* Hall value 2 : HALL_A = 0, HALL_B = 1, HALL_C = 0 */ - return SECTOR_FOUR; - } else if (hallValue == 3) { /* Hall value 3 : HALL_A = 0, HALL_B = 1, HALL_C = 1 */ - return SECTOR_FIVE; - } else if (hallValue == 1) { /* Hall value 1 : HALL_A = 0, HALL_B = 0, HALL_C = 1 */ - return SECTOR_SIX; - } else { - return 0; + APT_RegStruct *aptU = aptUvw[0]; + APT_RegStruct *aptV = aptUvw[1]; + APT_RegStruct *aptW = aptUvw[2]; /* index 2. */ + switch (sector) { + case SECTOR1: /* A+, C- */ + SIXSTEP_ForcePwmOut(aptU, APT_CHA_PWM_CHB_LOW); + SIXSTEP_ForcePwmOut(aptV, APT_CHA_LOW_CHB_LOW); + SIXSTEP_ForcePwmOut(aptW, APT_CHA_LOW_CHB_HIGH); + break; + case SECTOR2: /* B+, C- */ + SIXSTEP_ForcePwmOut(aptU, APT_CHA_LOW_CHB_LOW); + SIXSTEP_ForcePwmOut(aptV, APT_CHA_PWM_CHB_LOW); + SIXSTEP_ForcePwmOut(aptW, APT_CHA_LOW_CHB_HIGH); + break; + case SECTOR3: /* B+, A- */ + SIXSTEP_ForcePwmOut(aptU, APT_CHA_LOW_CHB_HIGH); + SIXSTEP_ForcePwmOut(aptV, APT_CHA_PWM_CHB_LOW); + SIXSTEP_ForcePwmOut(aptW, APT_CHA_LOW_CHB_LOW); + break; + case SECTOR4: /* C+, A- */ + SIXSTEP_ForcePwmOut(aptU, APT_CHA_LOW_CHB_HIGH); + SIXSTEP_ForcePwmOut(aptV, APT_CHA_LOW_CHB_LOW); + SIXSTEP_ForcePwmOut(aptW, APT_CHA_PWM_CHB_LOW); + break; + case SECTOR5: /* C+, B- */ + SIXSTEP_ForcePwmOut(aptU, APT_CHA_LOW_CHB_LOW); + SIXSTEP_ForcePwmOut(aptV, APT_CHA_LOW_CHB_HIGH); + SIXSTEP_ForcePwmOut(aptW, APT_CHA_PWM_CHB_LOW); + break; + case SECTOR6: /* A+, B- */ + SIXSTEP_ForcePwmOut(aptU, APT_CHA_PWM_CHB_LOW); + SIXSTEP_ForcePwmOut(aptV, APT_CHA_LOW_CHB_HIGH); + SIXSTEP_ForcePwmOut(aptW, APT_CHA_LOW_CHB_LOW); + break; + default: + break; } } /** - * @brief Obtain the corresponding sector based on the value of the hall sensor. - * @param hallValue Hall sensor value. - * @retval None. - */ -unsigned int HALL_SectorCalc(unsigned int hallValue) + * @brief Set six step angel at start up stage. + * @param sector 0-60: sec1, 60-120: sec2. + * @retval None. + */ +static float CalcSixStepRadian(unsigned int sector) { - /* Different installation, choose different function. */ - return HALL_InstallDegree120(hallValue); + /* Angle assignment in different sector */ + float sixStepAngle = 0.0f; + switch (sector) { + /* Sector one the angle is 30 */ + case SECTOR1: + sixStepAngle = EANGLE30; + break; + /* Sector two the angle is 90 degree */ + case SECTOR2: + sixStepAngle = EANGLE90; + break; + /* Sector three the angle is 150 degree */ + case SECTOR3: + sixStepAngle = EANGLE150; + break; + /* Sector four the angle is 210 degree */ + case SECTOR4: + sixStepAngle = EANGLE210; + break; + /* Sector five the angle is 270 degree */ + case SECTOR5: + sixStepAngle = EANGLE270; + break; + /* Sector six the angle is 330 degree */ + case SECTOR6: + sixStepAngle = EANGLE330; + break; + + default: + break; + } + return sixStepAngle; } + /** - * @brief Updated the Hall sensor jump duration. - * @param hall Hall sensor handle. + * @brief Hall sensor initialization interface. + * @param handle Hall sensor handle. + * @param Hall sensor synchronous electrical angle. + * @param ts Execution period. * @retval None. */ -static void HALL_DurationUpdate(HALL_Handle *hall) +void HALL_Init(HALL_Handle *hall, int dir, float pllBdw, float spdCutOffFre, float ts) { /* Verifying Parameters. */ MCS_ASSERT_PARAM(hall != NULL); - hall->durationLast3 = hall->durationLast2; - hall->durationLast2 = hall->durationLast1; - hall->durationLast1 = hall->timer; + hall->ts = ts; hall->timer = 0.0f; + hall->t1 = 0.0f; + hall->t2 = 0.0f; + hall->t3 = 0.0f; + hall->tAvg = 0.0f; + /* Initialization direction. */ + hall->dir = dir; + /* Initialize the basic angle based on the sector. */ + hall->angStart = 0.0f; + + hall->angleComp = 0.0f; + hall->elecAngle = 0.0f; + hall->spdEst = 0.0f; + hall->firstEdgeFilterFlag = 0; + + PLL_Init(&hall->pll, ts, pllBdw); + FOLPF_Init(&hall->spdLpf, ts, spdCutOffFre); } /** - * @brief Hall rotation direction. - * @param handle Hall sensor handle. - * @retval None. - */ -static void HALL_RotationDir(HALL_Handle *handle) + * @brief Calculate the start angle of FOC six-step control in clockwise direction. + * @param sector Motor sector. + * @retval None. + */ +static float HALL_StartAngleCw(HALL_SECTOR sector) +{ + float angStart = 0.0f; + switch (sector) { + case SECTOR1: + angStart = EANGLE0; /* 0 */ + break; + case SECTOR2: + angStart = EANGLE60; /* 60 */ + break; + case SECTOR3: + angStart = EANGLE120; /* 120 */ + break; + case SECTOR4: + angStart = EANGLE180; /* 180 */ + break; + case SECTOR5: + angStart = EANGLE240; /* 240 */ + break; + case SECTOR6: + angStart = EANGLE300; /* 300 */ + break; + default: + break; + } + return angStart; +} + +/** + * @brief Calculate the start angle of FOC six-step control in counter clockwise direction. + * @param sector Motor sector. + * @retval None. + */ +static float HALL_StartAngleCcw(HALL_SECTOR sector) { - /* Specail handle. */ - if (handle->sec == SECTOR_ONE && handle->secLast == SECTOR_SIX) { - handle->dir = HALL_DIR_CW; - handle->angleStartPoint = handle->phaseShift; + float angStart = 0.0f; + switch (sector) { + case SECTOR6: + angStart = EANGLE0; /* 0 */ + break; + case SECTOR5: + angStart = EANGLE300; /* 300 */ + break; + case SECTOR4: + angStart = EANGLE240; /* 240 */ + break; + case SECTOR3: + angStart = EANGLE180; /* 180 */ + break; + case SECTOR2: + angStart = EANGLE120; /* 120 */ + break; + case SECTOR1: + angStart = EANGLE60; /* 60 */ + break; + default: + break; } - /* CW direction handle. */ - if (handle->sec - handle->secLast == 1) { - handle->dir = HALL_DIR_CW; - handle->angleStartPoint = handle->phaseShift + (float)handle->secLast * ONE_PI_DIV_THREE; + return angStart; +} + +/** + * @brief Calculate the start angle of FOC six-step control + * @param sector 0-60: sec1, 60-120: sec2. + * @param dir Rotate direction. + * @retval None. + */ +static float HALL_StartAngleUpdate(HALL_SECTOR sector, int dir) +{ + if (dir == HALL_DIR_CW) { + /* Clockwise */ + return HALL_StartAngleCw(sector); + } else if (dir == HALL_DIR_CCW) { + /* Counter clockwise */ + return HALL_StartAngleCcw(sector); + } else { + return 0.0f; } } /** * @brief Updating Hall Sensor Information - * @param handle Hall sensor handle. + * @param hall Hall sensor handle. * @retval None. */ -void HALL_InformationUpdate(HALL_Handle *handle) +void HALL_CapmEvtCallBack(HALL_Handle *hall, HALL_SECTOR sector) { /* Verifying Parameters. */ - MCS_ASSERT_PARAM(handle != NULL); - - handle->sec = HALL_SectorCalc(handle->getHallValue()); + MCS_ASSERT_PARAM(hall != NULL); + hall->sector = sector; + hall->sixStepAngle = CalcSixStepRadian(sector); /* The first handle edge change is incorrect and needs to be filtered out. */ - if (handle->firstEdgeFilterFlag == 0) { - handle->firstEdgeFilterFlag = 1; - if (handle->sec) { - handle->angleStartPoint = (float)(handle->sec - 1) * ONE_PI_DIV_THREE; // S16_60_PHASE_SHIFT; - } else { - handle->angleStartPoint = 0; - } - handle->angle = handle->angleStartPoint; - handle->secLast = handle->sec; + if (hall->firstEdgeFilterFlag == 0) { + hall->firstEdgeFilterFlag = 1; + /* Sector start angle is (current_sector) * 60 degree. */ + hall->angStart = HALL_StartAngleUpdate(hall->sector, hall->dir); + hall->sectorLast = hall->sector; return; } - - /* Hall rotation: CW. */ - HALL_RotationDir(handle); - + hall->angStart = HALL_StartAngleUpdate(hall->sector, hall->dir); /* Updated the Hall sensor jump duration. */ - if (handle->sec != handle->secLast) { - HALL_DurationUpdate(handle); - handle->secLast = handle->sec; + if (hall->sector != hall->sectorLast) { + hall->t3 = hall->t2; + hall->t2 = hall->t1; + hall->t1 = hall->timer; + hall->timer = 0.0f; + hall->sectorLast = hall->sector; } } /** * @brief Calculate the electrical angle and electrical speed. - * @param handle Hall sensor handle. + * @param hall Hall sensor handle. * @retval None. */ -void HALL_AngSpdCalcExec(HALL_Handle *handle) +void HALL_Exec(HALL_Handle *hall, HALL_SECTOR sector) { - /* Verifying Parameters. */ - MCS_ASSERT_PARAM(handle != NULL); - - handle->durationAvg = ONE_DIV_THREE * (handle->durationLast1 + handle->durationLast2 + handle->durationLast3); - - if (Abs(handle->durationAvg) <= 1e-5f) { - handle->spd = 0.0f; - handle->angleComp = 0.0f; + float spdEst; + float runAngle; + float elecAngle; + hall->sector = sector; + hall->sixStepAngle = CalcSixStepRadian(sector); + /* Average time of three sectors. */ + hall->tAvg = ONE_DIV_THREE * (hall->t1 + hall->t2 + hall->t3); + /* Handle motor stationary state. */ + if (hall->tAvg <= 0.00001f) { + spdEst = 0.0f; + elecAngle = 0.0f; + hall->angleComp = 0.0f; } else { - /* Hall installing calibration. */ - #if (HALL_INSTALL_CALIBRATION_ENABLE == 0) - handle->angleComp = 0.0f; - #elif (HALL_INSTALL_CALIBRATION_ENABLE == 1) - handle->angleComp = (ONE_PI_DIV_THREE * ONE_DIV_THREE * \ - (handle->durationLast1 - handle->durationLast3) / handle->durationAvg); - #endif - /* Speed estimation (Hz). */ - handle->spd = (float)handle->dir / handle->durationAvg / 6.0f; - /* Angle estimation (float). */ - handle->angle = handle->angleStartPoint + (float)handle->dir * \ - (handle->timer / handle->durationAvg * ONE_PI_DIV_THREE + handle->angleComp); + if (hall->spdCalcCnt < SPEED_CALC_SECTOR_NUMS) { + runAngle = hall->timer / hall->tAvg * ONE_PI_DIV_THREE; + elecAngle = hall->angStart + hall->dir * runAngle; + spdEst = 1.0f / hall->t1 / SECTOR_MAX_NUM; + hall->spdCalcCnt++; + } else { + /* Hall installing calibration. */ + hall->angleComp = (ONE_PI_DIV_THREE * ONE_DIV_THREE * (hall->t1 - hall->t3) / hall->tAvg); + /* Angle estimation. */ + runAngle = hall->timer / hall->tAvg * ONE_PI_DIV_THREE; + elecAngle = hall->angStart + hall->dir * runAngle + hall->dir * hall->angleComp; + /* Speed estimation (Hz). */ + spdEst = 1.0f / hall->tAvg / SECTOR_MAX_NUM; + } } - + PLL_Exec(&hall->pll, GetSin(elecAngle), GetCos(elecAngle)); + hall->elecAngle = hall->pll.angle; + hall->spdEst = FOLPF_Exec(&hall->spdLpf, spdEst); + /* Update history values. */ - handle->timer += handle->ts; + hall->timer += hall->ts; + + HALL_CapmEvtCallBack(hall, sector); } /** * @brief Clearing historical data of hall sensors. - * @param handle Hall sensor handle. + * @param hall Hall sensor handle. * @retval None. */ -void HALL_Clear(HALL_Handle *handle) +void HALL_Clear(HALL_Handle *hall) { - /* Clear duration. */ - handle->durationLast1 = 0.0f; - handle->durationLast2 = 0.0f; - handle->durationLast3 = 0.0f; - handle->durationAvg = 0.0f; - /* Clear hall sector and last sector. */ - handle->sec = HALL_SectorCalc(handle->getHallValue()); - handle->secLast = HALL_SectorCalc(handle->getHallValue()); - /* Default direction is CW. */ - handle->dir = HALL_DIR_CW; - /* Handle angle start point. */ - if (handle->sec) { - handle->angleStartPoint = (float)(handle->sec - 1) * ONE_PI_DIV_THREE; - } else { - handle->angleStartPoint = 0; - } - handle->angle = handle->angleStartPoint; - handle->spd = 0.0f; - handle->firstEdgeFilterFlag = 0; - handle->timer = 0.0f; /* Hall timer. */ + MCS_ASSERT_PARAM(hall != NULL); + /* Clear hall parameters. */ + hall->timer = 0.0f; + /* Get motor current value. */ + hall->t1 = 0.0f; + hall->t2 = 0.0f; + hall->t3 = 0.0f; + hall->tAvg = 0.0f; + + /* Init current angle. */ + hall->angStart = 0.0f; + hall->elecAngle = 0.0f; + hall->sixStepAngle = 0.0f; + hall->spdEst = 0.0f; + hall->firstEdgeFilterFlag = 0; + hall->spdCalcCnt = 0; + + PLL_Clear(&hall->pll); + FOLPF_Clear(&hall->spdLpf); } \ No newline at end of file diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/hall/mcs_sensor_hall.h b/src/application/middleware_sample/mcs_hall_bldc_1shunt/hall/mcs_sensor_hall.h index 45943688a9c689604fc4d5f3a8032bda2f1fdb62..2ad89f22fcd7b11dcc91d0a6c0de14b0e007af0d 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/hall/mcs_sensor_hall.h +++ b/src/application/middleware_sample/mcs_hall_bldc_1shunt/hall/mcs_sensor_hall.h @@ -1,5 +1,5 @@ /** - * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -16,24 +16,22 @@ * 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. * @file mcs_sensor_hall.h - * @author MCU Algorithm Team - * @brief This file provides functions declaration of hall sensor data process related structures and functions. + * @author + * @brief */ - /* Define to prevent recursive inclusion ------------------------------------- */ -#ifndef McuMagicTag_MCS_HALL_Q15_H -#define McuMagicTag_MCS_HALL_Q15_H +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_SENSOR_HALL_H +#define McuMagicTag_MCS_SENSOR_HALL_H +/* Includes ------------------------------------------------------------------------------------ */ +#include "capm.h" +#include "apt.h" +#include "mcs_pll.h" +#include "mcs_filter.h" -#define HALL_INSTALL_60_DEGREE (1) -#define HALL_INSTALL_120_DEGREE (2) -#define HALL_INSTALL_MODE (HALL_INSTALL_120_DEGREE) +/* Typedef definitions ------------------------------------------------------------------------- */ -#define HALL_INSTALL_CALIBRATION_ENABLE (1) - -#define S16_120_PHASE_SHIFT (short)(65536.0f/3.0f) -#define S16_60_PHASE_SHIFT (short)(65536.0f/6.0f) - -typedef unsigned int (*MCS_GetHallValue)(void); +#define SPEED_CALC_SECTOR_NUMS 3u /** * @brief Rotation direction state define. @@ -46,34 +44,54 @@ typedef enum { HALL_DIR_CCW = -1 } HALL_DIR_STATE; +typedef enum { + SECTOR1 = 0, + SECTOR2, + SECTOR3, + SECTOR4, + SECTOR5, + SECTOR6, + SECTOR_MAX_NUM +} HALL_SECTOR; + /** * @brief Hall sensor control data structure */ typedef struct { - float ts; /**< Control period (s). */ - float timer; /**< Timer count value. */ - unsigned int sec; /**< Current sector. */ - unsigned int secLast; /**< Last sector. */ - float durationLast1; /**< Last sector jump interval. */ - float durationLast2; /**< The sector jump interval before durationLast1. */ - float durationLast3; /**< The sector jump interval before durationLast2. */ - float durationAvg; /**< Average transition interval. */ - HALL_DIR_STATE dir; /**< Rotation direction. */ + float ts; /**< Control period (s). */ + float timer; /**< Timer count value. */ + unsigned int sector; /**< Current sector. */ + unsigned int sectorLast; /**< Last sector. */ + unsigned int spdCalcCnt; + float t1; /**< Last sector jump interval. */ + float t2; /**< The sector jump interval before t1. */ + float t3; /**< The sector jump interval before t2. */ + float tAvg; /**< Average transition interval. */ + int dir; /**< Rotation direction. */ + + float angleComp; /**< Angle correction parameters. */ + float angStart; /**< The start electrical angle of the current sector.. */ - float angleComp; - float angleStartPoint; - float phaseShift; - float angle; - float spd; /**< Electrical speed. */ - short firstEdgeFilterFlag; /**< First jump filter flag. */ + float spdEst; /**< Electrical angle. */ + float elecAngle; /**< Electrical speed. */ + float sixStepAngle; - MCS_GetHallValue getHallValue; /**< Pointer to the function for obtaining the value of the hall sensor. */ + short firstEdgeFilterFlag; /**< First jump filter flag. */ + + PLL_Handle pll; + FOFLT_Handle spdLpf; } HALL_Handle; -void HALL_Init(HALL_Handle *hall, float phaseShift, float ts); -unsigned int HALL_SectorCalc(unsigned int hallValue); -void HALL_InformationUpdate(HALL_Handle *hall); -void HALL_AngSpdCalcExec(HALL_Handle *hall); +/*** Hall six step control ***/ +void SIXSTEP_AptConfig(APT_RegStruct **aptUvw, HALL_SECTOR sector); + +/*** Hall foc control ***/ +void HALL_Init(HALL_Handle *hall, int dir, float pllBdw, float spdCutOffFre, float ts); + +void HALL_Exec(HALL_Handle *hall, HALL_SECTOR sector); + +void HALL_CapmEvtCallBack(HALL_Handle *hall, HALL_SECTOR sector); + void HALL_Clear(HALL_Handle *hall); -#endif \ No newline at end of file +#endif diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/readme.md b/src/application/middleware_sample/mcs_hall_bldc_1shunt/readme.md index 1064400381d4dd311a102d0dfe22920812fc0567..402cdaea8833f3a79163f2d63cdf16d29192821f 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/readme.md +++ b/src/application/middleware_sample/mcs_hall_bldc_1shunt/readme.md @@ -1,10 +1,11 @@ -# Hall Bldc Six Step Wave +# Bldc Hall Six Step Wave **【功能描述】** -+ 基于3061M-48PIN/3065H-64PIN低压生态板,Hall有感BLDC电机六步方波控制应用。 ++ 基于3066M-64PIN/3061M-48PIN/3065H-64PIN低压生态板,Hall有感BLDC电机六步方波控制应用。 **【环境要求】** + 所用单板电源改制为演示用的24V低压,电机选用杰美康42JSF630AS-1000。 ++ 安装:电机Hall信号端子+-UVW对应单板+-H1H2H3。 **【IDE配置方法】** -+ chipConfig中的sample栏目里面选中Hall Bldc Six Step Wave示例,然后点击生成代码即可。 \ No newline at end of file ++ chipConfig中的sample栏目里面选中 Bldc Hall Six Step Wave 示例,然后点击生成代码即可。 \ No newline at end of file diff --git a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/application/mcs_motor_process.c b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/application/mcs_motor_process.c index fbfdd907482ec2960b121e116b554b052ee627d7..d53b28d7fc8d6aee8652ea6b32789754630ed946 100644 --- a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/application/mcs_motor_process.c +++ b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/application/mcs_motor_process.c @@ -54,43 +54,6 @@ static void TimerTickInit(MtrCtrlHandle *mtrCtrl) mtrCtrl->capChargeTickNum = (INV_CAP_CHARGE_MS * US_PER_MS / SYSTICK_PERIOD_US); } -/** - * @brief APT Synchronize initialize. - * @retval None. - */ -static void APT_SyncMasterInit(APT_Handle *aptHandle) -{ - HAL_APT_MasterSyncInit(aptHandle, APT_SYNC_OUT_ON_CNTR_ZERO); -} - -/** - * @brief Config the slave APT. - * @param aptx The slave APT handle. - * @retval None. - */ -static void APT_SyncSlaveInit(APT_Handle *aptHandle) -{ - APT_SlaveSyncIn aptSlave; - aptSlave.divPhase = 0; /* divide phase value */ - aptSlave.cntPhase = 0; /* counter phase value */ - aptSlave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; - aptSlave.syncInSrc = APT_SYNC_IN_SRC; /* sync source selection */ - aptSlave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; - HAL_APT_SlaveSyncInit(aptHandle, &aptSlave); -} - -/** - * @brief Configuring Master and Slave APTs. - * @retval None. - */ -static void AptMasterSalveSet(void) -{ - /* Compressor fan APT master/slave synchronization */ - APT_SyncMasterInit(&g_apt0); - APT_SyncSlaveInit(&g_apt1); - APT_SyncSlaveInit(&g_apt2); -} - /** * @brief Read the ADC current sampling value of the compressor. * @param CurrUvw Three-phase current. @@ -99,9 +62,9 @@ static void AptMasterSalveSet(void) static void ReadBemfUVWMotor(UVWBemf *bemfUVW) { MCS_ASSERT_PARAM(bemfUVW != NULL); - bemfUVW->u = (int)(HAL_ADC_GetConvResult(&g_adc0, ADC_SOC_NUM2)&0xFFF); - bemfUVW->v = (int)(HAL_ADC_GetConvResult(&g_adc0, ADC_SOC_NUM5)&0xFFF); - bemfUVW->w = (int)(HAL_ADC_GetConvResult(&g_adc0, ADC_SOC_NUM6)&0xFFF); + bemfUVW->u = (int)(HAL_ADC_GetConvResult(&ADC_HANDLE, ADC_U_SOC_NUM)&0xFFF); + bemfUVW->v = (int)(HAL_ADC_GetConvResult(&ADC_HANDLE, ADC_V_SOC_NUM)&0xFFF); + bemfUVW->w = (int)(HAL_ADC_GetConvResult(&ADC_HANDLE, ADC_W_SOC_NUM)&0xFFF); } /** @@ -223,7 +186,7 @@ static void MotorStatePerProc(SysStatusReg *statusReg, volatile FsmState *stateM } if (SysGetCmdStop(statusReg)) { SysCmdStopClr(statusReg); - *stateMachine = FSM_STOP; + *stateMachine = FSM_WAIT_STOP; } } @@ -351,6 +314,26 @@ static void CheckOverCurrentState(SysStatusReg *statusReg, FsmState *stateMachin } } +/** + * @brief Deceleration control phase before stop. + * @param mtrCtrl The motor control handle. + * @param statusReg Motor Control Status. + * @param targetSpd Deceleration target value. + * @param switchSpd Switch to stop state speed. + * @retval None. + */ +static void DecelerateSpeed(MtrCtrlHandle *mtrCtrl, FsmState *stateMachine, float targetSpd, float switchSpd) +{ + /* Reduce speed before stop. */ + mtrCtrl->spdRefHz = RMG_Exec(&mtrCtrl->spdRmg, targetSpd); + mtrCtrl->spdPi.error = mtrCtrl->spdRefHz - mtrCtrl->spdEstHz; + /* Speed loop control */ + mtrCtrl->pwmDuty = PI_Exec(&mtrCtrl->spdPi); + if (mtrCtrl->spdRefHz <= switchSpd) { /* Maximum speed for switching to the FSM_STOP state */ + *stateMachine = FSM_STOP; + } +} + /** * @brief System timer tick task. * @param mtrCtrl The motor control handle. @@ -392,6 +375,10 @@ static void TSK_SystickIsr(MtrCtrlHandle *mtrCtrl, APT_RegStruct **aptAddr) /* Speed loop control */ mtrCtrl->pwmDuty = PI_Exec(&mtrCtrl->spdPi); break; + case FSM_WAIT_STOP: + /* 5.0f : maximum speed for switching to the FSM_STOP state */ + DecelerateSpeed(mtrCtrl, (FsmState *)stateMachine, 0.0f, 5.0f); + break; case FSM_STOP: MotorPwmOutputDisable(aptAddr); SysRunningClr(statusReg); @@ -453,7 +440,7 @@ void MotorCarrierProcessCallback(void *aptHandle) BASE_FUNC_UNUSED(aptHandle); /* USER CODE BEGIN APT0_TIMER_INTERRUPT */ MCS_CarrierProcess(&g_mc); - if (g_mc.stateMachine == FSM_RUN) { + if (g_mc.stateMachine == FSM_RUN || g_mc.stateMachine == FSM_WAIT_STOP) { MotorBlockageProtect(); } /* USER CODE END APT0_TIMER_INTERRUPT */ @@ -481,8 +468,8 @@ static void AdjustSpeedFunction(void) static unsigned int potentiomitorAdcValue = 0; static float spdCmdHz = 0; static float spdCmdHzLast = SDP_MAX_VALUE; - HAL_ADC_SoftTrigSample(&g_adc0, ADC_SOC_NUM9); /* Get the speed adjustment resistance. */ - potentiomitorAdcValue = HAL_ADC_GetConvResult(&g_adc0, ADC_SOC_NUM9); + HAL_ADC_SoftTrigSample(&ADC_HANDLE, ADC_SOC_NUM9); /* Get the speed adjustment resistance. */ + potentiomitorAdcValue = HAL_ADC_GetConvResult(&ADC_HANDLE, ADC_SOC_NUM9); /* 4045.0 is adc sample max value of potentiomitor */ spdCmdHz = (float)potentiomitorAdcValue / 4045.0 * SDP_MAX_VALUE; if (spdCmdHz < SDP_MIN_VALUE) { /* Speed protection. */ @@ -544,13 +531,12 @@ int MotorMainProcess(void) { SystemInit(); /* System Initialization. */ - unsigned int tickNum100Ms = 150; /* 100ms tick */ + unsigned int tickNum100Ms = 200; /* 100ms tick */ static unsigned int tickCnt100Ms = 0; - unsigned int tickNum500Ms = 750; /* 500ms tick */ + unsigned int tickNum500Ms = 1000; /* 500ms tick */ static unsigned int tickCnt500Ms = 0; HAL_TIMER_Start(&g_timer1); - AptMasterSalveSet(); /* Disable PWM output before startup. */ MotorPwmOutputDisable(g_aptCp); InitSoftware(); @@ -568,7 +554,7 @@ int MotorMainProcess(void) break; } /* The LED blinks when no status is not error. */ - HAL_GPIO_TogglePin(&g_gpio2, GPIO_PIN_3); + HAL_GPIO_TogglePin(&SYS_LED_HANDLE, SYS_LED_PIN); tickCnt500Ms = g_mc.msTickCnt; } } diff --git a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/application/mcs_user_config.h b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/application/mcs_user_config.h index 5069433a95874a61e07846a581007bbc49914637..fc7eaa1c2ade0209fce740a1ce92b558b6fb88d2 100644 --- a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/application/mcs_user_config.h +++ b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/application/mcs_user_config.h @@ -22,10 +22,26 @@ #ifndef McuMagicTag_MCS_CONFIG_H #define McuMagicTag_MCS_CONFIG_H -/* APT synchronization */ -#define APT_SYNC_IN_SRC APT_SYNCIN_SRC_APT0_SYNCOUT -/* Overcurrent protection flag */ -#define APT_EVT_IRQ_CP IRQ_APT0_EVT +#if defined(CHIP_3061MNPICA) || defined(CHIP_3061MNNICA) || defined(CHIP_3061MNPIC8) || defined(CHIP_3061MNNIC8) +#define ADC_U_SOC_NUM ADC_SOC_NUM2 +#define ADC_V_SOC_NUM ADC_SOC_NUM5 +#define ADC_W_SOC_NUM ADC_SOC_NUM6 +#define ADC_SPD_ADJ_SOC_NUM ADC_SOC_NUM9 +#define ADC_HANDLE g_adc0 +#endif + +#if defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) +#define ADC_U_SOC_NUM ADC_SOC_NUM3 +#define ADC_V_SOC_NUM ADC_SOC_NUM5 +#define ADC_W_SOC_NUM ADC_SOC_NUM7 +#define ADC_SPD_ADJ_SOC_NUM ADC_SOC_NUM9 + +#define ADC_HANDLE g_adc2 +#endif + +#define APT_PWM_FREQ 12000 /* PWM frequency 12K Hz. */ +#define CTRL_CURR_PERIOD (1.0f / APT_PWM_FREQ) /* carrier ISR period (S) */ +#define CTRL_CURE_PERIOD_US 83 #define SYSTICK_PERIOD_US 500u /* systick period. unit : us */ @@ -40,16 +56,14 @@ #define MATH_PI 3.14 /* Pi */ #define MOTOR_K 0.013 /* Torque Coefficient */ -#define BOOST_FACTOR 0.1 /* Boosting factor */ - #define RAMP_STP 60 /* Slope of forced draging acceleration */ #define RAMP_DUTY_PWM 0.5 /* 1.0% */ #define FORCE_DRAG_MINDUTY 10 /* APT minimum duty cycle during forced drag */ -#define FORCE_DRAG_MAXDUTY 10 /* APT maximum duty cycle during forced drag */ +#define FORCE_DRAG_MAXDUTY 15 /* APT maximum duty cycle during forced drag */ -#define DRAG_START_INTERVAL 1000 /* Force drag change phase every 48 ms.(1000 * 60us = 60ms) */ -#define DRAG_STOP_INTERVAL 400 /* Force drag change phase every 24 ms.(200 * 60us = 12ms) */ +#define DRAG_START_INTERVAL 1000 /* Force drag change phase time */ +#define DRAG_STOP_INTERVAL 400 /* Force drag change phase time */ /* Parameters of the motor in the RUN */ #define FILTER_COUNT 3 /* Filter Times */ diff --git a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/common/mcs_carrier.c b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/common/mcs_carrier.c index 69958a6686d9759f756a96e2964fd8de2bc04ccc..7779fbef2e3eee99fb209f617bb4d3f7d923309d 100644 --- a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/common/mcs_carrier.c +++ b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/common/mcs_carrier.c @@ -29,42 +29,7 @@ #define S_TO_SYSTICK 100000000 /** - * @brief Set the count compare points along the left and right edges of PWM waveform. - * @param aptHandle APT module handle. - * @param duty PWM duty. Range: 1 ~ 99. - * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. - */ -static BASE_StatusType APT_SetPWMDutyByNumber(APT_Handle *aptHandle, float duty) -{ - APT_ASSERT_PARAM(aptHandle != NULL); - APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); - APT_PARAM_CHECK_WITH_RET(duty < 100.0, BASE_STATUS_ERROR); /* 100.0 % */ - APT_PARAM_CHECK_WITH_RET(duty > 0.0, BASE_STATUS_ERROR); /* 0.0 % */ - - unsigned int cntCmpLeftEdge; - unsigned int cntCmpRightEdge; - TC_REFC_REG tmpC; - TC_REFD_REG tmpD; - - if (aptHandle->waveform.cntMode == APT_COUNT_MODE_UP_DOWN) { - cntCmpLeftEdge = aptHandle->waveform.timerPeriod - \ - (int)(((float)aptHandle->waveform.timerPeriod / 100.0) * duty); /* 100.0 % */ - cntCmpRightEdge = cntCmpLeftEdge; - } else { - cntCmpLeftEdge = 1; - cntCmpRightEdge = (int)(((float)aptHandle->waveform.timerPeriod / 100.0) * duty + cntCmpLeftEdge); /* 100.0 % */ - } - tmpC = aptHandle->baseAddress->TC_REFC; - tmpC.BIT.rg_cnt_refc = cntCmpLeftEdge; - aptHandle->baseAddress->TC_REFC = tmpC; - tmpD = aptHandle->baseAddress->TC_REFD; - tmpD.BIT.rg_cnt_refd = cntCmpRightEdge; - aptHandle->baseAddress->TC_REFD = tmpD; - return BASE_STATUS_OK; -} - -/** - * @brief Sets the duty cycle of the H-bridge APT.. + * @brief Sets the duty cycle of the H-bridge APT. * @param aptHandle APT module handle. * @param duty PWM duty. Range: 0.1 ~ 99.9. * @retval None. @@ -74,13 +39,13 @@ void MCS_SetCtrAptDuty(MtrCtrlHandle *mtrCtrl, unsigned int duty) MCS_ASSERT_PARAM(mtrCtrl != NULL); MCS_ASSERT_PARAM(duty > 0); /* Set pwm duty of uvw pahse */ - APT_SetPWMDutyByNumber(mtrCtrl->stepCtrl.controlApt.u, duty); - APT_SetPWMDutyByNumber(mtrCtrl->stepCtrl.controlApt.v, duty); - APT_SetPWMDutyByNumber(mtrCtrl->stepCtrl.controlApt.w, duty); + HAL_APT_SetPWMDutyByNumber(mtrCtrl->stepCtrl.controlApt.u, duty); + HAL_APT_SetPWMDutyByNumber(mtrCtrl->stepCtrl.controlApt.v, duty); + HAL_APT_SetPWMDutyByNumber(mtrCtrl->stepCtrl.controlApt.w, duty); } /** - if (mtrCtrl->sysVar.accTimeCnt >= mtrCtrl->sysVar.dragChangePhaseTime) { + * @brief Strong drag start. * @param mtrCtrl The motor control handle. * @retval None. */ @@ -92,6 +57,7 @@ static void ForceDragAcc(MtrCtrlHandle *mtrCtrl) unsigned int dragChangeFreq; unsigned int timerperiod; unsigned int freqLast; + unsigned int aptCountsOneUs; mtrCtrl->sysVar.accTimeCnt++; if (mtrCtrl->sysVar.accTimeCnt < mtrCtrl->sysVar.dragChangePhaseTime) { @@ -102,10 +68,10 @@ static void ForceDragAcc(MtrCtrlHandle *mtrCtrl) /* Step 1: Calculate the voltage difference. */ voltageDValue = IN_VOLTAGE_BUS * RAMP_DUTY_PWM; /* Step 2: Calculate the commutation frequency. */ - freqLast = S_TO_US / (mtrCtrl->sysVar.dragChangePhaseTime * 83); /* The counting period is 83 us. */ + freqLast = S_TO_US / (mtrCtrl->sysVar.dragChangePhaseTime * CTRL_CURE_PERIOD_US); dragChangeFreq = voltageDValue * STEP_MAX_NUM * POLES / (MOTOR_K * 2 * MATH_PI) + freqLast; /* 2*PI = 360° */ /* Step 3: Convert the commutation frequency to the commutation count value. */ - timerperiod = mtrCtrl->stepCtrl.controlApt.u->waveform.timerPeriod * 83; /* The counting period is 83 us. */ + timerperiod = mtrCtrl->stepCtrl.controlApt.u->waveform.timerPeriod * CTRL_CURE_PERIOD_US; mtrCtrl->sysVar.dragChangePhaseTime = S_TO_US / (timerperiod * dragChangeFreq); /* Determine whether the change phase speed has reached the speed of stopping forced drag. */ @@ -120,9 +86,9 @@ static void ForceDragAcc(MtrCtrlHandle *mtrCtrl) /* Shorten the time interval of forced drag change phase. */ mtrCtrl->pwmDuty += RAMP_DUTY_PWM; - /* 150 : 1us = 150 systick */ - mtrCtrl->sysVar.waitTime = (mtrCtrl->sysVar.dragChangePhaseTime * 83 * 150) >> 1; /* The count period is 83us. */ - /* 2 : Change phase time is 2 the waiting time. */ + aptCountsOneUs = HAL_CRG_GetIpFreq(APT0_BASE) / S_TO_US; + mtrCtrl->sysVar.waitTime = (mtrCtrl->sysVar.dragChangePhaseTime * CTRL_CURE_PERIOD_US * aptCountsOneUs) >> 1; + /* Change phase time is 2 the waiting time. */ mtrCtrl->spdRefHz = (float)(HAL_CRG_GetIpFreq(SYSTICK_BASE) / (mtrCtrl->sysVar.waitTime * 2)) / STEP_MAX_NUM; mtrCtrl->spdEstHz = mtrCtrl->spdRefHz; mtrCtrl->spdRmg.yLast = mtrCtrl->spdRefHz; @@ -225,26 +191,34 @@ static void ChangePhase(MtrCtrlHandle *mtrCtrl) } /** - * @brief Zero-crossing detection and change phase - * @param mtrCtrl The motor control handle. - * @retval None. - */ + * @brief Zero-crossing detection and change phase + * @param mtrCtrl The motor control handle. + * @retval None. + */ void MCS_CarrierProcess(MtrCtrlHandle *mtrCtrl) { MCS_ASSERT_PARAM(mtrCtrl != NULL); - - if (mtrCtrl->stateMachine == FSM_STARTUP) { - /* Forced drag. */ - ForceDragAcc(mtrCtrl); - } else if (mtrCtrl->stateMachine == FSM_RUN) { - mtrCtrl->readBemfUVW(&mtrCtrl->bemf); - MCS_SetCtrAptDuty(mtrCtrl, mtrCtrl->pwmDuty); - if (mtrCtrl->sysVar.changePhaseFlag) { - /* Change phase process. */ - ChangePhase(mtrCtrl); - } else { - /* Zero-crossing detection procedure. */ - BemfZeroCheck(mtrCtrl); - } + /* Offset value of the calibration value of the three-phase current */ + + switch (mtrCtrl->stateMachine) { + case FSM_STARTUP: + ForceDragAcc(mtrCtrl); /* Forced drag. */ + break; + + case FSM_RUN: + case FSM_WAIT_STOP: + mtrCtrl->readBemfUVW(&mtrCtrl->bemf); + MCS_SetCtrAptDuty(mtrCtrl, mtrCtrl->pwmDuty); + if (mtrCtrl->sysVar.changePhaseFlag) { + /* Change phase process. */ + ChangePhase(mtrCtrl); + } else { + /* Zero-crossing detection procedure. */ + BemfZeroCheck(mtrCtrl); + } + break; + + default: + break; } } \ No newline at end of file diff --git a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/common/mcs_carrier.h b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/common/mcs_carrier.h index 31d235dbae9c90baa0e67a5af8c48958526a0498..05fc26667e96b59288aba49344f448a3bf243816 100644 --- a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/common/mcs_carrier.h +++ b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/common/mcs_carrier.h @@ -60,7 +60,6 @@ typedef struct { typedef struct { volatile float spdCmdHz; /**< Set target change phase frequency */ float spdRefHz; /**< Command values after speed ramp management */ - float spdCurrHz; /**< Actual change phase frequency of feedback */ float spdEstHz; /**< Actual change phase frequency of feedback */ float pwmDuty; /**< APT duty cycle */ unsigned int zeroPoint; /**< Adc value of zero point */ diff --git a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/func/mcs_six_step.c b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/func/mcs_six_step.c index 1104cf42dbe385a8a4d55c57e17a99c0eeeca1a1..c86e609c8e3512ec0e0569c06aae5f38afff8ebe 100644 --- a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/func/mcs_six_step.c +++ b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/func/mcs_six_step.c @@ -44,34 +44,34 @@ static void APT_ForcePwmByApt(APT_RegStruct *aptx, APT_Act actMode) { MCS_ASSERT_PARAM(aptx != NULL); switch (actMode) { - case APT_CHA_PWM_CHB_HIGH: + case APT_CHA_PWM_CHB_LOW: /* Channel A: 0 means not force output enable, channel A output PWM. */ DCL_APT_DisableSwContPWMAction(aptx, APT_PWM_CHANNEL_A); - DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_A, APT_PWM_OUT_ALWAYS_LOW); + DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); /* Channel B: 1 means force output enable. */ DCL_APT_EnableSwContPWMAction(aptx, APT_PWM_CHANNEL_B); /* Channel B: 2 means channel B force output LOW due to the A_H_B_L invert. */ - DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_B, APT_PWM_OUT_ALWAYS_HIGH); + DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); break; case APT_CHA_LOW_CHB_HIGH: /* Channel A: 1 means force output enable. */ /* Channel A: 1 means channel A force output LOW. */ DCL_APT_EnableSwContPWMAction(aptx, APT_PWM_CHANNEL_A); - DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_A, APT_PWM_OUT_ALWAYS_LOW); + DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); /* Channel B: 1 means force output enable. */ /* Channel B: 2 means channel B force output HIGH. */ DCL_APT_EnableSwContPWMAction(aptx, APT_PWM_CHANNEL_B); - DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_B, APT_PWM_OUT_ALWAYS_HIGH); + DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_HIGH); break; case APT_CHA_LOW_CHB_LOW: /* Channel A: 1 means force output enable. */ /* Channel A: 1 means channel A force output LOW. */ DCL_APT_EnableSwContPWMAction(aptx, APT_PWM_CHANNEL_A); - DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_A, APT_PWM_OUT_ALWAYS_LOW); + DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_A, APT_PWM_CONTINUOUS_ACTION_LOW); /* Channel B: 1 means force output enable. */ /* Channel B: 1 means channel A force output HIGH due to the A_H_B_L invert. */ DCL_APT_EnableSwContPWMAction(aptx, APT_PWM_CHANNEL_B); - DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_B, APT_PWM_OUT_ALWAYS_LOW); + DCL_APT_SetSwContPWMAction(aptx, APT_PWM_CHANNEL_B, APT_PWM_CONTINUOUS_ACTION_LOW); break; default: break; @@ -90,35 +90,35 @@ void SixStepPwm(const SixStepHandle *handle) APT_RegStruct *aptV = handle->controlApt.v->baseAddress; APT_RegStruct *aptW = handle->controlApt.w->baseAddress; switch (handle->phaseStep) { - case STEP1: /* U+, W- */ - APT_ForcePwmByApt(aptU, APT_CHA_PWM_CHB_HIGH); + case STEP1: /* U+, V- */ + APT_ForcePwmByApt(aptU, APT_CHA_PWM_CHB_LOW); APT_ForcePwmByApt(aptV, APT_CHA_LOW_CHB_LOW); APT_ForcePwmByApt(aptW, APT_CHA_LOW_CHB_HIGH); break; - case STEP2: /* V+, W- */ - APT_ForcePwmByApt(aptU, APT_CHA_PWM_CHB_HIGH); + case STEP2: /* U+, W- */ + APT_ForcePwmByApt(aptU, APT_CHA_PWM_CHB_LOW); APT_ForcePwmByApt(aptV, APT_CHA_LOW_CHB_HIGH); APT_ForcePwmByApt(aptW, APT_CHA_LOW_CHB_LOW); break; - case STEP3: /* V+, U- */ + case STEP3: /* V+, W- */ APT_ForcePwmByApt(aptU, APT_CHA_LOW_CHB_HIGH); - APT_ForcePwmByApt(aptV, APT_CHA_PWM_CHB_HIGH); + APT_ForcePwmByApt(aptV, APT_CHA_PWM_CHB_LOW); APT_ForcePwmByApt(aptW, APT_CHA_LOW_CHB_LOW); break; - case STEP4: /* W+, U- */ + case STEP4: /* V+, U- */ APT_ForcePwmByApt(aptU, APT_CHA_LOW_CHB_LOW); - APT_ForcePwmByApt(aptV, APT_CHA_PWM_CHB_HIGH); + APT_ForcePwmByApt(aptV, APT_CHA_PWM_CHB_LOW); APT_ForcePwmByApt(aptW, APT_CHA_LOW_CHB_HIGH); break; - case STEP5: /* W+, V- */ + case STEP5: /* W+, U- */ APT_ForcePwmByApt(aptU, APT_CHA_LOW_CHB_LOW); APT_ForcePwmByApt(aptV, APT_CHA_LOW_CHB_HIGH); - APT_ForcePwmByApt(aptW, APT_CHA_PWM_CHB_HIGH); + APT_ForcePwmByApt(aptW, APT_CHA_PWM_CHB_LOW); break; - case STEP6: /* U+, V- */ + case STEP6: /* W+, V- */ APT_ForcePwmByApt(aptU, APT_CHA_LOW_CHB_HIGH); APT_ForcePwmByApt(aptV, APT_CHA_LOW_CHB_LOW); - APT_ForcePwmByApt(aptW, APT_CHA_PWM_CHB_HIGH); + APT_ForcePwmByApt(aptW, APT_CHA_PWM_CHB_LOW); break; default: break; diff --git a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/func/mcs_six_step.h b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/func/mcs_six_step.h index cea88455ce095e8dcd4eaad32cb0067e2a176380..08198c4caedc927239402496adfd0b3fb18df415 100644 --- a/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/func/mcs_six_step.h +++ b/src/application/middleware_sample/mcs_sensorless_bldc_six_step_wave/func/mcs_six_step.h @@ -49,7 +49,7 @@ typedef enum { } PhaseEnum; typedef enum { - APT_CHA_PWM_CHB_HIGH, + APT_CHA_PWM_CHB_LOW, APT_CHA_LOW_CHB_HIGH, APT_CHA_LOW_CHB_LOW } APT_Act; diff --git a/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/inc/nos_task_schedule.h b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/inc/nos_task_schedule.h new file mode 100644 index 0000000000000000000000000000000000000000..59f0978d2a4c4e7175d75ad31cd04fdf4cf92469 --- /dev/null +++ b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/inc/nos_task_schedule.h @@ -0,0 +1,38 @@ +/** + * @copyright Copyright (c) Hisilicon Technologies Co., Ltd 2024-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file nos_task_schedule.h + * @author MCU Driver Team + * @brief timertask sample module. + * @details This file provides users with sample code to help use TIMER TASK function + */ +#ifndef NOS_TASK_SCHEDULE_H +#define NOS_TASK_SCHEDULE_H +#include "timer.h" + +typedef struct { + unsigned int timeout; + unsigned int timerBase; + unsigned int timerIrq; + TIMER_CallBackFunc callback; + unsigned int callbackParam; + int priority; +} HalTimerCreateInfo; + +void NOS_TaskSchedule(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/feature.h b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/feature.h new file mode 100644 index 0000000000000000000000000000000000000000..c85c9eb457e3293a852d0b4d082a51f8aac28822 --- /dev/null +++ b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/feature.h @@ -0,0 +1,120 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file feature.h + * @author MCU Driver Team + * @brief This file contains macro configurations related to the project. This file is generated by the IDE tool. + */ + +#ifndef McuMagicTag_FEATURE_H +#define McuMagicTag_FEATURE_H + +/* Macro definitions --------------------------------------------------------- */ +#define CHIP_3065HRPIRZ MACRO_ENABLE + +#define MACRO_ENABLE 1 +#define MACRO_DISABLE 0 + +/* Macro switch */ +#define BASE_DEFINE_USE_ASSERT MACRO_ENABLE +#ifndef FLASH_CRC_CONFIG +#define FLASH_CRC_CONFIG +#endif /* #ifndef FLASH_CRC_CONFIG */ +#define BASE_MATH_SINCOS_MIDDLE_TABLE MACRO_ENABLE /**< This macro is used to control the table type when the + BASE_MATH_GetSinCos() queries the table. When the value of + this macro is MACRO_ENABLE, the error value obtained by the + BASE_MATH_GetSinCos() is relatively small, and the return + value of the function may be greater than or less than the + actual value. When the value of this macro is MACRO_DISABLE, + the error value obtained by the BASE_MATH_GetSinCos() is + relatively large. However, in the range [0°, 180°) and + [180°, 360°), the return value of the function is either + greater than or less than the actual value. */ + +#define MCS_PARAM_CHECK MACRO_ENABLE +#define APT_PARAM_CHECK MACRO_ENABLE +#define ADC_PARAM_CHECK MACRO_ENABLE +#define CAPM_PARAM_CHECK MACRO_ENABLE +#define CRG_PARAM_CHECK MACRO_ENABLE +#define I2C_PARAM_CHECK MACRO_ENABLE +#define UART_PARAM_CHECK MACRO_ENABLE +#define SPI_PARAM_CHECK MACRO_ENABLE +#define TIMER_PARAM_CHECK MACRO_ENABLE +#define WDG_PARAM_CHECK MACRO_ENABLE +#define GPIO_PARAM_CHECK MACRO_ENABLE +#define GPT_PARAM_CHECK MACRO_ENABLE +#define DMA_PARAM_CHECK MACRO_ENABLE +#define CRC_PARAM_CHECK MACRO_ENABLE +#define CFD_PARAM_CHECK MACRO_ENABLE +#define CMM_PARAM_CHECK MACRO_ENABLE +#define CAN_PARAM_CHECK MACRO_ENABLE +#define FLASH_PARAM_CHECK MACRO_ENABLE +#define PMC_PARAM_CHECK MACRO_ENABLE +#define ACMP_PARAM_CHECK MACRO_ENABLE +#define DAC_PARAM_CHECK MACRO_ENABLE +#define PGA_PARAM_CHECK MACRO_ENABLE +#define IOCMG_PARAM_CHECK MACRO_ENABLE +#define IWDG_PARAM_CHECK MACRO_ENABLE +#define QDM_PARAM_CHECK MACRO_ENABLE +#define NOS_TASK_SUPPORT MACRO_ENABLE + +/* Peripheral module macro switch--------------------------------------------- */ +#define BOARD_DIM_NUM 1 /**< Number of dimming handle arrays. */ + +#define BOARD_KEY_NUM 10 /**< Number of key handle arrays. */ +#define BOARD_KEY_PRESS_ON GPIO_HIGH_LEVEL /**< GPIO status corresponding to long press valid. */ +#define BOARD_KEY_PRESS_OFF GPIO_LOW_LEVEL /**< GPIO status corresponding to short press valid. */ + +#define BOARD_LED_SEG_NUM 4 /**< Number of segments. */ +#define BOARD_LED_SEGMENT_ON GPIO_HIGH_LEVEL /**< GPIO level status corresponding to valid segments. */ +#define BOARD_LED_SEGMENT_OFF GPIO_LOW_LEVEL /**< GPIO level status corresponding to invalid segments. */ + +#define BOARD_MKEY_SCHEME_NUMBER BOARD_MKEY_SCHEME_NUMBER_ONE /**< Define the scheme to be adopted. */ +#define BOARD_MKEY_OUT_NUM 4 /**< Number of GPIO pins used as output during scanning. */ +#define BOARD_MKEY_IN_NUM 4 /**< Number of GPIO pins used as input during scanning. */ +#define BOARD_MKEY_OUT_PIN_VALID GPIO_LOW_LEVEL /**< GPIO level status corresponding to the valid \ + status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_OUT_PIN_INVALID GPIO_HIGH_LEVEL /**< GPIO level status corresponding to the \ + invalid status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_VALID GPIO_LOW_LEVEL /**< Indicates the GPIO level corresponding to the \ + valid status of the input GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_INVALID GPIO_HIGH_LEVEL /**< Indicates the GPIO level corresponding to the \ + invalid status of the input GPIO in the key matrix. */ + +#define BOARD_PULSES_NUM 2 /**< Number of pulse handles. */ + +#define BASE_DEFINE_SLIPAVERAGE_NUM 2 /**< Sliding average array length. */ + +#define LISTNODE_MAX 20 + +#define BASE_DEFINE_DMA_QUICKSTART + +#define XTRAIL_FREQ 30000000U + +#define DBG_USE_NO_PRINTF 0U +#define DBG_USE_UART_PRINTF 1U + +#define DBG_PRINTF_USE DBG_USE_UART_PRINTF +#if (DBG_PRINTF_USE == DBG_USE_UART_PRINTF) +#define DBG_PRINTF_UART_PORT UART0 +#endif + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_FEATURE_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/main.c b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..1869db7ed013a5009be3113b22b21363a7c9abf3 --- /dev/null +++ b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/main.c @@ -0,0 +1,58 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "nos_task_schedule.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + NOS_TaskSchedule(); + /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/main.h b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..1a1d3ceab401b3bf27ac352c552222e933ad4a93 --- /dev/null +++ b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/main.h @@ -0,0 +1,52 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "crg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/system_init.c b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..8c069eeaf7e5cdbaa8868bb0950fb5459eefc97f --- /dev/null +++ b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/init/system_init.c @@ -0,0 +1,101 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 32; /* PLL Multiplier 32 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_1; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); + + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +static void IOConfig(void) +{ + /* Config PIN50 */ + HAL_IOCMG_SetPinAltFuncMode(IO50_AS_JTAG_TMS); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO50_AS_JTAG_TMS, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO50_AS_JTAG_TMS, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO50_AS_JTAG_TMS, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO50_AS_JTAG_TMS, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN49 */ + HAL_IOCMG_SetPinAltFuncMode(IO49_AS_JTAG_TCK); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO49_AS_JTAG_TCK, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO49_AS_JTAG_TCK, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO49_AS_JTAG_TCK, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO49_AS_JTAG_TCK, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/readme.md b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..748198187c6376f01f5d848a687228d2e714bc03 --- /dev/null +++ b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/readme.md @@ -0,0 +1,25 @@ +# 定时器任务调度器使用参考示例 +## 关键字: 任务调度,定时器,任务创建,任务启动,任务停止 + +**【功能描述】** ++ 用例中创建3个定时器任务,分别定时100us,200us,1ms。用例在运行100ms后停止所有定时器任务,打印出三个任务的触发执行时间,通过时间戳可以看出定时器是否预定时间定时触发。 + +**【示例配置】** ++ 任务栈大小配置:通过定义全局数组变量的方式分配各个任务的栈空间。 + ++ 任务创建:调用“NOS_CreateTimerTask()”接口创建新的定时器任务。 + ++ 任务启动:调用“NOS_StartTimerTask()”接口启动已创建成功的指定定时器任务。 + ++ 任务停止运行:调用“NOS_StopTimerTask”接口停止正在运行的指定定时器任务。 + +**【示例效果】** ++ 当用户烧录编译后的示例代码后,初始化和配置完成后,示例代码中会创建3个定时器任务,分别定时100us,200us,1ms。用例在运行100ms后停止所有定时器任务,打印出三个任务的触发执行时间,通过时间戳可以看出定时器是否预定时间定时触发。 + +**【注意事项】** ++ 示例代码使用UART0进行结果打印输出,需要对UART0进行初始化配置。 ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 ++ 必须打开“NOS_TASK_SUPPORT”全局宏 ++ 必须关闭用户模式支持宏 \ No newline at end of file diff --git a/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/src/nos_task_schedule.c b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/src/nos_task_schedule.c new file mode 100644 index 0000000000000000000000000000000000000000..a429cc2b62880535c5c7a98b0aa469174fa3522f --- /dev/null +++ b/src/application/middleware_sample/operation_systerm/nos/nos_task_schedule/src/nos_task_schedule.c @@ -0,0 +1,192 @@ +/** + * @copyright Copyright (c) Hisilicon Technologies Co., Ltd 2024-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sample_timer_task.c + * @author MCU Driver Team + * @brief timertask sample module. + * @details This file provides users with sample code to help use TIMER TASK function + */ +#include "feature.h" +#include "main.h" +#ifdef NOS_TASK_SUPPORT +#include "debug.h" +#include "systick.h" +#include "nos_task.h" +#include "crg.h" +#include "nos_task_schedule.h" + +#define TIMER_DFX_CNT 100 +#define TIMER0_TIMEOUT 100 +#define TIMER1_TIMEOUT 200 +#define TIMER2_TIMEOUT 1000 +#define TIMER0_PRIORITY 0 +#define TIMER1_PRIORITY 1 +#define TIMER2_PRIORITY 2 +#define SAMPLE_RUNNING_TIME 100 + +#define TIMER_NUM 3 +#define TIMER0_INDEX 0 +#define TIMER1_INDEX 1 +#define TIMER2_INDEX 2 + +static unsigned char __attribute__((aligned(16))) g_task0StackSpace[0x200] = {0}; +static unsigned char __attribute__((aligned(16))) g_task1StackSpace[0x200] = {0}; +static unsigned char __attribute__((aligned(16))) g_task2StackSpace[0x200] = {0}; + +typedef struct { + unsigned int param; + unsigned int time; +} DfxTimerTask; + +static DfxTimerTask g_dfxTest[TIMER_DFX_CNT] = {0}; +static unsigned int g_testCnt; + +/** + * @brief task0 callback function. + * @param param task param. + * @retval None. + */ +static void TIMER0_CallbackFunc(void *param) +{ + if (g_testCnt < TIMER_DFX_CNT) { + g_dfxTest[g_testCnt].param = (unsigned int)(uintptr_t)param; + g_dfxTest[g_testCnt].time = (unsigned int)SYSTICK_GetTimeStampUs(); /* get time stamp us */ + g_testCnt++; /* task has been scheduled times */ + } +} + +/** + * @brief task1 callback function. + * @param param task param. + * @retval None. + */ +static void TIMER1_CallbackFunc(void *param) +{ + if (g_testCnt < TIMER_DFX_CNT) { + g_dfxTest[g_testCnt].param = (unsigned int)(uintptr_t)param; + g_dfxTest[g_testCnt].time = (unsigned int)SYSTICK_GetTimeStampUs(); /* get time stamp us */ + g_testCnt++; /* task has been scheduled times */ + } +} + +/** + * @brief task2 callback function. + * @param param task param. + * @retval None. + */ +static void TIMER2_CallbackFunc(void *param) +{ + if (g_testCnt < TIMER_DFX_CNT) { + g_dfxTest[g_testCnt].param = (unsigned int)(uintptr_t)param; + g_dfxTest[g_testCnt].time = (unsigned int)SYSTICK_GetTimeStampUs(); /* get time stamp us */ + g_testCnt++; /* task has been scheduled times */ + } +} + +static unsigned int g_sampleTaskPid[TIMER_NUM]; +static NOS_TimerTaskInitParam g_timerTaskParams[TIMER_NUM] = { + { + .name = "task0", + .timeout = TIMER0_TIMEOUT, + .callback = TIMER0_CallbackFunc, /* task0 callback function. */ + .callbackParam = (void *)TIMER0_TIMEOUT, + .priority = TIMER0_PRIORITY, + .stackSize = sizeof(g_task0StackSpace), + .stackAddr = (unsigned int)g_task0StackSpace + }, + { + .name = "task1", + .timeout = TIMER1_TIMEOUT, + .callback = TIMER1_CallbackFunc, /* task1 callback function. */ + .callbackParam = (void *)TIMER1_TIMEOUT, + .priority = TIMER1_PRIORITY, + .stackSize = sizeof(g_task1StackSpace), + .stackAddr = (unsigned int)g_task1StackSpace + }, + { + .name = "task2", + .timeout = TIMER2_TIMEOUT, + .callback = TIMER2_CallbackFunc, /* task2 callback function. */ + .callbackParam = (void *)TIMER2_TIMEOUT, + .priority = TIMER2_PRIORITY, + .stackSize = sizeof(g_task2StackSpace), + .stackAddr = (unsigned int)g_task2StackSpace + } +}; + +/** + * @brief Creat timer task and return task id for task. + * @param None. + * @retval unsigned int 0 means function call success. + */ +static unsigned int TIMER_SampleCreateTimer(void) +{ + DBG_PRINTF("****************************************************** \r\n"); + DBG_PRINTF("Test for NosTimerTask: timer create & start\r\n"); + + DBG_PRINTF("****************************************************** \r\n"); + + for (int i = 0; i < TIMER_NUM; i++) { + /* Creat timer task and return task id for task. */ + (void)NOS_CreateTimerTask(&g_sampleTaskPid[i], &g_timerTaskParams[i]); + } + + for (int i = 0; i < TIMER_NUM; i++) { + /* start timer task. */ + (void)NOS_StartTimerTask(g_sampleTaskPid[i]); + } + return 0; +} + +/** + * @brief Print task schedule result. + * @param None. + * @retval None. + */ +static void TASK_PrintResult(void) +{ + int cnt[TIMER_NUM] = {0}; + for (int i = 0; i < TIMER_DFX_CNT; i++) { + if (g_dfxTest[i].param == TIMER0_TIMEOUT) { + cnt[TIMER0_INDEX]++; /* task0 schedule times */ + } else if (g_dfxTest[i].param == TIMER1_TIMEOUT) { + cnt[TIMER1_INDEX]++; /* task1 schedule times */ + } else if (g_dfxTest[i].param == TIMER2_TIMEOUT) { + cnt[TIMER2_INDEX]++; /* task2 schedule times */ + } + DBG_PRINTF("enter callback timeout=%d timestamp=%dus \r\n", g_dfxTest[i].param, g_dfxTest[i].time); + } + DBG_PRINTF("total cnt:%d cnt[100us]:%d,cnt[200us]:%d, cnt[1000us]:%d \r\n", TIMER_DFX_CNT, cnt[TIMER0_INDEX], + cnt[TIMER1_INDEX], cnt[TIMER2_INDEX]); +} + +static void TIMER_SampleStopTimer(void) +{ + for (int i = 0; i < TIMER_NUM; i++) { + NOS_StopTimerTask(g_sampleTaskPid[i]); /* stop timer task. */ + } +} + +void NOS_TaskSchedule(void) +{ + SystemInit(); + (void)TIMER_SampleCreateTimer(); /* creat and start task schedule */ + BASE_FUNC_DelayMs(SAMPLE_RUNNING_TIME); + TIMER_SampleStopTimer(); /* stop task schedule */ + TASK_PrintResult(); /* print task schedule result */ +} +#endif /* NOS_TASK_SUPPORT */ \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/init/main.c b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..584bc6cc70f9901466a549cd7f62c1f22f81743b --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/init/main.c @@ -0,0 +1,59 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +#include "user_app.h" +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +/* USER CODE BEGIN 1 */ +GPIO_Handle g_gpio3; +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + UserAppProgress(); + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/init/main.h b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..165af1f4f128cd5b72bb3a9f2bc914a8fbd7c734 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/init/main.h @@ -0,0 +1,58 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "i2c.h" +#include "i2c_ex.h" +#include "crg.h" +#include "iocmg.h" +#include "gpio.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern UART_Handle g_uart0; +extern GPIO_Handle g_gpio3; +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +/* USER CODE BEGIN 0 */ +void GPIO3_5_CallbackFunc(void *param); +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/init/system_init.c b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..0cc9404a37c1e864f6f78493e6de32e754424c01 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/init/system_init.c @@ -0,0 +1,122 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_DMA; + g_uart0.rxMode = UART_MODE_INTERRUPT; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +__weak void GPIO3_5_CallbackFunc(void *param) +{ + BASE_FUNC_UNUSED(param); /* Prevent compilation alarms. */ +} + +static void GPIO_Init(void) +{ + HAL_CRG_IpEnableSet(GPIO3_BASE, IP_CLK_ENABLE); + g_gpio3.baseAddress = GPIO3; + + g_gpio3.pins = GPIO_PIN_5; + HAL_GPIO_Init(&g_gpio3); /* Init GPIO. */ + HAL_GPIO_SetDirection(&g_gpio3, g_gpio3.pins, GPIO_INPUT_MODE); + HAL_GPIO_SetValue(&g_gpio3, g_gpio3.pins, GPIO_LOW_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio3, g_gpio3.pins, GPIO_INT_TYPE_FALL_EDGE); + + HAL_GPIO_RegisterCallBack(&g_gpio3, GPIO_PIN_5, GPIO3_5_CallbackFunc); + IRQ_Register(IRQ_GPIO3, HAL_GPIO_IrqHandler, &g_gpio3); + IRQ_SetPriority(IRQ_GPIO3, 1); /* set gpio1 interrupt priority to 1, 1~15. 1 is priority value */ + IRQ_EnableN(IRQ_GPIO3); /* gpio interrupt enable */ +} + +static void IOConfig(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_5_AS_GPIO3_5); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_5_AS_GPIO3_5, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_5_AS_GPIO3_5, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_5_AS_GPIO3_5, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_5_AS_GPIO3_5, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + /* USER CODE BEGIN system_init */ + GPIO_Init(); + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/readme.md b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..c029dd15caaaa64c3bd1283d5fb541bcb6ba9a6f --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/readme.md @@ -0,0 +1,26 @@ +# MCU芯片 OTA APP升级参考示例 +## 关键字: OTA,APP升级 + +**【功能描述】** ++ OTA是一种通过无线通信实现远程更新设备固件的方法。MCU OTA为通过外部具有无线通信的器件接收新固件数据,外部器件将新固件数据通过MCU串行通信接口发送给MCU,实现固件更新。MCU的OTA主要工作是将串行通信接口接收的新固件数据更新到用户指定的程序区,完成固件的升级。 ++ 此示例展示了APP具有升级功能的代码编写,拷贝升级、交叉升级模型一般包括1个user boot flash分区、2个APP flash分区、1个参数存储flash区。User boot flash分区拷贝升级和交叉升级模型存在差异,APP运行flash分区的升级功能相同。所以此APP升级示例可适用于拷贝升级、交叉升级模型的APP编写参考。 ++ flash空间使用: + 1.APP flash分区:起始地址0x3004000,大小36K; + 2.参数存储flash分区:起始地址0x301FC00,大小1K; + +**【示例配置】** ++ 配置UART0波特率为115200作为升级速率。 + ++ 配置CRC使用16bit校验结果,用于校验通信数据正确性。 + ++ 配置flash阻塞方式进行擦除、编写,用于更新flash存储固件。 + + +**【示例效果】** ++ 升级功能是APP完成的,当升级GPIO管脚获取信号后,会进入OTA升级环节。主机在1s内发起与OTA程序握手,握手成功进入固件升级阶段,完成固件升级后,主机下发命令复位MCU。MCU再次重新运行。 + +**【注意事项】** ++ 示例代码使用UART0作为升级通道,需要硬件预留UART0的升级管脚。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_app/user_app.c b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_app/user_app.c new file mode 100644 index 0000000000000000000000000000000000000000..1c066e17d28e43a8bb461a8957d229139ce8ce65 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_app/user_app.c @@ -0,0 +1,99 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_app.c + * @author MCU Driver Team + * @brief This file provides the user app function. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "user_loader.h" +#include "debug.h" +#include "user_app.h" + +/* Macro definitions --------------------------------------------------------- */ +#define USER_LOADER_HANDSHAKE_TIMEOUT 1000 +#define DBG_PRINTF_FINISH_WAIT_TIME 100 +#define LOOP_PRINTF_TIME 1000 + +static unsigned int g_otaFlage = 0; + +void GPIO3_5_CallbackFunc(void *param) +{ + BASE_FUNC_UNUSED(param); /* Prevent compilation alarms. */ + g_otaFlage = 1; +} + +/** + * @brief Start the OTA upgrade process. + * @param None. + * @retval None. + */ +static void StartOtaProgress(void) +{ + /* Initializes module resources required for the upgrade. */ + ULOADER_Handle uloaderHandle; + FLASH_Handle flashHandle; + CRC_Handle crcHandle; + UART_Handle uart0Handle; + ULOADER_Cmd cmd; + + uloaderHandle.flash = &flashHandle; + uloaderHandle.crc = &crcHandle; + uloaderHandle.comHandle = (void *)&uart0Handle; + uloaderHandle.mode = COMMUNICATION_UART; + ULOADER_Init(&uloaderHandle); /* Init the module resources of user loader. */ + /* User OTA progress */ + if (ULOADER_HandShake(&uloaderHandle, USER_LOADER_HANDSHAKE_TIMEOUT) == BASE_STATUS_OK) { + while (true) { + if (ULOADER_ReceiveCmd(&uloaderHandle, &cmd) != BASE_STATUS_OK) { + continue; + } + if (ULOADER_CommandExec(&uloaderHandle, &cmd) != BASE_STATUS_OK) { + ULOADER_Ack(&uloaderHandle, ACK_FAIL, 0); + } + } + } + + ULOADER_DeInit(&uloaderHandle); + BASE_FUNC_SoftReset(); /* Hand shake fail, reset the chip. */ +} + +/** + * @brief User app progress function. + * @param None. + * @retval None. + */ +void UserAppProgress(void) +{ + SystemInit(); /* Init peripheral module */ + while (true) { + /* User Logic Program Example. */ + DBG_PRINTF("User loop wait ota flage\r\n"); + BASE_FUNC_DELAY_MS(LOOP_PRINTF_TIME); + + /* The program enters the OTA phase and starts the firmware upgrade. */ + if (g_otaFlage == 1) { + /* All interrupts used in the APP must be disabled to ensure that the upgrade process is not interrupted. */ + IRQ_DisableN(IRQ_GPIO3); + DBG_PRINTF("User loader start.\r\n"); + BASE_FUNC_DELAY_MS(DBG_PRINTF_FINISH_WAIT_TIME); + StartOtaProgress(); /* Start the user OTA progress. */ + } + } +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_app/user_app.h b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_app/user_app.h new file mode 100644 index 0000000000000000000000000000000000000000..17c9840bfae8cc064ec86fad1705402cc2dac134 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_app/user_app.h @@ -0,0 +1,32 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_app.h + * @author MCU Driver Team + * @brief This file provides the user app function. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_USER_APP_H +#define McuMagicTag_USER_APP_H + +/* Includes ------------------------------------------------------------------*/ +#include "user_loader.h" + +void UserAppProgress(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_handshake_read.c b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_handshake_read.c new file mode 100644 index 0000000000000000000000000000000000000000..3e7a0163dce3b142d1d185c3ee20cbe6a4098b4d --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_handshake_read.c @@ -0,0 +1,170 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_handshake_read.c + * @author MCU Driver Team + * @brief This file provides the user handshake and read functions to manage the following functionalities of + * the user loader. + * + Receiving handshake frames functions. + * + UART, I2C, SPI read blocking adapt functions. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "user_handshake_read.h" + +/* Macro definitions --------------------------------------------------------- */ +#define SYSTICK_MS_DIV 1000 +#define ACK_SIZE 6 +#define RECEIVE_ONE_BYTE_DELAY_TIME 40 +#define RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME 500 + +/** + * @brief Check whether the automatic baud rate detection is complete. + * @param handle UART handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType IsActiveUart(UART_Handle *handle) +{ + if (handle->baseAddress->UART_RIS.BIT.abdcris == 1 && handle->baseAddress->UART_RIS.BIT.abderis == 0 && + handle->baseAddress->UART_ABDEN.BIT.abdbusy == 0) { + HAL_UART_DisableBaudDetectionEx(handle); /* Auto-baud detection complete. */ + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief User receive one byte. + * @param handle UART handle. + * @param targetByte the target byte. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType UartReceiveTargetByte(UART_Handle *handle, unsigned char targetData, unsigned int timeout) +{ + unsigned int preTick = DCL_SYSTICK_GetTick(); /* Get current tick. */ + unsigned int curTick; + unsigned long long delta = 0; + unsigned long long targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SYSTICK_MS_DIV * timeout; + unsigned char headFrame; + + while (true) { + /* Receives handshake frames sent by the host. */ + headFrame = DCL_UART_ReadData(handle->baseAddress); + if (headFrame == targetData) { + return BASE_STATUS_OK; + } + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* Check timeout. */ + break; + } + preTick = curTick; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief User loader receiving handshake frame. + * @param handle UART handle. + * @param buf Address of the data buffer to be saved. + * @param length the size of the data to be receiving. + * @param targetByte the target byte. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType UloaderReceiveHandShakeFrame(UART_Handle *handle, unsigned char *buf, unsigned int length, + unsigned char targetByte) +{ + BASE_StatusType ret; + if (IsActiveUart(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + /* Receives handshake frames sent ack frame to the host. */ + ret = HAL_UART_WriteBlocking(handle, buf, ACK_SIZE, RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + /* Receives handshake frames sent by the host. */ + ret = UartReceiveTargetByte(handle, targetByte, RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + buf[0] = targetByte; /* receive target byte, and then recive data. */ + ret = HAL_UART_ReadBlocking(handle, &buf[1], (length - 1), RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME); + return ret; +} + +/** + * @brief Blocking read data in UART mode. + * @param handle UART handle. + * @param rData Address of the data buffer to be saved. + * @param dataSize the size of the data to be receiving. + * @param targetByte the target byte. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType ULOADER_UART_ReadBlocking(UART_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout) +{ + BASE_StatusType ret; + /* Receives handshake frames sent by the host. */ + ret = UartReceiveTargetByte(handle, targetByte, timeout); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + rData[0] = targetByte; /* receive target byte, and then recive data. */ + ret = HAL_UART_ReadBlocking(handle, &rData[1], (dataSize - 1), timeout); + return ret; +} + +/** + * @brief Blocking read data in I2C mode. + * @param handle I2C handle. + * @param rData Address of the data buffer to be saved. + * @param dataSize the size of the data to be receiving. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType ULOADER_I2C_ReadBlocking(I2C_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned int timeout) +{ + BASE_FUNC_UNUSED(handle); /* Compiler prevention alarm */ + BASE_FUNC_UNUSED(rData); + BASE_FUNC_UNUSED(dataSize); + BASE_FUNC_UNUSED(timeout); + return BASE_STATUS_OK; +} + +/** + * @brief Blocking read data in SPI mode. + * @param handle SPI handle. + * @param rData Address of the data buffer to be saved. + * @param dataSize the size of the data to be receiving. + * @param targetByte the target byte. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType ULOADER_SPI_ReadBlocking(SPI_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout) +{ + BASE_FUNC_UNUSED(handle); /* Compiler prevention alarm */ + BASE_FUNC_UNUSED(rData); + BASE_FUNC_UNUSED(dataSize); + BASE_FUNC_UNUSED(targetByte); + BASE_FUNC_UNUSED(timeout); + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_handshake_read.h b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_handshake_read.h new file mode 100644 index 0000000000000000000000000000000000000000..3f7b1db82ef7715b1879bf45d4e8387203d5eda1 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_handshake_read.h @@ -0,0 +1,49 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_handshake_read.h + * @author MCU Driver Team + * @brief This file provides the user handshake and read functions to manage the following functionalities of + * the user loader. + * + Receiving handshake frames functions. + * + UART, I2C, SPI read blocking adapt functions. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_USER_HADNSHAKE_READ_H +#define McuMagicTag_USER_HADNSHAKE_READ_H + +/* Includes ------------------------------------------------------------------*/ +#include "uart.h" +#include "uart_ex.h" +#include "i2c.h" +#include "i2c_ex.h" +#include "spi.h" +#include "spi_ex.h" +#include "can.h" +#include "iocmg.h" + +BASE_StatusType UloaderReceiveHandShakeFrame(UART_Handle *handle, unsigned char *buf, unsigned int lenth, + unsigned char targetByte); +BASE_StatusType ULOADER_UART_ReadBlocking(UART_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout); +BASE_StatusType ULOADER_I2C_ReadBlocking(I2C_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned int timeout); +BASE_StatusType ULOADER_SPI_ReadBlocking(SPI_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_loader.c b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_loader.c new file mode 100644 index 0000000000000000000000000000000000000000..1af264d0e3c4ddf39903fd2bd32232bf20dcc264 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_loader.c @@ -0,0 +1,754 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_loader.c + * @author MCU Driver Team + * @brief This file provides the user loader structure and functions to manage the following functionalities of + * the user loader. + * + Initialization and de-initialization functions. + * + Handshake, command receiving, and command execution functions. + * + Read and write functions. + * + Atomic command function. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "user_handshake_read.h" +#include "user_loader.h" + +/* Macro definitions --------------------------------------------------------- */ +#define HANDSHAKE_FRAME_SIZE 9 + +#define DELAY_TIME 1000 +#define SYSTICK_MS_DIV 1000 +#define FRAME_CMD_OFFSET 0 +#define HEADER_COMMAND_HIGH 1 +#define HEADER_COMMAND_LOW 2 +#define COMMDNA_BASE_LENGHT 3 + +#define CRC_LAST_WIDTH 0x2 +#define ACK_FRAME_SIZE 6 +#define ACK_FRAME_TYPE_OFFSET 0 +#define ACK_FRAME_SEQ_OFFSET 1 +#define ACK_FRAME_INV_SEQ_OFFSET 2 +#define ACK_FRAME_RESULT_OFFSET 3 + +#define MAX_FRAME_DATA_SIZE 1024 /**< Max size of Frame Data Payload */ +#define MAX_FRAME_INDEX 254 + +#define FRAME_HEAD_TAIL_SIZE 5 +#define IMAGE_ADDR_OFFSET 1 /**< Image address offset field in header frame */ +#define IMAGE_SIZE_OFFSET 5 /**< Image size offset field in header frame */ +#define WRITE_ADDRESS_MUILYP 8 + +#define TRY_TIMES_WAIT 10 +#define DATA_HEAD_FRAME_SIZE 14 + +#define NEGOTIATE_FRAME_NUMS_POS 4 +#define NEGOTIATE_FRAME_SIZE_POS 8 + +#define ADDR_REMOVE_HIGH_POS 0xFFFFFF +#define OFFSET_LENGHT_THIRD 3 +#define OFFSET_LENGHT_SEVEN 7 +#define OFTHIRD 3 + +#define FLASH_ERASE_PAGE 1024 +#define ERASE_ADDRESS_MUILTYP 1024 + +#define BYTE_0 0 +#define BYTE_0_OFFSET 24 +#define BYTE_1 1 +#define BYTE_1_OFFSET 16 +#define BYTE_2 2 +#define BYTE_2_OFFSET 8 +#define BYTE_3 3 + +#define WAIT_ACK_FINISH_TIME 2 /* Wait until the ACK message is sent. */ + +#define PARAMETER_OFFSET_FLAG 1 +#define PARAMETER_OFFSET_COPY_START_ADDR 5 +#define PARAMETER_OFFSET_COPY_SIZE 9 +#define PARAMETER_OFFSET_BACKUP_ADDR 13 + +#define ULOADER_UART_BAND_RATE 115200 + +/** + * @brief Convert big-endian data to unsigned short. + * @param buf the buffer to store conversion data. + * @retval the value, unsigned short. + */ +static unsigned short ShiftToShort(unsigned char *buffer) +{ + if (buffer == NULL) { /* Null pointer check. */ + return 0; + } + return (((buffer[0] << 0x08) & 0xff00) + (buffer[1] & 0xff)); +} + +/** + * @brief Convert big-endian data to unsigned short. + * @param data the data of be converted. + * @param buf the buffer to store conversion data. + * @retval None. + */ +static void UShortToBigEndian(unsigned short data, unsigned char *const buf) +{ + unsigned int i = 0; + buf[i++] = (unsigned char)((data >> 0x8) & 0xFF); /* get the higher 8 bit of unsigned short */ + buf[i] = (unsigned char)(data & 0xFF); +} + +/** + * @brief Convert an unsigned int into big-endian data of the char type for storage. + * @param data the data of be converted. + * @param buf the buffer to store conversion data. + * @retval None. + */ +static void UInitToBigEndian(unsigned int data, unsigned char *const buf) +{ + unsigned int i = 0; + buf[i++] = (unsigned char)((data >> BYTE_0_OFFSET) & 0xFF); /* get the higher 8 bit of unsigned short */ + buf[i++] = (unsigned char)((data >> BYTE_1_OFFSET) & 0xFF); + buf[i++] = (unsigned char)((data >> BYTE_2_OFFSET) & 0xFF); + buf[i] = (unsigned char)(data & 0xFF); +} + +/** + * @brief Get the value of min. + * @param a the compare of value. + * @param b the compare of value. + * @retval the data of min. + */ +static inline unsigned int GetMinValue(unsigned int a, unsigned int b) +{ + return a < b ? a : b; +} + +/** + * @brief Combines two pieces of data of the char type into one piece of data of the short type. + * @param highByte the high byte. + * @param lowByte the low byte. + * @retval the data, unsigned short. + */ +static inline unsigned short MergeToUshort(unsigned char highByte, unsigned char lowByte) +{ + return (highByte << 0x8) + lowByte; /* Make highByte in the high 8 bit */ +} + +/** + * @brief Convert big-endian data to unsigned int. + * @param buf the buffer to be converted. + * @retval the data, unsigned int. + */ +static inline unsigned int BigEndianToUint(const unsigned char *buf) +{ + unsigned int i = 0; + unsigned int sum; + if (buf == NULL) { /* Null pointer check. */ + return 0; + } + sum = buf[i++] << BYTE_0_OFFSET; /* Highest 8 bits. */ + sum += buf[i++] << BYTE_1_OFFSET; + sum += buf[i++] << BYTE_2_OFFSET; + sum += buf[i++]; /* Lowest 8 bits. */ + return sum; +} + +static void UloaderUart0PinInit(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +static void UloaderUart0PinDeInit(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_GPIO0_3); /* Check function selection */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_GPIO0_4); /* Check function selection */ +} + +/** + * @brief Init the UART0 resources used by the user loader. + * @param handle User loader handle. + * @retval None. + */ +static void UloaderUart0Init(UART_Handle *handle) +{ + UloaderUart0PinInit(); + + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + handle->baseAddress = UART0; + + handle->baudRate = ULOADER_UART_BAND_RATE; /* The baudrate. */ + handle->dataLength = UART_DATALENGTH_8BIT; + handle->stopBits = UART_STOPBITS_ONE; + handle->parity = UART_PARITY_NONE; + handle->txMode = UART_MODE_BLOCKING; + handle->rxMode = UART_MODE_BLOCKING; + handle->fifoMode = BASE_CFG_ENABLE; + handle->fifoTxThr = UART_FIFODEPTH_SIZE6; + handle->fifoRxThr = UART_FIFODEPTH_SIZE6; + handle->hwFlowCtr = BASE_CFG_DISABLE; + handle->handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + handle->handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(handle); + HAL_UART_EnableBaudDetectionEx(handle); /* Enable baud auto detect. */ +} + +/** + * @brief Init the CRC resources used by the user loader. + * @param handle User loader handle. + * @retval None. + */ +static void UloaderCrcInit(CRC_Handle *handle) +{ + HAL_CRG_IpEnableSet(CRC_BASE, IP_CLK_ENABLE); /* Enable the CRG of CRC modular. */ + + handle->baseAddress = CRC; + handle->inputDataFormat = CRC_MODE_BIT8; /* Input data length is 8 byte. */ + handle->polyMode = CRC16_1021_POLY_MODE; + handle->initValueType = TYPE_CRC_INIT_VALUE_00; + handle->resultXorValueType = TYPE_CRC_XOR_VALUE_00; + handle->reverseEnableType = REVERSE_INPUT_FALSE_OUTPUT_FALSE; + handle->xorEndianEnbaleType = DISABLE_XOR_ENABLE_LSB; + HAL_CRC_Init(handle); /* Init CRC. */ +} + +/** + * @brief Init the flash resources used by the user loader. + * @param handle User loader handle. + * @retval None. + */ +static void UloaderFlashInit(FLASH_Handle *handle) +{ + HAL_CRG_IpEnableSet(EFC_BASE, BASE_CFG_SET); /* Enable the CRG of EFC modular. */ + handle->baseAddress = EFC; + handle->peMode = FLASH_PE_OP_BLOCK; + HAL_FLASH_Init(handle); /* Init flash. */ +} + +/** + * @brief Init the module resources of user loader. + * @param handle User loader handle. + * @retval BASE status type: OK, ERROR. + */ +void ULOADER_Init(ULOADER_Handle *handle) +{ + /* Reset crc\uart\flash */ + HAL_CRG_IpClkResetSet(CRC_BASE, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(UART0_BASE, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(EFC_BASE, BASE_CFG_SET); + /* Init crc\uart\flash */ + UloaderFlashInit(handle->flash); + UloaderUart0Init(handle->comHandle); /* If the communication protocols are different, change the value here. */ + UloaderCrcInit(handle->crc); +} + +/** + * @brief Deinit the module resources of user loader. + * @param handle User loader handle. + * @retval BASE status type: OK, ERROR. + */ +void ULOADER_DeInit(ULOADER_Handle *handle) +{ + /* Reset crc\uart\flash */ + HAL_CRG_IpClkResetSet(handle->comHandle, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(handle->crc, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(handle->flash, BASE_CFG_SET); + UloaderUart0PinDeInit(); +} + +/** + * @brief Handshake negotiation function. + * @param handle User loader handle. + * @param timeout the value of timeout. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_HandShake(ULOADER_Handle *handle, unsigned int timeout) +{ + unsigned int preTick = DCL_SYSTICK_GetTick(); /* Get the current tick. */ + unsigned int curTick; + unsigned long long delta = 0; + /* Get the timeout of tick */ + unsigned long long targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SYSTICK_MS_DIV * timeout; + + unsigned char buf[HANDSHAKE_FRAME_SIZE] = {0}; + BASE_StatusType ret; + unsigned short receiveCrc; + unsigned short calculateCrc; + + while (true) { /* Receive data cyclically until timeout. */ + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* Check timeout. */ + return BASE_STATUS_TIMEOUT; + } + preTick = curTick; + + /* Response data in the configuration success state. */ + buf[ACK_FRAME_TYPE_OFFSET] = XACK; + buf[ACK_FRAME_SEQ_OFFSET] = 0x00; + buf[ACK_FRAME_INV_SEQ_OFFSET] = 0xff; + buf[ACK_FRAME_RESULT_OFFSET] = ACK_SUCCESS; + calculateCrc = HAL_CRC_Calculate(handle->crc, buf, ACK_FRAME_SIZE - 0x02); /* 2: crc length. */ + UShortToBigEndian(calculateCrc, &buf[ACK_FRAME_SIZE - 0x02]); + /* Receive handshake frame data. */ + ret = UloaderReceiveHandShakeFrame(handle->comHandle, buf, LENGTH_XHDSHK_FRAME, XHDSHK); + if (ret != BASE_STATUS_OK) { + continue; + } + /* Data Crc check. */ + receiveCrc = ShiftToShort(&buf[ACK_FRAME_SIZE + 0x01]); /* The offset of crc data. */ + calculateCrc = HAL_CRC_Calculate(handle->crc, buf, ACK_FRAME_SIZE + 0x01); + if (receiveCrc != calculateCrc) { + continue; + } + ULOADER_Ack(handle, ACK_SUCCESS, 0); + return BASE_STATUS_OK; + } +} + +/** + * @brief Receiving commands function. + * @param handle User loader handle. + * @param receiveCmd User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_ReceiveCmd(ULOADER_Handle *handle, ULOADER_Cmd *receiveCmd) +{ + /* receive command header and command. */ + unsigned char recvBuffer[LENGTH_XHEAD_FRAME] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; /* command size. */ + unsigned short cmdLength; + while (1) { + /* receive command header. */ + if (ULOADER_ReadDate(handle, recvBuffer, LENGTH_XHEAD_FRAME, XCMD, DELAY_TIME) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + if (recvBuffer[FRAME_CMD_OFFSET] != XCMD) { + ULOADER_Ack(handle, ACK_FAIL, 0); + return BASE_STATUS_ERROR; + } + if (recvBuffer[HEADER_COMMAND_HIGH] == 0xFF) { /* 0xFF: Judgement trail frame */ + ULOADER_Ack(handle, ACK_SUCCESS, XTAIL); + return BASE_STATUS_ERROR; + } + /* Command Header Check */ + ULOADER_Ack(handle, ACK_SUCCESS, 0); + /* Receive the boot cmd */ + cmdLength = MergeToUshort(recvBuffer[HEADER_COMMAND_HIGH], recvBuffer[HEADER_COMMAND_LOW]); + cmdLength = cmdLength + COMMDNA_BASE_LENGHT; /* 3:head + 2 crc */ + if (ULOADER_ReadDate(handle, (unsigned char *)receiveCmd, cmdLength, XKEY, DELAY_TIME) != BASE_STATUS_OK) { + ULOADER_Ack(handle, ACK_FAIL, receiveCmd->type); + return BASE_STATUS_ERROR; + } + if (receiveCmd->type != XKEY) { /* Received data is not destination bytes. */ + ULOADER_Ack(handle, ACK_FAIL, 0); + return BASE_STATUS_ERROR; + } + receiveCmd->type = receiveCmd->rcvBuf[0]; + receiveCmd->rcvBufLength = cmdLength; + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Command execution function. + * @param handle User loader handle. + * @param execCmd User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CommandExec(ULOADER_Handle *handle, ULOADER_Cmd *execCmd) +{ + /* Funciton transfer table. */ + switch (execCmd->type) { + case ATOMIS_WRITE: /* Write command */ + if (ULOADER_CMD_Write(handle, execCmd) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + case ATOMIS_ERASE: /* Erase command */ + if (ULOADER_CMD_Erase(handle, execCmd) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + case ATOMIS_UPDATE: /* Updata command */ + if (ULOADER_CMD_Update(handle, execCmd) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + case ATOMIS_RESET: /* Reset command */ + if (ULOADER_CMD_Reset(handle) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + default: + break; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Normalized write data. + * @param handle User loader handle. + * @param wData the buffer of receive data. + * @param dataSize the size of need receive. + * @param timeout the value of timeout. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_WriteDate(ULOADER_Handle *handle, unsigned char *wData, unsigned int dataSize, + unsigned int timeout) +{ + /* CRC produce. */ + unsigned int crc; + crc = HAL_CRC_Calculate(handle->crc, wData, dataSize - CRC_LAST_WIDTH); + UShortToBigEndian(crc, &wData[dataSize - CRC_LAST_WIDTH]); + + /* Send Data. */ + if (handle->mode == COMMUNICATION_UART) { + return HAL_UART_WriteBlocking((UART_Handle *)handle->comHandle, wData, dataSize, timeout); + } else if (handle->mode == COMMUNICATION_I2C) { + return HAL_I2C_SlaveWriteBlocking((I2C_Handle *)handle->comHandle, wData, dataSize, timeout); + } else if (handle->mode == COMMUNICATION_SPI) { + return HAL_SPI_WriteBlocking((SPI_Handle *)handle->comHandle, wData, dataSize, timeout); + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Normalized read data. + * @param handle User loader handle. + * @param rData the buffer of receive data. + * @param dataSize the size of need receive. + * @param targetByte the target byte. + * @param timeout the value of timeout. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_ReadDate(ULOADER_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned short targetByte, unsigned int timeout) +{ + BASE_StatusType ret; + unsigned int crcReceive = 0; + unsigned int crcCalculate = 0; + + /* Check the communication mode. */ + if (handle->mode == COMMUNICATION_UART) { + ret = ULOADER_UART_ReadBlocking((UART_Handle *)handle->comHandle, rData, dataSize, targetByte, timeout); + } else if (handle->mode == COMMUNICATION_I2C) { + ret = ULOADER_I2C_ReadBlocking((I2C_Handle *)handle->comHandle, rData, dataSize, timeout); + } else if (handle->mode == COMMUNICATION_SPI) { + ret = ULOADER_SPI_ReadBlocking((SPI_Handle *)handle->comHandle, rData, dataSize, targetByte, timeout); + } else { + return BASE_STATUS_ERROR; /* Illegal communication mode. */ + } + + /* CRC Check */ + if (ret == BASE_STATUS_OK) { + crcReceive = MergeToUshort(rData[dataSize - 0x2], rData[dataSize - 1]); + crcCalculate = HAL_CRC_Calculate(handle->crc, rData, dataSize - CRC_LAST_WIDTH); + if (crcReceive == crcCalculate) { + return BASE_STATUS_OK; + } + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Answering host. + * @param handle User loader handle. + * @param status answering status. + * @param index the index of frame to answer. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_Ack(ULOADER_Handle *handle, ACK_Status status, unsigned char index) + +{ + unsigned char frame[ACK_FRAME_SIZE]; + unsigned int sequence = index; + + /* Construct the Frame */ + frame[ACK_FRAME_TYPE_OFFSET] = XACK; + frame[ACK_FRAME_SEQ_OFFSET] = index; + frame[ACK_FRAME_INV_SEQ_OFFSET] = (unsigned char)(~sequence & 0xFF); + frame[ACK_FRAME_RESULT_OFFSET] = status; + + /* Write frame to host. */ + return ULOADER_WriteDate(handle, frame, ACK_FRAME_SIZE, DELAY_TIME); +} + +/** + * @brief Receives file head date from the host. + * @param handle User loader handle. + * @param buf the buffer of receive date. + * @param size the size of receive. + * @param perFrameSize Size of each frame to be transmitted. + * @param tryTimes retry Times After Failure. + * @retval BASE status type: OK, ERROR. + */ +static BASE_StatusType ReceiveFileHead(ULOADER_Handle *handle, unsigned char *buf, unsigned int size, + unsigned int *perFrameSize, unsigned char *tryTimes) +{ + unsigned int frameNums = 0; + unsigned char answer = 0; + unsigned int tempTryTime = 0; + + /* Number of retransmission times. */ + while (tempTryTime < TRY_TIMES_WAIT) { + /* Read file heade data. */ + if (ULOADER_ReadDate(handle, buf, DATA_HEAD_FRAME_SIZE, XHEAD, DELAY_TIME) != BASE_STATUS_OK) { + tempTryTime++; + continue; + } + + /* Negotiate frame size */ + frameNums = BigEndianToUint(&buf[NEGOTIATE_FRAME_NUMS_POS]); + if (frameNums > MAX_FRAME_INDEX) { + tempTryTime++; + ULOADER_Ack(handle, ACK_FAIL, 0); + continue; + } + + *perFrameSize = BigEndianToUint(&buf[NEGOTIATE_FRAME_SIZE_POS]); + if (*perFrameSize > MAX_FRAME_DATA_SIZE || *perFrameSize == 0) { + tempTryTime++; + ULOADER_Ack(handle, ACK_FAIL, 0); + continue; + } + + answer = size % *perFrameSize == 0 ? 0 : 1; + if (((size / *perFrameSize) + answer) != frameNums) { /* Data length integrity check. */ + /* Negotiate fail */ + tempTryTime++; + ULOADER_Ack(handle, ACK_FAIL, 0); + continue; + } + ULOADER_Ack(handle, ACK_SUCCESS, 0); + *tryTimes = tempTryTime; + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Receives data from the host. + * @param handle User loader handle. + * @param buf the buffer of receive date. + * @param remainLen Remaining transmission data volume. + * @param perFrameSize Size of each frame to be transmitted. + * @param addr the target of flash address. + * @retval BASE status type: OK, ERROR. + */ +static BASE_StatusType ReceiveFileDate(ULOADER_Handle *handle, unsigned char *buf, unsigned int remainLen, + unsigned int perFrameSize, unsigned int addr) +{ + BASE_StatusType ret; + unsigned char oldIdIndex = 0; + unsigned char tryTimes = 0; + unsigned int rcvLen; + unsigned int targetAddr = addr; + unsigned int targetremainLen = remainLen; + + /* Number of retransmission times. */ + while (tryTimes < TRY_TIMES_WAIT) { + /* Gets the minimum number of transfers for the last receive processing. */ + rcvLen = GetMinValue(targetremainLen, perFrameSize); + buf[1] = 0; + if (targetremainLen > 0) { /* There is still data to be received and continue to receive data. */ + if (ULOADER_ReadDate(handle, buf, rcvLen + FRAME_HEAD_TAIL_SIZE, XDATA, DELAY_TIME) != BASE_STATUS_OK) { + ULOADER_Ack(handle, ACK_FAIL, buf[1]); + tryTimes++; + continue; + } + } else { + /* There is no data to be received, and received file tail frame. */ + if (ULOADER_ReadDate(handle, buf, rcvLen + FRAME_HEAD_TAIL_SIZE, XTAIL, DELAY_TIME) != BASE_STATUS_OK) { + ULOADER_Ack(handle, ACK_FAIL, buf[1]); + tryTimes++; + continue; + } + } + /* Check the Sequence of Received Data Packets. */ + if ((buf[1] - oldIdIndex) != 1) { + ULOADER_Ack(handle, ACK_SUCCESS, oldIdIndex); + continue; + } + + /* Data info and trail judgement. */ + if (buf[0] == XTAIL && targetremainLen <= 0) { + /* Ack file trail frame. */ + ULOADER_Ack(handle, ACK_SUCCESS, buf[1]); + return BASE_STATUS_OK; + } + + /* Writes the received data to the flash memory. */ + ret = HAL_FLASH_WriteBlocking(handle->flash, (unsigned int)(buf + OFFSET_LENGHT_THIRD), + targetAddr & ADDR_REMOVE_HIGH_POS, + ((rcvLen + OFFSET_LENGHT_SEVEN) >> OFFSET_LENGHT_THIRD) << OFFSET_LENGHT_THIRD); + if (ret != BASE_STATUS_OK) { + tryTimes++; + ULOADER_Ack(handle, ACK_FAIL, buf[1]); /* Flash write error */ + continue; + } + + tryTimes = 0; /* Reset times. */ + ULOADER_Ack(handle, ACK_SUCCESS, buf[1]); + /* ID update and check. */ + oldIdIndex = buf[1]; + targetAddr += rcvLen; + targetremainLen -= rcvLen; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Write the flash page by atomic write command. + * @param handle User loader handle. + * @param command User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Write(ULOADER_Handle *handle, ULOADER_Cmd *command) +{ + BASE_StatusType ret; + unsigned int addr; + unsigned int size; + unsigned char tryTimes = 0; + unsigned int remainLen; + unsigned int perFrameSize = 0; + unsigned char buf[MAX_FRAME_DATA_SIZE + FRAME_HEAD_TAIL_SIZE]; + + /* Step1: Check the address validity. */ + addr = BigEndianToUint(&command->rcvBuf[IMAGE_ADDR_OFFSET]); /* Get the address of erase. */ + size = BigEndianToUint(&command->rcvBuf[IMAGE_SIZE_OFFSET]); /* Get the size of erase. */ + /* Address must be an integer multiple of 8, and size cannot be 0. */ + if (((addr % WRITE_ADDRESS_MUILYP) != 0) || size == 0) { + return BASE_STATUS_ERROR; + } + ULOADER_Ack(handle, ACK_SUCCESS, 0); + + /* Step2:Receive the file header frame. */ + remainLen = size; + ret = ReceiveFileHead(handle, buf, size, &perFrameSize, &tryTimes); + if (tryTimes == TRY_TIMES_WAIT || ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + /* Step3:Received data is written into the flash memory. */ + ret = ReceiveFileDate(handle, buf, remainLen, perFrameSize, addr); + return ret; +} + +/** + * @brief Erase the flash page by atomic erase command. + * @param handle User loader handle. + * @param command User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Erase(ULOADER_Handle *handle, ULOADER_Cmd *command) +{ + BASE_StatusType ret; + unsigned int addr; + unsigned int size; + + addr = BigEndianToUint(&command->rcvBuf[IMAGE_ADDR_OFFSET]); /* Get the address of erase. */ + size = BigEndianToUint(&command->rcvBuf[IMAGE_SIZE_OFFSET]); /* Get the size of erase. */ + /* Address must be an integer multiple of 1024. */ + if (((addr % ERASE_ADDRESS_MUILTYP) != 0)) { + return BASE_STATUS_ERROR; + } + /* The size must be an integer multiple of 1024 and not equal to 0. */ + if ((size == 0) || ((size % ERASE_ADDRESS_MUILTYP) != 0)) { + return BASE_STATUS_ERROR; + } + + /* Erase flash page. */ + ret = HAL_FLASH_EraseBlocking(handle->flash, FLASH_ERASE_MODE_PAGE, addr & ADDR_REMOVE_HIGH_POS, + size / FLASH_ERASE_PAGE); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + ULOADER_Ack(handle, ACK_SUCCESS, 0); + return BASE_STATUS_OK; +} + +/** + * @brief Updating OTA Parameters by atomic update command. + * @param handle User loader handle. + * @param command User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Update(ULOADER_Handle *handle, ULOADER_Cmd *command) +{ + BASE_StatusType ret; + unsigned char buf[FLASH_ERASE_PAGE]; + unsigned int upDateFlag; + unsigned int copyStartAddr; + unsigned int copySize; + unsigned int appBakAddr; + + upDateFlag = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_FLAG]); /* Get the firmware update flag. */ + copyStartAddr = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_COPY_START_ADDR]); /* Get the copy address. */ + copySize = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_COPY_SIZE]); /* Get the size of new firmware. */ + appBakAddr = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_BACKUP_ADDR]); /* Get the firmware backup address. */ + /* Read the flash page of upgrade parameters. */ + ret = HAL_FLASH_Read(handle->flash, (PARAMETER_ADDR - FLASH_READ_BASE), FLASH_ERASE_PAGE, buf, FLASH_ERASE_PAGE); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + /* Erase the flash page of upgrade parameters. */ + ret = HAL_FLASH_EraseBlocking(handle->flash, FLASH_ERASE_MODE_PAGE, PARAMETER_ADDR & ADDR_REMOVE_HIGH_POS, 1); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + /* Modify the parameter and assign a value. */ + UInitToBigEndian(upDateFlag, &buf[PARAMETER_OFFSET_FLAG - 0x01]); + UInitToBigEndian(copyStartAddr, &buf[PARAMETER_OFFSET_COPY_START_ADDR - 0x01]); + UInitToBigEndian(copySize, &buf[PARAMETER_OFFSET_COPY_SIZE - 0x01]); + UInitToBigEndian(appBakAddr, &buf[PARAMETER_OFFSET_BACKUP_ADDR - 0x01]); + /* Write the flash page of upgrade parameters. */ + ret = HAL_FLASH_WriteBlocking(handle->flash, (unsigned int)buf, PARAMETER_ADDR & ADDR_REMOVE_HIGH_POS, + FLASH_ERASE_PAGE); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + ULOADER_Ack(handle, ACK_SUCCESS, 0); + return BASE_STATUS_OK; +} + +/** + * @brief MCU reset by atomic reset command. + * @param handle User loader handle. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Reset(ULOADER_Handle *handle) +{ + ULOADER_Ack(handle, ACK_SUCCESS, 0); + BASE_FUNC_DELAY_MS(WAIT_ACK_FINISH_TIME); /* Wait until the ACK message is sent. */ + BASE_FUNC_SoftReset(); + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_loader.h b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_loader.h new file mode 100644 index 0000000000000000000000000000000000000000..20cc48122bc2edab738ec7d8c63e4bef01dd1532 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_cross_upgrade_app/user_loader/user_loader.h @@ -0,0 +1,127 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_loader.h + * @author MCU Driver Team + * @brief This file provides the user loader structure and functions to manage the following functionalities of + * the user loader. + * + Initialization and de-initialization functions. + * + Handshake, command receiving, and command execution functions. + * + Read and write functions. + * + Atomic command function. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_USER_LOADER_H +#define McuMagicTag_USER_LOADER_H + +/* Includes ------------------------------------------------------------------*/ +#include "flash.h" +#include "crc.h" +#include "uart.h" +#include "spi.h" +#include "i2c.h" +#include "can.h" +#include "crg.h" + +/* Macro definitions --------------------------------------------------------- */ +#define PARAMETER_ADDR 0x301FC00 +#define CMD_PAYLOAD_MAX 30 /**< Command payload length */ + +/* Frame header flag parameter. */ +#define XHDSHK 0xEB +#define XHEAD 0xFE +#define XDATA 0xDA +#define XTAIL 0xED +#define XACK 0xCB +#define XCMD 0xAB +#define XKEY 0xCD +#define XVER 0xCE + +/* The length of different frame. */ +#define LENGTH_XHDSHK_FRAME 9 +#define LENGTH_XHEAD_FRAME 5 +#define LENGTH_XCMD_FRAME 12 +#define LENGTH_XHDATA_FRAME 11 +#define LENGTH_XDATA_ADD_FRAME 5 +#define LENGTH_XEND_FRAME 6 +#define LENGTH_ACK_FRAME 6 + +/** + * @brief Atomis commands enumeration definition. + */ +enum { + ATOMIS_WRITE = 0xD2, /**< 0xD2: Download Image */ + ATOMIS_ERASE = 0xE4, /**< 0xE4: Get version information. */ + ATOMIS_RESET = 0x87, /**< 0x87: Reset MCU. */ + ATOMIS_UPDATE = 0x90, /**< 0x90: Update parameter settings. */ +}; + +/** + * @brief Communication mode enumeration definition. + */ +typedef enum { + COMMUNICATION_UART = 0, + COMMUNICATION_I2C = 1, + COMMUNICATION_SPI = 2, + COMMUNICATION_CAN = 3, +} COMMUNICATION_Mode; + +/** + * @brief Answering status enumeration definition. + */ +typedef enum { + ACK_FAIL = 0xA5, + ACK_SUCCESS = 0x5A, +} ACK_Status; + +/** + * @brief User loader command frame structure definition. + */ +typedef struct { + unsigned char type; /**< Command Type. */ + unsigned char rcvBuf[CMD_PAYLOAD_MAX]; /**< Command Buf All Command contents. */ + unsigned short rcvBufLength; /**< Buffer length. */ +} ULOADER_Cmd; + +/** + * @brief Module handle structure definition. + */ +typedef struct _ULOADER_Handle { + void *comHandle; /**< Register base address. */ + FLASH_Handle *flash; + CRC_Handle *crc; + COMMUNICATION_Mode mode; +} ULOADER_Handle; + +void ULOADER_Init(ULOADER_Handle *handle); +void ULOADER_DeInit(ULOADER_Handle *handle); +BASE_StatusType ULOADER_HandShake(ULOADER_Handle *handle, unsigned int timeout); +BASE_StatusType ULOADER_ReceiveCmd(ULOADER_Handle *handle, ULOADER_Cmd *receiveCmd); +BASE_StatusType ULOADER_CommandExec(ULOADER_Handle *handle, ULOADER_Cmd *execCmd); + +BASE_StatusType ULOADER_WriteDate(ULOADER_Handle *handle, unsigned char *wData, unsigned int dataSize, + unsigned int timeout); +BASE_StatusType ULOADER_ReadDate(ULOADER_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned short targetByte, unsigned int timeout); +BASE_StatusType ULOADER_Ack(ULOADER_Handle *handle, ACK_Status status, unsigned char index); + +BASE_StatusType ULOADER_CMD_Write(ULOADER_Handle *handle, ULOADER_Cmd *command); +BASE_StatusType ULOADER_CMD_Erase(ULOADER_Handle *handle, ULOADER_Cmd *command); +BASE_StatusType ULOADER_CMD_Update(ULOADER_Handle *handle, ULOADER_Cmd *command); +BASE_StatusType ULOADER_CMD_Reset(ULOADER_Handle *handle); +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_upgrade_boot/init/main.c b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..219dd7c1c6756779c3f591b9640c5d2b71e2257c --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/init/main.c @@ -0,0 +1,57 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +#include "user_boot.h" +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + UserBoot(); + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_upgrade_boot/init/main.h b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..56b768a21b756a577b83329fc3db29c94aa7022a --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/init/main.h @@ -0,0 +1,49 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "crg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +void SystemInit(void); +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); + +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_upgrade_boot/init/system_init.c b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..fd748849e1b6a3e15a36ad15778c857731928b35 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/init/system_init.c @@ -0,0 +1,52 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +void SystemInit(void) +{ + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_upgrade_boot/readme.md b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..abd8792ffd3b2103a34d2097cebc376d4aa1616a --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/readme.md @@ -0,0 +1,23 @@ +# MCU芯片 OTA Copy Upgrade Boot(拷贝升级Boot)参考示例 +## 关键字: OTA,Copy upgrade,升级,Boot + +**【功能描述】** ++ OTA是一种通过无线通信实现远程更新设备固件的方法。MCU OTA为通过外部具有无线通信的器件接收新固件数据,外部器件将新固件数据通过MCU串行通信接口发送给MCU,实现固件更新。MCU的OTA主要工作是将串行通信接口接收的新固件数据更新到用户指定的程序区,完成固件的升级。 ++ OTA的拷贝升级在功能上包括1个user boot flash分区、1个APP运行flash分区、1个APP备份flash分区、1个参数存储flash区。user boot flash分区具有判断、拷贝、跳转功能。APP运行flash分区具有升级功能、业务逻辑处理功能。APP备份flash分区用于存储新的固件,不运行。参数存储flash区用于存储升级相关配置参数。User boot分区与APP运行分区在flash上进行严格划分,由boot根据参数存储区的参数配置决定是否将APP备份flash分区数据拷贝到APP运行flash分区,并跳转执行。 ++ flash空间使用: + 1.boot flash分区:起始地址0x3000000,大小16K; + 2.参数存储flash分区:起始地址0x301FC00,大小1K; + +**【示例配置】** + ++ 配置flash阻塞方式进行读取参数存储区数据,用于判断boot是否执行APP数据拷贝和跳转地址。 + + +**【示例效果】** ++ 当用户复位芯片后,MCU首先会执行boot程序,boot读取参数存储区数据,判断获取跳转APP运行地址和拷贝标志,进行拷贝(根据拷贝标志决定)、跳转。 + +**【注意事项】** ++ 升级模型需开启中断服务函数基地址不锁定宏,保证APP中断正常执行。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_upgrade_boot/user_boot/user_boot.c b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/user_boot/user_boot.c new file mode 100644 index 0000000000000000000000000000000000000000..89033104d21755dbe8bd9cd7d90128b6d9156e33 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/user_boot/user_boot.c @@ -0,0 +1,167 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_boot.c + * @author MCU Driver Team + * @brief This file provides the user boot function. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "flash.h" +#include "crg.h" +#include "user_boot.h" + +/* Macro definitions --------------------------------------------------------- */ +#define USER_UPDATE_FLAG 0x01 +#define USER_PARAMTER_FLASH_START 0x301FC00 +#define USER_APP_RUN_INIT_ADDR 0x3004000 + +#define USER_LOADER_PARAMETER_SIZE 1024 +#define USER_LOADER_PARAMETER_PAGE_NUM 1 + +#define UPDATA_APP_FLAGE_OFFSET 0 +#define APP_RUN_START_ADDR_OFFSET 4 +#define APP_RUN_SIZE_OFFSET 8 +#define APP_BAK_START_ADDR_OFFSET 12 + +#define EFLASH_MAGIC_NUMBER 0xA37E95BD +#define EFLASH_MAGIC_OFFSET 0x04 + +#define BYTE_0 0 +#define BYTE_0_OFFSET 24 +#define BYTE_1 1 +#define BYTE_1_OFFSET 16 +#define BYTE_2 2 +#define BYTE_2_OFFSET 8 +#define BYTE_3 3 + +/** + * @brief User boot function. + * @param flash handle FLASH handle. + * @retval None. + */ +static void FlashInit(FLASH_Handle *flash) +{ + HAL_CRG_IpEnableSet(EFC_BASE, BASE_CFG_ENABLE); /* Enable the CRG of EFC modular. */ + flash->baseAddress = EFC; + flash->peMode = FLASH_PE_OP_BLOCK; + HAL_FLASH_Init(flash); /* Init flash. */ +} + +/** + * @brief Gets the value of a word in a char array. + * @param buffer the data array. + * @retval the value, unit : word. + */ +static unsigned int GetWordValue(unsigned char *buffer) +{ + unsigned int ret; + unsigned int i = 0; + if (buffer == NULL) { /* Null pointer check. */ + return 0; + } + + ret = buffer[i++] << BYTE_0_OFFSET; /* Highest 8 bits. */ + ret += buffer[i++] << BYTE_1_OFFSET; + ret += buffer[i++] << BYTE_2_OFFSET; + ret += buffer[i++]; + return ret; +} + +/** + * @brief Jump function. + * @param addr the target address of jump. + * @retval None. + */ +static void UserLoaderJump(unsigned int addr) +{ + /* Judgement flash empty */ + unsigned int *magic = (unsigned int *)(void *)addr; + if (*magic != EFLASH_MAGIC_NUMBER) { + while (1) { + ; + } + } + /* Jump to app run start address. */ + (*(void(*)(void))(addr + EFLASH_MAGIC_OFFSET))(); +} + +/** + * @brief User boot function. + * @param None. + * @retval None. + */ +void UserBoot(void) +{ + SystemInit(); /* Init peripheral module */ + unsigned char loaderParameter[USER_LOADER_PARAMETER_SIZE] = {0}; + BASE_StatusType ret; + FLASH_Handle flash; + + unsigned int updateFlage; + unsigned int appRunStartAddr; + unsigned int appRunSize; + unsigned int appBakStartAddr; + + /* Init flash */ + FlashInit(&flash); + + /* Get the flage of user loader. */ + HAL_FLASH_Read(&flash, USER_PARAMTER_FLASH_START - FLASH_READ_BASE, USER_LOADER_PARAMETER_SIZE, + loaderParameter, USER_LOADER_PARAMETER_SIZE); + /* Get the address of app run. */ + appRunStartAddr = GetWordValue(&loaderParameter[APP_RUN_START_ADDR_OFFSET]); + if (appRunStartAddr < USER_APP_RUN_INIT_ADDR || appRunStartAddr == 0xFFFFFFFF) { /* Check the address validity. */ + appRunStartAddr = USER_APP_RUN_INIT_ADDR; + } + /* Get the firmware update status. */ + updateFlage = GetWordValue(&loaderParameter[UPDATA_APP_FLAGE_OFFSET]); + /* Need to update app run. */ + if (updateFlage == USER_UPDATE_FLAG) { + appRunSize = GetWordValue(&loaderParameter[APP_RUN_SIZE_OFFSET]); + appBakStartAddr = GetWordValue(&loaderParameter[APP_BAK_START_ADDR_OFFSET]); + /* Erase original firmware and prepare to move new firmware. */ + unsigned int eraseNum = appRunSize / FLASH_ONE_PAGE_SIZE; + eraseNum += ((appRunSize % FLASH_ONE_PAGE_SIZE) == 0) ? 0 : 1; + ret = HAL_FLASH_EraseBlocking(&flash, FLASH_ERASE_MODE_PAGE, (appRunStartAddr - FLASH_READ_BASE), eraseNum); + if (ret != BASE_STATUS_OK) { + UserLoaderJump(appRunStartAddr); + } + /* Copy data from app bak flash to app run flash. */ + ret = HAL_FLASH_WriteBlocking(&flash, appBakStartAddr, appRunStartAddr, appRunSize); + if (ret != BASE_STATUS_OK) { + UserLoaderJump(appRunStartAddr); + } + + /* Clear APP update flage */ + loaderParameter[0x03] = 0; /* 0x03 is offset of flage of update. */ + ret = HAL_FLASH_EraseBlocking(&flash, FLASH_ERASE_MODE_PAGE, (USER_PARAMTER_FLASH_START - FLASH_READ_BASE), + USER_LOADER_PARAMETER_PAGE_NUM); + if (ret != BASE_STATUS_OK) { + UserLoaderJump(appRunStartAddr); + } + /* copy data from app bak flash to app run flash. */ + ret = HAL_FLASH_WriteBlocking(&flash, (unsigned int)(uintptr_t)loaderParameter, USER_PARAMTER_FLASH_START, + USER_LOADER_PARAMETER_SIZE); + if (ret != BASE_STATUS_OK) { + UserLoaderJump(appRunStartAddr); + } + } + + /* Jump to app run start address. */ + UserLoaderJump(appRunStartAddr); +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_copy_upgrade_boot/user_boot/user_boot.h b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/user_boot/user_boot.h new file mode 100644 index 0000000000000000000000000000000000000000..6c3bb541038b0711d43fce5630dfb7eb58f57564 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_copy_upgrade_boot/user_boot/user_boot.h @@ -0,0 +1,32 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_boot.h + * @author MCU Driver Team + * @brief This file provides the user boot function. + */ + +/* Includes ------------------------------------------------------------------*/ +#ifndef McuMagicTag_USER_BOOT_H +#define McuMagicTag_USER_BOOT_H + +#include "main.h" +#include "flash.h" + +void UserBoot(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_boot/init/main.c b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..219dd7c1c6756779c3f591b9640c5d2b71e2257c --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/init/main.c @@ -0,0 +1,57 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +#include "user_boot.h" +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + UserBoot(); + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_boot/init/main.h b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..3b6b7ed6d38cb5f49e30cca84c560b1b440fc53e --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/init/main.h @@ -0,0 +1,48 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "crg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +void SystemInit(void); +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_boot/init/system_init.c b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..fd748849e1b6a3e15a36ad15778c857731928b35 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/init/system_init.c @@ -0,0 +1,52 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +void SystemInit(void) +{ + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_boot/readme.md b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..dc275e7245d3ab12e140a949973f92d1ac6c5342 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/readme.md @@ -0,0 +1,23 @@ +# MCU芯片 OTA Cross Upgrade Boot(交叉升级Boot)参考示例 +## 关键字: OTA,cross upgrade,升级,Boot + +**【功能描述】** ++ OTA是一种通过无线通信实现远程更新设备固件的方法。MCU OTA为通过外部具有无线通信的器件接收新固件数据,外部器件将新固件数据通过MCU串行通信接口发送给MCU,实现固件更新。MCU的OTA主要工作是将串行通信接口接收的新固件数据更新到用户指定的程序区,完成固件的升级。 ++ OTA的交叉升级在功能上包括1个user boot flash分区、2个APP运行flash分区、1个参数存储flash区。user boot flash分区具有判断、跳转功能。APP运行flash分区具有升级功能、业务逻辑处理功能。参数存储flash区用于存储升级相关配置参数。User boot分区与APP运行分区在flash上进行严格划分,由boot根据参数存储区的参数配置决定跳转到哪个APP运行。 ++ flash空间使用: + 1.boot flash分区:起始地址0x3000000,大小16K; + 2.参数存储flash分区:起始地址0x301FC00,大小1K; + +**【示例配置】** + ++ 配置flash阻塞方式进行读取参数存储区数据,用于判断boot跳转APP地址。 + + +**【示例效果】** ++ 当用户复位芯片后,MCU首先会执行boot程序,boot读取参数存储区数据,判断获取跳转APP运行地址,进行跳转。 + +**【注意事项】** ++ 升级模型需开启中断服务函数基地址不锁定宏,保证APP中断正常执行。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_boot/user_boot/user_boot.c b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/user_boot/user_boot.c new file mode 100644 index 0000000000000000000000000000000000000000..1a8a924de7b28f0de4f478100f194496b7bb3d2a --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/user_boot/user_boot.c @@ -0,0 +1,141 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_boot.c + * @author MCU Driver Team + * @brief This file provides the user boot function. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "flash.h" +#include "crg.h" +#include "user_boot.h" + +#define UASE_APP0_RUN_FLAG 0x00 +#define UASE_APP1_RUN_FLAG 0x01 + +#define USER_PARAMTER_FLASH_START 0x301FC00 +#define USER_APP_RUN_INIT_ADDR 0x3004000 + +#define USER_LOADER_PARAMETER_SIZE 1024 +#define USER_LOADER_PARAMETER_PAGE_NUM 1 + +#define JUMP_APP_FLAGE_OFFSET 0 +#define APP0_RUN_START_ADDR_OFFSET 4 +#define APP1_RUN_START_ADDR_OFFSET 8 + +#define EFLASH_MAGIC_NUMBER 0xA37E95BD +#define EFLASH_MAGIC_OFFSET 0x04 +/* + * byte and bit offset in unsigned int + */ +#define BYTE_0 0 +#define BYTE_0_OFFSET 24 +#define BYTE_1 1 +#define BYTE_1_OFFSET 16 +#define BYTE_2 2 +#define BYTE_2_OFFSET 8 +#define BYTE_3 3 + +/** + * @brief Gets the value of a word in a char array. + * @param buffer the data array. + * @retval the value, unit : word. + */ +static unsigned int GetWordValue(unsigned char *buffer) +{ + unsigned int ret; + unsigned int i = 0; + if (buffer == NULL) { /* Null pointer check. */ + return 0; + } + + ret = buffer[i++] << BYTE_0_OFFSET; /* Highest 8 bits. */ + ret += buffer[i++] << BYTE_1_OFFSET; + ret += buffer[i++] << BYTE_2_OFFSET; + ret += buffer[i++]; + return ret; +} + +/** + * @brief Jump function. + * @param addr the target address of jump. + * @retval None. + */ +static void UserLoaderJump(unsigned int addr) +{ + /* Judgement flash empty */ + unsigned int *magic = (unsigned int *)(void *)addr; + if (*magic != EFLASH_MAGIC_NUMBER) { + while (1) { + ; + } + } + /* Jump to app run start address. */ + (*(void(*)(void))(addr + EFLASH_MAGIC_OFFSET))(); +} + +/** + * @brief User boot function. + * @param flash handle FLASH handle. + * @retval None. + */ +static void FlashInit(FLASH_Handle *flash) +{ + HAL_CRG_IpEnableSet(EFC_BASE, BASE_CFG_ENABLE); /* Enable the CRG of EFC modular. */ + flash->baseAddress = EFC; + flash->peMode = FLASH_PE_OP_BLOCK; + HAL_FLASH_Init(flash); /* Init flash. */ +} + +/** + * @brief User boot function. + * @param None. + * @retval None. + */ +void UserBoot(void) +{ + SystemInit(); /* Init peripheral module */ + unsigned char loaderParameter[USER_LOADER_PARAMETER_SIZE] = {0}; + FLASH_Handle flash; + unsigned int jumpAppFlage; + unsigned int app0RunStartAddr; + unsigned int app1RunStartAddr; + + /* Init flash */ + FlashInit(&flash); + /* Get the flage of user loader. */ + HAL_FLASH_Read(&flash, USER_PARAMTER_FLASH_START - FLASH_READ_BASE, USER_LOADER_PARAMETER_SIZE, + loaderParameter, USER_LOADER_PARAMETER_SIZE); + + jumpAppFlage = GetWordValue(&loaderParameter[JUMP_APP_FLAGE_OFFSET]); + app0RunStartAddr = GetWordValue(&loaderParameter[APP0_RUN_START_ADDR_OFFSET]); + if (app0RunStartAddr < USER_APP_RUN_INIT_ADDR || app0RunStartAddr == 0xFFFFFFFF) { /* Check the address validity. */ + app0RunStartAddr = USER_APP_RUN_INIT_ADDR; + } + app1RunStartAddr = GetWordValue(&loaderParameter[APP1_RUN_START_ADDR_OFFSET]); + if (app1RunStartAddr < USER_APP_RUN_INIT_ADDR || app1RunStartAddr == 0xFFFFFFFF) { /* Check the address validity. */ + app1RunStartAddr = USER_APP_RUN_INIT_ADDR; + } + + /* The app1 is new, and jump to the app1 address. */ + if (jumpAppFlage == UASE_APP1_RUN_FLAG) { + UserLoaderJump(app1RunStartAddr); + } + /* Jump to app run start address. */ + UserLoaderJump(app0RunStartAddr); +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_boot/user_boot/user_boot.h b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/user_boot/user_boot.h new file mode 100644 index 0000000000000000000000000000000000000000..db5b30c6e408cc1749a481fff45199704f7209be --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_boot/user_boot/user_boot.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_boot.h + * @author MCU Driver Team + * @brief This file provides the user boot function. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_USER_BOOT_H +#define McuMagicTag_USER_BOOT_H + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "flash.h" +#include "user_boot.h" + +void UserBoot(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_remap/init/main.c b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..d3498b7c9f8e4492807892552defe61f5bfed0cf --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/init/main.c @@ -0,0 +1,59 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +#include "user_app.h" +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +UART_Handle g_uart0; +GPIO_Handle g_gpio3; +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + UserAppProgress(); + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_remap/init/main.h b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..83feeb5c93a3a54e84a3e24775b90947fb4c27c2 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/init/main.h @@ -0,0 +1,55 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "uart.h" +#include "uart_ex.h" +#include "crg.h" +#include "gpio.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +extern GPIO_Handle g_gpio3; +extern UART_Handle g_uart0; + +void SystemInit(void); +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +/* USER CODE BEGIN 0 */ +void GPIO3_5_CallbackFunc(void *param); +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_remap/init/system_init.c b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..af24f652b56d25a713624d7fe57924ae70908bd7 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/init/system_init.c @@ -0,0 +1,121 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "iocmg.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_DMA; + g_uart0.rxMode = UART_MODE_INTERRUPT; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE7; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE7; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +__weak void GPIO3_5_CallbackFunc(void *param) +{ + BASE_FUNC_UNUSED(param); /* Prevent compilation alarms. */ +} + +static void GPIO_Init(void) +{ + HAL_CRG_IpEnableSet(GPIO3_BASE, IP_CLK_ENABLE); + g_gpio3.baseAddress = GPIO3; + + g_gpio3.pins = GPIO_PIN_5; + HAL_GPIO_Init(&g_gpio3); /* Init GPIO. */ + HAL_GPIO_SetDirection(&g_gpio3, g_gpio3.pins, GPIO_INPUT_MODE); + HAL_GPIO_SetValue(&g_gpio3, g_gpio3.pins, GPIO_LOW_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio3, g_gpio3.pins, GPIO_INT_TYPE_FALL_EDGE); + + HAL_GPIO_RegisterCallBack(&g_gpio3, GPIO_PIN_5, GPIO3_5_CallbackFunc); + IRQ_Register(IRQ_GPIO3, HAL_GPIO_IrqHandler, &g_gpio3); + IRQ_SetPriority(IRQ_GPIO3, 1); /* set gpio1 interrupt priority to 1, 1~15. 1 is priority value */ + IRQ_EnableN(IRQ_GPIO3); /* gpio interrupt enable */ +} + +static void IOConfig(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_5_AS_GPIO3_5); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_5_AS_GPIO3_5, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_5_AS_GPIO3_5, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_5_AS_GPIO3_5, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_5_AS_GPIO3_5, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + GPIO_Init(); + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_remap/readme.md b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..208dded94afd8fae54788bccbf47171604d10c28 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/readme.md @@ -0,0 +1,28 @@ +# MCU芯片 OTA Cross Upgrade Remap(交叉升级-remap)参考示例 +## 关键字: OTA,cross upgrade,升级,Remap + +**【功能描述】** ++ OTA是一种通过无线通信实现远程更新设备固件的方法。MCU OTA为通过外部具有无线通信的器件接收新固件数据,外部器件将新固件数据通过MCU串行通信接口发送给MCU,实现固件更新。MCU的OTA主要工作是将串行通信接口接收的新固件数据更新到用户指定的程序区,完成固件的升级。 ++ OTA的交叉升级remap在功能上包括1个user boot flash分区、1个APP运行flash分区、1个参数存储flash区。user boot flash分区具有判断跳转、remap功能。APP运行flash分区具有升级功能、业务逻辑处理功能。参数存储flash区用于存储升级相关配置参数。User boot分区与APP运行分区在flash上未进行严格划分,boot跳转到APP运行的地址是动态获取的。 ++ flash空间使用: + 1.boot 和 APP flash分区:起始地址0x3000000,大小255K; + 2.参数存储flash分区:起始地址0x307FC00,大小1K; + +**【示例配置】** ++ 配置UART0波特率为115200作为升级速率。 + ++ 配置CRC使用16bit校验结果,用于校验通信数据正确性。 + ++ 配置flash阻塞方式进行擦除、编写,用于更新flash存储固件。 + + +**【示例效果】** ++ 当用户复位芯片后,MCU首先会执行boot程序,boot进行判断是否执行remap功能,完成判断后跳转到APP运行地址执行程序。 ++ 升级功能是APP完成的,当升级GPIO管脚获取信号后,会进入OTA升级环节。主机在1s内发起与OTA程序握手,握手成功进入固件升级阶段,完成固件升级后,主机下发命令复位MCU。MCU再次重新运行。 + +**【注意事项】** ++ 示例代码使用UART0作为升级通道,需要硬件预留UART0的升级管脚。 ++ 升级模型需开启中断服务函数基地址不锁定宏,保证APP中断正常执行。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_app/user_app.c b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_app/user_app.c new file mode 100644 index 0000000000000000000000000000000000000000..06f6a7aa192cbd6ac265e1c1f8e0abd608a382cb --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_app/user_app.c @@ -0,0 +1,196 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_boot.c + * @author MCU Driver Team + * @brief This file provides the user boot function. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "flash.h" +#include "crg.h" +#include "debug.h" +#include "user_app.h" + +#define USER_PARAMTER_FLASH_ERASE_SIZE 1 +#define USER_PARAMTER_FLASH_WRITE_SIZE 1024 + +#define USER_PARAMTER_FORMER_FLASH_ADDR 0x303FC00 +#define USER_PARAMTER_BACK_FLASH_ADDR 0x307FC00 + +#define USER_LOADER_PARAMETER_SIZE 1024 +#define REMAP_FLAGE_OFFSET 0 + +#define EFLASH_MAGIC_NUMBER 0xA37E95BD +#define EFLASH_MAGIC_OFFSET 0x04 + +#define REMAP_ENABLE_MASK 0x01 + +#define BYTE_0 0 +#define BYTE_0_OFFSET 24 +#define BYTE_1 1 +#define BYTE_1_OFFSET 16 +#define BYTE_2 2 +#define BYTE_2_OFFSET 8 +#define BYTE_3 3 + +#define USER_LOADER_HANDSHAKE_TIMEOUT 1000 +#define DBG_PRINTF_FINISH_WAIT_TIME 100 +#define LOOP_PRINTF_TIME 1000 + +static unsigned int g_otaFlage = 0; + +void GPIO3_5_CallbackFunc(void *param) +{ + BASE_FUNC_UNUSED(param); /* Prevent compilation alarms. */ + g_otaFlage = 1; +} + +/** + * @brief Gets the value of a word in a char array. + * @param buffer the data array. + * @retval the value, unit : word. + */ +static unsigned int GetWordValue(unsigned char *buffer, unsigned int size) +{ + unsigned int ret; + unsigned int index = 0; + BASE_FUNC_UNUSED(size); /* Compiler prevention alarm. */ + if (buffer == NULL) { /* Null pointer check. */ + return 0; + } + + ret = buffer[index++] << BYTE_0_OFFSET; /* Highest 8 bits. */ + ret += buffer[index++] << BYTE_1_OFFSET; + ret += buffer[index++] << BYTE_2_OFFSET; + ret += buffer[index++]; + return ret; +} + +/** + * @brief User boot function. + * @param flash handle FLASH handle. + * @retval None. + */ +static void FlashInit(FLASH_Handle *flash) +{ + HAL_CRG_IpEnableSet(EFC_BASE, BASE_CFG_ENABLE); /* Enable the CRG of EFC modular. */ + flash->baseAddress = EFC; + flash->peMode = FLASH_PE_OP_BLOCK; + HAL_FLASH_Init(flash); /* Init flash. */ +} + +/** + * @brief Jump function. + * @param addr the target address of jump. + * @retval None. + */ +static void UserLoaderJump(unsigned int addr) +{ + /* Jump to ServiceProgress() address. */ + (*(void(*)(void))(addr))(); +} + +/** + * @brief Start the OTA upgrade process. + * @param None. + * @retval None. + */ +static void StartOtaProgress(void) +{ + /* Initializes module resources required for the upgrade. */ + ULOADER_Handle uLoaderHandle; + FLASH_Handle flashHandle; + CRC_Handle crcHandle; + UART_Handle uart0Handle; + ULOADER_Cmd cmd; + + uLoaderHandle.flash = &flashHandle; + uLoaderHandle.crc = &crcHandle; + uLoaderHandle.comHandle = (void *)&uart0Handle; + uLoaderHandle.mode = COMMUNICATION_UART; + ULOADER_Init(&uLoaderHandle); /* Init the module resources of user loader. */ + /* User OTA progress */ + if (ULOADER_HandShake(&uLoaderHandle, USER_LOADER_HANDSHAKE_TIMEOUT) == BASE_STATUS_OK) { + while (true) { + if (ULOADER_ReceiveCmd(&uLoaderHandle, &cmd) != BASE_STATUS_OK) { + continue; + } + if (ULOADER_CommandExec(&uLoaderHandle, &cmd) != BASE_STATUS_OK) { + ULOADER_Ack(&uLoaderHandle, ACK_FAIL, 0); + } + } + } + + ULOADER_DeInit(&uLoaderHandle); + BASE_FUNC_SoftReset(); /* Hand shake fail, reset the chip. */ +} + +/** + * @brief User app progress function. + * @param None. + * @retval None. + */ +static void ServiceProgress(void) +{ + while (true) { + /* User Logic Program Example. */ + DBG_PRINTF("User app loop wait remap ota flage\r\n"); + BASE_FUNC_DELAY_MS(LOOP_PRINTF_TIME); + + /* The program enters the OTA phase and starts the firmware upgrade. */ + if (g_otaFlage == 1) { + /* All interrupts used in the APP must be disabled to ensure that the upgrade process is not interrupted. */ + IRQ_DisableN(IRQ_GPIO3); + DBG_PRINTF("User loader start.\r\n"); + BASE_FUNC_DELAY_MS(DBG_PRINTF_FINISH_WAIT_TIME); + StartOtaProgress(); /* Start the user OTA progress. */ + } + } +} + +/** + * @brief User boot function. + * @param None. + * @retval None. + */ +void UserAppProgress(void) +{ + SystemInit(); /* Init peripheral module */ + unsigned char loaderParameter[USER_LOADER_PARAMETER_SIZE] = {0}; + FLASH_Handle flash; + unsigned int remapReg; + + /* Init flash */ + FlashInit(&flash); + /* Get the flage of user loader. */ + HAL_FLASH_Read(&flash, USER_PARAMTER_FORMER_FLASH_ADDR - FLASH_READ_BASE, USER_LOADER_PARAMETER_SIZE, + loaderParameter, USER_LOADER_PARAMETER_SIZE); + + remapReg = GetWordValue(&loaderParameter[REMAP_FLAGE_OFFSET], 0x04); /* 0x04: one word equal 4 byte. */ + if (remapReg == REMAP_ENABLE_MASK) { + /* Enable remap and jump. */ + DCL_SYSCTRL_SetRemapMode(SYSCTRL_REMAP_MODE3); + DCL_SYSCTRL_EnableRemap(); + + /* The target function address is related to the code. */ + unsigned int addr = (unsigned int)ServiceProgress; + UserLoaderJump(addr); /* Jump to ServiceProgress() address. */ + } + + ServiceProgress(); /* Executing a Service Processing Program. */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_app/user_app.h b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_app/user_app.h new file mode 100644 index 0000000000000000000000000000000000000000..5c27e4404eacaee823e7dde3785bc9a48e7fc1c4 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_app/user_app.h @@ -0,0 +1,33 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_boot.h + * @author MCU Driver Team + * @brief This file provides the user boot function. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_USER_APP_H +#define McuMagicTag_USER_APP_H + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "user_loader.h" + +void UserAppProgress(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_handshake_read.c b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_handshake_read.c new file mode 100644 index 0000000000000000000000000000000000000000..3e7a0163dce3b142d1d185c3ee20cbe6a4098b4d --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_handshake_read.c @@ -0,0 +1,170 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_handshake_read.c + * @author MCU Driver Team + * @brief This file provides the user handshake and read functions to manage the following functionalities of + * the user loader. + * + Receiving handshake frames functions. + * + UART, I2C, SPI read blocking adapt functions. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "user_handshake_read.h" + +/* Macro definitions --------------------------------------------------------- */ +#define SYSTICK_MS_DIV 1000 +#define ACK_SIZE 6 +#define RECEIVE_ONE_BYTE_DELAY_TIME 40 +#define RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME 500 + +/** + * @brief Check whether the automatic baud rate detection is complete. + * @param handle UART handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType IsActiveUart(UART_Handle *handle) +{ + if (handle->baseAddress->UART_RIS.BIT.abdcris == 1 && handle->baseAddress->UART_RIS.BIT.abderis == 0 && + handle->baseAddress->UART_ABDEN.BIT.abdbusy == 0) { + HAL_UART_DisableBaudDetectionEx(handle); /* Auto-baud detection complete. */ + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief User receive one byte. + * @param handle UART handle. + * @param targetByte the target byte. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType UartReceiveTargetByte(UART_Handle *handle, unsigned char targetData, unsigned int timeout) +{ + unsigned int preTick = DCL_SYSTICK_GetTick(); /* Get current tick. */ + unsigned int curTick; + unsigned long long delta = 0; + unsigned long long targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SYSTICK_MS_DIV * timeout; + unsigned char headFrame; + + while (true) { + /* Receives handshake frames sent by the host. */ + headFrame = DCL_UART_ReadData(handle->baseAddress); + if (headFrame == targetData) { + return BASE_STATUS_OK; + } + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* Check timeout. */ + break; + } + preTick = curTick; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief User loader receiving handshake frame. + * @param handle UART handle. + * @param buf Address of the data buffer to be saved. + * @param length the size of the data to be receiving. + * @param targetByte the target byte. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType UloaderReceiveHandShakeFrame(UART_Handle *handle, unsigned char *buf, unsigned int length, + unsigned char targetByte) +{ + BASE_StatusType ret; + if (IsActiveUart(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + /* Receives handshake frames sent ack frame to the host. */ + ret = HAL_UART_WriteBlocking(handle, buf, ACK_SIZE, RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + /* Receives handshake frames sent by the host. */ + ret = UartReceiveTargetByte(handle, targetByte, RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + buf[0] = targetByte; /* receive target byte, and then recive data. */ + ret = HAL_UART_ReadBlocking(handle, &buf[1], (length - 1), RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME); + return ret; +} + +/** + * @brief Blocking read data in UART mode. + * @param handle UART handle. + * @param rData Address of the data buffer to be saved. + * @param dataSize the size of the data to be receiving. + * @param targetByte the target byte. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType ULOADER_UART_ReadBlocking(UART_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout) +{ + BASE_StatusType ret; + /* Receives handshake frames sent by the host. */ + ret = UartReceiveTargetByte(handle, targetByte, timeout); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + rData[0] = targetByte; /* receive target byte, and then recive data. */ + ret = HAL_UART_ReadBlocking(handle, &rData[1], (dataSize - 1), timeout); + return ret; +} + +/** + * @brief Blocking read data in I2C mode. + * @param handle I2C handle. + * @param rData Address of the data buffer to be saved. + * @param dataSize the size of the data to be receiving. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType ULOADER_I2C_ReadBlocking(I2C_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned int timeout) +{ + BASE_FUNC_UNUSED(handle); /* Compiler prevention alarm */ + BASE_FUNC_UNUSED(rData); + BASE_FUNC_UNUSED(dataSize); + BASE_FUNC_UNUSED(timeout); + return BASE_STATUS_OK; +} + +/** + * @brief Blocking read data in SPI mode. + * @param handle SPI handle. + * @param rData Address of the data buffer to be saved. + * @param dataSize the size of the data to be receiving. + * @param targetByte the target byte. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType ULOADER_SPI_ReadBlocking(SPI_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout) +{ + BASE_FUNC_UNUSED(handle); /* Compiler prevention alarm */ + BASE_FUNC_UNUSED(rData); + BASE_FUNC_UNUSED(dataSize); + BASE_FUNC_UNUSED(targetByte); + BASE_FUNC_UNUSED(timeout); + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_handshake_read.h b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_handshake_read.h new file mode 100644 index 0000000000000000000000000000000000000000..3f7b1db82ef7715b1879bf45d4e8387203d5eda1 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_handshake_read.h @@ -0,0 +1,49 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_handshake_read.h + * @author MCU Driver Team + * @brief This file provides the user handshake and read functions to manage the following functionalities of + * the user loader. + * + Receiving handshake frames functions. + * + UART, I2C, SPI read blocking adapt functions. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_USER_HADNSHAKE_READ_H +#define McuMagicTag_USER_HADNSHAKE_READ_H + +/* Includes ------------------------------------------------------------------*/ +#include "uart.h" +#include "uart_ex.h" +#include "i2c.h" +#include "i2c_ex.h" +#include "spi.h" +#include "spi_ex.h" +#include "can.h" +#include "iocmg.h" + +BASE_StatusType UloaderReceiveHandShakeFrame(UART_Handle *handle, unsigned char *buf, unsigned int lenth, + unsigned char targetByte); +BASE_StatusType ULOADER_UART_ReadBlocking(UART_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout); +BASE_StatusType ULOADER_I2C_ReadBlocking(I2C_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned int timeout); +BASE_StatusType ULOADER_SPI_ReadBlocking(SPI_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_loader.c b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_loader.c new file mode 100644 index 0000000000000000000000000000000000000000..2c6e9ba69e157ac15be93f843ed239c6abc8b84c --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_loader.c @@ -0,0 +1,764 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_loader.c + * @author MCU Driver Team + * @brief This file provides the user loader structure and functions to manage the following functionalities of + * the user loader. + * + Initialization and de-initialization functions. + * + Handshake, command receiving, and command execution functions. + * + Read and write functions. + * + Atomic command function. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "user_handshake_read.h" +#include "user_loader.h" + +/* Macro definitions --------------------------------------------------------- */ +#define HANDSHAKE_FRAME_SIZE 9 + +#define DELAY_TIME 1000 +#define SYSTICK_MS_DIV 1000 +#define FRAME_CMD_OFFSET 0 +#define HEADER_COMMAND_HIGH 1 +#define HEADER_COMMAND_LOW 2 +#define COMMDNA_BASE_LENGHT 3 + +#define CRC_LAST_WIDTH 0x2 +#define ACK_FRAME_SIZE 6 +#define ACK_FRAME_TYPE_OFFSET 0 +#define ACK_FRAME_SEQ_OFFSET 1 +#define ACK_FRAME_INV_SEQ_OFFSET 2 +#define ACK_FRAME_RESULT_OFFSET 3 + +#define MAX_FRAME_DATA_SIZE 1024 /**< Max size of Frame Data Payload */ +#define MAX_FRAME_INDEX 254 + +#define FRAME_HEAD_TAIL_SIZE 5 +#define IMAGE_ADDR_OFFSET 1 /**< Image address offset field in header frame */ +#define IMAGE_SIZE_OFFSET 5 /**< Image size offset field in header frame */ +#define WRITE_ADDRESS_MUILYP 8 + +#define TRY_TIMES_WAIT 10 +#define DATA_HEAD_FRAME_SIZE 14 + +#define NEGOTIATE_FRAME_NUMS_POS 4 +#define NEGOTIATE_FRAME_SIZE_POS 8 + +#define ADDR_REMOVE_HIGH_POS 0xFFFFFF +#define OFFSET_LENGHT_THIRD 3 +#define OFFSET_LENGHT_SEVEN 7 +#define OFTHIRD 3 + +#define FLASH_ERASE_PAGE 1024 +#define ERASE_ADDRESS_MUILTYP 1024 + +#define BYTE_0 0 +#define BYTE_0_OFFSET 24 +#define BYTE_1 1 +#define BYTE_1_OFFSET 16 +#define BYTE_2 2 +#define BYTE_2_OFFSET 8 +#define BYTE_3 3 + +#define WAIT_ACK_FINISH_TIME 2 /* Wait until the ACK message is sent. */ + +#define PARAMETER_OFFSET_FLAG 1 +#define PARAMETER_OFFSET_COPY_START_ADDR 5 +#define PARAMETER_OFFSET_COPY_SIZE 9 +#define PARAMETER_OFFSET_BACKUP_ADDR 13 + +#define ULOADER_UART_BAND_RATE 115200 + +/** + * @brief Convert big-endian data to unsigned short. + * @param buf the buffer to store conversion data. + * @retval the value, unsigned short. + */ +static unsigned short ShiftToShort(unsigned char *buffer) +{ + if (buffer == NULL) { + return 0; + } + return (((buffer[0] << 0x08) & 0xff00) + (buffer[1] & 0xff)); +} + +/** + * @brief Convert big-endian data to unsigned short. + * @param data the data of be converted. + * @param buf the buffer to store conversion data. + * @retval None. + */ +static void UShortToBigEndian(unsigned short data, unsigned char *const buf) +{ + unsigned int i = 0; + buf[i++] = (unsigned char)((data >> 0x8) & 0xFF); /* get the higher 8 bit of unsigned short */ + buf[i] = (unsigned char)(data & 0xFF); +} + +/** + * @brief Convert an unsigned int into big-endian data of the char type for storage. + * @param data the data of be converted. + * @param buf the buffer to store conversion data. + * @retval None. + */ +static void UInitToBigEndian(unsigned int data, unsigned char *const buf) +{ + unsigned int i = 0; + buf[i++] = (unsigned char)((data >> BYTE_0_OFFSET) & 0xFF); /* get the higher 8 bit of unsigned short */ + buf[i++] = (unsigned char)((data >> BYTE_1_OFFSET) & 0xFF); + buf[i++] = (unsigned char)((data >> BYTE_2_OFFSET) & 0xFF); + buf[i] = (unsigned char)(data & 0xFF); +} + +/** + * @brief Get the value of min. + * @param a the compare of value. + * @param b the compare of value. + * @retval the data of min. + */ +static inline unsigned int GetMinValue(unsigned int a, unsigned int b) +{ + return a < b ? a : b; +} + +/** + * @brief Combines two pieces of data of the char type into one piece of data of the short type. + * @param highByte the high byte. + * @param lowByte the low byte. + * @retval the data, unsigned short. + */ +static inline unsigned short MergeToUshort(unsigned char highByte, unsigned char lowByte) +{ + return (highByte << 0x8) + lowByte; /* Make highByte in the high 8 bit */ +} + +/** + * @brief Convert big-endian data to unsigned int. + * @param buf the buffer to be converted. + * @retval the data, unsigned int. + */ +static inline unsigned int BigEndianToUint(const unsigned char *buf) +{ + unsigned int i = 0; + unsigned int sum; + if (buf == NULL) { /* Null pointer check. */ + return 0; + } + sum = buf[i++] << BYTE_0_OFFSET; /* Highest 8 bits. */ + sum += buf[i++] << BYTE_1_OFFSET; + sum += buf[i++] << BYTE_2_OFFSET; + sum += buf[i++]; + return sum; +} + +/** + * @brief Uart0 pin int. + * @param None. + * @retval None. + */ +static void UloaderUart0PinInit(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +/** + * @brief Uart0 pin deint. + * @param None. + * @retval None. + */ +static void UloaderUart0PinDeInit(void) +{ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_GPIO0_3); + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_GPIO0_4); +} + +/** + * @brief Init the UART0 resources used by the user loader. + * @param handle User loader handle. + * @retval None. + */ +static void UloaderUart0Init(UART_Handle *handle) +{ + UloaderUart0PinInit(); + + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + handle->baseAddress = UART0; + + handle->baudRate = ULOADER_UART_BAND_RATE; /* The baudrate. */ + handle->dataLength = UART_DATALENGTH_8BIT; + handle->stopBits = UART_STOPBITS_ONE; + handle->parity = UART_PARITY_NONE; + handle->txMode = UART_MODE_BLOCKING; + handle->rxMode = UART_MODE_BLOCKING; + handle->fifoMode = BASE_CFG_ENABLE; + handle->fifoTxThr = UART_FIFODEPTH_SIZE6; + handle->fifoRxThr = UART_FIFODEPTH_SIZE6; + handle->hwFlowCtr = BASE_CFG_DISABLE; + handle->handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + handle->handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(handle); + HAL_UART_EnableBaudDetectionEx(handle); /* Enable baud auto detect. */ +} + +/** + * @brief Init the CRC resources used by the user loader. + * @param handle User loader handle. + * @retval None. + */ +static void UloaderCrcInit(CRC_Handle *handle) +{ + HAL_CRG_IpEnableSet(CRC_BASE, IP_CLK_ENABLE); /* Enable the CRG of CRC modular. */ + + handle->baseAddress = CRC; + handle->inputDataFormat = CRC_MODE_BIT8; /* Input data length is 8 byte. */ + handle->polyMode = CRC16_1021_POLY_MODE; + handle->initValueType = TYPE_CRC_INIT_VALUE_00; + handle->resultXorValueType = TYPE_CRC_XOR_VALUE_00; + handle->reverseEnableType = REVERSE_INPUT_FALSE_OUTPUT_FALSE; + handle->xorEndianEnbaleType = DISABLE_XOR_ENABLE_LSB; + HAL_CRC_Init(handle); /* Init CRC. */ +} + +/** + * @brief Init the flash resources used by the user loader. + * @param handle User loader handle. + * @retval None. + */ +static void UloaderFlashInit(FLASH_Handle *handle) +{ + HAL_CRG_IpEnableSet(EFC_BASE, BASE_CFG_SET); /* Enable the CRG of EFC modular. */ + handle->baseAddress = EFC; + handle->peMode = FLASH_PE_OP_BLOCK; + HAL_FLASH_Init(handle); /* Init flash. */ +} + +/** + * @brief Init the module resources of user loader. + * @param handle User loader handle. + * @retval BASE status type: OK, ERROR. + */ +void ULOADER_Init(ULOADER_Handle *handle) +{ + /* Reset crc\uart\flash */ + HAL_CRG_IpClkResetSet(CRC_BASE, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(UART0_BASE, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(EFC_BASE, BASE_CFG_SET); + /* Init crc\uart\flash */ + UloaderFlashInit(handle->flash); + UloaderUart0Init(handle->comHandle); /* If the communication protocols are different, change the value here. */ + UloaderCrcInit(handle->crc); +} + +/** + * @brief Deinit the module resources of user loader. + * @param handle User loader handle. + * @retval BASE status type: OK, ERROR. + */ +void ULOADER_DeInit(ULOADER_Handle *handle) +{ + /* Reset crc\uart\flash */ + HAL_CRG_IpClkResetSet(handle->comHandle, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(handle->crc, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(handle->flash, BASE_CFG_SET); + UloaderUart0PinDeInit(); +} + +/** + * @brief Handshake negotiation function. + * @param handle User loader handle. + * @param timeout the value of timeout. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_HandShake(ULOADER_Handle *handle, unsigned int timeout) +{ + unsigned int preTick = DCL_SYSTICK_GetTick(); /* Get the current tick. */ + unsigned int curTick; + unsigned long long delta = 0; + /* Get the timeout of tick */ + unsigned long long targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SYSTICK_MS_DIV * timeout; + + unsigned char buf[HANDSHAKE_FRAME_SIZE] = {0}; + BASE_StatusType ret; + unsigned short receiveCrc; + unsigned short calculateCrc; + + while (true) { /* Receive data cyclically until timeout. */ + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* Check timeout. */ + return BASE_STATUS_TIMEOUT; + } + preTick = curTick; + + /* Response data in the configuration success state. */ + buf[ACK_FRAME_TYPE_OFFSET] = XACK; + buf[ACK_FRAME_SEQ_OFFSET] = 0x00; + buf[ACK_FRAME_INV_SEQ_OFFSET] = 0xff; + buf[ACK_FRAME_RESULT_OFFSET] = ACK_SUCCESS; + calculateCrc = HAL_CRC_Calculate(handle->crc, buf, ACK_FRAME_SIZE - 0x02); /* 2: crc length. */ + UShortToBigEndian(calculateCrc, &buf[ACK_FRAME_SIZE - 0x02]); + /* Receive handshake frame data. */ + ret = UloaderReceiveHandShakeFrame(handle->comHandle, buf, LENGTH_XHDSHK_FRAME, XHDSHK); + if (ret != BASE_STATUS_OK) { + continue; + } + /* Data Crc check. */ + receiveCrc = ShiftToShort(&buf[ACK_FRAME_SIZE + 0x01]); /* The offset of crc data. */ + calculateCrc = HAL_CRC_Calculate(handle->crc, buf, ACK_FRAME_SIZE + 0x01); + if (receiveCrc != calculateCrc) { + continue; + } + ULOADER_Ack(handle, ACK_SUCCESS, 0); + return BASE_STATUS_OK; + } +} + +/** + * @brief Receiving commands function. + * @param handle User loader handle. + * @param receiveCmd User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_ReceiveCmd(ULOADER_Handle *handle, ULOADER_Cmd *receiveCmd) +{ + /* receive command header and command. */ + unsigned char recvBuffer[LENGTH_XHEAD_FRAME] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; /* command size. */ + unsigned short cmdLength; + while (1) { + /* receive command header. */ + if (ULOADER_ReadDate(handle, recvBuffer, LENGTH_XHEAD_FRAME, XCMD, DELAY_TIME) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + if (recvBuffer[FRAME_CMD_OFFSET] != XCMD) { + ULOADER_Ack(handle, ACK_FAIL, 0); + return BASE_STATUS_ERROR; + } + if (recvBuffer[HEADER_COMMAND_HIGH] == 0xFF) { /* 0xFF: Judgement trail frame */ + ULOADER_Ack(handle, ACK_SUCCESS, XTAIL); + return BASE_STATUS_ERROR; + } + /* Command Header Check */ + ULOADER_Ack(handle, ACK_SUCCESS, 0); + /* Receive the boot cmd */ + cmdLength = MergeToUshort(recvBuffer[HEADER_COMMAND_HIGH], recvBuffer[HEADER_COMMAND_LOW]); + cmdLength = cmdLength + COMMDNA_BASE_LENGHT; /* 3:head + 2 crc */ + if (ULOADER_ReadDate(handle, (unsigned char *)receiveCmd, cmdLength, XKEY, DELAY_TIME) != BASE_STATUS_OK) { + ULOADER_Ack(handle, ACK_FAIL, receiveCmd->type); + return BASE_STATUS_ERROR; + } + if (receiveCmd->type != XKEY) { /* Received data is not destination bytes. */ + ULOADER_Ack(handle, ACK_FAIL, 0); + return BASE_STATUS_ERROR; + } + receiveCmd->type = receiveCmd->rcvBuf[0]; + receiveCmd->rcvBufLength = cmdLength; + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Command execution function. + * @param handle User loader handle. + * @param execCmd User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CommandExec(ULOADER_Handle *handle, ULOADER_Cmd *execCmd) +{ + /* Funciton transfer table. */ + switch (execCmd->type) { + case ATOMIS_WRITE: /* Write command */ + if (ULOADER_CMD_Write(handle, execCmd) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + case ATOMIS_ERASE: /* Erase command */ + if (ULOADER_CMD_Erase(handle, execCmd) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + case ATOMIS_UPDATE: /* Updata command */ + if (ULOADER_CMD_Update(handle, execCmd) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + case ATOMIS_RESET: /* Reset command */ + if (ULOADER_CMD_Reset(handle) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + default: + break; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Normalized write data. + * @param handle User loader handle. + * @param wData the buffer of receive data. + * @param dataSize the size of need receive. + * @param timeout the value of timeout. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_WriteDate(ULOADER_Handle *handle, unsigned char *wData, unsigned int dataSize, + unsigned int timeout) +{ + /* CRC produce. */ + unsigned int crc; + crc = HAL_CRC_Calculate(handle->crc, wData, dataSize - CRC_LAST_WIDTH); + UShortToBigEndian(crc, &wData[dataSize - CRC_LAST_WIDTH]); + + /* Send Data. */ + if (handle->mode == COMMUNICATION_UART) { + return HAL_UART_WriteBlocking((UART_Handle *)handle->comHandle, wData, dataSize, timeout); + } else if (handle->mode == COMMUNICATION_I2C) { + return HAL_I2C_SlaveWriteBlocking((I2C_Handle *)handle->comHandle, wData, dataSize, timeout); + } else if (handle->mode == COMMUNICATION_SPI) { + return HAL_SPI_WriteBlocking((SPI_Handle *)handle->comHandle, wData, dataSize, timeout); + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Normalized read data. + * @param handle User loader handle. + * @param rData the buffer of receive data. + * @param dataSize the size of need receive. + * @param targetByte the target byte. + * @param timeout the value of timeout. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_ReadDate(ULOADER_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned short targetByte, unsigned int timeout) +{ + BASE_StatusType ret; + unsigned int crcReceive = 0; + unsigned int crcCalculate = 0; + + /* Check the communication mode. */ + if (handle->mode == COMMUNICATION_UART) { + ret = ULOADER_UART_ReadBlocking((UART_Handle *)handle->comHandle, rData, dataSize, targetByte, timeout); + } else if (handle->mode == COMMUNICATION_I2C) { + ret = ULOADER_I2C_ReadBlocking((I2C_Handle *)handle->comHandle, rData, dataSize, timeout); + } else if (handle->mode == COMMUNICATION_SPI) { + ret = ULOADER_SPI_ReadBlocking((SPI_Handle *)handle->comHandle, rData, dataSize, targetByte, timeout); + } else { + return BASE_STATUS_ERROR; /* Illegal communication mode. */ + } + + /* CRC Check */ + if (ret == BASE_STATUS_OK) { + crcReceive = MergeToUshort(rData[dataSize - 0x2], rData[dataSize - 1]); + crcCalculate = HAL_CRC_Calculate(handle->crc, rData, dataSize - CRC_LAST_WIDTH); + if (crcReceive == crcCalculate) { + return BASE_STATUS_OK; + } + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Answering host. + * @param handle User loader handle. + * @param status answering status. + * @param index the index of frame to answer. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_Ack(ULOADER_Handle *handle, ACK_Status status, unsigned char index) + +{ + unsigned char frame[ACK_FRAME_SIZE]; + unsigned int sequence = index; + + /* Construct the Frame */ + frame[ACK_FRAME_TYPE_OFFSET] = XACK; + frame[ACK_FRAME_SEQ_OFFSET] = index; + frame[ACK_FRAME_INV_SEQ_OFFSET] = (unsigned char)(~sequence & 0xFF); + frame[ACK_FRAME_RESULT_OFFSET] = status; + + /* Write frame to host. */ + return ULOADER_WriteDate(handle, frame, ACK_FRAME_SIZE, DELAY_TIME); +} + +/** + * @brief Receives file head date from the host. + * @param handle User loader handle. + * @param buf the buffer of receive date. + * @param size the size of receive. + * @param perFrameSize Size of each frame to be transmitted. + * @param tryTimes retry Times After Failure. + * @retval BASE status type: OK, ERROR. + */ +static BASE_StatusType ReceiveFileHead(ULOADER_Handle *handle, unsigned char *buf, unsigned int size, + unsigned int *perFrameSize, unsigned char *tryTimes) +{ + unsigned int frameNums = 0; + unsigned char answer = 0; + unsigned int tempTryTime = 0; + + /* Number of retransmission times. */ + while (tempTryTime < TRY_TIMES_WAIT) { + /* Read file heade data. */ + if (ULOADER_ReadDate(handle, buf, DATA_HEAD_FRAME_SIZE, XHEAD, DELAY_TIME) != BASE_STATUS_OK) { + tempTryTime++; + continue; + } + + /* Negotiate frame size */ + frameNums = BigEndianToUint(&buf[NEGOTIATE_FRAME_NUMS_POS]); + if (frameNums > MAX_FRAME_INDEX) { + tempTryTime++; + ULOADER_Ack(handle, ACK_FAIL, 0); + continue; + } + + *perFrameSize = BigEndianToUint(&buf[NEGOTIATE_FRAME_SIZE_POS]); + if (*perFrameSize > MAX_FRAME_DATA_SIZE || *perFrameSize == 0) { + tempTryTime++; + ULOADER_Ack(handle, ACK_FAIL, 0); + continue; + } + + answer = size % *perFrameSize == 0 ? 0 : 1; + if (((size / *perFrameSize) + answer) != frameNums) { /* Data length integrity check. */ + /* Negotiate fail */ + tempTryTime++; + ULOADER_Ack(handle, ACK_FAIL, 0); + continue; + } + ULOADER_Ack(handle, ACK_SUCCESS, 0); + *tryTimes = tempTryTime; + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Receives data from the host. + * @param handle User loader handle. + * @param buf the buffer of receive date. + * @param remainLen Remaining transmission data volume. + * @param perFrameSize Size of each frame to be transmitted. + * @param addr the target of flash address. + * @retval BASE status type: OK, ERROR. + */ +static BASE_StatusType ReceiveFileDate(ULOADER_Handle *handle, unsigned char *buf, unsigned int remainLen, + unsigned int perFrameSize, unsigned int addr) +{ + BASE_StatusType ret; + unsigned char oldIdIndex = 0; + unsigned char tryTimes = 0; + unsigned int rcvLen; + unsigned int targetAddr = addr; + unsigned int targetremainLen = remainLen; + + /* Number of retransmission times. */ + while (tryTimes < TRY_TIMES_WAIT) { + /* Gets the minimum number of transfers for the last receive processing. */ + rcvLen = GetMinValue(targetremainLen, perFrameSize); + buf[1] = 0; + if (targetremainLen > 0) { /* There is still data to be received and continue to receive data. */ + if (ULOADER_ReadDate(handle, buf, rcvLen + FRAME_HEAD_TAIL_SIZE, XDATA, DELAY_TIME) != BASE_STATUS_OK) { + ULOADER_Ack(handle, ACK_FAIL, buf[1]); + tryTimes++; + continue; + } + } else { + /* There is no data to be received, and received file tail frame. */ + if (ULOADER_ReadDate(handle, buf, rcvLen + FRAME_HEAD_TAIL_SIZE, XTAIL, DELAY_TIME) != BASE_STATUS_OK) { + ULOADER_Ack(handle, ACK_FAIL, buf[1]); + tryTimes++; + continue; + } + } + /* Check the Sequence of Received Data Packets. */ + if ((buf[1] - oldIdIndex) != 1) { + ULOADER_Ack(handle, ACK_SUCCESS, oldIdIndex); + continue; + } + + /* Data info and trail judgement. */ + if (buf[0] == XTAIL && targetremainLen <= 0) { + /* Ack file trail frame. */ + ULOADER_Ack(handle, ACK_SUCCESS, buf[1]); + return BASE_STATUS_OK; + } + + /* Writes the received data to the flash memory. */ + ret = HAL_FLASH_WriteBlocking(handle->flash, (unsigned int)(buf + OFFSET_LENGHT_THIRD), + targetAddr & ADDR_REMOVE_HIGH_POS, + ((rcvLen + OFFSET_LENGHT_SEVEN) >> OFFSET_LENGHT_THIRD) << OFFSET_LENGHT_THIRD); + if (ret != BASE_STATUS_OK) { + tryTimes++; + ULOADER_Ack(handle, ACK_FAIL, buf[1]); /* Flash write error */ + continue; + } + + tryTimes = 0; /* Reset times. */ + ULOADER_Ack(handle, ACK_SUCCESS, buf[1]); + /* ID update and check. */ + oldIdIndex = buf[1]; + targetAddr += rcvLen; + targetremainLen -= rcvLen; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Write the flash page by atomic write command. + * @param handle User loader handle. + * @param command User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Write(ULOADER_Handle *handle, ULOADER_Cmd *command) +{ + BASE_StatusType ret; + unsigned int addr; + unsigned int size; + unsigned char tryTimes = 0; + unsigned int remainLen; + unsigned int perFrameSize = 0; + unsigned char buf[MAX_FRAME_DATA_SIZE + FRAME_HEAD_TAIL_SIZE]; + + /* Step1: Check the address validity. */ + addr = BigEndianToUint(&command->rcvBuf[IMAGE_ADDR_OFFSET]); /* Get the address of erase. */ + size = BigEndianToUint(&command->rcvBuf[IMAGE_SIZE_OFFSET]); /* Get the size of erase. */ + /* Address must be an integer multiple of 8, and size cannot be 0. */ + if (((addr % WRITE_ADDRESS_MUILYP) != 0) || size == 0) { + return BASE_STATUS_ERROR; + } + ULOADER_Ack(handle, ACK_SUCCESS, 0); + + /* Step2:Receive the file header frame. */ + remainLen = size; + ret = ReceiveFileHead(handle, buf, size, &perFrameSize, &tryTimes); + if (tryTimes == TRY_TIMES_WAIT || ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + /* Step3:Received data is written into the flash memory. */ + ret = ReceiveFileDate(handle, buf, remainLen, perFrameSize, addr); + return ret; +} + +/** + * @brief Erase the flash page by atomic erase command. + * @param handle User loader handle. + * @param command User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Erase(ULOADER_Handle *handle, ULOADER_Cmd *command) +{ + BASE_StatusType ret; + unsigned int addr; + unsigned int size; + + addr = BigEndianToUint(&command->rcvBuf[IMAGE_ADDR_OFFSET]); /* Get the address of erase. */ + size = BigEndianToUint(&command->rcvBuf[IMAGE_SIZE_OFFSET]); /* Get the size of erase. */ + /* Address must be an integer multiple of 1024. */ + if (((addr % ERASE_ADDRESS_MUILTYP) != 0)) { + return BASE_STATUS_ERROR; + } + /* The size must be an integer multiple of 1024 and not equal to 0. */ + if ((size == 0) || ((size % ERASE_ADDRESS_MUILTYP) != 0)) { + return BASE_STATUS_ERROR; + } + + /* Erase flash page. */ + ret = HAL_FLASH_EraseBlocking(handle->flash, FLASH_ERASE_MODE_PAGE, addr & ADDR_REMOVE_HIGH_POS, + size / FLASH_ERASE_PAGE); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + ULOADER_Ack(handle, ACK_SUCCESS, 0); + return BASE_STATUS_OK; +} + +/** + * @brief Updating OTA Parameters by atomic update command. + * @param handle User loader handle. + * @param command User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Update(ULOADER_Handle *handle, ULOADER_Cmd *command) +{ + BASE_StatusType ret; + unsigned char buf[FLASH_ERASE_PAGE]; + unsigned int upDateFlag; + unsigned int copyStartAddr; + unsigned int copySize; + unsigned int appBakAddr; + + upDateFlag = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_FLAG]); /* Get the firmware update flag. */ + copyStartAddr = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_COPY_START_ADDR]); /* Get the copy address. */ + copySize = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_COPY_SIZE]); /* Get the size of new firmware. */ + appBakAddr = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_BACKUP_ADDR]); /* Get the firmware backup address. */ + /* Read the flash page of upgrade parameters. */ + ret = HAL_FLASH_Read(handle->flash, (PARAMETER_ADDR - FLASH_READ_BASE), FLASH_ERASE_PAGE, buf, FLASH_ERASE_PAGE); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + /* Erase the flash page of upgrade parameters. */ + ret = HAL_FLASH_EraseBlocking(handle->flash, FLASH_ERASE_MODE_PAGE, PARAMETER_ADDR & ADDR_REMOVE_HIGH_POS, 1); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + /* Modify the parameter and assign a value. */ + UInitToBigEndian(upDateFlag, &buf[PARAMETER_OFFSET_FLAG - 0x01]); + UInitToBigEndian(copyStartAddr, &buf[PARAMETER_OFFSET_COPY_START_ADDR - 0x01]); + UInitToBigEndian(copySize, &buf[PARAMETER_OFFSET_COPY_SIZE - 0x01]); + UInitToBigEndian(appBakAddr, &buf[PARAMETER_OFFSET_BACKUP_ADDR - 0x01]); + /* Write the flash page of upgrade parameters. */ + ret = HAL_FLASH_WriteBlocking(handle->flash, (unsigned int)buf, PARAMETER_ADDR & ADDR_REMOVE_HIGH_POS, + FLASH_ERASE_PAGE); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + ULOADER_Ack(handle, ACK_SUCCESS, 0); + return BASE_STATUS_OK; +} + +/** + * @brief MCU reset by atomic reset command. + * @param handle User loader handle. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Reset(ULOADER_Handle *handle) +{ + ULOADER_Ack(handle, ACK_SUCCESS, 0); + BASE_FUNC_DELAY_MS(WAIT_ACK_FINISH_TIME); /* Wait until the ACK message is sent. */ + BASE_FUNC_SoftReset(); + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_loader.h b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_loader.h new file mode 100644 index 0000000000000000000000000000000000000000..8ecd2d16d31228f744f8d6ba28aedec14c70c73f --- /dev/null +++ b/src/application/middleware_sample/ota/ota_cross_upgrade_remap/user_loader/user_loader.h @@ -0,0 +1,129 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_loader.h + * @author MCU Driver Team + * @brief This file provides the user loader structure and functions to manage the following functionalities of + * the user loader. + * + Initialization and de-initialization functions. + * + Handshake, command receiving, and command execution functions. + * + Read and write functions. + * + Atomic command function. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_USER_LOADER_H +#define McuMagicTag_USER_LOADER_H + +/* Includes ------------------------------------------------------------------*/ +#include "flash.h" +#include "crc.h" +#include "uart.h" +#include "spi.h" +#include "i2c.h" +#include "can.h" +#include "crg.h" + +/* Macro definitions --------------------------------------------------------- */ +#define PARAMETER_ADDR 0x303FC00 +#define PARAMETER_ADDR_BACK 0x703FC00 + +#define CMD_PAYLOAD_MAX 30 /**< Command payload length */ + +/* Frame header flag parameter. */ +#define XHDSHK 0xEB +#define XHEAD 0xFE +#define XDATA 0xDA +#define XTAIL 0xED +#define XACK 0xCB +#define XCMD 0xAB +#define XKEY 0xCD +#define XVER 0xCE + +/* The length of different frame. */ +#define LENGTH_XHDSHK_FRAME 9 +#define LENGTH_XHEAD_FRAME 5 +#define LENGTH_XCMD_FRAME 12 +#define LENGTH_XHDATA_FRAME 11 +#define LENGTH_XDATA_ADD_FRAME 5 +#define LENGTH_XEND_FRAME 6 +#define LENGTH_ACK_FRAME 6 + +/** + * @brief Atomis commands enumeration definition. + */ +enum { + ATOMIS_WRITE = 0xD2, /**< 0xD2: Download Image */ + ATOMIS_ERASE = 0xE4, /**< 0xE4: Get version information. */ + ATOMIS_RESET = 0x87, /**< 0x87: Reset MCU. */ + ATOMIS_UPDATE = 0x90, /**< 0x90: Update parameter settings. */ +}; + +/** + * @brief Communication mode enumeration definition. + */ +typedef enum { + COMMUNICATION_UART = 0, + COMMUNICATION_I2C = 1, + COMMUNICATION_SPI = 2, + COMMUNICATION_CAN = 3, +} COMMUNICATION_Mode; + +/** + * @brief Answering status enumeration definition. + */ +typedef enum { + ACK_FAIL = 0xA5, + ACK_SUCCESS = 0x5A, +} ACK_Status; + +/** + * @brief User loader command frame structure definition. + */ +typedef struct { + unsigned char type; /**< Command Type. */ + unsigned char rcvBuf[CMD_PAYLOAD_MAX]; /**< Command Buf All Command contents. */ + unsigned short rcvBufLength; /**< Buffer length. */ +} ULOADER_Cmd; + +/** + * @brief Module handle structure definition. + */ +typedef struct _ULOADER_Handle { + void *comHandle; /**< Register base address. */ + FLASH_Handle *flash; + CRC_Handle *crc; + COMMUNICATION_Mode mode; +} ULOADER_Handle; + +void ULOADER_Init(ULOADER_Handle *handle); +void ULOADER_DeInit(ULOADER_Handle *handle); +BASE_StatusType ULOADER_HandShake(ULOADER_Handle *handle, unsigned int timeout); +BASE_StatusType ULOADER_ReceiveCmd(ULOADER_Handle *handle, ULOADER_Cmd *receiveCmd); +BASE_StatusType ULOADER_CommandExec(ULOADER_Handle *handle, ULOADER_Cmd *execCmd); + +BASE_StatusType ULOADER_WriteDate(ULOADER_Handle *handle, unsigned char *wData, unsigned int dataSize, + unsigned int timeout); +BASE_StatusType ULOADER_ReadDate(ULOADER_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned short targetByte, unsigned int timeout); +BASE_StatusType ULOADER_Ack(ULOADER_Handle *handle, ACK_Status status, unsigned char index); + +BASE_StatusType ULOADER_CMD_Write(ULOADER_Handle *handle, ULOADER_Cmd *command); +BASE_StatusType ULOADER_CMD_Erase(ULOADER_Handle *handle, ULOADER_Cmd *command); +BASE_StatusType ULOADER_CMD_Update(ULOADER_Handle *handle, ULOADER_Cmd *command); +BASE_StatusType ULOADER_CMD_Reset(ULOADER_Handle *handle); +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_overwrite_upgrade/init/main.c b/src/application/middleware_sample/ota/ota_overwrite_upgrade/init/main.c new file mode 100644 index 0000000000000000000000000000000000000000..219dd7c1c6756779c3f591b9640c5d2b71e2257c --- /dev/null +++ b/src/application/middleware_sample/ota/ota_overwrite_upgrade/init/main.c @@ -0,0 +1,57 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +#include "user_boot.h" +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ +/* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ + /* USER CODE END 2 */ + /* USER CODE BEGIN 3 */ + UserBoot(); + /* 建议用户放置初始配置代码 */ + /* USER CODE END 3 */ + while (1) { + /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ + /* USER CODE END 4 */ + } + /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} + +/* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ +/* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_overwrite_upgrade/init/main.h b/src/application/middleware_sample/ota/ota_overwrite_upgrade/init/main.h new file mode 100644 index 0000000000000000000000000000000000000000..e628cfd9fba22446f99505db554ecffb6645b3a9 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_overwrite_upgrade/init/main.h @@ -0,0 +1,48 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "crg.h" + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +void SystemInit(void); +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_overwrite_upgrade/init/system_init.c b/src/application/middleware_sample/ota/ota_overwrite_upgrade/init/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..fd748849e1b6a3e15a36ad15778c857731928b35 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_overwrite_upgrade/init/system_init.c @@ -0,0 +1,52 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" + +#define UART0_BAND_RATE 115200 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +void SystemInit(void) +{ + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_overwrite_upgrade/readme.md b/src/application/middleware_sample/ota/ota_overwrite_upgrade/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..95be094bfd3e42ef67934c69ebae2363e243d86b --- /dev/null +++ b/src/application/middleware_sample/ota/ota_overwrite_upgrade/readme.md @@ -0,0 +1,28 @@ +# MCU芯片 OTA Overwrite Upgrade(覆盖升级)参考示例 +## 关键字: OTA,Overwrite,升级 + +**【功能描述】** ++ OTA是一种通过无线通信实现远程更新设备固件的方法。MCU OTA为通过外部具有无线通信的器件接收新固件数据,外部器件将新固件数据通过MCU串行通信接口发送给MCU,实现固件更新。MCU的OTA主要工作是将串行通信接口接收的新固件数据更新到用户指定的程序区,完成固件的升级。 ++ OTA的覆盖升级包括1个user bootloader flash分区、1个APP运行flash分区、1个参数存储flash区。user bootloader flash分区具有判断跳转、升级功能。APP运行flash分区仅用于执行用户逻辑代码。参数存储flash区用于存储升级相关配置参数。 ++ flash空间使用: + 1.bootloader flash分区:起始地址0x3000000,大小40K; + 2.APP flash分区:起始地址0x300A000, 大小471K; + 3.参数存储flash分区:起始地址0x301FC00,大小1K; + +**【示例配置】** ++ 配置UART0波特率为115200作为升级速率。 + ++ 配置CRC使用16bit校验结果,用于校验通信数据正确性。 + ++ 配置flash阻塞方式进行擦除、编写,用于更新flash存储固件。 + + +**【示例效果】** ++ 当用户复位芯片后,MCU首先会执行OTA升级程序,主机在1s内发起与OTA程序握手,握手成功进入固件升级阶段,完成固件升级后,主机下发命令复位MCU。MCU再次重新运行时主机不发起与OTA握手,等待1s后bootloader跳转APP运行地址执行新的程序。 + +**【注意事项】** ++ 示例代码使用UART0作为升级通道,需要硬件预留UART0的升级管脚。 ++ 升级模型需开启中断服务函数基地址不锁定宏,保证APP中断正常执行。 ++ 此示例init文件夹下的工程初始化配置是基于3066MNPINH芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考sample下的init文件内容。 ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_boot/user_boot.c b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_boot/user_boot.c new file mode 100644 index 0000000000000000000000000000000000000000..90777af7c93396ac0d9727387e4a9eb2700207c5 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_boot/user_boot.c @@ -0,0 +1,150 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_boot.c + * @author MCU Driver Team + * @brief This file provides the user boot function. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "flash.h" +#include "crg.h" +#include "user_loader.h" +#include "user_boot.h" + +/* Macro definitions --------------------------------------------------------- */ +#define USER_PARAMTER_FLASH_START 0x301FC00 +#define USER_APP_RUN_INIT_ADDR 0x300A000 + +#define USER_LOADER_PARAMETER_SIZE 1024 +#define USER_LOADER_PARAMETER_PAGE_NUM 1 + +#define APP_RUN_START_ADDR_OFFSET 4 + +#define EFLASH_MAGIC_NUMBER 0xA37E95BD +#define EFLASH_MAGIC_OFFSET 0x04 + +#define BYTE_0 0 +#define BYTE_0_OFFSET 24 +#define BYTE_1 1 +#define BYTE_1_OFFSET 16 +#define BYTE_2 2 +#define BYTE_2_OFFSET 8 +#define BYTE_3 3 + +#define USER_LOADER_HANDSHAKE_TIMEOUT 1000 + +/** + * @brief Gets the value of a word in a char array. + * @param buffer the data array. + * @retval the value, unit : word. + */ +static unsigned int GetWordValue(unsigned char *buffer) +{ + unsigned int ret; + unsigned int i = 0; + if (buffer == NULL) { /* Null pointer check. */ + return 0; + } + + ret = buffer[i++] << BYTE_0_OFFSET; /* Highest 8 bits. */ + ret += buffer[i++] << BYTE_1_OFFSET; + ret += buffer[i++] << BYTE_2_OFFSET; + ret += buffer[i++]; + return ret; +} + +/** + * @brief Jump function. + * @param addr the target address of jump. + * @retval None. + */ +static void UserLoaderJump(unsigned int addr) +{ + /* Judgement flash empty */ + unsigned int *magic = (unsigned int *)(void *)addr; + if (*magic != EFLASH_MAGIC_NUMBER) { + while (1) { + ; + } + } + /* Jump to app run start address. */ + (*(void(*)(void))(addr + EFLASH_MAGIC_OFFSET))(); +} + +/** + * @brief User boot function. + * @param flash handle FLASH handle. + * @retval None. + */ +static void FlashInit(FLASH_Handle *flash) +{ + HAL_CRG_IpEnableSet(EFC_BASE, BASE_CFG_ENABLE); /* Enable the CRG of EFC modular. */ + flash->baseAddress = EFC; + flash->peMode = FLASH_PE_OP_BLOCK; + HAL_FLASH_Init(flash); /* Init flash. */ +} + +/** + * @brief User boot function. + * @param None. + * @retval None. + */ +void UserBoot(void) +{ + SystemInit(); /* Init peripheral module */ + unsigned char loaderParameter[USER_LOADER_PARAMETER_SIZE] = {0}; + unsigned int appRunStartAddr; + + ULOADER_Handle uloaderHandle; + FLASH_Handle flashHandle; + CRC_Handle crcHandle; + UART_Handle uart0Handle; + ULOADER_Cmd cmd; + + /* Init flash */ + FlashInit(&flashHandle); + /* Get the flage of OTA parameters. */ + HAL_FLASH_Read(&flashHandle, USER_PARAMTER_FLASH_START - FLASH_READ_BASE, + USER_LOADER_PARAMETER_SIZE, loaderParameter, USER_LOADER_PARAMETER_SIZE); + appRunStartAddr = GetWordValue(&loaderParameter[APP_RUN_START_ADDR_OFFSET]); + if (appRunStartAddr < USER_APP_RUN_INIT_ADDR || appRunStartAddr == 0xFFFFFFFF) { /* Check the address validity. */ + appRunStartAddr = USER_APP_RUN_INIT_ADDR; + } + + uloaderHandle.flash = &flashHandle; + uloaderHandle.crc = &crcHandle; + uloaderHandle.comHandle = (void *)&uart0Handle; + uloaderHandle.mode = COMMUNICATION_UART; + ULOADER_Init(&uloaderHandle); /* Init the module resources of user loader. */ + + /* User OTA progress */ + if (ULOADER_HandShake(&uloaderHandle, USER_LOADER_HANDSHAKE_TIMEOUT) == BASE_STATUS_OK) { + while (true) { + if (ULOADER_ReceiveCmd(&uloaderHandle, &cmd) != BASE_STATUS_OK) { + continue; + } + if (ULOADER_CommandExec(&uloaderHandle, &cmd) != BASE_STATUS_OK) { + ULOADER_Ack(&uloaderHandle, ACK_FAIL, 0); + } + } + } + + ULOADER_DeInit(&uloaderHandle); + /* Jump to app run start address. */ + UserLoaderJump(appRunStartAddr); +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_boot/user_boot.h b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_boot/user_boot.h new file mode 100644 index 0000000000000000000000000000000000000000..f48a1f1a2ea3b6a07a2b5c8fabb8d865224e398f --- /dev/null +++ b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_boot/user_boot.h @@ -0,0 +1,32 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_boot.h + * @author MCU Driver Team + * @brief This file provides the user boot function. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_USER_BOOT_H +#define McuMagicTag_USER_BOOT_H + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +void UserBoot(void); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_handshake_read.c b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_handshake_read.c new file mode 100644 index 0000000000000000000000000000000000000000..3e7a0163dce3b142d1d185c3ee20cbe6a4098b4d --- /dev/null +++ b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_handshake_read.c @@ -0,0 +1,170 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_handshake_read.c + * @author MCU Driver Team + * @brief This file provides the user handshake and read functions to manage the following functionalities of + * the user loader. + * + Receiving handshake frames functions. + * + UART, I2C, SPI read blocking adapt functions. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "user_handshake_read.h" + +/* Macro definitions --------------------------------------------------------- */ +#define SYSTICK_MS_DIV 1000 +#define ACK_SIZE 6 +#define RECEIVE_ONE_BYTE_DELAY_TIME 40 +#define RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME 500 + +/** + * @brief Check whether the automatic baud rate detection is complete. + * @param handle UART handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType IsActiveUart(UART_Handle *handle) +{ + if (handle->baseAddress->UART_RIS.BIT.abdcris == 1 && handle->baseAddress->UART_RIS.BIT.abderis == 0 && + handle->baseAddress->UART_ABDEN.BIT.abdbusy == 0) { + HAL_UART_DisableBaudDetectionEx(handle); /* Auto-baud detection complete. */ + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief User receive one byte. + * @param handle UART handle. + * @param targetByte the target byte. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType UartReceiveTargetByte(UART_Handle *handle, unsigned char targetData, unsigned int timeout) +{ + unsigned int preTick = DCL_SYSTICK_GetTick(); /* Get current tick. */ + unsigned int curTick; + unsigned long long delta = 0; + unsigned long long targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SYSTICK_MS_DIV * timeout; + unsigned char headFrame; + + while (true) { + /* Receives handshake frames sent by the host. */ + headFrame = DCL_UART_ReadData(handle->baseAddress); + if (headFrame == targetData) { + return BASE_STATUS_OK; + } + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* Check timeout. */ + break; + } + preTick = curTick; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief User loader receiving handshake frame. + * @param handle UART handle. + * @param buf Address of the data buffer to be saved. + * @param length the size of the data to be receiving. + * @param targetByte the target byte. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType UloaderReceiveHandShakeFrame(UART_Handle *handle, unsigned char *buf, unsigned int length, + unsigned char targetByte) +{ + BASE_StatusType ret; + if (IsActiveUart(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + /* Receives handshake frames sent ack frame to the host. */ + ret = HAL_UART_WriteBlocking(handle, buf, ACK_SIZE, RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + /* Receives handshake frames sent by the host. */ + ret = UartReceiveTargetByte(handle, targetByte, RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + buf[0] = targetByte; /* receive target byte, and then recive data. */ + ret = HAL_UART_ReadBlocking(handle, &buf[1], (length - 1), RECEIVE_HAND_SHAKE_FRAME_DELAY_TIME); + return ret; +} + +/** + * @brief Blocking read data in UART mode. + * @param handle UART handle. + * @param rData Address of the data buffer to be saved. + * @param dataSize the size of the data to be receiving. + * @param targetByte the target byte. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType ULOADER_UART_ReadBlocking(UART_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout) +{ + BASE_StatusType ret; + /* Receives handshake frames sent by the host. */ + ret = UartReceiveTargetByte(handle, targetByte, timeout); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + rData[0] = targetByte; /* receive target byte, and then recive data. */ + ret = HAL_UART_ReadBlocking(handle, &rData[1], (dataSize - 1), timeout); + return ret; +} + +/** + * @brief Blocking read data in I2C mode. + * @param handle I2C handle. + * @param rData Address of the data buffer to be saved. + * @param dataSize the size of the data to be receiving. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType ULOADER_I2C_ReadBlocking(I2C_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned int timeout) +{ + BASE_FUNC_UNUSED(handle); /* Compiler prevention alarm */ + BASE_FUNC_UNUSED(rData); + BASE_FUNC_UNUSED(dataSize); + BASE_FUNC_UNUSED(timeout); + return BASE_STATUS_OK; +} + +/** + * @brief Blocking read data in SPI mode. + * @param handle SPI handle. + * @param rData Address of the data buffer to be saved. + * @param dataSize the size of the data to be receiving. + * @param targetByte the target byte. + * @param timeout Timeout period, unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType ULOADER_SPI_ReadBlocking(SPI_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout) +{ + BASE_FUNC_UNUSED(handle); /* Compiler prevention alarm */ + BASE_FUNC_UNUSED(rData); + BASE_FUNC_UNUSED(dataSize); + BASE_FUNC_UNUSED(targetByte); + BASE_FUNC_UNUSED(timeout); + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_handshake_read.h b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_handshake_read.h new file mode 100644 index 0000000000000000000000000000000000000000..3f7b1db82ef7715b1879bf45d4e8387203d5eda1 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_handshake_read.h @@ -0,0 +1,49 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_handshake_read.h + * @author MCU Driver Team + * @brief This file provides the user handshake and read functions to manage the following functionalities of + * the user loader. + * + Receiving handshake frames functions. + * + UART, I2C, SPI read blocking adapt functions. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_USER_HADNSHAKE_READ_H +#define McuMagicTag_USER_HADNSHAKE_READ_H + +/* Includes ------------------------------------------------------------------*/ +#include "uart.h" +#include "uart_ex.h" +#include "i2c.h" +#include "i2c_ex.h" +#include "spi.h" +#include "spi_ex.h" +#include "can.h" +#include "iocmg.h" + +BASE_StatusType UloaderReceiveHandShakeFrame(UART_Handle *handle, unsigned char *buf, unsigned int lenth, + unsigned char targetByte); +BASE_StatusType ULOADER_UART_ReadBlocking(UART_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout); +BASE_StatusType ULOADER_I2C_ReadBlocking(I2C_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned int timeout); +BASE_StatusType ULOADER_SPI_ReadBlocking(SPI_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned char targetByte, unsigned int timeout); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_loader.c b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_loader.c new file mode 100644 index 0000000000000000000000000000000000000000..5d17a32d2538416857c486e636c4e19644adc748 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_loader.c @@ -0,0 +1,754 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_loader.c + * @author MCU Driver Team + * @brief This file provides the user loader structure and functions to manage the following functionalities of + * the user loader. + * + Initialization and de-initialization functions. + * + Handshake, command receiving, and command execution functions. + * + Read and write functions. + * + Atomic command function. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "user_handshake_read.h" +#include "user_loader.h" + +/* Macro definitions --------------------------------------------------------- */ +#define HANDSHAKE_FRAME_SIZE 9 + +#define DELAY_TIME 1000 +#define SYSTICK_MS_DIV 1000 +#define FRAME_CMD_OFFSET 0 +#define HEADER_COMMAND_HIGH 1 +#define HEADER_COMMAND_LOW 2 +#define COMMDNA_BASE_LENGHT 3 + +#define CRC_LAST_WIDTH 0x2 +#define ACK_FRAME_SIZE 6 +#define ACK_FRAME_TYPE_OFFSET 0 +#define ACK_FRAME_SEQ_OFFSET 1 +#define ACK_FRAME_INV_SEQ_OFFSET 2 +#define ACK_FRAME_RESULT_OFFSET 3 + +#define MAX_FRAME_DATA_SIZE 1024 /**< Max size of Frame Data Payload */ +#define MAX_FRAME_INDEX 254 + +#define FRAME_HEAD_TAIL_SIZE 5 +#define IMAGE_ADDR_OFFSET 1 /**< Image address offset field in header frame */ +#define IMAGE_SIZE_OFFSET 5 /**< Image size offset field in header frame */ +#define WRITE_ADDRESS_MUILYP 8 + +#define TRY_TIMES_WAIT 10 +#define DATA_HEAD_FRAME_SIZE 14 + +#define NEGOTIATE_FRAME_NUMS_POS 4 +#define NEGOTIATE_FRAME_SIZE_POS 8 + +#define ADDR_REMOVE_HIGH_POS 0xFFFFFF +#define OFFSET_LENGHT_THIRD 3 +#define OFFSET_LENGHT_SEVEN 7 +#define OFTHIRD 3 + +#define FLASH_ERASE_PAGE 1024 +#define ERASE_ADDRESS_MUILTYP 1024 + +#define BYTE_0 0 +#define BYTE_0_OFFSET 24 +#define BYTE_1 1 +#define BYTE_1_OFFSET 16 +#define BYTE_2 2 +#define BYTE_2_OFFSET 8 +#define BYTE_3 3 + +#define WAIT_ACK_FINISH_TIME 2 /* Wait until the ACK message is sent. */ + +#define PARAMETER_OFFSET_FLAG 1 +#define PARAMETER_OFFSET_COPY_START_ADDR 5 +#define PARAMETER_OFFSET_COPY_SIZE 9 +#define PARAMETER_OFFSET_BACKUP_ADDR 13 + +#define ULOADER_UART_BAND_RATE 115200 + +/** + * @brief Convert big-endian data to unsigned short. + * @param buf the buffer to store conversion data. + * @retval the value, unsigned short. + */ +static unsigned short ShiftToShort(unsigned char *buffer) +{ + if (buffer == NULL) { + return 0; + } + return (((buffer[0] << 0x08) & 0xff00) + (buffer[1] & 0xff)); +} + +/** + * @brief Convert big-endian data to unsigned short. + * @param data the data of be converted. + * @param buf the buffer to store conversion data. + * @retval None. + */ +static void UShortToBigEndian(unsigned short data, unsigned char *const buf) +{ + unsigned int i = 0; + buf[i++] = (unsigned char)((data >> 0x8) & 0xFF); /* get the higher 8 bit of unsigned short */ + buf[i] = (unsigned char)(data & 0xFF); +} + +/** + * @brief Convert an unsigned int into big-endian data of the char type for storage. + * @param data the data of be converted. + * @param buf the buffer to store conversion data. + * @retval None. + */ +static void UInitToBigEndian(unsigned int data, unsigned char *const buf) +{ + unsigned int i = 0; + buf[i++] = (unsigned char)((data >> BYTE_0_OFFSET) & 0xFF); /* get the higher 8 bit of unsigned short */ + buf[i++] = (unsigned char)((data >> BYTE_1_OFFSET) & 0xFF); + buf[i++] = (unsigned char)((data >> BYTE_2_OFFSET) & 0xFF); + buf[i] = (unsigned char)(data & 0xFF); +} + +/** + * @brief Get the value of min. + * @param a the compare of value. + * @param b the compare of value. + * @retval the data of min. + */ +static inline unsigned int GetMinValue(unsigned int a, unsigned int b) +{ + return a < b ? a : b; +} + +/** + * @brief Combines two pieces of data of the char type into one piece of data of the short type. + * @param highByte the high byte. + * @param lowByte the low byte. + * @retval the data, unsigned short. + */ +static inline unsigned short MergeToUshort(unsigned char highByte, unsigned char lowByte) +{ + return (highByte << 0x8) + lowByte; /* Make highByte in the high 8 bit */ +} + +/** + * @brief Convert big-endian data to unsigned int. + * @param buf the buffer to be converted. + * @retval the data, unsigned int. + */ +static inline unsigned int BigEndianToUint(const unsigned char *buf) +{ + unsigned int i = 0; + unsigned int sum; + if (buf == NULL) { /* Null pointer check. */ + return 0; + } + sum = buf[i++] << BYTE_0_OFFSET; /* Highest 8 bits. */ + sum += buf[i++] << BYTE_1_OFFSET; + sum += buf[i++] << BYTE_2_OFFSET; + sum += buf[i++]; + return sum; +} + +static void UloaderUart0PinInit(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_3_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_3_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_3_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_3_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_4_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_4_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_4_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_4_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +static void UloaderUart0PinDeInit(void) +{ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_3_AS_GPIO0_3); + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO0_4_AS_GPIO0_4); +} + +/** + * @brief Init the UART0 resources used by the user loader. + * @param handle User loader handle. + * @retval None. + */ +static void UloaderUart0Init(UART_Handle *handle) +{ + UloaderUart0PinInit(); + + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* UART0 clock enable. */ + handle->baseAddress = UART0; + + handle->baudRate = ULOADER_UART_BAND_RATE; /* The baudrate. */ + handle->dataLength = UART_DATALENGTH_8BIT; + handle->stopBits = UART_STOPBITS_ONE; + handle->parity = UART_PARITY_NONE; + handle->txMode = UART_MODE_BLOCKING; + handle->rxMode = UART_MODE_BLOCKING; + handle->fifoMode = BASE_CFG_ENABLE; + handle->fifoTxThr = UART_FIFODEPTH_SIZE6; + handle->fifoRxThr = UART_FIFODEPTH_SIZE6; + handle->hwFlowCtr = BASE_CFG_DISABLE; + handle->handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + handle->handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(handle); + HAL_UART_EnableBaudDetectionEx(handle); /* Enable baud auto detect. */ +} + +/** + * @brief Init the CRC resources used by the user loader. + * @param handle User loader handle. + * @retval None. + */ +static void UloaderCrcInit(CRC_Handle *handle) +{ + HAL_CRG_IpEnableSet(CRC_BASE, IP_CLK_ENABLE); /* Enable the CRG of CRC modular. */ + + handle->baseAddress = CRC; + handle->inputDataFormat = CRC_MODE_BIT8; /* Input data length is 8 byte. */ + handle->polyMode = CRC16_1021_POLY_MODE; + handle->initValueType = TYPE_CRC_INIT_VALUE_00; + handle->resultXorValueType = TYPE_CRC_XOR_VALUE_00; + handle->reverseEnableType = REVERSE_INPUT_FALSE_OUTPUT_FALSE; + handle->xorEndianEnbaleType = DISABLE_XOR_ENABLE_LSB; + HAL_CRC_Init(handle); /* Init CRC. */ +} + +/** + * @brief Init the flash resources used by the user loader. + * @param handle User loader handle. + * @retval None. + */ +static void UloaderFlashInit(FLASH_Handle *handle) +{ + HAL_CRG_IpEnableSet(EFC_BASE, BASE_CFG_SET); /* Enable the CRG of EFC modular. */ + handle->baseAddress = EFC; + handle->peMode = FLASH_PE_OP_BLOCK; + HAL_FLASH_Init(handle); /* Init flash. */ +} + +/** + * @brief Init the module resources of user loader. + * @param handle User loader handle. + * @retval BASE status type: OK, ERROR. + */ +void ULOADER_Init(ULOADER_Handle *handle) +{ + /* Reset crc\uart\flash */ + HAL_CRG_IpClkResetSet(CRC_BASE, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(UART0_BASE, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(EFC_BASE, BASE_CFG_SET); + /* Init crc\uart\flash */ + UloaderFlashInit(handle->flash); + UloaderUart0Init(handle->comHandle); /* If the communication protocols are different, change the value here. */ + UloaderCrcInit(handle->crc); +} + +/** + * @brief Deinit the module resources of user loader. + * @param handle User loader handle. + * @retval BASE status type: OK, ERROR. + */ +void ULOADER_DeInit(ULOADER_Handle *handle) +{ + /* Reset crc\uart\flash */ + HAL_CRG_IpClkResetSet(handle->comHandle, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(handle->crc, BASE_CFG_SET); + HAL_CRG_IpClkResetSet(handle->flash, BASE_CFG_SET); + UloaderUart0PinDeInit(); +} + +/** + * @brief Handshake negotiation function. + * @param handle User loader handle. + * @param timeout the value of timeout. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_HandShake(ULOADER_Handle *handle, unsigned int timeout) +{ + unsigned int preTick = DCL_SYSTICK_GetTick(); /* Get the current tick. */ + unsigned int curTick; + unsigned long long delta = 0; + /* Get the timeout of tick */ + unsigned long long targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SYSTICK_MS_DIV * timeout; + + unsigned char buf[HANDSHAKE_FRAME_SIZE] = {0}; + BASE_StatusType ret; + unsigned short receiveCrc; + unsigned short calculateCrc; + + while (true) { /* Receive data cyclically until timeout. */ + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* Check timeout. */ + return BASE_STATUS_TIMEOUT; + } + preTick = curTick; + + /* Response data in the configuration success state. */ + buf[ACK_FRAME_TYPE_OFFSET] = XACK; + buf[ACK_FRAME_SEQ_OFFSET] = 0x00; + buf[ACK_FRAME_INV_SEQ_OFFSET] = 0xff; + buf[ACK_FRAME_RESULT_OFFSET] = ACK_SUCCESS; + calculateCrc = HAL_CRC_Calculate(handle->crc, buf, ACK_FRAME_SIZE - 0x02); /* 2: crc length. */ + UShortToBigEndian(calculateCrc, &buf[ACK_FRAME_SIZE - 0x02]); + /* Receive handshake frame data. */ + ret = UloaderReceiveHandShakeFrame(handle->comHandle, buf, LENGTH_XHDSHK_FRAME, XHDSHK); + if (ret != BASE_STATUS_OK) { + continue; + } + /* Data Crc check. */ + receiveCrc = ShiftToShort(&buf[ACK_FRAME_SIZE + 0x01]); /* The offset of crc data. */ + calculateCrc = HAL_CRC_Calculate(handle->crc, buf, ACK_FRAME_SIZE + 0x01); + if (receiveCrc != calculateCrc) { + continue; + } + ULOADER_Ack(handle, ACK_SUCCESS, 0); + return BASE_STATUS_OK; + } +} + +/** + * @brief Receiving commands function. + * @param handle User loader handle. + * @param receiveCmd User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_ReceiveCmd(ULOADER_Handle *handle, ULOADER_Cmd *receiveCmd) +{ + /* receive command header and command. */ + unsigned char recvBuffer[LENGTH_XHEAD_FRAME] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; /* command size. */ + unsigned short cmdLength; + while (1) { + /* receive command header. */ + if (ULOADER_ReadDate(handle, recvBuffer, LENGTH_XHEAD_FRAME, XCMD, DELAY_TIME) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + if (recvBuffer[FRAME_CMD_OFFSET] != XCMD) { + ULOADER_Ack(handle, ACK_FAIL, 0); + return BASE_STATUS_ERROR; + } + if (recvBuffer[HEADER_COMMAND_HIGH] == 0xFF) { /* 0xFF: Judgement trail frame */ + ULOADER_Ack(handle, ACK_SUCCESS, XTAIL); + return BASE_STATUS_ERROR; + } + /* Command Header Check */ + ULOADER_Ack(handle, ACK_SUCCESS, 0); + /* Receive the boot cmd */ + cmdLength = MergeToUshort(recvBuffer[HEADER_COMMAND_HIGH], recvBuffer[HEADER_COMMAND_LOW]); + cmdLength = cmdLength + COMMDNA_BASE_LENGHT; /* 3:head + 2 crc */ + if (ULOADER_ReadDate(handle, (unsigned char *)receiveCmd, cmdLength, XKEY, DELAY_TIME) != BASE_STATUS_OK) { + ULOADER_Ack(handle, ACK_FAIL, receiveCmd->type); + return BASE_STATUS_ERROR; + } + if (receiveCmd->type != XKEY) { /* Received data is not destination bytes. */ + ULOADER_Ack(handle, ACK_FAIL, 0); + return BASE_STATUS_ERROR; + } + receiveCmd->type = receiveCmd->rcvBuf[0]; + receiveCmd->rcvBufLength = cmdLength; + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Command execution function. + * @param handle User loader handle. + * @param execCmd User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CommandExec(ULOADER_Handle *handle, ULOADER_Cmd *execCmd) +{ + /* Funciton transfer table. */ + switch (execCmd->type) { + case ATOMIS_WRITE: /* Write command */ + if (ULOADER_CMD_Write(handle, execCmd) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + case ATOMIS_ERASE: /* Erase command */ + if (ULOADER_CMD_Erase(handle, execCmd) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + case ATOMIS_UPDATE: /* Updata command */ + if (ULOADER_CMD_Update(handle, execCmd) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + case ATOMIS_RESET: /* Reset command */ + if (ULOADER_CMD_Reset(handle) == BASE_STATUS_OK) { + return BASE_STATUS_OK; + } + break; + default: + break; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Normalized write data. + * @param handle User loader handle. + * @param wData the buffer of receive data. + * @param dataSize the size of need receive. + * @param timeout the value of timeout. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_WriteDate(ULOADER_Handle *handle, unsigned char *wData, unsigned int dataSize, + unsigned int timeout) +{ + /* CRC produce. */ + unsigned int crc; + crc = HAL_CRC_Calculate(handle->crc, wData, dataSize - CRC_LAST_WIDTH); + UShortToBigEndian(crc, &wData[dataSize - CRC_LAST_WIDTH]); + + /* Send Data. */ + if (handle->mode == COMMUNICATION_UART) { + return HAL_UART_WriteBlocking((UART_Handle *)handle->comHandle, wData, dataSize, timeout); + } else if (handle->mode == COMMUNICATION_I2C) { + return HAL_I2C_SlaveWriteBlocking((I2C_Handle *)handle->comHandle, wData, dataSize, timeout); + } else if (handle->mode == COMMUNICATION_SPI) { + return HAL_SPI_WriteBlocking((SPI_Handle *)handle->comHandle, wData, dataSize, timeout); + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Normalized read data. + * @param handle User loader handle. + * @param rData the buffer of receive data. + * @param dataSize the size of need receive. + * @param targetByte the target byte. + * @param timeout the value of timeout. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_ReadDate(ULOADER_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned short targetByte, unsigned int timeout) +{ + BASE_StatusType ret; + unsigned int crcReceive = 0; + unsigned int crcCalculate = 0; + + /* Check the communication mode. */ + if (handle->mode == COMMUNICATION_UART) { + ret = ULOADER_UART_ReadBlocking((UART_Handle *)handle->comHandle, rData, dataSize, targetByte, timeout); + } else if (handle->mode == COMMUNICATION_I2C) { + ret = ULOADER_I2C_ReadBlocking((I2C_Handle *)handle->comHandle, rData, dataSize, timeout); + } else if (handle->mode == COMMUNICATION_SPI) { + ret = ULOADER_SPI_ReadBlocking((SPI_Handle *)handle->comHandle, rData, dataSize, targetByte, timeout); + } else { + return BASE_STATUS_ERROR; /* Illegal communication mode. */ + } + + /* CRC Check */ + if (ret == BASE_STATUS_OK) { + crcReceive = MergeToUshort(rData[dataSize - 0x2], rData[dataSize - 1]); + crcCalculate = HAL_CRC_Calculate(handle->crc, rData, dataSize - CRC_LAST_WIDTH); + if (crcReceive == crcCalculate) { + return BASE_STATUS_OK; + } + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Answering host. + * @param handle User loader handle. + * @param status answering status. + * @param index the index of frame to answer. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_Ack(ULOADER_Handle *handle, ACK_Status status, unsigned char index) + +{ + unsigned char frame[ACK_FRAME_SIZE]; + unsigned int sequence = index; + + /* Construct the Frame */ + frame[ACK_FRAME_TYPE_OFFSET] = XACK; + frame[ACK_FRAME_SEQ_OFFSET] = index; + frame[ACK_FRAME_INV_SEQ_OFFSET] = (unsigned char)(~sequence & 0xFF); + frame[ACK_FRAME_RESULT_OFFSET] = status; + + /* Write frame to host. */ + return ULOADER_WriteDate(handle, frame, ACK_FRAME_SIZE, DELAY_TIME); +} + +/** + * @brief Receives file head date from the host. + * @param handle User loader handle. + * @param buf the buffer of receive date. + * @param size the size of receive. + * @param perFrameSize Size of each frame to be transmitted. + * @param tryTimes retry Times After Failure. + * @retval BASE status type: OK, ERROR. + */ +static BASE_StatusType ReceiveFileHead(ULOADER_Handle *handle, unsigned char *buf, unsigned int size, + unsigned int *perFrameSize, unsigned char *tryTimes) +{ + unsigned int frameNums = 0; + unsigned char answer = 0; + unsigned int tempTryTime = 0; + + /* Number of retransmission times. */ + while (tempTryTime < TRY_TIMES_WAIT) { + /* Read file heade data. */ + if (ULOADER_ReadDate(handle, buf, DATA_HEAD_FRAME_SIZE, XHEAD, DELAY_TIME) != BASE_STATUS_OK) { + tempTryTime++; + continue; + } + + /* Negotiate frame size */ + frameNums = BigEndianToUint(&buf[NEGOTIATE_FRAME_NUMS_POS]); + if (frameNums > MAX_FRAME_INDEX) { + tempTryTime++; + ULOADER_Ack(handle, ACK_FAIL, 0); + continue; + } + + *perFrameSize = BigEndianToUint(&buf[NEGOTIATE_FRAME_SIZE_POS]); + if (*perFrameSize > MAX_FRAME_DATA_SIZE || *perFrameSize == 0) { + tempTryTime++; + ULOADER_Ack(handle, ACK_FAIL, 0); + continue; + } + + answer = size % *perFrameSize == 0 ? 0 : 1; + if (((size / *perFrameSize) + answer) != frameNums) { /* Data length integrity check. */ + /* Negotiate fail */ + tempTryTime++; + ULOADER_Ack(handle, ACK_FAIL, 0); + continue; + } + ULOADER_Ack(handle, ACK_SUCCESS, 0); + *tryTimes = tempTryTime; + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Receives data from the host. + * @param handle User loader handle. + * @param buf the buffer of receive date. + * @param remainLen Remaining transmission data volume. + * @param perFrameSize Size of each frame to be transmitted. + * @param addr the target of flash address. + * @retval BASE status type: OK, ERROR. + */ +static BASE_StatusType ReceiveFileDate(ULOADER_Handle *handle, unsigned char *buf, unsigned int remainLen, + unsigned int perFrameSize, unsigned int addr) +{ + BASE_StatusType ret; + unsigned char oldIdIndex = 0; + unsigned char tryTimes = 0; + unsigned int rcvLen; + unsigned int targetAddr = addr; + unsigned int targetremainLen = remainLen; + + /* Number of retransmission times. */ + while (tryTimes < TRY_TIMES_WAIT) { + /* Gets the minimum number of transfers for the last receive processing. */ + rcvLen = GetMinValue(targetremainLen, perFrameSize); + buf[1] = 0; + if (targetremainLen > 0) { /* There is still data to be received and continue to receive data. */ + if (ULOADER_ReadDate(handle, buf, rcvLen + FRAME_HEAD_TAIL_SIZE, XDATA, DELAY_TIME) != BASE_STATUS_OK) { + ULOADER_Ack(handle, ACK_FAIL, buf[1]); + tryTimes++; + continue; + } + } else { + /* There is no data to be received, and received file tail frame. */ + if (ULOADER_ReadDate(handle, buf, rcvLen + FRAME_HEAD_TAIL_SIZE, XTAIL, DELAY_TIME) != BASE_STATUS_OK) { + ULOADER_Ack(handle, ACK_FAIL, buf[1]); + tryTimes++; + continue; + } + } + /* Check the Sequence of Received Data Packets. */ + if ((buf[1] - oldIdIndex) != 1) { + ULOADER_Ack(handle, ACK_SUCCESS, oldIdIndex); + continue; + } + + /* Data info and trail judgement. */ + if (buf[0] == XTAIL && targetremainLen <= 0) { + /* Ack file trail frame. */ + ULOADER_Ack(handle, ACK_SUCCESS, buf[1]); + return BASE_STATUS_OK; + } + + /* Writes the received data to the flash memory. */ + ret = HAL_FLASH_WriteBlocking(handle->flash, (unsigned int)(buf + OFFSET_LENGHT_THIRD), + targetAddr & ADDR_REMOVE_HIGH_POS, + ((rcvLen + OFFSET_LENGHT_SEVEN) >> OFFSET_LENGHT_THIRD) << OFFSET_LENGHT_THIRD); + if (ret != BASE_STATUS_OK) { + tryTimes++; + ULOADER_Ack(handle, ACK_FAIL, buf[1]); /* Flash write error */ + continue; + } + + tryTimes = 0; /* Reset times. */ + ULOADER_Ack(handle, ACK_SUCCESS, buf[1]); + /* ID update and check. */ + oldIdIndex = buf[1]; + targetAddr += rcvLen; + targetremainLen -= rcvLen; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Write the flash page by atomic write command. + * @param handle User loader handle. + * @param command User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Write(ULOADER_Handle *handle, ULOADER_Cmd *command) +{ + BASE_StatusType ret; + unsigned int addr; + unsigned int size; + unsigned char tryTimes = 0; + unsigned int remainLen; + unsigned int perFrameSize = 0; + unsigned char buf[MAX_FRAME_DATA_SIZE + FRAME_HEAD_TAIL_SIZE]; + + /* Step1: Check the address validity. */ + addr = BigEndianToUint(&command->rcvBuf[IMAGE_ADDR_OFFSET]); /* Get the address of erase. */ + size = BigEndianToUint(&command->rcvBuf[IMAGE_SIZE_OFFSET]); /* Get the size of erase. */ + /* Address must be an integer multiple of 8, and size cannot be 0. */ + if (((addr % WRITE_ADDRESS_MUILYP) != 0) || size == 0) { + return BASE_STATUS_ERROR; + } + ULOADER_Ack(handle, ACK_SUCCESS, 0); + + /* Step2:Receive the file header frame. */ + remainLen = size; + ret = ReceiveFileHead(handle, buf, size, &perFrameSize, &tryTimes); + if (tryTimes == TRY_TIMES_WAIT || ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + /* Step3:Received data is written into the flash memory. */ + ret = ReceiveFileDate(handle, buf, remainLen, perFrameSize, addr); + return ret; +} + +/** + * @brief Erase the flash page by atomic erase command. + * @param handle User loader handle. + * @param command User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Erase(ULOADER_Handle *handle, ULOADER_Cmd *command) +{ + BASE_StatusType ret; + unsigned int addr; + unsigned int size; + + addr = BigEndianToUint(&command->rcvBuf[IMAGE_ADDR_OFFSET]); /* Get the address of erase. */ + size = BigEndianToUint(&command->rcvBuf[IMAGE_SIZE_OFFSET]); /* Get the size of erase. */ + /* Address must be an integer multiple of 1024. */ + if (((addr % ERASE_ADDRESS_MUILTYP) != 0)) { + return BASE_STATUS_ERROR; + } + /* The size must be an integer multiple of 1024 and not equal to 0. */ + if ((size == 0) || ((size % ERASE_ADDRESS_MUILTYP) != 0)) { + return BASE_STATUS_ERROR; + } + + /* Erase flash page. */ + ret = HAL_FLASH_EraseBlocking(handle->flash, FLASH_ERASE_MODE_PAGE, addr & ADDR_REMOVE_HIGH_POS, + size / FLASH_ERASE_PAGE); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + ULOADER_Ack(handle, ACK_SUCCESS, 0); + return BASE_STATUS_OK; +} + +/** + * @brief Updating OTA Parameters by atomic update command. + * @param handle User loader handle. + * @param command User loader command frame. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Update(ULOADER_Handle *handle, ULOADER_Cmd *command) +{ + BASE_StatusType ret; + unsigned char buf[FLASH_ERASE_PAGE]; + unsigned int upDateFlag; + unsigned int copyStartAddr; + unsigned int copySize; + unsigned int appBakAddr; + + upDateFlag = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_FLAG]); /* Get the firmware update flag. */ + copyStartAddr = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_COPY_START_ADDR]); /* Get the copy address. */ + copySize = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_COPY_SIZE]); /* Get the size of new firmware. */ + appBakAddr = BigEndianToUint(&command->rcvBuf[PARAMETER_OFFSET_BACKUP_ADDR]); /* Get the firmware backup address. */ + /* Read the flash page of upgrade parameters. */ + ret = HAL_FLASH_Read(handle->flash, (PARAMETER_ADDR - FLASH_READ_BASE), FLASH_ERASE_PAGE, buf, FLASH_ERASE_PAGE); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + /* Erase the flash page of upgrade parameters. */ + ret = HAL_FLASH_EraseBlocking(handle->flash, FLASH_ERASE_MODE_PAGE, PARAMETER_ADDR & ADDR_REMOVE_HIGH_POS, 1); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + /* Modify the parameter and assign a value. */ + UInitToBigEndian(upDateFlag, &buf[PARAMETER_OFFSET_FLAG - 0x01]); + UInitToBigEndian(copyStartAddr, &buf[PARAMETER_OFFSET_COPY_START_ADDR - 0x01]); + UInitToBigEndian(copySize, &buf[PARAMETER_OFFSET_COPY_SIZE - 0x01]); + UInitToBigEndian(appBakAddr, &buf[PARAMETER_OFFSET_BACKUP_ADDR - 0x01]); + /* Write the flash page of upgrade parameters. */ + ret = HAL_FLASH_WriteBlocking(handle->flash, (unsigned int)buf, PARAMETER_ADDR & ADDR_REMOVE_HIGH_POS, + FLASH_ERASE_PAGE); + if (ret != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + ULOADER_Ack(handle, ACK_SUCCESS, 0); + return BASE_STATUS_OK; +} + +/** + * @brief MCU reset by atomic reset command. + * @param handle User loader handle. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType ULOADER_CMD_Reset(ULOADER_Handle *handle) +{ + ULOADER_Ack(handle, ACK_SUCCESS, 0); + BASE_FUNC_DELAY_MS(WAIT_ACK_FINISH_TIME); /* Wait until the ACK message is sent. */ + BASE_FUNC_SoftReset(); + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_loader.h b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_loader.h new file mode 100644 index 0000000000000000000000000000000000000000..20cc48122bc2edab738ec7d8c63e4bef01dd1532 --- /dev/null +++ b/src/application/middleware_sample/ota/ota_overwrite_upgrade/user_loader/user_loader.h @@ -0,0 +1,127 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_loader.h + * @author MCU Driver Team + * @brief This file provides the user loader structure and functions to manage the following functionalities of + * the user loader. + * + Initialization and de-initialization functions. + * + Handshake, command receiving, and command execution functions. + * + Read and write functions. + * + Atomic command function. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_USER_LOADER_H +#define McuMagicTag_USER_LOADER_H + +/* Includes ------------------------------------------------------------------*/ +#include "flash.h" +#include "crc.h" +#include "uart.h" +#include "spi.h" +#include "i2c.h" +#include "can.h" +#include "crg.h" + +/* Macro definitions --------------------------------------------------------- */ +#define PARAMETER_ADDR 0x301FC00 +#define CMD_PAYLOAD_MAX 30 /**< Command payload length */ + +/* Frame header flag parameter. */ +#define XHDSHK 0xEB +#define XHEAD 0xFE +#define XDATA 0xDA +#define XTAIL 0xED +#define XACK 0xCB +#define XCMD 0xAB +#define XKEY 0xCD +#define XVER 0xCE + +/* The length of different frame. */ +#define LENGTH_XHDSHK_FRAME 9 +#define LENGTH_XHEAD_FRAME 5 +#define LENGTH_XCMD_FRAME 12 +#define LENGTH_XHDATA_FRAME 11 +#define LENGTH_XDATA_ADD_FRAME 5 +#define LENGTH_XEND_FRAME 6 +#define LENGTH_ACK_FRAME 6 + +/** + * @brief Atomis commands enumeration definition. + */ +enum { + ATOMIS_WRITE = 0xD2, /**< 0xD2: Download Image */ + ATOMIS_ERASE = 0xE4, /**< 0xE4: Get version information. */ + ATOMIS_RESET = 0x87, /**< 0x87: Reset MCU. */ + ATOMIS_UPDATE = 0x90, /**< 0x90: Update parameter settings. */ +}; + +/** + * @brief Communication mode enumeration definition. + */ +typedef enum { + COMMUNICATION_UART = 0, + COMMUNICATION_I2C = 1, + COMMUNICATION_SPI = 2, + COMMUNICATION_CAN = 3, +} COMMUNICATION_Mode; + +/** + * @brief Answering status enumeration definition. + */ +typedef enum { + ACK_FAIL = 0xA5, + ACK_SUCCESS = 0x5A, +} ACK_Status; + +/** + * @brief User loader command frame structure definition. + */ +typedef struct { + unsigned char type; /**< Command Type. */ + unsigned char rcvBuf[CMD_PAYLOAD_MAX]; /**< Command Buf All Command contents. */ + unsigned short rcvBufLength; /**< Buffer length. */ +} ULOADER_Cmd; + +/** + * @brief Module handle structure definition. + */ +typedef struct _ULOADER_Handle { + void *comHandle; /**< Register base address. */ + FLASH_Handle *flash; + CRC_Handle *crc; + COMMUNICATION_Mode mode; +} ULOADER_Handle; + +void ULOADER_Init(ULOADER_Handle *handle); +void ULOADER_DeInit(ULOADER_Handle *handle); +BASE_StatusType ULOADER_HandShake(ULOADER_Handle *handle, unsigned int timeout); +BASE_StatusType ULOADER_ReceiveCmd(ULOADER_Handle *handle, ULOADER_Cmd *receiveCmd); +BASE_StatusType ULOADER_CommandExec(ULOADER_Handle *handle, ULOADER_Cmd *execCmd); + +BASE_StatusType ULOADER_WriteDate(ULOADER_Handle *handle, unsigned char *wData, unsigned int dataSize, + unsigned int timeout); +BASE_StatusType ULOADER_ReadDate(ULOADER_Handle *handle, unsigned char *rData, unsigned int dataSize, + unsigned short targetByte, unsigned int timeout); +BASE_StatusType ULOADER_Ack(ULOADER_Handle *handle, ACK_Status status, unsigned char index); + +BASE_StatusType ULOADER_CMD_Write(ULOADER_Handle *handle, ULOADER_Cmd *command); +BASE_StatusType ULOADER_CMD_Erase(ULOADER_Handle *handle, ULOADER_Cmd *command); +BASE_StatusType ULOADER_CMD_Update(ULOADER_Handle *handle, ULOADER_Cmd *command); +BASE_StatusType ULOADER_CMD_Reset(ULOADER_Handle *handle); +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/inc/mcs_chip_config.h b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/inc/mcs_chip_config.h index 2fc50e46f57c28a0828d82b6cae64ab93bc3553d..2ee23d10deebf47eb2d520b6cae94fdca6bff473 100644 --- a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/inc/mcs_chip_config.h +++ b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/inc/mcs_chip_config.h @@ -25,7 +25,9 @@ #include "feature.h" -#ifdef CHIP_3061MNPICA +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNNIKA) || defined (CHIP_3061MNPIC8) || defined(CHIP_3061MNNIC8) || \ + defined (CHIP_3061MNPIK8) || defined (CHIP_3061MNNIK8) #define ADCPTT_HANDLE g_adc0 #define ADCRESIS_HANDLE g_adc0 @@ -51,7 +53,8 @@ #endif -#if defined (CHIP_3065HRPIRZ) || defined (CHIP_3065ARPIRZ) +#if defined (CHIP_3065HRPIRZ) || defined (CHIP_3065ARPIRZ) || defined (CHIP_3066MNPIRH) || \ + defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) #define ADCU_HANDLE g_adc0 #define ADCW_HANDLE g_adc1 @@ -71,11 +74,24 @@ #define ADC0COMPENSATE 2033.0f #define ADC1COMPENSATE 2070.0f +#endif + +#if defined (CHIP_3065HRPIRZ) || defined (CHIP_3065ARPIRZ) + #define QDMNUM QDM0 #define QDMIRQNUM IRQ_QDM0 #define QDMBASEADDR QDM0_BASE #endif +#if defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) || \ + defined (CHIP_3065PNPIRA) + + #define QDMNUM QDM2 + #define QDMIRQNUM IRQ_QDM2 + #define QDMBASEADDR QDM2_BASE + +#endif + #endif \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/readme.md b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/readme.md index 592524f05d71519a9f2ddcb106b006fe7d8b381b..bb2f3beb451adcaab882422918edd44dcafe7c4e 100644 --- a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/readme.md +++ b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/readme.md @@ -6,7 +6,7 @@ **【环境要求】** + 所有单板电源改制为演示用的24V低压,电机选用42JSF630AS-1000 + 电机ABZ编码器线序分别对应功率板上ABZ通道接口 -+ 电机(绿蓝黄)相线分别对应功率板上U/V/W通道接口 ++ 电机(黄绿蓝)相线分别对应功率板上U/V/W通道接口 **【IDE配置方法】** + chipConfig中的Sample栏目里面选中pmsm encode qdm 2shunt foc示例,然后点击生成代码即可 diff --git a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/src/mcs_motor_process.c b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/src/mcs_motor_process.c index d6be6bb9532c43e5abd22d269b8330719cc6100f..18821884d5187ab3c9dcb8f2e216c67b5af70610 100644 --- a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/src/mcs_motor_process.c +++ b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/src/mcs_motor_process.c @@ -60,7 +60,7 @@ #define ADC_READINIT_TIMES 20 #define ADC_TRIMVALUE_MIN 1800.0f #define ADC_TRIMVALUE_MAX 2200.0f -#define IRQ_QDM0_PRIORITY 7 /* the QDM encoder IRQ priority, highest */ +#define IRQ_QDM_PRIORITY 7 /* the QDM encoder IRQ priority, highest */ #define ENC_TIMES_NUM 5 /*------------------------------- Param Definition -----------------------------------------------*/ /* Motor parameters. */ @@ -119,7 +119,7 @@ static void POSCTRL_InitWrapper(POSCTRL_Handle *posHandle, float ts) .upperLim = POS_UPPERLIM, }; /* Position loop param init. */ - POSCTRL_Init(posHandle, &posPi, ts); + POSCTRL_Init(posHandle, &posPi, ts, USER_SPD_SLOPE); } /* Motor speed loop PI param. */ @@ -360,7 +360,7 @@ static void MCS_StartupSwitch(MTRCTRL_Handle *mtrCtrl) break; case STARTUP_STAGE_SPD: /* current frequency increase */ - if (mtrCtrl->motorSpinPos > 3) { /* 3 is motor rotations number in If mode */ + if (mtrCtrl->encReady >= 1) { /* 1 means enc is ready */ /* Stage change */ mtrCtrl->stateMachine = FSM_RUN; } else { @@ -502,7 +502,7 @@ static void TSK_SystickIsr(MTRCTRL_Handle *mtrCtrl, APT_RegStruct **aptAddr) POSCTRL_SetTarget(&mtrCtrl->posCtrl, 200.0 * DOUBLE_PI * g_motorParam.mtrNp); float posFbk = POSCTRL_AngleExpand(&mtrCtrl->posCtrl, mtrCtrl->axisAngle); if (mtrCtrl->sysTickCnt % 5 == 0) { /* 5 is Position loop division coefficient. */ - mtrCtrl->spdRefHz = POSCTRL_Exec(&mtrCtrl->posCtrl, mtrCtrl->posCtrl.posTarget, posFbk); + mtrCtrl->spdRefHz = POSCTRL_Exec(&mtrCtrl->posCtrl, posFbk); } } /* Speed loop control */ @@ -545,6 +545,9 @@ static void TrimInitAdcShiftValue(MTRCTRL_Handle *mtrCtrl) adc1TempSum += adc1SampleTemp; } } + if (adcSampleTimes < 1.0f) { + adcSampleTimes = 1.0f; /* Prevent divide-by-zero errors */ + } adc0SampleTemp = adc0TempSum / adcSampleTimes; adc1SampleTemp = adc1TempSum / adcSampleTimes; /* Force convert to float */ @@ -850,47 +853,6 @@ static void InitSoftware(void) g_mc.getEncAngSpd = GetEncAngSpd; /* Callback function for obtaining the encoder speed angle. */ } -/** - * @brief Config the master APT. - * @param aptx The master APT handle. - * @retval None. - */ -static void AptMasterSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - /* Config the master APT. */ - HAL_APT_MasterSyncInit(aptx, APT_SYNC_OUT_ON_CNTR_ZERO); -} - -/** - * @brief Config the slave APT. - * @param aptx The slave APT handle. - * @retval None. - */ -static void AptSalveSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - APT_SlaveSyncIn slave; - /* Config the slave APT. */ - slave.divPhase = 0; - slave.cntPhase = 0; - slave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; - slave.syncInSrc = APT_SYNC_IN_SRC; - slave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; - HAL_APT_SlaveSyncInit(aptx, &slave); -} -/** - * @brief Configuring Master and Slave APTs. - * @retval None. - */ -static void AptMasterSalveSet(void) -{ - /* motor fan APT master/slave synchronization */ - AptMasterSet(&g_apt0); - AptSalveSet(&g_apt1); - AptSalveSet(&g_apt2); -} - /** * @brief Config the KEY func. * @param handle The GPIO handle. @@ -943,7 +905,6 @@ int MotorMainProcess(void) HAL_TIMER_Start(&g_timer0); HAL_TIMER_Start(&g_timer1); - AptMasterSalveSet(); /* Disable PWM output before startup. */ MotorPwmOutputDisable(g_apt); /* Software initialization. */ @@ -954,7 +915,7 @@ int MotorMainProcess(void) qdmInit.qdmAddr = g_periph.qdm.qdmAddr; qdmInit.zPlusesIrqFunc = ISR_QdmzPulses; qdmInit.zPlusesNvic = &g_periph.qdm.zPulsesNvic; - qdmInit.zPlusesIrqPrio = IRQ_QDM0_PRIORITY; + qdmInit.zPlusesIrqPrio = IRQ_QDM_PRIORITY; MCS_QdmInit(&qdmInit); /* The initialization must be performed before the carrier interrupt is enabled. */ /* Start the PWM clock. */ diff --git a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/protocol.c b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/protocol.c index 987b4c5a591e80ddcb15271cd1ce31e277d4d5a7..e4ecf50612feff0506323fd883c313188680a097 100644 --- a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/protocol.c +++ b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/protocol.c @@ -132,7 +132,7 @@ void CUST_AckCode(unsigned char *txBuf, unsigned char ackCode, float varParams) /* End of Message */ txBuf[FRAME_ONE_CHAR_LENTH + i++] = FRAME_END; txLen = FRAME_ONE_CHAR_LENTH + i++; - HAL_UART_WriteIT(&g_uart0, txBuf, txLen); + HAL_UART_WriteDMA(&g_uart0, txBuf, txLen); } /** diff --git a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/uart_module.c b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/uart_module.c index 6b231c02a247ba3ffc0c25cb9f5f680b2b3b92dd..cffd9349402398a77d0126ef6669809ba07f99ea 100644 --- a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/uart_module.c +++ b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/uart_module.c @@ -34,9 +34,6 @@ /* Start sending data to host delay after uart connect success */ #define UART_UPDATA_DELAY_TIME_MS (50) -/* Uart baudrate */ -#define UART0BAUDRATE (1843200) - /* Data buffer */ unsigned char g_uartRxBuf[UI_RX_BUF_LEN] = {0}; unsigned char g_uartTxBuf[UI_TX_BUF_LEN] = {0}; @@ -45,6 +42,7 @@ static FRAME_Handle g_uartFrame; /** * @brief Receive Data Clear. * @param uartFrame Receice Data. + * @retval None. */ static void FrameRecvClear(FRAME_Handle *uartFrame) { @@ -57,11 +55,13 @@ static void FrameRecvClear(FRAME_Handle *uartFrame) /* Clear received flag. */ uartFrame->rxFlag = 0; uartFrame->upDataCnt = 0; + uartFrame->rxAckFlag = 0; } /** * @brief Set Dma status. * @param mtrCtrl The motor control handle. + * @retval None. */ static void SetUartDmaStatus(MTRCTRL_Handle *mtrCtrl) { @@ -77,20 +77,10 @@ static void SetUartDmaStatus(MTRCTRL_Handle *mtrCtrl) } } -/** - * @brief Set uart baudRate. - * @param baudrate Uart baudRate. - */ -static void SetUartBaudRate(unsigned int baudrate) -{ - /* Re_Write uart0 baudrate. */ - g_uart0.baudRate = baudrate; - HAL_UART_Init(&g_uart0); -} - /** * @brief Uart Dma interupt callback func. - * @param null. + * @param handle Uart handle. + * @retval None. */ void UART0_TXDMACallback(void *handle) { @@ -99,6 +89,11 @@ void UART0_TXDMACallback(void *handle) static unsigned int getlastSystickCnt = 0; /* USER CODE BEGIN UART0_WRITE_DMA_FINISH */ g_uartFrame.txFlag = 1; + /* Received information answered, information update reserved. */ + if (g_uartFrame.rxAckFlag == 1) { + g_uartFrame.uartItTxFlag = 1; + g_uartFrame.rxAckFlag = 0; + } getCurSystickCnt = DCL_SYSTICK_GetTick(); if (getlastSystickCnt != 0) { /* Calculate unit frame data send time */ @@ -108,22 +103,10 @@ void UART0_TXDMACallback(void *handle) /* USER CODE END UART0_WRITE_DMA_FINISH */ } -/** - * @brief Uart0 interruput Write CallBack Function. - * @param handle Uart handle. - */ -void UART0WriteInterruptCallback(void *handle) -{ - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_WRITE_IT_FINISH */ - g_uartFrame.uartItTxFlag = 1; - g_uartFrame.txFlag = 1; - /* USER CODE END UART0_WRITE_IT_FINISH */ -} - /** * @brief Uart0 Interruput Read CallBack Function. * @param handle Uart handle. + * @retval None. */ void UART0ReadInterruptCallback(void *handle) { @@ -144,18 +127,19 @@ void UART0ReadInterruptCallback(void *handle) /** * @brief Uart Read Data Init Function. * @param void. + * @retval None. */ void UartRecvInit(void) { /* Uart reception initialization */ FrameRecvClear(&g_uartFrame); - SetUartBaudRate(UART0BAUDRATE); HAL_UART_ReadIT(&g_uart0, &g_uartFrame.rxData, 1); } /** * @brief Uart Read Data Process Function. * @param mtrCtrl The motor control handle. + * @retval None. */ void UartModuleProcess_Rx(MTRCTRL_Handle *mtrCtrl) { @@ -170,6 +154,7 @@ void UartModuleProcess_Rx(MTRCTRL_Handle *mtrCtrl) g_uartFrame.timeOutCnt = 0; /* Execute data process. */ CUST_DataReceProcss(mtrCtrl, g_uartRxBuf); + g_uartFrame.rxAckFlag = 1; g_uartFrame.rxLen = 0; } } @@ -179,6 +164,7 @@ void UartModuleProcess_Rx(MTRCTRL_Handle *mtrCtrl) /** * @brief Uart Write Data Process Function. * @param mtrCtrl The motor control handle. + * @retval None. */ void UartModuleProcess_Tx(MTRCTRL_Handle *mtrCtrl) { @@ -192,7 +178,7 @@ void UartModuleProcess_Tx(MTRCTRL_Handle *mtrCtrl) unsigned int txLen = CUST_TransmitData(mtrCtrl, g_uartTxBuf); /* If txIT mode send data finish, convert to DMA mode */ if (g_uartFrame.uartItTxFlag == 1) { - HAL_UART_WriteDMA(&g_uart0, g_uartTxBuf, txLen); + HAL_UART_WriteDMA(&g_uart0, g_uartTxBuf, txLen); } } } diff --git a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/uart_module.h b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/uart_module.h index 1b3588ea132e4bafdfa4e831b9e4e8b0ad4efdd2..f1f8f89951fd2ab017f9ad6082a2542ca925aaaa 100644 --- a/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/uart_module.h +++ b/src/application/middleware_sample/pmsm_encode_qdm_2shunt_foc/user_interface/uart_module.h @@ -36,6 +36,7 @@ typedef struct { unsigned int upDataCnt; unsigned int upDataDelayCnt; unsigned char uartItTxFlag; + unsigned char rxAckFlag; } FRAME_Handle; diff --git a/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_chip_config.h b/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_chip_config.h index 2fc50e46f57c28a0828d82b6cae64ab93bc3553d..6542fd52f7a9a6a062d69ac384a5e55778cbf4c3 100644 --- a/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_chip_config.h +++ b/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_chip_config.h @@ -25,7 +25,9 @@ #include "feature.h" -#ifdef CHIP_3061MNPICA +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNNIKA) || defined (CHIP_3061MNPIC8) || defined(CHIP_3061MNNIC8) || \ + defined (CHIP_3061MNPIK8) || defined (CHIP_3061MNNIK8) #define ADCPTT_HANDLE g_adc0 #define ADCRESIS_HANDLE g_adc0 @@ -45,13 +47,10 @@ #define ADC0COMPENSATE 2037.0f #define ADC1COMPENSATE 2027.0f - #define QDMNUM QDM1 - #define QDMIRQNUM IRQ_QDM1 - #define QDMBASEADDR QDM1_BASE - #endif -#if defined (CHIP_3065HRPIRZ) || defined (CHIP_3065ARPIRZ) +#if defined (CHIP_3065HRPIRZ) || defined (CHIP_3065ARPIRZ) || defined (CHIP_3066MNPIRH) || \ + defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) #define ADCU_HANDLE g_adc0 #define ADCW_HANDLE g_adc1 @@ -71,11 +70,6 @@ #define ADC0COMPENSATE 2033.0f #define ADC1COMPENSATE 2070.0f - #define QDMNUM QDM0 - #define QDMIRQNUM IRQ_QDM0 - #define QDMBASEADDR QDM0_BASE - #endif - #endif \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_sensor_hall.h b/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_sensor_hall.h index 6913aaf099486a3ac5b841360eadc6ce4f1df3ea..f410e0c1ce53cecf57419d5f10b5a3231cb8f32f 100644 --- a/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_sensor_hall.h +++ b/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_sensor_hall.h @@ -47,7 +47,7 @@ typedef enum { SECTOR_SIX } HALL_SECTOR; -#define EANGLE0 (0.0f) +#define EANGLE0 (0.00f) #define EANGLE30 (0.5235988f) #define EANGLE60 (1.0471976f) #define EANGLE90 (1.5707963f) diff --git a/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_user_config.h b/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_user_config.h index b0ba33e96f65ccf4dba0cc6fc2d9d4af89c239cb..2ac01fef355c18244383277d4f27f29bb6f1b369 100644 --- a/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_user_config.h +++ b/src/application/middleware_sample/pmsm_hall_2shunt_foc/inc/mcs_user_config.h @@ -65,10 +65,10 @@ #define CURR_UPPERLIM (INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.95f) #define SPD_KP 0.01f -#define SPD_KI 0.1f +#define SPD_KI 0.03f #define SPD_LOWERLIM -1.0f #define SPD_UPPERLIM 1.0f -#define SIXSTEPTOFOC 20.0f +#define SIXSTEPTOFOC 3.0f /* Hall paramater config. */ #define HALL_PHASESHIFT ONE_PI diff --git a/src/application/middleware_sample/pmsm_hall_2shunt_foc/src/mcs_carrier.c b/src/application/middleware_sample/pmsm_hall_2shunt_foc/src/mcs_carrier.c index 826916427a1843eeb5fc72315a5b2bd4d0e8551f..12290ac6aceb4f50ccf90f711dd02be0b443f344 100644 --- a/src/application/middleware_sample/pmsm_hall_2shunt_foc/src/mcs_carrier.c +++ b/src/application/middleware_sample/pmsm_hall_2shunt_foc/src/mcs_carrier.c @@ -111,9 +111,9 @@ void MCS_CarrierProcess(MTRCTRL_Handle *mtrCtrl) /* If speed is over set Speed threshold, switch control angle */ if (Abs(mtrCtrl->hallSpeed) >= SIXSTEPTOFOC) { sixStepToFocAngleCnt++; - /* 3000 is delay tick,delay 3000 tick cut from sixwave angle to foc control, + /* 1000 is delay count,delay 1000 * 100 us time convert from sixwave angle to foc angle, make sure cut speed point is steady */ - if (sixStepToFocAngleCnt >= 3000) { + if (sixStepToFocAngleCnt >= 1000) { mtrCtrl->controlMode = FOC_CONTROLMODE_SPEED; } } else { diff --git a/src/application/middleware_sample/pmsm_hall_2shunt_foc/src/mcs_motor_process.c b/src/application/middleware_sample/pmsm_hall_2shunt_foc/src/mcs_motor_process.c index bf4742aa2f15c9f0f08df8e4bb19704149fae89e..1276ef25096fbefb40e51709b447572e7f9c8214 100644 --- a/src/application/middleware_sample/pmsm_hall_2shunt_foc/src/mcs_motor_process.c +++ b/src/application/middleware_sample/pmsm_hall_2shunt_foc/src/mcs_motor_process.c @@ -510,6 +510,9 @@ static void TrimInitAdcShiftValue(MTRCTRL_Handle *mtrCtrl) adc1TempSum += adc1SampleTemp; } } + if (adcSampleTimes < 1.0f) { + adcSampleTimes = 1.0f; /* Prevent divide-by-zero errors */ + } adc0SampleTemp = adc0TempSum / adcSampleTimes; adc1SampleTemp = adc1TempSum / adcSampleTimes; /* Force convert to float */ @@ -767,6 +770,13 @@ static unsigned int GetHallValue(void) unsigned int hallB = HAL_CAPM_GetCrtEdge(&g_capm0) & 0x01; unsigned int hallC = HAL_CAPM_GetCrtEdge(&g_capm1) & 0x01; #endif + +#if defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + /* Get three hall values. */ + unsigned int hallA = HAL_CAPM_GetCrtEdge(&g_capm1) & 0x01; + unsigned int hallB = HAL_CAPM_GetCrtEdge(&g_capm0) & 0x01; + unsigned int hallC = HAL_CAPM_GetCrtEdge(&g_capm2) & 0x01; +#endif /* WVU-+ --> H3H2H1-+ */ unsigned int retValue = (hallC << 2) + (hallB << 1) + (hallA << 0); return retValue; @@ -788,47 +798,6 @@ static void InitSoftware(void) TSK_Init(); } -/** - * @brief Config the master APT. - * @param aptx The master APT handle. - * @retval None. - */ -static void AptMasterSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - /* Config the master APT. */ - HAL_APT_MasterSyncInit(aptx, APT_SYNC_OUT_ON_CNTR_ZERO); -} - -/** - * @brief Config the slave APT. - * @param aptx The slave APT handle. - * @retval None. - */ -static void AptSalveSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - APT_SlaveSyncIn slave; - /* Config the slave APT. */ - slave.divPhase = 0; - slave.cntPhase = 0; - slave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; - slave.syncInSrc = APT_SYNC_IN_SRC; - slave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; - HAL_APT_SlaveSyncInit(aptx, &slave); -} -/** - * @brief Configuring Master and Slave APTs. - * @retval None. - */ -static void AptMasterSalveSet(void) -{ - /* motor fan APT master/slave synchronization */ - AptMasterSet(&g_apt0); - AptSalveSet(&g_apt1); - AptSalveSet(&g_apt2); -} - /** * @brief Config the KEY func. * @param handle The GPIO handle. @@ -880,7 +849,6 @@ int MotorMainProcess(void) HAL_TIMER_Start(&g_timer0); HAL_TIMER_Start(&g_timer1); - AptMasterSalveSet(); /* Disable PWM output before startup. */ MotorPwmOutputDisable(g_apt); /* Software initialization. */ diff --git a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/inc/mcs_chip_config.h b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/inc/mcs_chip_config.h index 4b7088d53813f7aa5f732fc5f578ef9fb7655100..49b2d2119ab7f8b8e7df96ea9f631dec3f899ae7 100644 --- a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/inc/mcs_chip_config.h +++ b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/inc/mcs_chip_config.h @@ -25,8 +25,9 @@ #include "feature.h" -#ifdef CHIP_3061MNPICA - +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNNIKA) || defined (CHIP_3061MNPIC8) || defined(CHIP_3061MNNIC8) || \ + defined (CHIP_3061MNPIK8) || defined (CHIP_3061MNNIK8) #define ADCPTT_HANDLE g_adc0 #define ADCRESIS_HANDLE g_adc0 #define ADCUDC_HANDLE g_adc0 @@ -47,7 +48,8 @@ #endif -#if defined (CHIP_3065HRPIRZ) || defined (CHIP_3065ARPIRZ) +#if defined (CHIP_3065HRPIRZ) || defined (CHIP_3065ARPIRZ) || defined (CHIP_3066MNPIRH) || \ + defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) #define ADCU_HANDLE g_adc0 #define ADCW_HANDLE g_adc1 diff --git a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/inc/mcs_user_config.h b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/inc/mcs_user_config.h index ca8614649f44a9e94555aa8a00f712a24f01ba16..be3dc2d1405b3f612c27f0ae0900d0203c561c3e 100644 --- a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/inc/mcs_user_config.h +++ b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/inc/mcs_user_config.h @@ -79,8 +79,8 @@ #define CURRQAXIS_KI 20612.84f #define CURRDAXIS_KP 3.477114f #define CURRDAXIS_KI 20612.84f -#define CURR_LOWERLIM (-INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.95f) -#define CURR_UPPERLIM (INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.95f) +#define CURR_LOWERLIM (-INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.98f) +#define CURR_UPPERLIM (INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.98f) #define SPD_KP 0.00505f #define SPD_KI 0.012f @@ -99,6 +99,7 @@ .mtrJ = 0.0f, \ .maxElecSpd = 180.25f, \ .maxCurr = 0.105f, \ + .busVolt = INV_VOLTAGE_BUS, \ } #define ADC_UDC_COFFI 0.01289f /* 0.01289 = 3.3/4096*192/12 */ diff --git a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/init/system_init.c b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/init/system_init.c index 1351b0c79659d64b5c2511219c07807f45347bae..b52db77d0db2d69aa8fc98c1eddf54813785fbf1 100644 --- a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/init/system_init.c +++ b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/init/system_init.c @@ -22,57 +22,82 @@ #include "main.h" #include "ioconfig.h" +#include "iocmg.h" -#define UART0_BAND_RATE 115200 +#define UART0_BAUD_RATE 921600 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { CRG_Handle crg; crg.baseAddress = CRG; - crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; /* pll ref clock hosc */ crg.pllPreDiv = CRG_PLL_PREDIV_4; crg.pllFbDiv = 32; /* PLL Multiplier 32 */ crg.pllPostDiv = CRG_PLL_POSTDIV_1; crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; - if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { /* crg init */ return BASE_STATUS_ERROR; } *coreClkSelect = crg.coreClkSelect; return BASE_STATUS_OK; } + +static void DMA_Channel0Init(void *handle) +{ + DMA_ChannelParam dma_param; + dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; /* memory to periph */ + dma_param.srcAddrInc = DMA_ADDR_INCREASE; /* addr increase */ + dma_param.destAddrInc = DMA_ADDR_UNALTERED; + dma_param.srcPeriph = DMA_REQUEST_MEM; /* source memory */ + dma_param.destPeriph = DMA_REQUEST_UART0_TX; /* destination uart0 tx */ + dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; + dma_param.destWidth = DMA_TRANSWIDTH_BYTE; + dma_param.srcBurst = DMA_BURST_LENGTH_1; + dma_param.destBurst = DMA_BURST_LENGTH_1; + dma_param.pHandle = handle; + HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ZERO); /* init dma channel */ +} + +static void DMA_Init(void) +{ + HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); + g_dmac.baseAddress = DMA; + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; /* small endian */ + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); /* register intterupt */ + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); + IRQ_EnableN(IRQ_DMA_TC); + IRQ_EnableN(IRQ_DMA_ERR); + HAL_DMA_Init(&g_dmac); /* dma init */ + + DMA_Channel0Init((void *)(&g_uart0)); +} + static void ACMP1_Init(void) { - HAL_CRG_IpEnableSet(ACMP1_BASE, BASE_CFG_ENABLE); + HAL_CRG_IpEnableSet(ACMP1_BASE, BASE_CFG_ENABLE); /* acmp clock enable */ g_acmp1.baseAddress = ACMP1_BASE; - /* config acmp */ - g_acmp1.enable = true; - g_acmp1.syncEn = false; g_acmp1.inOutConfig.vinNNum = ACMP_VIN_MUX3; g_acmp1.inOutConfig.vinPNum = ACMP_VIN_MUX3; g_acmp1.inOutConfig.swVinPNum = ACMP_SW_VIN3; g_acmp1.inOutConfig.swVinNNum = ACMP_SW_VIN3; g_acmp1.inOutConfig.polarity = ACMP_OUT_NOT_INVERT; /* none invert */ g_acmp1.filterCtrl.filterMode = ACMP_FILTER_NONE; /* none filter */ - g_acmp1.hysteresisVol = 0; /* 0: without hysteresis */ + g_acmp1.hysteresisVol = ACMP_HYS_VOL_30MV; /* 30mv: without hysteresis */ HAL_ACMP_Init(&g_acmp1); } static void ADC0_Init(void) { - HAL_CRG_IpEnableSet(ADC0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(ADC0_BASE, IP_CLK_ENABLE); /* adc clock enable */ HAL_CRG_IpClkSelectSet(ADC0_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); - HAL_CRG_IpClkDivSet(ADC0_BASE, CRG_ADC_DIV_5); + HAL_CRG_IpClkDivSet(ADC0_BASE, CRG_ADC_DIV_5); /* adc clock div 5 */ g_adc0.baseAddress = ADC0; g_adc0.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc0.vrefBuf = ADC_VREF_2P5V; - g_adc0.irqNumOver = IRQ_ADC0_OVINT; - g_adc0.ADC_IntxParam[0].irqNum = IRQ_ADC0_INT1; /* interrupt 0 */ - g_adc0.ADC_IntxParam[1].irqNum = IRQ_ADC0_INT2; /* interrupt 1 */ - g_adc0.ADC_IntxParam[2].irqNum = IRQ_ADC0_INT3; /* interrupt 2 */ - g_adc0.ADC_IntxParam[3].irqNum = IRQ_ADC0_INT4; /* interrupt 3 */ + g_adc0.handleEx.vrefBuf = ADC_VREF_2P5V; HAL_ADC_Init(&g_adc0); SOC_Param socParam = {0}; @@ -81,25 +106,20 @@ static void ADC0_Init(void) socParam.sampleTotalTime = 3; /* adc sample total time 3 adc_clk */ socParam.softTrigSource = ADC_TRIGSOC_NONESOFT; socParam.intTrigSource = ADC_TRIGSOC_NONEINT; - socParam.periphTrigSource = ADC_TRIGSOC_APT0_SOCA; + socParam.periphTrigSource = ADC_TRIGSOC_APT0_SOCA; /* sample triggle by apt0 soca */ socParam.finishMode = ADC_SOCFINISH_NONE; - HAL_ADC_ConfigureSoc(&g_adc0, ADC_SOC_NUM8, &socParam); + HAL_ADC_ConfigureSoc(&g_adc0, ADC_SOC_NUM8, &socParam); /* adc soc config */ } static void ADC1_Init(void) { - HAL_CRG_IpEnableSet(ADC1_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(ADC1_BASE, IP_CLK_ENABLE); /* adc clock enable */ HAL_CRG_IpClkSelectSet(ADC1_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); - HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); + HAL_CRG_IpClkDivSet(ADC1_BASE, CRG_ADC_DIV_5); /* adc clock div 5 */ g_adc1.baseAddress = ADC1; g_adc1.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc1.vrefBuf = ADC_VREF_2P5V; - g_adc1.irqNumOver = IRQ_ADC1_OVINT; - g_adc1.ADC_IntxParam[0].irqNum = IRQ_ADC1_INT1; /* interrupt 0 */ - g_adc1.ADC_IntxParam[1].irqNum = IRQ_ADC1_INT2; /* interrupt 1 */ - g_adc1.ADC_IntxParam[2].irqNum = IRQ_ADC1_INT3; /* interrupt 2 */ - g_adc1.ADC_IntxParam[3].irqNum = IRQ_ADC1_INT4; /* interrupt 3 */ + g_adc1.handleEx.vrefBuf = ADC_VREF_2P5V; HAL_ADC_Init(&g_adc1); @@ -110,35 +130,20 @@ static void ADC1_Init(void) socParam.sampleTotalTime = 3; /* adc sample total time 3 adc_clk */ socParam.softTrigSource = ADC_TRIGSOC_NONESOFT; socParam.intTrigSource = ADC_TRIGSOC_NONEINT; - socParam.periphTrigSource = ADC_TRIGSOC_APT0_SOCB; + socParam.periphTrigSource = ADC_TRIGSOC_APT0_SOCB; /* sample triggle by apt0 socb */ socParam.finishMode = ADC_SOCFINISH_NONE; HAL_ADC_ConfigureSoc(&g_adc1, ADC_SOC_NUM8, &socParam); - - socParam.adcInput = ADC_CH_ADCINB6; /* TSENSOR(ADC INB6) */ - - socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ - socParam.sampleTotalTime = 3; /* adc sample total time 3 adc_clk */ - socParam.softTrigSource = ADC_TRIGSOC_SOFT; - socParam.intTrigSource = ADC_TRIGSOC_NONEINT; - socParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; - socParam.finishMode = ADC_SOCFINISH_NONE; - HAL_ADC_ConfigureSoc(&g_adc1, ADC_SOC_NUM0, &socParam); } static void ADC2_Init(void) { - HAL_CRG_IpEnableSet(ADC2_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(ADC2_BASE, IP_CLK_ENABLE); /* adc clock enable */ HAL_CRG_IpClkSelectSet(ADC2_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); - HAL_CRG_IpClkDivSet(ADC2_BASE, CRG_ADC_DIV_5); + HAL_CRG_IpClkDivSet(ADC2_BASE, CRG_ADC_DIV_5); /* adc clock div 5 */ g_adc2.baseAddress = ADC2; g_adc2.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc2.vrefBuf = ADC_VREF_2P5V; - g_adc2.irqNumOver = IRQ_ADC2_OVINT; - g_adc2.ADC_IntxParam[0].irqNum = IRQ_ADC2_INT1; /* interrupt 0 */ - g_adc2.ADC_IntxParam[1].irqNum = IRQ_ADC2_INT2; /* interrupt 1 */ - g_adc2.ADC_IntxParam[2].irqNum = IRQ_ADC2_INT3; /* interrupt 2 */ - g_adc2.ADC_IntxParam[3].irqNum = IRQ_ADC2_INT4; /* interrupt 3 */ + g_adc2.handleEx.vrefBuf = ADC_VREF_2P5V; HAL_ADC_Init(&g_adc2); SOC_Param socParam = {0}; @@ -151,45 +156,44 @@ static void ADC2_Init(void) socParam.finishMode = ADC_SOCFINISH_NONE; HAL_ADC_ConfigureSoc(&g_adc2, ADC_SOC_NUM0, &socParam); - socParam.adcInput = ADC_CH_ADCINB2; /* PIN40(ADC INB2) */ + socParam.adcInput = ADC_CH_ADCINA7; /* PIN36(ADC INA7) */ socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ socParam.sampleTotalTime = 3; /* adc sample total time 3 adc_clk */ socParam.softTrigSource = ADC_TRIGSOC_SOFT; socParam.intTrigSource = ADC_TRIGSOC_NONEINT; socParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; socParam.finishMode = ADC_SOCFINISH_NONE; - HAL_ADC_ConfigureSoc(&g_adc2, ADC_SOC_NUM1, &socParam); + HAL_ADC_ConfigureSoc(&g_adc2, ADC_SOC_NUM14, &socParam); - socParam.adcInput = ADC_CH_ADCINA7; /* PIN36(ADC INA7) */ + socParam.adcInput = ADC_CH_ADCINB2; /* PIN40(ADC INB2) */ socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ socParam.sampleTotalTime = 3; /* adc sample total time 3 adc_clk */ socParam.softTrigSource = ADC_TRIGSOC_SOFT; socParam.intTrigSource = ADC_TRIGSOC_NONEINT; socParam.periphTrigSource = ADC_TRIGSOC_NONEPERIPH; socParam.finishMode = ADC_SOCFINISH_NONE; - HAL_ADC_ConfigureSoc(&g_adc2, ADC_SOC_NUM14, &socParam); + HAL_ADC_ConfigureSoc(&g_adc2, ADC_SOC_NUM1, &socParam); } -__weak void MotorSysErrCallback(void *handle) +__weak void MotorSysErrCallback(void *aptHandle) { - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN MotorSysErrCallback */ - /* USER CODE END MotorSysErrCallback */ + BASE_FUNC_UNUSED(aptHandle); + /* USER CODE BEGIN APT0_EVENT_INTERRUPT */ + /* USER CODE END APT0_EVENT_INTERRUPT */ } -__weak void MotorCarrierProcessCallback(void *handle) +__weak void MotorCarrierProcessCallback(void *aptHandle) { - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN MotorCarrierProcessCallback */ - /* USER CODE END MotorCarrierProcessCallback */ + BASE_FUNC_UNUSED(aptHandle); + /* USER CODE BEGIN APT0_TIMER_INTERRUPT */ + /* USER CODE END APT0_TIMER_INTERRUPT */ } static void APT0_ProtectInit(void) { APT_OutCtrlProtectEx protectApt = {0}; protectApt.ocEventEnEx = BASE_CFG_ENABLE; /* enable event protect */ - protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; - protectApt.cbcClrModeEx = APT_CLEAR_CBC_ON_CNTR_ZERO; + protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; /* protect mode one shot */ protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocEvtInterruptEnEx = BASE_CFG_ENABLE; @@ -198,7 +202,7 @@ static void APT0_ProtectInit(void) protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_ACMP1; /* extern event is from acmp1 */ protectApt.evtPolarityMaskEx = APT_EM_ACMP1_INVERT_BIT; protectApt.filterCycleNumEx = 0; - HAL_APT_ProtectInitEx(&g_apt0, &protectApt); + HAL_APT_ProtectInitEx(&g_apt0, &protectApt); /* apt protect init */ } static void APT0_Init(void) @@ -206,15 +210,11 @@ static void APT0_Init(void) HAL_CRG_IpEnableSet(APT0_BASE, IP_CLK_ENABLE); g_apt0.baseAddress = APT0; - g_apt0.irqNumEvt = IRQ_APT0_EVT; - g_apt0.irqNumTmr = IRQ_APT0_TMR; - /* Clock Settings */ g_apt0.waveform.dividerFactor = 1 - 1; /* Timer Settings */ g_apt0.waveform.timerPeriod = 10000; /* apt timer count period is 10000 */ g_apt0.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; - /* Wave Form */ g_apt0.waveform.basicType = APT_PWM_BASIC_A_HIGH_B_LOW; g_apt0.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; @@ -222,60 +222,53 @@ static void APT0_Init(void) g_apt0.waveform.divInitVal = 0; g_apt0.waveform.cntInitVal = 0; g_apt0.waveform.cntCmpLeftEdge = 5000; /* apt signal left edge moment is 5000 */ - g_apt0.waveform.cntCmpRightEdge = 5000; /* apt signal right edge moment is 5000 */ + g_apt0.waveform.cntCmpRightEdge = 4000; /* 4000 is count compare point of the right edge of PWM waveform */ g_apt0.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_apt0.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; g_apt0.waveform.deadBandCnt = 300; /* apt signal dead duration is 300 */ - /* ADC Trigger SOCA */ g_apt0.adcTrg.trgEnSOCA = BASE_CFG_ENABLE; g_apt0.adcTrg.cntCmpSOCA = 1; g_apt0.adcTrg.trgSrcSOCA = APT_CS_SRC_CNTR_CMPA_DOWN; g_apt0.adcTrg.trgScaleSOCA = 1; - /* ADC Trigger SOCB */ g_apt0.adcTrg.trgEnSOCB = BASE_CFG_ENABLE; g_apt0.adcTrg.cntCmpSOCB = 1; g_apt0.adcTrg.trgSrcSOCB = APT_CS_SRC_CNTR_CMPB_DOWN; g_apt0.adcTrg.trgScaleSOCB = 1; - g_apt0.adcTrg.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_apt0.adcTrg.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; - /* Timer Triggle */ g_apt0.tmrInterrupt.tmrInterruptEn = BASE_CFG_ENABLE; g_apt0.tmrInterrupt.tmrInterruptSrc = APT_INT_SRC_CNTR_ZERO; g_apt0.tmrInterrupt.tmrInterruptScale = 1; - APT0_ProtectInit(); HAL_APT_PWMInit(&g_apt0); + IRQ_Register(IRQ_APT0_EVT, HAL_APT_EventIrqHandler, &g_apt0); HAL_APT_RegisterCallBack(&g_apt0, APT_EVENT_INTERRUPT, MotorSysErrCallback); - IRQ_SetPriority(g_apt0.irqNumEvt, 7); /* apt system error interrupt priority is 7 */ - HAL_APT_IRQService(&g_apt0); - IRQ_EnableN(g_apt0.irqNumEvt); - HAL_APT_RegisterCallBack(&g_apt0, APT_TIMER_INTERRUPT, MotorCarrierProcessCallback); + IRQ_SetPriority(IRQ_APT0_EVT, 7); /* 7 is priority value */ + IRQ_EnableN(IRQ_APT0_EVT); - IRQ_SetPriority(g_apt0.irqNumTmr, 6); /* apt timer count interrupt priority is 6 */ - HAL_APT_IRQService(&g_apt0); - IRQ_EnableN(g_apt0.irqNumTmr); + IRQ_Register(IRQ_APT0_TMR, HAL_APT_TimerIrqHandler, &g_apt0); + HAL_APT_RegisterCallBack(&g_apt0, APT_TIMER_INTERRUPT, MotorCarrierProcessCallback); + IRQ_SetPriority(IRQ_APT0_TMR, 6); /* 6 is priority value */ + IRQ_EnableN(IRQ_APT0_TMR); } static void APT1_ProtectInit(void) { APT_OutCtrlProtectEx protectApt = {0}; - protectApt.ocEventEnEx = BASE_CFG_ENABLE; /* enable event protect */ - protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; - protectApt.cbcClrModeEx = APT_CLEAR_CBC_ON_CNTR_ZERO; + protectApt.ocEventEnEx = BASE_CFG_ENABLE; + protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; /* protect mode one shot */ protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocEvtInterruptEnEx = BASE_CFG_DISABLE; - /* config systerm error event protect */ protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_ACMP1; /* extern event is from acmp1 */ protectApt.evtPolarityMaskEx = APT_EM_ACMP1_INVERT_BIT; protectApt.filterCycleNumEx = 0; - HAL_APT_ProtectInitEx(&g_apt1, &protectApt); + HAL_APT_ProtectInitEx(&g_apt1, &protectApt); /* apt protect init */ } static void APT1_Init(void) @@ -283,27 +276,22 @@ static void APT1_Init(void) HAL_CRG_IpEnableSet(APT1_BASE, IP_CLK_ENABLE); g_apt1.baseAddress = APT1; - g_apt1.irqNumEvt = IRQ_APT1_EVT; - g_apt1.irqNumTmr = IRQ_APT1_TMR; - /* Clock Settings */ g_apt1.waveform.dividerFactor = 1 - 1; /* Timer Settings */ - g_apt1.waveform.timerPeriod = 10000; /* apt timer count period is 10000 */ + g_apt1.waveform.timerPeriod = 10000; /* 10000 is count period of APT time-base timer */ g_apt1.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; - /* Wave Form */ g_apt1.waveform.basicType = APT_PWM_BASIC_A_HIGH_B_LOW; g_apt1.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; g_apt1.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; g_apt1.waveform.divInitVal = 0; g_apt1.waveform.cntInitVal = 0; - g_apt1.waveform.cntCmpLeftEdge = 5000; /* apt signal left edge moment is 5000 */ - g_apt1.waveform.cntCmpRightEdge = 5000; /* apt signal right edge moment is 5000 */ + g_apt1.waveform.cntCmpLeftEdge = 5000; /* 5000 is count compare point of the left edge of PWM waveform */ + g_apt1.waveform.cntCmpRightEdge = 4000; /* 4000 is count compare point of the right edge of PWM waveform */ g_apt1.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_apt1.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; - g_apt1.waveform.deadBandCnt = 300; /* apt signal dead duration is 300 */ - + g_apt1.waveform.deadBandCnt = 300; /* 300 is dead-band value */ APT1_ProtectInit(); HAL_APT_PWMInit(&g_apt1); @@ -312,18 +300,16 @@ static void APT1_Init(void) static void APT2_ProtectInit(void) { APT_OutCtrlProtectEx protectApt = {0}; - protectApt.ocEventEnEx = BASE_CFG_ENABLE; /* enable event protect */ - protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; - protectApt.cbcClrModeEx = APT_CLEAR_CBC_ON_CNTR_ZERO; + protectApt.ocEventEnEx = BASE_CFG_ENABLE; + protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; /* protect mode one shot */ protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocEvtInterruptEnEx = BASE_CFG_DISABLE; - /* config systerm error event protect */ protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_ACMP1; /* extern event is from acmp1 */ protectApt.evtPolarityMaskEx = APT_EM_ACMP1_INVERT_BIT; protectApt.filterCycleNumEx = 0; - HAL_APT_ProtectInitEx(&g_apt2, &protectApt); + HAL_APT_ProtectInitEx(&g_apt2, &protectApt); /* apt protect init */ } static void APT2_Init(void) @@ -331,311 +317,354 @@ static void APT2_Init(void) HAL_CRG_IpEnableSet(APT2_BASE, IP_CLK_ENABLE); g_apt2.baseAddress = APT2; - g_apt2.irqNumEvt = IRQ_APT2_EVT; - g_apt2.irqNumTmr = IRQ_APT2_TMR; - /* Clock Settings */ g_apt2.waveform.dividerFactor = 1 - 1; /* Timer Settings */ - g_apt2.waveform.timerPeriod = 10000; /* apt timer count period is 10000 */ + g_apt2.waveform.timerPeriod = 10000; /* 10000 is count period of APT time-base timer */ g_apt2.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; - /* Wave Form */ g_apt2.waveform.basicType = APT_PWM_BASIC_A_HIGH_B_LOW; g_apt2.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; g_apt2.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; g_apt2.waveform.divInitVal = 0; g_apt2.waveform.cntInitVal = 0; - g_apt2.waveform.cntCmpLeftEdge = 5000; /* apt signal left edge moment is 5000 */ - g_apt2.waveform.cntCmpRightEdge = 5000; /* apt signal right edge moment is 5000 */ + g_apt2.waveform.cntCmpLeftEdge = 5000; /* 5000 is count compare point of the left edge of PWM waveform */ + g_apt2.waveform.cntCmpRightEdge = 4000; /* 4000 is count compare point of the right edge of PWM waveform */ g_apt2.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_apt2.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; - g_apt2.waveform.deadBandCnt = 300; /* apt signal dead duration is 300 */ - + g_apt2.waveform.deadBandCnt = 300; /* 300 is dead-band value */ APT2_ProtectInit(); HAL_APT_PWMInit(&g_apt2); } + __weak void MotorStartStopKeyCallback(void *param) { - /* user can define in application */ GPIO_Handle *handle = (GPIO_Handle *)param; BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN GPIO_INTERRUPT */ + /* USER CODE END GPIO_INTERRUPT */ } static void GPIO_Init(void) { - /* config gpio param */ + HAL_CRG_IpEnableSet(GPIO2_BASE, IP_CLK_ENABLE); /* gpio clock enable */ + g_gpio2.baseAddress = GPIO2; + g_gpio2.pins = GPIO_PIN_2; + HAL_GPIO_Init(&g_gpio2); /* init gpio2_2 */ + HAL_GPIO_SetDirection(&g_gpio2, g_gpio2.pins, GPIO_INPUT_MODE); + HAL_GPIO_SetValue(&g_gpio2, g_gpio2.pins, GPIO_HIGH_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio2, g_gpio2.pins, GPIO_INT_TYPE_LOW_LEVEL); + + g_gpio2.pins = GPIO_PIN_6; + HAL_GPIO_Init(&g_gpio2); /* init gpio2_6 */ + HAL_GPIO_SetDirection(&g_gpio2, g_gpio2.pins, GPIO_OUTPUT_MODE); + HAL_GPIO_SetValue(&g_gpio2, g_gpio2.pins, GPIO_HIGH_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio2, g_gpio2.pins, GPIO_INT_TYPE_NONE); + HAL_CRG_IpEnableSet(GPIO0_BASE, IP_CLK_ENABLE); g_gpio0.baseAddress = GPIO0; - g_gpio0.dir = GPIO_OUTPUT_MODE; - g_gpio0.value = GPIO_HIGH_LEVEL; - g_gpio0.interruptMode = GPIO_INT_TYPE_NONE; - g_gpio0.pins = GPIO_PIN_6 | GPIO_PIN_7; /* gpio0_6 is the LED D13, gpio0_7 is LED D15 */ - HAL_GPIO_Init(&g_gpio0); + g_gpio0.pins = GPIO_PIN_7 | GPIO_PIN_6; + HAL_GPIO_Init(&g_gpio0); /* init gpio0_6 and gpio0_7 */ + HAL_GPIO_SetDirection(&g_gpio0, g_gpio0.pins, GPIO_OUTPUT_MODE); + HAL_GPIO_SetValue(&g_gpio0, g_gpio0.pins, GPIO_HIGH_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio0, g_gpio0.pins, GPIO_INT_TYPE_NONE); - HAL_CRG_IpEnableSet(GPIO2_BASE, IP_CLK_ENABLE); - g_gpio2.baseAddress = GPIO2; - g_gpio2.dir = GPIO_INPUT_MODE; - g_gpio2.value = GPIO_HIGH_LEVEL; - g_gpio2.interruptMode = GPIO_INT_TYPE_LOW_LEVEL; - g_gpio2.pins = GPIO_PIN_2; /* motor start and stop key */ - HAL_GPIO_Init(&g_gpio2); - g_gpio2.dir = GPIO_OUTPUT_MODE; - g_gpio2.value = GPIO_HIGH_LEVEL; - g_gpio2.interruptMode = GPIO_INT_TYPE_NONE; - g_gpio2.pins = GPIO_PIN_6; - HAL_GPIO_Init(&g_gpio2); - /* register motor start and stop key callback, gpio2_2 */ HAL_GPIO_RegisterCallBack(&g_gpio2, GPIO_PIN_2, MotorStartStopKeyCallback); - g_gpio2.irqNum = IRQ_GPIO2; - HAL_GPIO_IRQService(&g_gpio2); - IRQ_SetPriority(g_gpio2.irqNum, 1); /* set gpio1 interrupt priority to 1, 1~7 */ - IRQ_EnableN(g_gpio2.irqNum); /* gpio interrupt enable */ + IRQ_Register(IRQ_GPIO2, HAL_GPIO_IrqHandler, &g_gpio2); + IRQ_SetPriority(IRQ_GPIO2, 1); /* set gpio1 interrupt priority to 1, 1~7. 1 */ + IRQ_EnableN(IRQ_GPIO2); /* gpio interrupt enable */ + return; } static void PGA0_Init(void) { - HAL_CRG_IpEnableSet(PGA0_BASE, IP_CLK_ENABLE); - /* config pga param */ + HAL_CRG_IpEnableSet(PGA0_BASE, IP_CLK_ENABLE); /* pga clock enable */ + g_pga0.baseAddress = PGA0_BASE; - g_pga0.enable = BASE_CFG_ENABLE; - g_pga0.extLoopbackEn = BASE_CFG_DISABLE; - g_pga0.pgaMux = PGA_EXT_RES_VI0; - g_pga0.gain = PGA_GAIN_1X; /* gain is 1 */ + g_pga0.externalResistorMode = BASE_CFG_ENABLE; /* pga external resistor mode */ + g_pga0.handleEx.pgaMux = PGA_EXT_RES_VI0; + g_pga0.gain = PGA_GAIN_1X; HAL_PGA_Init(&g_pga0); + DCL_PGA_EnableOut(g_pga0.baseAddress); + DCL_PGA_EnableExtOut(g_pga0.baseAddress); } __weak void CheckPotentiometerValueCallback(void *handle) { - HAL_TIMER_IrqClear((TIMER_Handle *)handle); - /* USER CODE BEGIN CheckPotentiometerValueCallback */ - /* USER CODE END CheckPotentiometerValueCallback */ + DCL_TIMER_IrqClear((TIMER_RegStruct *)handle); + /* USER CODE BEGIN TIMER0 ITCallBackFunc */ + /* USER CODE END TIMER0 ITCallBackFunc */ } static void TIMER0_Init(void) { - unsigned int load = HAL_CRG_GetIpFreq((void *)TIMER0) / 1000000u * 1000000; + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER0) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 1000000; - HAL_CRG_IpEnableSet(TIMER0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(TIMER0_BASE, IP_CLK_ENABLE); /* timer clock enable */ HAL_CRG_IpClkSelectSet(TIMER0_BASE, CRG_PLL_NO_PREDV); g_timer0.baseAddress = TIMER0; - g_timer0.irqNum = IRQ_TIMER0; g_timer0.load = load - 1; /* Set timer value immediately */ g_timer0.bgLoad = load - 1; /* Set timer value */ g_timer0.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ g_timer0.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ g_timer0.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer0.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer0.dmaReqEnable = BASE_CFG_DISABLE; g_timer0.interruptEn = BASE_CFG_ENABLE; HAL_TIMER_Init(&g_timer0); - HAL_TIMER_RegisterCallback(&g_timer0, CheckPotentiometerValueCallback); - IRQ_SetPriority(g_timer0.irqNum, 1); - IRQ_EnableN(g_timer0.irqNum); + IRQ_Register(IRQ_TIMER0, HAL_TIMER_IrqHandler, &g_timer0); + HAL_TIMER_RegisterCallback(&g_timer0, TIMER_PERIOD_FIN, CheckPotentiometerValueCallback); + IRQ_SetPriority(IRQ_TIMER0, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER0); } __weak void MotorStatemachineCallBack(void *handle) { - HAL_TIMER_IrqClear((TIMER_Handle *)handle); - /* USER CODE BEGIN MotorStatemachineCallBack */ - /* USER CODE END MotorStatemachineCallBack */ + DCL_TIMER_IrqClear((TIMER_RegStruct *)handle); + /* USER CODE BEGIN TIMER1 ITCallBackFunc */ + /* USER CODE END TIMER1 ITCallBackFunc */ } + static void TIMER1_Init(void) { - unsigned int load = HAL_CRG_GetIpFreq((void *)TIMER1) / 1000000u * 500; + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER1) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 500; + HAL_CRG_IpEnableSet(TIMER1_BASE, IP_CLK_ENABLE); HAL_CRG_IpClkSelectSet(TIMER1_BASE, CRG_PLL_NO_PREDV); g_timer1.baseAddress = TIMER1; - g_timer1.irqNum = IRQ_TIMER1; g_timer1.load = load - 1; /* Set timer value immediately */ g_timer1.bgLoad = load - 1; /* Set timer value */ g_timer1.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ g_timer1.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ g_timer1.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer1.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer1.dmaReqEnable = BASE_CFG_DISABLE; g_timer1.interruptEn = BASE_CFG_ENABLE; HAL_TIMER_Init(&g_timer1); - HAL_TIMER_RegisterCallback(&g_timer1, MotorStatemachineCallBack); - IRQ_SetPriority(g_timer1.irqNum, 1); - IRQ_EnableN(g_timer1.irqNum); + IRQ_Register(IRQ_TIMER1, HAL_TIMER_IrqHandler, &g_timer1); + HAL_TIMER_RegisterCallback(&g_timer1, TIMER_PERIOD_FIN, MotorStatemachineCallBack); + IRQ_SetPriority(IRQ_TIMER1, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER1); +} + +__weak void UART0WriteInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_WRITE_IT_FINISH */ + /* USER CODE END UART0_WRITE_IT_FINISH */ +} + +__weak void UART0ReadInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_READ_IT_FINISH */ + /* USER CODE END UART0_READ_IT_FINISH */ +} + +__weak void UART0InterruptErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ + /* USER CODE END UART0_TRNS_IT_ERROR */ +} + +__weak void UART0_TXDMACallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART0_WRITE_DMA_FINISH */ + /* USER CODE END UART0_WRITE_DMA_FINISH */ } static void UART0_Init(void) { - HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); /* uart clock enable */ HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); - /* config uart param */ + g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; - g_uart0.baudRate = UART0_BAND_RATE; /* baud rate is 115200 */ + g_uart0.baudRate = UART0_BAUD_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; - g_uart0.txMode = UART_MODE_BLOCKING; - g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.txMode = UART_MODE_DMA; /* dma mode */ + g_uart0.rxMode = UART_MODE_INTERRUPT; g_uart0.fifoMode = BASE_CFG_ENABLE; g_uart0.fifoTxThr = UART_FIFOFULL_ONE_TWO; g_uart0.fifoRxThr = UART_FIFOFULL_ONE_TWO; g_uart0.hwFlowCtr = BASE_CFG_DISABLE; HAL_UART_Init(&g_uart0); + HAL_UART_RegisterCallBack(&g_uart0, UART_WRITE_IT_FINISH, UART0WriteInterruptCallback); + HAL_UART_RegisterCallBack(&g_uart0, UART_READ_IT_FINISH, UART0ReadInterruptCallback); + HAL_UART_RegisterCallBack(&g_uart0, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); + IRQ_Register(IRQ_UART0, HAL_UART_IrqHandler, &g_uart0); + IRQ_SetPriority(IRQ_UART0, 2); /* 2 is priority value */ + IRQ_EnableN(IRQ_UART0); + g_uart0.dmaHandle = &g_dmac; + g_uart0.uartDmaTxChn = 0; + HAL_UART_RegisterCallBack(&g_uart0, UART_WRITE_DMA_FINISH, UART0_TXDMACallback); } static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_9.BIT.func = 0x0; /* 0x0 is GPIO0_6 */ - iconfig->iocmg_9.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_9.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_9.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_9.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_9.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_10.BIT.func = 0x0; /* 0x0 is GPIO0_7 */ - iconfig->iocmg_10.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_10.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_10.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_10.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_10.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_25.BIT.func = 0x0; /* 0x0 is GPIO2_6 */ - iconfig->iocmg_25.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_25.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_25.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_25.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_25.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_21.BIT.func = 0x0; /* 0x0 is GPIO2_2 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_26.BIT.func = 0x2; /* 0x2 is ACMP1_OUT */ - iconfig->iocmg_26.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_26.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_26.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_26.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_26.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_27.BIT.func = 0x9; /* 0x9 is ACMP1_ANA_N */ - iconfig->iocmg_27.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_27.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_27.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_27.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_27.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_28.BIT.func = 0x9; /* 0x9 is ACMP1_ANA_P */ - iconfig->iocmg_28.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_28.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_28.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_28.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_28.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_48.BIT.func = 0x8; /* 0x8 is ADC2_ANA_B1 */ - iconfig->iocmg_48.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_48.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_48.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_48.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_48.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_55.BIT.func = 0x8; /* 0x8 is ADC2_ANA_B2 */ - iconfig->iocmg_55.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_55.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_55.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_55.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_55.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_51.BIT.func = 0x8; /* 0x8 is ADC2_ANA_A7 */ - iconfig->iocmg_51.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_51.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_51.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_51.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_51.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_38.BIT.func = 0x9; /* 0x9 is PGA0_ANA_P */ - iconfig->iocmg_38.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_38.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_38.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_38.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_38.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_39.BIT.func = 0x9; /* 0x9 is PGA0_ANA_N */ - iconfig->iocmg_39.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_39.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_39.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_39.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_39.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_40.BIT.func = 0x8; /* 0x8 is PGA0_ANA_EXT */ - iconfig->iocmg_40.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_40.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_40.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_40.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_40.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_32.BIT.func = 0x3; /* 0x3 is APT0_PWMA */ - iconfig->iocmg_32.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_32.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_32.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_32.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_32.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_35.BIT.func = 0x3; /* 0x3 is APT0_PWMB */ - iconfig->iocmg_35.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_35.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_35.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_35.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_35.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_33.BIT.func = 0x3; /* 0x3 is APT1_PWMA */ - iconfig->iocmg_33.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_33.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_33.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_33.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_33.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_36.BIT.func = 0x3; /* 0x3 is APT1_PWMB */ - iconfig->iocmg_36.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_36.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_36.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_36.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_36.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_34.BIT.func = 0x3; /* 0x3 is APT2_PWMA */ - iconfig->iocmg_34.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_34.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_34.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_34.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_34.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_37.BIT.func = 0x3; /* 0x3 is APT2_PWMB */ - iconfig->iocmg_37.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_37.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_37.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_37.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_37.BIT.se = BASE_CFG_DISABLE; + HAL_IOCMG_SetPinAltFuncMode(IO15_AS_APT0_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO15_AS_APT0_PWMA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO15_AS_APT0_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO15_AS_APT0_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO15_AS_APT0_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO18_AS_APT0_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO18_AS_APT0_PWMB, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO18_AS_APT0_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO18_AS_APT0_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO18_AS_APT0_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO16_AS_APT1_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO16_AS_APT1_PWMA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO16_AS_APT1_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO16_AS_APT1_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO16_AS_APT1_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO19_AS_APT1_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO19_AS_APT1_PWMB, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO19_AS_APT1_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO19_AS_APT1_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO19_AS_APT1_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO17_AS_APT2_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO17_AS_APT2_PWMA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO17_AS_APT2_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO17_AS_APT2_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO17_AS_APT2_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO20_AS_APT2_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO20_AS_APT2_PWMB, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO20_AS_APT2_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO20_AS_APT2_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO20_AS_APT2_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO10_AS_ACMP1_OUT); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO10_AS_ACMP1_OUT, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO10_AS_ACMP1_OUT, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO10_AS_ACMP1_OUT, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO10_AS_ACMP1_OUT, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO11_AS_ACMP1_ANA_N3); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO11_AS_ACMP1_ANA_N3, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO11_AS_ACMP1_ANA_N3, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO11_AS_ACMP1_ANA_N3, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO11_AS_ACMP1_ANA_N3, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO12_AS_ACMP1_ANA_P3); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO12_AS_ACMP1_ANA_P3, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO12_AS_ACMP1_ANA_P3, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO12_AS_ACMP1_ANA_P3, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO12_AS_ACMP1_ANA_P3, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO21_AS_PGA0_ANA_P0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO21_AS_PGA0_ANA_P0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO21_AS_PGA0_ANA_P0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO21_AS_PGA0_ANA_P0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO21_AS_PGA0_ANA_P0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO22_AS_PGA0_ANA_N0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO22_AS_PGA0_ANA_N0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO22_AS_PGA0_ANA_N0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO22_AS_PGA0_ANA_N0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO22_AS_PGA0_ANA_N0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO23_AS_PGA0_ANA_EXT0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO23_AS_PGA0_ANA_EXT0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO23_AS_PGA0_ANA_EXT0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO23_AS_PGA0_ANA_EXT0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO23_AS_PGA0_ANA_EXT0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO31_AS_ADC2_ANA_B1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO31_AS_ADC2_ANA_B1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO31_AS_ADC2_ANA_B1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO31_AS_ADC2_ANA_B1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO31_AS_ADC2_ANA_B1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO36_AS_ADC2_ANA_A7); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO36_AS_ADC2_ANA_A7, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO36_AS_ADC2_ANA_A7, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO36_AS_ADC2_ANA_A7, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO36_AS_ADC2_ANA_A7, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO40_AS_ADC2_ANA_B2); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO40_AS_ADC2_ANA_B2, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO40_AS_ADC2_ANA_B2, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO40_AS_ADC2_ANA_B2, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO40_AS_ADC2_ANA_B2, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + /* UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_GPIO2_2); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_GPIO2_2, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_GPIO2_2, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_GPIO2_2, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_GPIO2_2, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO56_AS_GPIO0_7); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO56_AS_GPIO0_7, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO56_AS_GPIO0_7, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO56_AS_GPIO0_7, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO56_AS_GPIO0_7, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO55_AS_GPIO0_6); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO55_AS_GPIO0_6, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO55_AS_GPIO0_6, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO55_AS_GPIO0_6, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO55_AS_GPIO0_6, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(IO9_AS_GPIO2_6); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO9_AS_GPIO2_6, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO9_AS_GPIO2_6, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO9_AS_GPIO2_6, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO9_AS_GPIO2_6, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +static void APT_SyncMasterInit(void) +{ + HAL_APT_MasterSyncInit(&g_apt0, APT_SYNC_OUT_ON_CNTR_ZERO); /* APT master synchronize */ +} + +static void APT_SyncSlaveInit(void) +{ + APT_SlaveSyncIn aptSlave; + + aptSlave.divPhase = 1 - 1; /* divide phase value */ + aptSlave.cntPhase = 0; /* counter phase value 0 */ + aptSlave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_DOWN; + aptSlave.syncInSrc = APT_SYNCIN_SRC_APT0_SYNCOUT; /* sync source selection */ + aptSlave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; + HAL_APT_SlaveSyncInit(&g_apt1, &aptSlave); + + aptSlave.divPhase = 1 - 1; /* divide phase value */ + aptSlave.cntPhase = 0; /* counter phase value 0 */ + aptSlave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_DOWN; + aptSlave.syncInSrc = APT_SYNCIN_SRC_APT0_SYNCOUT; /* sync source selection */ + aptSlave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; + HAL_APT_SlaveSyncInit(&g_apt2, &aptSlave); } void SystemInit(void) { IOConfig(); + DMA_Init(); UART0_Init(); ACMP1_Init(); /* ACMP init */ APT0_Init(); /* APT init */ @@ -649,6 +678,9 @@ void SystemInit(void) TIMER1_Init(); GPIO_Init(); + APT_SyncMasterInit(); + APT_SyncSlaveInit(); + /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/readme.md b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/readme.md index b641f3edb09d1b2d94cb19f9ea4b9887465a6985..70328de125208983fdc67d8a6474bd001ef941ef 100644 --- a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/readme.md +++ b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/readme.md @@ -8,3 +8,8 @@ **【IDE配置方法】** + chipConfig中的Sample栏目里面选中pmsm sensorless 1shunt foc示例,然后点击生成代码即可 + +**【注意事项】** ++ 此示例init文件夹下的工程初始化配置是基于3065HRPIRZ芯片工程生成的。 ++ 不通过IDE创建生成场景:初始化配置请参考SDK sample下的init文件内容; ++ 通过IDE创建生成场景:初始化配置请参考user/generatecode下的文件内容。 diff --git a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/src/mcs_motor_process.c b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/src/mcs_motor_process.c index d3981aa529af7b17f95062fee6b06db734a22af4..7f6a8810803908b3a7c57533c70ec59b23ca950b 100644 --- a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/src/mcs_motor_process.c +++ b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/src/mcs_motor_process.c @@ -114,7 +114,7 @@ static void FOSMO_InitWrapper(FOSMO_Handle *fosmo, float ts) .pllBdw = FOSMO_PLL_BDW, }; /* Init smo param. */ - FOSMO_Init(fosmo, fosmoParam, g_motorParam, ts); + FOSMO_Init(fosmo, fosmoParam, &g_motorParam, ts); } /* Smo4th param. */ @@ -128,7 +128,7 @@ static void SMO4TH_InitWrapper(SMO4TH_Handle *smo4TH) .fcLpf = SMO4TH_SPD_FILTER_CUTOFF_FREQ, }; /* Init smo param. */ - SMO4TH_Init(smo4TH, smo4thParam, g_motorParam, CTRL_CURR_PERIOD); + SMO4TH_Init(smo4TH, smo4thParam, &g_motorParam, CTRL_CURR_PERIOD); } /*------------------------------- Function Definition -----------------------------------------------*/ @@ -538,6 +538,9 @@ static void TrimInitAdcShiftValue(MTRCTRL_Handle *mtrCtrl) adc1TempSum += adc1SampleTemp; } } + if (adcSampleTimes < 1.0f) { + adcSampleTimes = 1.0f; /* Prevent divide-by-zero errors */ + } adc0SampleTemp = adc0TempSum / adcSampleTimes; adc1SampleTemp = adc1TempSum / adcSampleTimes; /* Force convert to float */ @@ -624,7 +627,7 @@ static void SetADCTriggerTime(unsigned short cntCmpSOCA, unsigned short cntCmpSO */ static float TempTable(float tempResisValue) { - float boardTemp; + float boardTemp = 0.0f; /* Temperatures between 15 and 30. */ if (tempResisValue > TEMP_RES_30 && tempResisValue <= TEMP_RES_15) { boardTemp = TEMP_15 + (TEMP_30 - TEMP_15) * (TEMP_RES_15 - tempResisValue) / (TEMP_RES_15 - TEMP_RES_30); @@ -859,47 +862,6 @@ static void InitSoftware(void) g_mc.setADCTriggerTimeCb = SetADCTriggerTime; } -/** - * @brief Config the master APT. - * @param aptx The master APT handle. - * @retval None. - */ -static void AptMasterSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - /* Config the master APT. */ - HAL_APT_MasterSyncInit(aptx, APT_SYNC_OUT_ON_CNTR_ZERO); -} - -/** - * @brief Config the slave APT. - * @param aptx The slave APT handle. - * @retval None. - */ -static void AptSalveSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - APT_SlaveSyncIn slave; - /* Config the slave APT. */ - slave.divPhase = 0; - slave.cntPhase = 0; - slave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; - slave.syncInSrc = APT_SYNC_IN_SRC; - slave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; - HAL_APT_SlaveSyncInit(aptx, &slave); -} -/** - * @brief Configuring Master and Slave APTs. - * @retval None. - */ -static void AptMasterSalveSet(void) -{ - /* motor APT master/slave synchronization */ - AptMasterSet(&g_apt0); - AptSalveSet(&g_apt1); - AptSalveSet(&g_apt2); -} - /** * @brief Config the KEY func. * @param handle The GPIO handle. @@ -952,7 +914,6 @@ int MotorMainProcess(void) HAL_TIMER_Start(&g_timer0); HAL_TIMER_Start(&g_timer1); - AptMasterSalveSet(); /* Disable PWM output before startup. */ MotorPwmOutputDisable(g_apt); /* Software initialization. */ diff --git a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/cust_process.c b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/cust_process.c index 9836dc765691d2163bf75a2356653eb8eecf5981..c56ab4d15ddb6a59c17782a0d06ccc06516c4418 100644 --- a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/cust_process.c +++ b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/cust_process.c @@ -194,14 +194,15 @@ static void SetObserverSmo1thPLLParams(FOSMO_Handle *smoHandle, CUSTDATATYPE_DEF { /* Get command code. */ int cmdCode = (int)(rxData->data[DATA_SEGMENT_TWO].typeF); + float pllBdw = 0.0f; switch (cmdCode) { case SET_SMO1TH_PLL_BDW: /* Set the bandwidth. */ - smoHandle->pll.pllBdw = rxData->data[DATA_SEGMENT_THREE].typeF; - smoHandle->pll.pi.kp = 2.0f * smoHandle->pll.pllBdw; /* kp = 2.0f * pllBdw */ - smoHandle->pll.pi.ki = smoHandle->pll.pllBdw * smoHandle->pll.pllBdw; /* ki = pllBdw * pllBdw */ + pllBdw = rxData->data[DATA_SEGMENT_THREE].typeF; + smoHandle->pll.pi.kp = 2.0f * pllBdw; /* kp = 2.0f * pllBdw */ + smoHandle->pll.pi.ki = pllBdw * pllBdw; /* ki = pllBdw * pllBdw */ ackCode = 0X0A; - CUST_AckCode(g_uartTxBuf, ackCode, smoHandle->pll.pllBdw); + CUST_AckCode(g_uartTxBuf, ackCode, pllBdw); break; case SET_SMO1TH_SPDFLITER_FC: /* Set the cutoff frequency. */ smoHandle->spdFilter.fc = rxData->data[DATA_SEGMENT_THREE].typeF; @@ -255,11 +256,11 @@ static void SetObserverSmo4thParams(SMO4TH_Handle *smo4thHandle, CUSTDATATYPE_DE */ static void SetObserverSmo4thPLLParams(SMO4TH_Handle *smo4thHandle, CUSTDATATYPE_DEF *rxData) { - smo4thHandle->pll.pllBdw = rxData->data[DATA_SEGMENT_TWO].typeF; - smo4thHandle->pll.pi.kp = (2.0f) * smo4thHandle->pll.pllBdw; /* kp = 2.0f * pllBdw */ - smo4thHandle->pll.pi.ki = smo4thHandle->pll.pllBdw * smo4thHandle->pll.pllBdw; + float pllBdw = rxData->data[DATA_SEGMENT_TWO].typeF; + smo4thHandle->pll.pi.kp = (2.0f) * pllBdw; /* kp = 2.0f * pllBdw */ + smo4thHandle->pll.pi.ki = pllBdw * pllBdw; ackCode = 0X11; - CUST_AckCode(g_uartTxBuf, ackCode, smo4thHandle->pll.pllBdw); + CUST_AckCode(g_uartTxBuf, ackCode, pllBdw); } /** diff --git a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/protocol.c b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/protocol.c index f655ada5ea8933139bd474281337ea5360a24fa4..56f0c0bb3fa394c355dcbef7f6387270bf31dd67 100644 --- a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/protocol.c +++ b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/protocol.c @@ -132,7 +132,7 @@ void CUST_AckCode(unsigned char *txBuf, unsigned char ackCode, float varParams) /* End of Message */ txBuf[FRAME_ONE_CHAR_LENTH + i++] = FRAME_END; txLen = FRAME_ONE_CHAR_LENTH + i++; - HAL_UART_WriteIT(&g_uart0, txBuf, txLen); + HAL_UART_WriteDMA(&g_uart0, txBuf, txLen); } /** diff --git a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/uart_module.c b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/uart_module.c index 6b231c02a247ba3ffc0c25cb9f5f680b2b3b92dd..e01d7c8d81b732a35b5772f5f7d1db7b82c37be2 100644 --- a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/uart_module.c +++ b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/uart_module.c @@ -34,9 +34,6 @@ /* Start sending data to host delay after uart connect success */ #define UART_UPDATA_DELAY_TIME_MS (50) -/* Uart baudrate */ -#define UART0BAUDRATE (1843200) - /* Data buffer */ unsigned char g_uartRxBuf[UI_RX_BUF_LEN] = {0}; unsigned char g_uartTxBuf[UI_TX_BUF_LEN] = {0}; @@ -45,6 +42,7 @@ static FRAME_Handle g_uartFrame; /** * @brief Receive Data Clear. * @param uartFrame Receice Data. + * @retval None. */ static void FrameRecvClear(FRAME_Handle *uartFrame) { @@ -57,11 +55,13 @@ static void FrameRecvClear(FRAME_Handle *uartFrame) /* Clear received flag. */ uartFrame->rxFlag = 0; uartFrame->upDataCnt = 0; + uartFrame->rxAckFlag = 0; } /** * @brief Set Dma status. * @param mtrCtrl The motor control handle. + * @retval None. */ static void SetUartDmaStatus(MTRCTRL_Handle *mtrCtrl) { @@ -77,20 +77,10 @@ static void SetUartDmaStatus(MTRCTRL_Handle *mtrCtrl) } } -/** - * @brief Set uart baudRate. - * @param baudrate Uart baudRate. - */ -static void SetUartBaudRate(unsigned int baudrate) -{ - /* Re_Write uart0 baudrate. */ - g_uart0.baudRate = baudrate; - HAL_UART_Init(&g_uart0); -} - /** * @brief Uart Dma interupt callback func. - * @param null. + * @param handle Uart handle. + * @retval None. */ void UART0_TXDMACallback(void *handle) { @@ -99,6 +89,11 @@ void UART0_TXDMACallback(void *handle) static unsigned int getlastSystickCnt = 0; /* USER CODE BEGIN UART0_WRITE_DMA_FINISH */ g_uartFrame.txFlag = 1; + /* Received information answered, information update reserved. */ + if (g_uartFrame.rxAckFlag == 1) { + g_uartFrame.uartItTxFlag = 1; + g_uartFrame.rxAckFlag = 0; + } getCurSystickCnt = DCL_SYSTICK_GetTick(); if (getlastSystickCnt != 0) { /* Calculate unit frame data send time */ @@ -108,22 +103,10 @@ void UART0_TXDMACallback(void *handle) /* USER CODE END UART0_WRITE_DMA_FINISH */ } -/** - * @brief Uart0 interruput Write CallBack Function. - * @param handle Uart handle. - */ -void UART0WriteInterruptCallback(void *handle) -{ - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_WRITE_IT_FINISH */ - g_uartFrame.uartItTxFlag = 1; - g_uartFrame.txFlag = 1; - /* USER CODE END UART0_WRITE_IT_FINISH */ -} - /** * @brief Uart0 Interruput Read CallBack Function. * @param handle Uart handle. + * @retval None. */ void UART0ReadInterruptCallback(void *handle) { @@ -144,18 +127,19 @@ void UART0ReadInterruptCallback(void *handle) /** * @brief Uart Read Data Init Function. * @param void. + * @retval None. */ void UartRecvInit(void) { /* Uart reception initialization */ FrameRecvClear(&g_uartFrame); - SetUartBaudRate(UART0BAUDRATE); HAL_UART_ReadIT(&g_uart0, &g_uartFrame.rxData, 1); } /** * @brief Uart Read Data Process Function. * @param mtrCtrl The motor control handle. + * @retval None. */ void UartModuleProcess_Rx(MTRCTRL_Handle *mtrCtrl) { @@ -170,6 +154,7 @@ void UartModuleProcess_Rx(MTRCTRL_Handle *mtrCtrl) g_uartFrame.timeOutCnt = 0; /* Execute data process. */ CUST_DataReceProcss(mtrCtrl, g_uartRxBuf); + g_uartFrame.rxAckFlag = 1; g_uartFrame.rxLen = 0; } } @@ -179,6 +164,7 @@ void UartModuleProcess_Rx(MTRCTRL_Handle *mtrCtrl) /** * @brief Uart Write Data Process Function. * @param mtrCtrl The motor control handle. + * @retval None. */ void UartModuleProcess_Tx(MTRCTRL_Handle *mtrCtrl) { @@ -192,7 +178,7 @@ void UartModuleProcess_Tx(MTRCTRL_Handle *mtrCtrl) unsigned int txLen = CUST_TransmitData(mtrCtrl, g_uartTxBuf); /* If txIT mode send data finish, convert to DMA mode */ if (g_uartFrame.uartItTxFlag == 1) { - HAL_UART_WriteDMA(&g_uart0, g_uartTxBuf, txLen); + HAL_UART_WriteDMA(&g_uart0, g_uartTxBuf, txLen); } } } diff --git a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/uart_module.h b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/uart_module.h index 1b3588ea132e4bafdfa4e831b9e4e8b0ad4efdd2..f1f8f89951fd2ab017f9ad6082a2542ca925aaaa 100644 --- a/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/uart_module.h +++ b/src/application/middleware_sample/pmsm_sensorless_1shunt_foc/user_interface/uart_module.h @@ -36,6 +36,7 @@ typedef struct { unsigned int upDataCnt; unsigned int upDataDelayCnt; unsigned char uartItTxFlag; + unsigned char rxAckFlag; } FRAME_Handle; diff --git a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_carrier.h b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_carrier.h index 627f41c6d62a40b3b7ae4cc2a4e0a9217cd19ca0..dea3ad66fde865889d8480d222b97f3900bd7dac 100644 --- a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_carrier.h +++ b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_carrier.h @@ -82,59 +82,59 @@ typedef enum { * @brief Motor control data structure */ typedef struct { - unsigned char motorStateFlag; - float spdCmdHz; /**< External input speed command value */ - float axisAngle; /**< Angle of the synchronous coordinate system */ - float spdRefHz; /**< Command value after speed ramp management */ - float currCtrlPeriod; /**< current loop control period */ - float adc0Compensate; /**< ADC0 softwaretrim compensate value */ - float adc1Compensate; /**< ADC1 softwaretrim compensate value */ - float udc; /**< Bus voltage */ - float powerBoardTemp; /**< Power boart surface temperature */ - unsigned short aptMaxcntCmp; /**< Apt Maximum Comparison Count */ - float adcCurrCofe; /**< Adc current sampling cofeature */ + unsigned char motorStateFlag; /**< Motor start/stop status flag. */ + float spdCmdHz; /**< External input speed command value. */ + float axisAngle; /**< Angle of the synchronous coordinate system. */ + float spdRefHz; /**< Command value after speed ramp management. */ + float currCtrlPeriod; /**< current loop control period. */ + float adc0Compensate; /**< ADC0 softwaretrim compensate value. */ + float adc1Compensate; /**< ADC1 softwaretrim compensate value. */ + float udc; /**< Bus voltage. */ + float powerBoardTemp; /**< Power boart surface temperature. */ + unsigned short aptMaxcntCmp; /**< Apt Maximum Comparison Count. */ + float adcCurrCofe; /**< Adc current sampling cofeature. */ - unsigned short sysTickCnt; /**< System Timer Tick Count */ - unsigned short capChargeTickNum; /**< Bootstrap Capacitor Charge Tick Count */ + unsigned short sysTickCnt; /**< System Timer Tick Count. */ + unsigned short capChargeTickNum; /**< Bootstrap Capacitor Charge Tick Count. */ volatile unsigned int msTickCnt; /**< Millisecond-level counter, which can be used in 1-ms and 5-ms tasks. */ - unsigned short msTickNum; /**< Number of ticks corresponding to 1 ms */ - char obserType; /**< Set Observer Type */ - char controlMode; /**< Set foc control or sixstep bldc control mode or others */ - char spdAdjustMode; /**< Set speed adjust mode */ - char uartConnectFlag; /**< Uart connect success flag */ - short uartHeartDetCnt; /**< Uart connect heart detect count */ - float uartTimeStamp; /**< Uart data time stamp */ - SysStatusReg statusReg; /**< System status */ - FsmState stateMachine; /**< Motor Control State Machine */ + unsigned short msTickNum; /**< Number of ticks corresponding to 1 ms. */ + char obserType; /**< Set Observer Type. */ + char controlMode; /**< Set foc control or sixstep bldc control mode or others. */ + char spdAdjustMode; /**< Set speed adjust mode. */ + char uartConnectFlag; /**< Uart connect success flag. */ + short uartHeartDetCnt; /**< Uart connect heart detect count. */ + float uartTimeStamp; /**< Uart data time stamp. */ + SysStatusReg statusReg; /**< System status. */ + FsmState stateMachine; /**< Motor Control State Machine. */ - SampleMode sampleMode; /**< sample mode */ - MOTOR_Param mtrParam; /**< Motor parameters */ - FOSMO_Handle smo; /**< SMO observer handle */ - SMO4TH_Handle smo4th; /**< SMO 4th observer handle */ - IF_Handle ifCtrl; /**< I/F control handle */ - SVPWM_Handle sv; /**< SVPWM Handle */ - R1SVPWM_Handle r1Sv; /**< Single-resistance phase-shifted SVPWM handld */ - RMG_Handle spdRmg; /**< Ramp management struct for the speed controller input reference */ - SPDCTRL_Handle spdCtrl; /**< Speed loop Control Handle */ - CURRCTRL_Handle currCtrl; /**< Current loop control handle */ - STARTUP_Handle startup; /**< Startup Switch Handle */ - FW_Handle fw; /**< Flux-Weakening Handle */ + SampleMode sampleMode; /**< Current sampling mode setting: single resistor, double resistor. */ + MOTOR_Param mtrParam; /**< Motor parameters. */ + FOSMO_Handle smo; /**< SMO observer handle. */ + SMO4TH_Handle smo4th; /**< SMO 4th observer handle. */ + IF_Handle ifCtrl; /**< I/F control handle. */ + SVPWM_Handle sv; /**< Dual-resistance/three-resistance sampling SVPWM Handle. */ + R1SVPWM_Handle r1Sv; /**< Single-resistance phase-shifted SVPWM handle. */ + RMG_Handle spdRmg; /**< Ramp management struct for the speed controller input reference. */ + SPDCTRL_Handle spdCtrl; /**< Speed loop Control Handle. */ + CURRCTRL_Handle currCtrl; /**< Current loop control handle. */ + STARTUP_Handle startup; /**< Startup Switch Handle. */ + FW_Handle fw; /**< Flux-Weakening Handle. */ - DqAxis idqRef; /**< Command value of the dq axis current */ - UvwAxis currUvw; /**< Three-phase current sampling value */ - AlbeAxis iabFbk; /**< αβ-axis current feedback value */ - DqAxis idqFbk; /**< Current feedback value of the dq axis */ - DqAxis vdqRef; /**< Current loop output dq voltage */ - AlbeAxis vabRef; /**< Current loop output voltage αβ */ - UvwAxis dutyUvw; /**< UVW three-phase duty cycle */ - UvwAxis dutyUvwLeft; /**< Single Resistor UVW Three-Phase Left Duty Cycle */ - UvwAxis dutyUvwRight; /**< Single Resistor UVW Three-Phase Right Duty Cycle*/ + DqAxis idqRef; /**< Command value of the dq axis current. */ + UvwAxis currUvw; /**< Three-phase current sampling value. */ + AlbeAxis iabFbk; /**< αβ-axis current feedback value. */ + DqAxis idqFbk; /**< Current feedback value of the dq axis. */ + DqAxis vdqRef; /**< Current loop output dq voltage. */ + AlbeAxis vabRef; /**< Current loop output voltage αβ. */ + UvwAxis dutyUvw; /**< UVW three-phase duty cycle. */ + UvwAxis dutyUvwLeft; /**< Single Resistor UVW Three-Phase Left Duty Cycle. */ + UvwAxis dutyUvwRight; /**< Single Resistor UVW Three-Phase Right Duty Cycle. */ - MCS_ReadCurrUvwCb readCurrUvwCb; /**< Read current callback function */ + MCS_ReadCurrUvwCb readCurrUvwCb; /**< Read current callback function. */ MCS_SetPwmDutyCb setPwmDutyCb; /**< Set the duty cycle callback function. */ MCS_SetADCTriggerTimeCb setADCTriggerTimeCb; /**< Sets the ADC trigger point callback function. */ - MotorProtStatus_Handle prot; /**< Protection handle. */ + MotorProtStatus_Handle prot; /**< Motor protect status detection flag bit handle. */ } MTRCTRL_Handle; void MCS_CarrierProcess(MTRCTRL_Handle *mtrCtrl); diff --git a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_chip_config.h b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_chip_config.h index fbb9682691af7c2e32dc9fb164a97c84859b5cdf..38c00b5ddbf9f63ab1a2e5b644eea55d634727ad 100644 --- a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_chip_config.h +++ b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_chip_config.h @@ -25,7 +25,9 @@ #include "feature.h" -#ifdef CHIP_3061MNPICA +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNNIKA) || defined (CHIP_3061MNPIC8) || defined(CHIP_3061MNNIC8) || \ + defined (CHIP_3061MNPIK8) || defined (CHIP_3061MNNIK8) #define ADCPTT_HANDLE g_adc0 #define ADCRESIS_HANDLE g_adc0 @@ -47,7 +49,8 @@ #endif -#if defined (CHIP_3065HRPIRZ) || defined (CHIP_3065ARPIRZ) +#if defined (CHIP_3065HRPIRZ) || defined (CHIP_3065ARPIRZ) || defined (CHIP_3066MNPIRH) || \ + defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) #define ADCU_HANDLE g_adc0 #define ADCW_HANDLE g_adc1 diff --git a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_user_config.h b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_user_config.h index 4eff5446d903abd905e17fc0c34cd2f59094d668..054c25e259d2d0ae380204895a89e32f062938a9 100644 --- a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_user_config.h +++ b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/inc/mcs_user_config.h @@ -27,14 +27,14 @@ #define SMO4TH -#define SYSTICK_PERIOD_US 500u /* systick period */ +#define SYSTICK_PERIOD_US 500u /* systick period. */ -#define INV_CAP_CHARGE_MS 3u +#define INV_CAP_CHARGE_MS 3u /* Capacitor charging time. */ -#define INV_VOLTAGE_BUS 12.0f /* Bus voltage, V */ +#define INV_VOLTAGE_BUS 12.0f /* Bus voltage, V. */ -#define CTRL_CURR_PERIOD 0.0001f /* carrier ISR period, 100us */ -#define CTRL_SYSTICK_PERIOD 0.0005f /* systick control period, 500us */ +#define CTRL_CURR_PERIOD 0.0001f /* carrier ISR period, 100us. */ +#define CTRL_SYSTICK_PERIOD 0.0005f /* systick control period, 500us. */ /* Duty of sample window, the real time is 0.06*50us = 3us. */ #define SAMPLE_WINDOW_DUTY 0.06f @@ -43,53 +43,53 @@ #define SAMPLE_POINT_SHIFT 0.008f /* Sampling resistance 200mOhm 0.0013295 */ -#define ADC_CURR_COFFI 0.0013295f /* 3.3/4096/3.03/0.2 pga: 3.03, 200mohm */ -/* APT */ -#define APT_SYNC_IN_SRC APT_SYNCIN_SRC_APT0_SYNCOUT +#define ADC_CURR_COFFI 0.0013295f /* 3.3/4096/3.03/0.2 pga: 3.03, 200mohm. */ -#define APT_U APT0_BASE /* Base address of U phase APT module */ -#define APT_V APT1_BASE /* Base address of V phase APT module */ -#define APT_W APT2_BASE /* Base address of W phase APT module */ +#define APT_U APT0_BASE /* Base address of U phase APT module. */ +#define APT_V APT1_BASE /* Base address of V phase APT module. */ +#define APT_W APT2_BASE /* Base address of W phase APT module. */ /* FOSMO */ #define FOSMO_GAIN 4.0f /* SMO gain */ -#define FOSMO_LAMBDA 2.0f /* SMO coefficient of cut-off frequency, its value = lambda * we */ +#define FOSMO_LAMBDA 2.0f /* SMO coefficient of cut-off frequency, its value = lambda * we. */ #define FOSMO_EMF_CUTOFF_FREQ 2.0f /* SMO back emf cutoff frequency. */ -#define SPEED_FILTER_CUTOFF_FREQUENCY 40.0f /* SMO speed cutoff frequency. of speed filter. */ +#define SPEED_FILTER_CUTOFF_FREQUENCY 40.0f /* SMO speed cutoff frequency of speed filter. */ #define FOSMO_PLL_BDW 30.0f /* SMO PLL bandwidth. */ /* SMO4TH */ -#define SMO4TH_PLL_BDW 30.0f -#define SMO4TH_KD 300.0f -#define SMO4TH_KQ 600.0f -#define SMO4TH_SPD_FILTER_CUTOFF_FREQ 40.0f +#define SMO4TH_PLL_BDW 30.0f /* SMO4TH PLL Bandwidth. */ +#define SMO4TH_KD 300.0f /* SMO4TH parameters KD. */ +#define SMO4TH_KQ 600.0f /* SMO4TH parameters KQ. */ +#define SMO4TH_SPD_FILTER_CUTOFF_FREQ 40.0f /* SMO4TH speed cutoff frequency of speed filter. */ /* User_Commond */ -#define CTRL_IF_CURR_AMP_A 0.07f /* IF control current amplitude */ -#define USER_TARGET_SPD_HZ 100.0f /* Parentheses are used to enter negative instructions */ -#define USER_SWITCH_SPDBEGIN_HZ 30.0f /* Start of handover interval */ -#define USER_SWITCH_SPDEND_HZ (USER_SWITCH_SPDBEGIN_HZ + 3.0f) /* End of handover period */ -#define USER_MAX_SPD_HZ 180.25f -#define USER_MIN_SPD_HZ 35.0f -#define USER_SPD_SLOPE 50.0f /* slope of velocity change */ -#define USER_CURR_SLOPE (CTRL_IF_CURR_AMP_A * 10.0f) /* Current change slope */ +#define CTRL_IF_CURR_AMP_A 0.07f /* IF control current amplitude. */ +#define USER_TARGET_SPD_HZ 100.0f /* User-defined target speed value. */ +#define USER_SWITCH_SPDBEGIN_HZ 30.0f /* Start of handover interval. */ +#define USER_SWITCH_SPDEND_HZ (USER_SWITCH_SPDBEGIN_HZ + 3.0f) /* End of handover period. */ +#define USER_MAX_SPD_HZ 180.25f /* User-defined maximum speed value. */ +#define USER_MIN_SPD_HZ 35.0f /* User-defined minimum speed value. */ +#define USER_SPD_SLOPE 50.0f /* slope of velocity change. */ +#define USER_CURR_SLOPE (CTRL_IF_CURR_AMP_A * 10.0f) /* Current change slope. */ /* PID PARAMS */ -#define CURRQAXIS_KP 5.023202f -#define CURRQAXIS_KI 20612.84f -#define CURRDAXIS_KP 3.477114f -#define CURRDAXIS_KI 20612.84f -#define CURR_LOWERLIM (-INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.95f) -#define CURR_UPPERLIM (INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.95f) - -#define SPD_KP 0.00505f -#define SPD_KI 0.012f -#define SPD_LOWERLIM -0.105f -#define SPD_UPPERLIM 0.105f +#define CURRQAXIS_KP 5.023202f /* Current loop Q axis Kp. */ +#define CURRQAXIS_KI 20612.84f /* Current loop Q axis Ki. */ +#define CURRDAXIS_KP 3.477114f /* Current loop D axis Kp. */ +#define CURRDAXIS_KI 20612.84f /* Current loop D axis Ki. */ +/* Current loop PID output lower limit. */ +#define CURR_LOWERLIM (-INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.98f) +/* Current loop PID output upper limit. */ +#define CURR_UPPERLIM (INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 0.98f) + +#define SPD_KP 0.00505f /* Speed loop Kp. */ +#define SPD_KI 0.012f /* Speed loop Ki. */ +#define SPD_LOWERLIM (-0.105f) /* Speed loop PID output lower limit. */ +#define SPD_UPPERLIM 0.105f /* Speed loop PID output upper limit. */ /* MOTOR PARAMS */ -/* Np, Rs, Ld, Lq, Psif, J, Nmax, Currmax, PPMR, zShift */ -/* mtrPsif & mtrJ parameter is not used in this project, temporarily set to 0 */ +/* Np, Rs, Ld, Lq, Psif, J, Nmax, Currmax, PPMR, zShift. */ +/* mtrPsif & mtrJ parameter is not used in this project, temporarily set to 0. */ #define MOTORPARAM_DEFAULTS { \ .mtrNp = 7, \ .mtrRs = 5.1f, \ @@ -99,8 +99,10 @@ .mtrJ = 0.0f, \ .maxElecSpd = 180.25f, \ .maxCurr = 0.105f, \ + .busVolt = INV_VOLTAGE_BUS, \ } -#define ADC_UDC_COFFI 0.01289f /* 0.01289 = 3.3/4096*192/12 */ +/* Bus voltage sampling conversion factor. */ +#define ADC_UDC_COFFI 0.01289f /* 0.01289 = 3.3/4096*192/12. */ #endif \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/main.c b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/main.c index 47884b3b3e4a158650604d182633094bed12f7a3..c29ded167454e080388d30ab55d994f5627ad0ff 100644 --- a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/main.c +++ b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/main.c @@ -25,6 +25,8 @@ #include "mcs_motor_process.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ ACMP_Handle g_acmp1; PGA_Handle g_pga0; @@ -42,23 +44,29 @@ DMA_Handle g_dmac; GPIO_Handle g_gpio0; GPIO_Handle g_gpio2; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ MotorMainProcess(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/main.h b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/main.h index b15b8dcc618c00bee598588f0a973715287cd75f..6d6390b34d6eac79f39183fd4f07d3486745ce1f 100644 --- a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/main.h +++ b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/main.h @@ -25,6 +25,7 @@ #define McuMagicTag_SYSTEM_INIT_H #include "adc.h" +#include "adc_ex.h" #include "acmp.h" #include "apt.h" #include "uart.h" @@ -75,12 +76,16 @@ void MotorCarrierProcessCallback(void *aptHandle); void MotorSysErrCallback(void *aptHandle); void CheckPotentiometerValueCallback(void *handle); void MotorStatemachineCallBack(void *handle); -void UART0WriteInterruptCallback(UART_Handle *handle); -void UART0ReadInterruptCallback(UART_Handle *handle); -void UART0InterruptErrorCallback(UART_Handle *handle); +void UART0WriteInterruptCallback(void *handle); +void UART0ReadInterruptCallback(void *handle); +void UART0InterruptErrorCallback(void *handle); -void UART0_TXDMACallback(UART_Handle *handle); +void UART0_TXDMACallback(void *handle); void MotorStartStopKeyCallback(void *param); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/system_init.c b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/system_init.c index 23b3f0f3362f0aaeec7811cc2c2b5e20bde7fe81..8accd5fbb7200f786b529b5dcda52a98f5dfda7d 100644 --- a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/system_init.c +++ b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/init/system_init.c @@ -24,7 +24,7 @@ #include "ioconfig.h" #include "iocmg.h" -#define UART0_BAND_RATE 921600 +#define UART0_BAUD_RATE 921600 BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) { @@ -45,20 +45,20 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void DMA_Channel0Init(void *handle) { - /* enable DMA function for uart data transfer */ + /* enable DMA function for uart data transfer */ DMA_ChannelParam dma_param; dma_param.direction = DMA_MEMORY_TO_PERIPH_BY_DMAC; dma_param.srcAddrInc = DMA_ADDR_INCREASE; dma_param.destAddrInc = DMA_ADDR_UNALTERED; dma_param.srcPeriph = DMA_REQUEST_MEM; - /* enable UART0 tx mode DMA */ + /* enable UART0 tx mode DMA */ dma_param.destPeriph = DMA_REQUEST_UART0_TX; dma_param.srcWidth = DMA_TRANSWIDTH_BYTE; dma_param.destWidth = DMA_TRANSWIDTH_BYTE; dma_param.srcBurst = DMA_BURST_LENGTH_1; dma_param.destBurst = DMA_BURST_LENGTH_1; dma_param.pHandle = handle; - /* init DMA config module */ + /* init DMA config module */ HAL_DMA_InitChannel(&g_dmac, &dma_param, DMA_CHANNEL_ZERO); } @@ -66,11 +66,10 @@ static void DMA_Init(void) { HAL_CRG_IpEnableSet(DMA_BASE, IP_CLK_ENABLE); g_dmac.baseAddress = DMA; - g_dmac.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; - g_dmac.irqNumTc = IRQ_DMA_TC; - g_dmac.irqNumError = IRQ_DMA_ERR; - HAL_DMA_IRQService(&g_dmac); + g_dmac.handleEx.srcByteOrder = DMA_BYTEORDER_SMALLENDIAN; + g_dmac.handleEx.destByteOrder = DMA_BYTEORDER_SMALLENDIAN; + IRQ_Register(IRQ_DMA_TC, HAL_DMA_IrqHandlerTc, &g_dmac); + IRQ_Register(IRQ_DMA_ERR, HAL_DMA_IrqHandlerError, &g_dmac); IRQ_EnableN(IRQ_DMA_TC); IRQ_EnableN(IRQ_DMA_ERR); HAL_DMA_Init(&g_dmac); @@ -84,38 +83,31 @@ static void ACMP1_Init(void) g_acmp1.baseAddress = ACMP1_BASE; /* set acmp base address */ - g_acmp1.enable = true; /* enable acmp input capture function */ - g_acmp1.syncEn = false; g_acmp1.inOutConfig.vinNNum = ACMP_VIN_MUX3; g_acmp1.inOutConfig.vinPNum = ACMP_VIN_MUX3; g_acmp1.inOutConfig.swVinPNum = ACMP_SW_VIN3; g_acmp1.inOutConfig.swVinNNum = ACMP_SW_VIN3; - /* set acmp polarity */ + /* set acmp polarity */ g_acmp1.inOutConfig.polarity = ACMP_OUT_NOT_INVERT; g_acmp1.filterCtrl.filterMode = ACMP_FILTER_NONE; - g_acmp1.hysteresisVol = ACMP_HYS_VOL_ZERO; + g_acmp1.hysteresisVol = ACMP_HYS_VOL_30MV; /* 30mv: without hysteresis */ HAL_ACMP_Init(&g_acmp1); } static void ADC0_Init(void) { HAL_CRG_IpEnableSet(ADC0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(ADC0_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); + HAL_CRG_IpClkSelectSet(ADC0_BASE, CRG_ADC_CLK_SELECT_PLL_DIV); /* Select PLL as clock. */ HAL_CRG_IpClkDivSet(ADC0_BASE, CRG_ADC_DIV_5); g_adc0.baseAddress = ADC0; g_adc0.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc0.vrefBuf = ADC_VREF_2P5V; - g_adc0.irqNumOver = IRQ_ADC0_OVINT; - g_adc0.ADC_IntxParam[0].irqNum = IRQ_ADC0_INT1; /* interrupt 0 */ - g_adc0.ADC_IntxParam[1].irqNum = IRQ_ADC0_INT2; /* interrupt 1 */ - g_adc0.ADC_IntxParam[2].irqNum = IRQ_ADC0_INT3; /* interrupt 2 */ - g_adc0.ADC_IntxParam[3].irqNum = IRQ_ADC0_INT4; /* interrupt 3 */ + g_adc0.handleEx.vrefBuf = ADC_VREF_2P5V; - HAL_ADC_Init(&g_adc0); + HAL_ADC_Init(&g_adc0); /* ADC init. */ SOC_Param socParam = {0}; - socParam.adcInput = ADC_CH_ADCINA0; /* PGA0_OUT(ADC INA0) */ + socParam.adcInput = ADC_CH_ADCINA0; /* ADC INA0 */ socParam.sampleHoldTime = 2; /* adc sample holed time 2 adc_clk */ socParam.sampleTotalTime = 3; /* adc sample total time 3 adc_clk */ @@ -134,12 +126,7 @@ static void ADC1_Init(void) g_adc1.baseAddress = ADC1; g_adc1.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc1.vrefBuf = ADC_VREF_2P5V; - g_adc1.irqNumOver = IRQ_ADC1_OVINT; - g_adc1.ADC_IntxParam[0].irqNum = IRQ_ADC1_INT1; /* interrupt 0 */ - g_adc1.ADC_IntxParam[1].irqNum = IRQ_ADC1_INT2; /* interrupt 1 */ - g_adc1.ADC_IntxParam[2].irqNum = IRQ_ADC1_INT3; /* interrupt 2 */ - g_adc1.ADC_IntxParam[3].irqNum = IRQ_ADC1_INT4; /* interrupt 3 */ + g_adc1.handleEx.vrefBuf = ADC_VREF_2P5V; HAL_ADC_Init(&g_adc1); @@ -173,12 +160,7 @@ static void ADC2_Init(void) g_adc2.baseAddress = ADC2; g_adc2.socPriority = ADC_PRIMODE_ALL_ROUND; - g_adc2.vrefBuf = ADC_VREF_2P5V; - g_adc2.irqNumOver = IRQ_ADC2_OVINT; - g_adc2.ADC_IntxParam[0].irqNum = IRQ_ADC2_INT1; /* interrupt 0 */ - g_adc2.ADC_IntxParam[1].irqNum = IRQ_ADC2_INT2; /* interrupt 1 */ - g_adc2.ADC_IntxParam[2].irqNum = IRQ_ADC2_INT3; /* interrupt 2 */ - g_adc2.ADC_IntxParam[3].irqNum = IRQ_ADC2_INT4; /* interrupt 3 */ + g_adc2.handleEx.vrefBuf = ADC_VREF_2P5V; HAL_ADC_Init(&g_adc2); @@ -230,11 +212,10 @@ __weak void MotorCarrierProcessCallback(void *aptHandle) static void APT0_ProtectInit(void) { - /* enable apt0 event interupt protection function */ + /* enable apt0 event interupt protection function */ APT_OutCtrlProtectEx protectApt = {0}; protectApt.ocEventEnEx = BASE_CFG_ENABLE; protectApt.ocEventModeEx =APT_OUT_CTRL_ONE_SHOT; - protectApt.cbcClrModeEx = APT_CLEAR_CBC_ON_CNTR_ZERO; protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; /* low action protection */ protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocEvtInterruptEnEx = BASE_CFG_ENABLE; @@ -242,7 +223,7 @@ static void APT0_ProtectInit(void) protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_ACMP1; protectApt.evtPolarityMaskEx = APT_EM_ACMP1_INVERT_BIT; protectApt.filterCycleNumEx = 0; - /* set apt protect register */ + /* set apt protect register */ HAL_APT_ProtectInitEx(&g_apt0, &protectApt); } @@ -251,13 +232,11 @@ static void APT0_Init(void) HAL_CRG_IpEnableSet(APT0_BASE, IP_CLK_ENABLE); g_apt0.baseAddress = APT0; - g_apt0.irqNumEvt = IRQ_APT0_EVT; - g_apt0.irqNumTmr = IRQ_APT0_TMR; /* Clock Settings */ g_apt0.waveform.dividerFactor = 1 - 1; /* Timer Settings */ - g_apt0.waveform.timerPeriod = 10000; /* apt timer count period is 10000 */ + g_apt0.waveform.timerPeriod = 10000; /* 10000 is count period of APT time-base timer */ g_apt0.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; /* Wave Form */ @@ -266,15 +245,15 @@ static void APT0_Init(void) g_apt0.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; g_apt0.waveform.divInitVal = 0; g_apt0.waveform.cntInitVal = 0; - g_apt0.waveform.cntCmpLeftEdge = 5000; /* apt left edge count period is 5000 */ - g_apt0.waveform.cntCmpRightEdge = 5000; /* apt right edge count period is 5000 */ + g_apt0.waveform.cntCmpLeftEdge = 5000; /* 5000 is count compare point of the left edge of PWM waveform */ + g_apt0.waveform.cntCmpRightEdge = 5000; /* 5000 is count compare point of the right edge of PWM waveform */ g_apt0.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_apt0.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; - g_apt0.waveform.deadBandCnt = 300; /* apt dead band count value is 300 */ + g_apt0.waveform.deadBandCnt = 300; /* 300 is dead-band value */ /* ADC Trigger SOCA */ g_apt0.adcTrg.trgEnSOCA = BASE_CFG_ENABLE; - g_apt0.adcTrg.cntCmpSOCA = 1; + g_apt0.adcTrg.cntCmpSOCA = 1; /* 1 is count compare point of ADC trigger source SOCA when using CMPA */ g_apt0.adcTrg.trgSrcSOCA = APT_CS_SRC_CNTR_CMPA_DOWN; g_apt0.adcTrg.trgScaleSOCA = 1; @@ -295,32 +274,32 @@ static void APT0_Init(void) APT0_ProtectInit(); HAL_APT_PWMInit(&g_apt0); + IRQ_Register(IRQ_APT0_EVT, HAL_APT_EventIrqHandler, &g_apt0); HAL_APT_RegisterCallBack(&g_apt0, APT_EVENT_INTERRUPT, MotorSysErrCallback); - IRQ_SetPriority(g_apt0.irqNumEvt, 7); /* apt event interupt level is 7 */ - HAL_APT_IRQService(&g_apt0); - IRQ_EnableN(g_apt0.irqNumEvt); + IRQ_SetPriority(IRQ_APT0_EVT, 7); /* 7 is priority value */ + IRQ_EnableN(IRQ_APT0_EVT); + + IRQ_Register(IRQ_APT0_TMR, HAL_APT_TimerIrqHandler, &g_apt0); HAL_APT_RegisterCallBack(&g_apt0, APT_TIMER_INTERRUPT, MotorCarrierProcessCallback); - IRQ_SetPriority(g_apt0.irqNumTmr, 6); /* apt timer interupt level is 6 */ - HAL_APT_IRQService(&g_apt0); - IRQ_EnableN(g_apt0.irqNumTmr); + IRQ_SetPriority(IRQ_APT0_TMR, 6); /* 6 is priority value */ + IRQ_EnableN(IRQ_APT0_TMR); } static void APT1_ProtectInit(void) { APT_OutCtrlProtectEx protectApt = {0}; - /* enable apt1 event interupt protection function */ + /* enable apt1 event interupt protection function */ protectApt.ocEventEnEx = BASE_CFG_ENABLE; - protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; - protectApt.cbcClrModeEx = APT_CLEAR_CBC_ON_CNTR_ZERO; + protectApt.ocEventModeEx =APT_OUT_CTRL_ONE_SHOT; protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; - /* disable apt1 event interupt protection function */ + /* disable apt1 event interupt protection function */ protectApt.ocEvtInterruptEnEx = BASE_CFG_DISABLE; protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_ACMP1; protectApt.evtPolarityMaskEx = APT_EM_ACMP1_INVERT_BIT; protectApt.filterCycleNumEx = 0; - /* init APT config module */ + /* init APT config module */ HAL_APT_ProtectInitEx(&g_apt1, &protectApt); } @@ -329,13 +308,11 @@ static void APT1_Init(void) HAL_CRG_IpEnableSet(APT1_BASE, IP_CLK_ENABLE); g_apt1.baseAddress = APT1; - g_apt1.irqNumEvt = IRQ_APT1_EVT; - g_apt1.irqNumTmr = IRQ_APT1_TMR; /* Clock Settings */ g_apt1.waveform.dividerFactor = 1 - 1; /* Timer Settings */ - g_apt1.waveform.timerPeriod = 10000; /* apt timer count period is 10000 */ + g_apt1.waveform.timerPeriod = 10000; /* 10000 is count period of APT time-base timer */ g_apt1.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; /* Wave Form */ @@ -344,11 +321,11 @@ static void APT1_Init(void) g_apt1.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; g_apt1.waveform.divInitVal = 0; g_apt1.waveform.cntInitVal = 0; - g_apt1.waveform.cntCmpLeftEdge = 5000; /* apt left edge count period is 5000 */ - g_apt1.waveform.cntCmpRightEdge = 5000; /* apt right edge count period is 5000 */ + g_apt1.waveform.cntCmpLeftEdge = 5000; /* 5000 is count compare point of the left edge of PWM waveform */ + g_apt1.waveform.cntCmpRightEdge = 5000; /* 5000 is count compare point of the right edge of PWM waveform */ g_apt1.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_apt1.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; - g_apt1.waveform.deadBandCnt = 300; /* apt dead band count value is 300 */ + g_apt1.waveform.deadBandCnt = 300; /* 300 is dead-band value */ APT1_ProtectInit(); @@ -358,19 +335,18 @@ static void APT1_Init(void) static void APT2_ProtectInit(void) { APT_OutCtrlProtectEx protectApt = {0}; - /* enable apt2 event interupt protection function */ + /* enable apt2 event interupt protection function */ protectApt.ocEventEnEx = BASE_CFG_ENABLE; protectApt.ocEventModeEx =APT_OUT_CTRL_ONE_SHOT; - protectApt.cbcClrModeEx = APT_CLEAR_CBC_ON_CNTR_ZERO; protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; - /* disable apt2 event interupt protection function */ + /* disable apt2 event interupt protection function */ protectApt.ocEvtInterruptEnEx = BASE_CFG_DISABLE; protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_ACMP1; protectApt.evtPolarityMaskEx = APT_EM_ACMP1_INVERT_BIT; protectApt.filterCycleNumEx = 0; - /* init APT config module */ + /* init APT config module */ HAL_APT_ProtectInitEx(&g_apt2, &protectApt); } @@ -379,13 +355,11 @@ static void APT2_Init(void) HAL_CRG_IpEnableSet(APT2_BASE, IP_CLK_ENABLE); g_apt2.baseAddress = APT2; - g_apt2.irqNumEvt = IRQ_APT2_EVT; - g_apt2.irqNumTmr = IRQ_APT2_TMR; /* Clock Settings */ g_apt2.waveform.dividerFactor = 1 - 1; /* Timer Settings */ - g_apt2.waveform.timerPeriod = 10000; /* apt timer count period is 10000 */ + g_apt2.waveform.timerPeriod = 10000; /* 10000 is count period of APT time-base timer */ g_apt2.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; /* Wave Form */ @@ -394,11 +368,11 @@ static void APT2_Init(void) g_apt2.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; g_apt2.waveform.divInitVal = 0; g_apt2.waveform.cntInitVal = 0; - g_apt2.waveform.cntCmpLeftEdge = 5000; /* apt left edge count period is 5000 */ - g_apt2.waveform.cntCmpRightEdge = 5000; /* apt right edge count period is 5000 */ + g_apt2.waveform.cntCmpLeftEdge = 5000; /* 5000 is count compare point of the left edge of PWM waveform */ + g_apt2.waveform.cntCmpRightEdge = 5000; /* 5000 is count compare point of the right edge of PWM waveform */ g_apt2.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_apt2.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; - g_apt2.waveform.deadBandCnt = 300; /* apt dead band count value is 300 */ + g_apt2.waveform.deadBandCnt = 300; /* 300 is dead-band value */ APT2_ProtectInit(); @@ -407,7 +381,7 @@ static void APT2_Init(void) __weak void MotorStartStopKeyCallback(void *param) { - /* gpio input interupt function */ + /* gpio input interupt function */ GPIO_Handle *handle = (GPIO_Handle *)param; BASE_FUNC_UNUSED(handle); } @@ -416,48 +390,47 @@ static void GPIO_Init(void) { HAL_CRG_IpEnableSet(GPIO0_BASE, IP_CLK_ENABLE); g_gpio0.baseAddress = GPIO0; - /* set gpio0_6_7 output mode */ - g_gpio0.dir = GPIO_OUTPUT_MODE; - g_gpio0.value = GPIO_HIGH_LEVEL; - g_gpio0.interruptMode = GPIO_INT_TYPE_NONE; g_gpio0.pins = GPIO_PIN_6 | GPIO_PIN_7; HAL_GPIO_Init(&g_gpio0); - /* enable GPIO clk */ + HAL_GPIO_SetDirection(&g_gpio0, g_gpio0.pins, GPIO_OUTPUT_MODE); + HAL_GPIO_SetValue(&g_gpio0, g_gpio0.pins, GPIO_HIGH_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio0, g_gpio0.pins, GPIO_INT_TYPE_NONE); + /* enable GPIO clk */ HAL_CRG_IpEnableSet(GPIO2_BASE, IP_CLK_ENABLE); g_gpio2.baseAddress = GPIO2; - /* set gpio2_6 output mode */ - g_gpio2.dir = GPIO_OUTPUT_MODE; - g_gpio2.value = GPIO_HIGH_LEVEL; - g_gpio2.interruptMode = GPIO_INT_TYPE_NONE; - g_gpio2.pins = GPIO_PIN_6; + g_gpio2.pins = GPIO_PIN_6; /* set gpio2_6 config mode */ HAL_GPIO_Init(&g_gpio2); - /* set gpio2_2 input mode */ - g_gpio2.dir = GPIO_INPUT_MODE; - g_gpio2.value = GPIO_HIGH_LEVEL; - g_gpio2.interruptMode = GPIO_INT_TYPE_LOW_LEVEL; - g_gpio2.pins = GPIO_PIN_2; + HAL_GPIO_SetDirection(&g_gpio2, g_gpio2.pins, GPIO_OUTPUT_MODE); + HAL_GPIO_SetValue(&g_gpio2, g_gpio2.pins, GPIO_HIGH_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio2, g_gpio2.pins, GPIO_INT_TYPE_NONE); + + g_gpio2.pins = GPIO_PIN_2; /* set gpio2_2 config mode */ HAL_GPIO_Init(&g_gpio2); - /* enable GPIO interupt function */ + HAL_GPIO_SetDirection(&g_gpio2, g_gpio2.pins, GPIO_INPUT_MODE); + HAL_GPIO_SetValue(&g_gpio2, g_gpio2.pins, GPIO_HIGH_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio2, g_gpio2.pins, GPIO_INT_TYPE_LOW_LEVEL); + /* enable GPIO interupt function */ HAL_GPIO_RegisterCallBack(&g_gpio2, GPIO_PIN_2, MotorStartStopKeyCallback); - g_gpio2.irqNum = IRQ_GPIO2; - HAL_GPIO_IRQService(&g_gpio2); - IRQ_SetPriority(g_gpio2.irqNum, 1); /* set gpio1 interrupt priority to 1, 1~7 */ - IRQ_EnableN(g_gpio2.irqNum); /* gpio interrupt enable */ + IRQ_Register(IRQ_GPIO2, HAL_GPIO_IrqHandler, &g_gpio2); + IRQ_SetPriority(IRQ_GPIO2, 1); /* set gpio1 interrupt priority to 1, 1~7. 1 */ + IRQ_EnableN(IRQ_GPIO2); /* gpio interrupt enable */ return; } static void PGA0_Init(void) { + /* PGA enable. */ HAL_CRG_IpEnableSet(PGA0_BASE, IP_CLK_ENABLE); g_pga0.baseAddress = PGA0_BASE; - g_pga0.enable = BASE_CFG_ENABLE; /* enable pga0 */ - g_pga0.extLoopbackEn = BASE_CFG_DISABLE; - g_pga0.pgaMux = PGA_EXT_RES_VI0; - g_pga0.gain = PGA_GAIN_1X; - /* init pga0 module */ + g_pga0.externalResistorMode = BASE_CFG_DISABLE; + g_pga0.handleEx.pgaMux = PGA_EXT_RES_VI0; + + /* init pga0 module */ HAL_PGA_Init(&g_pga0); + DCL_PGA_EnableOut(g_pga0.baseAddress); + DCL_PGA_EnableExtOut(g_pga0.baseAddress); } static void PGA1_Init(void) @@ -465,17 +438,18 @@ static void PGA1_Init(void) HAL_CRG_IpEnableSet(PGA1_BASE, IP_CLK_ENABLE); g_pga1.baseAddress = PGA1_BASE; /* enable pga1 */ - g_pga1.enable = BASE_CFG_ENABLE; - g_pga1.extLoopbackEn = BASE_CFG_DISABLE; - g_pga1.pgaMux = PGA_EXT_RES_VI3; - g_pga1.gain = PGA_GAIN_1X; - /* init pga1 module */ + g_pga1.externalResistorMode = BASE_CFG_DISABLE; + g_pga1.handleEx.pgaMux = PGA_EXT_RES_VI3; + + /* init pga1 module */ HAL_PGA_Init(&g_pga1); + DCL_PGA_EnableOut(g_pga1.baseAddress); + DCL_PGA_EnableExtOut(g_pga1.baseAddress); } __weak void CheckPotentiometerValueCallback(void *handle) { - HAL_TIMER_IrqClear((TIMER_Handle *)handle); + DCL_TIMER_IrqClear((TIMER_RegStruct *)handle); /* USER CODE BEGIN TIMER0 ITCallBackFunc */ /* USER CODE END TIMER0 ITCallBackFunc */ } @@ -488,26 +462,25 @@ static void TIMER0_Init(void) HAL_CRG_IpClkSelectSet(TIMER0_BASE, CRG_PLL_NO_PREDV); g_timer0.baseAddress = TIMER0; - g_timer0.irqNum = IRQ_TIMER0; g_timer0.load = load - 1; /* Set timer value immediately */ g_timer0.bgLoad = load - 1; /* Set timer value */ g_timer0.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ g_timer0.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ g_timer0.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ - g_timer0.dmaAdcSingleReqEnable = BASE_CFG_DISABLE; - g_timer0.dmaBurstReqEnable = BASE_CFG_DISABLE; + g_timer0.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer0.dmaReqEnable = BASE_CFG_DISABLE; g_timer0.interruptEn = BASE_CFG_ENABLE; HAL_TIMER_Init(&g_timer0); - - HAL_TIMER_RegisterCallback(&g_timer0, CheckPotentiometerValueCallback); - IRQ_SetPriority(g_timer0.irqNum, 1); - IRQ_EnableN(g_timer0.irqNum); + IRQ_Register(IRQ_TIMER0, HAL_TIMER_IrqHandler, &g_timer0); + HAL_TIMER_RegisterCallback(&g_timer0, TIMER_PERIOD_FIN, CheckPotentiometerValueCallback); + IRQ_SetPriority(IRQ_TIMER0, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER0); } __weak void MotorStatemachineCallBack(void *handle) { - HAL_TIMER_IrqClear((TIMER_Handle *)handle); + DCL_TIMER_IrqClear((TIMER_RegStruct *)handle); /* USER CODE BEGIN TIMER1 ITCallBackFunc */ /* USER CODE END TIMER1 ITCallBackFunc */ } @@ -520,45 +493,44 @@ static void TIMER1_Init(void) HAL_CRG_IpClkSelectSet(TIMER1_BASE, CRG_PLL_NO_PREDV); g_timer1.baseAddress = TIMER1; - g_timer1.irqNum = IRQ_TIMER1; g_timer1.load = load - 1; /* Set timer value immediately */ g_timer1.bgLoad = load - 1; /* Set timer value */ g_timer1.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ g_timer1.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ g_timer1.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ - g_timer1.dmaAdcSingleReqEnable = BASE_CFG_DISABLE; - g_timer1.dmaBurstReqEnable = BASE_CFG_DISABLE; + g_timer1.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer1.dmaReqEnable = BASE_CFG_DISABLE; g_timer1.interruptEn = BASE_CFG_ENABLE; HAL_TIMER_Init(&g_timer1); - - HAL_TIMER_RegisterCallback(&g_timer1, MotorStatemachineCallBack); - IRQ_SetPriority(g_timer1.irqNum, 1); - IRQ_EnableN(g_timer1.irqNum); + IRQ_Register(IRQ_TIMER1, HAL_TIMER_IrqHandler, &g_timer1); + HAL_TIMER_RegisterCallback(&g_timer1, TIMER_PERIOD_FIN, MotorStatemachineCallBack); + IRQ_SetPriority(IRQ_TIMER1, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_TIMER1); } -__weak void UART0WriteInterruptCallback(UART_Handle *handle) +__weak void UART0WriteInterruptCallback(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN UART0_WRITE_IT_FINISH */ /* USER CODE END UART0_WRITE_IT_FINISH */ } -__weak void UART0ReadInterruptCallback(UART_Handle *handle) +__weak void UART0ReadInterruptCallback(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN UART0_READ_IT_FINISH */ /* USER CODE END UART0_READ_IT_FINISH */ } -__weak void UART0InterruptErrorCallback(UART_Handle *handle) +__weak void UART0InterruptErrorCallback(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN UART0_TRNS_IT_ERROR */ /* USER CODE END UART0_TRNS_IT_ERROR */ } -__weak void UART0_TXDMACallback(UART_Handle *handle) +__weak void UART0_TXDMACallback(void *handle) { BASE_FUNC_UNUSED(handle); /* USER CODE BEGIN UART0_WRITE_DMA_FINISH */ @@ -571,9 +543,8 @@ static void UART0_Init(void) HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_PLL_NO_PREDV); g_uart0.baseAddress = UART0; - g_uart0.irqNum = IRQ_UART0; - g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.baudRate = UART0_BAUD_RATE; g_uart0.dataLength = UART_DATALENGTH_8BIT; g_uart0.stopBits = UART_STOPBITS_ONE; g_uart0.parity = UART_PARITY_NONE; @@ -587,9 +558,9 @@ static void UART0_Init(void) HAL_UART_RegisterCallBack(&g_uart0, UART_WRITE_IT_FINISH, UART0WriteInterruptCallback); HAL_UART_RegisterCallBack(&g_uart0, UART_READ_IT_FINISH, UART0ReadInterruptCallback); HAL_UART_RegisterCallBack(&g_uart0, UART_TRNS_IT_ERROR, UART0InterruptErrorCallback); - HAL_UART_IRQService(&g_uart0); - IRQ_SetPriority(g_uart0.irqNum, 1); - IRQ_EnableN(g_uart0.irqNum); + IRQ_Register(IRQ_UART0, HAL_UART_IrqHandler, &g_uart0); + IRQ_SetPriority(IRQ_UART0, 1); /* 1 is priority value */ + IRQ_EnableN(IRQ_UART0); g_uart0.dmaHandle = &g_dmac; g_uart0.uartDmaTxChn = 0; HAL_UART_RegisterCallBack(&g_uart0, UART_WRITE_DMA_FINISH, UART0_TXDMACallback); @@ -597,200 +568,202 @@ static void UART0_Init(void) static void IOConfig(void) { - IOConfig_RegStruct *iconfig = IOCONFIG; - - iconfig->iocmg_26.BIT.func = 0x2; /* 0x2 is ACMP1_OUT */ - iconfig->iocmg_26.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_26.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_26.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_26.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_26.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_27.BIT.func = 0x9; /* 0x9 is ACMP1_ANA_N */ - iconfig->iocmg_27.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_27.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_27.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_27.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_27.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_28.BIT.func = 0x9; /* 0x9 is ACMP1_ANA_P */ - iconfig->iocmg_28.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_28.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_28.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_28.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_28.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_48.BIT.func = 0x8; /* 0x8 is ADC2_ANA_B1 */ - iconfig->iocmg_48.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_48.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_48.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_48.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_48.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_55.BIT.func = 0x8; /* 0x8 is ADC2_ANA_B2 */ - iconfig->iocmg_55.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_55.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_55.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_55.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_55.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_51.BIT.func = 0x8; /* 0x8 is ADC2_ANA_A7 */ - iconfig->iocmg_51.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_51.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_51.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_51.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_51.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_32.BIT.func = 0x3; /* 0x3 is APT0_PWMA */ - iconfig->iocmg_32.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_32.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_32.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_32.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_32.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_35.BIT.func = 0x3; /* 0x3 is APT0_PWMB */ - iconfig->iocmg_35.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_35.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_35.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_35.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_35.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_33.BIT.func = 0x3; /* 0x3 is APT1_PWMA */ - iconfig->iocmg_33.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_33.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_33.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_33.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_33.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_36.BIT.func = 0x3; /* 0x3 is APT1_PWMB */ - iconfig->iocmg_36.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_36.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_36.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_36.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_36.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_34.BIT.func = 0x3; /* 0x3 is APT2_PWMA */ - iconfig->iocmg_34.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_34.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_34.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_34.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_34.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_37.BIT.func = 0x3; /* 0x3 is APT2_PWMB */ - iconfig->iocmg_37.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_37.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_37.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_37.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_37.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_9.BIT.func = 0x0; /* 0x0 is GPIO0_6 */ - iconfig->iocmg_9.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_9.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_9.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_9.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_9.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_10.BIT.func = 0x0; /* 0x0 is GPIO0_7 */ - iconfig->iocmg_10.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_10.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_10.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_10.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_10.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_25.BIT.func = 0x0; /* 0x0 is GPIO2_6 */ - iconfig->iocmg_25.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_25.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_25.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_25.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_25.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_21.BIT.func = 0x0; /* 0x0 is GPIO2_2 */ - iconfig->iocmg_21.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_21.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_21.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_21.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_38.BIT.func = 0x9; /* 0x9 is PGA0_ANA_P */ - iconfig->iocmg_38.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_38.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_38.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_38.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_38.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_39.BIT.func = 0x9; /* 0x9 is PGA0_ANA_N */ - iconfig->iocmg_39.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_39.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_39.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_39.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_39.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_40.BIT.func = 0x8; /* 0x8 is PGA0_ANA_EXT */ - iconfig->iocmg_40.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_40.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_40.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_40.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_40.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_43.BIT.func = 0x9; /* 0x9 is PGA1_ANA_EXT */ - iconfig->iocmg_43.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_43.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_43.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_43.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_43.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_42.BIT.func = 0x9; /* 0x9 is PGA1_ANA_N */ - iconfig->iocmg_42.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_42.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_42.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_42.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_42.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_41.BIT.func = 0x9; /* 0x9 is PGA1_ANA_P */ - iconfig->iocmg_41.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_41.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_41.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_41.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_41.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_6.BIT.func = 0x4; /* 0x4 is UART0_TXD */ - iconfig->iocmg_6.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_6.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.pu = BASE_CFG_DISABLE; - iconfig->iocmg_6.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_6.BIT.se = BASE_CFG_DISABLE; - - iconfig->iocmg_7.BIT.func = 0x4; /* 0x4 is UART0_RXD */ - iconfig->iocmg_7.BIT.ds = IO_DRV_LEVEL2; - iconfig->iocmg_7.BIT.pd = BASE_CFG_DISABLE; - iconfig->iocmg_7.BIT.pu = BASE_CFG_ENABLE; - iconfig->iocmg_7.BIT.sr = IO_SPEED_SLOW; - iconfig->iocmg_7.BIT.se = BASE_CFG_DISABLE; + /* Config PIN10 */ + HAL_IOCMG_SetPinAltFuncMode(IO10_AS_ACMP1_OUT); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO10_AS_ACMP1_OUT, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO10_AS_ACMP1_OUT, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO10_AS_ACMP1_OUT, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO10_AS_ACMP1_OUT, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN11 */ + HAL_IOCMG_SetPinAltFuncMode(IO11_AS_ACMP1_ANA_N3); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO11_AS_ACMP1_ANA_N3, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO11_AS_ACMP1_ANA_N3, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO11_AS_ACMP1_ANA_N3, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO11_AS_ACMP1_ANA_N3, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN12 */ + HAL_IOCMG_SetPinAltFuncMode(IO12_AS_ACMP1_ANA_P3); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO12_AS_ACMP1_ANA_P3, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO12_AS_ACMP1_ANA_P3, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO12_AS_ACMP1_ANA_P3, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO12_AS_ACMP1_ANA_P3, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN31 */ + HAL_IOCMG_SetPinAltFuncMode(IO31_AS_ADC2_ANA_B1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO31_AS_ADC2_ANA_B1, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO31_AS_ADC2_ANA_B1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO31_AS_ADC2_ANA_B1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO31_AS_ADC2_ANA_B1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN40 */ + HAL_IOCMG_SetPinAltFuncMode(IO40_AS_ADC2_ANA_B2); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO40_AS_ADC2_ANA_B2, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO40_AS_ADC2_ANA_B2, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO40_AS_ADC2_ANA_B2, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO40_AS_ADC2_ANA_B2, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN36 */ + HAL_IOCMG_SetPinAltFuncMode(IO36_AS_ADC2_ANA_A7); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO36_AS_ADC2_ANA_A7, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO36_AS_ADC2_ANA_A7, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO36_AS_ADC2_ANA_A7, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO36_AS_ADC2_ANA_A7, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN15 */ + HAL_IOCMG_SetPinAltFuncMode(IO15_AS_APT0_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO15_AS_APT0_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO15_AS_APT0_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO15_AS_APT0_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO15_AS_APT0_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN18 */ + HAL_IOCMG_SetPinAltFuncMode(IO18_AS_APT0_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO18_AS_APT0_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO18_AS_APT0_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO18_AS_APT0_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO18_AS_APT0_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN16 */ + HAL_IOCMG_SetPinAltFuncMode(IO16_AS_APT1_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO16_AS_APT1_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO16_AS_APT1_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO16_AS_APT1_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO16_AS_APT1_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN19 */ + HAL_IOCMG_SetPinAltFuncMode(IO19_AS_APT1_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO19_AS_APT1_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO19_AS_APT1_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO19_AS_APT1_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO19_AS_APT1_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN17 */ + HAL_IOCMG_SetPinAltFuncMode(IO17_AS_APT2_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO17_AS_APT2_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO17_AS_APT2_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO17_AS_APT2_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO17_AS_APT2_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN20 */ + HAL_IOCMG_SetPinAltFuncMode(IO20_AS_APT2_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO20_AS_APT2_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO20_AS_APT2_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO20_AS_APT2_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO20_AS_APT2_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN55 */ + HAL_IOCMG_SetPinAltFuncMode(IO55_AS_GPIO0_6); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO55_AS_GPIO0_6, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO55_AS_GPIO0_6, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO55_AS_GPIO0_6, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO55_AS_GPIO0_6, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN56 */ + HAL_IOCMG_SetPinAltFuncMode(IO56_AS_GPIO0_7); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO56_AS_GPIO0_7, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO56_AS_GPIO0_7, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO56_AS_GPIO0_7, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO56_AS_GPIO0_7, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN9 */ + HAL_IOCMG_SetPinAltFuncMode(IO9_AS_GPIO2_6); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO9_AS_GPIO2_6, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO9_AS_GPIO2_6, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO9_AS_GPIO2_6, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO9_AS_GPIO2_6, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN5 */ + HAL_IOCMG_SetPinAltFuncMode(IO5_AS_GPIO2_2); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO5_AS_GPIO2_2, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO5_AS_GPIO2_2, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO5_AS_GPIO2_2, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO5_AS_GPIO2_2, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN21 */ + HAL_IOCMG_SetPinAltFuncMode(IO21_AS_PGA0_ANA_P0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO21_AS_PGA0_ANA_P0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO21_AS_PGA0_ANA_P0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO21_AS_PGA0_ANA_P0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO21_AS_PGA0_ANA_P0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN22 */ + HAL_IOCMG_SetPinAltFuncMode(IO22_AS_PGA0_ANA_N0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO22_AS_PGA0_ANA_N0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO22_AS_PGA0_ANA_N0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO22_AS_PGA0_ANA_N0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO22_AS_PGA0_ANA_N0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN23 */ + HAL_IOCMG_SetPinAltFuncMode(IO23_AS_PGA0_ANA_EXT0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO23_AS_PGA0_ANA_EXT0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO23_AS_PGA0_ANA_EXT0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO23_AS_PGA0_ANA_EXT0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO23_AS_PGA0_ANA_EXT0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN30 */ + HAL_IOCMG_SetPinAltFuncMode(IO30_AS_PGA1_ANA_EXT0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO30_AS_PGA1_ANA_EXT0, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO30_AS_PGA1_ANA_EXT0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO30_AS_PGA1_ANA_EXT0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO30_AS_PGA1_ANA_EXT0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN29 */ + HAL_IOCMG_SetPinAltFuncMode(IO29_AS_PGA1_ANA_N3); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO29_AS_PGA1_ANA_N3, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO29_AS_PGA1_ANA_N3, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO29_AS_PGA1_ANA_N3, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO29_AS_PGA1_ANA_N3, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN28 */ + HAL_IOCMG_SetPinAltFuncMode(IO28_AS_PGA1_ANA_P3); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO28_AS_PGA1_ANA_P3, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO28_AS_PGA1_ANA_P3, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO28_AS_PGA1_ANA_P3, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO28_AS_PGA1_ANA_P3, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN52 */ + HAL_IOCMG_SetPinAltFuncMode(IO52_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO52_AS_UART0_TXD, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(IO52_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO52_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO52_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN53 */ + HAL_IOCMG_SetPinAltFuncMode(IO53_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(IO53_AS_UART0_RXD, PULL_UP); /* Pull-up and Pull-down, UART RX recommend PULL_UP */ + HAL_IOCMG_SetPinSchmidtMode(IO53_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(IO53_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(IO53_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +static void APT_SyncMasterInit(void) +{ + /* APT master set. */ + HAL_APT_MasterSyncInit(&g_apt0, APT_SYNC_OUT_ON_CNTR_ZERO); +} + +static void APT_SyncSlaveInit(void) +{ + APT_SlaveSyncIn aptSlave; + + aptSlave.divPhase = 0; /* divide phase value */ + aptSlave.cntPhase = 0; /* counter phase value */ + aptSlave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; + aptSlave.syncInSrc = APT_SYNCIN_SRC_APT0_SYNCOUT; /* sync source selection */ + aptSlave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; + HAL_APT_SlaveSyncInit(&g_apt1, &aptSlave); + + aptSlave.divPhase = 0; /* divide phase value */ + aptSlave.cntPhase = 0; /* counter phase value */ + aptSlave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; + aptSlave.syncInSrc = APT_SYNCIN_SRC_APT0_SYNCOUT; /* sync source selection */ + aptSlave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; + HAL_APT_SlaveSyncInit(&g_apt2, &aptSlave); } void SystemInit(void) { - /* init system module */ + /* init system module */ IOConfig(); DMA_Init(); UART0_Init(); ACMP1_Init(); - /* init APT module */ + /* init APT module */ APT0_Init(); APT1_Init(); APT2_Init(); - /* init ADC module */ + /* init ADC module */ ADC0_Init(); ADC1_Init(); ADC2_Init(); - /* init PGA module */ + /* init PGA module */ PGA0_Init(); PGA1_Init(); - /* init TIMER module */ + /* init TIMER module */ TIMER0_Init(); TIMER1_Init(); GPIO_Init(); + APT_SyncMasterInit(); + APT_SyncSlaveInit(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/src/mcs_motor_process.c b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/src/mcs_motor_process.c index feac3798ba91e651b736b4d0ff2eeb56f35c1c90..79bc3949d31044e401311212f30ff7c6ef3d136f 100644 --- a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/src/mcs_motor_process.c +++ b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/src/mcs_motor_process.c @@ -36,7 +36,6 @@ #include "mcs_chip_config.h" #include - /*------------------------------- Macro Definition -----------------------------------------------*/ #define US_PER_MS 1000 #define ANGLE_RANGE_ABS 65536 @@ -114,7 +113,7 @@ static void FOSMO_InitWrapper(FOSMO_Handle *fosmo, float ts) .pllBdw = FOSMO_PLL_BDW, }; /* Init smo param. */ - FOSMO_Init(fosmo, fosmoParam, g_motorParam, ts); + FOSMO_Init(fosmo, fosmoParam, &g_motorParam, ts); } /* Smo4th param. */ @@ -128,7 +127,7 @@ static void SMO4TH_InitWrapper(SMO4TH_Handle *smo4TH) .fcLpf = SMO4TH_SPD_FILTER_CUTOFF_FREQ, }; /* Init smo param. */ - SMO4TH_Init(smo4TH, smo4thParam, g_motorParam, CTRL_CURR_PERIOD); + SMO4TH_Init(smo4TH, smo4thParam, &g_motorParam, CTRL_CURR_PERIOD); } /*------------------------------- Function Definition -----------------------------------------------*/ @@ -173,8 +172,12 @@ static void TSK_Init(void) MtrParamInit(&g_mc.mtrParam, g_motorParam); TimerTickInit(&g_mc); - SVPWM_Init(&g_mc.sv, INV_VOLTAGE_BUS * ONE_DIV_SQRT3); - R1SVPWM_Init(&g_mc.r1Sv, INV_VOLTAGE_BUS * ONE_DIV_SQRT3, SAMPLE_POINT_SHIFT, SAMPLE_WINDOW_DUTY); + if (g_mc.sampleMode == DUAL_RESISTORS) { + SVPWM_Init(&g_mc.sv, INV_VOLTAGE_BUS * ONE_DIV_SQRT3); /* Dual resistors SVPWM init. */ + } else if (g_mc.sampleMode == SINGLE_RESISTOR) { + /* Single resistor SVPWM init. */ + R1SVPWM_Init(&g_mc.r1Sv, INV_VOLTAGE_BUS * ONE_DIV_SQRT3, SAMPLE_POINT_SHIFT, SAMPLE_WINDOW_DUTY); + } SPDCTRL_InitWrapper(&g_mc.spdCtrl, CTRL_SYSTICK_PERIOD); CURRCTRL_InitWrapper(&g_mc.currCtrl, &g_mc.idqRef, &g_mc.idqFbk, CTRL_CURR_PERIOD); @@ -538,6 +541,9 @@ static void TrimInitAdcShiftValue(MTRCTRL_Handle *mtrCtrl) adc1TempSum += adc1SampleTemp; } } + if (adcSampleTimes < 1.0f) { + adcSampleTimes = 1.0f; /* Prevent divide-by-zero errors */ + } adc0SampleTemp = adc0TempSum / adcSampleTimes; adc1SampleTemp = adc1TempSum / adcSampleTimes; /* Force convert to float */ @@ -625,7 +631,7 @@ static void SetADCTriggerTime(unsigned short cntCmpSOCA, unsigned short cntCmpSO */ static float TempTable(float tempResisValue) { - float boardTemp; + float boardTemp = 0.0f; /* Temperatures between 15 and 30. */ if (tempResisValue > TEMP_RES_30 && tempResisValue <= TEMP_RES_15) { boardTemp = TEMP_15 + (TEMP_30 - TEMP_15) * (TEMP_RES_15 - tempResisValue) / (TEMP_RES_15 - TEMP_RES_30); @@ -860,47 +866,6 @@ static void InitSoftware(void) g_mc.setADCTriggerTimeCb = SetADCTriggerTime; } -/** - * @brief Config the master APT. - * @param aptx The master APT handle. - * @retval None. - */ -static void AptMasterSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - /* Config the master APT. */ - HAL_APT_MasterSyncInit(aptx, APT_SYNC_OUT_ON_CNTR_ZERO); -} - -/** - * @brief Config the slave APT. - * @param aptx The slave APT handle. - * @retval None. - */ -static void AptSalveSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - APT_SlaveSyncIn slave; - /* Config the slave APT. */ - slave.divPhase = 0; - slave.cntPhase = 0; - slave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; - slave.syncInSrc = APT_SYNC_IN_SRC; - slave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; - HAL_APT_SlaveSyncInit(aptx, &slave); -} -/** - * @brief Configuring Master and Slave APTs. - * @retval None. - */ -static void AptMasterSalveSet(void) -{ - /* motor APT master/slave synchronization */ - AptMasterSet(&g_apt0); - AptSalveSet(&g_apt1); - AptSalveSet(&g_apt2); -} - /** * @brief Config the KEY func. * @param handle The GPIO handle. @@ -953,7 +918,6 @@ int MotorMainProcess(void) HAL_TIMER_Start(&g_timer0); HAL_TIMER_Start(&g_timer1); - AptMasterSalveSet(); /* Disable PWM output before startup. */ MotorPwmOutputDisable(g_apt); /* Software initialization. */ diff --git a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/cust_process.c b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/cust_process.c index 9836dc765691d2163bf75a2356653eb8eecf5981..7c4f75252f9cb7a7fd3b2452ad276e8074519121 100644 --- a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/cust_process.c +++ b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/cust_process.c @@ -194,14 +194,14 @@ static void SetObserverSmo1thPLLParams(FOSMO_Handle *smoHandle, CUSTDATATYPE_DEF { /* Get command code. */ int cmdCode = (int)(rxData->data[DATA_SEGMENT_TWO].typeF); - + float pllBdw = 0.0f; switch (cmdCode) { case SET_SMO1TH_PLL_BDW: /* Set the bandwidth. */ - smoHandle->pll.pllBdw = rxData->data[DATA_SEGMENT_THREE].typeF; - smoHandle->pll.pi.kp = 2.0f * smoHandle->pll.pllBdw; /* kp = 2.0f * pllBdw */ - smoHandle->pll.pi.ki = smoHandle->pll.pllBdw * smoHandle->pll.pllBdw; /* ki = pllBdw * pllBdw */ + pllBdw = rxData->data[DATA_SEGMENT_THREE].typeF; + smoHandle->pll.pi.kp = 2.0f * pllBdw; /* kp = 2.0f * pllBdw */ + smoHandle->pll.pi.ki = pllBdw * pllBdw; /* ki = pllBdw * pllBdw */ ackCode = 0X0A; - CUST_AckCode(g_uartTxBuf, ackCode, smoHandle->pll.pllBdw); + CUST_AckCode(g_uartTxBuf, ackCode, pllBdw); break; case SET_SMO1TH_SPDFLITER_FC: /* Set the cutoff frequency. */ smoHandle->spdFilter.fc = rxData->data[DATA_SEGMENT_THREE].typeF; @@ -255,11 +255,11 @@ static void SetObserverSmo4thParams(SMO4TH_Handle *smo4thHandle, CUSTDATATYPE_DE */ static void SetObserverSmo4thPLLParams(SMO4TH_Handle *smo4thHandle, CUSTDATATYPE_DEF *rxData) { - smo4thHandle->pll.pllBdw = rxData->data[DATA_SEGMENT_TWO].typeF; - smo4thHandle->pll.pi.kp = (2.0f) * smo4thHandle->pll.pllBdw; /* kp = 2.0f * pllBdw */ - smo4thHandle->pll.pi.ki = smo4thHandle->pll.pllBdw * smo4thHandle->pll.pllBdw; + float pllBdw = rxData->data[DATA_SEGMENT_TWO].typeF; + smo4thHandle->pll.pi.kp = (2.0f) * pllBdw; /* kp = 2.0f * pllBdw */ + smo4thHandle->pll.pi.ki = pllBdw * pllBdw; ackCode = 0X11; - CUST_AckCode(g_uartTxBuf, ackCode, smo4thHandle->pll.pllBdw); + CUST_AckCode(g_uartTxBuf, ackCode, pllBdw); } /** @@ -296,7 +296,7 @@ static void CMDCODE_SetMotorSpdAndSlope(MTRCTRL_Handle *mtrCtrl, CUSTDATATYPE_DE switch (cmdCode) { case SET_SPD_COMMAND_HZ: /* Set target speed(hz). */ mtrCtrl->spdCmdHz = rxData->data[DATA_SEGMENT_THREE].typeF * mtrCtrl->mtrParam.mtrNp / CONST_VALUE_60; - /* Judgement the value > 0.00001, make sure denominator != 0 */ + /* Judgement the value > 0.00001, make sure denominator != 0. */ if (rxData->data[DATA_SEGMENT_FOUR].typeF > 0.00001f) { mtrCtrl->spdRmg.delta = mtrCtrl->spdCmdHz / rxData->data[DATA_SEGMENT_FOUR].typeF * CTRL_SYSTICK_PERIOD; } diff --git a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/protocol.c b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/protocol.c index f655ada5ea8933139bd474281337ea5360a24fa4..56f0c0bb3fa394c355dcbef7f6387270bf31dd67 100644 --- a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/protocol.c +++ b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/protocol.c @@ -132,7 +132,7 @@ void CUST_AckCode(unsigned char *txBuf, unsigned char ackCode, float varParams) /* End of Message */ txBuf[FRAME_ONE_CHAR_LENTH + i++] = FRAME_END; txLen = FRAME_ONE_CHAR_LENTH + i++; - HAL_UART_WriteIT(&g_uart0, txBuf, txLen); + HAL_UART_WriteDMA(&g_uart0, txBuf, txLen); } /** diff --git a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/uart_module.c b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/uart_module.c index 6b231c02a247ba3ffc0c25cb9f5f680b2b3b92dd..df5e918648921817e0e0fd5c9d98c5c0ee6bcb26 100644 --- a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/uart_module.c +++ b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/uart_module.c @@ -34,9 +34,6 @@ /* Start sending data to host delay after uart connect success */ #define UART_UPDATA_DELAY_TIME_MS (50) -/* Uart baudrate */ -#define UART0BAUDRATE (1843200) - /* Data buffer */ unsigned char g_uartRxBuf[UI_RX_BUF_LEN] = {0}; unsigned char g_uartTxBuf[UI_TX_BUF_LEN] = {0}; @@ -45,6 +42,7 @@ static FRAME_Handle g_uartFrame; /** * @brief Receive Data Clear. * @param uartFrame Receice Data. + * @retval None. */ static void FrameRecvClear(FRAME_Handle *uartFrame) { @@ -57,11 +55,13 @@ static void FrameRecvClear(FRAME_Handle *uartFrame) /* Clear received flag. */ uartFrame->rxFlag = 0; uartFrame->upDataCnt = 0; + uartFrame->rxAckFlag = 0; } /** * @brief Set Dma status. * @param mtrCtrl The motor control handle. + * @retval None. */ static void SetUartDmaStatus(MTRCTRL_Handle *mtrCtrl) { @@ -77,20 +77,10 @@ static void SetUartDmaStatus(MTRCTRL_Handle *mtrCtrl) } } -/** - * @brief Set uart baudRate. - * @param baudrate Uart baudRate. - */ -static void SetUartBaudRate(unsigned int baudrate) -{ - /* Re_Write uart0 baudrate. */ - g_uart0.baudRate = baudrate; - HAL_UART_Init(&g_uart0); -} - /** * @brief Uart Dma interupt callback func. - * @param null. + * @param handle Uart handle. + * @retval None. */ void UART0_TXDMACallback(void *handle) { @@ -99,6 +89,11 @@ void UART0_TXDMACallback(void *handle) static unsigned int getlastSystickCnt = 0; /* USER CODE BEGIN UART0_WRITE_DMA_FINISH */ g_uartFrame.txFlag = 1; + /* Received information answered, information update reserved. */ + if (g_uartFrame.rxAckFlag == 1) { + g_uartFrame.uartItTxFlag = 1; + g_uartFrame.rxAckFlag = 0; + } getCurSystickCnt = DCL_SYSTICK_GetTick(); if (getlastSystickCnt != 0) { /* Calculate unit frame data send time */ @@ -108,22 +103,10 @@ void UART0_TXDMACallback(void *handle) /* USER CODE END UART0_WRITE_DMA_FINISH */ } -/** - * @brief Uart0 interruput Write CallBack Function. - * @param handle Uart handle. - */ -void UART0WriteInterruptCallback(void *handle) -{ - BASE_FUNC_UNUSED(handle); - /* USER CODE BEGIN UART0_WRITE_IT_FINISH */ - g_uartFrame.uartItTxFlag = 1; - g_uartFrame.txFlag = 1; - /* USER CODE END UART0_WRITE_IT_FINISH */ -} - /** * @brief Uart0 Interruput Read CallBack Function. * @param handle Uart handle. + * @retval None. */ void UART0ReadInterruptCallback(void *handle) { @@ -144,18 +127,19 @@ void UART0ReadInterruptCallback(void *handle) /** * @brief Uart Read Data Init Function. * @param void. + * @retval None. */ void UartRecvInit(void) { /* Uart reception initialization */ FrameRecvClear(&g_uartFrame); - SetUartBaudRate(UART0BAUDRATE); HAL_UART_ReadIT(&g_uart0, &g_uartFrame.rxData, 1); } /** * @brief Uart Read Data Process Function. * @param mtrCtrl The motor control handle. + * @retval None. */ void UartModuleProcess_Rx(MTRCTRL_Handle *mtrCtrl) { @@ -170,6 +154,7 @@ void UartModuleProcess_Rx(MTRCTRL_Handle *mtrCtrl) g_uartFrame.timeOutCnt = 0; /* Execute data process. */ CUST_DataReceProcss(mtrCtrl, g_uartRxBuf); + g_uartFrame.rxAckFlag = 1; g_uartFrame.rxLen = 0; } } @@ -179,20 +164,21 @@ void UartModuleProcess_Rx(MTRCTRL_Handle *mtrCtrl) /** * @brief Uart Write Data Process Function. * @param mtrCtrl The motor control handle. + * @retval None. */ void UartModuleProcess_Tx(MTRCTRL_Handle *mtrCtrl) { /* Verify Parameters */ MCS_ASSERT_PARAM(mtrCtrl != NULL); if (g_uartFrame.txFlag == 1) { /* Send data flag. */ - mtrCtrl->uartTimeStamp = (float)getdeltaSystickCnt; /* Unit data time stamp */ - g_uartFrame.upDataCnt = 0; - g_uartFrame.txFlag = 0; - /* Send data to host. */ - unsigned int txLen = CUST_TransmitData(mtrCtrl, g_uartTxBuf); - /* If txIT mode send data finish, convert to DMA mode */ - if (g_uartFrame.uartItTxFlag == 1) { - HAL_UART_WriteDMA(&g_uart0, g_uartTxBuf, txLen); - } + mtrCtrl->uartTimeStamp = (float)getdeltaSystickCnt; /* Unit data time stamp */ + g_uartFrame.upDataCnt = 0; + g_uartFrame.txFlag = 0; + /* Send data to host. */ + unsigned int txLen = CUST_TransmitData(mtrCtrl, g_uartTxBuf); + /* If txIT mode send data finish, convert to DMA mode */ + if (g_uartFrame.uartItTxFlag == 1) { + HAL_UART_WriteDMA(&g_uart0, g_uartTxBuf, txLen); + } } } diff --git a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/uart_module.h b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/uart_module.h index 1b3588ea132e4bafdfa4e831b9e4e8b0ad4efdd2..f1f8f89951fd2ab017f9ad6082a2542ca925aaaa 100644 --- a/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/uart_module.h +++ b/src/application/middleware_sample/pmsm_sensorless_2shunt_foc/user_interface/uart_module.h @@ -36,6 +36,7 @@ typedef struct { unsigned int upDataCnt; unsigned int upDataDelayCnt; unsigned char uartItTxFlag; + unsigned char rxAckFlag; } FRAME_Handle; diff --git a/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/inc/mcs_user_config.h b/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/inc/mcs_user_config.h index cf8e1911e31a97979bbc3f29cfa2c41295b7b3f4..5c20fc59d1bd3dce6992ffc8f99541ae7da15c38 100644 --- a/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/inc/mcs_user_config.h +++ b/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/inc/mcs_user_config.h @@ -44,8 +44,6 @@ /* Sampling resistance 50mOhm 0.0053179 */ #define ADC_CURR_COFFI 0.0053179f /* 3.3/4096/3.03/0.05 pga: 3.03, 50mohm */ -/* APT */ -#define APT_SYNC_IN_SRC APT_SYNCIN_SRC_APT0_SYNCOUT #define APT_U APT0_BASE /* Base address of U phase APT module */ #define APT_V APT1_BASE /* Base address of V phase APT module */ @@ -59,31 +57,33 @@ #define SPEED_FILTER_CUTOFF_FREQUENCY 40.0f /* SMO speed cutoff frequency. of speed filter. */ /* SMO4TH */ -#define SPECIAL_SMO4TH_PLL_BDW 50.0f -#define SPECIAL_SMO4TH_KD 1000.0f -#define SPECIAL_SMO4TH_KQ 7000.0f -#define SPECIAL_SMO4TH_SPD_FILTER_CUTOFF_FREQ 40.0f +#define SPECIAL_SMO4TH_PLL_BDW 50.0f /* SMO4TH PLL Bandwidth. */ +#define SPECIAL_SMO4TH_KD 1000.0f /* SMO4TH parameters KD. */ +#define SPECIAL_SMO4TH_KQ 7000.0f /* SMO4TH parameters KQ. */ +#define SPECIAL_SMO4TH_SPD_FILTER_CUTOFF_FREQ 40.0f /* SMO4TH speed cutoff frequency of speed filter. */ /* User_Commond */ -#define CTRL_IF_CURR_AMP_A 0.5f /* IF control current amplitude */ +#define CTRL_IF_CURR_AMP_A 0.5f /* IF control current amplitude */ #define USER_TARGET_SPD_HZ 100.0f /* Parentheses are used to enter negative instructions */ #define USER_SWITCH_SPDBEGIN_HZ 40.0f /* Start of handover interval */ -#define USER_MAX_SPD_HZ 200.0f +#define USER_MAX_SPD_HZ 200.0f /* User-defined maximum speed value. */ #define USER_SPD_SLOPE 20.0f /* slope of velocity change */ #define USER_CURR_SLOPE (CTRL_IF_CURR_AMP_A * 5.0f) /* Current change slope */ /* PID PARAMS */ -#define CURRQAXIS_KP 5.023202f -#define CURRQAXIS_KI 20612.84f -#define CURRDAXIS_KP 3.477114f -#define CURRDAXIS_KI 20612.84f +#define CURRQAXIS_KP 5.023202f /* Current loop Q axis Kp. */ +#define CURRQAXIS_KI 20612.84f /* Current loop Q axis Ki. */ +#define CURRDAXIS_KP 3.477114f /* Current loop D axis Kp. */ +#define CURRDAXIS_KI 20612.84f /* Current loop D axis Ki. */ +/* Current loop PID output lower limit. */ #define CURR_LOWERLIM (-INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 1.0f) +/* Current loop PID output upper limit. */ #define CURR_UPPERLIM (INV_VOLTAGE_BUS * ONE_DIV_SQRT3 * 1.0f) -#define SPD_KP 0.0105f -#define SPD_KI 0.03f -#define SPD_LOWERLIM -2.0f -#define SPD_UPPERLIM 2.0f +#define SPD_KP 0.0105f /* Speed loop Kp. */ +#define SPD_KI 0.03f /* Speed loop Ki. */ +#define SPD_LOWERLIM -2.0f /* Speed loop PID output lower limit. */ +#define SPD_UPPERLIM 2.0f /* Speed loop PID output upper limit. */ /* MOTOR PARAMS */ /* Np, Rs, Ld, Lq, Psif, J, Nmax, Currmax, PPMR, zShift */ @@ -96,6 +96,7 @@ .mtrJ = 0.0f, \ .maxElecSpd = 300.0f, \ .maxCurr = 1.0f, \ + .busVolt = INV_VOLTAGE_BUS, \ } #endif \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/main.c b/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/main.c index 2ff4bc16017a4d83107e6791caa030813cff5d32..65dd064c1d135382d412570ddc904c4c7a5ad96a 100644 --- a/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/main.c +++ b/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/main.c @@ -25,6 +25,8 @@ #include "mcs_motor_process.h" #include "main.h" /* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* 建议用户放置头文件 */ /* USER CODE END 0 */ ACMP_Handle g_acmp0; PGA_Handle g_pga0; @@ -37,23 +39,29 @@ ADC_Handle g_adc0; GPIO_Handle g_gpio0; GPIO_Handle g_gpio2; /* USER CODE BEGIN 1 */ +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ /* USER CODE END 1 */ int main(void) { /* USER CODE BEGIN 2 */ + /* 建议用户放置初始化代码或启动代码等 */ /* USER CODE END 2 */ MotorMainProcess(); /* USER CODE BEGIN 3 */ + /* 建议用户放置初始配置代码 */ /* USER CODE END 3 */ while (1) { /* USER CODE BEGIN 4 */ + /* 建议用户放置周期性执行代码 */ /* USER CODE END 4 */ } /* USER CODE BEGIN 5 */ + /* 建议用户放置代码流程 */ /* USER CODE END 5 */ return BASE_STATUS_OK; } /* USER CODE BEGIN 6 */ +/* 建议用户放置自定义函数 */ /* USER CODE END 6 */ \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/main.h b/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/main.h index 107297dda254cebc0270fc887e01762f4892094e..e6c6aa386c5793a786c11e3d1ca9ef9c1189c37f 100644 --- a/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/main.h +++ b/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/main.h @@ -67,11 +67,15 @@ extern GPIO_Handle g_gpio2; BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); void SystemInit(void); -void MotorCarrierProcessCallback(void *aptHandle); -void MotorSysErrCallback(void *aptHandle); void MotorStatemachineCallBack(void *handle); void TIMER1_DMAOverFlow_InterruptProcess(void *handle); +void MotorCarrierProcessCallback(void *aptHandle); +void MotorSysErrCallback(void *aptHandle); void MotorStartStopKeyCallback(void *param); +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + #endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/system_init.c b/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/system_init.c index 68762dc6c836b87ae468507b8744c2ce9f5484dd..5228e31eb353e22d39f3e5e200c553a13505c4cb 100644 --- a/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/system_init.c +++ b/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/init/system_init.c @@ -36,7 +36,7 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ - crg.handleEx.clk1MDiv = (25 - 1); /* The 25 - 1 is div coffecient */ + crg.handleEx.clk1MDiv = (25 - 1); /* 25 is the div of the clk_1m in CLOCK. */ if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; @@ -47,19 +47,17 @@ BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) static void ACMP0_Init(void) { - /* enable acmp input capture function */ HAL_CRG_IpEnableSet(ACMP0_BASE, IP_CLK_ENABLE); /* ACMP clock bit reset. */ - HAL_CRG_IpClkSelectSet(ACMP0_BASE, 0); g_acmp0.baseAddress = ACMP0_BASE; g_acmp0.inOutConfig.inputNNum = ACMP_INPUT_N_SELECT4; g_acmp0.inOutConfig.inputPNum = ACMP_INPUT_P_SELECT4; - /* set acmp polarity */ + /* set acmp polarity */ g_acmp0.inOutConfig.polarity = ACMP_OUT_NOT_INVERT; g_acmp0.filterCtrl.filterMode = ACMP_FILTER_FILTER; g_acmp0.filterCtrl.filterStep = 100; /* 100 is filter step size of the comparator. */ - g_acmp0.hysteresisVol = ACMP_HYS_VOL_ZERO; + g_acmp0.hysteresisVol = ACMP_HYS_VOL_30MV; g_acmp0.interruptEn = BASE_CFG_UNSET; - /* acmp0 init */ + /* acmp0 init */ HAL_ACMP_Init(&g_acmp0); } @@ -106,11 +104,10 @@ __weak void MotorCarrierProcessCallback(void *aptHandle) static void APT0_ProtectInit(void) { - /* enable apt0 event interupt protection function */ + /* enable apt0 event interupt protection function */ APT_OutCtrlProtectEx protectApt = {0}; protectApt.ocEventEnEx = BASE_CFG_ENABLE; protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; - protectApt.cbcClrModeEx = APT_CLEAR_CBC_ON_CNTR_ZERO; protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; /* low action protection */ protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocEvtInterruptEnEx = BASE_CFG_ENABLE; @@ -118,7 +115,7 @@ static void APT0_ProtectInit(void) protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_ACMP0; protectApt.evtPolarityMaskEx = APT_EM_ACMP0_INVERT_BIT; protectApt.filterCycleNumEx = 0; - /* set apt protect register */ + /* set apt protect register */ HAL_APT_ProtectInitEx(&g_apt0, &protectApt); } @@ -131,7 +128,7 @@ static void APT0_Init(void) /* Clock Settings */ g_apt0.waveform.dividerFactor = 1 - 1; /* Timer Settings */ - g_apt0.waveform.timerPeriod = 7500; /* apt init timer period is 7500 */ + g_apt0.waveform.timerPeriod = 7500; /* 7500 is count period of APT time-base timer */ g_apt0.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; /* Wave Form */ @@ -140,15 +137,15 @@ static void APT0_Init(void) g_apt0.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; g_apt0.waveform.divInitVal = 0; g_apt0.waveform.cntInitVal = 0; - g_apt0.waveform.cntCmpLeftEdge = 500; /* apt init left edge count period is 500 */ - g_apt0.waveform.cntCmpRightEdge = 4000; /* apt init right edge count period is 4000 */ + g_apt0.waveform.cntCmpLeftEdge = 500; /* 500 is count compare point of the left edge of PWM waveform */ + g_apt0.waveform.cntCmpRightEdge = 4000; /* 4000 is count compare point of the right edge of PWM waveform */ g_apt0.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_apt0.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; - g_apt0.waveform.deadBandCnt = 225; /* apt dead band count value is 225 */ + g_apt0.waveform.deadBandCnt = 225; /* 225 is dead-band value */ /* ADC Trigger SOCA */ g_apt0.adcTrg.trgEnSOCA = BASE_CFG_ENABLE; - g_apt0.adcTrg.cntCmpSOCA = 375; /* apt trig sample count value is 375 */ + g_apt0.adcTrg.cntCmpSOCA = 375; /* 375 is count compare point of ADC trigger source SOCA when using CMPA */ g_apt0.adcTrg.trgSrcSOCA = APT_CS_SRC_CNTR_CMPA_DOWN; g_apt0.adcTrg.trgScaleSOCA = 1; @@ -170,11 +167,11 @@ static void APT0_Init(void) HAL_APT_PWMInit(&g_apt0); HAL_APT_RegisterCallBack(&g_apt0, APT_EVENT_INTERRUPT, MotorSysErrCallback); - IRQ_SetPriority(IRQ_APT0_EVT, 7); /* apt event interupt level is 7 */ + IRQ_SetPriority(IRQ_APT0_EVT, 7); /* 7 is priority value */ IRQ_Register(IRQ_APT0_EVT, HAL_APT_EventIrqHandler, &g_apt0); IRQ_EnableN(IRQ_APT0_EVT); HAL_APT_RegisterCallBack(&g_apt0, APT_TIMER_INTERRUPT, MotorCarrierProcessCallback); - IRQ_SetPriority(IRQ_APT0_TMR, 6); /* apt timer interupt level is 6 */ + IRQ_SetPriority(IRQ_APT0_TMR, 6); /* 6 is priority value */ IRQ_Register(IRQ_APT0_TMR, HAL_APT_TimerIrqHandler, &g_apt0); IRQ_EnableN(IRQ_APT0_TMR); } @@ -182,19 +179,18 @@ static void APT0_Init(void) static void APT1_ProtectInit(void) { APT_OutCtrlProtectEx protectApt = {0}; - /* enable apt1 event interupt protection function */ + /* enable apt1 event interupt protection function */ protectApt.ocEventEnEx = BASE_CFG_ENABLE; protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; - protectApt.cbcClrModeEx = APT_CLEAR_CBC_ON_CNTR_ZERO; protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; - /* disable apt1 event interupt protection function */ + /* disable apt1 event interupt protection function */ protectApt.ocEvtInterruptEnEx = BASE_CFG_DISABLE; protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_ACMP0; protectApt.evtPolarityMaskEx = APT_EM_ACMP0_INVERT_BIT; protectApt.filterCycleNumEx = 0; - /* init APT config module */ + /* init APT config module */ HAL_APT_ProtectInitEx(&g_apt1, &protectApt); } @@ -207,7 +203,7 @@ static void APT1_Init(void) /* Clock Settings */ g_apt1.waveform.dividerFactor = 1 - 1; /* Timer Settings */ - g_apt1.waveform.timerPeriod = 7500; /* apt init timer period is 7500 */ + g_apt1.waveform.timerPeriod = 7500; /* 7500 is count period of APT time-base timer */ g_apt1.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; /* Wave Form */ @@ -216,31 +212,32 @@ static void APT1_Init(void) g_apt1.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; g_apt1.waveform.divInitVal = 0; g_apt1.waveform.cntInitVal = 0; - g_apt1.waveform.cntCmpLeftEdge = 500; /* apt init left edge count period is 500 */ - g_apt1.waveform.cntCmpRightEdge = 4000; /* apt init right edge count period is 4000 */ + g_apt1.waveform.cntCmpLeftEdge = 500; /* 500 is count compare point of the left edge of PWM waveform */ + g_apt1.waveform.cntCmpRightEdge = 4000; /* 4000 is count compare point of the right edge of PWM waveform */ g_apt1.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_apt1.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; - g_apt1.waveform.deadBandCnt = 225; /* apt dead band count value is 225 */ + g_apt1.waveform.deadBandCnt = 225; /* 225 is dead-band value */ + APT1_ProtectInit(); + HAL_APT_PWMInit(&g_apt1); } static void APT2_ProtectInit(void) { APT_OutCtrlProtectEx protectApt = {0}; - /* enable apt2 event interupt protection function */ + /* enable apt2 event interupt protection function */ protectApt.ocEventEnEx = BASE_CFG_ENABLE; protectApt.ocEventModeEx = APT_OUT_CTRL_ONE_SHOT; - protectApt.cbcClrModeEx = APT_CLEAR_CBC_ON_CNTR_ZERO; protectApt.ocActionEx = APT_OUT_CTRL_ACTION_LOW; protectApt.ocActionBEx = APT_OUT_CTRL_ACTION_LOW; - /* disable apt2 event interupt protection function */ + /* disable apt2 event interupt protection function */ protectApt.ocEvtInterruptEnEx = BASE_CFG_DISABLE; protectApt.ocSysEvent = APT_SYS_EVT_DEBUG | APT_SYS_EVT_CLK | APT_SYS_EVT_MEM; protectApt.originalEvtEx = APT_EM_ORIGINAL_SRC_ACMP0; protectApt.evtPolarityMaskEx = APT_EM_ACMP0_INVERT_BIT; protectApt.filterCycleNumEx = 0; - /* init APT config module */ + /* init APT config module */ HAL_APT_ProtectInitEx(&g_apt2, &protectApt); } @@ -253,7 +250,7 @@ static void APT2_Init(void) /* Clock Settings */ g_apt2.waveform.dividerFactor = 1 - 1; /* Timer Settings */ - g_apt2.waveform.timerPeriod = 7500; /* apt init timer period is 7500 */ + g_apt2.waveform.timerPeriod = 7500; /* 7500 is count period of APT time-base timer */ g_apt2.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; /* Wave Form */ @@ -262,18 +259,20 @@ static void APT2_Init(void) g_apt2.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; g_apt2.waveform.divInitVal = 0; g_apt2.waveform.cntInitVal = 0; - g_apt2.waveform.cntCmpLeftEdge = 500; /* apt init left edge count period is 500 */ - g_apt2.waveform.cntCmpRightEdge = 4000; /* apt init right edge count period is 4000 */ + g_apt2.waveform.cntCmpLeftEdge = 500; /* 500 is count compare point of the left edge of PWM waveform */ + g_apt2.waveform.cntCmpRightEdge = 4000; /* 4000 is count compare point of the right edge of PWM waveform */ g_apt2.waveform.cntCmpLoadMode = APT_BUFFER_INDEPENDENT_LOAD; g_apt2.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; - g_apt2.waveform.deadBandCnt = 225; /* apt dead band count value is 225 */ + g_apt2.waveform.deadBandCnt = 225; /* 225 is dead-band value */ + APT2_ProtectInit(); + HAL_APT_PWMInit(&g_apt2); } __weak void MotorStartStopKeyCallback(void *param) { - /* gpio interupt callback function */ + /* gpio interupt callback function */ GPIO_Handle *handle = (GPIO_Handle *)param; BASE_FUNC_UNUSED(handle); } @@ -282,13 +281,13 @@ static void GPIO_Init(void) { HAL_CRG_IpEnableSet(GPIO0_BASE, IP_CLK_ENABLE); g_gpio0.baseAddress = GPIO0; - /* set gpio0_6 config mode */ + /* set gpio0_6 config mode */ g_gpio0.pins = GPIO_PIN_6; HAL_GPIO_Init(&g_gpio0); HAL_GPIO_SetDirection(&g_gpio0, g_gpio0.pins, GPIO_OUTPUT_MODE); HAL_GPIO_SetValue(&g_gpio0, g_gpio0.pins, GPIO_LOW_LEVEL); HAL_GPIO_SetIrqType(&g_gpio0, g_gpio0.pins, GPIO_INT_TYPE_NONE); - /* enable gpio2 config */ + /* enable gpio2 config */ HAL_CRG_IpEnableSet(GPIO2_BASE, IP_CLK_ENABLE); g_gpio2.baseAddress = GPIO2; /* set gpio2_4 config mode */ @@ -306,7 +305,7 @@ static void GPIO_Init(void) /* set gpio2_3 config callback function */ HAL_GPIO_RegisterCallBack(&g_gpio2, GPIO_PIN_3, MotorStartStopKeyCallback); IRQ_Register(IRQ_GPIO2, HAL_GPIO_IrqHandler, &g_gpio2); - IRQ_SetPriority(IRQ_GPIO2, 1); /* set gpio1 interrupt priority to 1, 1~15 */ + IRQ_SetPriority(IRQ_GPIO2, 1); /* set gpio1 interrupt priority to 1, 1~15. 1 is priority value */ IRQ_EnableN(IRQ_GPIO2); /* gpio interrupt enable */ return; @@ -315,10 +314,9 @@ static void GPIO_Init(void) static void PGA0_Init(void) { HAL_CRG_IpEnableSet(PGA0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(PGA0_BASE, 0); + /* congfig pga0 base address */ g_pga0.baseAddress = PGA0_BASE; - g_pga0.gain = PGA_GAIN_2X; g_pga0.externalResistorMode = BASE_CFG_ENABLE; g_pga0.handleEx.extCapCompensation = PGA_EXT_COMPENSATION_2X; /* init pga0 module */ @@ -329,10 +327,9 @@ static void PGA1_Init(void) { /* enable pga1 */ HAL_CRG_IpEnableSet(PGA1_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(PGA1_BASE, 0); + /* config pga1 base address */ g_pga1.baseAddress = PGA1_BASE; - g_pga1.gain = PGA_GAIN_2X; g_pga1.externalResistorMode = BASE_CFG_ENABLE; g_pga1.handleEx.extCapCompensation = PGA_EXT_COMPENSATION_2X; /* init pga1 module */ @@ -348,8 +345,9 @@ __weak void MotorStatemachineCallBack(void *handle) static void TIMER1_Init(void) { - HAL_CRG_IpEnableSet(TIMER1_BASE, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet(TIMER1_BASE, IP_CLK_ENABLE); /* TIMER1 clock enable. */ unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER1) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 500; + g_timer1.baseAddress = TIMER1; g_timer1.load = load - 1; /* Set timer value immediately */ g_timer1.bgLoad = load - 1; /* Set timer value */ @@ -363,7 +361,7 @@ static void TIMER1_Init(void) IRQ_Register(IRQ_TIMER1, HAL_TIMER_IrqHandler, &g_timer1); HAL_TIMER_RegisterCallback(&g_timer1, TIMER_PERIOD_FIN, MotorStatemachineCallBack); - IRQ_SetPriority(IRQ_TIMER1, 1); + IRQ_SetPriority(IRQ_TIMER1, 1); /* 1 is priority value */ IRQ_EnableN(IRQ_TIMER1); } @@ -371,118 +369,142 @@ static void IOConfig(void) { SYSCTRL0->SC_SYS_STAT.BIT.update_mode = 0; SYSCTRL0->SC_SYS_STAT.BIT.update_mode_clear = 1; - HAL_IOCMG_SetPinAltFuncMode(GPIO3_1_AS_APT1_PWMA); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO3_1_AS_APT1_PWMA, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO3_1_AS_APT1_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO3_1_AS_APT1_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO3_1_AS_APT1_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_1_AS_APT1_PWMB); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_1_AS_APT1_PWMB, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_1_AS_APT1_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_1_AS_APT1_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_1_AS_APT1_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO3_0_AS_APT0_PWMA); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO3_0_AS_APT0_PWMA, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO3_0_AS_APT0_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO3_0_AS_APT0_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO3_0_AS_APT0_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_0_AS_APT0_PWMB); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_0_AS_APT0_PWMB, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_0_AS_APT0_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_0_AS_APT0_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_0_AS_APT0_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO3_2_AS_APT2_PWMA); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO3_2_AS_APT2_PWMA, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO3_2_AS_APT2_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO3_2_AS_APT2_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO3_2_AS_APT2_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ - - HAL_IOCMG_SetPinAltFuncMode(GPIO4_2_AS_APT2_PWMB); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO4_2_AS_APT2_PWMB, PULL_NONE); /* Pull-up and pull-down */ - HAL_IOCMG_SetPinSchmidtMode(GPIO4_2_AS_APT2_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ - HAL_IOCMG_SetPinLevelShiftRate(GPIO4_2_AS_APT2_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ - HAL_IOCMG_SetPinDriveRate(GPIO4_2_AS_APT2_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN4 */ HAL_IOCMG_SetPinAltFuncMode(GPIO2_6_AS_PGA0_N0); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_6_AS_PGA0_N0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO2_6_AS_PGA0_N0, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO2_6_AS_PGA0_N0, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO2_6_AS_PGA0_N0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO2_6_AS_PGA0_N0, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN5 */ HAL_IOCMG_SetPinAltFuncMode(GPIO2_5_AS_PGA0_P0); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_5_AS_PGA0_P0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO2_5_AS_PGA0_P0, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO2_5_AS_PGA0_P0, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO2_5_AS_PGA0_P0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO2_5_AS_PGA0_P0, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN3 */ HAL_IOCMG_SetPinAltFuncMode(GPIO2_7_AS_PGA0_OUT); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_7_AS_PGA0_OUT, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO2_7_AS_PGA0_OUT, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO2_7_AS_PGA0_OUT, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO2_7_AS_PGA0_OUT, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO2_7_AS_PGA0_OUT, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN11 */ HAL_IOCMG_SetPinAltFuncMode(GPIO1_5_AS_PGA1_P0); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO1_5_AS_PGA1_P0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO1_5_AS_PGA1_P0, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO1_5_AS_PGA1_P0, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO1_5_AS_PGA1_P0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO1_5_AS_PGA1_P0, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN12 */ HAL_IOCMG_SetPinAltFuncMode(GPIO1_6_AS_PGA1_N0); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO1_6_AS_PGA1_N0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO1_6_AS_PGA1_N0, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO1_6_AS_PGA1_N0, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO1_6_AS_PGA1_N0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO1_6_AS_PGA1_N0, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN13 */ HAL_IOCMG_SetPinAltFuncMode(GPIO1_7_AS_PGA1_OUT); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO1_7_AS_PGA1_OUT, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO1_7_AS_PGA1_OUT, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO1_7_AS_PGA1_OUT, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO1_7_AS_PGA1_OUT, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO1_7_AS_PGA1_OUT, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN48 */ HAL_IOCMG_SetPinAltFuncMode(GPIO0_6_AS_GPIO0_6); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO0_6_AS_GPIO0_6, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO0_6_AS_GPIO0_6, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO0_6_AS_GPIO0_6, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO0_6_AS_GPIO0_6, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO0_6_AS_GPIO0_6, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN41 */ HAL_IOCMG_SetPinAltFuncMode(GPIO2_4_AS_GPIO2_4); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_4_AS_GPIO2_4, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO2_4_AS_GPIO2_4, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO2_4_AS_GPIO2_4, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO2_4_AS_GPIO2_4, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO2_4_AS_GPIO2_4, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN35 */ HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_GPIO2_3); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_GPIO2_3, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_GPIO2_3, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_GPIO2_3, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_GPIO2_3, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_GPIO2_3, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN7 */ HAL_IOCMG_SetPinAltFuncMode(GPIO3_7_AS_ACMP0_OUT); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO3_7_AS_ACMP0_OUT, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO3_7_AS_ACMP0_OUT, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO3_7_AS_ACMP0_OUT, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO3_7_AS_ACMP0_OUT, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO3_7_AS_ACMP0_OUT, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN8 */ HAL_IOCMG_SetPinAltFuncMode(GPIO3_6_AS_ACMP_N4); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO3_6_AS_ACMP_N4, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO3_6_AS_ACMP_N4, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO3_6_AS_ACMP_N4, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO3_6_AS_ACMP_N4, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO3_6_AS_ACMP_N4, DRIVER_RATE_2); /* Output signal edge fast/slow */ - + /* Config PIN9 */ HAL_IOCMG_SetPinAltFuncMode(GPIO3_5_AS_ACMP_P4); /* Check function selection */ - HAL_IOCMG_SetPinPullMode(GPIO3_5_AS_ACMP_P4, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinPullMode(GPIO3_5_AS_ACMP_P4, PULL_NONE); /* Pull-up and Pull-down */ HAL_IOCMG_SetPinSchmidtMode(GPIO3_5_AS_ACMP_P4, SCHMIDT_DISABLE); /* Schmitt input on/off */ HAL_IOCMG_SetPinLevelShiftRate(GPIO3_5_AS_ACMP_P4, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ HAL_IOCMG_SetPinDriveRate(GPIO3_5_AS_ACMP_P4, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN19 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_0_AS_APT0_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_0_AS_APT0_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_0_AS_APT0_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_0_AS_APT0_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_0_AS_APT0_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN23 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_0_AS_APT0_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_0_AS_APT0_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_0_AS_APT0_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_0_AS_APT0_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_0_AS_APT0_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN20 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_1_AS_APT1_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_1_AS_APT1_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_1_AS_APT1_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_1_AS_APT1_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_1_AS_APT1_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN24 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_1_AS_APT1_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_1_AS_APT1_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_1_AS_APT1_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_1_AS_APT1_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_1_AS_APT1_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN21 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO3_2_AS_APT2_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_2_AS_APT2_PWMA, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_2_AS_APT2_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_2_AS_APT2_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_2_AS_APT2_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + /* Config PIN25 */ + HAL_IOCMG_SetPinAltFuncMode(GPIO4_2_AS_APT2_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_2_AS_APT2_PWMB, PULL_NONE); /* Pull-up and Pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_2_AS_APT2_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_2_AS_APT2_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_2_AS_APT2_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ +} + +static void APT_SyncMasterInit(void) +{ + /* APT master set. */ + HAL_APT_MasterSyncInit(&g_apt0, APT_SYNC_OUT_ON_CNTR_ZERO); +} + +static void APT_SyncSlaveInit(void) +{ + APT_SlaveSyncIn aptSlave; + + aptSlave.cntPhase = 0; /* counter phase value */ + aptSlave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; + aptSlave.syncInSrc = APT_SYNCIN_SRC_APT0_SYNCOUT; /* sync source selection */ + aptSlave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; + HAL_APT_SlaveSyncInit(&g_apt1, &aptSlave); + + aptSlave.cntPhase = 0; /* counter phase value */ + aptSlave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; + aptSlave.syncInSrc = APT_SYNCIN_SRC_APT0_SYNCOUT; /* sync source selection */ + aptSlave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; + HAL_APT_SlaveSyncInit(&g_apt2, &aptSlave); } void SystemInit(void) { - /* init system module */ + /* init system module */ IOConfig(); ACMP0_Init(); /* init APT module */ @@ -498,6 +520,8 @@ void SystemInit(void) TIMER1_Init(); GPIO_Init(); + APT_SyncMasterInit(); + APT_SyncSlaveInit(); /* USER CODE BEGIN system_init */ /* USER CODE END system_init */ } \ No newline at end of file diff --git a/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/src/mcs_motor_process.c b/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/src/mcs_motor_process.c index 08beb988db0a4e6e70d9d46b50d7a8e46d6adecf..1b1d27d76eb4255a9100512714cadf13e3545b04 100644 --- a/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/src/mcs_motor_process.c +++ b/src/application/middleware_sample/pmsm_sensorless_foc_2shunt_hv/src/mcs_motor_process.c @@ -103,7 +103,7 @@ static void FOSMO_InitWrapper(FOSMO_Handle *fosmo, float ts) .pllBdw = SPECIAL_SMO4TH_PLL_BDW, }; /* Init smo param. */ - FOSMO_Init(fosmo, fosmoParam, g_motorParam, ts); + FOSMO_Init(fosmo, fosmoParam, &g_motorParam, ts); } /* Smo4th param. */ @@ -117,7 +117,7 @@ static void SMO4TH_InitWrapper(SMO4TH_Handle *smo4TH) .fcLpf = SPECIAL_SMO4TH_SPD_FILTER_CUTOFF_FREQ, }; /* Init smo param. */ - SMO4TH_Init(smo4TH, smo4thParam, g_motorParam, CTRL_CURR_PERIOD); + SMO4TH_Init(smo4TH, smo4thParam, &g_motorParam, CTRL_CURR_PERIOD); } @@ -514,6 +514,9 @@ static void TrimInitAdcShiftValue(MTRCTRL_Handle *mtrCtrl) adc1TempSum += adc1SampleTemp; } } + if (adcSampleTimes < 1.0f) { + adcSampleTimes = 1.0f; /* Prevent divide-by-zero errors */ + } adc0SampleTemp = adc0TempSum / adcSampleTimes; adc1SampleTemp = adc1TempSum / adcSampleTimes; /* Force convert to float */ @@ -655,47 +658,6 @@ static void InitSoftware(void) g_mc.setADCTriggerTimeCb = SetADCTriggerTime; } -/** - * @brief Config the master APT. - * @param aptx The master APT handle. - * @retval None. - */ -static void AptMasterSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - /* Config the master APT. */ - HAL_APT_MasterSyncInit(aptx, APT_SYNC_OUT_ON_CNTR_ZERO); -} - -/** - * @brief Config the slave APT. - * @param aptx The slave APT handle. - * @retval None. - */ -static void AptSalveSet(APT_Handle *aptx) -{ - MCS_ASSERT_PARAM(aptx != NULL); - APT_SlaveSyncIn slave; - /* Config the slave APT. */ - slave.divPhase = 0; - slave.cntPhase = 0; - slave.syncCntMode = APT_COUNT_MODE_AFTER_SYNC_UP; - slave.syncInSrc = APT_SYNC_IN_SRC; - slave.cntrSyncSrc = APT_CNTR_SYNC_SRC_SYNCIN; - HAL_APT_SlaveSyncInit(aptx, &slave); -} -/** - * @brief Configuring Master and Slave APTs. - * @retval None. - */ -static void AptMasterSalveSet(void) -{ - /* motor APT master/slave synchronization */ - AptMasterSet(&g_apt0); - AptSalveSet(&g_apt1); - AptSalveSet(&g_apt2); -} - /** * @brief Config the KEY func. * @param handle The GPIO handle. @@ -746,7 +708,6 @@ int MotorMainProcess(void) SystemInit(); HAL_TIMER_Start(&g_timer1); - AptMasterSalveSet(); /* Disable PWM output before startup. */ MotorPwmOutputDisable(g_apt); /* Software initialization. */ diff --git a/src/board/dimming/src/dimming.c b/src/board/dimming/src/dimming.c index f5a642c6004a9eb0f0797fedfc91a756ece49501..34104aea6ca2fa6bad13198b9f294e82ae13720c 100644 --- a/src/board/dimming/src/dimming.c +++ b/src/board/dimming/src/dimming.c @@ -119,7 +119,9 @@ BOARD_DIM_Ret BOARD_DIM_SetDuty(int index, int targetLevel) #if defined (CHIP_3065HRPICZ) || defined(CHIP_3065HRPIRZ) || defined(CHIP_3061HRPIKZ) || defined (CHIP_3065ARPIRZ) currentDutyVal= g_dimInfo[index].gptHandle->duty; #endif -#if defined (CHIP_3061MNPICA) || defined(CHIP_3061MNPIKA) +#if defined (CHIP_3061MNPICA) || defined(CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNNIKA) || defined (CHIP_3061MNPIC8) || defined(CHIP_3061MNNIC8) || \ + defined (CHIP_3061MNPIK8) || defined (CHIP_3061MNNIK8) currentDutyVal = g_dimInfo[index].gptHandle->refB0.refdot; #endif if (currentDutyVal == BOARD_DIM_TABLE_MAX_VALUE) { /* Maximum Limit Processing. */ @@ -159,7 +161,9 @@ void BOARD_DIM_TimerCallBack(void *param) #if defined (CHIP_3065HRPICZ) || defined(CHIP_3065HRPIRZ) || defined(CHIP_3061HRPIKZ) || defined (CHIP_3065ARPIRZ) g_dimInfo[i].gptHandle->duty = g_dimTables[g_dimInfo[i].nowIndex]; #endif -#if defined (CHIP_3061MNPICA) || defined(CHIP_3061MNPIKA) +#if defined (CHIP_3061MNPICA) || defined(CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNNIKA) || defined (CHIP_3061MNPIC8) || defined(CHIP_3061MNNIC8) || \ + defined (CHIP_3061MNPIK8) || defined (CHIP_3061MNNIK8) g_dimInfo[i].gptHandle->refB0.refdot = g_dimTables[g_dimInfo[i].nowIndex]; #endif HAL_GPT_Config(g_dimInfo[i].gptHandle); diff --git a/src/build/build.py b/src/build/build.py index 2bb80f167fb49c6dd6672a11831ebd92d8633dbe..edbd2b3382266a01ab47c8012eb4b8145b204c5f 100644 --- a/src/build/build.py +++ b/src/build/build.py @@ -33,9 +33,34 @@ import platform import logging import stat import shlex +import logging from build_gn import read_json_file, del_allgn, AutoCreate +LOGGER = None + + +def init_logger(): + global LOGGER + LOGGER = logging.getLogger() + LOGGER.setLevel(logging.INFO) + + if not pathlib.Path('out').exists(): + makedirs('out') + + file_handler = logging.FileHandler('out/build.log', mode='w') + file_handler.setLevel(logging.INFO) + + console_handler = logging.StreamHandler() + console_handler.setLevel(logging.INFO) + + formatter = logging.Formatter('%(message)s') + file_handler.setFormatter(formatter) + console_handler.setFormatter(formatter) + + LOGGER.addHandler(file_handler) + LOGGER.addHandler(console_handler) + def usage(): ''' @@ -58,6 +83,8 @@ def copy_xml(): 'mss_prim_db') xml_path = build_tmp_path.joinpath('dfx_db', 'log.xml') target_path = pathlib.Path.cwd().joinpath('out') + if not os.path.exists(xml_path): + LOGGER.info("xml path is not exist") shutil.copy(xml_path, target_path) if os.path.isdir(build_tmp_path): shutil.rmtree(build_tmp_path) @@ -67,16 +94,20 @@ def generatefile(file_path, config): ''' Function description: Signing Executable Files. ''' + dfx_path = pathlib.Path.cwd().joinpath('drivers', 'debug', 'log') + if os.path.exists(dfx_path): + LOGGER.info("exist dfx feature, copy log.xml") + copy_xml() + toolchain_prefix = config.get_toolchain_prefix() # Instantiation parameter check. if not isinstance(file_path, str): - raise TypeError("file_path in para type error {}".format( - type(file_path))) + raise TypeError("file_path in para type error {}".format(type(file_path))) file_abspath = pathlib.Path(file_path).resolve() # Generate the bin file. bin_abspath = file_abspath.parent.joinpath('{}.bin' .format(file_abspath.stem)) - cmd = ['riscv32-linux-musl-objcopy', '-Obinary', str(file_abspath), str(bin_abspath)] + cmd = [toolchain_prefix + 'objcopy', '-Obinary', str(file_abspath), str(bin_abspath)] process = subprocess.Popen(cmd, shell=False) process.wait() ret_code = process.returncode @@ -86,7 +117,7 @@ def generatefile(file_path, config): # Generate the hex file. hex_abspath = file_abspath.parent.joinpath('{}.hex' .format(file_abspath.stem)) - cmd = ['riscv32-linux-musl-objcopy', '-Oihex', str(file_abspath), str(hex_abspath)] + cmd = [toolchain_prefix + 'objcopy', '-Oihex', str(file_abspath), str(hex_abspath)] process = subprocess.Popen(cmd, shell=False) process.wait() ret_code = process.returncode @@ -102,14 +133,21 @@ def generatefile(file_path, config): flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL modes = stat.S_IWUSR | stat.S_IRUSR with os.fdopen(os.open(list_path, flags, modes), 'w+') as list_file: - cmd = ['riscv32-linux-musl-objdump', '-S', str(file_abspath)] + cmd = [toolchain_prefix + 'objdump', '-S', str(file_abspath)] process = subprocess.Popen(cmd, stdout=list_file, shell=False) process.wait() ret_code = process.returncode if ret_code != 0: raise Exception("list_file failed, return code is " + ret_code) else: - cmd = ['riscv32-linux-musl-strip', str(file_abspath)] + strip_path = None + if config.tool_chain == "bisheng": + strip_path = pathlib.Path(config.compiler_path).joinpath("riscv32", 'riscv32-linux-musl-strip') + else: + strip_path = pathlib.Path(config.compiler_path).joinpath('riscv32-linux-musl-strip') + cmd = [strip_path, str(file_abspath)] + + process = subprocess.Popen(cmd, shell=False) process.wait() ret_code = process.returncode @@ -122,39 +160,39 @@ def run_build(**kwargs): Function description: Start building. ''' + LOGGER.info("\n=== start build ===\n") config = kwargs.get('config') compile_var = Compile() compile_var.compile(config) file_path = str(pathlib.Path().joinpath('out', 'bin', 'target.elf')) generatefile(file_path, config) + LOGGER.info("Build success!") + LOGGER.info("\n=== end build ===\n") -def exec_command(cmd, log_path, **kwargs): +def exec_command(cmd, **kwargs): ''' Function description: Run the build command. ''' - flags = os.O_WRONLY | os.O_CREAT - modes = stat.S_IWUSR | stat.S_IRUSR - with os.fdopen(os.open(log_path, flags, modes), 'w') as log_file: - process = subprocess.Popen(cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True, - errors='ignore', - **kwargs) - # Write the build process to the build.log. - for line in iter(process.stdout.readline, ''): - log_file.write(line) + process = subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + errors='ignore', + **kwargs) + + for line in iter(process.stdout.readline, ''): + LOGGER.info(line.replace('\n', ' ')) process.wait() ret_code = process.returncode # An error code is returned when the command is executed. if ret_code != 0: - with os.fdopen(os.open(log_path, flags, modes), 'at') as log_file: - for line in iter(process.stderr.readline, ''): - log_file.write(line) + for line in iter(process.stderr.readline, ''): + LOGGER.info(line.replace('\n', ' ')) + LOGGER.info('you can check build log in out/build.log') raise Exception("{} failed, return code is {}".format(cmd, ret_code)) @@ -162,7 +200,6 @@ def parsejson_startautocreat(config): ''' Function description: Parsing Chip Template Files. ''' - # Obtaining the gn and ninja Paths. Compile.get_tool_path() # Read the content of the compilation configuration file. @@ -175,8 +212,8 @@ def parsejson_startautocreat(config): check_output(config) check_extcomponent() del_allgn() - AutoCreate(json_content) - return True + AutoCreate(json_content, LOGGER) + LOGGER.info("The compilation script is successfully built.") def makedirs(path, exist_ok=True): @@ -186,11 +223,11 @@ def makedirs(path, exist_ok=True): try: os.makedirs(path) - except OSError: + except OSError as e: if not pathlib.Path(path).is_dir(): - raise Exception("{} makedirs failed".format(path)) + raise Exception("{} makedirs failed".format(path)) from e if not exist_ok: - raise Exception("{} exists, makedirs failed".format(path)) + raise Exception("{} exists, makedirs failed".format(path)) from e finally: pass @@ -268,7 +305,6 @@ def config_create(**kwargs): ''' Function description: Start to create configuration. ''' - config = kwargs.get('config') parsejson_startautocreat(config) return True @@ -294,6 +330,7 @@ def exec_create(args): config = Config(args) del_output(config) del_allgn() + LOGGER.info("Clean Successfully!") else: raise Exception("Error: action not found.") @@ -304,16 +341,15 @@ class Config(): ''' def __init__(self, args): + self.compiler_path = None self.action = args.action[0] self.build_type = args.build_type[0] self.tool_chain = args.tool_chain[0] self.__set_path() self.config = pathlib.Path(self.get_build_path())\ .joinpath('config.ini') - self.log_path = pathlib.Path(self.get_out_path()).joinpath('build.log') self.cfg = ConfigParser() self.cfg.read(self.config) - self.toolenv_check() self.set_default_cmd() self.set_env_path() self.args_list = [] @@ -336,28 +372,6 @@ class Config(): return self.__out_path - def toolenv_check(self): - ''' - Function description: Check whether the tool chain path is set. - ''' - - toolspath = self.cfg.get('gn_args', 'tools_path') - user_tool_path = os.path.join(os.path.expanduser("~"), - ".deveco-device-tool/compiler_tool_chain") - if not os.path.exists(user_tool_path): - # use default tool chain path - return - - if toolspath != user_tool_path: - self.cfg.set('gn_args', 'tools_path', user_tool_path) - flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC - modes = stat.S_IWUSR | stat.S_IRUSR - with os.fdopen(os.open(self.config, flags, modes), - 'w') as configini: - self.cfg.write(configini) - elif not toolspath: - raise Exception("Error: please set config.ini tools_path.") - def set_default_cmd(self): ''' Function description: Write the toolchain and version information to @@ -381,7 +395,8 @@ class Config(): self.cfg.set(section, 'build_type', self.build_type) if self.tool_chain != default_tool_chain: if self.tool_chain != 'hcc' and\ - self.tool_chain != 'hcc_fpu': + self.tool_chain != 'hcc_fpu' and\ + self.tool_chain != 'bisheng': raise Exception('Error: {} is not tool_chain, please check.'\ .format(self.tool_chain)) # Updating the userconfig.json File. @@ -389,6 +404,13 @@ class Config(): .joinpath(self.tool_chain, userconfig_file_name), target_path) self.cfg.set(section, 'toolchain_select', self.tool_chain) + toolchain_prefix_key = 'toolchain_prefix' + if self.tool_chain == 'hcc' or self.tool_chain == 'hcc_fpu': + self.cfg.set(section, toolchain_prefix_key, "riscv32-linux-musl-") + elif self.tool_chain == 'bisheng': + self.cfg.set(section, toolchain_prefix_key, "llvm-") + else: + self.cfg.set(section, toolchain_prefix_key, "llvm-") if not pathlib.Path(target_path).joinpath(userconfig_file_name).exists(): # userconfig.json file corresponding to different tool chains. shutil.copy(pathlib.Path(compileopt_path)\ @@ -407,8 +429,6 @@ class Config(): Function description: Write the toolchain and version information to the config.ini file. ''' - - compiler_path = None tools_path = self.cfg.get('gn_args', 'tools_path') cur_sys = platform.system() @@ -417,31 +437,39 @@ class Config(): ninja_name = 'ninja-linux' hcc_name = 'cc_riscv32_musl' hccfpu_name = 'cc_riscv32_musl_fp' + llvm_name = 'linx-llvm-binary-release-musl' elif cur_sys == "Windows": - gn_name = 'gn-win' - ninja_name = 'ninja-win' + gn_name = 'gn' + ninja_name = 'ninja' hcc_name = 'cc_riscv32_musl_win' hccfpu_name = 'cc_riscv32_musl_fp_win' + llvm_name = 'linx-llvm-binary-release-win-musl' # Setting GN and NINJA env. gn_path = pathlib.Path(tools_path).joinpath(cur_sys, gn_name) ninja_path = pathlib.Path(tools_path).joinpath(cur_sys, ninja_name) # Setting Toolchain env. + bin_folder_name = 'bin' if self.tool_chain == 'hcc': - # Check whether the env contains hcc. - compiler_path = distutils.spawn\ - .find_executable("riscv32-linux-musl-gcc") - if compiler_path is None: - # If no, set the hcc path to the env. - compiler_path = pathlib.Path(tools_path)\ - .joinpath(cur_sys, hcc_name, 'bin') + # Set the hcc path to the env. + self.compiler_path = pathlib.Path(tools_path)\ + .joinpath(cur_sys, hcc_name, bin_folder_name) + if not pathlib.Path(self.compiler_path).exists(): + # Check whether the env contains hcc. If not exist, use env tool. + self.compiler_path = os.path.dirname(distutils.spawn.find_executable("riscv32-linux-musl-gcc")) elif self.tool_chain == 'hcc_fpu': - # Check whether the env contains hcc_fpu. - compiler_path = distutils.spawn\ - .find_executable("riscv32-linux-musl-gcc") - if compiler_path is None: - # If no, set the hcc_fpu path to the env. - compiler_path = pathlib.Path(tools_path)\ - .joinpath(cur_sys, hccfpu_name, 'bin') + # Set the hcc_fpu path to the env. + self.compiler_path = pathlib.Path(tools_path)\ + .joinpath(cur_sys, hccfpu_name, bin_folder_name) + if not pathlib.Path(self.compiler_path).exists(): + # Check whether the env contains hcc_fpu. If not exist, use env tool. + self.compiler_path = os.path.dirname(distutils.spawn.find_executable("riscv32-linux-musl-gcc")) + elif self.tool_chain == 'bisheng': + # Set the hcc_fpu path to the env. + self.compiler_path = pathlib.Path(tools_path)\ + .joinpath(cur_sys, llvm_name, bin_folder_name) + if not pathlib.Path(self.compiler_path).exists(): + # Check whether the env contains llvm. If not exist, use env tool. + self.compiler_path = os.path.dirname(distutils.spawn.find_executable("clang")) else: raise Exception('Error: Unsupported compiler {}.'\ .format(self.tool_chain)) @@ -449,12 +477,12 @@ class Config(): str_path = 'PATH' if cur_sys == "Linux": # Setting Temporary Environment Variables - os.environ[str_path] = "{}:{}:{}:{}".format(os.environ[str_path], - gn_path, ninja_path, compiler_path) + os.environ[str_path] = "{}:{}:{}:{}".format(self.compiler_path, + gn_path, ninja_path, os.environ[str_path]) elif cur_sys == "Windows": # Setting Temporary Environment Variables - os.environ[str_path] = "{};{};{};{}".format(os.environ[str_path], - gn_path, ninja_path, compiler_path) + os.environ[str_path] = "{};{};{};{}".format(self.compiler_path, + gn_path, ninja_path, os.environ[str_path]) # get compile cmd def get_cmd(self, gn_path, ninja_path): @@ -468,6 +496,9 @@ class Config(): self.args_list.append(self.cfg.get('gn_args', 'toolchain_args')) return "".join(self.args_list).replace('\"', '\\"') + def get_toolchain_prefix(self): + return self.cfg.get('gn_args', 'toolchain_prefix') + def __set_path(self): self.__root_path = pathlib.Path.cwd() self.__build_path = pathlib.Path(self.__root_path).joinpath('build') @@ -517,7 +548,7 @@ class Compile(): if sys.platform == 'linux': cmd = shlex.split(cmd) # If shell is True, cmd is a string; if not, a sequence. - exec_command(cmd, log_path=config.log_path, shell=False) + exec_command(cmd, shell=False) class CallbackDict(object): @@ -546,7 +577,8 @@ def main(argv): ''' Function description: build and compile entry function. ''' - + # initialize logger + init_logger() # Read the default command value configini_path = pathlib.Path.cwd().joinpath('build', 'config.ini') configini = ConfigParser() @@ -566,18 +598,7 @@ def main(argv): parser.set_defaults(command=exec_create) args = parser.parse_args() - try: - status = args.command(args) - # Generally, press Ctrl+C to raise exception. - except KeyboardInterrupt: - logging.warning('interrupted') - status = -1 - # Catch Other Exceptions - except Exception as exce: - parser.print_help() - status = -1 - finally: - pass + status = args.command(args) return status diff --git a/src/build/build_gn.py b/src/build/build_gn.py index b3ac601d82d708891c4d81600ecabbdbc36709d1..4f50894deab92c0a35e82c58b9f26d24625b2bcd 100644 --- a/src/build/build_gn.py +++ b/src/build/build_gn.py @@ -22,16 +22,19 @@ import sys import os +import platform import stat import subprocess import pathlib import json import shlex import shutil +import distutils.spawn +from configparser import ConfigParser from createxml.mk_prim_xml_step1 import CreateCfg from createxml.mk_prim_xml_step2 import CreateXml - + def read_json_file(input_file): ''' @@ -64,16 +67,42 @@ def del_allgn(): os.remove(global_buildfile) +def get_gn_args_config(): + configini_path = pathlib.Path.cwd().joinpath('build', 'config.ini') + config_ini_data = ConfigParser() + config_ini_data.read(configini_path) + return config_ini_data + + +def set_link_path(config_gn_args): + config_tools_path = config_gn_args.get('gn_args', 'tools_path') + link_path = None + if config_tools_path: + cur_sys = platform.system() + if cur_sys == "Linux": + link_path = pathlib.Path(config_tools_path).joinpath("Linux", 'linx-llvm-binary-release-musl', + 'riscv32-elf', 'lib', 'rv32imfc_ilp32f') + elif cur_sys == "Windows": + link_path = pathlib.Path(config_tools_path).joinpath("Windows", 'linx-llvm-binary-release-win-musl', + 'riscv32-elf', 'lib', 'rv32imfc_ilp32f') + else: + clang_dir = os.path.dirname(distutils.spawn.find_executable("clang")) + link_path = pathlib.Path(clang_dir).joinpath("..", "riscv32-elf", "lib", "rv32imfc_ilp32f") + return link_path + + class AutoCreate(): ''' Function description: Automatically builds the compilation framework. ''' - def __init__(self, json_content): + def __init__(self, json_content, logger): ''' Function description: Initialization is invoked by default. ''' + self.logger = logger + if 'system' not in json_content: raise Exception('Error: system not exist,please check.') @@ -84,6 +113,8 @@ class AutoCreate(): # Save the path of third-party components so that # they are not scanned during automatic construction. self.ext_component_path = [] + self.xmlfiles = [] + self.includes_path = [] for subsystem in json_content['system']: if subsystem['name'] == 'compile': @@ -150,15 +181,8 @@ class AutoCreate(): if not pathlib.Path(include).is_dir(): raise Exception('Error: {} is not a dir, please ' 'check.'.format(include)) - for (dirpath, _, filenames) in os.walk(pathlib.Path( - include)): - for file in filenames: - if pathlib.Path(file).suffix != '.h': - continue - include_file = pathlib.Path(dirpath).joinpath(file) - copy_path = pathlib.Path('middleware').joinpath( - 'thirdparty', 'sysroot', 'include') - shutil.copy(include_file, copy_path) + for (dirpath, _, filenames) in os.walk(pathlib.Path(include)): + copy_includes(dirpath, filenames) @staticmethod def cmd_exec(command): @@ -231,6 +255,16 @@ class AutoCreate(): return False return True + + @staticmethod + def copy_includes(self, dirpath, files): + for file in files: + if pathlib.Path(file).suffix != '.h': + continue + include_file = pathlib.Path(dirpath).joinpath(file) + copy_path = pathlib.Path('middleware').joinpath( + 'thirdparty', 'sysroot', 'include') + shutil.copy(include_file, copy_path) def subsystem_transplant(self, subsystem): ''' @@ -270,7 +304,6 @@ class AutoCreate(): ''' Function description: Compiling Subsystem ''' - # Instantiation parameter check. if not isinstance(subsystem, dict): raise TypeError("subsystem in para type error {}".format( @@ -302,6 +335,11 @@ class AutoCreate(): # Global compilation script building self.globalgn_create(globalbuild_dict) + dfx_path = pathlib.Path.cwd().joinpath('drivers', 'debug', 'log') + if os.path.exists(dfx_path): + self.logger.info("exist dfx feature, create log.xml") + self.xml_create() + def localgn_create(self, module_content): ''' Function description: Module partial construction. @@ -480,6 +518,7 @@ class AutoCreate(): if self.cflags: self.build_content.append(" cflags = [\n") for cflags in self.cflags: + cflags = cflags.replace(" ", "\", \"") self.build_content.append(prefix + cflags + suffix) self.build_content.append(close_bracket) @@ -494,6 +533,7 @@ class AutoCreate(): if self.ldflags: self.build_content.append(" ldflags = [\n") for ldflags in self.ldflags: + ldflags = ldflags.replace(" ", "\", \"") self.build_content.append(prefix + ldflags + suffix) self.lds_scripts_config() @@ -544,23 +584,27 @@ class AutoCreate(): c_file = self.xmlfiles module_name = "mcu_xml" str_dfx_db = 'dfx_db' - build_tmp_path = pathlib.Path.cwd().joinpath('build', 'createxml', - 'mss_prim_db') + build_tmp_path = pathlib.Path.cwd().joinpath('build', 'createxml', 'mss_prim_db') if not build_tmp_path: os.makedirs(build_tmp_path) prim_xml_cfg_dir = build_tmp_path.joinpath(str_dfx_db, 'xml_cfg') - prim_xml_cfg_file = build_tmp_path.joinpath(str_dfx_db, 'xml_cfg', - module_name + '.cfg') - in_path = pathlib.Path.cwd().joinpath('build', 'createxml', - 'mk_dfx_xml.json') + prim_xml_cfg_file = build_tmp_path.joinpath(str_dfx_db, 'xml_cfg', module_name + '.cfg') + in_path = pathlib.Path.cwd().joinpath('build', 'createxml', 'mk_dfx_xml.json') hdb_xml_temp_root_dir = build_tmp_path.joinpath('modules') - hdb_xml_file_id = pathlib.Path.cwd().joinpath('drivers', - 'debug', 'log', 'inc', 'file_id_defs.h') + hdb_xml_file_id = pathlib.Path.cwd().joinpath('drivers', 'debug', 'log', 'inc', 'file_id_defs.h') prim_xml_key_word = module_name i_file_dir = build_tmp_path.joinpath('modules', module_name) prim_xml_dst_full_path = build_tmp_path.joinpath(str_dfx_db, 'log.xml') sources = c_file - build_xml_para.update({"cflags": self.cflags}) + cflags = [] + for cflag in self.cflags: + cflags + cflag.split() + config_gn_args = get_gn_args_config() + config_toolchain_select = config_gn_args.get('gn_args', 'toolchain_select') + cc = 'riscv32-linux-musl-gcc' + if config_toolchain_select == 'bisheng': + cc = 'clang' + build_xml_para.update({"cflags": cflags}) build_xml_para.update({"c_file": c_file}) build_xml_para.update({"build_tmp_path": build_tmp_path}) build_xml_para.update({"prim_xml_cfg_dir": prim_xml_cfg_dir}) @@ -572,7 +616,7 @@ class AutoCreate(): build_xml_para.update({"prim_xml_key_word": prim_xml_key_word}) build_xml_para.update({"i_file_dir": i_file_dir}) build_xml_para.update({"sources": sources}) - build_xml_para.update({"cc": "riscv32-linux-musl-gcc"}) + build_xml_para.update({"cc": cc}) build_xml_para.update({"include": self.includes_path}) build_xml_para.update({"prim_xml_dst_full_path": prim_xml_dst_full_path}) @@ -602,27 +646,26 @@ class AutoCreate(): Function description: Global Source File Search. ''' - self.nocheck_lists = [] - self.nocheck_lists_file = [] + nocheck_lists = [] + nocheck_lists_file = [] self.build_content.append(" sources = [\n") - self.xmlfiles = [] for module_list in self.json_module_path: for sources_list in module_list: if pathlib.Path(sources_list).is_file(): - self.nocheck_lists_file.append(sources_list) + nocheck_lists_file.append(sources_list) else: - self.nocheck_lists.append(sources_list) + nocheck_lists.append(sources_list) for nocheck_list in self.nocheck: - self.nocheck_lists.append(nocheck_list) - self.nocheck_lists.extend(self.ext_component_path) + nocheck_lists.append(nocheck_list) + nocheck_lists.extend(self.ext_component_path) - self._root_path = pathlib.Path() - for (dirpath, dirnames, filenames) in os.walk(self._root_path): + root_path = pathlib.Path() + for (dirpath, dirnames, filenames) in os.walk(root_path): dirnames.sort() filenames.sort() # Find all module code except in the JSON file - if not self.nochecklist(dirpath, self.nocheck_lists): + if not self.nochecklist(dirpath, nocheck_lists): continue for file_global in filenames: @@ -631,7 +674,7 @@ class AutoCreate(): continue if not self.nochecklist(str(pathlib.Path(dirpath). joinpath(file_global)), - self.nocheck_lists_file): + nocheck_lists_file): continue if pathlib.Path(file_global).suffix == '.c': self.xmlfiles.append("{}".format( @@ -704,7 +747,6 @@ class AutoCreate(): return True def includes_scan(self, path): - self.includes_path = [] for (dirpath, dirnames, filenames) in os.walk(path): dirnames.sort() filenames.sort() @@ -746,10 +788,10 @@ class AutoCreate(): if filename == "target": continue break - self._lds_scripts_path = pathlib.Path("..").joinpath('chip', + lds_scripts_path = pathlib.Path("..").joinpath('chip', filename, 'flash.lds') self.build_content.append(" \"-T{}\",\n" - .format(self._lds_scripts_path)) + .format(lds_scripts_path)) def library_link_config(self): ''' @@ -799,6 +841,11 @@ class AutoCreate(): self.build_content.append(" \"-l{}\",\n" .format(extlibsname[3:-2])) self.build_content.append(" \"-Wl,--no-whole-archive\",\n") + config_gn_args = get_gn_args_config() + config_toolchain_select = config_gn_args.get('gn_args', 'toolchain_select') + if (config_toolchain_select == 'bisheng'): + link_path = set_link_path(config_gn_args) + self.build_content.append(" \"-L{}\", \n".format(link_path)) def main(argv): diff --git a/src/build/ci_entry.py b/src/build/ci_entry.py new file mode 100644 index 0000000000000000000000000000000000000000..becf89591bcfb4ace0a7abba21a613818b2f16ef --- /dev/null +++ b/src/build/ci_entry.py @@ -0,0 +1,232 @@ +# !/usr/bin/env python +# -*- coding: utf-8 -*- + +# @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. +# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +# following conditions are met: +# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +# disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +# following disclaimer in the documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder 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 HOLDER 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. +# ci_entry.py Function implementation: CI build entry file, which is used to +# copy code and invoke build compilation scripts. + +import os +import sys +import pathlib +from configparser import ConfigParser +import stat +import shutil +import shlex +import subprocess +import platform + +from build_gn import read_json_file +from ide_entry import un_alltools +from build import remove_readonly + +# ci release map +chose_ci_release_sdk = { + "SolarA2_1.0.0": "3065h", + "SolarA2_1.0.1": "3061m", + "SolarA2_1.0.2": "3015", + "SolarA2_1.1.0": "3066m", + "SolarA2_1.1.1": "3066h" +} + + +def dest_path_cpoy(copy_path, dirprocesspath, dirpath, filenames): + ''' + Function description: Source file copy to destination address. + ''' + # Destination address + dest_path = pathlib.Path(copy_path).joinpath(dirprocesspath) + if not dest_path.exists(): + os.makedirs(dest_path) + # Copy files + for file in filenames: + if 'entry.py' in file or 'trustlist.json' in file: + continue + source_file = pathlib.Path(dirpath).joinpath(file) + shutil.copy(source_file, dest_path) + + +def filter_copy_adpater(copy_path, dirpath, filenames): + ''' + Function description: project create. + ''' + ipbefore_list = [] + ipafter_list = [] + cur_sys = platform.system() + if cur_sys == 'Windows': + ipbefore_list = dirpath.split('\\') + elif cur_sys == 'Linux': + ipbefore_list = dirpath.split('/') + ipafter_list = [] + p_vindex = 0 + p_cindex = -1 + for v_index, ipdir in enumerate(ipbefore_list): + if ipdir.startswith('v') and '.' in ipdir: + continue + # Filtering files + if '_v' in ipdir: + p_vindex = v_index + if 'common_v' in ipdir: + p_cindex = v_index + ipafter_list.append(ipdir) + # Filtering similar catalogs with v + if ipafter_list[p_vindex - 1] + '_v' in ipafter_list[p_vindex]: + ipafter_list.pop(p_vindex) + if p_cindex >= 0: + ipafter_list[p_cindex] = 'common' + p_cindex = -1 + dirprocesspath = '/'.join(ipafter_list) + dest_path_cpoy(copy_path, dirprocesspath, dirpath, filenames) + + +def traversal_path(copy_path, module_path, version): + ''' + Function description: create and copy work. + ''' + # copy file by different chip version + for (dirpath, _, filenames) in os.walk(module_path): + filter_copy_adpater(copy_path, dirpath, filenames) + + +def copy_drive_modules(copy_abspath, product, ip_name, copyjson_content): + ''' + Function description: Copying drive modules + ''' + source_path = os.path.join('drivers', ip_name) + for ip_content in copyjson_content[ip_name]: + # Merge paths + source_path = os.path.join(source_path, ip_content) + if pathlib.Path(source_path).is_dir(): + traversal_path(copy_abspath, source_path, product) + # File copy processing in driver module + elif pathlib.Path(source_path).is_file(): + parent_path = pathlib.Path(source_path).parent + copy_parent_path = pathlib.Path(copy_abspath).joinpath(parent_path) + # Create if the file does not exist + if not copy_parent_path.exists(): + os.makedirs(copy_parent_path) + shutil.copy(source_path, copy_parent_path) + source_path = '' + source_path = os.path.join('drivers', ip_name) + + +def copy_code(product, copy_path): + ''' + Function description: file filter for different chip type + ''' + # Instantiation parameter check. + if not isinstance(copy_path, str): + raise TypeError("copy_path in para type error {}".format( + type(copy_path))) + if not isinstance(product, str): + raise TypeError("product in para type error {}".format( + type(product))) + # Copy file path + if pathlib.Path(copy_path).exists(): + shutil.rmtree(os.path.realpath(copy_path), onerror=remove_readonly) + copy_abspath = pathlib.Path(copy_path).resolve() + copyjson_path = pathlib.Path.cwd()\ + .joinpath('chip', "{}".format(product), 'codecopy.json') + copyjson_content = read_json_file(copyjson_path) + # Add the basic modules + for module_path in copyjson_content['modules']: + if pathlib.Path(module_path).is_dir(): + traversal_path(copy_abspath, module_path, product) + elif pathlib.Path(module_path).is_file(): + # File copy processing in basic module + parent_path = pathlib.Path(module_path).parent + copy_parent_path = pathlib.Path(copy_abspath).joinpath(parent_path) + # Create if the file does not exist + if not copy_parent_path.exists(): + os.makedirs(copy_parent_path) + shutil.copy(module_path, copy_parent_path) + if str(parent_path) == 'chip\\target' or str(parent_path) == 'chip/target' : + userconfig_json_name = module_path.split('/')[-1] + os.rename(pathlib.Path(copy_parent_path).joinpath(userconfig_json_name), + pathlib.Path(copy_parent_path).joinpath('userconfig.json')) + # Copying drive modules + for ip_name in copyjson_content['ip_drive_file']: + copy_drive_modules(copy_abspath, product, ip_name, copyjson_content) + + +def differ_file_copy(copy_chip, copy_path, tools_path): + ''' + Function description: Projection generation for different chip + ''' + # Decompress all compilation tools. + un_alltools(tools_path) + + # Detach the chip package. + copy_code(copy_chip, copy_path) + os.chdir(pathlib.Path(copy_path).resolve()) + target_pathconfigsource = pathlib.Path().cwd().joinpath('chip', copy_chip, 'target') + target_pathconfigdest = pathlib.Path().cwd().joinpath('chip', 'target') + # Target file replace + if pathlib.Path(target_pathconfigsource).exists(): + shutil.rmtree(target_pathconfigdest) + shutil.copytree(target_pathconfigsource, target_pathconfigdest) + # Write the path of the full package tool to the config.ini file. + config_path = pathlib.Path().cwd().joinpath('build', 'config.ini') + config = ConfigParser() + config.read(config_path) + config.set('gn_args', 'tools_path', tools_path) + flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC + modes = stat.S_IWUSR | stat.S_IRUSR + flagsone = os.O_RDWR | os.O_CREAT + # File socket of the config.ini file. + with os.fdopen(os.open(config_path, flags, modes), 'w+') as configini: + config.write(configini) + # Executing Build and Compile Commands + cmd = shlex.split('python build/build.py build') + proc = subprocess.Popen(cmd) + proc.wait() + ret_code = proc.returncode + if ret_code != 0: + raise Exception("CI {} failed, return code is {}".format(cmd, ret_code)) + + +def ci_entry(argv): + ''' + Function description: ci entry function. + ''' + if not pathlib.Path('build/ci_entry.py').exists(): + os.chdir("/home/ci/driver") + # Save the path of the full package tool. + tools_path = str(pathlib.Path().cwd().joinpath('tools', 'toolchain')) + # CI building or releasing + if len(argv) == 3: + if argv[0] == 'release': + copy_chip = argv[1] + copy_path = argv[2] + else: + copy_chip = argv[1] + '_' + argv[2] + # pick chip name from map + try: + copy_chip = chose_ci_release_sdk[copy_chip] + except KeyError: + copy_chip = '3065h' + copy_path = 'mcu_' + copy_chip + '_project' + else: + # default value + copy_chip = '3065h' + copy_path = '../mcu_pro' + # Copying and generating project files + working_path = pathlib.Path.cwd() + differ_file_copy(copy_chip, copy_path, tools_path) + +if __name__ == "__main__": + sys.exit(ci_entry(sys.argv)) diff --git a/src/build/config.ini b/src/build/config.ini index 01f981905966d66d9612e81539fc609f7f6d58f2..4e53cdbb3f669f8d45c0f1833f60333901f7318e 100644 --- a/src/build/config.ini +++ b/src/build/config.ini @@ -5,12 +5,13 @@ out_path = gn_args = gn_cmd = %(gn_path)s gen %(out_path)s --root=. --dotfile=build/.gn --args="%(gn_args)s" ninja_path = -ninja_cmd = %(ninja_path)s -w dupbuild=warn -C %(out_path)s +ninja_cmd = %(ninja_path)s -C %(out_path)s [gn_args] tools_path = build_type = release build_type_args = build_type="%(build_type)s" -toolchain_select = hcc_fpu +toolchain_select = bisheng +toolchain_prefix = llvm- toolchain_args = build_compiler_specified="%(toolchain_select)s" gen_crc = yes diff --git a/src/build/config/BUILDCONFIG.gn b/src/build/config/BUILDCONFIG.gn index db7374feea247973a246dc7099bc4fe8392b3709..ccda2b644e51b14dad3988a00d15b31a39802376 100644 --- a/src/build/config/BUILDCONFIG.gn +++ b/src/build/config/BUILDCONFIG.gn @@ -22,4 +22,6 @@ if (build_compiler_specified == "hcc") { set_default_toolchain("//build/toolchain:riscv32_hcc") }else if (build_compiler_specified == "hcc_fpu") { set_default_toolchain("//build/toolchain:riscv32_hcc") +}else if (build_compiler_specified == "bisheng") { + set_default_toolchain("//build/toolchain:bisheng") } diff --git a/src/build/config/bisheng_131_hard/userconfig.json b/src/build/config/bisheng_131_hard/userconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..5bfdb59861daa08573d1c5104e37f6b62538b29c --- /dev/null +++ b/src/build/config/bisheng_131_hard/userconfig.json @@ -0,0 +1,115 @@ +{ + "system": [ + { + "name": "compile", + "subsystem": [ + { + "name": "static_lib", + "component": [ + { + "name": "", + "target_type": "static", + "sources": [], + "includes": [], + "define": [], + "libs": [], + "lds_scripts": [], + "cflags": [], + "asmflags": [], + "ldflags": [] + } + ] + }, + { + "name": "compile_frame", + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Werror=implicit-function-declaration", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm -imm-compare", + "-mllvm -emit-muliadd", + "-mllvm -merge-immshf", + "-mllvm -emit-uxtb-uxth", + "-mllvm --enable-lli=true", + "-mllvm -fldm-stm-optimize", + "-mllvm -himideer-push-pop", + "-mllvm --jump-is-expensive=false", + "-mllvm --min-jump-table-entries=1000000", + "-mllvm -enable-rodata-sections=true", + "-mllvm -enable-branch-imm-no-zero=true", + "-mllvm --riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm -unroll-runtime", + "-mllvm -enable-loop-flatten=true", + "-mllvm -enable-loop-fusion=true", + "-mllvm -enable-small-loop-unroll=false", + "-mllvm -enable-unroll-and-jam=true", + "-mllvm -allow-unroll-and-jam=true", + "-mllvm -unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ], + "define": [ + "FLOAT_SUPPORT" + ], + "nocheck": [], + "extlibspath": [], + "extlibsname": [], + "extlibsinclude": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/build/config/bisheng_132_hard/userconfig.json b/src/build/config/bisheng_132_hard/userconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..9711d7d696dac356d1e0752eb7140a058eab8c3e --- /dev/null +++ b/src/build/config/bisheng_132_hard/userconfig.json @@ -0,0 +1,109 @@ +{ + "system": [ + { + "name": "compile", + "subsystem": [ + { + "name": "static_lib", + "component": [ + { + "name": "", + "target_type": "static", + "sources": [], + "includes": [], + "define": [], + "libs": [], + "lds_scripts": [], + "cflags": [], + "asmflags": [], + "ldflags": [] + } + ] + }, + { + "name": "compile_frame", + "cflags": [ + "-Os", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fno-strict-aliasing", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imafcbxlinxma_xlinxmb_xlinxmc_xlinxmd_xlinxmg", + "--target=riscv32", + "-mllvm -imm-compare", + "-mllvm -emit-muliadd", + "-mllvm -merge-immshf", + "-mllvm -emit-uxtb-uxth", + "-mllvm --enable-lli=true", + "-mllvm -fldm-stm-optimize", + "-mllvm -m-push-pop", + "-mllvm --jump-is-expensive=false", + "-mllvm --min-jump-table-entries=1000000", + "-mllvm --enable-oz-inline-threshold=true", + "-mllvm --allow-unalign-ldst=true", + "-mllvm --enable-machine-outliner=always", + "-mllvm -machine-outliner-funcbytes=4", + "-mllvm -enable-ldst-multiple-opt=true", + "-mllvm -enable-rodata-sections=true", + "-mllvm -enable-sequence-abstract=true", + "-mllvm -enable-branch-imm-no-zero=true", + "-mllvm --riscv-enable-copyelim=true", + "-fvisibility=hidden" + ], + "asmflags": [], + "ldflags": [ + "--target=riscv32", + "-Wl,-Map,bin/target.map", + "-nostdlib", + "-Wl,--gc-sections", + "-Wl,--enjal8m", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "-lclang_rt.builtins-riscv32", + "-lc" + ], + "define": [ + "FLOAT_SUPPORT" + ], + "nocheck": [], + "extlibspath": [], + "extlibsname": [], + "extlibsinclude": [] + } + ] + } + ] +} diff --git a/src/build/createxml/mk_prim_xml_step1.py b/src/build/createxml/mk_prim_xml_step1.py index 1e44025b2d943ac54633b2935762a0b8ebd6fcfe..c9c08adcfce7628da55e9a7e54444b3fab2b4b83 100644 --- a/src/build/createxml/mk_prim_xml_step1.py +++ b/src/build/createxml/mk_prim_xml_step1.py @@ -34,7 +34,7 @@ class CreateCfg(): errors='replace') as file: for line in file: mod = re.search(\ - "^#define[\s]+THIS_FILE_ID[\s]+(FILE_ID_[\w]*)",\ + "^#define[\s]+THIS_FILE_ID[\s]+(FILE_ID_[\w]*)", \ line.strip()) if mod is None: continue @@ -121,7 +121,7 @@ class CreateCfg(): file_id_str = self.file_id_dic.get(file_id_str) if file_id_str is None: raise Exception(self.file_id_dic) - cmd_line = ['riscv32-linux-musl-gcc', '-E', src_full_file_name] + \ + cmd_line = [self.params.get('cc'), '-E', src_full_file_name] + \ cflag + include + ["-DMAKE_PRIM_XML_PROCESS_IN", '-D__FILE_NAME__ = %s' % src_file_name, '-D__FILE_IDX__ = %s' % file_id_str, @@ -140,8 +140,6 @@ class CreateCfg(): full_file_name_list = self.params.get('sources') self.dst_full_file_name_list = CreateCfg.conver_c_2_i(self, full_file_name_list) - if self.dst_full_file_name_list is None: - return -1 def get_necessary_information(self): diff --git a/src/build/toolchain/BUILD.gn b/src/build/toolchain/BUILD.gn index 282da139fe593eb7d8f6c12f4c4e3968e3863490..b26f5bae0af922ced87a5a21f4140f694a7180bd 100644 --- a/src/build/toolchain/BUILD.gn +++ b/src/build/toolchain/BUILD.gn @@ -26,3 +26,9 @@ hcc_toolchain("riscv32_hcc") { ld = cc } +hcc_toolchain("bisheng") { + cc = "clang" + cxx = "clang++" + ar = "llvm-ar" + ld = cc +} diff --git a/src/chip/3061h/chipinit/chipinit.c b/src/chip/3061h/chipinit/chipinit.c index 5247dd10bfbcd3bc9bf61488b3ca729fec837d42..2576fc2543e2c5c8206e72082f0cf40ffba14d56 100644 --- a/src/chip/3061h/chipinit/chipinit.c +++ b/src/chip/3061h/chipinit/chipinit.c @@ -61,18 +61,20 @@ void Chip_Init(void) Chip_InitFail(); } - /* Config FLASH Clock */ + /* Config Flash Clock */ FLASH_ClockConfig(coreClkSelect); + IRQ_Init(); SYSTICK_Init(); - /* Set CoreClock Select after FLASH Config Done */ + /* Set CoreClock Select after Flash Config Done */ CRG_SetCoreClockSelect(coreClkSelect); - /* Waiting CRG Config Done */ if (HAL_CRG_GetCoreClkFreq() != HOSC_FREQ) { FLASH_WaitClockConfigDone(); } - - IRQ_Init(); +#ifdef NOS_TASK_SUPPORT + /* Support IRQ to upload the totalCycle and detect the timeout lists */ + SYSTICK_IRQ_Enable(); +#endif ADC_InitVref(); TSENSOR_InitVrefList(); PGA_InitVref(); diff --git a/src/chip/3061h/chipinit/nosinit/nosinit.c b/src/chip/3061h/chipinit/nosinit/nosinit.c index 38dcd197144cd84c31a00ddabaa9a59a629bf2f9..722dcac760af0649763247b564b9cad72fb40502 100644 --- a/src/chip/3061h/chipinit/nosinit/nosinit.c +++ b/src/chip/3061h/chipinit/nosinit/nosinit.c @@ -20,7 +20,7 @@ * @brief nos init module. * @details nos initialization function during startup */ - +#include "feature.h" #ifdef NOS_TASK_SUPPORT #include "nos_task.h" #include "nosinit.h" @@ -36,7 +36,7 @@ unsigned char __attribute__((aligned(16))) g_taskMainStackSpace[CFG_NOS_MAINTASK static unsigned int g_nosSysFreq; // Get tick in real time -static unsigned long long NOS_GetTick() +static unsigned long long NOS_GetTick(void) { unsigned int cycle, cycleh; asm volatile("csrr %0, cycle" : "=r"(cycle)); @@ -65,7 +65,7 @@ void NOS_Init(void) param.taskEntry = (NOS_TaskEntryFunc)main; /* Set the entry function by user define */ param.param = 0; param.priority = NOS_TASK_PRIORITY_LOWEST; - param.stackAddr = g_taskMainStackSpace; + param.stackAddr = (unsigned int)g_taskMainStackSpace; param.stackSize = sizeof(g_taskMainStackSpace); param.privateData = 0; (void)NOS_TaskCreate(¶m, &taskId); diff --git a/src/chip/3061h/chipinit/nosinit/nosinit.h b/src/chip/3061h/chipinit/nosinit/nosinit.h index 81c83b4369c54cf8a41b184ee062e5fd8b4792d6..fa89d018048c5e7b0a4c49c36ca29c9dd4ebc906 100644 --- a/src/chip/3061h/chipinit/nosinit/nosinit.h +++ b/src/chip/3061h/chipinit/nosinit/nosinit.h @@ -21,6 +21,15 @@ * @details nos initialization function during startup */ +#ifndef NOS_INIT_H +#define NOS_INIT_H + +#include "feature.h" + #ifdef NOS_TASK_SUPPORT -int main(void); +extern int main(void); +extern void OsHwiDispatchTick(void); +void NOS_Init(void); +#endif + #endif \ No newline at end of file diff --git a/src/chip/3061h/chipinit/systickinit/systickinit.c b/src/chip/3061h/chipinit/systickinit/systickinit.c index 7f641067d7665995b36fe9d9bcf562e542e019c1..e0c390d60da098168213e49b3149a4e71abe43ca 100644 --- a/src/chip/3061h/chipinit/systickinit/systickinit.c +++ b/src/chip/3061h/chipinit/systickinit/systickinit.c @@ -23,31 +23,38 @@ #include "baseaddr.h" #include "timer.h" #include "systick.h" -#include "systickinit.h" #include "crg.h" - -TIMER_Handle g_systickHandle; - +#include "systickinit.h" +#include "feature.h" #ifdef NOS_TASK_SUPPORT #include "interrupt.h" #include "systick.h" +#include "nosinit.h" +#endif + +TIMER_Handle g_systickHandle; +#ifdef NOS_TASK_SUPPORT #define NOS_TickPostDispatch OsHwiDispatchTick -void SYSTICK_Default_Callback(void) +static void SYSTICK_Default_Callback(void *handle) { /* The default systick callback when using th nos task */ - HAL_TIMER_IrqClear(&g_systickHandle); + BASE_FUNC_UNUSED(handle); NOS_TickPostDispatch(); } void SYSTICK_IRQ_Enable(void) { /* When Support NOS Task, Need to open the TickIRQ, us per tick will to update the load */ - g_systickHandle.irqNum = IRQ_TIMER3; + g_systickHandle.load = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + g_systickHandle.bgLoad = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_LOAD); /* config load value */ + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_BGLOAD); /* config bgLoad value */ g_systickHandle.interruptEn = BASE_CFG_ENABLE; - HAL_TIMER_RegisterCallback(&g_systickHandle, SYSTICK_Default_Callback); - HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_INTERRUPT); // enable the systickIRQ - IRQ_SetPriority(g_systickHandle.irqNum, 1); + HAL_TIMER_RegisterCallback(&g_systickHandle, TIMER_PERIOD_FIN, SYSTICK_Default_Callback); + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_INTERRUPT); /* enable the systickIRQ */ + IRQ_SetPriority(IRQ_TIMER3, 1); + IRQ_Register(IRQ_TIMER3, HAL_TIMER_IrqHandler, &g_systickHandle); IRQ_EnableN(IRQ_TIMER3); } @@ -57,7 +64,7 @@ unsigned int SYSTICK_GetTickInterval(void) return CFG_SYSTICK_TICKINTERVAL_US; } -static inline unsigned int DCL_GetCpuCycle() +static inline unsigned int DCL_GetCpuCycle(void) { /* Get the Cpu Cycle Register(CSR) */ unsigned int cycle; @@ -99,27 +106,17 @@ unsigned int SYSTICK_GetTimeStampUs(void) * @param None * @retval None */ -void SYSTICK_Init() +void SYSTICK_Init(void) { /* Choose the config to support GetTick and Delay */ g_systickHandle.baseAddress = SYSTICK; -#ifdef NOS_TASK_SUPPORT - /* Change the period load to the user defined usecond */ - g_systickHandle.load = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; - g_systickHandle.bgLoad = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; -#else g_systickHandle.load = SYSTICK_MAX_VALUE; g_systickHandle.bgLoad = SYSTICK_MAX_VALUE; -#endif g_systickHandle.mode = TIMER_MODE_RUN_PERIODIC; g_systickHandle.prescaler = TIMERPRESCALER_NO_DIV; g_systickHandle.size = TIMER_SIZE_32BIT; /* Don't Support IRQ because only needs to read the value of systick */ g_systickHandle.interruptEn = BASE_CFG_DISABLE; HAL_TIMER_Init(&g_systickHandle); -#ifdef NOS_TASK_SUPPORT - /* Support IRQ to upload the totalCycle and detect the timeout lists */ - SYSTICK_IRQ_Enable(); -#endif HAL_TIMER_Start(&g_systickHandle); } \ No newline at end of file diff --git a/src/chip/3061h/chipinit/systickinit/systickinit.h b/src/chip/3061h/chipinit/systickinit/systickinit.h index 7b7b1e0efd13e18d373f188b733768fd5ccf46bf..37588bdb5ec6e438ba646f440487f58d863cabe9 100644 --- a/src/chip/3061h/chipinit/systickinit/systickinit.h +++ b/src/chip/3061h/chipinit/systickinit/systickinit.h @@ -24,6 +24,11 @@ #ifndef McuMagicTag_SYSTICKINIT_H #define McuMagicTag_SYSTICKINIT_H +#include "feature.h" + void SYSTICK_Init(void); +#ifdef NOS_TASK_SUPPORT +void SYSTICK_IRQ_Enable(void); +#endif #endif \ No newline at end of file diff --git a/src/chip/3061h/codecopy.json b/src/chip/3061h/codecopy.json index ce0d9ba4cb6f3a64cdd22154ce1420f8a488bb5d..b69e057551d2141a5ebd78317dd582e9e2f03512 100644 --- a/src/chip/3061h/codecopy.json +++ b/src/chip/3061h/codecopy.json @@ -16,17 +16,18 @@ "chip/3061h/systick.h", "chip/3061h/flash.lds", "chip/3061h/startup.S", - "chip/target", + "chip/target/userconfig_for_306xh.json", "drivers/debug", "generatecode", "middleware/control_library", + "middleware/function_safety", "middleware/hisilicon/loaderboot", "middleware/hisilicon/nostask/arch", "middleware/hisilicon/nostask/config", - "middleware/hisilicon/libboundscheck_v1.1.16", "middleware/hisilicon/nostask/include", "middleware/hisilicon/nostask/kernel", "middleware/hisilicon/nostask/nos_api", + "middleware/hisilicon/libboundscheck_v1.1.16", "middleware/thirdparty/sysroot", "tools/uttest", "bundle.json" diff --git a/src/chip/3061h/flash.lds b/src/chip/3061h/flash.lds index 4b8d720d508e4a1631217d0d253847331b06c4af..4b8f333f9b770c3535588549a7727c3ef2844d9b 100644 --- a/src/chip/3061h/flash.lds +++ b/src/chip/3061h/flash.lds @@ -22,71 +22,73 @@ OUTPUT_ARCH( "riscv" ) ENTRY(_start) + SRAM_START = 0x4000000; SRAM_END = 0x4000000 + 16K; -RAM_CODE_START = 0x2000000; -RAM_CODE_SIZE = 0; +/* USER CODE BEGIN 0 */ +/* USER CODE ڴ벻ᱻǣᱻɵĬϴ븲ǣUSER CODE ͬ */ +/* USER CODE END 0 */ + +RAM_DIAGNOSE_BUF_START = SRAM_START; +RAM_DIAGNOSE_BUF_SIZE = 0x20; + +RAM_CODE_START = 0x2000000 + RAM_DIAGNOSE_BUF_SIZE; +RAM_CODE_SIZE = 0; -RAM_RESERVE_DATA_START = SRAM_START + RAM_CODE_SIZE; +RAM_RESERVE_DATA_START = RAM_DIAGNOSE_BUF_START + RAM_DIAGNOSE_BUF_SIZE + RAM_CODE_SIZE; RAM_RESERVE_DATA_SIZE = 0; -RAM_START = RAM_RESERVE_DATA_START + RAM_RESERVE_DATA_SIZE; -RAM_END = SRAM_START + 16K; +STACK_SRAM_BOUND_SIZE = 0x10; -STL_TEST_START = RAM_START; -RAM_BUF_SIZE = 0x20; -RAM_PNT_SIZE = 0x10; -CLASSB_SIZE = 0x28; -CLASSB_INV_SIZE = 0x28; -STL_MEM_CHK_SIZE = RAM_BUF_SIZE + RAM_PNT_SIZE + CLASSB_SIZE + CLASSB_INV_SIZE; -STACK_TEST_SIZE = 0x10; +RAM_START = RAM_RESERVE_DATA_START + RAM_RESERVE_DATA_SIZE; +RAM_SIZE = 10K - RAM_CODE_SIZE - RAM_RESERVE_DATA_SIZE - RAM_DIAGNOSE_BUF_SIZE - STACK_SRAM_BOUND_SIZE; +RAM_END = SRAM_END; -RAM_DATA_START = STL_TEST_START + STL_MEM_CHK_SIZE; -RAM_DATA_SIZE = 10K - RAM_CODE_SIZE - RAM_RESERVE_DATA_SIZE - STL_MEM_CHK_SIZE - STACK_TEST_SIZE; +STACK_SRAM_BOUND_START = RAM_START + RAM_SIZE; +STACK_START = STACK_SRAM_BOUND_START + STACK_SRAM_BOUND_SIZE; -STACK_TEST_START = RAM_DATA_START + RAM_DATA_SIZE; +NMI_STACK_SIZE = 1024; +STACK_SIZE = 6144 - NMI_STACK_SIZE; +INIT_STACK_SIZE = 1024; -STATCK_START = STACK_TEST_START + STACK_TEST_SIZE; -STACK_SIZE = 5k; -NMI_STACK_SIZE = 1k; -INIT_STACK_SIZE = 1k; -FLASH_START = 0x3000000; -FLASH_SIZE = 160K; +FLASH_START = 0x3000000; +FLASH_SIZE = 152K - 4; MEMORY { + /* ram for diagnose buf */ + RAM_DIAGNOSE_BUF(rw) : ORIGIN = RAM_DIAGNOSE_BUF_START, LENGTH = RAM_DIAGNOSE_BUF_SIZE + /* ram for code */ RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE /* ram for reserved data */ RAM_RESERVE_DATA(rw) : ORIGIN = RAM_RESERVE_DATA_START, LENGTH = RAM_RESERVE_DATA_SIZE - /*ram for STL var */ - RAM_BUF(xrw) : ORIGIN = STL_TEST_START, LENGTH = RAM_BUF_SIZE - RAM_PNT(xrw) : ORIGIN = STL_TEST_START + RAM_BUF_SIZE, LENGTH = RAM_PNT_SIZE - CLASSB(xrw) : ORIGIN = STL_TEST_START + RAM_BUF_SIZE + RAM_PNT_SIZE, LENGTH = CLASSB_SIZE - CLASSB_INV(xrw) : ORIGIN = STL_TEST_START + RAM_BUF_SIZE + RAM_PNT_SIZE + CLASSB_SIZE, LENGTH = CLASSB_INV_SIZE - /* ram for common bss and data */ - RAM_DATA(xrw) : ORIGIN = RAM_DATA_START, LENGTH = RAM_DATA_SIZE + RAM_DATA(xrw) : ORIGIN = RAM_START, LENGTH = RAM_SIZE - /* ram for stack test array (size: 1word) */ - STACK_TEST(xrw) : ORIGIN = RAM_DATA_START + RAM_DATA_SIZE, LENGTH = STACK_TEST_SIZE + /* ram for common bss and data */ + STACK_SRAM_BOUND(xrw) : ORIGIN = STACK_SRAM_BOUND_START, LENGTH = STACK_SRAM_BOUND_SIZE /* ram for stack */ - RAM_STACK(xrw) : ORIGIN = STATCK_START, LENGTH = STACK_SIZE + NMI_STACK_SIZE + RAM_STACK(xrw) : ORIGIN = STACK_START, LENGTH = STACK_SIZE + NMI_STACK_SIZE /*magic number */ FLASH_MAGIC(rw) : ORIGIN = FLASH_START, LENGTH = 4 /* ram for target */ FLASH_CODE(rx) : ORIGIN = FLASH_START + 4, LENGTH = FLASH_SIZE -} +/* USER CODE BEGIN 1 */ +/* USER CODE ڴ벻ᱻǣᱻɵĬϴ븲ǣUSER CODE ͬ */ +/* USER CODE END 1 */ +} SECTIONS { + /* The startup code goes first into FLASH */ .data.magic : ALIGN(4) { KEEP(*(.data.magic)) @@ -98,11 +100,6 @@ SECTIONS KEEP(*(.text.entry)) } > FLASH_CODE - STACK_TEST (NOLOAD): - { - *(STACK_BOTTOM) - } > STACK_TEST - /* Stack in SRAM at Highest addresses */ .stacks (NOLOAD) : { @@ -114,9 +111,9 @@ SECTIONS __INTERRUPT_STACK_BEGIN__ = __SYSTEM_STACK_END__; . = ALIGN(0x20); __NMI_STACK_BEGIN__ = __SYSTEM_STACK_END__; + __nmi_stack_bottom = .; . += NMI_STACK_SIZE; - . = ALIGN(0x20); - __NMI_STACK_END__ = __NMI_STACK_BEGIN__ + NMI_STACK_SIZE ; + __nmi_stack_top = .; } > RAM_STACK __stack_top = __SYSTEM_STACK_END__; __init_stack_top = __SYSTEM_STACK_BEGIN__ + INIT_STACK_SIZE; @@ -160,16 +157,39 @@ SECTIONS __data_load = LOADADDR(.data); __data_start = .; *(.data*) + *(.sdata*) . = ALIGN(4); __data_end = .; } > RAM_DATA AT> FLASH_CODE __data_size = __data_end - __data_start; + .stackBound : ALIGN(4) + { + __stack_sram_bound_data_load = LOADADDR(.stackBound); + __stack_sram_bound_data_start = .; + *(STACK_SRAM_BOUND) + . = ALIGN(4); + __stack_sram_bound_data_end = .; + } > STACK_SRAM_BOUND AT> FLASH_CODE + + .ramBuf : ALIGN(4) + { + *(RAM_DIAGNOSE_BUF) + } > RAM_DIAGNOSE_BUF AT> FLASH_CODE + + .checkSum : ALIGN(4) + { + __checksum_addr = .; + *(CHECKSUM) + __checksum_end = .; + } > FLASH_CODE + /* bss section */ .bss (NOLOAD) : ALIGN(4) { __bss_begin__ = .; *(.bss*) + *(.sbss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; @@ -177,35 +197,7 @@ SECTIONS __bss_size__ = __bss_end__ - __bss_begin__; __global_pointer$ = __data_start + ((__data_size + __bss_size__) / 2); - /* CHECKSUM section in FLASH end */ - CHECKSUM : - { - __checksum_addr = .; - *(CHECKSUM) - __checksum_end = .; - } > FLASH_CODE - - /* Runtime ram buffer */ - RAM_BUF (NOLOAD): - { - *(RUN_TIME_RAM_BUF) - } > RAM_BUF - - /* Ram test pointer */ - RAM_PNT (NOLOAD): - { - *(RUN_TIME_RAM_PNT) - } > RAM_PNT - - /* STL classB var */ - CLASSB (NOLOAD): - { - *(CLASS_B_RAM) - } > CLASSB - - /* STL classB var inverse */ - CLASSB_INV (NOLOAD): - { - *(CLASS_B_RAM_REV) - } > CLASSB_INV +/* USER CODE BEGIN 2 */ +/* USER CODE ڴ벻ᱻǣᱻɵĬϴ븲ǣUSER CODE ͬ */ +/* USER CODE END 2 */ } diff --git a/src/chip/3061h/flashdefault.lds b/src/chip/3061h/flashdefault.lds new file mode 100644 index 0000000000000000000000000000000000000000..0fe0a41ea3c9628c9afbbf1b5156c84bc31499ee --- /dev/null +++ b/src/chip/3061h/flashdefault.lds @@ -0,0 +1,85 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flash.lds + * @author MCU Application Driver Team + * @brief RISCV flash link script + */ + +OUTPUT_ARCH( "riscv" ) + +SRAM_START = 0x4000000; +SRAM_END = 0x4000000 + 16K; + +RAM_CODE_START = 0x2000000; +RAM_CODE_SIZE = 0; + +RAM_START = SRAM_START; +RAM_END = SRAM_END; +RAM_SIZE = 16384; + +FLASH_START = 0x3000000; +FLASH_SIZE = 0x26000; + +MEMORY +{ + /* ram for code */ + RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE + /* ram for common bss and data */ + RAM_DATA(xrw) : ORIGIN = RAM_START + RAM_CODE_SIZE, LENGTH = RAM_SIZE + /* ram for target */ + FLASH_CODE(rx) : ORIGIN = FLASH_START, LENGTH = FLASH_SIZE +} + +SECTIONS +{ + .text : ALIGN(4) + { + __start_addr = .; + *(.text*) + *(.ram.text*) + . = ALIGN(4); + __rodata_start = .; + *(.rodata*) + . = ALIGN(4); + __rodata_end = .; + *(.got*) + __text_end = .; + } > FLASH_CODE + + /* data section */ + .data : ALIGN(4) + { + __data_load = LOADADDR(.data); + __data_start = .; + *(.data*) + *(.sdata*) + . = ALIGN(4); + __data_end = .; + } > RAM_DATA AT> FLASH_CODE + + /* bss section */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_begin__ = .; + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM_DATA +} \ No newline at end of file diff --git a/src/chip/3061h/ip_crg/ip_crg_common.c b/src/chip/3061h/ip_crg/ip_crg_common.c index 90544f0f402059614786445bdbd4226481cd5f14..bb8a0f198b9775540a1cd5f55f41bf87d08553da 100644 --- a/src/chip/3061h/ip_crg/ip_crg_common.c +++ b/src/chip/3061h/ip_crg/ip_crg_common.c @@ -58,7 +58,7 @@ unsigned int CHIP_GetIpFreqHz(const void *ipBaseAddr) } #endif -static const CHIP_CrgIpMatchInfo g_CrgIpMatch[] = { +static const CHIP_CrgIpMatchInfo g_crgIpMatch[] = { {UART0_BASE, CRG_IP_WITH_LS, 0x30, 0}, {UART1_BASE, CRG_IP_WITH_LS, 0x34, 0}, {UART2_BASE, CRG_IP_WITH_LS, 0x38, 0}, @@ -116,17 +116,17 @@ static const CHIP_CrgIpMatchInfo g_CrgIpMatch[] = { }; /** - * @brief Get IP Match Info, @see g_CrgIpMatch + * @brief Get IP Match Info, @see g_crgIpMatch * @param baseAddr The ip base address - * @retval The Address(offset) in g_CrgIpMatch if match success + * @retval The Address(offset) in g_crgIpMatch if match success * @retval 0 if match fail */ CHIP_CrgIpMatchInfo *GetCrgIpMatchInfo(const void *baseAddr) { unsigned int i; - for (i = 0; i < sizeof(g_CrgIpMatch) / sizeof(g_CrgIpMatch[0]); ++i) { - if (baseAddr == g_CrgIpMatch[i].ipBaseAddr) { - return (CHIP_CrgIpMatchInfo *)&g_CrgIpMatch[i]; + for (i = 0; i < sizeof(g_crgIpMatch) / sizeof(g_crgIpMatch[0]); ++i) { + if (baseAddr == g_crgIpMatch[i].ipBaseAddr) { + return (CHIP_CrgIpMatchInfo *)&g_crgIpMatch[i]; } } return (CHIP_CrgIpMatchInfo *)0; diff --git a/src/chip/3061h/startup.S b/src/chip/3061h/startup.S index d32cdd64dc1067e2ee35143c361a08ef83657849..4e2a292288b0842d64fbe59c8a261c4ea696b239 100644 --- a/src/chip/3061h/startup.S +++ b/src/chip/3061h/startup.S @@ -767,6 +767,12 @@ coderom_data_copy: la t2, __data_end jal mem_cpy +stack_sram_bound_data_copy: + la t0, __stack_sram_bound_data_start /* SRAM addr */ + la t1, __stack_sram_bound_data_load /* ROM addr */ + la t2, __stack_sram_bound_data_end + jal mem_cpy + pmp_init: #if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) li t0, 0xB00 diff --git a/src/chip/3061h/sysctrl.h b/src/chip/3061h/sysctrl.h index 7cbf166502c0c2f4d18d5bd90a9a70363282dc11..fc47689fba2eb19326fe94aeb2f421502c2ebef6 100644 --- a/src/chip/3061h/sysctrl.h +++ b/src/chip/3061h/sysctrl.h @@ -626,8 +626,8 @@ static inline void DCL_SYSCTRL_ScWriteProtectionDisable(void) static inline void DCL_SYSCTRL_ScWriteProtectionEnable(void) { /* Set the corresponding bit without affecting the other bits and set the high 16 bits to EA51 to write to */ - SYSCTRL0->SC_LOCKEN.reg = - ((SYSCTRL0->SC_LOCKEN.reg & SC_LOW_BIT_MASK) | SC_LOCKEN_SC_ENABLE_MASK) + SC_LOCKEN_VALID_HIGH_BIT; + SYSCTRL0->SC_LOCKEN.reg = ((SYSCTRL0->SC_LOCKEN.reg & SC_LOW_BIT_MASK) | SC_LOCKEN_SC_ENABLE_MASK) + + SC_LOCKEN_VALID_HIGH_BIT; } /** @@ -662,6 +662,15 @@ static inline void DCL_SYSCTRL_GenerateSoftInterrupt(void) { SYSCTRL0->SC_SOFT_INT.BIT.software_int = 1; } +/** + * @brief Clear software interrupt register, writing 0 clear software interrupt. + * @param None. + * @retval None. + */ +static inline void DCL_SYSCTRL_ClearSoftInterrupt(void) +{ + SYSCTRL0->SC_SOFT_INT.BIT.software_int = 0; +} /** * @brief Set Software interrupt event ID. diff --git a/src/chip/3061h/systick.h b/src/chip/3061h/systick.h index 1a72e8d430d5841cf8e16081208852e198626caa..172099f841784395fc44e9df1cc48ff2313b103d 100644 --- a/src/chip/3061h/systick.h +++ b/src/chip/3061h/systick.h @@ -29,7 +29,7 @@ #define McuMagicTag_SYSTICK_H /* Includes ------------------------------------------------------------------*/ - +#include "feature.h" /** * @addtogroup SYSTICK * @{ diff --git a/src/chip/3061m/chipinit/anatrim/anatrim.c b/src/chip/3061m/chipinit/anatrim/anatrim.c index 00b3ca0bcddef2c30958862b5c7ffb8845abb93e..c4d15d92fdb8b64f1117d4cb3c9635224b584696 100644 --- a/src/chip/3061m/chipinit/anatrim/anatrim.c +++ b/src/chip/3061m/chipinit/anatrim/anatrim.c @@ -22,7 +22,7 @@ */ #include "anatrim.h" -float g_tsensorGain = 0.00041f; +float g_tsensorGain = 0.0041f; /** * @brief Calculate the conversion gain of the tsensor. @@ -87,25 +87,25 @@ static void CHIP_AnalogTrim(void) FOTP_INFO_RGN0_NUMBER_22 trimData22; FOTP_InfoGet(FOTP_INFO_RNG0, 22U, (void *)&trimData22.comData); /* 22 is the number of trim data in otp */ - ADC0->ADC_PGA0_OEGE_TRIM0.BIT.cfg_pga0_gain_trim2 = trimData22.REG.data0.pga0_gain2; - ADC0->ADC_PGA0_OEGE_TRIM0.BIT.cfg_pga0_ofst_trim2 = trimData22.REG.data0.pga0_offset2; - ADC0->ADC_PGA0_OEGE_TRIM1.BIT.cfg_pga0_gain_trim4 = trimData22.REG.data1.pga0_gain4; - ADC0->ADC_PGA0_OEGE_TRIM1.BIT.cfg_pga0_ofst_trim4 = trimData22.REG.data1.pga0_offset4; - ADC0->ADC_PGA0_OEGE_TRIM2.BIT.cfg_pga0_gain_trim8 = trimData22.REG.data2.pga0_gain8; - ADC0->ADC_PGA0_OEGE_TRIM2.BIT.cfg_pga0_ofst_trim8 = trimData22.REG.data2.pga0_offset8; - ADC0->ADC_PGA0_OEGE_TRIM3.BIT.cfg_pga0_gain_trim16 = trimData22.REG.data3.pga0_gain16; - ADC0->ADC_PGA0_OEGE_TRIM3.BIT.cfg_pga0_ofst_trim16 = trimData22.REG.data3.pga0_offset16; + ADC0->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_gain_trim2 = trimData22.REG.data0.pga0_gain2; + ADC0->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_ofst_trim2 = trimData22.REG.data0.pga0_offset2; + ADC0->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_gain_trim4 = trimData22.REG.data1.pga0_gain4; + ADC0->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_ofst_trim4 = trimData22.REG.data1.pga0_offset4; + ADC0->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_gain_trim8 = trimData22.REG.data2.pga0_gain8; + ADC0->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_ofst_trim8 = trimData22.REG.data2.pga0_offset8; + ADC0->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_gain_trim16 = trimData22.REG.data3.pga0_gain16; + ADC0->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_ofst_trim16 = trimData22.REG.data3.pga0_offset16; FOTP_INFO_RGN0_NUMBER_23 trimData23; FOTP_InfoGet(FOTP_INFO_RNG0, 23U, (void *)&trimData23.comData); /* 23 is the number of trim data in otp */ - ADC0->ADC_PGA1_OEGE_TRIM0.BIT.cfg_pga1_gain_trim2 = trimData23.REG.data0.pga1_gain2; - ADC0->ADC_PGA1_OEGE_TRIM0.BIT.cfg_pga1_ofst_trim2 = trimData23.REG.data0.pga1_offset2; - ADC0->ADC_PGA1_OEGE_TRIM1.BIT.cfg_pga1_gain_trim4 = trimData23.REG.data1.pga1_gain4; - ADC0->ADC_PGA1_OEGE_TRIM1.BIT.cfg_pga1_ofst_trim4 = trimData23.REG.data1.pga1_offset4; - ADC0->ADC_PGA1_OEGE_TRIM2.BIT.cfg_pga1_gain_trim8 = trimData23.REG.data2.pga1_gain8; - ADC0->ADC_PGA1_OEGE_TRIM2.BIT.cfg_pga1_ofst_trim8 = trimData23.REG.data2.pga1_offset8; - ADC0->ADC_PGA1_OEGE_TRIM3.BIT.cfg_pga1_gain_trim16 = trimData23.REG.data3.pga1_gain16; - ADC0->ADC_PGA1_OEGE_TRIM3.BIT.cfg_pga1_ofst_trim16 = trimData23.REG.data3.pga1_offset16; + ADC0->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_gain_trim2 = trimData23.REG.data0.pga1_gain2; + ADC0->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_ofst_trim2 = trimData23.REG.data0.pga1_offset2; + ADC0->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_gain_trim4 = trimData23.REG.data1.pga1_gain4; + ADC0->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_ofst_trim4 = trimData23.REG.data1.pga1_offset4; + ADC0->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_gain_trim8 = trimData23.REG.data2.pga1_gain8; + ADC0->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_ofst_trim8 = trimData23.REG.data2.pga1_offset8; + ADC0->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_gain_trim16 = trimData23.REG.data3.pga1_gain16; + ADC0->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_ofst_trim16 = trimData23.REG.data3.pga1_offset16; } /** diff --git a/src/chip/3061m/chipinit/chipinit.c b/src/chip/3061m/chipinit/chipinit.c index 3cea5d59b1672bebf678748d5d06d8938d9b9a63..dfc942b1c55363e59c1f981651c78467191f27a2 100644 --- a/src/chip/3061m/chipinit/chipinit.c +++ b/src/chip/3061m/chipinit/chipinit.c @@ -29,6 +29,9 @@ #include "anatrim.h" #include "crg.h" #include "interrupt.h" +#ifdef NOS_TASK_SUPPORT +#include "nosinit.h" +#endif #include "chipinit.h" /** @@ -58,12 +61,17 @@ void Chip_Init(void) /* Config FLASH Clock */ FLASH_ClockConfig(coreClkSelect); + IRQ_Init(); SYSTICK_Init(); /* Set CoreClock Select after FLASH Config Done */ CRG_SetCoreClockSelect(coreClkSelect); - - IRQ_Init(); +#ifdef NOS_TASK_SUPPORT + SYSTICK_IRQ_Enable(); +#endif ANAVREF_Init(); ANATRIM_Entry(); /* User Add Code Here */ +#ifdef NOS_TASK_SUPPORT + NOS_Init(); +#endif } \ No newline at end of file diff --git a/src/chip/3061m/chipinit/nosinit/nosinit.c b/src/chip/3061m/chipinit/nosinit/nosinit.c new file mode 100644 index 0000000000000000000000000000000000000000..722dcac760af0649763247b564b9cad72fb40502 --- /dev/null +++ b/src/chip/3061m/chipinit/nosinit/nosinit.c @@ -0,0 +1,74 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file nosinit.c + * @author MCU Driver Team + * @brief nos init module. + * @details nos initialization function during startup + */ +#include "feature.h" +#ifdef NOS_TASK_SUPPORT +#include "nos_task.h" +#include "nosinit.h" +#include "systick.h" +#include "crg.h" + +#ifndef CFG_NOS_MAINTASK_STACKSIZE +#define CFG_NOS_MAINTASK_STACKSIZE 0x500 +#endif +#define CYCCLE_PERUS 200 +// User define the stack size of main task by CFG_NOS_MAINTASK_STACKSIZE +unsigned char __attribute__((aligned(16))) g_taskMainStackSpace[CFG_NOS_MAINTASK_STACKSIZE]; + +static unsigned int g_nosSysFreq; +// Get tick in real time +static unsigned long long NOS_GetTick(void) +{ + unsigned int cycle, cycleh; + asm volatile("csrr %0, cycle" : "=r"(cycle)); + asm volatile("csrr %0, cycleh" : "=r"(cycleh)); + unsigned long long longCycle = (unsigned long long)cycle + (unsigned long long)cycleh * 0xFFFFFFFF; + // tick = cycle/freq + return longCycle / g_nosSysFreq; +} + +/** + * @brief Init the Nos Task Schedule + * @param None + * @retval None + */ +void NOS_Init(void) +{ + unsigned int taskId; + NOS_SysConfig config = {}; + g_nosSysFreq = SYSTICK_GetCRGHZ() / CRG_FREQ_1MHz * CFG_SYSTICK_TICKINTERVAL_US; + config.usecPerTick = SYSTICK_GetTickInterval(); /* Set the tick size of Nos task schedule */ + config.getTickFunc = NOS_GetTick; + config.cyclePerUs = CYCCLE_PERUS; + NOS_TaskInit(&config); + NOS_TaskInitParam param = {}; + param.name = "mainTask"; + param.taskEntry = (NOS_TaskEntryFunc)main; /* Set the entry function by user define */ + param.param = 0; + param.priority = NOS_TASK_PRIORITY_LOWEST; + param.stackAddr = (unsigned int)g_taskMainStackSpace; + param.stackSize = sizeof(g_taskMainStackSpace); + param.privateData = 0; + (void)NOS_TaskCreate(¶m, &taskId); + (void)NOS_StartScheduler(); /* Nos task schedule start */ +} +#endif \ No newline at end of file diff --git a/src/application/drivers_sample/capm/capm_hall_sample/init/main.c b/src/chip/3061m/chipinit/nosinit/nosinit.h similarity index 82% rename from src/application/drivers_sample/capm/capm_hall_sample/init/main.c rename to src/chip/3061m/chipinit/nosinit/nosinit.h index 799e6d09622820d6526978f1e225ac12cf557b65..ec962fe6ed725cdfa752a34aa48c0c6a7770bdbd 100644 --- a/src/application/drivers_sample/capm/capm_hall_sample/init/main.c +++ b/src/chip/3061m/chipinit/nosinit/nosinit.h @@ -15,26 +15,20 @@ * 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. - * @file main.c + * @file nosinit.h * @author MCU Driver Team - * @brief Main program body. + * @brief nos init module. + * @details nos initialization function during startup */ -#include "feature.h" -#include "main.h" -#include "debug.h" -#include "capm_hall_sample.h" -#include "capm.h" -#include "capm_ip.h" + +#ifndef NOS_INIT_H +#define NOS_INIT_H -CAPM_Handle g_capmAConfig; -CAPM_Handle g_capmBConfig; -CAPM_Handle g_capmCConfig; -UART_Handle g_uart0; +#include "feature.h" +#ifdef NOS_TASK_SUPPORT +extern int main(void); +extern void OsHwiDispatchTick(void); +void NOS_Init(void); +#endif /* #ifdef NOS_TASK_SUPPORT */ -int main(void) -{ - CAPM_HallSample(); - while (1) { - } - return BASE_STATUS_OK; -} \ No newline at end of file +#endif /* #ifndef NOS_INIT_H */ \ No newline at end of file diff --git a/src/chip/3061m/chipinit/systickinit/systickinit.c b/src/chip/3061m/chipinit/systickinit/systickinit.c index 2d787dc26e51f8ed990ec0da05dbf270f7e60021..682aceb078b7a5f68328449940c1bf154983bb5c 100644 --- a/src/chip/3061m/chipinit/systickinit/systickinit.c +++ b/src/chip/3061m/chipinit/systickinit/systickinit.c @@ -22,8 +22,57 @@ */ #include "baseaddr.h" #include "crg.h" +#include "timer.h" #include "systick.h" #include "systickinit.h" +#include "feature.h" +#ifdef NOS_TASK_SUPPORT +#include "interrupt.h" +#include "nosinit.h" +#endif +TIMER_Handle g_systickHandle; +#ifdef NOS_TASK_SUPPORT +#define NOS_TickPostDispatch OsHwiDispatchTick + +static void SYSTICK_Default_Callback(void *handle) +{ + /* The default systick callback when using th nos task */ + BASE_FUNC_UNUSED(handle); + NOS_TickPostDispatch(); +} + +void SYSTICK_IRQ_Enable(void) +{ + HAL_CRG_IpEnableSet(TIMER3_BASE, IP_CLK_ENABLE); + /* Choose the config to support GetTick and Delay */ + g_systickHandle.baseAddress = TIMER3; /* use timer module */ + g_systickHandle.load = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + g_systickHandle.bgLoad = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + g_systickHandle.mode = TIMER_MODE_RUN_PERIODIC; + g_systickHandle.prescaler = TIMERPRESCALER_NO_DIV; /* frequency not divition */ + g_systickHandle.size = TIMER_SIZE_32BIT; + g_systickHandle.interruptEn = BASE_CFG_ENABLE; + HAL_TIMER_Init(&g_systickHandle); + HAL_TIMER_RegisterCallback(&g_systickHandle, TIMER_PERIOD_FIN, SYSTICK_Default_Callback); /* nos task schedule */ + IRQ_SetPriority(IRQ_TIMER3, 1); /* interrupt priority 1 */ + IRQ_Register(IRQ_TIMER3, HAL_TIMER_IrqHandler, &g_systickHandle); + IRQ_EnableN(IRQ_TIMER3); + HAL_TIMER_Start(&g_systickHandle); /* start timer module */ +} + +unsigned int SYSTICK_GetTickInterval(void) +{ + /* Get the tick interval(the number of usecond per tick) */ + return CFG_SYSTICK_TICKINTERVAL_US; +} + +#endif + +unsigned int SYSTICK_GetTimeStampUs(void) +{ + /* Get the systick timestamp(convert from the systick value) */ + return DCL_SYSTICK_GetTick() / (SYSTICK_GetCRGHZ() / CRG_FREQ_1MHz); +} /** * @brief Init the systick @@ -43,6 +92,10 @@ void SYSTICK_Init(void) */ unsigned int SYSTICK_GetCRGHZ(void) { +#ifdef NOS_TASK_SUPPORT + return HAL_CRG_GetCoreClkFreq(); +#else /* Get the Systick IP */ return HAL_CRG_GetIpFreq(SYSTICK_BASE); +#endif } \ No newline at end of file diff --git a/src/chip/3061m/chipinit/systickinit/systickinit.h b/src/chip/3061m/chipinit/systickinit/systickinit.h index 7a8710ad348912b685744dc32c061d5b19fb3e27..ce91525b98881112aac63704a25eada772e8cd8e 100644 --- a/src/chip/3061m/chipinit/systickinit/systickinit.h +++ b/src/chip/3061m/chipinit/systickinit/systickinit.h @@ -24,6 +24,12 @@ #ifndef McuMagicTag_SYSTICKINIT_H #define McuMagicTag_SYSTICKINIT_H +#include "feature.h" + void SYSTICK_Init(void); unsigned int SYSTICK_GetCRGHZ(void); +#ifdef NOS_TASK_SUPPORT +void SYSTICK_IRQ_Enable(void); +#endif + #endif \ No newline at end of file diff --git a/src/chip/3061m/codecopy.json b/src/chip/3061m/codecopy.json index e482c90187f535e3a8d11a0c9eb521ec48bf5220..1568b4fb757d30147c01e269d53f5f47dc97e22b 100644 --- a/src/chip/3061m/codecopy.json +++ b/src/chip/3061m/codecopy.json @@ -3,23 +3,18 @@ "application/user", "build", "chip/3061m", - "chip/target", + "chip/target/userconfig_for_3061m.json", "drivers/debug", "generatecode", "middleware/control_library", - "middleware/hisilicon/loaderboot", - "middleware/hisilicon/nostask/arch", - "middleware/hisilicon/nostask/config", - "middleware/hisilicon/nostask/include", + "middleware/function_safety", "middleware/hisilicon/libboundscheck_v1.1.16", - "middleware/hisilicon/nostask/kernel", - "middleware/hisilicon/nostask/nos_api", "middleware/thirdparty/sysroot", "tools/uttest", "bundle.json" ], - "ip_drive_file": ["acmp", "adc", "apt", "base", "can", "capm", "cmm", "crc", "crg", + "ip_drive_file": ["acmp", "adc", "apt", "base", "can", "capm", "cmm", "cfd", "crc", "crg", "dac", "dma", "flash", "gpio", "gpt", "i2c", "pga", "pmc", "qdm", "spi", "timer", "tsensor", "uart", "iwdg", "iocmg", "wwdg"], "acmp" : ["common", "acmp_v1", "testcase_v1"], @@ -29,6 +24,7 @@ "can" : ["common", "can_v0", "testcase_v0"], "capm" : ["common", "capm_v1", "testcase_v1"], "cmm" : ["common", "cmm_v1", "testcase_v1"], + "cfd" : ["common", "cfd_v1", "testcase_v1"], "crc" : ["common", "crc_v1", "testcase_v1"], "crg" : ["common", "crg_v1", "testcase_v1"], "dac" : ["common", "dac_v1", "testcase_v1"], diff --git a/src/chip/3061m/flash.lds b/src/chip/3061m/flash.lds index 12ae5e5fd25c13f5cfd2a6becfcd602171413169..20eec30d365fed9cc5dd5dac69c787200d18146a 100644 --- a/src/chip/3061m/flash.lds +++ b/src/chip/3061m/flash.lds @@ -23,35 +23,34 @@ OUTPUT_ARCH( "riscv" ) ENTRY(_start) +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 0 */ + SRAM_START = 0x4000000; SRAM_END = 0x4000000 + 32K; -RAM_CODE_START = 0x2000000; +RAM_DIAGNOSE_BUF_START = SRAM_START; +RAM_DIAGNOSE_BUF_SIZE = 0x20; + +RAM_CODE_START = 0x2000000 + RAM_DIAGNOSE_BUF_SIZE; RAM_CODE_SIZE = 0; -RAM_RESERVE_DATA_START = SRAM_START + RAM_CODE_SIZE; +RAM_RESERVE_DATA_START = RAM_DIAGNOSE_BUF_START + RAM_DIAGNOSE_BUF_SIZE + RAM_CODE_SIZE; RAM_RESERVE_DATA_SIZE = 0; +STACK_SRAM_BOUND_SIZE = 0x10; + RAM_START = RAM_RESERVE_DATA_START + RAM_RESERVE_DATA_SIZE; -RAM_SIZE = 0x5000 - RAM_CODE_SIZE - RAM_RESERVE_DATA_SIZE; +RAM_SIZE = 0x5000 - RAM_CODE_SIZE - RAM_RESERVE_DATA_SIZE - RAM_DIAGNOSE_BUF_SIZE - STACK_SRAM_BOUND_SIZE; RAM_END = SRAM_END; -STL_TEST_START = RAM_START; -RAM_BUF_SIZE = 0x20; -RAM_PNT_SIZE = 0x10; -CLASSB_SIZE = 0x28; -CLASSB_INV_SIZE = 0x28; -STL_MEM_CHK_SIZE = RAM_BUF_SIZE + RAM_PNT_SIZE + CLASSB_SIZE + CLASSB_INV_SIZE; -STACK_TEST_SIZE = 0x10; +STACK_SRAM_BOUND_START = RAM_START + RAM_SIZE; -RAM_DATA_START = STL_TEST_START + STL_MEM_CHK_SIZE; -RAM_DATA_SIZE = RAM_SIZE - STL_MEM_CHK_SIZE - STACK_TEST_SIZE; +STACK_START = STACK_SRAM_BOUND_START + STACK_SRAM_BOUND_SIZE; -STACK_TEST_START = RAM_DATA_START + RAM_DATA_SIZE; - -STATCK_START = STACK_TEST_START + STACK_TEST_SIZE; -STACK_SIZE = 0x3000 - 1024; NMI_STACK_SIZE = 1024; +STACK_SIZE = 0x3000 - NMI_STACK_SIZE; INIT_STACK_SIZE = 1024; FLASH_START = 0x3000000; @@ -59,32 +58,33 @@ FLASH_SIZE = 0x1fffc; MEMORY { + /* ram for diagnose buf */ + RAM_DIAGNOSE_BUF(rw) : ORIGIN = RAM_DIAGNOSE_BUF_START, LENGTH = RAM_DIAGNOSE_BUF_SIZE + /* ram for code */ RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE /* ram for reserved data */ RAM_RESERVE_DATA(rw) : ORIGIN = RAM_RESERVE_DATA_START, LENGTH = RAM_RESERVE_DATA_SIZE - /*ram for STL var */ - RAM_BUF(xrw) : ORIGIN = STL_TEST_START, LENGTH = RAM_BUF_SIZE - RAM_PNT(xrw) : ORIGIN = STL_TEST_START + RAM_BUF_SIZE, LENGTH = RAM_PNT_SIZE - CLASSB(xrw) : ORIGIN = STL_TEST_START + RAM_BUF_SIZE + RAM_PNT_SIZE, LENGTH = CLASSB_SIZE - CLASSB_INV(xrw) : ORIGIN = STL_TEST_START + RAM_BUF_SIZE + RAM_PNT_SIZE + CLASSB_SIZE, LENGTH = CLASSB_INV_SIZE - /* ram for common bss and data */ - RAM_DATA(xrw) : ORIGIN = RAM_DATA_START, LENGTH = RAM_DATA_SIZE + RAM_DATA(xrw) : ORIGIN = RAM_START, LENGTH = RAM_SIZE - /* ram for stack test array (size: 1word) */ - STACK_TEST(xrw) : ORIGIN = RAM_DATA_START + RAM_DATA_SIZE, LENGTH = STACK_TEST_SIZE + /* ram for common bss and data */ + STACK_SRAM_BOUND(xrw) : ORIGIN = STACK_SRAM_BOUND_START, LENGTH = STACK_SRAM_BOUND_SIZE /* ram for stack */ - RAM_STACK(xrw) : ORIGIN = STATCK_START, LENGTH = STACK_SIZE + NMI_STACK_SIZE + RAM_STACK(xrw) : ORIGIN = STACK_START, LENGTH = STACK_SIZE + NMI_STACK_SIZE /*magic number */ FLASH_MAGIC(rw) : ORIGIN = FLASH_START, LENGTH = 4 /* ram for target */ FLASH_CODE(rx) : ORIGIN = FLASH_START + 4, LENGTH = FLASH_SIZE + +/* USER CODE BEGIN 1 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 1 */ } SECTIONS @@ -101,11 +101,6 @@ SECTIONS KEEP(*(.text.entry)) } > FLASH_CODE - STACK_TEST (NOLOAD): - { - *(STACK_BOTTOM) - } > STACK_TEST - /* Stack in SRAM at Highest addresses */ .stacks (NOLOAD) : { @@ -163,16 +158,39 @@ SECTIONS __data_load = LOADADDR(.data); __data_start = .; *(.data*) + *(.sdata*) . = ALIGN(4); __data_end = .; } > RAM_DATA AT> FLASH_CODE __data_size = __data_end - __data_start; + .stackBound : ALIGN(4) + { + __stack_sram_bound_data_load = LOADADDR(.stackBound); + __stack_sram_bound_data_start = .; + *(STACK_SRAM_BOUND) + . = ALIGN(4); + __stack_sram_bound_data_end = .; + } > STACK_SRAM_BOUND AT> FLASH_CODE + + .ramBuf : ALIGN(4) + { + *(RAM_DIAGNOSE_BUF) + } > RAM_DIAGNOSE_BUF AT> FLASH_CODE + + .checkSum : ALIGN(4) + { + __checksum_addr = .; + *(CHECKSUM) + __checksum_end = .; + } > FLASH_CODE + /* bss section */ .bss (NOLOAD) : ALIGN(4) { __bss_begin__ = .; *(.bss*) + *(.sbss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; @@ -180,35 +198,7 @@ SECTIONS __bss_size__ = __bss_end__ - __bss_begin__; __global_pointer$ = __data_start + ((__data_size + __bss_size__) / 2); - /* CHECKSUM section in FLASH end */ - CHECKSUM : - { - __checksum_addr = .; - *(CHECKSUM) - __checksum_end = .; - } > FLASH_CODE - - /* Runtime ram buffer */ - RAM_BUF (NOLOAD): - { - *(RUN_TIME_RAM_BUF) - } > RAM_BUF - - /* Ram test pointer */ - RAM_PNT (NOLOAD): - { - *(RUN_TIME_RAM_PNT) - } > RAM_PNT - - /* STL classB var */ - CLASSB (NOLOAD): - { - *(CLASS_B_RAM) - } > CLASSB - - /* STL classB var inverse */ - CLASSB_INV (NOLOAD): - { - *(CLASS_B_RAM_REV) - } > CLASSB_INV +/* USER CODE BEGIN 2 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 2 */ } \ No newline at end of file diff --git a/src/chip/3061m/flashdefault.lds b/src/chip/3061m/flashdefault.lds new file mode 100644 index 0000000000000000000000000000000000000000..f6d91bdb1794aa4c8078dc3721628828f58be39c --- /dev/null +++ b/src/chip/3061m/flashdefault.lds @@ -0,0 +1,85 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flash.lds + * @author MCU Application Driver Team + * @brief RISCV flash link script + */ + +OUTPUT_ARCH( "riscv" ) + +SRAM_START = 0x4000000; +SRAM_END = 0x4000000 + 32K; + +RAM_CODE_START = 0x2000000; +RAM_CODE_SIZE = 0; + +RAM_START = SRAM_START; +RAM_END = SRAM_END; +RAM_SIZE = 32768; + +FLASH_START = 0x3000000; +FLASH_SIZE = 0x20000; + +MEMORY +{ + /* ram for code */ + RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE + /* ram for common bss and data */ + RAM_DATA(xrw) : ORIGIN = RAM_START + RAM_CODE_SIZE, LENGTH = RAM_SIZE + /* ram for target */ + FLASH_CODE(rx) : ORIGIN = FLASH_START, LENGTH = FLASH_SIZE +} + +SECTIONS +{ + .text : ALIGN(4) + { + __start_addr = .; + *(.text*) + *(.ram.text*) + . = ALIGN(4); + __rodata_start = .; + *(.rodata*) + . = ALIGN(4); + __rodata_end = .; + *(.got*) + __text_end = .; + } > FLASH_CODE + + /* data section */ + .data : ALIGN(4) + { + __data_load = LOADADDR(.data); + __data_start = .; + *(.data*) + *(.sdata*) + . = ALIGN(4); + __data_end = .; + } > RAM_DATA AT> FLASH_CODE + + /* bss section */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_begin__ = .; + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM_DATA +} \ No newline at end of file diff --git a/src/chip/3061m/ioconfig.h b/src/chip/3061m/ioconfig.h index 7e5a9eaf06898dfe94087117a58b372c9bfdeca1..5339a3ed848e42d6420356bbe130a6a6f1f3f988 100644 --- a/src/chip/3061m/ioconfig.h +++ b/src/chip/3061m/ioconfig.h @@ -44,19 +44,22 @@ typedef struct { unsigned char space0[12]; IOCMG_REG IOCFG_GPIO5_0; /**< Pin GPIO5_0 IO Config Register, offset address:0x000010U */ unsigned char space1[4]; -#ifdef CHIP_3061MNPICA /* Only CHIP_3061MNPICA is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) /* Only 48Pins chip is supported. */ IOCMG_REG IOCFG_GPIO3_3; /**< Pin GPIO3_3 IO Config Register, offset address:0x000018U */ #else unsigned char space2[4]; #endif -#ifdef CHIP_3061MNPICA /* Only CHIP_3061MNPICA is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) /* Only 48Pins chip is supported. */ IOCMG_REG IOCFG_GPIO2_4; /**< Pin GPIO2_4 IO Config Register, offset address:0x00001CU */ #else unsigned char space3[4]; #endif unsigned char space4[224]; IOCMG_REG IOCFG_GPIO0_7; /**< Pin GPIO0_7 IO Config Register, offset address:0x000100U */ -#ifdef CHIP_3061MNPICA /* Only CHIP_3061MNPICA is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) /* Only 48Pins chip is supported. */ IOCMG_REG IOCFG_GPIO5_1; /**< Pin GPIO5_1 IO Config Register, offset address:0x000104U */ #else unsigned char space5[4]; @@ -64,7 +67,8 @@ typedef struct { IOCMG_REG IOCFG_GPIO2_7; /**< Pin GPIO2_7 IO Config Register, offset address:0x000108U */ IOCMG_REG IOCFG_GPIO2_6; /**< Pin GPIO2_6 IO Config Register, offset address:0x00010CU */ IOCMG_REG IOCFG_GPIO2_5; /**< Pin GPIO2_5 IO Config Register, offset address:0x000110U */ -#ifdef CHIP_3061MNPICA /* Only CHIP_3061MNPICA is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) /* Only 48Pins chip is supported. */ IOCMG_REG IOCFG_GPIO5_2; /**< Pin GPIO5_2 IO Config Register, offset address:0x000114U */ #else unsigned char space6[4]; @@ -72,7 +76,8 @@ typedef struct { IOCMG_REG IOCFG_GPIO3_7; /**< Pin GPIO3_7 IO Config Register, offset address:0x000118U */ IOCMG_REG IOCFG_GPIO3_6; /**< Pin GPIO3_6 IO Config Register, offset address:0x00011CU */ IOCMG_REG IOCFG_GPIO3_5; /**< Pin GPIO3_5 IO Config Register, offset address:0x000120U */ -#ifdef CHIP_3061MNPICA /* Only CHIP_3061MNPICA is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) /* Only 48Pins chip is supported. */ IOCMG_REG IOCFG_GPIO5_3; /**< Pin GPIO5_3 IO Config Register, offset address:0x000124U */ #else unsigned char space7[4]; @@ -81,7 +86,8 @@ typedef struct { IOCMG_REG IOCFG_GPIO1_6; /**< Pin GPIO1_6 IO Config Register, offset address:0x00012CU */ IOCMG_REG IOCFG_GPIO1_7; /**< Pin GPIO1_7 IO Config Register, offset address:0x000130U */ IOCMG_REG IOCFG_GPIO4_7; /**< Pin GPIO4_7 IO Config Register, offset address:0x000134U */ -#ifdef CHIP_3061MNPICA /* Only CHIP_3061MNPICA is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) /* Only 48Pins chip is supported. */ IOCMG_REG IOCFG_GPIO4_5; /**< Pin GPIO4_5 IO Config Register, offset address:0x000138U */ IOCMG_REG IOCFG_GPIO4_6; /**< Pin GPIO4_6 IO Config Register, offset address:0x00013CU */ IOCMG_REG IOCFG_GPIO1_3; /**< Pin GPIO1_3 IO Config Register, offset address:0x000140U */ @@ -96,7 +102,8 @@ typedef struct { IOCMG_REG IOCFG_EF_BIST_INTF; /**< Pin EF_BIST_INTF IO Config Register, offset address:0x000158U */ IOCMG_REG IOCFG_GPIO4_1; /**< Pin GPIO4_1 IO Config Register, offset address:0x00015CU */ IOCMG_REG IOCFG_GPIO4_2; /**< Pin GPIO4_2 IO Config Register, offset address:0x000160U */ -#ifdef CHIP_3061MNPICA /* Only CHIP_3061MNPICA is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) /* Only 48Pins chip is supported. */ IOCMG_REG IOCFG_GPIO4_3; /**< Pin GPIO4_3 IO Config Register, offset address:0x000164U */ IOCMG_REG IOCFG_GPIO1_0; /**< Pin GPIO1_0 IO Config Register, offset address:0x000168U */ IOCMG_REG IOCFG_GPIO1_1; /**< Pin GPIO1_1 IO Config Register, offset address:0x00016CU */ @@ -107,7 +114,8 @@ typedef struct { #endif IOCMG_REG IOCFG_GPIO2_0; /**< Pin GPIO2_0 IO Config Register, offset address:0x000178U */ IOCMG_REG IOCFG_GPIO2_1; /**< Pin GPIO2_1 IO Config Register, offset address:0x00017CU */ -#ifdef CHIP_3061MNPICA /* Only CHIP_3061MNPICA is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) /* Only 48Pins chip is supported. */ IOCMG_REG IOCFG_GPIO2_2; /**< Pin GPIO2_2 IO Config Register, offset address:0x000180U */ IOCMG_REG IOCFG_GPIO2_3; /**< Pin GPIO2_3 IO Config Register, offset address:0x000184U */ #else diff --git a/src/chip/3061m/iomap/iomap.h b/src/chip/3061m/iomap/iomap.h index e9c6f92d91f5c166c77e9c1c229bb6da9b932e6b..a7dafaf404a5f3fa399650f12f613d2b0b08121d 100644 --- a/src/chip/3061m/iomap/iomap.h +++ b/src/chip/3061m/iomap/iomap.h @@ -40,8 +40,9 @@ #define GPIO0_7_AS_ACMP0_OUT IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_6, 0x02b1) #define GPIO0_7_AS_ADC_AIN4 IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_12, 0x02b1) -/* Only CHIP_3061MNPICA and CHIP_3061MNPIC8 is supported. */ -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIC8) +/* Only 48Pins is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) #define GPIO5_1_AS_GPIO5_1 IOCMG_PIN_MUX(IOCFG_GPIO5_1, FUNC_MODE_0, 0x0230) #define GPIO5_1_AS_ADC0_STATUS IOCMG_PIN_MUX(IOCFG_GPIO5_1, FUNC_MODE_5, 0x0230) #define GPIO5_1_AS_ADC_EXT_TRIG3 IOCMG_PIN_MUX(IOCFG_GPIO5_1, FUNC_MODE_6, 0x0230) @@ -67,8 +68,9 @@ #define GPIO2_5_AS_PGA0_P0 IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_13, 0x0230) #define GPIO2_5_AS_ACMP_P3 IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_14, 0x0230) -/* Only CHIP_3061MNPICA and CHIP_3061MNPIC8 is supported. */ -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIC8) +/* Only 48Pins is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) #define GPIO5_2_AS_GPIO5_2 IOCMG_PIN_MUX(IOCFG_GPIO5_2, FUNC_MODE_0, 0x0230) #define GPIO5_2_AS_GPT2_PWM IOCMG_PIN_MUX(IOCFG_GPIO5_2, FUNC_MODE_1, 0x0230) #define GPIO5_2_AS_ADC0_STATUS IOCMG_PIN_MUX(IOCFG_GPIO5_2, FUNC_MODE_5, 0x0230) @@ -93,8 +95,9 @@ #define GPIO3_5_AS_ADC_AIN11 IOCMG_PIN_MUX(IOCFG_GPIO3_5, FUNC_MODE_12, 0x0230) #define GPIO3_5_AS_ACMP_P4 IOCMG_PIN_MUX(IOCFG_GPIO3_5, FUNC_MODE_13, 0x0230) -/* Only CHIP_3061MNPICA and CHIP_3061MNPIC8 is supported. */ -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIC8) +/* Only 48Pins is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) #define GPIO5_3_AS_GPIO5_3 IOCMG_PIN_MUX(IOCFG_GPIO5_3, FUNC_MODE_0, 0x0230) #define GPIO5_3_AS_ADC0_STATUS IOCMG_PIN_MUX(IOCFG_GPIO5_3, FUNC_MODE_5, 0x0230) #define GPIO5_3_AS_ADC_EXT_TRIG1 IOCMG_PIN_MUX(IOCFG_GPIO5_3, FUNC_MODE_6, 0x0230) @@ -130,8 +133,9 @@ #define GPIO4_7_AS_ADC_AIN15 IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_12, 0x0230) #define GPIO4_7_AS_DAC_OUT IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_13, 0x0230) -/* Only CHIP_3061MNPICA and CHIP_3061MNPIC8 is supported. */ -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIC8) +/* Only 48Pins is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) #define GPIO4_5_AS_GPIO4_5 IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_0, 0x0230) #define GPIO4_5_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_2, 0x0230) #define GPIO4_5_AS_UART3_CTSN IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_3, 0x0230) @@ -172,8 +176,9 @@ #define GPIO3_2_AS_I2C1_SDA IOCMG_PIN_MUX(IOCFG_GPIO3_2, FUNC_MODE_2, 0x0230) #define GPIO3_2_AS_SPI1_CSN0 IOCMG_PIN_MUX(IOCFG_GPIO3_2, FUNC_MODE_4, 0x0230) -/* Only CHIP_3061MNPICA and CHIP_3061MNPIC8 is supported. */ -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIC8) +/* Only 48Pins is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) #define GPIO3_3_AS_GPIO3_3 IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_0, 0x0230) #define GPIO3_3_AS_APT3_PWMA IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_1, 0x0230) #define GPIO3_3_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_2, 0x0230) @@ -195,8 +200,9 @@ #define GPIO4_2_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO4_2, FUNC_MODE_2, 0x0230) #define GPIO4_2_AS_SPI1_TXD IOCMG_PIN_MUX(IOCFG_GPIO4_2, FUNC_MODE_4, 0x0230) -/* Only CHIP_3061MNPICA and CHIP_3061MNPIC8 is supported. */ -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIC8) +/* Only 48Pins is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) #define GPIO4_3_AS_GPIO4_3 IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_0, 0x0230) #define GPIO4_3_AS_APT3_PWMB IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_1, 0x0230) #define GPIO4_3_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_2, 0x0230) @@ -249,8 +255,9 @@ #define GPIO5_0_AS_QDM1_INDEX IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_5, 0x0230) #define GPIO5_0_AS_WAKEUP0 IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_6, 0x0230) -/* Only CHIP_3061MNPICA and CHIP_3061MNPIC8 is supported. */ -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIC8) +/* Only 48Pins is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) #define GPIO2_2_AS_GPIO2_2 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_0, 0x0230) #define GPIO2_2_AS_CAN_RX IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_1, 0x0230) #define GPIO2_2_AS_UART0_TXD IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_2, 0x0230) @@ -287,8 +294,9 @@ #define GPIO0_4_AS_UART0_RXD IOCMG_PIN_MUX(IOCFG_GPIO0_4, FUNC_MODE_3, 0x0230) #define GPIO0_4_AS_XTAL_IN IOCMG_PIN_MUX(IOCFG_GPIO0_4, FUNC_MODE_12, 0x0230) -/* Only CHIP_3061MNPICA and CHIP_3061MNPIC8 is supported. */ -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIC8) +/* Only 48Pins is supported. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNNIC8) #define GPIO2_4_AS_GPIO2_4 IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_0, 0x0230) #define GPIO2_4_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_2, 0x0230) #define GPIO2_4_AS_CAPM2_IN IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_4, 0x0230) diff --git a/src/chip/3061m/startup.S b/src/chip/3061m/startup.S index 8aedfa8f6d20cf1dc6a88b224c57ebec789a9f51..95e41a41641a6faa860dae52d4c8335d6bdc5344 100644 --- a/src/chip/3061m/startup.S +++ b/src/chip/3061m/startup.S @@ -24,8 +24,18 @@ #define ENTRY_S #include "feature.h" +#ifdef NOS_TASK_SUPPORT +.extern OsHwiPostHandle +.extern OsTaskTrueSwitch +#define NOS_HwiPostDispatch OsHwiPostHandle +#define NOS_TaskDispatch OsTaskTrueSwitch +#define NOS_TASK_SWITCH_MAGIC_NUM 0xACBCCCDC +#define TICK_IRQ_EN_BASE 0xBE0 +#define TICK_IRQ_EN_NUM 0x8 +#endif .extern __stack_top +.extern __init_stack_top .extern __irq_stack_top .extern SysErrNmiEntry .extern SysErrExcEntry @@ -51,11 +61,19 @@ #define NESTED_IRQ_SUPPORT #define COMPILE_LDM /**< Support stmia and ldmia instruction */ +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs more stack to restore TickIRQEnable */ +#ifdef FLOAT_SUPPORT +#define TOTAL_INT_SIZE_ON_STACK (44 * REGBYTES) +#else +#define TOTAL_INT_SIZE_ON_STACK (24 * REGBYTES) +#endif +#else #ifdef FLOAT_SUPPORT #define TOTAL_INT_SIZE_ON_STACK (40 * REGBYTES) #else #define TOTAL_INT_SIZE_ON_STACK (20 * REGBYTES) #endif +#endif #define SYSERR_INT_SIZE_ON_STACK (28 * REGBYTES) @@ -87,18 +105,8 @@ #define locipri15 0xBCF #define EFC_BASE_ADDR 0x14710000 /* efc base address */ -#define EFC_MAGIC_LOCK_RW 0x14710200 /* cmd operation magic word protection register */ -#define EFC_MAGIC_NUMBER 0xFEDCBA98 /* magic number */ #define SYSRAM_ERROR 0x10108300 #define SC_SYS_STAT_ADDR 0x10100018 /**< System state register address */ -#define TIMER0_CONTROL 0x14300008 -#define TIMER0_INTENABLE (1 << 5) -#define UART0_BASE_ADDR 0x14000000 -#define IBRD_OFFSET 0x24 -#define FBRD_OFFSET 0x28 -#define LCR_H_OFFSET 0x2C -#define CR_OFFSET 0x30 -#define DMACR_OFFSET 0x48 .equ cipri, 0x7ED .equ prithd, 0xBFE @@ -371,9 +379,11 @@ IntHandler: li a1, (3<<11) csrs mstatus, a1 +#ifndef NOS_TASK_SUPPORT /* When using NOS_TASK_SUPPORT, enable gloal irq after change to irq stack */ la a1, custom_nested_irq_main_handler_entry csrw mepc, a1 mret +#endif /* #ifndef NOS_TASK */ #endif .align 2 @@ -392,8 +402,37 @@ custom_nested_irq_main_handler_entry: SREG t4, 16 * REGBYTES(sp) SREG t5, 17 * REGBYTES(sp) SREG t6, 18 * REGBYTES(sp) +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to save TickIRQEnable */ + csrr t0, TICK_IRQ_EN_BASE + andi t0, t0, TICK_IRQ_EN_NUM + SREG t0, 19 * REGBYTES(sp) +#endif #ifdef FLOAT_SUPPORT +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to save TickIRQEnable */ + FSREG f0, 23 * REGBYTES(sp) + FSREG f1, 24 * REGBYTES(sp) + FSREG f2, 25 * REGBYTES(sp) + FSREG f3, 26 * REGBYTES(sp) + FSREG f4, 27 * REGBYTES(sp) + FSREG f5, 28 * REGBYTES(sp) + FSREG f6, 29 * REGBYTES(sp) + FSREG f7, 30 * REGBYTES(sp) + FSREG f10, 31 * REGBYTES(sp) + FSREG f11, 32 * REGBYTES(sp) + FSREG f12, 33 * REGBYTES(sp) + FSREG f13, 34 * REGBYTES(sp) + FSREG f14, 35 * REGBYTES(sp) + FSREG f15, 36 * REGBYTES(sp) + FSREG f16, 37 * REGBYTES(sp) + FSREG f17, 38 * REGBYTES(sp) + FSREG f28, 39 * REGBYTES(sp) + FSREG f29, 40 * REGBYTES(sp) + FSREG f30, 41 * REGBYTES(sp) + FSREG f31, 42 * REGBYTES(sp) + frcsr t0 + SREG t0, 43 * REGBYTES(sp) +#else FSREG f0, 19 * REGBYTES(sp) FSREG f1, 20 * REGBYTES(sp) FSREG f2, 21 * REGBYTES(sp) @@ -414,11 +453,41 @@ custom_nested_irq_main_handler_entry: FSREG f29, 36 * REGBYTES(sp) FSREG f30, 37 * REGBYTES(sp) FSREG f31, 38 * REGBYTES(sp) + frcsr t0 + SREG t0, 39 * REGBYTES(sp) /* save fcsr */ +#endif #endif +#ifdef NOS_TASK_SUPPORT + LREG a2, 6 * REGBYTES(sp) + bnez a2, IrqCallback /* Should determine whether need to switch stack */ + csrw mscratch, sp + la sp, __irq_stack_top - 16 + +IrqCallback: + addi sp, sp, -4 * REGBYTES + SREG a2, 0 * REGBYTES(sp) /* save prithd in irq stack */ andi a0, a0, MCAUSE_MASK_INT_NUM + la a1, IrqCallbackNew /* When using NOS_TASK_SUPPORT, enable gloal irq after change to irq stack */ + csrw mepc, a1 + mret + +IrqCallbackNew: call InterruptEntry + li a2, 0x8 + csrrc zero, mstatus, a2 /* When using NOS_TASK_SUPPORT, disable gloal irq before any stack operation */ + LREG a2, 0 * REGBYTES(sp) /* restore prithd in irq stack */ + addi sp, sp, 4 * REGBYTES + + bnez a2, BacktoIrq + csrr sp, mscratch + tail NOS_HwiPostDispatch /* Should determine whether need to reschedule */ +#else + andi a0, a0, MCAUSE_MASK_INT_NUM + call InterruptEntry +#endif +BacktoIrq: LREG t1, 1 * REGBYTES(sp) LREG t2, 2 * REGBYTES(sp) LREG a2, 5 * REGBYTES(sp) @@ -432,8 +501,37 @@ custom_nested_irq_main_handler_entry: LREG t4, 16 * REGBYTES(sp) LREG t5, 17 * REGBYTES(sp) LREG t6, 18 * REGBYTES(sp) +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to restore TickIRQEnable */ + LREG t0, 19 * REGBYTES(sp) + andi t0, t0, TICK_IRQ_EN_NUM + csrs TICK_IRQ_EN_BASE, t0 +#endif #ifdef FLOAT_SUPPORT +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to save TickIRQEnable */ + FLREG f0, 23 * REGBYTES(sp) + FLREG f1, 24 * REGBYTES(sp) + FLREG f2, 25 * REGBYTES(sp) + FLREG f3, 26 * REGBYTES(sp) + FLREG f4, 27 * REGBYTES(sp) + FLREG f5, 28 * REGBYTES(sp) + FLREG f6, 29 * REGBYTES(sp) + FLREG f7, 30 * REGBYTES(sp) + FLREG f10, 31 * REGBYTES(sp) + FLREG f11, 32 * REGBYTES(sp) + FLREG f12, 33 * REGBYTES(sp) + FLREG f13, 34 * REGBYTES(sp) + FLREG f14, 35 * REGBYTES(sp) + FLREG f15, 36 * REGBYTES(sp) + FLREG f16, 37 * REGBYTES(sp) + FLREG f17, 38 * REGBYTES(sp) + FLREG f28, 39 * REGBYTES(sp) + FLREG f29, 40 * REGBYTES(sp) + FLREG f30, 41 * REGBYTES(sp) + FLREG f31, 42 * REGBYTES(sp) + LREG t0, 43 * REGBYTES(sp) + fscsr t0 +#else FLREG f0, 19 * REGBYTES(sp) FLREG f1, 20 * REGBYTES(sp) FLREG f2, 21 * REGBYTES(sp) @@ -454,6 +552,9 @@ custom_nested_irq_main_handler_entry: FLREG f29, 36 * REGBYTES(sp) FLREG f30, 37 * REGBYTES(sp) FLREG f31, 38 * REGBYTES(sp) + LREG t0, 39 * REGBYTES(sp) /* restore fcsr */ + fscsr t0 +#endif #endif quit_int: @@ -467,11 +568,13 @@ quit_int: LREG t0, 0 * REGBYTES(sp) #else LREG a0, 7 * REGBYTES(sp) /* load mstatus */ - csrr t0, mstatus LREG a1, 8 * REGBYTES(sp) /* load mepc */ +#ifndef NOS_TASK_SUPPORT /* When using NOS_TASK_SUPPORT, don't check mstatus */ + csrr t0, mstatus andi t0, t0, MSTATUS_MIE bnei t0, 0, restore_mstatus andi a0, a0, ~(MSTATUS_MIE | MSTATUS_MPIE) +#endif restore_mstatus: csrw mstatus, a0 @@ -498,6 +601,27 @@ restore_mstatus: .align 2 TrapVector: + +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to check mcause == ecall and a0 = magic word for taskSwitch */ + addi sp, sp, -8 + SREG a1, 0(sp) + SREG a2, 4(sp) + csrr a1, mcause + li a2, MCAUSE_ECALL_FROM_MMODE + bne a1, a2, IsTrap + li a2, NOS_TASK_SWITCH_MAGIC_NUM + bne a0, a2, IsTrap + LREG a2, 4(sp) + LREG a1, 0(sp) + addi sp, sp, 8 + tail NOS_TaskDispatch + +IsTrap: + LREG a2, 4(sp) + LREG a1, 0(sp) + addi sp, sp, 8 +#endif + push_reg csrr a0, mcause li t1, MCAUSE_ECALL_FROM_MMODE @@ -579,11 +703,6 @@ flash_init: ori t1, t1, 1 sw t1, 0x124(t0) -/* enable flash cmd */ - li t0, EFC_MAGIC_NUMBER - li t1, EFC_MAGIC_LOCK_RW - sw t0, (t1) - /* initialize global pointer */ .option push .option norelax @@ -591,22 +710,11 @@ flash_init: .option pop /* initialize stack pointer */ +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to use irq stack */ + la sp, __init_stack_top +#else la sp, __stack_top - -/* timer0 interrupt enable */ - li t0, TIMER0_CONTROL - lw t1, (t0) - andi t1, t1, TIMER0_INTENABLE - sw t1, (t0) - -/* uart0 deinit */ - li t0, 0x14000000 - li t1, 0 - sw t1, IBRD_OFFSET(t0) - sw t1, FBRD_OFFSET(t0) - sw t1, LCR_H_OFFSET(t0) - sw t1, CR_OFFSET(t0) - sw t1, DMACR_OFFSET(t0) +#endif /* perform the rest of initialization in C */ clear_sram: @@ -643,6 +751,12 @@ start_coderom_data_copy: la t2, __data_end jal mem_cpy +stack_sram_bound_data_copy: + la t0, __stack_sram_bound_data_start /* SRAM addr */ + la t1, __stack_sram_bound_data_load /* ROM addr */ + la t2, __stack_sram_bound_data_end + jal mem_cpy + pmp_init: li t0, 0xB00 csrw pmpaddr0, t0 @@ -675,14 +789,6 @@ pmp_init: csrw pmpcfg1,t0 #endif -/* disable Icache */ - csrwi 0x7C0, 0x0 /* disable ICACHE */ - fence - -/* disable Dcache */ - csrwi 0x7C1, 0x0 /* disable DCACHE */ - fence - /* support float and mie */ li t0,0x2008 csrs mstatus,t0 @@ -709,10 +815,15 @@ pmp_init: csrw locipri15, t0 ecall + +#ifdef NOS_TASK_SUPPORT + jal Chip_Init +#else jal Chip_Init /* jump to C func. */ jal main +#endif dead_loop: j dead_loop diff --git a/src/chip/3061m/sysctrl.h b/src/chip/3061m/sysctrl.h index b23f23aa63b8904c1b4f1f6cc4ec89fd0bcbe8c6..caeeec398052692fca2142c8e932e9d16a2533fc 100644 --- a/src/chip/3061m/sysctrl.h +++ b/src/chip/3061m/sysctrl.h @@ -511,6 +511,17 @@ static inline void DCL_SYSCTRL_GenerateSoftInterrupt(void) SYSCTRL0->SC_SOFT_INT.BIT.software_int = 1; } +/** + * @brief Clear software interrupt register, writing 0 clear software interrupt. + * @param None. + * @retval None. + */ +static inline void DCL_SYSCTRL_ClearSoftInterrupt(void) +{ + SYSCTRL0->SC_SOFT_INT.BIT.software_int = 0; +} + + /** * @brief Set Software interrupt event ID. * @param id the software interrupt event ID. diff --git a/src/chip/3061m/systick.h b/src/chip/3061m/systick.h index 8e4f42eb30db1e8c1a5235d91582b184f4a3282b..3f1c2553f22e71f729611c8d1d6b2ec28c3a06d1 100644 --- a/src/chip/3061m/systick.h +++ b/src/chip/3061m/systick.h @@ -31,6 +31,7 @@ /* Includes ------------------------------------------------------------------*/ #include "baseaddr.h" #include "systickinit.h" +#include "feature.h" /** * @addtogroup SYSTICK * @{ @@ -47,6 +48,12 @@ * @brief Definition of SYSTICK configuration parameters. * @{ */ +#ifdef NOS_TASK_SUPPORT +#ifndef CFG_SYSTICK_TICKINTERVAL_US +#define CFG_SYSTICK_TICKINTERVAL_US 100 +#endif +unsigned int SYSTICK_GetTickInterval(void); +#endif #define SYSTICK_MAX_VALUE 0xFFFFFFFFUL @@ -104,6 +111,8 @@ static inline unsigned int DCL_SYSTICK_GetTick(void) return SYSTICK->MTIME; /* Systick value(Lower 32bit register) */ } +unsigned int SYSTICK_GetTimeStampUs(void); + /** * @} */ diff --git a/src/chip/3065a/chipinit/chipinit.c b/src/chip/3065a/chipinit/chipinit.c index 5247dd10bfbcd3bc9bf61488b3ca729fec837d42..2d9cdac2f2be6c70037c472c0f059ccb22088fa4 100644 --- a/src/chip/3065a/chipinit/chipinit.c +++ b/src/chip/3065a/chipinit/chipinit.c @@ -63,16 +63,18 @@ void Chip_Init(void) /* Config FLASH Clock */ FLASH_ClockConfig(coreClkSelect); + IRQ_Init(); SYSTICK_Init(); /* Set CoreClock Select after FLASH Config Done */ CRG_SetCoreClockSelect(coreClkSelect); - /* Waiting CRG Config Done */ if (HAL_CRG_GetCoreClkFreq() != HOSC_FREQ) { FLASH_WaitClockConfigDone(); } - - IRQ_Init(); +#ifdef NOS_TASK_SUPPORT + /* Support IRQ to upload the totalCycle and detect the timeout lists */ + SYSTICK_IRQ_Enable(); +#endif ADC_InitVref(); TSENSOR_InitVrefList(); PGA_InitVref(); diff --git a/src/chip/3065a/chipinit/nosinit/nosinit.c b/src/chip/3065a/chipinit/nosinit/nosinit.c index 38dcd197144cd84c31a00ddabaa9a59a629bf2f9..722dcac760af0649763247b564b9cad72fb40502 100644 --- a/src/chip/3065a/chipinit/nosinit/nosinit.c +++ b/src/chip/3065a/chipinit/nosinit/nosinit.c @@ -20,7 +20,7 @@ * @brief nos init module. * @details nos initialization function during startup */ - +#include "feature.h" #ifdef NOS_TASK_SUPPORT #include "nos_task.h" #include "nosinit.h" @@ -36,7 +36,7 @@ unsigned char __attribute__((aligned(16))) g_taskMainStackSpace[CFG_NOS_MAINTASK static unsigned int g_nosSysFreq; // Get tick in real time -static unsigned long long NOS_GetTick() +static unsigned long long NOS_GetTick(void) { unsigned int cycle, cycleh; asm volatile("csrr %0, cycle" : "=r"(cycle)); @@ -65,7 +65,7 @@ void NOS_Init(void) param.taskEntry = (NOS_TaskEntryFunc)main; /* Set the entry function by user define */ param.param = 0; param.priority = NOS_TASK_PRIORITY_LOWEST; - param.stackAddr = g_taskMainStackSpace; + param.stackAddr = (unsigned int)g_taskMainStackSpace; param.stackSize = sizeof(g_taskMainStackSpace); param.privateData = 0; (void)NOS_TaskCreate(¶m, &taskId); diff --git a/src/chip/3065a/chipinit/nosinit/nosinit.h b/src/chip/3065a/chipinit/nosinit/nosinit.h index 81c83b4369c54cf8a41b184ee062e5fd8b4792d6..fa89d018048c5e7b0a4c49c36ca29c9dd4ebc906 100644 --- a/src/chip/3065a/chipinit/nosinit/nosinit.h +++ b/src/chip/3065a/chipinit/nosinit/nosinit.h @@ -21,6 +21,15 @@ * @details nos initialization function during startup */ +#ifndef NOS_INIT_H +#define NOS_INIT_H + +#include "feature.h" + #ifdef NOS_TASK_SUPPORT -int main(void); +extern int main(void); +extern void OsHwiDispatchTick(void); +void NOS_Init(void); +#endif + #endif \ No newline at end of file diff --git a/src/chip/3065a/chipinit/systickinit/systickinit.c b/src/chip/3065a/chipinit/systickinit/systickinit.c index 7f641067d7665995b36fe9d9bcf562e542e019c1..6b075c43ca6a00e79584b1549b515501080d14d2 100644 --- a/src/chip/3065a/chipinit/systickinit/systickinit.c +++ b/src/chip/3065a/chipinit/systickinit/systickinit.c @@ -23,31 +23,38 @@ #include "baseaddr.h" #include "timer.h" #include "systick.h" -#include "systickinit.h" #include "crg.h" - -TIMER_Handle g_systickHandle; - +#include "systickinit.h" +#include "feature.h" #ifdef NOS_TASK_SUPPORT #include "interrupt.h" #include "systick.h" +#include "nosinit.h" +#endif + +TIMER_Handle g_systickHandle; +#ifdef NOS_TASK_SUPPORT #define NOS_TickPostDispatch OsHwiDispatchTick -void SYSTICK_Default_Callback(void) +static void SYSTICK_Default_Callback(void *handle) { /* The default systick callback when using th nos task */ - HAL_TIMER_IrqClear(&g_systickHandle); + BASE_FUNC_UNUSED(handle); NOS_TickPostDispatch(); } void SYSTICK_IRQ_Enable(void) { /* When Support NOS Task, Need to open the TickIRQ, us per tick will to update the load */ - g_systickHandle.irqNum = IRQ_TIMER3; + g_systickHandle.load = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + g_systickHandle.bgLoad = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_LOAD); /* config load value */ + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_BGLOAD); /* config bgLoad value */ g_systickHandle.interruptEn = BASE_CFG_ENABLE; - HAL_TIMER_RegisterCallback(&g_systickHandle, SYSTICK_Default_Callback); - HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_INTERRUPT); // enable the systickIRQ - IRQ_SetPriority(g_systickHandle.irqNum, 1); + HAL_TIMER_RegisterCallback(&g_systickHandle, TIMER_PERIOD_FIN, SYSTICK_Default_Callback); + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_INTERRUPT); /* enable the systickIRQ */ + IRQ_SetPriority(IRQ_TIMER3, 1); + IRQ_Register(IRQ_TIMER3, HAL_TIMER_IrqHandler, &g_systickHandle); IRQ_EnableN(IRQ_TIMER3); } @@ -57,7 +64,7 @@ unsigned int SYSTICK_GetTickInterval(void) return CFG_SYSTICK_TICKINTERVAL_US; } -static inline unsigned int DCL_GetCpuCycle() +static inline unsigned int DCL_GetCpuCycle(void) { /* Get the Cpu Cycle Register(CSR) */ unsigned int cycle; @@ -99,27 +106,17 @@ unsigned int SYSTICK_GetTimeStampUs(void) * @param None * @retval None */ -void SYSTICK_Init() +void SYSTICK_Init(void) { /* Choose the config to support GetTick and Delay */ g_systickHandle.baseAddress = SYSTICK; -#ifdef NOS_TASK_SUPPORT - /* Change the period load to the user defined usecond */ - g_systickHandle.load = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; - g_systickHandle.bgLoad = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; -#else g_systickHandle.load = SYSTICK_MAX_VALUE; g_systickHandle.bgLoad = SYSTICK_MAX_VALUE; -#endif g_systickHandle.mode = TIMER_MODE_RUN_PERIODIC; g_systickHandle.prescaler = TIMERPRESCALER_NO_DIV; g_systickHandle.size = TIMER_SIZE_32BIT; /* Don't Support IRQ because only needs to read the value of systick */ g_systickHandle.interruptEn = BASE_CFG_DISABLE; HAL_TIMER_Init(&g_systickHandle); -#ifdef NOS_TASK_SUPPORT - /* Support IRQ to upload the totalCycle and detect the timeout lists */ - SYSTICK_IRQ_Enable(); -#endif HAL_TIMER_Start(&g_systickHandle); } \ No newline at end of file diff --git a/src/chip/3065a/chipinit/systickinit/systickinit.h b/src/chip/3065a/chipinit/systickinit/systickinit.h index 7b7b1e0efd13e18d373f188b733768fd5ccf46bf..7460e352344e0a5e62cbb2e85d82f0a3c3d8079c 100644 --- a/src/chip/3065a/chipinit/systickinit/systickinit.h +++ b/src/chip/3065a/chipinit/systickinit/systickinit.h @@ -24,6 +24,12 @@ #ifndef McuMagicTag_SYSTICKINIT_H #define McuMagicTag_SYSTICKINIT_H +#include "feature.h" + void SYSTICK_Init(void); +#ifdef NOS_TASK_SUPPORT +void SYSTICK_IRQ_Enable(void); +#endif + #endif \ No newline at end of file diff --git a/src/chip/3065a/codecopy.json b/src/chip/3065a/codecopy.json new file mode 100644 index 0000000000000000000000000000000000000000..7265710c4445da6c887d6d760c561584a1cb55e0 --- /dev/null +++ b/src/chip/3065a/codecopy.json @@ -0,0 +1,65 @@ +{ + "modules": [ + "application/user", + "build", + "chip/3065a/chipinit", + "chip/3065a/fotp", + "chip/3065a/iomap/3065arpirz", + "chip/3065a/ip_crg", + "chip/3065a/baseaddr.h", + "chip/3065a/chipinc.h", + "chip/3065a/info.h", + "chip/3065a/interrupt_ip.h", + "chip/3065a/ioconfig.h", + "chip/3065a/locktype.h", + "chip/3065a/sysctrl.h", + "chip/3065a/systick.h", + "chip/3065a/flash.lds", + "chip/3065a/startup.S", + "chip/target/userconfig_for_306xh.json", + "drivers/debug", + "generatecode", + "middleware/control_library", + "middleware/function_safety", + "middleware/hisilicon/loaderboot", + "middleware/hisilicon/nostask/arch", + "middleware/hisilicon/nostask/config", + "middleware/hisilicon/nostask/include", + "middleware/hisilicon/nostask/kernel", + "middleware/hisilicon/nostask/nos_api", + "middleware/hisilicon/libboundscheck_v1.1.16", + "middleware/thirdparty/sysroot", + "tools/uttest", + "bundle.json" + ], + + "ip_drive_file": ["acmp", "adc", "apt", "base", "can", "capm", "cfd", "cmm", "crc", "crg", + "dac", "dma", "flash", "gpio", "gpt", "i2c", "pga", "pmc", "qdm", "spi", + "timer", "tsensor", "uart", "wdg", "iocmg", "iwdg"], + "acmp" : ["common", "acmp_v0", "sample", "testcase_v0"], + "adc" : ["common", "adc_v0", "sample", "testcase_v0"], + "apt" : ["common", "apt_v0", "sample", "testcase_v0"], + "base" : ["common", "base_v0"], + "can" : ["common", "can_v0", "sample", "testcase_v0"], + "capm" : ["common", "capm_v0", "testcase_v0"], + "cfd" : ["common", "cfd_v0", "testcase_v0"], + "cmm" : ["common", "cmm_v0", "testcase_v0"], + "crc" : ["common", "crc_v0", "testcase_v0"], + "crg" : ["common", "crg_v0", "testcase_v0"], + "dac" : ["common", "dac_v0", "sample", "testcase_v0"], + "dma" : ["common", "dma_v0", "testcase_v0"], + "flash" : ["common", "flash_v0", "testcase_v0"], + "gpio" : ["common", "gpio_v0", "testcase_v0"], + "gpt" : ["common_v0", "gpt_v0", "testcase_v0"], + "i2c" : ["common", "i2c_v0", "testcase_v0"], + "pga" : ["common", "pga_v0", "sample", "testcase_v0"], + "pmc" : ["common", "pmc_v0", "sample", "testcase_v0"], + "qdm" : ["common", "qdm_v0", "testcase_v0"], + "spi" : ["common", "spi_v0", "testcase_v0"], + "timer" : ["common", "timer_v0", "testcase_v0"], + "tsensor" : ["common", "tsensor_v0", "testcase_v0"], + "uart" : ["common", "uart_v0", "testcase_v0"], + "wdg" : ["common", "wdg_v0", "testcase_v0"], + "iocmg" : ["common", "iocmg_v0", "testcase_v0"], + "iwdg" : ["common", "iwdg_v0", "testcase_v0"] +} \ No newline at end of file diff --git a/src/chip/3065a/flash.lds b/src/chip/3065a/flash.lds index 147aff72589fb2edbd281023aa0bb2abc5b2450f..6ffcf73c43f15b384524ba53d9c28ff0efdb863c 100644 --- a/src/chip/3065a/flash.lds +++ b/src/chip/3065a/flash.lds @@ -30,15 +30,15 @@ SRAM_END = 0x4000000 + 16K; /* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ /* USER CODE END 0 */ -RAM_CODE_START = 0x2000000; +RAM_DIAGNOSE_BUF_START = SRAM_START; +RAM_DIAGNOSE_BUF_SIZE = 0x20; + +RAM_CODE_START = 0x2000000 + RAM_DIAGNOSE_BUF_SIZE; RAM_CODE_SIZE = 0; -RAM_RESERVE_DATA_START = SRAM_START + RAM_CODE_SIZE; +RAM_RESERVE_DATA_START = RAM_DIAGNOSE_BUF_START + RAM_DIAGNOSE_BUF_SIZE + RAM_CODE_SIZE; RAM_RESERVE_DATA_SIZE = 0; -RAM_DIAGNOSE_BUF_START = RAM_RESERVE_DATA_START + RAM_RESERVE_DATA_SIZE; -RAM_DIAGNOSE_BUF_SIZE = 0x20; - STACK_SRAM_BOUND_SIZE = 0x10; RAM_START = RAM_RESERVE_DATA_START + RAM_RESERVE_DATA_SIZE; @@ -57,15 +57,15 @@ FLASH_SIZE = 152K - 4; MEMORY { + /* ram for diagnose buf */ + RAM_DIAGNOSE_BUF(rw) : ORIGIN = RAM_DIAGNOSE_BUF_START, LENGTH = RAM_DIAGNOSE_BUF_SIZE + /* ram for code */ RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE /* ram for reserved data */ RAM_RESERVE_DATA(rw) : ORIGIN = RAM_RESERVE_DATA_START, LENGTH = RAM_RESERVE_DATA_SIZE - /* ram for diagnose buf */ - RAM_DIAGNOSE_BUF(rw) : ORIGIN = RAM_DIAGNOSE_BUF_START, LENGTH = RAM_DIAGNOSE_BUF_SIZE - /* ram for common bss and data */ RAM_DATA(xrw) : ORIGIN = RAM_START, LENGTH = RAM_SIZE @@ -157,6 +157,7 @@ SECTIONS __data_load = LOADADDR(.data); __data_start = .; *(.data*) + *(.sdata*) . = ALIGN(4); __data_end = .; } > RAM_DATA AT> FLASH_CODE @@ -171,7 +172,12 @@ SECTIONS __stack_sram_bound_data_end = .; } > STACK_SRAM_BOUND AT> FLASH_CODE - .checkSum (NOLOAD) : ALIGN(4) + .ramBuf : ALIGN(4) + { + *(RAM_DIAGNOSE_BUF) + } > RAM_DIAGNOSE_BUF AT> FLASH_CODE + + .checkSum : ALIGN(4) { __checksum_addr = .; *(CHECKSUM) @@ -183,6 +189,7 @@ SECTIONS { __bss_begin__ = .; *(.bss*) + *(.sbss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; @@ -190,11 +197,6 @@ SECTIONS __bss_size__ = __bss_end__ - __bss_begin__; __global_pointer$ = __data_start + ((__data_size + __bss_size__) / 2); - .ramBuf (NOLOAD) : ALIGN(4) - { - *(RAM_DIAGNOSE_BUF) - } > RAM_DIAGNOSE_BUF - /* USER CODE BEGIN 2 */ /* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ /* USER CODE END 2 */ diff --git a/src/chip/3065a/flashdefault.lds b/src/chip/3065a/flashdefault.lds new file mode 100644 index 0000000000000000000000000000000000000000..0fe0a41ea3c9628c9afbbf1b5156c84bc31499ee --- /dev/null +++ b/src/chip/3065a/flashdefault.lds @@ -0,0 +1,85 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flash.lds + * @author MCU Application Driver Team + * @brief RISCV flash link script + */ + +OUTPUT_ARCH( "riscv" ) + +SRAM_START = 0x4000000; +SRAM_END = 0x4000000 + 16K; + +RAM_CODE_START = 0x2000000; +RAM_CODE_SIZE = 0; + +RAM_START = SRAM_START; +RAM_END = SRAM_END; +RAM_SIZE = 16384; + +FLASH_START = 0x3000000; +FLASH_SIZE = 0x26000; + +MEMORY +{ + /* ram for code */ + RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE + /* ram for common bss and data */ + RAM_DATA(xrw) : ORIGIN = RAM_START + RAM_CODE_SIZE, LENGTH = RAM_SIZE + /* ram for target */ + FLASH_CODE(rx) : ORIGIN = FLASH_START, LENGTH = FLASH_SIZE +} + +SECTIONS +{ + .text : ALIGN(4) + { + __start_addr = .; + *(.text*) + *(.ram.text*) + . = ALIGN(4); + __rodata_start = .; + *(.rodata*) + . = ALIGN(4); + __rodata_end = .; + *(.got*) + __text_end = .; + } > FLASH_CODE + + /* data section */ + .data : ALIGN(4) + { + __data_load = LOADADDR(.data); + __data_start = .; + *(.data*) + *(.sdata*) + . = ALIGN(4); + __data_end = .; + } > RAM_DATA AT> FLASH_CODE + + /* bss section */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_begin__ = .; + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM_DATA +} \ No newline at end of file diff --git a/src/chip/3065a/systick.h b/src/chip/3065a/systick.h index 1a72e8d430d5841cf8e16081208852e198626caa..172099f841784395fc44e9df1cc48ff2313b103d 100644 --- a/src/chip/3065a/systick.h +++ b/src/chip/3065a/systick.h @@ -29,7 +29,7 @@ #define McuMagicTag_SYSTICK_H /* Includes ------------------------------------------------------------------*/ - +#include "feature.h" /** * @addtogroup SYSTICK * @{ diff --git a/src/chip/3065h/chipinit/chipinit.c b/src/chip/3065h/chipinit/chipinit.c index 5247dd10bfbcd3bc9bf61488b3ca729fec837d42..2d9cdac2f2be6c70037c472c0f059ccb22088fa4 100644 --- a/src/chip/3065h/chipinit/chipinit.c +++ b/src/chip/3065h/chipinit/chipinit.c @@ -63,16 +63,18 @@ void Chip_Init(void) /* Config FLASH Clock */ FLASH_ClockConfig(coreClkSelect); + IRQ_Init(); SYSTICK_Init(); /* Set CoreClock Select after FLASH Config Done */ CRG_SetCoreClockSelect(coreClkSelect); - /* Waiting CRG Config Done */ if (HAL_CRG_GetCoreClkFreq() != HOSC_FREQ) { FLASH_WaitClockConfigDone(); } - - IRQ_Init(); +#ifdef NOS_TASK_SUPPORT + /* Support IRQ to upload the totalCycle and detect the timeout lists */ + SYSTICK_IRQ_Enable(); +#endif ADC_InitVref(); TSENSOR_InitVrefList(); PGA_InitVref(); diff --git a/src/chip/3065h/chipinit/nosinit/nosinit.c b/src/chip/3065h/chipinit/nosinit/nosinit.c index 38dcd197144cd84c31a00ddabaa9a59a629bf2f9..722dcac760af0649763247b564b9cad72fb40502 100644 --- a/src/chip/3065h/chipinit/nosinit/nosinit.c +++ b/src/chip/3065h/chipinit/nosinit/nosinit.c @@ -20,7 +20,7 @@ * @brief nos init module. * @details nos initialization function during startup */ - +#include "feature.h" #ifdef NOS_TASK_SUPPORT #include "nos_task.h" #include "nosinit.h" @@ -36,7 +36,7 @@ unsigned char __attribute__((aligned(16))) g_taskMainStackSpace[CFG_NOS_MAINTASK static unsigned int g_nosSysFreq; // Get tick in real time -static unsigned long long NOS_GetTick() +static unsigned long long NOS_GetTick(void) { unsigned int cycle, cycleh; asm volatile("csrr %0, cycle" : "=r"(cycle)); @@ -65,7 +65,7 @@ void NOS_Init(void) param.taskEntry = (NOS_TaskEntryFunc)main; /* Set the entry function by user define */ param.param = 0; param.priority = NOS_TASK_PRIORITY_LOWEST; - param.stackAddr = g_taskMainStackSpace; + param.stackAddr = (unsigned int)g_taskMainStackSpace; param.stackSize = sizeof(g_taskMainStackSpace); param.privateData = 0; (void)NOS_TaskCreate(¶m, &taskId); diff --git a/src/chip/3065h/chipinit/nosinit/nosinit.h b/src/chip/3065h/chipinit/nosinit/nosinit.h index 81c83b4369c54cf8a41b184ee062e5fd8b4792d6..fa89d018048c5e7b0a4c49c36ca29c9dd4ebc906 100644 --- a/src/chip/3065h/chipinit/nosinit/nosinit.h +++ b/src/chip/3065h/chipinit/nosinit/nosinit.h @@ -21,6 +21,15 @@ * @details nos initialization function during startup */ +#ifndef NOS_INIT_H +#define NOS_INIT_H + +#include "feature.h" + #ifdef NOS_TASK_SUPPORT -int main(void); +extern int main(void); +extern void OsHwiDispatchTick(void); +void NOS_Init(void); +#endif + #endif \ No newline at end of file diff --git a/src/chip/3065h/chipinit/systickinit/systickinit.c b/src/chip/3065h/chipinit/systickinit/systickinit.c index 7f641067d7665995b36fe9d9bcf562e542e019c1..4b466bb5fe5fdf41ad8120cb75f9a12dc8bf34aa 100644 --- a/src/chip/3065h/chipinit/systickinit/systickinit.c +++ b/src/chip/3065h/chipinit/systickinit/systickinit.c @@ -23,31 +23,38 @@ #include "baseaddr.h" #include "timer.h" #include "systick.h" -#include "systickinit.h" #include "crg.h" - -TIMER_Handle g_systickHandle; - +#include "systickinit.h" +#include "feature.h" #ifdef NOS_TASK_SUPPORT #include "interrupt.h" #include "systick.h" +#include "nosinit.h" +#endif + +TIMER_Handle g_systickHandle; +#ifdef NOS_TASK_SUPPORT #define NOS_TickPostDispatch OsHwiDispatchTick -void SYSTICK_Default_Callback(void) +static void SYSTICK_Default_Callback(void *handle) { /* The default systick callback when using th nos task */ - HAL_TIMER_IrqClear(&g_systickHandle); + BASE_FUNC_UNUSED(handle); NOS_TickPostDispatch(); } void SYSTICK_IRQ_Enable(void) { /* When Support NOS Task, Need to open the TickIRQ, us per tick will to update the load */ - g_systickHandle.irqNum = IRQ_TIMER3; + g_systickHandle.load = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + g_systickHandle.bgLoad = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_LOAD); /* config load value */ + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_BGLOAD); /* config bgLoad value */ g_systickHandle.interruptEn = BASE_CFG_ENABLE; - HAL_TIMER_RegisterCallback(&g_systickHandle, SYSTICK_Default_Callback); - HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_INTERRUPT); // enable the systickIRQ - IRQ_SetPriority(g_systickHandle.irqNum, 1); + HAL_TIMER_RegisterCallback(&g_systickHandle, TIMER_PERIOD_FIN, SYSTICK_Default_Callback); + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_INTERRUPT); /* enable the systickIRQ */ + IRQ_SetPriority(IRQ_TIMER3, 1); + IRQ_Register(IRQ_TIMER3, HAL_TIMER_IrqHandler, &g_systickHandle); IRQ_EnableN(IRQ_TIMER3); } @@ -57,7 +64,7 @@ unsigned int SYSTICK_GetTickInterval(void) return CFG_SYSTICK_TICKINTERVAL_US; } -static inline unsigned int DCL_GetCpuCycle() +static inline unsigned int DCL_GetCpuCycle(void) { /* Get the Cpu Cycle Register(CSR) */ unsigned int cycle; @@ -99,27 +106,17 @@ unsigned int SYSTICK_GetTimeStampUs(void) * @param None * @retval None */ -void SYSTICK_Init() +void SYSTICK_Init(void) { /* Choose the config to support GetTick and Delay */ g_systickHandle.baseAddress = SYSTICK; -#ifdef NOS_TASK_SUPPORT - /* Change the period load to the user defined usecond */ - g_systickHandle.load = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; - g_systickHandle.bgLoad = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; -#else - g_systickHandle.load = SYSTICK_MAX_VALUE; - g_systickHandle.bgLoad = SYSTICK_MAX_VALUE; -#endif - g_systickHandle.mode = TIMER_MODE_RUN_PERIODIC; - g_systickHandle.prescaler = TIMERPRESCALER_NO_DIV; - g_systickHandle.size = TIMER_SIZE_32BIT; + g_systickHandle.load = SYSTICK_MAX_VALUE; + g_systickHandle.bgLoad = SYSTICK_MAX_VALUE; + g_systickHandle.mode = TIMER_MODE_RUN_PERIODIC; + g_systickHandle.prescaler = TIMERPRESCALER_NO_DIV; + g_systickHandle.size = TIMER_SIZE_32BIT; /* Don't Support IRQ because only needs to read the value of systick */ g_systickHandle.interruptEn = BASE_CFG_DISABLE; HAL_TIMER_Init(&g_systickHandle); -#ifdef NOS_TASK_SUPPORT - /* Support IRQ to upload the totalCycle and detect the timeout lists */ - SYSTICK_IRQ_Enable(); -#endif HAL_TIMER_Start(&g_systickHandle); } \ No newline at end of file diff --git a/src/chip/3065h/chipinit/systickinit/systickinit.h b/src/chip/3065h/chipinit/systickinit/systickinit.h index 7b7b1e0efd13e18d373f188b733768fd5ccf46bf..37588bdb5ec6e438ba646f440487f58d863cabe9 100644 --- a/src/chip/3065h/chipinit/systickinit/systickinit.h +++ b/src/chip/3065h/chipinit/systickinit/systickinit.h @@ -24,6 +24,11 @@ #ifndef McuMagicTag_SYSTICKINIT_H #define McuMagicTag_SYSTICKINIT_H +#include "feature.h" + void SYSTICK_Init(void); +#ifdef NOS_TASK_SUPPORT +void SYSTICK_IRQ_Enable(void); +#endif #endif \ No newline at end of file diff --git a/src/chip/3065h/codecopy.json b/src/chip/3065h/codecopy.json index c987b4b801fa325073a990e739367db4c31a6cf4..058fb1fc80ee7cc43c81e57a79d67a3c7a2d6db3 100644 --- a/src/chip/3065h/codecopy.json +++ b/src/chip/3065h/codecopy.json @@ -16,17 +16,18 @@ "chip/3065h/systick.h", "chip/3065h/flash.lds", "chip/3065h/startup.S", - "chip/target", + "chip/target/userconfig_for_306xh.json", "drivers/debug", "generatecode", "middleware/control_library", + "middleware/function_safety", "middleware/hisilicon/loaderboot", "middleware/hisilicon/nostask/arch", "middleware/hisilicon/nostask/config", "middleware/hisilicon/nostask/include", - "middleware/hisilicon/libboundscheck_v1.1.16", "middleware/hisilicon/nostask/kernel", "middleware/hisilicon/nostask/nos_api", + "middleware/hisilicon/libboundscheck_v1.1.16", "middleware/thirdparty/sysroot", "tools/uttest", "bundle.json" diff --git a/src/chip/3065h/flash.lds b/src/chip/3065h/flash.lds index 1dc3b023c8bedca1ca507d00f9a892650af2b3fe..e283dc905634f52d03916e1f857d3c0353f5d859 100644 --- a/src/chip/3065h/flash.lds +++ b/src/chip/3065h/flash.lds @@ -26,18 +26,18 @@ ENTRY(_start) SRAM_START = 0x4000000; SRAM_END = 0x4000000 + 16K; -RAM_CODE_START = 0x2000000; +RAM_DIAGNOSE_BUF_START = SRAM_START; +RAM_DIAGNOSE_BUF_SIZE = 0x20; + +RAM_CODE_START = 0x2000000 + RAM_DIAGNOSE_BUF_SIZE; RAM_CODE_SIZE = 0; -RAM_RESERVE_DATA_START = SRAM_START + RAM_CODE_SIZE; +RAM_RESERVE_DATA_START = RAM_DIAGNOSE_BUF_START + RAM_DIAGNOSE_BUF_SIZE + RAM_CODE_SIZE; RAM_RESERVE_DATA_SIZE = 0; -RAM_DIAGNOSE_BUF_START = RAM_RESERVE_DATA_START + RAM_RESERVE_DATA_SIZE; -RAM_DIAGNOSE_BUF_SIZE = 0x20; - STACK_SRAM_BOUND_SIZE = 0x10; -RAM_START = RAM_RESERVE_DATA_START + RAM_RESERVE_DATA_SIZE + RAM_DIAGNOSE_BUF_SIZE; +RAM_START = RAM_RESERVE_DATA_START + RAM_RESERVE_DATA_SIZE; RAM_SIZE = 0x2800 - RAM_CODE_SIZE - RAM_RESERVE_DATA_SIZE - RAM_DIAGNOSE_BUF_SIZE - STACK_SRAM_BOUND_SIZE; RAM_END = SRAM_END; @@ -52,15 +52,15 @@ FLASH_SIZE = 0x25ffc; MEMORY { + /* ram for diagnose buf */ + RAM_DIAGNOSE_BUF(rw) : ORIGIN = RAM_DIAGNOSE_BUF_START, LENGTH = RAM_DIAGNOSE_BUF_SIZE + /* ram for code */ RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE /* ram for reserved data */ RAM_RESERVE_DATA(rw) : ORIGIN = RAM_RESERVE_DATA_START, LENGTH = RAM_RESERVE_DATA_SIZE - /* ram for diagnose buf */ - RAM_DIAGNOSE_BUF(rw) : ORIGIN = RAM_DIAGNOSE_BUF_START, LENGTH = RAM_DIAGNOSE_BUF_SIZE - /* ram for common bss and data */ RAM_DATA(xrw) : ORIGIN = RAM_START, LENGTH = RAM_SIZE @@ -148,6 +148,7 @@ SECTIONS __data_load = LOADADDR(.data); __data_start = .; *(.data*) + *(.sdata*) . = ALIGN(4); __data_end = .; } > RAM_DATA AT> FLASH_CODE @@ -162,7 +163,12 @@ SECTIONS __stack_sram_bound_data_end = .; } > STACK_SRAM_BOUND AT> FLASH_CODE - .checkSum (NOLOAD) : ALIGN(4) + .ramBuf : ALIGN(4) + { + *(RAM_DIAGNOSE_BUF) + } > RAM_DIAGNOSE_BUF AT> FLASH_CODE + + .checkSum : ALIGN(4) { __checksum_addr = .; *(CHECKSUM) @@ -174,6 +180,7 @@ SECTIONS { __bss_begin__ = .; *(.bss*) + *(.sbss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; @@ -181,8 +188,7 @@ SECTIONS __bss_size__ = __bss_end__ - __bss_begin__; __global_pointer$ = __data_start + ((__data_size + __bss_size__) / 2); - .ramBuf (NOLOAD) : ALIGN(4) - { - *(RAM_DIAGNOSE_BUF) - } > RAM_DIAGNOSE_BUF +/* USER CODE BEGIN 2 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +/* USER CODE END 2 */ } \ No newline at end of file diff --git a/src/chip/3065h/flashdefault.lds b/src/chip/3065h/flashdefault.lds new file mode 100644 index 0000000000000000000000000000000000000000..0fe0a41ea3c9628c9afbbf1b5156c84bc31499ee --- /dev/null +++ b/src/chip/3065h/flashdefault.lds @@ -0,0 +1,85 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flash.lds + * @author MCU Application Driver Team + * @brief RISCV flash link script + */ + +OUTPUT_ARCH( "riscv" ) + +SRAM_START = 0x4000000; +SRAM_END = 0x4000000 + 16K; + +RAM_CODE_START = 0x2000000; +RAM_CODE_SIZE = 0; + +RAM_START = SRAM_START; +RAM_END = SRAM_END; +RAM_SIZE = 16384; + +FLASH_START = 0x3000000; +FLASH_SIZE = 0x26000; + +MEMORY +{ + /* ram for code */ + RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE + /* ram for common bss and data */ + RAM_DATA(xrw) : ORIGIN = RAM_START + RAM_CODE_SIZE, LENGTH = RAM_SIZE + /* ram for target */ + FLASH_CODE(rx) : ORIGIN = FLASH_START, LENGTH = FLASH_SIZE +} + +SECTIONS +{ + .text : ALIGN(4) + { + __start_addr = .; + *(.text*) + *(.ram.text*) + . = ALIGN(4); + __rodata_start = .; + *(.rodata*) + . = ALIGN(4); + __rodata_end = .; + *(.got*) + __text_end = .; + } > FLASH_CODE + + /* data section */ + .data : ALIGN(4) + { + __data_load = LOADADDR(.data); + __data_start = .; + *(.data*) + *(.sdata*) + . = ALIGN(4); + __data_end = .; + } > RAM_DATA AT> FLASH_CODE + + /* bss section */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_begin__ = .; + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM_DATA +} \ No newline at end of file diff --git a/src/chip/3065h/systick.h b/src/chip/3065h/systick.h index 1a72e8d430d5841cf8e16081208852e198626caa..172099f841784395fc44e9df1cc48ff2313b103d 100644 --- a/src/chip/3065h/systick.h +++ b/src/chip/3065h/systick.h @@ -29,7 +29,7 @@ #define McuMagicTag_SYSTICK_H /* Includes ------------------------------------------------------------------*/ - +#include "feature.h" /** * @addtogroup SYSTICK * @{ diff --git a/src/chip/3065p/anavref.h b/src/chip/3065p/anavref.h new file mode 100644 index 0000000000000000000000000000000000000000..e09484e0f3dff393afc3be92ddf236f39da35d61 --- /dev/null +++ b/src/chip/3065p/anavref.h @@ -0,0 +1,92 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file anavref.h + * @author MCU Driver Team + * @brief anavref register mapping structure + */ + +/* Macro definitions */ +#ifndef McuMagicTag_ANAVREF_IP_H +#define McuMagicTag_ANAVREF_IP_H + +#include "baseinc.h" + +/** + * @brief Define the union VREF_CTRL_REG0 + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_ref_enh : 1; /**< vref enable */ + unsigned int reserved0 : 31; + } BIT; +} volatile VREF_CTRL_REG0; + +/** + * @brief Define the union VREF_CTRL_REG1 + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_ref_chop_enh : 1; /**< vref chopping enable */ + unsigned int reserved0 : 15; + unsigned int da_ref_temp_trim_enh : 1; /**< vref High-precision mode enable */ + unsigned int reserved1 : 15; + } BIT; +} volatile VREF_CTRL_REG1; + + +/** + * @brief Define the union VREF_TRIM_REG0 + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_iref_trim : 8; /**< iref trim */ + unsigned int da_ref_vref_trim : 8; /**< IBIAS voltage trim */ + unsigned int da_ref_vbg_trim : 8; /**< vref voltage trim */ + unsigned int da_ref_buf_trim : 8; /**< vref buffer trim */ + } BIT; +} volatile VREF_TRIM_REG0; + +/** + * @brief Define the union VREF_TRIM_REG1 + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_ref_temp_trim3 : 8; /**< Benchmark temperature drift trim information */ + unsigned int da_ref_temp_trim2 : 8; /**< Benchmark temperature drift trim information */ + unsigned int da_ref_temp_trim1 : 8; /**< Benchmark temperature drift trim information */ + unsigned int da_ref_temp_trim0 : 8; /**< Benchmark temperature drift trim information */ + } BIT; +} volatile VREF_TRIM_REG1; + +/** + * @brief Define the VREF_RegStruct + */ +typedef struct { + VREF_CTRL_REG0 VREF_CTRL0; /**< Offset address: 0x0000000U*/ + unsigned int space0[7]; + VREF_CTRL_REG1 VREF_CTRL1; /**< Offset address: 0x0000020U*/ + unsigned int space1[7]; + VREF_TRIM_REG0 VREF_TRIM0; /**< Offset address: 0x0000040U*/ + VREF_TRIM_REG1 VREF_TRIM1; /**< Offset address: 0x0000044U*/ +} volatile VREF_RegStruct; + +#endif /* McuMagicTag_ANAVREF_IP_H */ \ No newline at end of file diff --git a/src/chip/3065p/baseaddr.h b/src/chip/3065p/baseaddr.h new file mode 100644 index 0000000000000000000000000000000000000000..bf595dbaf2e42f46c1f4d0349542ed5039470597 --- /dev/null +++ b/src/chip/3065p/baseaddr.h @@ -0,0 +1,235 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file baseaddr.h + * @author MCU Driver Team + * @brief Definition of MCU register baseaddress + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_BASEADDR_H +#define McuMagicTag_BASEADDR_H + +#define CRG_BASE (void *)0x10000000 +#define CMM_BASE (void *)0x10010000 +#define CFD_BASE (void *)0x10020000 +#define SYSCTRL0_BASE (void *)0x10100000 +#define SYSCTRL1_BASE (void *)0x10100000 /* The base address offset is configured in the register. */ +#define UART0_BASE (void *)0x14000000 +#define UART1_BASE (void *)0x14001000 +#define UART2_BASE (void *)0x14002000 +#define UART3_BASE (void *)0x14003000 +#define UART4_BASE (void *)0x14004000 + +#define I2C0_BASE (void *)0x14100000 +#define SPI0_BASE (void *)0x14200000 +#define SPI1_BASE (void *)0x14201000 +#define TIMER0_BASE (void *)0x14300000 +#define TIMER1_BASE (void *)0x14301000 +#define TIMER2_BASE (void *)0x14302000 +#define TIMER3_BASE (void *)0x14303000 + +#define SYSTICK_BASE (void *)0x14380000 +#define WWDG_BASE (void *)0x14400000 +#define IWDG_BASE (void *)0x14401000 +#define GPIO0_BASE (void *)0x14500000 +#define GPIO1_BASE (void *)0x14501000 +#define GPIO2_BASE (void *)0x14502000 +#define GPIO3_BASE (void *)0x14503000 +#define GPIO4_BASE (void *)0x14504000 +#define GPIO5_BASE (void *)0x14505000 +#define GPIO6_BASE (void *)0x14506000 +#define GPIO7_BASE (void *)0x14507000 +#define GPIO8_BASE (void *)0x14508000 +#define GPIO9_BASE (void *)0x14509000 +#define CAN_BASE (void *)0x14600000 +#define CAN1_BASE (void *)0x14601000 +#define GPT0_BASE (void *)0x14700000 +#define GPT1_BASE (void *)0x14701000 + +#define EFC_BASE (void *)0x14710000 +#define PMC_BASE (void *)0x147E0000 +#define IOCMG_BASE (void *)0x147F0000 +#define CRC_BASE (void *)0x14800000 +#define APT0_BASE (void *)0x14A00000 +#define APT1_BASE (void *)0x14A01000 +#define APT2_BASE (void *)0x14A02000 +#define APT3_BASE (void *)0x14A03000 +#define APT4_BASE (void *)0x14A04000 +#define APT5_BASE (void *)0x14A05000 +#define APT6_BASE (void *)0x14A06000 +#define APT7_BASE (void *)0x14A07000 +#define APT8_BASE (void *)0x14A08000 + +#define CAPM0_BASE (void *)0x14B00000 +#define CAPM1_BASE (void *)0x14B01000 +#define CAPM2_BASE (void *)0x14B02000 +#define CAPM_COMM_BASE (void *)0x14B03000 + +#define QDM0_BASE (void *)0x14C00000 +#define QDM1_BASE (void *)0x14C01000 +#define QDM2_BASE (void *)0x14C02000 +#define QDM3_BASE (void *)0x14C03000 +#define ADC0_BASE (void *)0x18000000 +#define ADC1_BASE (void *)0x18001000 +#define ADC2_BASE (void *)0x18002000 +#define VREF_BASE (void *)0x18100000 +#define PGA0_BASE (void *)0x18200000 +#define PGA1_BASE (void *)0x18201000 +#define PGA2_BASE (void *)0x18202000 +#define ACMP0_BASE (void *)0x18300000 +#define ACMP1_BASE (void *)0x18301000 +#define ACMP2_BASE (void *)0x18302000 +#define DAC0_BASE (void *)0x18400000 +#define DAC1_BASE (void *)0x18401000 +#define DAC2_BASE (void *)0x18402000 + +#define TSENSOR_BASE (void *)0x18500000 +#define ANA_CTRL_TOP_BASE (void *)0x18600000 + +#define DMA_BASE (void *)0x1C000000 +#define DMA_CHANNEL0_BASE (void *)0x1C000100 +#define DMA_CHANNEL1_BASE (void *)0x1C000120 +#define DMA_CHANNEL2_BASE (void *)0x1C000140 +#define DMA_CHANNEL3_BASE (void *)0x1C000160 +#define DMA_CHANNEL4_BASE (void *)0x1C000180 +#define DMA_CHANNEL5_BASE (void *)0x1C0001A0 + +#define CRG ((CRG_RegStruct *)CRG_BASE) +#define CMM ((CMM_RegStruct *)CMM_BASE) +#define CFD ((CFD_RegStruct *)CFD_BASE) +#define SYSCTRL0 ((SYSCTRL0_RegStruct *)SYSCTRL0_BASE) +#define SYSCTRL1 ((SYSCTRL1_RegStruct *)SYSCTRL1_BASE) +#define UART0 ((UART_RegStruct *)UART0_BASE) +#define UART1 ((UART_RegStruct *)UART1_BASE) +#define UART2 ((UART_RegStruct *)UART2_BASE) +#define UART3 ((UART_RegStruct *)UART3_BASE) +#define UART4 ((UART_RegStruct *)UART4_BASE) +#define I2C0 ((I2C_RegStruct *)I2C0_BASE) +#define SPI0 ((SPI_RegStruct *)SPI0_BASE) +#define SPI1 ((SPI_RegStruct *)SPI1_BASE) +#define TIMER0 ((TIMER_RegStruct *)TIMER0_BASE) +#define TIMER1 ((TIMER_RegStruct *)TIMER1_BASE) +#define TIMER2 ((TIMER_RegStruct *)TIMER2_BASE) +#define TIMER3 ((TIMER_RegStruct *)TIMER3_BASE) +#define SYSTICK ((SYSTICK_RegStruct *)SYSTICK_BASE) +#define WWDG ((WWDG_RegStruct *)WWDG_BASE) +#define IWDG ((IWDG_RegStruct *)IWDG_BASE) +#define GPIO0 ((GPIO_RegStruct *)GPIO0_BASE) +#define GPIO1 ((GPIO_RegStruct *)GPIO1_BASE) +#define GPIO2 ((GPIO_RegStruct *)GPIO2_BASE) +#define GPIO3 ((GPIO_RegStruct *)GPIO3_BASE) +#define GPIO4 ((GPIO_RegStruct *)GPIO4_BASE) +#define GPIO5 ((GPIO_RegStruct *)GPIO5_BASE) +#define GPIO6 ((GPIO_RegStruct *)GPIO6_BASE) +#define GPIO7 ((GPIO_RegStruct *)GPIO7_BASE) +#define GPIO8 ((GPIO_RegStruct *)GPIO8_BASE) +#define GPIO9 ((GPIO_RegStruct *)GPIO9_BASE) + +#define CAN ((CAN_RegStruct *)CAN_BASE) +#define CAN1 ((CAN_RegStruct *)CAN1_BASE) +#define GPT0 ((GPT_RegStruct *)GPT0_BASE) +#define GPT1 ((GPT_RegStruct *)GPT1_BASE) +#define EFC ((EFC_RegStruct *)EFC_BASE) +#define PMC ((PMC_RegStruct *)PMC_BASE) +#define CRC ((CRC_RegStruct *)CRC_BASE) +#define APT0 ((APT_RegStruct *)APT0_BASE) +#define APT1 ((APT_RegStruct *)APT1_BASE) +#define APT2 ((APT_RegStruct *)APT2_BASE) +#define APT3 ((APT_RegStruct *)APT3_BASE) +#define APT4 ((APT_RegStruct *)APT4_BASE) +#define APT5 ((APT_RegStruct *)APT5_BASE) +#define APT6 ((APT_RegStruct *)APT6_BASE) +#define APT7 ((APT_RegStruct *)APT7_BASE) +#define APT8 ((APT_RegStruct *)APT8_BASE) +#define CAPM0 ((CAPM_RegStruct *)CAPM0_BASE) +#define CAPM1 ((CAPM_RegStruct *)CAPM1_BASE) +#define CAPM2 ((CAPM_RegStruct *)CAPM2_BASE) +#define CAPM_COMM ((CAPM_COMM_RegStruct *)CAPM_COMM_BASE) +#define QDM0 ((QDM_RegStruct *)QDM0_BASE) +#define QDM1 ((QDM_RegStruct *)QDM1_BASE) +#define QDM2 ((QDM_RegStruct *)QDM2_BASE) +#define QDM3 ((QDM_RegStruct *)QDM3_BASE) +#define ADC0 ((ADC_RegStruct *)ADC0_BASE) +#define ADC1 ((ADC_RegStruct *)ADC1_BASE) +#define ADC2 ((ADC_RegStruct *)ADC2_BASE) +#define PGA0 ((PGA_RegStruct *)PGA0_BASE) +#define PGA1 ((PGA_RegStruct *)PGA1_BASE) +#define PGA2 ((PGA_RegStruct *)PGA2_BASE) +#define DAC0 ((DAC_RegStruct *)DAC0_BASE) +#define DAC1 ((DAC_RegStruct *)DAC1_BASE) +#define DAC2 ((DAC_RegStruct *)DAC2_BASE) +#define TSENSOR ((TSENSOR_RegStruct *)TSENSOR_BASE) +#define ACMP0 ((ACMP_RegStruct *)ACMP0_BASE) +#define ACMP1 ((ACMP_RegStruct *)ACMP1_BASE) +#define ACMP2 ((ACMP_RegStruct *)ACMP2_BASE) +#define DMA ((DMA_RegStruct *)DMA_BASE) +#define DMA_CHANNEL0 ((DMA_ChannelRegStruct *)DMA_CHANNEL0_BASE) +#define DMA_CHANNEL1 ((DMA_ChannelRegStruct *)DMA_CHANNEL1_BASE) +#define DMA_CHANNEL2 ((DMA_ChannelRegStruct *)DMA_CHANNEL2_BASE) +#define DMA_CHANNEL3 ((DMA_ChannelRegStruct *)DMA_CHANNEL3_BASE) +#define DMA_CHANNEL4 ((DMA_ChannelRegStruct *)DMA_CHANNEL4_BASE) +#define DMA_CHANNEL5 ((DMA_ChannelRegStruct *)DMA_CHANNEL5_BASE) +#define IOCMG ((IOConfig_RegStruct*)IOCMG_BASE) +#define VREF ((VREF_RegStruct *)VREF_BASE) + +#define IsCRGInstance(instance) ((instance) == CRG) +#define IsCMMInstance(instance) ((instance) == CMM) +#define IsCFDInstance(instance) ((instance) == CFD) +#define IsSYSCTRLInstance(instance) (((instance) == SYSCTRL0) || ((instance) == SYSCTRL1)) +#define IsUARTInstance(instance) (((instance) == UART0) || ((instance) == UART1) || \ + ((instance) == UART2) || ((instance) == UART3) || ((instance) == UART4)) +#define IsI2CInstance(instance) ((instance) == I2C0) +#define IsSPIInstance(instance) (((instance) == SPI0) || ((instance) == SPI1)) +#define IsTIMERInstance(instance) (((instance) == TIMER0) || ((instance) == TIMER1) || \ + ((instance) == TIMER2) || ((instance) == TIMER3)) +#define IsSYSTICKInstance(instance) ((instance) == SYSTICK) +#define IsWWDGInstance(instance) ((instance) == WWDG) +#define IsIWDGInstance(instance) ((instance) == IWDG) +#define IsGPIOInstance(instance) (((instance) == GPIO0) || ((instance) == GPIO1) || \ + ((instance) == GPIO2) || ((instance) == GPIO3) || \ + ((instance) == GPIO4) || ((instance) == GPIO5) || \ + ((instance) == GPIO6) || ((instance) == GPIO7) || \ + ((instance) == GPIO8) || ((instance) == GPIO9)) +#define IsCANInstance(instance) ((instance) == CAN || ((instance) == CAN1)) +#define IsGPTInstance(instance) (((instance) == GPT0) || ((instance) == GPT1)) +#define IsEFCInstance(instance) ((instance) == EFC) +#define IsPMCInstance(instance) ((instance) == PMC) +#define IsIOCMGInstance(instance) ((instance) == IOCMG) +#define IsCRCInstance(instance) ((instance) == CRC) +#define IsAPTInstance(instance) (((instance) == APT0) || ((instance) == APT1) || \ + ((instance) == APT2) || ((instance) == APT3) || \ + ((instance) == APT4) || ((instance) == APT5) || \ + ((instance) == APT6) || ((instance) == APT7) || ((instance) == APT8)) +#define IsCAPMInstance(instance) (((instance) == CAPM0) || ((instance) == CAPM1) || ((instance) == CAPM2)) +#define IsCAPMCOMMInstance(instance) ((instance) == CAPM_COMM) +#define IsQDMInstance(instance) (((instance) == QDM0) || ((instance) == QDM1) || \ + ((instance) == QDM2) || ((instance) == QDM3)) +#define IsADCInstance(instance) (((instance) == ADC0) || ((instance) == ADC1) || ((instance) == ADC2)) +#define IsPGAInstance(instance) (((instance) == PGA0) || ((instance) == PGA1) || ((instance) == PGA2)) +#define IsDACInstance(instance) (((instance) == DAC0) || ((instance) == DAC1) || ((instance) == DAC2)) +#define IsACMPInstance(instance) (((instance) == ACMP0) || ((instance) == ACMP1) || ((instance) == ACMP2)) +#define IsDMAInstance(instance) ((instance) == DMA) +#define IsDMACHXInstance(instance) (((instance) == DMA_CHANNEL0) || ((instance) == DMA_CHANNEL1) || \ + ((instance) == DMA_CHANNEL2) || ((instance) == DMA_CHANNEL3) || \ + ((instance) == DMA_CHANNEL4) || ((instance) == DMA_CHANNEL5)) +#define SRAM_START 0x2000000 +#define SRAM_END 0x2010000 +#define REGISTER_START 0x10000000 +#define REGISTER_END 0x1C000FFF + +#endif /* McuMagicTag_BASEADDR_H */ \ No newline at end of file diff --git a/src/chip/3065p/chipinc.h b/src/chip/3065p/chipinc.h new file mode 100644 index 0000000000000000000000000000000000000000..89db675aa64c1c8ee85b7b3b17d8d114e438901e --- /dev/null +++ b/src/chip/3065p/chipinc.h @@ -0,0 +1,37 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file chipinc.h + * @author MCU Driver Team + * @brief Contains chip-related header files. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_CHIPINC_H +#define McuMagicTag_CHIPINC_H + +/* Includes ------------------------------------------------------------------ */ +#include "feature.h" +#include "info.h" +#include "baseaddr.h" +#include "locktype.h" +#include "interrupt_ip.h" +#include "sysctrl.h" +#include "systick.h" +#include "ip_crg_common.h" + +#endif /* McuMagicTag_CHIPINC_H */ \ No newline at end of file diff --git a/src/chip/3065p/chipinit/anatrim/anatrim.c b/src/chip/3065p/chipinit/anatrim/anatrim.c new file mode 100644 index 0000000000000000000000000000000000000000..e628b7d398ff6a67d48400b9f58fe082f7cd4015 --- /dev/null +++ b/src/chip/3065p/chipinit/anatrim/anatrim.c @@ -0,0 +1,259 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file anatrim.c + * @author MCU Driver Team + * @brief Chip Init modlue. + * @details Calibration of analog module parameters. + */ +#include "anatrim.h" + +float g_tsensorGain = 0.00418f; + +#ifdef FPGA +#else + +/** + * @brief Obtains the chip ID. + * @param None + * @retval None + */ +static bool CHIP_GetInfo(void) +{ + FOTP_INFO_RGN0_NUMBER_4 emptyData; + FOTP_INFO_RGN0_NUMBER_2 idData; + FOTP_InfoGet(FOTP_INFO_RNG0, 4U, (void *)&emptyData.comData); /* 4 is the number of fotp_empty_flag in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 2U, (void *)&idData.comData); /* 2 is the number of idData in otp */ + if (emptyData.REG.fotp_empty_flag != 0x5AA59669 || idData.REG.chip_id == 0xFFFFFFFF) { + return false; + } + return true; +} + +/** + * @brief VREF trim config. + * @param None + * @retval None + */ +static void VREF_Trim(void) +{ + FOTP_INFO_RGN0_NUMBER_20 trimData20; + FOTP_InfoGet(FOTP_INFO_RNG0, 20U, (void *)&trimData20.comData); /* 20 is the number of trim data in otp */ + /* VREF */ + VREF->VREF_TRIM0.BIT.da_iref_trim = trimData20.REG.data0.da_iref_trim; + VREF->VREF_TRIM0.BIT.da_ref_vref_trim = trimData20.REG.data0.da_ref_vref_trim; + VREF->VREF_TRIM0.BIT.da_ref_vbg_trim = trimData20.REG.data0.da_ref_vbg_trim; + unsigned int value = trimData20.REG.data1.da_ref_temp_trim3; + value |= (trimData20.REG.data1.da_ref_temp_trim2 << 8U); /* Shift left by 8 bits */ + value |= (trimData20.REG.data1.da_ref_temp_trim1 << 16U); /* Shift left by 16 bits */ + value |= (trimData20.REG.data0.da_ref_temp_trim0 << 24U); /* Shift left by 24 bits */ + VREF->VREF_TRIM1.reg = value; +} + +/** + * @brief TSENSOR trim config. + * @param None + * @retval None + */ +static void TSENSOR_Trim(void) +{ + HAL_CRG_IpEnableSet((void *)ADC1, IP_CLK_ENABLE); /* Enable the clock for calibration */ + FOTP_INFO_RGN0_NUMBER_20 trimData20; + FOTP_INFO_RGN0_NUMBER_21 trimData21; + FOTP_InfoGet(FOTP_INFO_RNG0, 20U, (void *)&trimData20.comData); /* 20 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 21U, (void *)&trimData21.comData); /* 21 is the number of trim data in otp */ + /* TSENSOR */ + TSENSOR->TSENSOR_TRIM.reg = trimData20.REG.data1.da_ref_vptat_trim; + ADC1->ADC_TSENSOR_TRIM.BIT.cfg_tsensor_ofst_trim = trimData21.REG.data1.ts_offset; + HAL_CRG_IpEnableSet((void *)ADC1, IP_CLK_DISABLE); /* The clock is disabled after calibration */ +} + +/** + * @brief PGA trim config. + * @param None + * @retval None + */ +static void PGA_Trim(void) +{ + HAL_CRG_IpEnableSet((void *)PGA0, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet((void *)PGA1, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet((void *)PGA2, IP_CLK_ENABLE); + FOTP_INFO_RGN0_NUMBER_21 trimData21; + FOTP_InfoGet(FOTP_INFO_RNG0, 21U, (void *)&trimData21.comData); /* 21 is the number of trim data in otp */ + /* PGA */ + PGA0->PGA_TRIM.BIT.da_pga_vos_trim = trimData21.REG.data0.da_pga0_vos_trim; + PGA1->PGA_TRIM.BIT.da_pga_vos_trim = trimData21.REG.data0.da_pga1_vos_trim; + PGA2->PGA_TRIM.BIT.da_pga_vos_trim = trimData21.REG.data1.da_pga2_vos_trim; + HAL_CRG_IpEnableSet((void *)PGA0, IP_CLK_DISABLE); + HAL_CRG_IpEnableSet((void *)PGA1, IP_CLK_DISABLE); + HAL_CRG_IpEnableSet((void *)PGA2, IP_CLK_DISABLE); +} + +/** + * @brief ADC0 trim config. + * @param None + * @retval None + */ +static void ADC0_Trim(void) +{ + HAL_CRG_IpEnableSet((void *)ADC0, IP_CLK_ENABLE); /* Enable the clock for calibration */ + + FOTP_INFO_RGN0_NUMBER_21 trimData21; + FOTP_INFO_RGN0_NUMBER_22 trimData22; + FOTP_INFO_RGN0_NUMBER_23 trimData23; + FOTP_INFO_RGN0_NUMBER_24 trimData24; + FOTP_InfoGet(FOTP_INFO_RNG0, 21U, (void *)&trimData21.comData); /* 21 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 22U, (void *)&trimData22.comData); /* 22 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 23U, (void *)&trimData23.comData); /* 23 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 24U, (void *)&trimData24.comData); /* 24 is the number of trim data in otp */ + + ADC0->ADC_OEGE_TRIM.BIT.cfg_gain_cali_trim = trimData21.REG.data2.saradc0_gain; + ADC0->ADC_OEGE_TRIM.BIT.cfg_ofst_cali_trim = trimData21.REG.data2.saradc0_offset; + + ADC0->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_gain_trim2 = trimData22.REG.data2.saradc0_ain0_gain2; + ADC0->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_ofst_trim2 = trimData22.REG.data2.saradc0_ain0_offset2; + ADC0->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_gain_trim4 = trimData22.REG.data3.saradc0_ain0_gain4; + ADC0->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_ofst_trim4 = trimData22.REG.data3.saradc0_ain0_offset4; + ADC0->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_gain_trim8 = trimData23.REG.data0.saradc0_ain0_gain8; + ADC0->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_ofst_trim8 = trimData23.REG.data0.saradc0_ain0_offset8; + ADC0->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_gain_trim16 = trimData23.REG.data1.saradc0_ain0_gain16; + ADC0->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_ofst_trim16 = trimData23.REG.data1.saradc0_ain0_offset16; + + ADC0->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_gain_trim2 = trimData23.REG.data2.saradc0_ain1_gain2; + ADC0->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_ofst_trim2 = trimData23.REG.data2.saradc0_ain1_offset2; + ADC0->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_gain_trim4 = trimData23.REG.data3.saradc0_ain1_gain4; + ADC0->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_ofst_trim4 = trimData23.REG.data3.saradc0_ain1_offset4; + ADC0->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_gain_trim8 = trimData24.REG.data0.saradc0_ain1_gain8; + ADC0->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_ofst_trim8 = trimData24.REG.data0.saradc0_ain1_offset8; + ADC0->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_gain_trim16 = trimData24.REG.data1.saradc0_ain1_gain16; + ADC0->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_ofst_trim16 = trimData24.REG.data1.saradc0_ain1_offset16; + + HAL_CRG_IpEnableSet((void *)ADC0, IP_CLK_DISABLE); /* The clock is disabled after calibration */ +} + +/** + * @brief ADC1 trim config. + * @param None + * @retval None + */ +static void ADC1_Trim(void) +{ + HAL_CRG_IpEnableSet((void *)ADC1, IP_CLK_ENABLE); /* Enable the clock for calibration */ + + FOTP_INFO_RGN0_NUMBER_21 trimData21; + FOTP_INFO_RGN0_NUMBER_24 trimData24; + FOTP_INFO_RGN0_NUMBER_25 trimData25; + FOTP_INFO_RGN0_NUMBER_26 trimData26; + FOTP_InfoGet(FOTP_INFO_RNG0, 21U, (void *)&trimData21.comData); /* 21 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 24U, (void *)&trimData24.comData); /* 24 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 25U, (void *)&trimData25.comData); /* 25 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 26U, (void *)&trimData26.comData); /* 26 is the number of trim data in otp */ + + ADC1->ADC_OEGE_TRIM.BIT.cfg_gain_cali_trim = trimData21.REG.data3.saradc1_gain; + ADC1->ADC_OEGE_TRIM.BIT.cfg_ofst_cali_trim = trimData21.REG.data3.saradc1_offset; + + ADC1->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_gain_trim2 = trimData24.REG.data2.saradc1_ain0_gain2; + ADC1->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_ofst_trim2 = trimData24.REG.data2.saradc1_ain0_offset2; + ADC1->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_gain_trim4 = trimData24.REG.data3.saradc1_ain0_gain4; + ADC1->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_ofst_trim4 = trimData24.REG.data3.saradc1_ain0_offset4; + ADC1->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_gain_trim8 = trimData25.REG.data0.saradc1_ain0_gain8; + ADC1->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_ofst_trim8 = trimData25.REG.data0.saradc1_ain0_offset8; + ADC1->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_gain_trim16 = trimData25.REG.data1.saradc1_ain0_gain16; + ADC1->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_ofst_trim16 = trimData25.REG.data1.saradc1_ain0_offset16; + + ADC1->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_gain_trim2 = trimData25.REG.data2.saradc1_ain1_gain2; + ADC1->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_ofst_trim2 = trimData25.REG.data2.saradc1_ain1_offset2; + ADC1->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_gain_trim4 = trimData25.REG.data3.saradc1_ain1_gain4; + ADC1->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_ofst_trim4 = trimData25.REG.data3.saradc1_ain1_offset4; + ADC1->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_gain_trim8 = trimData26.REG.data0.saradc1_ain1_gain8; + ADC1->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_ofst_trim8 = trimData26.REG.data0.saradc1_ain1_offset8; + ADC1->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_gain_trim16 = trimData26.REG.data1.saradc1_ain1_gain16; + ADC1->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_ofst_trim16 = trimData26.REG.data1.saradc1_ain1_offset16; + + HAL_CRG_IpEnableSet((void *)ADC1, IP_CLK_DISABLE); /* The clock is disabled after calibration */ +} + +/** + * @brief ADC2 trim config. + * @param None + * @retval None + */ +static void ADC2_Trim(void) +{ + HAL_CRG_IpEnableSet((void *)ADC2, IP_CLK_ENABLE); /* Enable the clock for calibration */ + + FOTP_INFO_RGN0_NUMBER_22 trimData22; + FOTP_INFO_RGN0_NUMBER_26 trimData26; + FOTP_INFO_RGN0_NUMBER_27 trimData27; + FOTP_INFO_RGN0_NUMBER_28 trimData28; + FOTP_InfoGet(FOTP_INFO_RNG0, 22U, (void *)&trimData22.comData); /* 22 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 26U, (void *)&trimData26.comData); /* 26 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 27U, (void *)&trimData27.comData); /* 27 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 28U, (void *)&trimData28.comData); /* 28 is the number of trim data in otp */ + + ADC2->ADC_OEGE_TRIM.BIT.cfg_gain_cali_trim = trimData22.REG.data0.saradc2_gain; + ADC2->ADC_OEGE_TRIM.BIT.cfg_ofst_cali_trim = trimData22.REG.data0.saradc2_offset; + + ADC2->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_gain_trim2 = trimData26.REG.data2.saradc2_ain0_gain2; + ADC2->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_ofst_trim2 = trimData26.REG.data2.saradc2_ain0_offset2; + ADC2->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_gain_trim4 = trimData26.REG.data3.saradc2_ain0_gain4; + ADC2->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_ofst_trim4 = trimData26.REG.data3.saradc2_ain0_offset4; + ADC2->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_gain_trim8 = trimData27.REG.data0.saradc2_ain0_gain8; + ADC2->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_ofst_trim8 = trimData27.REG.data0.saradc2_ain0_offset8; + ADC2->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_gain_trim16 = trimData27.REG.data1.saradc2_ain0_gain16; + ADC2->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_ofst_trim16 = trimData27.REG.data1.saradc2_ain0_offset16; + + ADC2->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_gain_trim2 = trimData27.REG.data2.saradc2_ain1_gain2; + ADC2->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_ofst_trim2 = trimData27.REG.data2.saradc2_ain1_offset2; + ADC2->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_gain_trim4 = trimData27.REG.data3.saradc2_ain1_gain4; + ADC2->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_ofst_trim4 = trimData27.REG.data3.saradc2_ain1_offset4; + ADC2->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_gain_trim8 = trimData28.REG.data0.saradc2_ain1_gain8; + ADC2->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_ofst_trim8 = trimData28.REG.data0.saradc2_ain1_offset8; + ADC2->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_gain_trim16 = trimData28.REG.data1.saradc2_ain1_gain16; + ADC2->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_ofst_trim16 = trimData28.REG.data1.saradc2_ain1_offset16; + + HAL_CRG_IpEnableSet((void *)ADC2, IP_CLK_DISABLE); /* The clock is disabled after calibration */ +} + +/** + * @brief Analog module trim. + * @param None + * @retval None + */ +static void CHIP_AnalogTrim(void) +{ + VREF_Trim(); /* VREF trim config */ + PGA_Trim(); /* PGA trim config */ + TSENSOR_Trim(); /* TSENSOR trim config */ + ADC0_Trim(); /* ADC0 trim config */ + ADC1_Trim(); /* ADC1 trim config */ + ADC2_Trim(); /* ADC2 trim config */ +} + +/** + * @brief Parameter calibration entry of the analog module. + * @param None + * @retval None + */ +void ANATRIM_Entry(void) +{ + if (CHIP_GetInfo() == false) { /* If the chip information is incorrect, calibration is not performed */ + return; + } + CHIP_AnalogTrim(); /* Analog trim config */ +} +#endif \ No newline at end of file diff --git a/src/chip/3065p/chipinit/anatrim/anatrim.h b/src/chip/3065p/chipinit/anatrim/anatrim.h new file mode 100644 index 0000000000000000000000000000000000000000..0cc6fa83494b25402535e727f97ad9d25ecba4fa --- /dev/null +++ b/src/chip/3065p/chipinit/anatrim/anatrim.h @@ -0,0 +1,39 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file anatrim.h + * @author MCU Driver Team + * @brief Chip Init modlue. + * @details Calibration of analog module parameters. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_ANATRIM_H +#define McuMagicTag_ANATRIM_H +#include "baseinc.h" +#ifdef FPGA +#else +#include "fotp_info_read.h" +#include "anavref.h" +#include "tsensor_ip.h" +#include "adc_ip.h" +#include "pga_ip.h" +#include "crg.h" +void ANATRIM_Entry(void); +#endif +extern float g_tsensorGain; +#endif /* McuMagicTag_ANATRIM_H */ \ No newline at end of file diff --git a/src/chip/3065p/chipinit/anavrefinit/anavrefinit.c b/src/chip/3065p/chipinit/anavrefinit/anavrefinit.c new file mode 100644 index 0000000000000000000000000000000000000000..7023ec0b6650b8ab99f0bfc098db7b60b3777be9 --- /dev/null +++ b/src/chip/3065p/chipinit/anavrefinit/anavrefinit.c @@ -0,0 +1,39 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file anavrefinit.c + * @author MCU Driver Team + * @brief anavref init modlue. + * @details anavref initialization function during startup + */ + +#include "anavrefinit.h" + +/** + * @brief Set Crg Core clock select + * @param None + * @retval None + */ +void ANAVREF_Init(void) +{ + HAL_CRG_IpEnableSet(VREF_BASE, IP_CLK_ENABLE); + VREF->VREF_CTRL1.BIT.da_ref_temp_trim_enh = 0x1; + VREF->VREF_CTRL0.BIT.da_ref_enh = BASE_CFG_ENABLE; + BASE_FUNC_DELAY_US(200); /* delay 200us */ + VREF->VREF_CTRL1.BIT.da_ref_chop_enh = BASE_CFG_ENABLE; + BASE_FUNC_DELAY_US(40); /* delay 40us */ +} \ No newline at end of file diff --git a/src/chip/3065p/chipinit/anavrefinit/anavrefinit.h b/src/chip/3065p/chipinit/anavrefinit/anavrefinit.h new file mode 100644 index 0000000000000000000000000000000000000000..8272b76d57b77698e5870d082a6507ffdb148c21 --- /dev/null +++ b/src/chip/3065p/chipinit/anavrefinit/anavrefinit.h @@ -0,0 +1,32 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file anavrefint.h + * @author MCU Driver Team + * @brief anavref init modlue. + * @details anavref initialization function during startup + */ + +#ifndef McuMagicTag_ANAVREF_H +#define McuMagicTag_ANAVREF_H + +#include "baseinc.h" +#include "crg.h" +#include "anavref.h" + +void ANAVREF_Init(void); +#endif \ No newline at end of file diff --git a/src/chip/3065p/chipinit/chipinit.c b/src/chip/3065p/chipinit/chipinit.c new file mode 100644 index 0000000000000000000000000000000000000000..8f5eec8edd90405a34057755d5b3a44f2308f10b --- /dev/null +++ b/src/chip/3065p/chipinit/chipinit.c @@ -0,0 +1,83 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file chipint.c + * @author MCU Driver Team + * @brief Chip Init modlue. + * @details Declare a function that needs to be executed as soon as the C + * runtime environment is ready + */ +#include "chipinc.h" +#include "crginit.h" +#include "systickinit.h" +#include "flashinit.h" +#include "crg.h" +#include "interrupt.h" +#ifdef NOS_TASK_SUPPORT +#include "nosinit.h" +#endif +#include "chipinit.h" + +#include "anavrefinit.h" +#ifndef FPGA /* Delete the compilation macro after the ASIC to release the header file. */ +#include "anatrim.h" +#endif + +/** + * @brief Chip Init Fail Process, deadloop if Chip Init fail + * @param None + * @retval None + */ +static inline void Chip_InitFail(void) +{ + while (1) { + ; + } +} + +/** + * @brief Chip Init + * @param None + * @retval None + */ +void Chip_Init(void) +{ + CRG_CoreClkSelect coreClkSelect; + /* Config CRG */ + if (CRG_Config(&coreClkSelect) != BASE_STATUS_OK) { + Chip_InitFail(); + } + + /* Config FLASH Clock */ + FLASH_ClockConfig(coreClkSelect); + IRQ_Init(); + SYSTICK_Init(); + /* Set CoreClock Select after FLASH Config Done */ + CRG_SetCoreClockSelect(coreClkSelect); +#ifdef NOS_TASK_SUPPORT + SYSTICK_IRQ_Enable(); +#endif + ANAVREF_Init(); +#ifndef FPGA /* Delete the compilation macro after the ASIC to release the header file. */ + ANATRIM_Entry(); +#endif + +#ifdef NOS_TASK_SUPPORT + NOS_Init(); +#endif + /* User Add Code Here */ +} \ No newline at end of file diff --git a/src/chip/3065p/chipinit/chipinit.h b/src/chip/3065p/chipinit/chipinit.h new file mode 100644 index 0000000000000000000000000000000000000000..9b3a43298d22e663267d4a1c17104d5e594755c3 --- /dev/null +++ b/src/chip/3065p/chipinit/chipinit.h @@ -0,0 +1,31 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file chipinit.h + * @author MCU Driver Team + * @brief Chip Init modlue. + * @details Declare a function that needs to be executed as soon as the C + * runtime environment is ready + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_CHIPINIT_H +#define McuMagicTag_CHIPINIT_H + +void Chip_Init(void); + +#endif /* McuMagicTag_CHIPINIT_H */ \ No newline at end of file diff --git a/src/chip/3065p/chipinit/crginit/crginit.c b/src/chip/3065p/chipinit/crginit/crginit.c new file mode 100644 index 0000000000000000000000000000000000000000..390e02bab828179153f88df93974d085201ec74d --- /dev/null +++ b/src/chip/3065p/chipinit/crginit/crginit.c @@ -0,0 +1,65 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file crginit.c + * @author MCU Driver Team + * @brief crg init modlue. + * @details crg initialization function during startup + */ +#include "crginit.h" + +/** + * @brief CRG Config + * @param coreClkSelect OutPut core clock select value + * @retval None + */ +__weak BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + BASE_FUNC_ASSERT_PARAM(coreClkSelect != NULL); + + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllFbDiv = 0x30; /* PLL loop divider ratio = 0x30 */ + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; /* ASIC need change as CRG_CORE_CLK_SELECT_PLL */ + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; /* Set the 1MHz clock select. */ + crg.handleEx.clk1MDiv = 0x18; /* 0x18 : ensure that the 1MHz clock frequency is 1 MHz. */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +/** + * @brief Set Crg Core clock select + * @param coreClkSelect Input core clock select value + * @retval None + */ +void CRG_SetCoreClockSelect(CRG_CoreClkSelect coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.coreClkSelect = coreClkSelect; + if (crg.coreClkSelect == CRG_CORE_CLK_SELECT_TCXO) { /* If an external crystal oscillator is selected. */ + BASE_FUNC_DELAY_MS(10); /* 10: delay 10ms, wait clokc stable. */ + } + HAL_CRG_SetCoreClockSelect(&crg); +} \ No newline at end of file diff --git a/src/chip/3065p/chipinit/crginit/crginit.h b/src/chip/3065p/chipinit/crginit/crginit.h new file mode 100644 index 0000000000000000000000000000000000000000..0f064c5ce9601a8a69cb43b0e983f8a56657e8f9 --- /dev/null +++ b/src/chip/3065p/chipinit/crginit/crginit.h @@ -0,0 +1,33 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file crginit.h + * @author MCU Driver Team + * @brief crg init modlue. + * @details crg initialization function during startup + */ + +#ifndef McuMagicTag_CRGINIT_H +#define McuMagicTag_CRGINIT_H + +#include "baseinc.h" +#include "crg.h" + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void CRG_SetCoreClockSelect(CRG_CoreClkSelect coreClkSelect); + +#endif \ No newline at end of file diff --git a/src/chip/3065p/chipinit/flashinit/flashinit.c b/src/chip/3065p/chipinit/flashinit/flashinit.c new file mode 100644 index 0000000000000000000000000000000000000000..99db1d2ac873cde873ac35c95542a7ce2ab9e9c8 --- /dev/null +++ b/src/chip/3065p/chipinit/flashinit/flashinit.c @@ -0,0 +1,114 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flashinit.c + * @author MCU Driver Team + * @brief flash init modlue. + * @details flash initialization function during startup + */ +#include "chipinit.h" +#include "crg.h" +#include "flash_ip.h" +#include "flashinit.h" + +#define CHIP_MAX_FREQ (200 * 1000 * 1000) /* 200MHz. */ +#define FLASH_BASE_FREQ (375 * 100 * 1000) /* 37.5MHz. */ +#define FLASH_MAX_DIV 5 + +/** + * @brief Get the Rounding up value + * @param frequence frequnce + * @param div Output Divison + * @retval None + */ +static void SetFlashDiv(unsigned int frequency, unsigned int *nreadDiv) +{ + unsigned int div; + unsigned int freq = frequency; + /* Get frequency divider of flash. */ + if (freq < FLASH_BASE_FREQ) { + freq = FLASH_BASE_FREQ; + } + if (freq > CHIP_MAX_FREQ) { + freq = CHIP_MAX_FREQ; + } + + /* Get the flash frequency division based on the frequency. */ + if ((freq % FLASH_BASE_FREQ) == 0) { + div = freq / FLASH_BASE_FREQ; + } else { + div = (freq / FLASH_BASE_FREQ) + 1; + } + + /* Ensure the flash frequency division is valid. */ + if (div > FLASH_MAX_DIV) { + div = FLASH_MAX_DIV; + } + *nreadDiv = div; +} + +/** + * @brief Get the Rounding up value + * @param coreClkSelect Core Clock select + * @retval Frequency of Flash + */ +static unsigned int GetFlashFreq(CRG_CoreClkSelect coreClkSelect) +{ + unsigned int hclk; + /* Get frequency of flash. */ + switch (coreClkSelect) { + case CRG_CORE_CLK_SELECT_HOSC: + hclk = HOSC_FREQ; + break; + case CRG_CORE_CLK_SELECT_TCXO: + hclk = XTRAIL_FREQ; + break; + case CRG_CORE_CLK_SELECT_PLL: + hclk = HAL_CRG_GetPllFreq(); + break; + default: + hclk = LOSC_FREQ; + break; + } + return hclk; +} + +/** + * @brief Set flash clock frequence base on hclk + * @param coreClkSelect core clock select + * @retval None + */ +void FLASH_ClockConfig(CRG_CoreClkSelect coreClkSelect) +{ + EFC_RegStruct *efc = EFC; + EFLASH_CLK_CFG_REG cfg; + unsigned int hclk; + unsigned int nreadDiv; + + /* Step 1: Set nread_div */ + hclk = GetFlashFreq(coreClkSelect); + cfg.reg = efc->EFLASH_CLK_CFG.reg; + SetFlashDiv(hclk, &nreadDiv); + cfg.BIT.nread_div = nreadDiv; + cfg.BIT.busclk_sw_req = BASE_CFG_SET; + efc->EFLASH_CLK_CFG.reg = cfg.reg; + + /* Step 2: Wait Busclk_sw_req */ + while (efc->EFLASH_CLK_CFG.BIT.busclk_sw_req == BASE_CFG_SET) { + ; + } +} \ No newline at end of file diff --git a/src/chip/3065p/chipinit/flashinit/flashinit.h b/src/chip/3065p/chipinit/flashinit/flashinit.h new file mode 100644 index 0000000000000000000000000000000000000000..d70635b0b69d8287fa91f5babb09167ba9ed5964 --- /dev/null +++ b/src/chip/3065p/chipinit/flashinit/flashinit.h @@ -0,0 +1,32 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flashinit.h + * @author MCU Driver Team + * @brief flash init modlue. + * @details flash initialization function during startup + */ + +#ifndef McuMagicTag_FLASHINIT_H +#define McuMagicTag_FLASHINIT_H + +#include "baseinc.h" +#include "crg.h" + +void FLASH_ClockConfig(CRG_CoreClkSelect coreClkSelect); + +#endif \ No newline at end of file diff --git a/src/chip/3065p/chipinit/nosinit/nosinit.c b/src/chip/3065p/chipinit/nosinit/nosinit.c new file mode 100644 index 0000000000000000000000000000000000000000..d6ab7811a349a80f3baa3f93110c63b5ee0daf53 --- /dev/null +++ b/src/chip/3065p/chipinit/nosinit/nosinit.c @@ -0,0 +1,74 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file nosinit.c + * @author MCU Driver Team + * @brief nos init module. + * @details nos initialization function during startup + */ +#include "feature.h" +#ifdef NOS_TASK_SUPPORT +#include "nos_task.h" +#include "nosinit.h" +#include "systick.h" +#include "crg.h" + +#ifndef CFG_NOS_MAINTASK_STACKSIZE +#define CFG_NOS_MAINTASK_STACKSIZE 0x500 +#endif +#define CYCCLE_PERUS 200 +// User define the stack size of main task by CFG_NOS_MAINTASK_STACKSIZE +unsigned char __attribute__((aligned(16))) g_taskMainStackSpace[CFG_NOS_MAINTASK_STACKSIZE]; + +static unsigned int g_nosSysFreq; +// Get tick in real time +static unsigned long long NOS_GetTick(void) +{ + unsigned int cycle, cycleh; + asm volatile("csrr %0, cycle" : "=r"(cycle)); + asm volatile("csrr %0, cycleh" : "=r"(cycleh)); + unsigned long long longCycle = (unsigned long long)cycle + (unsigned long long)cycleh * 0xFFFFFFFF; + // tick = cycle/freq + return longCycle / g_nosSysFreq; +} + +/** + * @brief Init the Nos Task Schedule + * @param None + * @retval None + */ +void NOS_Init(void) +{ + unsigned int taskId; + NOS_SysConfig config = {}; + g_nosSysFreq = SYSTICK_GetCRGHZ() / CRG_FREQ_1MHz * CFG_SYSTICK_TICKINTERVAL_US; + config.usecPerTick = SYSTICK_GetTickInterval(); /* Set the tick size of Nos task schedule */ + config.getTickFunc = NOS_GetTick; + config.cyclePerUs = CYCCLE_PERUS; + NOS_TaskInit(&config); + NOS_TaskInitParam param = {}; + param.name = "mainTask"; + param.taskEntry = (NOS_TaskEntryFunc)main; /* Set the entry function by user define */ + param.param = 0; + param.priority = NOS_TASK_PRIORITY_LOWEST; + param.stackAddr = (unsigned int)g_taskMainStackSpace; + param.stackSize = sizeof(g_taskMainStackSpace); + param.privateData = 0; + (void)NOS_TaskCreate(¶m, &taskId); + (void)NOS_StartScheduler(); /* Nos task schedule start */ +} +#endif \ No newline at end of file diff --git a/src/chip/3065p/chipinit/nosinit/nosinit.h b/src/chip/3065p/chipinit/nosinit/nosinit.h new file mode 100644 index 0000000000000000000000000000000000000000..18025762238b8dd8d1eb8abe877264b07b05bb40 --- /dev/null +++ b/src/chip/3065p/chipinit/nosinit/nosinit.h @@ -0,0 +1,35 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file nosinit.h + * @author MCU Driver Team + * @brief nos init module. + * @details nos initialization function during startup + */ + +#ifndef NOS_INIT_H +#define NOS_INIT_H + +#include "feature.h" + +#ifdef NOS_TASK_SUPPORT +extern int main(void); +extern void OsHwiDispatchTick(void); +void NOS_Init(void); +#endif + +#endif \ No newline at end of file diff --git a/src/chip/3065p/chipinit/systickinit/systickinit.c b/src/chip/3065p/chipinit/systickinit/systickinit.c new file mode 100644 index 0000000000000000000000000000000000000000..1d81c25ebb5a33a7edb04258d615267b8948221b --- /dev/null +++ b/src/chip/3065p/chipinit/systickinit/systickinit.c @@ -0,0 +1,102 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file systickinit.c + * @author MCU Driver Team + * @brief systick init modlue. + * @details systick initialization function during startup + */ +#include "baseaddr.h" +#include "crg.h" +#include "timer.h" +#include "systick.h" +#include "systickinit.h" +#include "feature.h" +#ifdef NOS_TASK_SUPPORT +#include "interrupt.h" +#include "nosinit.h" +#endif + +TIMER_Handle g_systickHandle; +#ifdef NOS_TASK_SUPPORT +#define NOS_TickPostDispatch OsHwiDispatchTick + +static void SYSTICK_Default_Callback(void *handle) +{ + /* The default systick callback when using th nos task */ + BASE_FUNC_UNUSED(handle); + NOS_TickPostDispatch(); +} + +void SYSTICK_IRQ_Enable(void) +{ + HAL_CRG_IpEnableSet(TIMER3_BASE, IP_CLK_ENABLE); + /* Choose the config to support GetTick and Delay */ + g_systickHandle.baseAddress = TIMER3; /* use timer module */ + g_systickHandle.load = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + g_systickHandle.bgLoad = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + g_systickHandle.mode = TIMER_MODE_RUN_PERIODIC; + g_systickHandle.prescaler = TIMERPRESCALER_NO_DIV; /* frequency not divition */ + g_systickHandle.size = TIMER_SIZE_32BIT; + g_systickHandle.interruptEn = BASE_CFG_ENABLE; + HAL_TIMER_Init(&g_systickHandle); + HAL_TIMER_RegisterCallback(&g_systickHandle, TIMER_PERIOD_FIN, SYSTICK_Default_Callback); /* nos task schedule */ + IRQ_SetPriority(IRQ_TIMER3, 1); /* interrupt priority 1 */ + IRQ_Register(IRQ_TIMER3, HAL_TIMER_IrqHandler, &g_systickHandle); + IRQ_EnableN(IRQ_TIMER3); + HAL_TIMER_Start(&g_systickHandle); /* start timer module */ +} + +unsigned int SYSTICK_GetTickInterval(void) +{ + /* Get the tick interval(the number of usecond per tick) */ + return CFG_SYSTICK_TICKINTERVAL_US; +} + +#endif + +unsigned int SYSTICK_GetTimeStampUs(void) +{ + /* Get the systick timestamp(convert from the systick value) */ + return DCL_SYSTICK_GetTick() / (SYSTICK_GetCRGHZ() / CRG_FREQ_1MHz); +} + +/** + * @brief Init the systick + * @param None + * @retval None + */ +void SYSTICK_Init(void) +{ + SYSTICK->TIMER_CTRL.reg = 0; + SYSTICK->TIMER_CTRL.BIT.enable = 1; +} + +/** + * @brief Get the Systick frep(Hz) + * @param None + * @retval Clock frep of systick(Hz) + */ +unsigned int SYSTICK_GetCRGHZ(void) +{ +#ifdef NOS_TASK_SUPPORT + return HAL_CRG_GetCoreClkFreq(); +#else + /* Get the Systick IP */ + return HAL_CRG_GetIpFreq(SYSTICK_BASE); +#endif +} \ No newline at end of file diff --git a/src/chip/3065p/chipinit/systickinit/systickinit.h b/src/chip/3065p/chipinit/systickinit/systickinit.h new file mode 100644 index 0000000000000000000000000000000000000000..a7d60cdf20fcecf2dfc14b1d071bf247a20c4fd3 --- /dev/null +++ b/src/chip/3065p/chipinit/systickinit/systickinit.h @@ -0,0 +1,35 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file systickinit.h + * @author MCU Driver Team + * @brief systick init modlue. + * @details systick initialization function during startup + */ + +#ifndef McuMagicTag_SYSTICKINIT_H +#define McuMagicTag_SYSTICKINIT_H + +#include "feature.h" + +void SYSTICK_Init(void); +unsigned int SYSTICK_GetCRGHZ(void); +#ifdef NOS_TASK_SUPPORT +void SYSTICK_IRQ_Enable(void); +#endif + +#endif \ No newline at end of file diff --git a/src/chip/3065p/codecopy.json b/src/chip/3065p/codecopy.json new file mode 100644 index 0000000000000000000000000000000000000000..a656e82a75caddf5e82cf87fdab1fd02706ac3aa --- /dev/null +++ b/src/chip/3065p/codecopy.json @@ -0,0 +1,47 @@ +{ + "modules": [ + "application/user", + "build", + "chip/3065p", + "chip/target/userconfig_for_3066m.json", + "drivers/debug", + "generatecode", + "middleware/control_library", + "middleware/function_safety", + "middleware/hisilicon/libboundscheck_v1.1.16", + "middleware/thirdparty/sysroot", + "tools/uttest", + "bundle.json" + ], + + "ip_drive_file": ["acmp", "adc", "apt", "base", "can", "capm", "cfd", "cmm", "crc", "crg", + "dac", "dma", "flash", "gpio", "gpt", "i2c", "pga", "pmc", "qdm", "spi", + "timer", "tsensor", "uart", "iwdg", "iocmg", "wwdg", "smbus"], + "acmp" : ["common", "acmp_v2", "testcase_v2"], + "adc" : ["common", "adc_v1", "testcase_v1"], + "apt" : ["common", "apt_v2", "testcase_v1"], + "base" : ["common", "base_v0"], + "can" : ["common", "can_v0", "testcase_v0"], + "capm" : ["common", "capm_v1", "testcase_v1"], + "cfd" : ["common", "cfd_v0", "testcase_v0"], + "cmm" : ["common", "cmm_v2", "testcase_v2"], + "crc" : ["common", "crc_v1", "testcase_v1"], + "crg" : ["common", "crg_v3", "testcase_v3"], + "dac" : ["common", "dac_v1", "testcase_v1"], + "dma" : ["common", "dma_v1", "testcase_v1"], + "flash" : ["common", "flash_v3", "testcase_v1"], + "gpio" : ["common", "gpio_v0", "testcase_v0"], + "gpt" : ["common_v1", "gpt_v1", "testcase_v1"], + "i2c" : ["common", "i2c_v3", "testcase_v1"], + "pga" : ["common", "pga_v2", "testcase_v2"], + "pmc" : ["common", "pmc_v3", "testcase_v3"], + "qdm" : ["common", "qdm_v0", "testcase_v0"], + "spi" : ["common", "spi_v3", "testcase_v3"], + "timer" : ["common", "timer_v1", "testcase_v1"], + "tsensor" : ["common", "tsensor_v1", "testcase_v1"], + "uart" : ["common", "uart_v3", "testcase_v3"], + "iwdg" : ["common", "iwdg_v2", "testcase_v2"], + "iocmg" : ["common", "iocmg_v3", "testcase_v3"], + "wwdg" : ["common", "wwdg_v2", "testcase_v2"], + "smbus" : ["common", "smbus_v0", "testcase_v0"] +} \ No newline at end of file diff --git a/src/chip/3065p/flash.lds b/src/chip/3065p/flash.lds new file mode 100644 index 0000000000000000000000000000000000000000..94ca630817cca0b9932e0ade2abfe25691340580 --- /dev/null +++ b/src/chip/3065p/flash.lds @@ -0,0 +1,190 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flash.lds + * @author MCU Application Driver Team + * @brief RISCV flash link script + */ + +OUTPUT_ARCH( "riscv" ) +ENTRY(_start) + +SRAM_START = 0x2000000; +SRAM_END = 0x2000000 + 64K; + +RAM_DIAGNOSE_BUF_START = SRAM_START; +RAM_DIAGNOSE_BUF_SIZE = 0x20; + +RAM_CODE_START = 0x2000000 + RAM_DIAGNOSE_BUF_SIZE; +RAM_CODE_SIZE = 0; + +RAM_RESERVE_DATA_START = RAM_DIAGNOSE_BUF_START + RAM_DIAGNOSE_BUF_SIZE + RAM_CODE_SIZE; +RAM_RESERVE_DATA_SIZE = 0; + +STACK_SRAM_BOUND_SIZE = 0x10; + +RAM_START = RAM_RESERVE_DATA_START + RAM_RESERVE_DATA_SIZE; +RAM_SIZE = 0x2800 - RAM_CODE_SIZE - RAM_RESERVE_DATA_SIZE - RAM_DIAGNOSE_BUF_SIZE - STACK_SRAM_BOUND_SIZE; +RAM_END = SRAM_END; + +STACK_SRAM_BOUND_START = RAM_START + RAM_SIZE; +STACK_START = STACK_SRAM_BOUND_START + STACK_SRAM_BOUND_SIZE; +STACK_SIZE = 6k - 1k; +NMI_STACK_SIZE = 1k; +INIT_STACK_SIZE = 1k; + +FLASH_START = 0x3000000; +FLASH_SIZE = 0x80000 - 4; + +MEMORY +{ + /* ram for diagnose buf */ + RAM_DIAGNOSE_BUF(rw) : ORIGIN = RAM_DIAGNOSE_BUF_START, LENGTH = RAM_DIAGNOSE_BUF_SIZE + + /* ram for code */ + RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE + + /* ram for reserved data */ + RAM_RESERVE_DATA(rw) : ORIGIN = RAM_RESERVE_DATA_START, LENGTH = RAM_RESERVE_DATA_SIZE + + /* ram for common bss and data */ + RAM_DATA(xrw) : ORIGIN = RAM_START, LENGTH = RAM_SIZE + + /* ram for common bss and data */ + STACK_SRAM_BOUND(xrw) : ORIGIN = STACK_SRAM_BOUND_START, LENGTH = STACK_SRAM_BOUND_SIZE + + /* ram for stack */ + RAM_STACK(xrw) : ORIGIN = STACK_START, LENGTH = STACK_SIZE + NMI_STACK_SIZE + + /*magic number */ + FLASH_MAGIC(rw) : ORIGIN = FLASH_START, LENGTH = 4 + + /* ram for target */ + FLASH_CODE(rx) : ORIGIN = FLASH_START + 4, LENGTH = FLASH_SIZE +} + +SECTIONS +{ + /* The startup code goes first into FLASH */ + .data.magic : ALIGN(4) + { + KEEP(*(.data.magic)) + } > FLASH_MAGIC + + /* The startup code goes first into FLASH_CODE */ + .text.entry : ALIGN(4) + { + KEEP(*(.text.entry)) + } > FLASH_CODE + + /* Stack in SRAM at Highest addresses */ + .stacks (NOLOAD) : + { + . = ALIGN(4); + __SYSTEM_STACK_BEGIN__ = ORIGIN(RAM_STACK); + KEEP(*(.stacks)) + __SYSTEM_STACK_END__ = ORIGIN(RAM_STACK) + STACK_SIZE; + . = ALIGN(0x20); + __INTERRUPT_STACK_BEGIN__ = __SYSTEM_STACK_END__; + . = ALIGN(0x20); + __NMI_STACK_BEGIN__ = __SYSTEM_STACK_END__; + __nmi_stack_bottom = .; + . += NMI_STACK_SIZE; + __nmi_stack_top = .; + } > RAM_STACK + __stack_top = __SYSTEM_STACK_END__; + __init_stack_top = __SYSTEM_STACK_BEGIN__ + INIT_STACK_SIZE; + __irq_stack_top = __SYSTEM_STACK_END__; + + .text.sram : ALIGN(4) + { + __sram_code_load_addr = LOADADDR(.text.sram); + __sram_code_start_addr = .; + *(.text.sram) + . = ALIGN(4); + __sram_code_end_addr = .; + } > RAM_CODE AT > FLASH_CODE + + .reserved.data : ALIGN(4) + { + __reserved_code_load_addr = LOADADDR(.reserved.data); + __reserved_code_start_addr = .; + *(.reserved.data*) + . = ALIGN(4); + __reserved_code_end_addr = .; + } > RAM_RESERVE_DATA AT > FLASH_CODE + + .text : ALIGN(4) + { + __start_addr = .; + *(.text*) + *(.ram.text*) + . = ALIGN(4); + __rodata_start = .; + *(.rodata*) + . = ALIGN(4); + __rodata_end = .; + *(.got*) + __text_end = .; + } > FLASH_CODE + + /* data section */ + .data : ALIGN(4) + { + __data_load = LOADADDR(.data); + __data_start = .; + *(.data*) + *(.sdata*) + . = ALIGN(4); + __data_end = .; + } > RAM_DATA AT> FLASH_CODE + __data_size = __data_end - __data_start; + + .stackBound : ALIGN(4) + { + __stack_sram_bound_data_load = LOADADDR(.stackBound); + __stack_sram_bound_data_start = .; + *(STACK_SRAM_BOUND) + . = ALIGN(4); + __stack_sram_bound_data_end = .; + } > STACK_SRAM_BOUND AT> FLASH_CODE + + .ramBuf : ALIGN(4) + { + *(RAM_DIAGNOSE_BUF) + } > RAM_DIAGNOSE_BUF AT> FLASH_CODE + + .checkSum : ALIGN(4) + { + __checksum_addr = .; + *(CHECKSUM) + __checksum_end = .; + } > FLASH_CODE + + /* bss section */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_begin__ = .; + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM_DATA + __bss_size__ = __bss_end__ - __bss_begin__; + __global_pointer$ = __data_start + ((__data_size + __bss_size__) / 2); +} \ No newline at end of file diff --git a/src/chip/3065p/flashdefault.lds b/src/chip/3065p/flashdefault.lds new file mode 100644 index 0000000000000000000000000000000000000000..f5f6590113d6b15efd4e9edf363b0c24c15f4d11 --- /dev/null +++ b/src/chip/3065p/flashdefault.lds @@ -0,0 +1,85 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flash.lds + * @author MCU Application Driver Team + * @brief RISCV flash link script + */ + +OUTPUT_ARCH( "riscv" ) + +SRAM_START = 0x2000000; +SRAM_END = 0x2000000 + 64K; + +RAM_CODE_START = 0x2000000; +RAM_CODE_SIZE = 0; + +RAM_START = SRAM_START; +RAM_END = SRAM_END; +RAM_SIZE = 65536; + +FLASH_START = 0x3000000; +FLASH_SIZE = 0x80000; + +MEMORY +{ + /* ram for code */ + RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE + /* ram for common bss and data */ + RAM_DATA(xrw) : ORIGIN = RAM_START + RAM_CODE_SIZE, LENGTH = RAM_SIZE + /* ram for target */ + FLASH_CODE(rx) : ORIGIN = FLASH_START, LENGTH = FLASH_SIZE +} + +SECTIONS +{ + .text : ALIGN(4) + { + __start_addr = .; + *(.text*) + *(.ram.text*) + . = ALIGN(4); + __rodata_start = .; + *(.rodata*) + . = ALIGN(4); + __rodata_end = .; + *(.got*) + __text_end = .; + } > FLASH_CODE + + /* data section */ + .data : ALIGN(4) + { + __data_load = LOADADDR(.data); + __data_start = .; + *(.data*) + *(.sdata*) + . = ALIGN(4); + __data_end = .; + } > RAM_DATA AT> FLASH_CODE + + /* bss section */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_begin__ = .; + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM_DATA +} \ No newline at end of file diff --git a/src/chip/3065p/fotp/fotp.h b/src/chip/3065p/fotp/fotp.h new file mode 100644 index 0000000000000000000000000000000000000000..a5bb5b732513be7b2657e8a238ab8859c00ab7fc --- /dev/null +++ b/src/chip/3065p/fotp/fotp.h @@ -0,0 +1,826 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file fotp.h + * @author MCU Driver Team + * @brief This file provides firmware functions to manage the following + * functionalities of the system control register. + * + Register Struct of FOTP RNG0 and FOTP RNG1 + */ +#ifndef McuMagicTag_FOTP_H +#define McuMagicTag_FOTP_H + +#define FOTP_INFO_REG_MAX_ID 251 /* Max index of fotp info rng 0 and rng 1 and rng 2 and rng 3 */ + +typedef enum { + FOTP_INFO_RNG0, + FOTP_INFO_RNG1, + FOTP_INFO_RNG2, + FOTP_INFO_RNG3, + FOTP_INFO_MAXTYPE, +} FOTP_InfoRngType; + +typedef struct { + unsigned int data[4]; +} FOTP_CommonData; + +/* + * FOTP INFO RNG0 + */ +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int DIEID_STD_VER : 3; + unsigned int MR_FLAG : 1; + unsigned int LOTID0 : 6; + unsigned int LOTID1 : 6; + unsigned int LOTID2 : 6; + unsigned int LOTID3 : 6; + unsigned int LOTID4 : 4; + } data0; + struct { + unsigned int LOTID4 : 2; + unsigned int LOTID5 : 6; + unsigned int WAFERID : 5; + unsigned int DIEX : 8; + unsigned int DIEY : 8; + unsigned int PASSFLAG_RT_CP : 1; + unsigned int reserved : 2; + } data1; + unsigned int reserved[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_0; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int YEAR : 6; + unsigned int MON : 4; + unsigned int DAY : 5; + unsigned int HOUR : 5; + unsigned int MIN : 6; + unsigned int SEC : 6; + } data0; + struct { + unsigned int LOSC_CTRIM : 9; + unsigned int HOSC_CTRM : 10; + unsigned int reserved : 1; + unsigned int PMU_BG_TRIM : 5; + unsigned int reserved1 : 1; + unsigned int PMU_CLDO_TRIM : 5; + unsigned int reserved2 : 1; + } data1; + unsigned int reserved[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_1; + +typedef union { + FOTP_CommonData comData; + struct { + unsigned int chip_id; + unsigned int reserved; + struct { + unsigned int version_id : 8; + unsigned int reserved : 24; + } data2; + unsigned int customer_id; + } REG; +} FOTP_INFO_RGN0_NUMBER_2; + +typedef union { + FOTP_CommonData comData; + struct { + unsigned int fotp_empty_flag; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_4; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn0_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn4_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN0_NUMBER_5; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int bootrom_debug_enable : 8; + unsigned int reserved : 24; + } data0; + struct { + unsigned int bootrom_hide_disable : 1; + unsigned int reserved : 31; + } data1; + struct { + unsigned int ef_bist_intf_enable : 1; + unsigned int reserved : 31; + } data2; + struct { + unsigned int dft_jtag_enable : 1; + unsigned int reserved : 31; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_6; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int cpu_fpu_enable : 1; + unsigned int reserved : 7; + unsigned int sysram_size_cfg : 3; + unsigned int reserved1 : 5; + unsigned int eflash_size_cfg : 10; + unsigned int reserved2 : 5; + unsigned int cpu_maxfreq_cfg : 1; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_7; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int adc0_enable : 1; + unsigned int adc1_enable : 1; + unsigned int adc2_enable : 1; + unsigned int dac0_enable : 1; + unsigned int dac1_enable : 1; + unsigned int dac2_enable : 1; + unsigned int pga0_enable : 1; + unsigned int pga1_enable : 1; + unsigned int pga2_enable : 1; + unsigned int acmp0_enable : 1; + unsigned int acmp1_enable : 1; + unsigned int acmp2_enable : 1; + unsigned int reserved : 20; + } data0; + unsigned int reserved0; + struct { + unsigned int apt0_hr_enable : 1; + unsigned int apt1_hr_enable : 1; + unsigned int apt2_hr_enable : 1; + unsigned int apt3_hr_enable : 1; + unsigned int apt4_hr_enable : 1; + unsigned int apt5_hr_enable : 1; + unsigned int apt6_hr_enable : 1; + unsigned int apt7_hr_enable : 1; + unsigned int apt8_hr_enable : 1; + unsigned int reserved : 23; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN0_NUMBER_8; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int apt0_enable : 1; + unsigned int apt1_enable : 1; + unsigned int apt2_enable : 1; + unsigned int apt3_enable : 1; + unsigned int apt4_enable : 1; + unsigned int apt5_enable : 1; + unsigned int apt6_enable : 1; + unsigned int apt7_enable : 1; + unsigned int apt8_enable : 1; + unsigned int reserved : 7; + unsigned int can0_enable : 1; + unsigned int can1_enable : 1; + unsigned int reserved1 : 14; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_9; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int IDDQ_DVDD : 8; + unsigned int IDDQ_AVDD : 8; + unsigned int reserved : 16; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_10; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int hpm_core : 16; + unsigned int reserved : 16; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_11; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int PASSFLAG_CP_RT : 1; + unsigned int reserved : 31; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_13; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int PASSFLAG_FT_HT : 1; + unsigned int reserved : 31; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_16; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int DVS_FLOW_FLAG : 1; + unsigned int DVS_PASS_FLAG : 1; + unsigned int reserved : 30; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_17; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int FAILFLAG_ALL : 2; + unsigned int reserved : 30; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_18; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int PASSFLAG_FT_RT : 1; + unsigned int reserved : 31; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_19; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int da_ref_vbg_trim : 8; + unsigned int da_ref_vref_trim : 8; + unsigned int da_iref_trim : 8; + unsigned int da_ref_temp_trim0 : 8; + } data0; + struct { + unsigned int da_ref_temp_trim1 : 8; + unsigned int da_ref_temp_trim2 : 8; + unsigned int da_ref_temp_trim3 : 8; + unsigned int da_ref_vptat_trim : 8; + } data1; + struct { + unsigned int da_ref_buf_trim : 8; + unsigned int reserved : 8; + unsigned int reserved1 : 8; + unsigned int reserved2 : 8; + } data2; + struct { + unsigned int reserved : 8; + unsigned int da_ana_top_trim0 : 8; + unsigned int da_ana_top_trim1 : 8; + unsigned int reserved1 : 8; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_20; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int da_pga0_vos_trim : 9; + unsigned int reserved : 7; + unsigned int da_pga1_vos_trim : 9; + unsigned int reserved1 : 7; + } data0; + struct { + unsigned int da_pga2_vos_trim : 9; + unsigned int reserved : 7; + unsigned int ts_offset : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc0_gain : 13; + unsigned int reserved : 3; + unsigned int saradc0_offset : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc1_gain : 13; + unsigned int reserved : 3; + unsigned int saradc1_offset : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_21; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc2_gain : 13; + unsigned int reserved : 3; + unsigned int saradc2_offset : 12; + unsigned int reserved1 : 4; + } data0; + unsigned int reserved0; + struct { + unsigned int saradc0_ain0_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain0_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc0_ain0_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain0_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_22; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc0_ain0_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain0_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc0_ain0_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain0_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc0_ain1_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain1_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc0_ain1_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain1_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_23; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc0_ain1_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain1_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc0_ain1_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain1_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc1_ain0_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain0_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc1_ain0_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain0_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_24; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc1_ain0_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain0_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc1_ain0_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain0_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc1_ain1_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain1_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc1_ain1_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain1_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_25; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc1_ain1_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain1_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc1_ain1_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain1_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc2_ain0_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain0_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc2_ain0_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain0_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_26; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc2_ain0_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain0_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc2_ain0_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain0_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc2_ain1_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain1_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc2_ain1_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain1_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_27; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc2_ain1_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain1_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc2_ain1_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain1_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + unsigned int reserved[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_28; + +/* + * FOTP INFO RNG1 + */ +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int main_rgn0_0_protection_level : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN1_NUMBER_0; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int uart0_enable : 1; + unsigned int uart1_enable : 1; + unsigned int uart2_enable : 1; + unsigned int uart3_enable : 1; + unsigned int uart4_enable : 1; + unsigned int reserved : 3; + unsigned int IWDG_DEEPSLEEP : 1; + unsigned int reserved1 : 1; + unsigned int IWDG_SW : 1; + unsigned int reserved2 : 13; + unsigned int verify_disable : 1; + unsigned int reserved3 : 7; + } data0; + struct { + unsigned int func_jtag_enable : 8; + unsigned int sysram_parity_disable : 1; + unsigned int reserved : 23; + } data1; + struct { + unsigned int uart_boot_enable : 1; + unsigned int spi_boot_enable : 1; + unsigned int i2c_boot_enable : 1; + unsigned int can_boot_enable : 1; + unsigned int smbus_boot_enable : 1; + unsigned int reserved : 27; + } data2; + struct { + unsigned int main_rgn0_0_size : 10; + unsigned int reserved : 22; + } data3; + } REG; +} FOTP_INFO_RGN1_NUMBER_8; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn1_0_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn1_1_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN1_NUMBER_56; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn1_2_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn1_3_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN1_NUMBER_57; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn1_4_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn1_5_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN1_NUMBER_58; + +/* + * FOTP INFO RNG2 + */ +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int main_rgn0_1_start_addr : 10; + unsigned int reserved : 6; + unsigned int main_rgn0_1_end_addr : 10; + unsigned int reserved1 : 6; + } data0; + struct { + unsigned int main_rgn0_1_code_end : 10; + unsigned int reserved : 14; + unsigned int main_rgn0_1_protection_level : 8; + } data1; + struct { + unsigned int sram_rgn0_1_start_addr : 10; + unsigned int reserved : 6; + unsigned int sram_rgn0_1_end_addr : 10; + unsigned int reserved1 : 6; + } data2; + struct { + unsigned int sram_rgn0_1_cpsrc_addr : 10; + unsigned int reserved : 14; + unsigned int sram_rgn0_1_disable : 8; + } data3; + } REG; +} FOTP_INFO_RGN2_NUMBER_0; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn2_0_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn2_1_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN2_NUMBER_56; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn2_2_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn2_3_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN2_NUMBER_57; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn2_4_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn2_5_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN2_NUMBER_58; + +/* + * FOTP INFO RNG3 + */ +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int main_rgn0_2_start_addr : 10; + unsigned int reserved : 6; + unsigned int main_rgn0_2_end_addr : 10; + unsigned int reserved1 : 6; + } data0; + struct { + unsigned int main_rgn0_2_code_end : 10; + unsigned int reserved : 14; + unsigned int main_rgn0_2_protection_level : 8; + } data1; + struct { + unsigned int sram_rgn0_2_start_addr : 10; + unsigned int reserved : 6; + unsigned int sram_rgn0_2_end_addr : 10; + unsigned int reserved1 : 6; + } data2; + struct { + unsigned int sram : 10; + unsigned int reserved : 14; + unsigned int sram_rgn0_2_disable : 8; + } data3; + } REG; +} FOTP_INFO_RGN3_NUMBER_0; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn3_0_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn3_1_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN3_NUMBER_56; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn3_2_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn3_3_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN3_NUMBER_57; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn3_4_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn3_5_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN3_NUMBER_58; + +#endif \ No newline at end of file diff --git a/src/chip/3065p/fotp/fotp_info_read.c b/src/chip/3065p/fotp/fotp_info_read.c new file mode 100644 index 0000000000000000000000000000000000000000..91569e4e6dafb13558f78b096f2e567aef4938f6 --- /dev/null +++ b/src/chip/3065p/fotp/fotp_info_read.c @@ -0,0 +1,141 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file fotp_info_read.c + * @author MCU Driver Team + * @brief This file provides firmware functions to manage the following + * functionalities of the fotp control register. + * + FOTP INFO Read API + */ +#include "chipinc.h" +#include "flash.h" +#include "fotp_info_read.h" +#define FOTP_INFO_RNG0_BASEADDR 0x800000 +#define FOTP_INFO_RNG1_BASEADDR 0x800400 +#define FOTP_INFO_RNG2_BASEADDR 0x800800 +#define FOTP_INFO_RNG3_BASEADDR 0x800C00 +#define REG_WORDS_NUM 16 +#define FLASH_READ_128BIT 1 + +/** + * @brief Read Four words of FOTP. + * @param efc Flash control register base address + * @retval BASE_STATUS_ERROR fail. + * @retval BASE_STATUS_OK success. + */ +static unsigned int FOTP_CheckReadStatus(EFC_RegStruct *efc) +{ + /* Check for errors in the flash reading process. */ + if (efc->INT_RAW_STATUS.BIT.int_raw_err_illegal || + efc->INT_RAW_STATUS.BIT.int_raw_err_ecc_corr || + efc->INT_RAW_STATUS.BIT.int_raw_err_ecc_chk) { + efc->INT_CLEAR.BIT.int_clr_err_ecc_corr = BASE_CFG_SET; + efc->INT_CLEAR.BIT.int_clr_err_illegal = BASE_CFG_SET; + efc->INT_CLEAR.BIT.int_clr_err_ecc_chk = BASE_CFG_SET; + efc->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; + return BASE_STATUS_ERROR; + } + return BASE_STATUS_OK; +} + +/** + * @brief Get the base address of the info Partition. + * @param type FOTP Range Type + * @retval the base address of info. + */ +static unsigned int GetInfoRegionAddr(FOTP_InfoRngType type) +{ + unsigned int addr; + switch (type) { + case FOTP_INFO_RNG0: + addr = FOTP_INFO_RNG0_BASEADDR; /* info0 base address. */ + break; + + case FOTP_INFO_RNG1: + addr = FOTP_INFO_RNG1_BASEADDR; /* info1 base address. */ + break; + + case FOTP_INFO_RNG2: + addr = FOTP_INFO_RNG2_BASEADDR; /* info2 base address. */ + break; + + case FOTP_INFO_RNG3: + addr = FOTP_INFO_RNG3_BASEADDR; /* info3 base address. */ + break; + + default: + addr = FOTP_INFO_RNG0_BASEADDR; + break; + } + return addr; +} + +/** + * @brief Read Four words of FOTP. + * @param type FOTP Range Type + * @param index FOTP register index + * @param buf Buffer of read data + * @retval BASE_STATUS_ERROR fail. + * @retval BASE_STATUS_OK success. + */ +unsigned int FOTP_InfoGet(FOTP_InfoRngType type, unsigned int index, FOTP_CommonData *buf) +{ + EFC_RegStruct *p = EFC; + unsigned int addr; + + if (buf == NULL) { + return BASE_STATUS_ERROR; + } + + if ((type >= FOTP_INFO_MAXTYPE) || (index > FOTP_INFO_REG_MAX_ID)) { + return BASE_STATUS_ERROR; + } + + /* If there is a read command, return */ + if (p->EFLASH_CMD.BIT.cmd_start) { + return BASE_STATUS_ERROR; + } + + p->MAGIC_LOCK = FLASH_KEY_REGISTER_UNLOCK_VALUE; + + /* Configure the read command parameters and start the read command */ + addr = GetInfoRegionAddr(type); + + addr += index * REG_WORDS_NUM; + p->EFLASH_ADDR.BIT.cmd_addr = addr >> 2; /* Right shift 2 bit change to word */ + p->EFLASH_CMD.BIT.cmd_code = FLASH_OPERATION_READ; + p->EFLASH_CMD.BIT.cmd_read_size = FLASH_READ_128BIT; + p->EFLASH_CMD.BIT.cmd_start = BASE_CFG_SET; + + while (p->EFLASH_CMD.BIT.cmd_start) { + ; + } + while (p->EFLASH_CMD.BIT.exec_state) { + ; + } + /* read error, clear interrupt and return */ + if (FOTP_CheckReadStatus(p) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + /* Read data from FIFO to buffer */ + for (unsigned int i = 0; i < sizeof(buf->data) / sizeof(buf->data[0]); ++i) { + buf->data[i] = p->FLASH_RDATA; + } + p->INT_CLEAR.BIT.int_clr_finish = BASE_CFG_SET; + p->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/chip/3065p/fotp/fotp_info_read.h b/src/chip/3065p/fotp/fotp_info_read.h new file mode 100644 index 0000000000000000000000000000000000000000..1f6c2a80e607421f68b64cbb089cdebc19d1c5e4 --- /dev/null +++ b/src/chip/3065p/fotp/fotp_info_read.h @@ -0,0 +1,31 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file fotp_info_read.h + * @author MCU Driver Team + * @brief This file provides firmware functions to manage the following + * functionalities of the system control register. + * + FOTP Register Read API + */ +#ifndef McuMagicTag_FOTP_INFO_READ_H +#define McuMagicTag_FOTP_INFO_READ_H + +#include "fotp.h" + +unsigned int FOTP_InfoGet(FOTP_InfoRngType type, unsigned int index, FOTP_CommonData *buf); + +#endif diff --git a/src/chip/3065p/info.h b/src/chip/3065p/info.h new file mode 100644 index 0000000000000000000000000000000000000000..9c8dd7ad3c4bc0e460728075d85c0453164a9bb9 --- /dev/null +++ b/src/chip/3065p/info.h @@ -0,0 +1,30 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file info.h + * @author MCU Driver Team + * @brief Defines chip attributes. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_INFO_H +#define McuMagicTag_INFO_H + +#define CHIP_DELAY_CYCLES_PER_LOOP (4) /**< CPU cycles. Known number of this CPU cycles required to execute the \ + BASE_FUNC_delay() loop. */ + +#endif /* McuMagicTag_INFO_H */ \ No newline at end of file diff --git a/src/chip/3065p/interrupt_ip.h b/src/chip/3065p/interrupt_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..1fb09cd258ad55e083ec98398ca32b9382ba4924 --- /dev/null +++ b/src/chip/3065p/interrupt_ip.h @@ -0,0 +1,205 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file interrupt_ip.h + * @author MCU Driver Team + * @brief interrupt module driver. + * This file define the interrupt number + */ + +#ifndef MCUMagicTag_INTERRUPT_IP_H +#define MCUMagicTag_INTERRUPT_IP_H + +/* Typedef definitions -------------------------------------------------------*/ +#define MSTATUS_MIE 0x00000008U /**< mie in mstatus */ +#define MSTATUS_MPIE 0x00000080U /**< mpie in mstatus */ +#define UINT32_CUT_MASK 0xFFFFFFFFU + +#define IRQ_PRIO_HIGHEST 15 /**< Highest priority of a hardware interrupt. */ +#define IRQ_PRIO_LOWEST 1 /**< Lowest priority of a hardware interrupt. */ + +/** + * @brief Count of system interrupt vector. + * The number of standard interrupts inside the CPU. The interrupt number + * is 0~25. The software interrupt nesting scheme cannot use standard + * interrupts, which means that external system integration will ensure + * that no standard interrupts will be triggered. + */ +#define IRQ_VECTOR_CNT 26 + +/** + * @brief Count of local interrupt vector 0 - 5, enabled by CSR mie 26 -31 bit. + */ +#define IRQ_MIE_VECTOR_CNT 6 + +/** + * @brief Count of IRQ controlled by CSR mie + */ +#define IRQ_MIE_TOTAL_CNT (IRQ_VECTOR_CNT + IRQ_MIE_VECTOR_CNT) +#define IRQ_LOCIEN1_OFFSET 64 +#define IRQ_LOCIEN2_OFFSET 96 +#define IRQ_LOCIEN3_OFFSET 128 + +/** + * @brief rv_custom_csr + * locipri0~15 are registers that control the priority of interrupts, + * and every 4 bits control the priority of an interrupt + */ +#define LOCIPRI0 0xBC0 +#define LOCIPRI1 0xBC1 +#define LOCIPRI2 0xBC2 +#define LOCIPRI3 0xBC3 +#define LOCIPRI4 0xBC4 +#define LOCIPRI5 0xBC5 +#define LOCIPRI6 0xBC6 +#define LOCIPRI7 0xBC7 +#define LOCIPRI8 0xBC8 +#define LOCIPRI9 0xBC9 +#define LOCIPRI10 0xBCA +#define LOCIPRI11 0xBCB +#define LOCIPRI12 0xBCC +#define LOCIPRI13 0xBCD +#define LOCIPRI14 0xBCE +#define LOCIPRI15 0xBCF + +#define LOCIPRI(x) LOCIPRI##x + +/** + * @brief locien0~3 are registers that control interrupt enable + */ +#define LOCIEN0 0xBE0 +#define LOCIEN1 0xBE1 +#define LOCIEN2 0xBE2 +#define LOCIEN3 0xBE3 + +/** + * @brief locipd0~3 are registers that control the interrupt flag bit. Each bit + * controls an interrupt. If the corresponding bit bit is 1, it means the + * corresponding interrupt is triggered. + */ +#define LOCIPD0 0xBE8 +#define LOCIPD1 0xBE9 +#define LOCIPD2 0xBEA +#define LOCIPD3 0xBEB + +/** + * @brief Locipclr is the register that clears the interrupt flag bit, and the + * corresponding interrupt number is assigned to the locipclr register, + * and the hardware will clear the corresponding interrupt flag bit, that + * is, the corresponding locipd bit is set + */ +#define LOCIPCLR 0xBF0 + +/** + * @brief The maximum number of interrupts supported, excluding 26 internal standard + * interrupts, up to 230 external non-standard interrupts can be supported + */ +#define IRQ_NUM 256 + +/* ---------- Interrupt Number Definition ----------------------------------- */ +typedef enum { + IRQ_SOFTWARE = 26, /* The first 0~25 interrupts are the internal standard interrupts of the CPU, + and the customizable external non-standard interrupts start from 26 */ + IRQ_UART0 = 28, + IRQ_UART1 = 29, + IRQ_UART2 = 30, + IRQ_MTIMER = 31, + IRQ_TIMER0 = 32, + IRQ_TIMER1 = 33, + IRQ_TIMER2 = 34, + IRQ_TIMER3 = 35, + IRQ_GPT0_INT = 36, + IRQ_GPT0_PRD_INT = 37, + IRQ_GPT1_INT = 38, + IRQ_GPT1_PRD_INT = 39, + IRQ_WWDG = 40, + IRQ_IWDG = 41, + IRQ_I2C0 = 42, + IRQ_SPI0 = 44, + IRQ_SPI1 = 45, + IRQ_CAN = 46, + IRQ_CAN1 = 47, + IRQ_APT0_EVT = 48, + IRQ_APT0_TMR = 49, + IRQ_APT1_EVT = 50, + IRQ_APT1_TMR = 51, + IRQ_APT2_EVT = 52, + IRQ_APT2_TMR = 53, + IRQ_APT3_EVT = 54, + IRQ_APT3_TMR = 55, + IRQ_APT4_EVT = 56, + IRQ_APT4_TMR = 57, + IRQ_APT5_EVT = 58, + IRQ_APT5_TMR = 59, + IRQ_APT6_EVT = 60, + IRQ_APT6_TMR = 61, + IRQ_APT7_EVT = 62, + IRQ_APT7_TMR = 63, + IRQ_APT8_EVT = 64, + IRQ_APT8_TMR = 65, + IRQ_UART3 = 66, + IRQ_UART4 = 67, + IRQ_CMM = 68, + IRQ_CFD = 69, + IRQ_CAPM0 = 70, + IRQ_CAPM1 = 71, + IRQ_CAPM2 = 72, + IRQ_QDM0 = 73, + IRQ_QDM1 = 74, + IRQ_QDM2 = 75, + IRQ_QDM3 = 76, + IRQ_DMA_TC = 77, + IRQ_DMA_ERR = 78, + IRQ_SYSRAM_PARITY_ERR = 79, + IRQ_EFC = 81, + IRQ_EFC_ERR = 82, + IRQ_PVD = 85, + IRQ_ACMP0_INT = 86, + IRQ_ACMP1_INT = 87, + IRQ_ACMP2_INT = 88, + IRQ_ADC0_EVENT = 91, + IRQ_ADC0_ERR = 92, + IRQ_ADC0_INT0 = 93, + IRQ_ADC0_INT1 = 94, + IRQ_ADC0_INT2 = 95, + IRQ_ADC0_INT3 = 96, + IRQ_ADC1_EVENT = 97, + IRQ_ADC1_ERR = 98, + IRQ_ADC1_INT0 = 99, + IRQ_ADC1_INT1 = 100, + IRQ_ADC1_INT2 = 101, + IRQ_ADC1_INT3 = 102, + IRQ_ADC2_EVENT = 103, + IRQ_ADC2_ERR = 104, + IRQ_ADC2_INT0 = 105, + IRQ_ADC2_INT1 = 106, + IRQ_ADC2_INT2 = 107, + IRQ_ADC2_INT3 = 108, + IRQ_GPIO0 = 109, + IRQ_GPIO1 = 110, + IRQ_GPIO2 = 111, + IRQ_GPIO3 = 112, + IRQ_GPIO4 = 113, + IRQ_GPIO5 = 114, + IRQ_GPIO6 = 115, + IRQ_GPIO7 = 116, + IRQ_GPIO8 = 117, + IRQ_GPIO9 = 118, + IRQ_MAX, /**< The maximum number of interrupts currently supported */ +} IRQ_ID; + +#endif /* MCUMagicTag_INTERRUPT_IP_H */ \ No newline at end of file diff --git a/src/chip/3065p/ioconfig.h b/src/chip/3065p/ioconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..4ca99418975a8ebf97dcc95ec501444edaa65345 --- /dev/null +++ b/src/chip/3065p/ioconfig.h @@ -0,0 +1,119 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file ioconfig.h + * @author MCU Driver Team + * @brief ioconfig module driver + * @details This file provides IOConfig register mapping structure. + */ + +/* Macro definitions */ +#ifndef McuMagicTag_IOCONFIG_H +#define McuMagicTag_IOCONFIG_H + +typedef union { + unsigned int reg; + struct { + unsigned int func : 4; /**< IO function selection. */ + unsigned int ds : 2; /**< Pin drive capability selection. */ + unsigned int reserved0 : 1; + unsigned int pd : 1; /**< Pin pull down control. */ + unsigned int pu : 1; /**< Pin pull up control. */ + unsigned int sr : 1; /**< Electrical level shift speed control. */ + unsigned int se : 1; /**< Schmidt input control. */ + unsigned int reserved1 : 1; /**< Reserved: Open drain control reserved. */ + unsigned int reserved2 : 20; + } BIT; +} volatile IOCMG_REG; + +typedef struct { + IOCMG_REG IOCFG_GPIO0_0; /**< Pin GPIO0_0 IO Config Register, offset address:0x000000U */ + IOCMG_REG IOCFG_GPIO0_1; /**< Pin GPIO0_1 IO Config Register, offset address:0x000004U */ + IOCMG_REG IOCFG_GPIO0_2; /**< Pin GPIO0_2 IO Config Register, offset address:0x000008U */ + IOCMG_REG IOCFG_GPIO0_3; /**< Pin GPIO0_3 IO Config Register, offset address:0x00000CU */ + IOCMG_REG IOCFG_GPIO0_4; /**< Pin GPIO0_4 IO Config Register, offset address:0x000010U */ + IOCMG_REG IOCFG_GPIO0_5; /**< Pin GPIO0_5 IO Config Register, offset address:0x000014U */ + IOCMG_REG IOCFG_GPIO0_6; /**< Pin GPIO0_6 IO Config Register, offset address:0x000018U */ + IOCMG_REG IOCFG_GPIO0_7; /**< Pin GPIO0_7 IO Config Register, offset address:0x00001CU */ + IOCMG_REG IOCFG_GPIO1_0; /**< Pin GPIO1_0 IO Config Register, offset address:0x000020U */ + IOCMG_REG IOCFG_GPIO1_1; /**< Pin GPIO1_1 IO Config Register, offset address:0x000024U */ + IOCMG_REG IOCFG_GPIO1_2; /**< Pin GPIO1_2 IO Config Register, offset address:0x000028U */ + IOCMG_REG IOCFG_GPIO1_3; /**< Pin GPIO1_3 IO Config Register, offset address:0x00002CU */ + IOCMG_REG IOCFG_GPIO1_4; /**< Pin GPIO1_4 IO Config Register, offset address:0x000030U */ + IOCMG_REG IOCFG_GPIO1_5; /**< Pin GPIO1_5 IO Config Register, offset address:0x000034U */ + IOCMG_REG IOCFG_GPIO1_6; /**< Pin GPIO1_6 IO Config Register, offset address:0x000038U */ + IOCMG_REG IOCFG_GPIO1_7; /**< Pin GPIO1_7 IO Config Register, offset address:0x00003CU */ + IOCMG_REG IOCFG_GPIO2_0; /**< Pin GPIO2_0 IO Config Register, offset address:0x000040U */ + IOCMG_REG IOCFG_GPIO2_1; /**< Pin GPIO2_1 IO Config Register, offset address:0x000044U */ + IOCMG_REG IOCFG_GPIO2_2; /**< Pin GPIO2_2 IO Config Register, offset address:0x000048U */ + IOCMG_REG IOCFG_GPIO2_3; /**< Pin GPIO2_3 IO Config Register, offset address:0x00004CU */ + IOCMG_REG IOCFG_GPIO2_4; /**< Pin GPIO2_4 IO Config Register, offset address:0x000050U */ + IOCMG_REG IOCFG_GPIO2_5; /**< Pin GPIO2_5 IO Config Register, offset address:0x000054U */ + IOCMG_REG IOCFG_GPIO2_6; /**< Pin GPIO2_6 IO Config Register, offset address:0x000058U */ + IOCMG_REG IOCFG_GPIO2_7; /**< Pin GPIO2_7 IO Config Register, offset address:0x00005CU */ + IOCMG_REG IOCFG_GPIO3_0; /**< Pin GPIO3_0 IO Config Register, offset address:0x000060U */ + IOCMG_REG IOCFG_GPIO3_1; /**< Pin GPIO3_1 IO Config Register, offset address:0x000064U */ + IOCMG_REG IOCFG_GPIO3_2; /**< Pin GPIO3_2 IO Config Register, offset address:0x000068U */ + IOCMG_REG IOCFG_GPIO3_3; /**< Pin GPIO3_3 IO Config Register, offset address:0x00006CU */ + IOCMG_REG IOCFG_GPIO3_4; /**< Pin GPIO3_4 IO Config Register, offset address:0x000070U */ + IOCMG_REG IOCFG_GPIO3_5; /**< Pin GPIO3_5 IO Config Register, offset address:0x000074U */ + IOCMG_REG IOCFG_GPIO3_6; /**< Pin GPIO3_6 IO Config Register, offset address:0x000078U */ + IOCMG_REG IOCFG_GPIO3_7; /**< Pin GPIO3_7 IO Config Register, offset address:0x00007CU */ + IOCMG_REG IOCFG_GPIO4_0; /**< Pin GPIO4_0 IO Config Register, offset address:0x000080U */ + IOCMG_REG IOCFG_GPIO4_1; /**< Pin GPIO4_1 IO Config Register, offset address:0x000084U */ + IOCMG_REG IOCFG_GPIO4_2; /**< Pin GPIO4_2 IO Config Register, offset address:0x000088U */ + IOCMG_REG IOCFG_GPIO4_3; /**< Pin GPIO4_3 IO Config Register, offset address:0x00008CU */ + IOCMG_REG IOCFG_GPIO4_4; /**< Pin GPIO4_4 IO Config Register, offset address:0x000090U */ + IOCMG_REG IOCFG_GPIO4_5; /**< Pin GPIO4_5 IO Config Register, offset address:0x000094U */ + IOCMG_REG IOCFG_GPIO4_6; /**< Pin GPIO4_6 IO Config Register, offset address:0x000098U */ + IOCMG_REG IOCFG_GPIO4_7; /**< Pin GPIO4_7 IO Config Register, offset address:0x00009CU */ + IOCMG_REG IOCFG_GPIO5_0; /**< Pin GPIO5_0 IO Config Register, offset address:0x0000A0U */ + IOCMG_REG IOCFG_GPIO5_1; /**< Pin GPIO5_1 IO Config Register, offset address:0x0000A4U */ + IOCMG_REG IOCFG_GPIO5_2; /**< Pin GPIO5_2 IO Config Register, offset address:0x0000A8U */ + IOCMG_REG IOCFG_GPIO5_3; /**< Pin GPIO5_3 IO Config Register, offset address:0x0000ACU */ + IOCMG_REG IOCFG_GPIO5_4; /**< Pin GPIO5_4 IO Config Register, offset address:0x0000B0U */ + IOCMG_REG IOCFG_GPIO5_5; /**< Pin GPIO5_5 IO Config Register, offset address:0x0000B4U */ + IOCMG_REG IOCFG_GPIO5_6; /**< Pin GPIO5_6 IO Config Register, offset address:0x0000B8U */ + IOCMG_REG IOCFG_GPIO5_7; /**< Pin GPIO5_7 IO Config Register, offset address:0x0000BCU */ + IOCMG_REG IOCFG_GPIO6_0; /**< Pin GPIO6_0 IO Config Register, offset address:0x0000C0U */ + IOCMG_REG IOCFG_GPIO6_1; /**< Pin GPIO6_1 IO Config Register, offset address:0x0000C4U */ + IOCMG_REG IOCFG_GPIO6_2; /**< Pin GPIO6_2 IO Config Register, offset address:0x0000C8U */ + IOCMG_REG IOCFG_GPIO6_3; /**< Pin GPIO6_3 IO Config Register, offset address:0x0000CCU */ + IOCMG_REG IOCFG_GPIO6_4; /**< Pin GPIO6_4 IO Config Register, offset address:0x0000D0U */ + IOCMG_REG IOCFG_GPIO6_5; /**< Pin GPIO6_5 IO Config Register, offset address:0x0000D4U */ + IOCMG_REG IOCFG_GPIO6_6; /**< Pin GPIO6_6 IO Config Register, offset address:0x0000D8U */ + IOCMG_REG IOCFG_GPIO6_7; /**< Pin GPIO6_7 IO Config Register, offset address:0x0000DCU */ + IOCMG_REG IOCFG_GPIO7_0; /**< Pin GPIO7_0 IO Config Register, offset address:0x0000E0U */ + IOCMG_REG IOCFG_GPIO7_1; /**< Pin GPIO7_1 IO Config Register, offset address:0x0000E4U */ + IOCMG_REG IOCFG_GPIO7_2; /**< Pin GPIO7_2 IO Config Register, offset address:0x0000E8U */ + IOCMG_REG IOCFG_GPIO7_3; /**< Pin GPIO7_3 IO Config Register, offset address:0x0000ECU */ + IOCMG_REG IOCFG_GPIO7_4; /**< Pin GPIO7_4 IO Config Register, offset address:0x0000F0U */ + IOCMG_REG IOCFG_GPIO7_5; /**< Pin GPIO7_5 IO Config Register, offset address:0x0000F4U */ + IOCMG_REG IOCFG_GPIO7_6; /**< Pin GPIO7_6 IO Config Register, offset address:0x0000F8U */ + IOCMG_REG IOCFG_GPIO7_7; /**< Pin GPIO7_7 IO Config Register, offset address:0x0000FCU */ + IOCMG_REG IOCFG_GPIO8_0; /**< Pin GPIO8_0 IO Config Register, offset address:0x000100U */ + IOCMG_REG IOCFG_GPIO8_1; /**< Pin GPIO8_1 IO Config Register, offset address:0x000104U */ + IOCMG_REG IOCFG_GPIO8_2; /**< Pin GPIO8_2 IO Config Register, offset address:0x000108U */ + IOCMG_REG IOCFG_GPIO8_3; /**< Pin GPIO8_3 IO Config Register, offset address:0x00010CU */ + IOCMG_REG IOCFG_GPIO8_4; /**< Pin GPIO8_4 IO Config Register, offset address:0x000110U */ + IOCMG_REG IOCFG_GPIO8_5; /**< Pin GPIO8_5 IO Config Register, offset address:0x000114U */ + IOCMG_REG IOCFG_GPIO8_6; /**< Pin GPIO8_6 IO Config Register, offset address:0x000118U */ + IOCMG_REG IOCFG_GPIO8_7; /**< Pin GPIO8_7 IO Config Register, offset address:0x00011CU */ + IOCMG_REG IOCFG_GPIO9_0; /**< Pin GPIO9_0 IO Config Register, offset address:0x000120U */ +} volatile IOConfig_RegStruct; + +#endif /* McuMagicTag_IOCONFIG_H */ \ No newline at end of file diff --git a/src/chip/3065p/iomap/iomap.h b/src/chip/3065p/iomap/iomap.h new file mode 100644 index 0000000000000000000000000000000000000000..a478644bb4aacebf8bf602e76e7683f8d785c10a --- /dev/null +++ b/src/chip/3065p/iomap/iomap.h @@ -0,0 +1,581 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file iomap.h + * @author MCU Driver Team + * @brief Defines chip pin map and function mode. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_IOMAP_H +#define McuMagicTag_IOMAP_H + +/* get offset value of member in type struct */ +#define OFFSET_OF(type, member) (unsigned int)(&(((type *)0)->member)) + +#define IOCMG_PIN_MUX(regx, funcNum, regValueDefault) \ + (unsigned int)(((OFFSET_OF(IOConfig_RegStruct, regx) & 0x00000FFF) << 16) | \ + (((regValueDefault) & 0xFFFFFFF0) | (funcNum))) +/* pin function mode info ---------------------------------------------------- */ +#define GPIO0_0_AS_GPIO0_0 IOCMG_PIN_MUX(IOCFG_GPIO0_0, FUNC_MODE_0, 0x0a81) +#define GPIO0_0_AS_JTAG_TCK IOCMG_PIN_MUX(IOCFG_GPIO0_0, FUNC_MODE_1, 0x0a81) +#define GPIO0_0_AS_WAKEUP0 IOCMG_PIN_MUX(IOCFG_GPIO0_0, FUNC_MODE_3, 0x0a81) +#define GPIO0_0_AS_UART0_CTSN IOCMG_PIN_MUX(IOCFG_GPIO0_0, FUNC_MODE_4, 0x0a81) +#define GPIO0_0_AS_UART4_CTSN IOCMG_PIN_MUX(IOCFG_GPIO0_0, FUNC_MODE_5, 0x0a81) + +#define GPIO0_1_AS_GPIO0_1 IOCMG_PIN_MUX(IOCFG_GPIO0_1, FUNC_MODE_0, 0x0b21) +#define GPIO0_1_AS_JTAG_TMS IOCMG_PIN_MUX(IOCFG_GPIO0_1, FUNC_MODE_1, 0x0b21) +#define GPIO0_1_AS_WAKEUP1 IOCMG_PIN_MUX(IOCFG_GPIO0_1, FUNC_MODE_3, 0x0b21) +#define GPIO0_1_AS_UART0_RTSN IOCMG_PIN_MUX(IOCFG_GPIO0_1, FUNC_MODE_4, 0x0b21) +#define GPIO0_1_AS_UART4_RTSN IOCMG_PIN_MUX(IOCFG_GPIO0_1, FUNC_MODE_5, 0x0b21) + +#define GPIO0_2_AS_GPIO0_2 IOCMG_PIN_MUX(IOCFG_GPIO0_2, FUNC_MODE_0, 0x0a00) +#define GPIO0_2_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO0_2, FUNC_MODE_1, 0x0a00) +#define GPIO0_2_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO0_2, FUNC_MODE_2, 0x0a00) +#define GPIO0_2_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO0_2, FUNC_MODE_3, 0x0a00) +#define GPIO0_2_AS_UART4_RXD IOCMG_PIN_MUX(IOCFG_GPIO0_2, FUNC_MODE_4, 0x0a00) + +#define GPIO0_3_AS_GPIO0_3 IOCMG_PIN_MUX(IOCFG_GPIO0_3, FUNC_MODE_0, 0x0a00) +#define GPIO0_3_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO0_3, FUNC_MODE_2, 0x0a00) +#define GPIO0_3_AS_UART0_TXD IOCMG_PIN_MUX(IOCFG_GPIO0_3, FUNC_MODE_4, 0x0a00) +#define GPIO0_3_AS_XTAL_OUT IOCMG_PIN_MUX(IOCFG_GPIO0_3, FUNC_MODE_12, 0x0a00) + +#define GPIO0_4_AS_GPIO0_4 IOCMG_PIN_MUX(IOCFG_GPIO0_4, FUNC_MODE_0, 0x0a00) +#define GPIO0_4_AS_UART0_RXD IOCMG_PIN_MUX(IOCFG_GPIO0_4, FUNC_MODE_4, 0x0a00) +#define GPIO0_4_AS_XTAL_IN IOCMG_PIN_MUX(IOCFG_GPIO0_4, FUNC_MODE_12, 0x0a00) + +#define GPIO0_5_AS_GPIO0_5 IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_0, 0x0a00) +#define GPIO0_5_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_1, 0x0a00) +#define GPIO0_5_AS_APT_EVTMP5 IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_2, 0x0a00) +#define GPIO0_5_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_3, 0x0a00) +#define GPIO0_5_AS_QDM3_INDEX IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_4, 0x0a00) +#define GPIO0_5_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_6, 0x0a00) +#define GPIO0_5_AS_ADC_EXT_TRIG3 IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_7, 0x0a00) +#define GPIO0_5_AS_PMC2HOSC_PD IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_9, 0x0a00) +#define GPIO0_5_AS_PMC2CORE_POR_N IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_10, 0x0a00) +#define GPIO0_5_AS_EF_PSW_EN IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_11, 0x0a00) +#define GPIO0_5_AS_HOSC_TEST IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_12, 0x0a00) +#define GPIO0_5_AS_PLL_TEST IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_13, 0x0a00) + +#define GPIO0_6_AS_GPIO0_6 IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_0, 0x0a00) +#define GPIO0_6_AS_CAN_RX IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_1, 0x0a00) +#define GPIO0_6_AS_APT_EVTIO5 IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_2, 0x0a00) +#define GPIO0_6_AS_QDM3_A IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_3, 0x0a00) +#define GPIO0_6_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_4, 0x0a00) +#define GPIO0_6_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_5, 0x0a00) +#define GPIO0_6_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_6, 0x0a00) +#define GPIO0_6_AS_UART4_RXD IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_7, 0x0a00) +#define GPIO0_6_AS_UART2_CTSN IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_8, 0x0a00) + +#define GPIO0_7_AS_GPIO0_7 IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_0, 0x0a00) +#define GPIO0_7_AS_CAN_TX IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_1, 0x0a00) +#define GPIO0_7_AS_QDM3_B IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_3, 0x0a00) +#define GPIO0_7_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_4, 0x0a00) +#define GPIO0_7_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_5, 0x0a00) +#define GPIO0_7_AS_UART4_TXD IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_6, 0x0a00) +#define GPIO0_7_AS_UART2_RTSN IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_7, 0x0a00) + +#define GPIO1_0_AS_GPIO1_0 IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_0, 0x0a00) +#define GPIO1_0_AS_QDM0_A IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_1, 0x0a00) +#define GPIO1_0_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_2, 0x0a00) +#define GPIO1_0_AS_UART2_TXD IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_3, 0x0a00) +#define GPIO1_0_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_4, 0x0a00) +#define GPIO1_0_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_5, 0x0a00) +#define GPIO1_0_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_6, 0x0a00) +#define GPIO1_0_AS_UART4_CTSN IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_7, 0x0a00) + +#define GPIO1_1_AS_GPIO1_1 IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_0, 0x0a00) +#define GPIO1_1_AS_QDM0_B IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_1, 0x0a00) +#define GPIO1_1_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_2, 0x0a00) +#define GPIO1_1_AS_UART2_RXD IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_3, 0x0a00) +#define GPIO1_1_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_4, 0x0a00) +#define GPIO1_1_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_6, 0x0a00) +#define GPIO1_1_AS_UART4_RTSN IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_7, 0x0a00) + +#define GPIO1_2_AS_GPIO1_2 IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_0, 0x0e80) +#define GPIO1_2_AS_UPDATE_MO IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_1, 0x0e80) +#define GPIO1_2_AS_UART1_RTSN IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_4, 0x0e80) +#define GPIO1_2_AS_SMB0_SPND IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_6, 0x0e80) +#define GPIO1_2_AS_TEST_CLK IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_11, 0x0e80) +#define GPIO1_2_AS_PMU_TEST IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_12, 0x0e80) + +#define GPIO1_3_AS_GPIO1_3 IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_0, 0x0a21) +#define GPIO1_3_AS_JTAG_TDO IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_1, 0x0a21) +#define GPIO1_3_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_2, 0x0a21) +#define GPIO1_3_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_3, 0x0a21) +#define GPIO1_3_AS_UART1_RXD IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_4, 0x0a21) +#define GPIO1_3_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_5, 0x0a21) +#define GPIO1_3_AS_QDM1_A IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_6, 0x0a21) + +#define GPIO1_4_AS_GPIO1_4 IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_0, 0x0b01) +#define GPIO1_4_AS_JTAG_TDI IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_1, 0x0b01) +#define GPIO1_4_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_3, 0x0b01) +#define GPIO1_4_AS_UART1_TXD IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_4, 0x0b01) +#define GPIO1_4_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_5, 0x0b01) +#define GPIO1_4_AS_QDM1_B IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_6, 0x0b01) + +#define GPIO1_5_AS_GPIO1_5 IOCMG_PIN_MUX(IOCFG_GPIO1_5, FUNC_MODE_0, 0x0a00) +#define GPIO1_5_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO1_5, FUNC_MODE_1, 0x0a00) +#define GPIO1_5_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO1_5, FUNC_MODE_2, 0x0a00) +#define GPIO1_5_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO1_5, FUNC_MODE_3, 0x0a00) +#define GPIO1_5_AS_UART3_RXD IOCMG_PIN_MUX(IOCFG_GPIO1_5, FUNC_MODE_4, 0x0a00) + +#define GPIO1_6_AS_GPIO1_6 IOCMG_PIN_MUX(IOCFG_GPIO1_6, FUNC_MODE_0, 0x0a00) +#define GPIO1_6_AS_QDM0_INDEX IOCMG_PIN_MUX(IOCFG_GPIO1_6, FUNC_MODE_1, 0x0a00) +#define GPIO1_6_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO1_6, FUNC_MODE_2, 0x0a00) + +#define GPIO1_7_AS_GPIO1_7 IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_0, 0x0a81) +#define GPIO1_7_AS_JTAG_TRSTN IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_1, 0x0a81) +#define GPIO1_7_AS_UART3_CTSN IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_2, 0x0a81) +#define GPIO1_7_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_3, 0x0a81) +#define GPIO1_7_AS_UART1_CTSN IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_4, 0x0a81) +#define GPIO1_7_AS_SPI0_CSN0 IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_5, 0x0a81) +#define GPIO1_7_AS_ADC_EXT_TRIG1 IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_6, 0x0a81) +#define GPIO1_7_AS_QDM2_INDEX IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_7, 0x0a81) +#define GPIO1_7_AS_ADC1_ANA_A11 IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_12, 0x0a81) +#define GPIO1_7_AS_ACMP1_ANA_N2 IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_13, 0x0a81) + +#define GPIO2_0_AS_GPIO2_0 IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_0, 0x0a00) +#define GPIO2_0_AS_UART3_RXD IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_2, 0x0a00) +#define GPIO2_0_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_3, 0x0a00) +#define GPIO2_0_AS_SPI0_MOSI IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_5, 0x0a00) +#define GPIO2_0_AS_QDM2_A IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_6, 0x0a00) +#define GPIO2_0_AS_PVD_TOGGLE IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_10, 0x0a00) +#define GPIO2_0_AS_EF_BIST_SCK IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_11, 0x0a00) +#define GPIO2_0_AS_ADC1_ANA_A12 IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_12, 0x0a00) +#define GPIO2_0_AS_ADC0_ANA_A9 IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_13, 0x0a00) + +#define GPIO2_1_AS_GPIO2_1 IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_0, 0x0a00) +#define GPIO2_1_AS_UART3_TXD IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_2, 0x0a00) +#define GPIO2_1_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_3, 0x0a00) +#define GPIO2_1_AS_SPI0_MISO IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_5, 0x0a00) +#define GPIO2_1_AS_QDM2_B IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_6, 0x0a00) +#define GPIO2_1_AS_EF_BIST_SDI IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_11, 0x0a00) +#define GPIO2_1_AS_ADC1_ANA_A13 IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_12, 0x0a00) +#define GPIO2_1_AS_ADC0_ANA_A2 IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_13, 0x0a00) + +#define GPIO2_2_AS_GPIO2_2 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_0, 0x0a00) +#define GPIO2_2_AS_APT_EVTMP4 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_2, 0x0a00) +#define GPIO2_2_AS_UART1_RTSN IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_3, 0x0a00) +#define GPIO2_2_AS_UART3_RTSN IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_4, 0x0a00) +#define GPIO2_2_AS_SPI0_CSN1 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_5, 0x0a00) +#define GPIO2_2_AS_ADC1_STATUS IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_6, 0x0a00) +#define GPIO2_2_AS_EF_BIST_SDO IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_11, 0x0a00) +#define GPIO2_2_AS_ADC1_ANA_A8 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_12, 0x0a00) +#define GPIO2_2_AS_ACMP1_ANA_P2 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_13, 0x0a00) +#define GPIO2_2_AS_ADC0_ANA_A10 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_14, 0x0a00) + +#define GPIO2_3_AS_GPIO2_3 IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_0, 0x0a00) +#define GPIO2_3_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_1, 0x0a00) +#define GPIO2_3_AS_SPI0_CLK IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_5, 0x0a00) +#define GPIO2_3_AS_EF_BIST_SCE IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_11, 0x0a00) +#define GPIO2_3_AS_ADC1_ANA_A2 IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_12, 0x0a00) +#define GPIO2_3_AS_PGA1_ANA_P0 IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_13, 0x0a00) + +#define GPIO2_4_AS_GPIO2_4 IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_0, 0x0a00) +#define GPIO2_4_AS_APT6_PWMA IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_3, 0x0a00) +#define GPIO2_4_AS_UART0_RXD IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_4, 0x0a00) +#define GPIO2_4_AS_QDM1_A IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_5, 0x0a00) +#define GPIO2_4_AS_ADC1_ANA_A10 IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_12, 0x0a00) +#define GPIO2_4_AS_PGA1_ANA_N0 IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_13, 0x0a00) + +#define GPIO2_5_AS_GPIO2_5 IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_0, 0x0a00) +#define GPIO2_5_AS_APT7_PWMA IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_3, 0x0a00) +#define GPIO2_5_AS_UART0_TXD IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_4, 0x0a00) +#define GPIO2_5_AS_QDM1_B IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_5, 0x0a00) +#define GPIO2_5_AS_PGA1_ANA_EXT0 IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_13, 0x0a00) + +#define GPIO2_6_AS_GPIO2_6 IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_0, 0x0a00) +#define GPIO2_6_AS_APT8_PWMA IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_3, 0x0a00) +#define GPIO2_6_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_4, 0x0a00) +#define GPIO2_6_AS_QDM1_INDEX IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_6, 0x0a00) +#define GPIO2_6_AS_ADC0_STATUS IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_7, 0x0a00) +#define GPIO2_6_AS_ADC1_ANA_A3 IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_12, 0x0a00) +#define GPIO2_6_AS_ADC2_ANA_A12 IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_13, 0x0a00) + +#define GPIO2_7_AS_GPIO2_7 IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_0, 0x0a00) +#define GPIO2_7_AS_ACMP1_OUT IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_2, 0x0a00) +#define GPIO2_7_AS_APT6_PWMB IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_3, 0x0a00) +#define GPIO2_7_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_4, 0x0a00) +#define GPIO2_7_AS_UART0_RTSN IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_5, 0x0a00) +#define GPIO2_7_AS_ADC1_ANA_A4 IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_12, 0x0a00) +#define GPIO2_7_AS_ADC2_ANA_A13 IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_13, 0x0a00) + +#define GPIO3_0_AS_GPIO3_0 IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_0, 0x0a00) +#define GPIO3_0_AS_APT7_PWMB IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_3, 0x0a00) +#define GPIO3_0_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_4, 0x0a00) +#define GPIO3_0_AS_UART0_CTSN IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_5, 0x0a00) +#define GPIO3_0_AS_ADC1_ANA_A5 IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_12, 0x0a00) +#define GPIO3_0_AS_ACMP1_ANA_N3 IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_13, 0x0a00) +#define GPIO3_0_AS_ADC0_ANA_A6 IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_14, 0x0a00) + +#define GPIO3_1_AS_GPIO3_1 IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_0, 0x0a00) +#define GPIO3_1_AS_APT8_PWMB IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_3, 0x0a00) +#define GPIO3_1_AS_QDM2_INDEX IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_5, 0x0a00) +#define GPIO3_1_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_6, 0x0a00) +#define GPIO3_1_AS_ADC1_ANA_A6 IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_12, 0x0a00) +#define GPIO3_1_AS_ACMP1_ANA_P3 IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_13, 0x0a00) + +#define GPIO3_2_AS_GPIO3_2 IOCMG_PIN_MUX(IOCFG_GPIO3_2, FUNC_MODE_0, 0x0a00) +#define GPIO3_2_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO3_2, FUNC_MODE_4, 0x0a00) +#define GPIO3_2_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO3_2, FUNC_MODE_5, 0x0a00) +#define GPIO3_2_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO3_2, FUNC_MODE_7, 0x0a00) + +#define GPIO3_3_AS_GPIO3_3 IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_0, 0x0a00) +#define GPIO3_3_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_1, 0x0a00) +#define GPIO3_3_AS_UART0_RXD IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_2, 0x0a00) +#define GPIO3_3_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_3, 0x0a00) +#define GPIO3_3_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_4, 0x0a00) +#define GPIO3_3_AS_UART3_CTSN IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_5, 0x0a00) +#define GPIO3_3_AS_SMB0_ALTN IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_6, 0x0a00) + +#define GPIO3_4_AS_GPIO3_4 IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_0, 0x0a00) +#define GPIO3_4_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_1, 0x0a00) +#define GPIO3_4_AS_UART0_TXD IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_2, 0x0a00) +#define GPIO3_4_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_3, 0x0a00) +#define GPIO3_4_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_4, 0x0a00) +#define GPIO3_4_AS_UART3_RTSN IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_6, 0x0a00) +#define GPIO3_4_AS_SMB0_SPNDN IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_7, 0x0a00) + +#define GPIO3_5_AS_GPIO3_5 IOCMG_PIN_MUX(IOCFG_GPIO3_5, FUNC_MODE_0, 0x0a00) +#define GPIO3_5_AS_APT0_PWMA IOCMG_PIN_MUX(IOCFG_GPIO3_5, FUNC_MODE_3, 0x0a00) +#define GPIO3_5_AS_UART2_TXD IOCMG_PIN_MUX(IOCFG_GPIO3_5, FUNC_MODE_4, 0x0a00) + +#define GPIO3_6_AS_GPIO3_6 IOCMG_PIN_MUX(IOCFG_GPIO3_6, FUNC_MODE_0, 0x0a00) +#define GPIO3_6_AS_APT1_PWMA IOCMG_PIN_MUX(IOCFG_GPIO3_6, FUNC_MODE_3, 0x0a00) +#define GPIO3_6_AS_UART2_RXD IOCMG_PIN_MUX(IOCFG_GPIO3_6, FUNC_MODE_4, 0x0a00) + +#define GPIO3_7_AS_GPIO3_7 IOCMG_PIN_MUX(IOCFG_GPIO3_7, FUNC_MODE_0, 0x0a00) +#define GPIO3_7_AS_APT2_PWMA IOCMG_PIN_MUX(IOCFG_GPIO3_7, FUNC_MODE_3, 0x0a00) +#define GPIO3_7_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO3_7, FUNC_MODE_4, 0x0a00) + +#define GPIO4_0_AS_GPIO4_0 IOCMG_PIN_MUX(IOCFG_GPIO4_0, FUNC_MODE_0, 0x0a00) +#define GPIO4_0_AS_APT0_PWMB IOCMG_PIN_MUX(IOCFG_GPIO4_0, FUNC_MODE_3, 0x0a00) +#define GPIO4_0_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO4_0, FUNC_MODE_4, 0x0a00) + +#define GPIO4_1_AS_GPIO4_1 IOCMG_PIN_MUX(IOCFG_GPIO4_1, FUNC_MODE_0, 0x0a00) +#define GPIO4_1_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO4_1, FUNC_MODE_2, 0x0a00) +#define GPIO4_1_AS_APT1_PWMB IOCMG_PIN_MUX(IOCFG_GPIO4_1, FUNC_MODE_3, 0x0a00) + +#define GPIO4_2_AS_GPIO4_2 IOCMG_PIN_MUX(IOCFG_GPIO4_2, FUNC_MODE_0, 0x0a00) +#define GPIO4_2_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO4_2, FUNC_MODE_2, 0x0a00) +#define GPIO4_2_AS_APT2_PWMB IOCMG_PIN_MUX(IOCFG_GPIO4_2, FUNC_MODE_3, 0x0a00) +#define GPIO4_2_AS_ANA_TEST IOCMG_PIN_MUX(IOCFG_GPIO4_2, FUNC_MODE_12, 0x0a00) + +#define GPIO4_3_AS_GPIO4_3 IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_0, 0x0a00) +#define GPIO4_3_AS_UART1_RXD IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_3, 0x0a00) +#define GPIO4_3_AS_QDM3_A IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_4, 0x0a00) +#define GPIO4_3_AS_ADC0_ANA_A7 IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_12, 0x0a00) +#define GPIO4_3_AS_PGA0_ANA_P0 IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_13, 0x0a00) +#define GPIO4_3_AS_ADC1_ANA_A14 IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_14, 0x0a00) + +#define GPIO4_4_AS_GPIO4_4 IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_0, 0x0a00) +#define GPIO4_4_AS_UART1_TXD IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_3, 0x0a00) +#define GPIO4_4_AS_QDM3_B IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_4, 0x0a00) +#define GPIO4_4_AS_ADC0_ANA_A8 IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_12, 0x0a00) +#define GPIO4_4_AS_PGA0_ANA_N0 IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_13, 0x0a00) +#define GPIO4_4_AS_ADC1_ANA_A15 IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_14, 0x0a00) + +#define GPIO4_5_AS_GPIO4_5 IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_0, 0x0a00) +#define GPIO4_5_AS_UART1_CTSN IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_3, 0x0a00) +#define GPIO4_5_AS_QDM3_INDEX IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_4, 0x0a00) +#define GPIO4_5_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_5, 0x0a00) +#define GPIO4_5_AS_PGA0_ANA_EXT0 IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_13, 0x0a00) + +#define GPIO4_6_AS_GPIO4_6 IOCMG_PIN_MUX(IOCFG_GPIO4_6, FUNC_MODE_0, 0x0a00) +#define GPIO4_6_AS_ADC_EXT_TRIG0 IOCMG_PIN_MUX(IOCFG_GPIO4_6, FUNC_MODE_6, 0x0a00) +#define GPIO4_6_AS_ADC0_ANA_A3 IOCMG_PIN_MUX(IOCFG_GPIO4_6, FUNC_MODE_12, 0x0a00) +#define GPIO4_6_AS_PGA1_ANA_P3 IOCMG_PIN_MUX(IOCFG_GPIO4_6, FUNC_MODE_13, 0x0a00) +#define GPIO4_6_AS_ADC2_ANA_A14 IOCMG_PIN_MUX(IOCFG_GPIO4_6, FUNC_MODE_14, 0x0a00) + +#define GPIO4_7_AS_GPIO4_7 IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_0, 0x0a00) +#define GPIO4_7_AS_CAN_RX IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_4, 0x0a00) +#define GPIO4_7_AS_UART1_RTSN IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_5, 0x0a00) +#define GPIO4_7_AS_UART0_RXD IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_6, 0x0a00) +#define GPIO4_7_AS_ADC0_ANA_A4 IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_12, 0x0a00) +#define GPIO4_7_AS_PGA1_ANA_N3 IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_13, 0x0a00) +#define GPIO4_7_AS_ACMP0_ANA_N1 IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_14, 0x0a00) +#define GPIO4_7_AS_ADC2_ANA_A15 IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_15, 0x0a00) + +#define GPIO5_0_AS_GPIO5_0 IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_0, 0x0a00) +#define GPIO5_0_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_1, 0x0a00) +#define GPIO5_0_AS_ACMP0_OUT IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_2, 0x0a00) +#define GPIO5_0_AS_APT_EVTMP4 IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_3, 0x0a00) +#define GPIO5_0_AS_CAN_TX IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_4, 0x0a00) +#define GPIO5_0_AS_ADC0_STATUS IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_5, 0x0a00) +#define GPIO5_0_AS_UART0_TXD IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_6, 0x0a00) +#define GPIO5_0_AS_PGA1_ANA_EXT1 IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_13, 0x0a00) + +#define GPIO5_1_AS_GPIO5_1 IOCMG_PIN_MUX(IOCFG_GPIO5_1, FUNC_MODE_0, 0x0a00) +#define GPIO5_1_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO5_1, FUNC_MODE_3, 0x0a00) +#define GPIO5_1_AS_SPI1_CSN0 IOCMG_PIN_MUX(IOCFG_GPIO5_1, FUNC_MODE_4, 0x0a00) +#define GPIO5_1_AS_UART1_TXD IOCMG_PIN_MUX(IOCFG_GPIO5_1, FUNC_MODE_5, 0x0a00) + +#define GPIO5_2_AS_GPIO5_2 IOCMG_PIN_MUX(IOCFG_GPIO5_2, FUNC_MODE_0, 0x0a00) +#define GPIO5_2_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO5_2, FUNC_MODE_3, 0x0a00) +#define GPIO5_2_AS_SPI1_MOSI IOCMG_PIN_MUX(IOCFG_GPIO5_2, FUNC_MODE_4, 0x0a00) +#define GPIO5_2_AS_UART1_RXD IOCMG_PIN_MUX(IOCFG_GPIO5_2, FUNC_MODE_5, 0x0a00) + +#define GPIO5_3_AS_GPIO5_3 IOCMG_PIN_MUX(IOCFG_GPIO5_3, FUNC_MODE_0, 0x0a00) +#define GPIO5_3_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO5_3, FUNC_MODE_2, 0x0a00) +#define GPIO5_3_AS_SPI1_MISO IOCMG_PIN_MUX(IOCFG_GPIO5_3, FUNC_MODE_4, 0x0a00) +#define GPIO5_3_AS_UART2_RXD IOCMG_PIN_MUX(IOCFG_GPIO5_3, FUNC_MODE_5, 0x0a00) + +#define GPIO5_4_AS_GPIO5_4 IOCMG_PIN_MUX(IOCFG_GPIO5_4, FUNC_MODE_0, 0x0a00) +#define GPIO5_4_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO5_4, FUNC_MODE_2, 0x0a00) +#define GPIO5_4_AS_SPI1_CLK IOCMG_PIN_MUX(IOCFG_GPIO5_4, FUNC_MODE_4, 0x0a00) +#define GPIO5_4_AS_UART2_TXD IOCMG_PIN_MUX(IOCFG_GPIO5_4, FUNC_MODE_5, 0x0a00) + +#define GPIO5_5_AS_GPIO5_5 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_0, 0x0a00) +#define GPIO5_5_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_2, 0x0a00) +#define GPIO5_5_AS_QDM1_INDEX IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_3, 0x0a00) +#define GPIO5_5_AS_SPI1_CSN1 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_4, 0x0a00) +#define GPIO5_5_AS_ADC0_GPIO0 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_9, 0x0a00) +#define GPIO5_5_AS_ADC1_GPIO0 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_10, 0x0a00) +#define GPIO5_5_AS_ADC2_GPIO0 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_11, 0x0a00) +#define GPIO5_5_AS_ADC2_ANA_A9 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_12, 0x0a00) +#define GPIO5_5_AS_PGA2_ANA_P0 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_13, 0x0a00) +#define GPIO5_5_AS_ACMP0_ANA_P1 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_14, 0x0a00) + +#define GPIO5_6_AS_GPIO5_6 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_0, 0x0a00) +#define GPIO5_6_AS_UART2_CTSN IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_2, 0x0a00) +#define GPIO5_6_AS_QDM1_A IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_3, 0x0a00) +#define GPIO5_6_AS_UART4_CTSN IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_4, 0x0a00) +#define GPIO5_6_AS_ADC0_GPIO1 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_9, 0x0a00) +#define GPIO5_6_AS_ADC1_GPIO1 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_10, 0x0a00) +#define GPIO5_6_AS_ADC2_GPIO1 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_11, 0x0a00) +#define GPIO5_6_AS_ADC2_ANA_A6 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_12, 0x0a00) +#define GPIO5_6_AS_PGA2_ANA_N0 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_13, 0x0a00) + +#define GPIO5_7_AS_GPIO5_7 IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_0, 0x0a00) +#define GPIO5_7_AS_UART2_RTSN IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_2, 0x0a00) +#define GPIO5_7_AS_QDM1_B IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_3, 0x0a00) +#define GPIO5_7_AS_UART4_RTSN IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_4, 0x0a00) +#define GPIO5_7_AS_ADC0_GPIO2 IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_9, 0x0a00) +#define GPIO5_7_AS_ADC1_GPIO2 IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_10, 0x0a00) +#define GPIO5_7_AS_ADC2_GPIO2 IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_11, 0x0a00) +#define GPIO5_7_AS_PGA2_ANA_EXT0 IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_13, 0x0a00) + +#define GPIO6_0_AS_GPIO6_0 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_0, 0x0a00) +#define GPIO6_0_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_1, 0x0a00) +#define GPIO6_0_AS_SPI1_CSN1 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_2, 0x0a00) +#define GPIO6_0_AS_UART2_TXD IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_3, 0x0a00) +#define GPIO6_0_AS_QDM0_A IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_4, 0x0a00) +#define GPIO6_0_AS_ADC0_GPIO3 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_9, 0x0a00) +#define GPIO6_0_AS_ADC1_GPIO3 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_10, 0x0a00) +#define GPIO6_0_AS_ADC2_GPIO3 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_11, 0x0a00) +#define GPIO6_0_AS_ADC2_ANA_A7 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_12, 0x0a00) +#define GPIO6_0_AS_ACMP2_ANA_N1 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_13, 0x0a00) +#define GPIO6_0_AS_ADC0_ANA_A13 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_14, 0x0a00) + +#define GPIO6_1_AS_GPIO6_1 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_0, 0x0a00) +#define GPIO6_1_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_1, 0x0a00) +#define GPIO6_1_AS_SPI1_MOSI IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_2, 0x0a00) +#define GPIO6_1_AS_UART2_RXD IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_3, 0x0a00) +#define GPIO6_1_AS_QDM0_B IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_4, 0x0a00) +#define GPIO6_1_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_5, 0x0a00) +#define GPIO6_1_AS_ADC0_GPIO4 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_9, 0x0a00) +#define GPIO6_1_AS_ADC1_GPIO4 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_10, 0x0a00) +#define GPIO6_1_AS_ADC2_GPIO4 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_11, 0x0a00) +#define GPIO6_1_AS_ADC2_ANA_A8 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_12, 0x0a00) +#define GPIO6_1_AS_ACMP2_ANA_P1 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_13, 0x0a00) +#define GPIO6_1_AS_ADC1_ANA_A9 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_14, 0x0a00) + +#define GPIO6_2_AS_GPIO6_2 IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_0, 0x0a00) +#define GPIO6_2_AS_ACMP2_OUT IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_2, 0x0a00) +#define GPIO6_2_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_3, 0x0a00) +#define GPIO6_2_AS_QDM0_INDEX IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_4, 0x0a00) +#define GPIO6_2_AS_SPI1_MISO IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_5, 0x0a00) +#define GPIO6_2_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_6, 0x0a00) +#define GPIO6_2_AS_ADC2_STATUS IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_7, 0x0a00) +#define GPIO6_2_AS_ADC2_ANA_A5 IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_12, 0x0a00) +#define GPIO6_2_AS_ADC1_ANA_A7 IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_13, 0x0a00) + +#define GPIO6_3_AS_GPIO6_3 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_0, 0x0a00) +#define GPIO6_3_AS_UART4_RXD IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_1, 0x0a00) +#define GPIO6_3_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_2, 0x0a00) +#define GPIO6_3_AS_CAN_RX IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_3, 0x0a00) +#define GPIO6_3_AS_SPI1_CSN0 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_4, 0x0a00) +#define GPIO6_3_AS_ADC_EXT_TRIG2 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_5, 0x0a00) +#define GPIO6_3_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_6, 0x0a00) +#define GPIO6_3_AS_SMB0_ALTN IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_7, 0x0a00) +#define GPIO6_3_AS_ANA_CTRL_GPIO0 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_11, 0x0a00) +#define GPIO6_3_AS_ADC2_ANA_A2 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_12, 0x0a00) +#define GPIO6_3_AS_ADC0_ANA_A14 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_13, 0x0a00) + +#define GPIO6_4_AS_GPIO6_4 IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_0, 0x0a00) +#define GPIO6_4_AS_UART4_TXD IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_1, 0x0a00) +#define GPIO6_4_AS_APT_EVTMP6 IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_2, 0x0a00) +#define GPIO6_4_AS_CAN_TX IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_3, 0x0a00) +#define GPIO6_4_AS_SPI1_CLK IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_4, 0x0a00) +#define GPIO6_4_AS_SMB0_SPNDN IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_5, 0x0a00) +#define GPIO6_4_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_6, 0x0a00) +#define GPIO6_4_AS_ANA_CTRL_GPI IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_11, 0x0a00) +#define GPIO6_4_AS_ADC2_ANA_A10 IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_12, 0x0a00) +#define GPIO6_4_AS_ADC0_ANA_A15 IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_13, 0x0a00) +#define GPIO6_4_AS_DAC0_ANA_OUT IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_14, 0x0a00) + +#define GPIO6_5_AS_GPIO6_5 IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_0, 0x0a00) +#define GPIO6_5_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_1, 0x0a00) +#define GPIO6_5_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_2, 0x0a00) +#define GPIO6_5_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_3, 0x0a00) +#define GPIO6_5_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_5, 0x0a00) +#define GPIO6_5_AS_UART3_RXD IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_6, 0x0a00) + +#define GPIO6_6_AS_GPIO6_6 IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_0, 0x0a00) +#define GPIO6_6_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_1, 0x0a00) +#define GPIO6_6_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_2, 0x0a00) +#define GPIO6_6_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_3, 0x0a00) +#define GPIO6_6_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_4, 0x0a00) +#define GPIO6_6_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_5, 0x0a00) +#define GPIO6_6_AS_UART3_TXD IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_6, 0x0a00) +#define GPIO6_6_AS_EF_BIST_SCE IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_11, 0x0a00) + +#define GPIO6_7_AS_GPIO6_7 IOCMG_PIN_MUX(IOCFG_GPIO6_7, FUNC_MODE_0, 0x0a00) +#define GPIO6_7_AS_APT3_PWMA IOCMG_PIN_MUX(IOCFG_GPIO6_7, FUNC_MODE_1, 0x0a00) +#define GPIO6_7_AS_UART1_RXD IOCMG_PIN_MUX(IOCFG_GPIO6_7, FUNC_MODE_2, 0x0a00) + +#define GPIO7_0_AS_GPIO7_0 IOCMG_PIN_MUX(IOCFG_GPIO7_0, FUNC_MODE_0, 0x0a30) +#define GPIO7_0_AS_APT4_PWMA IOCMG_PIN_MUX(IOCFG_GPIO7_0, FUNC_MODE_1, 0x0a30) +#define GPIO7_0_AS_UART1_TXD IOCMG_PIN_MUX(IOCFG_GPIO7_0, FUNC_MODE_2, 0x0a30) +#define GPIO7_0_AS_EF_BIST_SDO IOCMG_PIN_MUX(IOCFG_GPIO7_0, FUNC_MODE_11, 0x0a30) + +#define GPIO7_1_AS_GPIO7_1 IOCMG_PIN_MUX(IOCFG_GPIO7_1, FUNC_MODE_0, 0x0a00) +#define GPIO7_1_AS_APT5_PWMA IOCMG_PIN_MUX(IOCFG_GPIO7_1, FUNC_MODE_1, 0x0a00) +#define GPIO7_1_AS_SPI0_CSN0 IOCMG_PIN_MUX(IOCFG_GPIO7_1, FUNC_MODE_3, 0x0a00) +#define GPIO7_1_AS_UART1_RTSN IOCMG_PIN_MUX(IOCFG_GPIO7_1, FUNC_MODE_4, 0x0a00) +#define GPIO7_1_AS_UART3_RTSN IOCMG_PIN_MUX(IOCFG_GPIO7_1, FUNC_MODE_5, 0x0a00) + +#define GPIO7_2_AS_GPIO7_2 IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_0, 0x0a00) +#define GPIO7_2_AS_APT3_PWMB IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_1, 0x0a00) +#define GPIO7_2_AS_SPI0_MOSI IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_3, 0x0a00) +#define GPIO7_2_AS_UART1_CTSN IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_4, 0x0a00) +#define GPIO7_2_AS_UART3_CTSN IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_5, 0x0a00) +#define GPIO7_2_AS_EF_BIST_SDI IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_11, 0x0a00) + +#define GPIO7_3_AS_GPIO7_3 IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_0, 0x0a00) +#define GPIO7_3_AS_APT4_PWMB IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_1, 0x0a00) +#define GPIO7_3_AS_SPI0_MISO IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_3, 0x0a00) +#define GPIO7_3_AS_UART2_RTSN IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_4, 0x0a00) +#define GPIO7_3_AS_UART4_RTSN IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_5, 0x0a00) +#define GPIO7_3_AS_SMB0_ALTN IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_6, 0x0a00) + +#define GPIO7_4_AS_GPIO7_4 IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_0, 0x0a00) +#define GPIO7_4_AS_APT5_PWMB IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_1, 0x0a00) +#define GPIO7_4_AS_QDM2_INDEX IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_2, 0x0a00) +#define GPIO7_4_AS_SPI0_CLK IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_3, 0x0a00) +#define GPIO7_4_AS_UART2_CTSN IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_4, 0x0a00) +#define GPIO7_4_AS_UART4_CTSN IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_5, 0x0a00) +#define GPIO7_4_AS_SMB0_SPNDN IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_6, 0x0a00) +#define GPIO7_4_AS_EF_BIST_SCK IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_11, 0x0a00) + +#define GPIO7_5_AS_GPIO7_5 IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_0, 0x0a00) +#define GPIO7_5_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_1, 0x0a00) +#define GPIO7_5_AS_CAN_TX IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_2, 0x0a00) +#define GPIO7_5_AS_SPI0_CSN1 IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_3, 0x0a00) +#define GPIO7_5_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_4, 0x0a00) +#define GPIO7_5_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_5, 0x0a00) +#define GPIO7_5_AS_UART4_TXD IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_6, 0x0a00) + +#define GPIO7_6_AS_GPIO7_6 IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_0, 0x0a00) +#define GPIO7_6_AS_UART2_TXD IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_1, 0x0a00) +#define GPIO7_6_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_2, 0x0a00) +#define GPIO7_6_AS_WAKEUP2 IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_3, 0x0a00) +#define GPIO7_6_AS_APT_EVTIO4 IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_4, 0x0a00) +#define GPIO7_6_AS_QDM2_A IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_5, 0x0a00) +#define GPIO7_6_AS_PMU_ALDO_OK IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_11, 0x0a00) +#define GPIO7_6_AS_ADC2_ANA_A3 IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_12, 0x0a00) +#define GPIO7_6_AS_DAC1_ANA_OUT IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_13, 0x0a00) +#define GPIO7_6_AS_ADC0_ANA_A12 IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_14, 0x0a00) + +#define GPIO7_7_AS_GPIO7_7 IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_0, 0x0a00) +#define GPIO7_7_AS_UART2_RXD IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_1, 0x0a00) +#define GPIO7_7_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_2, 0x0a00) +#define GPIO7_7_AS_WAKEUP3 IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_3, 0x0a00) +#define GPIO7_7_AS_QDM2_B IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_5, 0x0a00) +#define GPIO7_7_AS_PMU_CLDO_EN IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_11, 0x0a00) +#define GPIO7_7_AS_ADC2_ANA_A4 IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_12, 0x0a00) +#define GPIO7_7_AS_DAC2_ANA_OUT IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_13, 0x0a00) + +#define GPIO8_0_AS_GPIO8_0 IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_0, 0x0a00) +#define GPIO8_0_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_1, 0x0a00) +#define GPIO8_0_AS_CAN_RX IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_2, 0x0a00) +#define GPIO8_0_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_3, 0x0a00) +#define GPIO8_0_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_4, 0x0a00) +#define GPIO8_0_AS_UART4_RXD IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_5, 0x0a00) + +#define GPIO8_1_AS_GPIO8_1 IOCMG_PIN_MUX(IOCFG_GPIO8_1, FUNC_MODE_0, 0x0f01) +#define GPIO8_1_AS_RESETN IOCMG_PIN_MUX(IOCFG_GPIO8_1, FUNC_MODE_1, 0x0f01) +#define GPIO8_1_AS_SYS_RSTN_OUT IOCMG_PIN_MUX(IOCFG_GPIO8_1, FUNC_MODE_2, 0x0f01) +#define GPIO8_1_AS_PMU_CLDO_OK IOCMG_PIN_MUX(IOCFG_GPIO8_1, FUNC_MODE_11, 0x0f01) + +#define GPIO8_2_AS_GPIO8_2 IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_0, 0x0a00) +#define GPIO8_2_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_1, 0x0a00) +#define GPIO8_2_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_2, 0x0a00) +#define GPIO8_2_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_3, 0x0a00) +#define GPIO8_2_AS_UART3_TXD IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_4, 0x0a00) +#define GPIO8_2_AS_QDM1_INDEX IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_5, 0x0a00) +#define GPIO8_2_AS_UART1_CTSN IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_6, 0x0a00) +#define GPIO8_2_AS_SMB0_ALTN IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_7, 0x0a00) +#define GPIO8_2_AS_PLL_LOCK IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_9, 0x0a00) +#define GPIO8_2_AS_HOSC_LOCK IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_10, 0x0a00) +#define GPIO8_2_AS_EF_PORB IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_11, 0x0a00) + +#define GPIO8_3_AS_GPIO8_3 IOCMG_PIN_MUX(IOCFG_GPIO8_3, FUNC_MODE_0, 0x0a00) +#define GPIO8_3_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO8_3, FUNC_MODE_1, 0x0a00) +#define GPIO8_3_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_3, FUNC_MODE_2, 0x0a00) +#define GPIO8_3_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_3, FUNC_MODE_3, 0x0a00) + +#define GPIO8_4_AS_GPIO8_4 IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_0, 0x0a00) +#define GPIO8_4_AS_UART3_RXD IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_1, 0x0a00) +#define GPIO8_4_AS_CAN_RX IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_2, 0x0a00) +#define GPIO8_4_AS_QDM2_A IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_3, 0x0a00) +#define GPIO8_4_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_4, 0x0a00) +#define GPIO8_4_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_5, 0x0a00) +#define GPIO8_4_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_6, 0x0a00) +#define GPIO8_4_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_7, 0x0a00) + +#define GPIO8_5_AS_GPIO8_5 IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_0, 0x0a00) +#define GPIO8_5_AS_UART3_TXD IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_1, 0x0a00) +#define GPIO8_5_AS_CAN_TX IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_2, 0x0a00) +#define GPIO8_5_AS_QDM2_B IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_3, 0x0a00) +#define GPIO8_5_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_4, 0x0a00) +#define GPIO8_5_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_5, 0x0a00) +#define GPIO8_5_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_6, 0x0a00) +#define GPIO8_5_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_7, 0x0a00) + +#define GPIO8_6_AS_GPIO8_6 IOCMG_PIN_MUX(IOCFG_GPIO8_6, FUNC_MODE_0, 0x0a00) +#define GPIO8_6_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_6, FUNC_MODE_1, 0x0a00) +#define GPIO8_6_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_6, FUNC_MODE_2, 0x0a00) +#define GPIO8_6_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO8_6, FUNC_MODE_3, 0x0a00) +#define GPIO8_6_AS_UART4_TXD IOCMG_PIN_MUX(IOCFG_GPIO8_6, FUNC_MODE_4, 0x0a00) + +#define GPIO8_7_AS_GPIO8_7 IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_0, 0x0a00) +#define GPIO8_7_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_1, 0x0a00) +#define GPIO8_7_AS_UART4_TXD IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_2, 0x0a00) +#define GPIO8_7_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_3, 0x0a00) +#define GPIO8_7_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_4, 0x0a00) +#define GPIO8_7_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_5, 0x0a00) + +#define GPIO9_0_AS_GPIO9_0 IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_0, 0x0a00) +#define GPIO9_0_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_1, 0x0a00) +#define GPIO9_0_AS_UART4_RXD IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_2, 0x0a00) +#define GPIO9_0_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_3, 0x0a00) +#define GPIO9_0_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_4, 0x0a00) +#define GPIO9_0_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_5, 0x0a00) + +#endif /* McuMagicTag_IOMAP_H */ \ No newline at end of file diff --git a/src/chip/3065p/ip_crg/ip_crg_common.c b/src/chip/3065p/ip_crg/ip_crg_common.c new file mode 100644 index 0000000000000000000000000000000000000000..c5a6c4582a5ac6b1f5313714019dff3e9bb54142 --- /dev/null +++ b/src/chip/3065p/ip_crg/ip_crg_common.c @@ -0,0 +1,124 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file ip_crg_common.c + * @author MCU Driver Team + * @brief Contains ip crg common header files. + */ + +/* Includes ----------------------------------------------------------------- */ +#include "baseaddr.h" +#include "ip_crg_common.h" + +/** + * @brief Get IP frequency by ip register base address + * @param ipBaseAddr The ip base address + * @retval The bus frequency where the IP is located + */ +#ifdef FPGA +unsigned int CHIP_GetIpFreqHz(const void *ipBaseAddr) +{ + if (ipBaseAddr == IWDG_BASE) { /* The IWDG working clock is LOSC clock. */ + return LOSC_FREQ; + } else { + return HOSC_FREQ; /* The base address does not match, return LOSC freq. */ + } +} +#endif + +static const CHIP_CrgIpMatchInfo g_crgIpMatch[] = { + {UART0_BASE, CRG_IP_NONE_CLK_SEL, 0x140, 0}, + {UART1_BASE, CRG_IP_NONE_CLK_SEL, 0x144, 0}, + {UART2_BASE, CRG_IP_NONE_CLK_SEL, 0x148, 0}, + {UART3_BASE, CRG_IP_NONE_CLK_SEL, 0x14C, 0}, + {UART4_BASE, CRG_IP_NONE_CLK_SEL, 0x150, 0}, + {TIMER0_BASE, CRG_IP_NONE_CLK_SEL, 0x240, 0}, + {TIMER1_BASE, CRG_IP_NONE_CLK_SEL, 0x244, 0}, + {TIMER2_BASE, CRG_IP_NONE_CLK_SEL, 0x248, 0}, + {TIMER3_BASE, CRG_IP_NONE_CLK_SEL, 0x24C, 0}, + {SYSTICK_BASE, CRG_IP_NONE_CLK_SEL, 0x40, 0}, + {SPI0_BASE, CRG_IP_NONE_CLK_SEL, 0x180, 0}, + {SPI1_BASE, CRG_IP_NONE_CLK_SEL, 0x184, 0}, + {I2C0_BASE, CRG_IP_NONE_CLK_SEL, 0x1C0, 0}, + {CAN_BASE, CRG_IP_CAN, 0x2C0, 0}, + {CAN1_BASE, CRG_IP_CAN, 0x2C4, 0}, + {GPT0_BASE, CRG_IP_NONE_CLK_SEL, 0x440, 0}, + {GPT1_BASE, CRG_IP_NONE_CLK_SEL, 0x444, 0}, + {WWDG_BASE, CRG_IP_WWDG, 0x200, 0}, + {CAPM0_BASE, CRG_IP_NONE_CLK_SEL, 0x280, 0}, + {CAPM1_BASE, CRG_IP_NONE_CLK_SEL, 0x284, 0}, + {CAPM2_BASE, CRG_IP_NONE_CLK_SEL, 0x288, 0}, + {DMA_BASE, CRG_IP_NONE_CLK_SEL, 0x300, 0}, + {GPIO0_BASE, CRG_IP_NONE_CLK_SEL, 0x480, 0}, + {GPIO1_BASE, CRG_IP_NONE_CLK_SEL, 0x484, 0}, + {GPIO2_BASE, CRG_IP_NONE_CLK_SEL, 0x488, 0}, + {GPIO3_BASE, CRG_IP_NONE_CLK_SEL, 0x48C, 0}, + {GPIO4_BASE, CRG_IP_NONE_CLK_SEL, 0x490, 0}, + {GPIO5_BASE, CRG_IP_NONE_CLK_SEL, 0x494, 0}, + {GPIO6_BASE, CRG_IP_NONE_CLK_SEL, 0x498, 0}, + {GPIO7_BASE, CRG_IP_NONE_CLK_SEL, 0x49C, 0}, + {GPIO8_BASE, CRG_IP_NONE_CLK_SEL, 0x4A0, 0}, + {GPIO9_BASE, CRG_IP_NONE_CLK_SEL, 0x4A4, 0}, + {IWDG_BASE, CRG_IP_IWDG, 0x3C0, 0}, + {QDM0_BASE, CRG_IP_NONE_CLK_SEL, 0x4C0, 0}, + {QDM1_BASE, CRG_IP_NONE_CLK_SEL, 0x4C4, 0}, + {QDM2_BASE, CRG_IP_NONE_CLK_SEL, 0x4C8, 0}, + {QDM3_BASE, CRG_IP_NONE_CLK_SEL, 0x4CC, 0}, + {CRC_BASE, CRG_IP_NONE_CLK_SEL, 0x380, 0}, + {APT0_BASE, CRG_IP_NONE_CLK_SEL, 0x400, 0}, + {APT1_BASE, CRG_IP_NONE_CLK_SEL, 0x404, 0}, + {APT2_BASE, CRG_IP_NONE_CLK_SEL, 0x408, 0}, + {APT3_BASE, CRG_IP_NONE_CLK_SEL, 0x40C, 0}, + {APT4_BASE, CRG_IP_NONE_CLK_SEL, 0x410, 0}, + {APT5_BASE, CRG_IP_NONE_CLK_SEL, 0x414, 0}, + {APT6_BASE, CRG_IP_NONE_CLK_SEL, 0x418, 0}, + {APT7_BASE, CRG_IP_NONE_CLK_SEL, 0x41C, 0}, + {APT8_BASE, CRG_IP_NONE_CLK_SEL, 0x420, 0}, + {CMM_BASE, CRG_IP_NONE_CLK_SEL, 0x0340, 0}, + {CFD_BASE, CRG_IP_NONE_CLK_SEL, 0x0344, 0}, + {VREF_BASE, CRG_IP_ANA, 0xA60, 0}, + {ACMP0_BASE, CRG_IP_ANA, 0xA70, 0}, + {ACMP1_BASE, CRG_IP_ANA, 0xA74, 0}, + {ACMP2_BASE, CRG_IP_ANA, 0xA78, 0}, + {DAC0_BASE, CRG_IP_ANA, 0xA80, 0}, + {DAC1_BASE, CRG_IP_ANA, 0xA84, 0}, + {DAC2_BASE, CRG_IP_ANA, 0xA88, 0}, + {PGA0_BASE, CRG_IP_ANA, 0xA90, 0}, + {PGA1_BASE, CRG_IP_ANA, 0xA94, 0}, + {PGA2_BASE, CRG_IP_ANA, 0xA98, 0}, + {ADC0_BASE, CRG_IP_ADC, 0xA00, 0}, + {ADC1_BASE, CRG_IP_ADC, 0xA08, 0}, + {ADC2_BASE, CRG_IP_ADC, 0xA10, 0}, + {EFC_BASE, CRG_IP_EFC, 0x500, 0}, +}; + +/** + * @brief Get IP Match Info, @see g_crgIpMatch + * @param baseAddr The ip base address + * @retval The Address(offset) in g_crgIpMatch if match success + * @retval 0 if match fail + */ +CHIP_CrgIpMatchInfo *GetCrgIpMatchInfo(const void *baseAddr) +{ + unsigned int i; + for (i = 0; i < sizeof(g_crgIpMatch) / sizeof(g_crgIpMatch[0]); ++i) { + if (baseAddr == g_crgIpMatch[i].ipBaseAddr) { + return (CHIP_CrgIpMatchInfo *)&g_crgIpMatch[i]; + } + } + return (CHIP_CrgIpMatchInfo *)0; /* The base address does not match, return 0. */ +} diff --git a/src/chip/3065p/ip_crg/ip_crg_common.h b/src/chip/3065p/ip_crg/ip_crg_common.h new file mode 100644 index 0000000000000000000000000000000000000000..431319ca1f49bf2ea1b46942fefe7efacf15e482 --- /dev/null +++ b/src/chip/3065p/ip_crg/ip_crg_common.h @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file ip_crg_common.h + * @author MCU Driver Team + * @brief Contains crg ip common header files. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_IP_CRG_COMMON_H +#define McuMagicTag_IP_CRG_COMMON_H + +/** + * @brief define the frequence of hosc, losc and xtrail + */ +#define HOSC_FREQ 25000000U +#define LOSC_FREQ 32000U + +/** + * @brief CRG Ip Type, Sorting based on operable registers + */ +typedef enum { + CRG_IP_WWDG = 0x0, + CRG_IP_NONE_CLK_SEL = 0x01, + CRG_IP_CAN = 0x02, + CRG_IP_ADC = 0x03, + CRG_IP_EFC = 0x04, + CRG_IP_IWDG = 0x05, + CRG_IP_ANA = 0x06, + CRG_IP_MAX_TYPE = 0x07, +} CHIP_CrgIpType; + +/** + * @brief CRG register and IP address matching relationship table + */ +typedef struct { + void *ipBaseAddr; /**< Ip base address */ + CHIP_CrgIpType type; /**< Ip type, @see CHIP_CrgIpType */ + unsigned short regOffset; /**< Offset in CRG registers */ + unsigned char bitOffset; /**< Bit Offset in CRG register */ +} CHIP_CrgIpMatchInfo; + +unsigned int CHIP_GetIpFreqHz(const void *ipBaseAddr); +CHIP_CrgIpMatchInfo *GetCrgIpMatchInfo(const void *baseAddr); +extern unsigned int HAL_CRG_GetIpFreq(const void *baseAddress); + +#endif /* McuMagicTag_IP_CRG_COMMON_H */ diff --git a/src/chip/3065p/locktype.h b/src/chip/3065p/locktype.h new file mode 100644 index 0000000000000000000000000000000000000000..d6cee22cc2912aadaf5bc5ca7104c0d7c1f97afb --- /dev/null +++ b/src/chip/3065p/locktype.h @@ -0,0 +1,43 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file locktype.h + * @author MCU Driver Team + * @brief This file lists all types that need to be locked on the chip. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_LOCKTYPE_H +#define McuMagicTag_LOCKTYPE_H + +/* Typedef definitions ------------------------------------------------------- */ +/** + * @brief This enum defines all hardware locks integrated by this MCU. + */ +typedef enum { + CHIP_LOCK_GPIO0 = 0, + CHIP_LOCK_GPIO1 = 1, + CHIP_LOCK_GPIO2 = 2, + CHIP_LOCK_GPIO3 = 3, + CHIP_LOCK_GPIO4 = 4, + CHIP_LOCK_GPIO5 = 5, + CHIP_LOCK_GPIO6 = 6, + CHIP_LOCK_GPIO7 = 7, + CHIP_LOCK_TOTAL +} CHIP_LockType; + +#endif /* McuMagicTag_LOCKTYPE_H */ \ No newline at end of file diff --git a/src/chip/3065p/startup.S b/src/chip/3065p/startup.S new file mode 100644 index 0000000000000000000000000000000000000000..2fac3aec9ca897c13b91ccaf052a1806ed3c1477 --- /dev/null +++ b/src/chip/3065p/startup.S @@ -0,0 +1,848 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file startup.S + * @author MCU Application Driver Team + * @brief RISC-V trap handling and startup code + */ + +#ifndef ENTRY_S +#define ENTRY_S + +#include "feature.h" +#ifdef NOS_TASK_SUPPORT +.extern OsHwiPostHandle +.extern OsTaskTrueSwitch +#define NOS_HwiPostDispatch OsHwiPostHandle +#define NOS_TaskDispatch OsTaskTrueSwitch +#define NOS_TASK_SWITCH_MAGIC_NUM 0xACBCCCDC +#define TICK_IRQ_EN_BASE 0xBE0 +#define TICK_IRQ_EN_NUM 0x8 +#endif + +.extern __stack_top +.extern __irq_stack_top +.extern SysErrNmiEntry +.extern SysErrExcEntry +.extern trap_entry +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) +.extern g_RiscvPrivMode +#endif + +#ifdef __riscv64 +#define LREG ld +#define SREG sd +#define FLREG fld +#define FSREG fsd +#define REGBYTES 8 +#else +#define LREG lw +#define SREG sw +#define FLREG flw +#define FSREG fsw +#define REGBYTES 4 +#endif + +#define NESTED_IRQ_SUPPORT +#define COMPILE_LDM /**< Support stmia and ldmia instruction */ + +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs more stack to restore TickIRQEnable */ +#ifdef FLOAT_SUPPORT +#define TOTAL_INT_SIZE_ON_STACK (44 * REGBYTES) +#else +#define TOTAL_INT_SIZE_ON_STACK (24 * REGBYTES) +#endif +#else +#ifdef FLOAT_SUPPORT +#define TOTAL_INT_SIZE_ON_STACK (40 * REGBYTES) +#else +#define TOTAL_INT_SIZE_ON_STACK (20 * REGBYTES) +#endif +#endif + +#define SYSERR_INT_SIZE_ON_STACK (28 * REGBYTES) + +#define MSTATUS_MPP_MACHINE 0x00001800 +#define MCAUSE_ECALL_FROM_MMODE 11 +#define MCAUSE_ECALL_FROM_UMODE 8 +#define EXC_SIZE_ON_STACK (160) + +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_MPIE 0x00000080 +#define MCAUSE_MASK_INT_BIT 0x80000000 +#define MCAUSE_MASK_INT_NUM 0x000000FF + +#define locipri0 0xBC0 +#define locipri1 0xBC1 +#define locipri2 0xBC2 +#define locipri3 0xBC3 +#define locipri4 0xBC4 +#define locipri5 0xBC5 +#define locipri6 0xBC6 +#define locipri7 0xBC7 +#define locipri8 0xBC8 +#define locipri9 0xBC9 +#define locipri10 0xBCA +#define locipri11 0xBCB +#define locipri12 0xBCC +#define locipri13 0xBCD +#define locipri14 0xBCE +#define locipri15 0xBCF + +#define EFC_BASE_ADDR 0x14710000 /* efc base address */ +#define EFC_MAGIC_LOCK_RW 0x14710200 /* cmd operation magic word protection register */ +#define EFC_MAGIC_NUMBER 0xFEDCBA98 /* magic number */ +#define SYSRAM_ERROR 0x10108300 +#define SC_SYS_STAT_ADDR 0x10100018 /**< System state register address */ +#define TIMER0_CONTROL 0x14300008 +#define TIMER0_INTENABLE (1 << 5) +#define UART0_BASE_ADDR 0x14000000 +#define IBRD_OFFSET 0x24 +#define FBRD_OFFSET 0x28 +#define LCR_H_OFFSET 0x2C +#define CR_OFFSET 0x30 +#define DMACR_OFFSET 0x48 + +.equ cipri, 0x7ED +.equ prithd, 0xBFE + + .section .data.magic + .word 0xA37E95BD /* eflash magic number, bootrom will check it */ + + .section .text.entry + .global _start + .option norvc +_start: + j handle_reset + +.macro push_reg + addi sp, sp, -(TOTAL_INT_SIZE_ON_STACK) +#ifdef COMPILE_LDM + stmia {ra, t0-t2, a0-a7, t3-t6}, (sp) +#else + SREG ra, 0 * REGBYTES(sp) + SREG t0, 1 * REGBYTES(sp) + SREG t1, 2 * REGBYTES(sp) + SREG t2, 3 * REGBYTES(sp) + SREG a0, 4 * REGBYTES(sp) + SREG a1, 5 * REGBYTES(sp) + SREG a2, 6 * REGBYTES(sp) + SREG a3, 7 * REGBYTES(sp) + SREG a4, 8 * REGBYTES(sp) + SREG a5, 9 * REGBYTES(sp) + SREG a6, 10 * REGBYTES(sp) + SREG a7, 11 * REGBYTES(sp) + SREG t3, 12 * REGBYTES(sp) + SREG t4, 13 * REGBYTES(sp) + SREG t5, 14 * REGBYTES(sp) + SREG t6, 15 * REGBYTES(sp) +#endif + addi sp, sp, -(TOTAL_INT_SIZE_ON_STACK) +.endm + +.macro pop_reg + addi sp, sp, TOTAL_INT_SIZE_ON_STACK +#ifdef COMPILE_LDM + ldmia {ra, t0-t2, a0-a7, t3-t6},(sp) +#else + LREG ra, 0 * REGBYTES(sp) + LREG t0, 1 * REGBYTES(sp) + LREG t1, 2 * REGBYTES(sp) + LREG t2, 3 * REGBYTES(sp) + LREG a0, 4 * REGBYTES(sp) + LREG a1, 5 * REGBYTES(sp) + LREG a2, 6 * REGBYTES(sp) + LREG a3, 7 * REGBYTES(sp) + LREG a4, 8 * REGBYTES(sp) + LREG a5, 9 * REGBYTES(sp) + LREG a6, 10 * REGBYTES(sp) + LREG a7, 11 * REGBYTES(sp) + LREG t3, 12 * REGBYTES(sp) + LREG t4, 13 * REGBYTES(sp) + LREG t5, 14 * REGBYTES(sp) + LREG t6, 15 * REGBYTES(sp) +#endif + addi sp, sp, TOTAL_INT_SIZE_ON_STACK +.endm + +.macro SAVE_SYSERR_REGS + addi sp,sp,-(SYSERR_INT_SIZE_ON_STACK) + SREG s0, 16 * REGBYTES(sp) + SREG s1, 17 * REGBYTES(sp) + SREG s2, 18 * REGBYTES(sp) + SREG s3, 19 * REGBYTES(sp) + SREG s4, 20 * REGBYTES(sp) + SREG s5, 21 * REGBYTES(sp) + SREG s6, 22 * REGBYTES(sp) + SREG s7, 23 * REGBYTES(sp) + SREG s8, 24 * REGBYTES(sp) + SREG s9, 25 * REGBYTES(sp) + SREG s10, 26 * REGBYTES(sp) + SREG s11, 27 * REGBYTES(sp) + + addi a1, sp, (TOTAL_INT_SIZE_ON_STACK + SYSERR_INT_SIZE_ON_STACK) + SREG a1, 28 * REGBYTES(sp) /* save original sp */ + + SREG gp, 29 * REGBYTES(sp) + SREG tp, 30 * REGBYTES(sp) + + csrr a0, mepc + csrr a1, mstatus + csrr a2, mtval + csrr a3, mcause + # csrr a4, ccause + + SREG a0, 31 * REGBYTES(sp) /* mepc */ + SREG a1, 32 * REGBYTES(sp) /* mstatus */ + SREG a2, 33 * REGBYTES(sp) /* mtval */ + SREG a3, 34 * REGBYTES(sp) /* mcause */ + # SREG a4, 35 * REGBYTES(sp) /* ccause */ + mv a0,sp +.endm + +/* The interrupt vector table must be aligned with 4 bytes */ +.align 2 +TrapHandler: + j TrapVector /* trap and INT 0 */ + j TrapVector /* INT 1 */ + j TrapVector /* INT 2 */ + j TrapVector /* INT 3 */ + j TrapVector /* INT 4 */ + j TrapVector /* INT 5 */ + j TrapVector /* INT 6 */ + j TrapVector /* INT 7 */ + j TrapVector /* INT 8 */ + j TrapVector /* INT 9 */ + j TrapVector /* INT 10 */ + j TrapVector /* INT 11 */ + j TrapVector /* INT 12 */ + j TrapVector /* INT 13 */ + j TrapVector /* INT 14 */ + j TrapVector /* INT 15 */ + j TrapVector /* INT 16 */ + j TrapVector /* INT 17 */ + j TrapVector /* INT 18 */ + j TrapVector /* INT 19 */ + j TrapVector /* INT 20 */ + j TrapVector /* INT 21 */ + j TrapVector /* INT 22 */ + j TrapVector /* INT 23 */ + j TrapVector /* INT 24 */ + j TrapVector /* INT 25 */ + + j IntHandler /* INT 26 */ + j IntHandler /* INT 27 */ + j IntHandler /* INT 28 */ + j IntHandler /* INT 29 */ + j IntHandler /* INT 30 */ + j IntHandler /* INT 31 */ + j IntHandler /* INT 32 */ + j IntHandler /* INT 33 */ + j IntHandler /* INT 34 */ + j IntHandler /* INT 35 */ + j IntHandler /* INT 36 */ + j IntHandler /* INT 37 */ + j IntHandler /* INT 38 */ + j IntHandler /* INT 39 */ + j IntHandler /* INT 40 */ + j IntHandler /* INT 41 */ + j IntHandler /* INT 42 */ + j IntHandler /* INT 43 */ + j IntHandler /* INT 44 */ + j IntHandler /* INT 45 */ + j IntHandler /* INT 46 */ + j IntHandler /* INT 47 */ + j IntHandler /* INT 48 */ + j IntHandler /* INT 49 */ + j IntHandler /* INT 50 */ + j IntHandler /* INT 51 */ + j IntHandler /* INT 52 */ + j IntHandler /* INT 53 */ + j IntHandler /* INT 54 */ + j IntHandler /* INT 55 */ + j IntHandler /* INT 56 */ + j IntHandler /* INT 57 */ + j IntHandler /* INT 58 */ + j IntHandler /* INT 59 */ + j IntHandler /* INT 60 */ + j IntHandler /* INT 61 */ + j IntHandler /* INT 62 */ + j IntHandler /* INT 63 */ + j IntHandler /* INT 64 */ + j IntHandler /* INT 65 */ + j IntHandler /* INT 66 */ + j IntHandler /* INT 67 */ + j IntHandler /* INT 68 */ + j IntHandler /* INT 69 */ + j IntHandler /* INT 70 */ + j IntHandler /* INT 71 */ + j IntHandler /* INT 72 */ + j IntHandler /* INT 73 */ + j IntHandler /* INT 74 */ + j IntHandler /* INT 75 */ + j IntHandler /* INT 76 */ + j IntHandler /* INT 77 */ + j IntHandler /* INT 78 */ + j IntHandler /* INT 79 */ + j IntHandler /* INT 80 */ + j IntHandler /* INT 81 */ + j IntHandler /* INT 82 */ + j IntHandler /* INT 83 */ + j IntHandler /* INT 84 */ + j IntHandler /* INT 85 */ + j IntHandler /* INT 86 */ + j IntHandler /* INT 87 */ + j IntHandler /* INT 88 */ + j IntHandler /* INT 89 */ + j IntHandler /* INT 90 */ + j IntHandler /* INT 91 */ + j IntHandler /* INT 92 */ + j IntHandler /* INT 93 */ + j IntHandler /* INT 94 */ + j IntHandler /* INT 95 */ + j IntHandler /* INT 96 */ + j IntHandler /* INT 97 */ + j IntHandler /* INT 98 */ + j IntHandler /* INT 99 */ + j IntHandler /* INT 100 */ + j IntHandler /* INT 101 */ + j IntHandler /* INT 102 */ + j IntHandler /* INT 103 */ + j IntHandler /* INT 104 */ + j IntHandler /* INT 105 */ + j IntHandler /* INT 106 */ + j IntHandler /* INT 107 */ + j IntHandler /* INT 108 */ + j IntHandler /* INT 109 */ + j IntHandler /* INT 110 */ + j IntHandler /* INT 111 */ + j IntHandler /* INT 112 */ + j IntHandler /* INT 113 */ + j IntHandler /* INT 114 */ + j IntHandler /* INT 115 */ + j IntHandler /* INT 116 */ + j IntHandler /* INT 117 */ + j IntHandler /* INT 118 */ + j IntHandler /* INT 119 */ + j IntHandler /* INT 120 */ + j IntHandler /* INT 121 */ + +.align 2 +NmiEntry: + SAVE_SYSERR_REGS + call SysErrNmiEntry +deadLoop1: + tail deadLoop1 + nop + +.align 2 +TrapEntry: + SAVE_SYSERR_REGS + /* Exception run with interrupts masked */ + csrc mstatus, MSTATUS_MIE + call SysErrExcEntry +deadLoop2: + tail deadLoop2 + +.align 2 +IntHandler: + addi sp, sp, -(TOTAL_INT_SIZE_ON_STACK) + + SREG a0, 3 * REGBYTES(sp) + SREG a1, 4 * REGBYTES(sp) + +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) + la a0, g_RiscvPrivMode + lw a1, (a0) + addi a1, a1, 1 + sw a1, (a0) +#endif + +#if defined(HARD_NESTED_IRQ_SUPPORT) && (HARD_NESTED_IRQ_SUPPORT == 1) + csrr a0, mcause +#else + csrr a0, cipri + csrr a1, prithd + csrw prithd, a0 /* read prithd */ + SREG a1, 6 * REGBYTES(sp) /* save prithd */ + csrr a1, mstatus /* read mstatus */ + SREG a1, 7 * REGBYTES(sp) /* save mstatus */ + csrr a1, mepc /* read mepc */ + SREG a1, 8 * REGBYTES(sp) /* save mepc */ + + csrr a0, mcause + + li a1, (3<<11) + csrs mstatus, a1 +#ifndef NOS_TASK_SUPPORT /* When using NOS_TASK_SUPPORT, enable gloal irq after change to irq stack */ + la a1, custom_nested_irq_main_handler_entry + csrw mepc, a1 + mret +#endif /* #ifndef NOS_TASK */ +#endif + +.align 2 +custom_nested_irq_main_handler_entry: + SREG t0, 0 * REGBYTES(sp) + SREG t1, 1 * REGBYTES(sp) + SREG t2, 2 * REGBYTES(sp) + SREG a2, 5 * REGBYTES(sp) + SREG ra, 9 * REGBYTES(sp) + SREG a3, 10 * REGBYTES(sp) + SREG a4, 11 * REGBYTES(sp) + SREG a5, 12 * REGBYTES(sp) + SREG a6, 13 * REGBYTES(sp) + SREG a7, 14 * REGBYTES(sp) + SREG t3, 15 * REGBYTES(sp) + SREG t4, 16 * REGBYTES(sp) + SREG t5, 17 * REGBYTES(sp) + SREG t6, 18 * REGBYTES(sp) +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to save TickIRQEnable */ + csrr t0, TICK_IRQ_EN_BASE + andi t0, t0, TICK_IRQ_EN_NUM + SREG t0, 19 * REGBYTES(sp) +#endif + +#ifdef FLOAT_SUPPORT +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to save TickIRQEnable */ + FSREG f0, 23 * REGBYTES(sp) + FSREG f1, 24 * REGBYTES(sp) + FSREG f2, 25 * REGBYTES(sp) + FSREG f3, 26 * REGBYTES(sp) + FSREG f4, 27 * REGBYTES(sp) + FSREG f5, 28 * REGBYTES(sp) + FSREG f6, 29 * REGBYTES(sp) + FSREG f7, 30 * REGBYTES(sp) + FSREG f10, 31 * REGBYTES(sp) + FSREG f11, 32 * REGBYTES(sp) + FSREG f12, 33 * REGBYTES(sp) + FSREG f13, 34 * REGBYTES(sp) + FSREG f14, 35 * REGBYTES(sp) + FSREG f15, 36 * REGBYTES(sp) + FSREG f16, 37 * REGBYTES(sp) + FSREG f17, 38 * REGBYTES(sp) + FSREG f28, 39 * REGBYTES(sp) + FSREG f29, 40 * REGBYTES(sp) + FSREG f30, 41 * REGBYTES(sp) + FSREG f31, 42 * REGBYTES(sp) + frcsr t0 + SREG t0, 43 * REGBYTES(sp) +#else + FSREG f0, 19 * REGBYTES(sp) + FSREG f1, 20 * REGBYTES(sp) + FSREG f2, 21 * REGBYTES(sp) + FSREG f3, 22 * REGBYTES(sp) + FSREG f4, 23 * REGBYTES(sp) + FSREG f5, 24 * REGBYTES(sp) + FSREG f6, 25 * REGBYTES(sp) + FSREG f7, 26 * REGBYTES(sp) + FSREG f10, 27 * REGBYTES(sp) + FSREG f11, 28 * REGBYTES(sp) + FSREG f12, 29 * REGBYTES(sp) + FSREG f13, 30 * REGBYTES(sp) + FSREG f14, 31 * REGBYTES(sp) + FSREG f15, 32 * REGBYTES(sp) + FSREG f16, 33 * REGBYTES(sp) + FSREG f17, 34 * REGBYTES(sp) + FSREG f28, 35 * REGBYTES(sp) + FSREG f29, 36 * REGBYTES(sp) + FSREG f30, 37 * REGBYTES(sp) + FSREG f31, 38 * REGBYTES(sp) + frcsr t0 + SREG t0, 39 * REGBYTES(sp) /* save fcsr */ +#endif +#endif + +#ifdef NOS_TASK_SUPPORT + LREG a2, 6 * REGBYTES(sp) + bnez a2, IrqCallback /* Should determine whether need to switch stack */ + csrw mscratch, sp + la sp, __irq_stack_top - 16 + +IrqCallback: + addi sp, sp, -4 * REGBYTES + SREG a2, 0 * REGBYTES(sp) /* save prithd in irq stack */ + andi a0, a0, MCAUSE_MASK_INT_NUM + la a1, IrqCallbackNew /* When using NOS_TASK_SUPPORT, enable gloal irq after change to irq stack */ + csrw mepc, a1 + mret + +IrqCallbackNew: + call InterruptEntry + li a2, 0x8 + csrrc zero, mstatus, a2 /* When using NOS_TASK_SUPPORT, disable gloal irq before any stack operation */ + LREG a2, 0 * REGBYTES(sp) /* restore prithd in irq stack */ + addi sp, sp, 4 * REGBYTES + + bnez a2, BacktoIrq + csrr sp, mscratch + tail NOS_HwiPostDispatch /* Should determine whether need to reschedule */ +#else + andi a0, a0, MCAUSE_MASK_INT_NUM + call InterruptEntry +#endif + +BacktoIrq: + LREG t1, 1 * REGBYTES(sp) + LREG t2, 2 * REGBYTES(sp) + LREG a2, 5 * REGBYTES(sp) + LREG ra, 9 * REGBYTES(sp) + LREG a3, 10 * REGBYTES(sp) + LREG a4, 11 * REGBYTES(sp) + LREG a5, 12 * REGBYTES(sp) + LREG a6, 13 * REGBYTES(sp) + LREG a7, 14 * REGBYTES(sp) + LREG t3, 15 * REGBYTES(sp) + LREG t4, 16 * REGBYTES(sp) + LREG t5, 17 * REGBYTES(sp) + LREG t6, 18 * REGBYTES(sp) +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to restore TickIRQEnable */ + LREG t0, 19 * REGBYTES(sp) + andi t0, t0, TICK_IRQ_EN_NUM + csrs TICK_IRQ_EN_BASE, t0 +#endif + +#ifdef FLOAT_SUPPORT +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to save TickIRQEnable */ + FLREG f0, 23 * REGBYTES(sp) + FLREG f1, 24 * REGBYTES(sp) + FLREG f2, 25 * REGBYTES(sp) + FLREG f3, 26 * REGBYTES(sp) + FLREG f4, 27 * REGBYTES(sp) + FLREG f5, 28 * REGBYTES(sp) + FLREG f6, 29 * REGBYTES(sp) + FLREG f7, 30 * REGBYTES(sp) + FLREG f10, 31 * REGBYTES(sp) + FLREG f11, 32 * REGBYTES(sp) + FLREG f12, 33 * REGBYTES(sp) + FLREG f13, 34 * REGBYTES(sp) + FLREG f14, 35 * REGBYTES(sp) + FLREG f15, 36 * REGBYTES(sp) + FLREG f16, 37 * REGBYTES(sp) + FLREG f17, 38 * REGBYTES(sp) + FLREG f28, 39 * REGBYTES(sp) + FLREG f29, 40 * REGBYTES(sp) + FLREG f30, 41 * REGBYTES(sp) + FLREG f31, 42 * REGBYTES(sp) + LREG t0, 43 * REGBYTES(sp) + fscsr t0 +#else + FLREG f0, 19 * REGBYTES(sp) + FLREG f1, 20 * REGBYTES(sp) + FLREG f2, 21 * REGBYTES(sp) + FLREG f3, 22 * REGBYTES(sp) + FLREG f4, 23 * REGBYTES(sp) + FLREG f5, 24 * REGBYTES(sp) + FLREG f6, 25 * REGBYTES(sp) + FLREG f7, 26 * REGBYTES(sp) + FLREG f10, 27 * REGBYTES(sp) + FLREG f11, 28 * REGBYTES(sp) + FLREG f12, 29 * REGBYTES(sp) + FLREG f13, 30 * REGBYTES(sp) + FLREG f14, 31 * REGBYTES(sp) + FLREG f15, 32 * REGBYTES(sp) + FLREG f16, 33 * REGBYTES(sp) + FLREG f17, 34 * REGBYTES(sp) + FLREG f28, 35 * REGBYTES(sp) + FLREG f29, 36 * REGBYTES(sp) + FLREG f30, 37 * REGBYTES(sp) + FLREG f31, 38 * REGBYTES(sp) + LREG t0, 39 * REGBYTES(sp) /* restore fcsr */ + fscsr t0 +#endif +#endif + +quit_int: + /* + * Since the interrupt is already turned off when loading mstatus (after entering the interrupt, + * the hardware will turn off the interrupt, so when saving mstatus, the interrupt is already turned off), + * so there is no need to turn off the interrupt separately. + */ + +#if defined(HARD_NESTED_IRQ_SUPPORT) && (HARD_NESTED_IRQ_SUPPORT == 1) + LREG t0, 0 * REGBYTES(sp) +#else + LREG a0, 7 * REGBYTES(sp) /* load mstatus */ + LREG a1, 8 * REGBYTES(sp) /* load mepc */ +#ifndef NOS_TASK_SUPPORT /* When using NOS_TASK_SUPPORT, don't check mstatus */ + csrr t0, mstatus + andi t0, t0, MSTATUS_MIE + bnei t0, 0, restore_mstatus + andi a0, a0, ~(MSTATUS_MIE | MSTATUS_MPIE) +#endif +restore_mstatus: + csrw mstatus, a0 + + LREG t0, 0 * REGBYTES(sp) + csrw mepc, a1 + LREG a0, 6 * REGBYTES(sp) /* load prithd */ + csrw prithd, a0 +#endif + +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) + la a0, g_RiscvPrivMode + lw a1, (a0) + addi a1, a1, -1 + sw a1, (a0) +#endif + + LREG a1, 4 * REGBYTES(sp) /* 2 consecutive csrw instructions will have a bubble */ + + LREG a0, 3 * REGBYTES(sp) + + addi sp, sp, TOTAL_INT_SIZE_ON_STACK + + mret + +.align 2 +TrapVector: + +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to check mcause == ecall and a0 = magic word for taskSwitch */ + addi sp, sp, -8 + SREG a1, 0(sp) + SREG a2, 4(sp) + csrr a1, mcause + li a2, MCAUSE_ECALL_FROM_MMODE + bne a1, a2, IsTrap + li a2, NOS_TASK_SWITCH_MAGIC_NUM + bne a0, a2, IsTrap + LREG a2, 4(sp) + LREG a1, 0(sp) + addi sp, sp, 8 + tail NOS_TaskDispatch + +IsTrap: + LREG a2, 4(sp) + LREG a1, 0(sp) + addi sp, sp, 8 +#endif + + push_reg + csrr a0, mcause + li t1, MCAUSE_ECALL_FROM_MMODE +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) + beq a0, t1, switch_to_umode +#else + beq a0, t1, switch_to_mmode +#endif + li t1, MCAUSE_ECALL_FROM_UMODE + beq a0, t1, switch_to_mmode + + li a1, MCAUSE_MASK_INT_BIT + li a2, MCAUSE_MASK_INT_NUM + and a1, a0, a1 + and a0, a0, a2 + + li a2, 0xc + beq a0, a2, NmiEntry + beqz a1, TrapEntry + pop_reg + mret + +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) +.align 2 +switch_to_umode: + li t2, MSTATUS_MPP_MACHINE + csrc mstatus, t2 + csrr t0, mepc + addi t0, t0, 4 + csrw mepc, t0 + pop_reg + mret +#endif + +.align 2 +switch_to_mmode: + li t2, MSTATUS_MPP_MACHINE + csrs mstatus, t2 + csrr t0, mepc + addi t0, t0, 4 + csrw mepc, t0 + pop_reg + mret + +.align 2 +mem_cpy: + bge t0, t2, cpy_done + lw t3, (t1) + sw t3, (t0) + addi t0, t0, 4 + addi t1, t1, 4 + j mem_cpy +cpy_done: + ret + +.align 2 +handle_reset: + csrwi mstatus, 0 + csrwi mie, 0 + csrci mstatus, 0x08 + la t0, TrapHandler + addi t0, t0, 1 + csrw mtvec, t0 + +#ifndef UNLOCK_MTVEC /* When using UNLOCK_MTVEC, don't lock mtvec register. */ + csrwi 0x7EF, 0x1 /* lock mtvec */ +#endif + +#if defined(HARD_NESTED_IRQ_SUPPORT) && (HARD_NESTED_IRQ_SUPPORT == 1) + csrwi 0x7C8, 0x1 /* enable hardware nest interrupt support */ +#endif + +flash_init: +/* eflash prefetch enable */ + li t0, EFC_BASE_ADDR + lw t1, 0x120(t0) + ori t1, t1, 1 + sw t1, 0x120(t0) + +/* eflash cache enable */ + lw t1, 0x124(t0) + ori t1, t1, 1 + sw t1, 0x124(t0) + +/* enable flash cmd */ + li t0, EFC_MAGIC_NUMBER + li t1, EFC_MAGIC_LOCK_RW + sw t0, (t1) + +/* initialize global pointer */ + .option push + .option norelax + la gp, __global_pointer$ + .option pop + +/* initialize stack pointer */ +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to use irq stack */ + la sp, __init_stack_top +#else + la sp, __stack_top +#endif + +/* perform the rest of initialization in C */ +clear_sram: + /* clear sysram parity error */ + li t0, SYSRAM_ERROR + lw t1, (t0) + ori t1, t1, 1 + sw t1, (t0) + + la t0, SRAM_START + la t1, SRAM_END + li t2, 0 + +clear_sram_loop: + sw t2, (t0) /* clear all sram */ + addi t0, t0, 4 /* increment clear index pointer */ + blt t0, t1, clear_sram_loop /* are we at the end yet, if not , contiue till the end */ + +start_coderom_code_copy: + la t0, __sram_code_start_addr /* SRAM addr */ + la t1, __sram_code_load_addr /* ROM addr */ + la t2, __sram_code_end_addr + jal mem_cpy + +start_reserved_data_copy: + la t0, __reserved_code_start_addr /* SRAM addr */ + la t1, __reserved_code_load_addr /* ROM addr */ + la t2, __reserved_code_end_addr + jal mem_cpy + +start_coderom_data_copy: + la t0, __data_start /* SRAM addr */ + la t1, __data_load /* ROM addr */ + la t2, __data_end + jal mem_cpy + +stack_sram_bound_data_copy: + la t0, __stack_sram_bound_data_start /* SRAM addr */ + la t1, __stack_sram_bound_data_load /* ROM addr */ + la t2, __stack_sram_bound_data_end + jal mem_cpy + +pmp_init: + li t0, 0xB00 + csrw pmpaddr0, t0 + li t0, 0x400400 /* 0x2C00~0x1000FFF, BOOTROM, enable R+X */ + csrw pmpaddr1, t0 + li t0, 0x800000 /* 0x1001000~0x1FFFFFF, Reserved: disable R+X+W */ + csrw pmpaddr2, t0 + li t0, 0x804000 /* 0x2000000~0x200FFFF, SYSRAM_ITCM */ + csrw pmpaddr3, t0 + li t0, 0xC00000 /* 0x2008000 ~ 0x2FFFFFF, Reserved: disable R+X+W */ + csrw pmpaddr4, t0 + li t0, 0x1000000 /* 0x3000000 ~ 0x03FFFFFF: EFLASH: enable R+X */ + csrw pmpaddr5, t0 + li t0, 0x1002000 /* 0x4000000 ~ 0x04007FFF: SYSTEM_DTCM enable R+W */ + csrw pmpaddr6, t0 + li t0, 0x7000400 /* 0x4008000 ~ 0x01C000FFF: REGISTER R+W */ + csrw pmpaddr7, t0 + + li t0,0xf3333333 /* register TOR-R-W */ + csrw 0x7d8,t0 +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) + li t0,0x0d080d8b /* 0x0d:TOR-R-X; 0x0b:TOR-R-W; 0x08:TOR; 0x0c:TOR-x; 0x09:TOR-R */ + csrw pmpcfg0,t0 + li t0,0x0b0b0d08 + csrw pmpcfg1,t0 +#else + li t0, 0x8F888D8B/* 0x0d:TOR-R-X; 0x0b:TOR-R-W; 0x08:TOR; 0x0c:TOR-x; 0x09:TOR-R */ + csrw pmpcfg0,t0 + li t0,0x8b8b8d88 + csrw pmpcfg1,t0 +#endif + +/* support float and mie */ + li t0,0x2008 + csrs mstatus,t0 + li t0,0x20 + csrs misa,t0 + +/* Interrupt set default priority = 1*/ + li t0, 0x11111111 + csrw locipri0, t0 + csrw locipri1, t0 + csrw locipri2, t0 + csrw locipri3, t0 + csrw locipri4, t0 + csrw locipri5, t0 + csrw locipri6, t0 + csrw locipri7, t0 + csrw locipri8, t0 + csrw locipri9, t0 + csrw locipri10, t0 + csrw locipri11, t0 + csrw locipri12, t0 + csrw locipri13, t0 + csrw locipri14, t0 + csrw locipri15, t0 + + ecall + +#ifdef NOS_TASK_SUPPORT + jal Chip_Init +#else + jal Chip_Init + +/* jump to C func. */ + jal main +#endif + +dead_loop: + j dead_loop + +#endif diff --git a/src/chip/3065p/sysctrl.h b/src/chip/3065p/sysctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..143bded8819a746983e2ee4da2058b9512356bae --- /dev/null +++ b/src/chip/3065p/sysctrl.h @@ -0,0 +1,665 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sysctrl.h + * @author MCU Driver Team + * @brief This file provides firmware functions to manage the following + * functionalities of the system control register. + * + Register Struct of SYSCTRL + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSCTRL_H +#define McuMagicTag_SYSCTRL_H + +/* Includes ------------------------------------------------------------------ */ +#include "baseaddr.h" +#include "typedefs.h" + +/* Macro definitions ---------------------------------------------------------*/ +#define SC_LOCKEN_VALID_HIGH_BIT 0xEA510000U /**< Upper 16 active bits of the SC_LOCKEN register */ +#define SC_LOW_BIT_MASK 0x0000FFFFU /**< Obtains the mask of the lower 16 bits. */ +#define SC_LOCKEN_CRG_DISABLE_MASK 0x0000FFFEU /**< CRG write protection disable mask in SC_LOCKEN */ +#define SC_LOCKEN_CRG_ENABLE_MASK 0x00000001U /**< CRG write protection enable mask in SC_LOCKEN */ +#define SC_LOCKEN_SC_DISABLE_MASK 0x0000FFFDU /**< SC write protection disable mask in SC_LOCKEN */ +#define SC_LOCKEN_SC_ENABLE_MASK 0x00000002U /**< SC write protection enbale mask in SC_LOCKEN */ + + +/** + * @brief Records the offsets of various states in the CPU status register. + */ +typedef enum { + SYSCTRL_NMI_BIT = 0x00000000U, + SYSCTRL_LOCKUP_BIT = 0x00000002U, + SYSCTRL_HARD_FAULT_BIT = 0x00000003U, + SYSCTRL_DEBUG_BIT = 0x00000004U, + SYSCTRL_SLEEP_BIT = 0x00000005U, + SYSCTRL_PC_VALID_BIT = 0x0000001FU +} SYSCTRL_CPU_Status; + +/** + * @brief FUNC_JTAG_SEL_REG register function item. + */ +typedef enum { + SYSCTRL_FUNC_JTAG_CORESIGHT = 0x00000000U, + SYSCTRL_FUNC_JYAG_EFLASH = 0x00000001U +} SYSCTRL_FUNC_JTAG_Status; + +/** + * @brief REMAP_MODE register function item. + */ +typedef enum { + SYSCTRL_REMAP_MODE0 = 0x00000000U, + SYSCTRL_REMAP_MODE1 = 0x00000001U, + SYSCTRL_REMAP_MODE2 = 0x00000002U, + SYSCTRL_REMAP_MODE3 = 0x00000003U, +} SYSCTRL_RemapMode; + + +/** + * @brief System soft reset register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int softresreq : 1; /**< Set any value to make system soft reset. */ + unsigned int reserved : 31; + } BIT; +} volatile SC_SYS_RES_REG; + +/** + * @brief Record the number of resets(soft reset, pin reset). + */ +typedef union { + unsigned int reg; + struct { + unsigned int soft_rst_cnt : 16; /**< Number of soft resets. */ + unsigned int ext_rst_cnt : 16; /**< Number of reset times of the RESETN pin. */ + } BIT; +} volatile SC_RST_CNT0_REG; + +/** + * @brief Record the number of resets(wdg reset, iwdg reset). + */ +typedef union { + unsigned int reg; + struct { + unsigned int wdg_rst_cnt : 16; /**< Number of WDG resets. */ + unsigned int iwdg_rst_cnt : 16; /**< Number of IWDG resets. */ + } BIT; +} volatile SC_RST_CNT1_REG; + +/** + * @brief System status register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int update_mode_clear : 1; /**< System upgrade flag clear register, 0:not clear, 1:clear. */ + unsigned int reserved0 : 3; + unsigned int update_mode : 1; /**< System upgrade flag, 0:not upgrade, 1:upgrade. */ + unsigned int reserved1 : 27; + } BIT; +} volatile SC_SYS_STAT_REG; + +/** + * @brief Software interrupt register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int software_int : 1; /**< Software interrupt register, writing 1 generates a software interrupt. */ + unsigned int reserved : 31; + } BIT; +} volatile SC_SOFT_INT_REG; + +/** + * @brief Software interrupt event ID register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int swint_evt_id : 32; /**< Software interrupt event ID. */ + } BIT; +} volatile SC_SOFT_EVT_ID_REG; + +/** + * @brief Lock register of key registers. + */ +typedef union { + unsigned int reg; + struct { + unsigned int crg_cfg_lock : 1; /**< Write protection for CRG, 0: write enabled, 1: write disabled. */ + unsigned int sc_cfg_lock : 1; /**< Write protection for SYSCTRL, 0: write enabled, 1: write disabled. */ + unsigned int reserved : 30; + } BIT; +} volatile SC_LOCKEN_REG; + +/** + * @brief SC dedicated hard reset register 0. (CH) This register is not reset by a system soft reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int sc_hrst_reg0 : 32; /**< If the value is 0xA5A5A5, the CPU stops starting the system. */ + } BIT; +} volatile SC_HRST_REG0_REG; + +/** + * @brief User dedicated hard reset register 0. (CH) This register is not reset by a system soft reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_hrst_reg0 : 32; /**< User-dedicated hard reset register 0. */ + } BIT; +} volatile USER_HRST_REG0_REG; + +/** + * @brief User dedicated hard reset register 1. (CH) This register is not reset by a system soft reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_hrst_reg1 : 32; /**< User-dedicated hard reset register 1. */ + } BIT; +} volatile USER_HRST_REG1_REG; + +/** + * @brief User dedicated POR reset register 0. (CH) This register is reset only by a POR reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_por_reg0 : 32; /**< User dedicated POR reset register 0. */ + } BIT; +} volatile USER_POR_REG0_REG; + +/** + * @brief User dedicated POR reset register 1. (CH) This register is reset only by a POR reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_por_reg1 : 32; /**< User dedicated POR reset register 1. */ + } BIT; +} volatile USER_POR_REG1_REG; + +/** + * @brief User dedicated register 0. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_reg0 : 32; /**< User dedicated register 0. */ + } BIT; +} volatile USER_REG0_REG; + +/** + * @brief User dedicated register 1. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_reg1 : 32; /**< User dedicated register 1. */ + } BIT; +} volatile USER_REG1_REG; + +/** + * @brief SYSCTRL0 register. + */ +typedef struct _SYSCTRL0_Regstruct { + char space0[4]; + SC_SYS_RES_REG SC_SYS_RES; /**< System soft reset register, offset address: 0x0004. */ + SC_RST_CNT0_REG SC_RST_CNT0; /**< Reset count register 0, offset address: 0x0008. */ + SC_RST_CNT1_REG SC_RST_CNT1; /**< Reset count register 1, offset address: 0x000C. */ + char space1[8]; + SC_SYS_STAT_REG SC_SYS_STAT; /**< System boot mode register, offset address: 0x0018. */ + char space2[4]; + SC_SOFT_INT_REG SC_SOFT_INT; /**< Software interrupt register, offset address: 0x0020. */ + SC_SOFT_EVT_ID_REG SC_SOFT_EVT_ID; /**< Software interrupt event ID register, offset address: 0x0024. */ + char space3[28]; + SC_LOCKEN_REG SC_LOCKEN; /**< Lock register of key registers, offset address: 0x0044. */ + char space4[440]; + SC_HRST_REG0_REG SC_HRST_REG0; /**< SC dedicated hard reset register 0, offset address: 0x0200. */ + char space5[3068]; + USER_POR_REG0_REG USER_POR_REG0; /**< User dedicated POR reset register 0, offset address: 0x0E00. */ + USER_POR_REG1_REG USER_POR_REG1; /**< User dedicated POR reset register 1, offset address: 0x0E04. */ + char space6[56]; + USER_HRST_REG0_REG USER_HRST_REG0; /**< User dedicated hard reset register 0, offset address: 0x0E40. */ + USER_HRST_REG1_REG USER_HRST_REG1; /**< User dedicated hard reset register 1, offset address: 0x0E44. */ + char space7[56]; + USER_REG0_REG USER_REG0; /**< User dedicated register 0, offset address: 0x0E80. */ + USER_REG1_REG USER_REG1; /**< User dedicated register 1, offset address: 0x0E84. */ +} volatile SYSCTRL0_RegStruct; + +/** + * @brief APT enable register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int apt0_run : 1; /**< APT0 enable control, 0:enable, 1:enable. */ + unsigned int apt1_run : 1; /**< APT1 enable control, 0:enable, 1:enable. */ + unsigned int apt2_run : 1; /**< APT2 enable control, 0:enable, 1:enable. */ + unsigned int apt3_run : 1; /**< APT3 enable control, 0:enable, 1:enable. */ + unsigned int apt4_run : 1; /**< APT4 enable control, 0:enable, 1:enable. */ + unsigned int apt5_run : 1; /**< APT5 enable control, 0:enable, 1:enable. */ + unsigned int apt6_run : 1; /**< APT6 enable control, 0:enable, 1:enable. */ + unsigned int apt7_run : 1; /**< APT7 enable control, 0:enable, 1:enable. */ + unsigned int apt8_run : 1; /**< APT8 enable control, 0:enable, 1:enable. */ + unsigned int reserved : 23; + } BIT; +} volatile APT_RUN_REG; + +/** + * @brief Poe filter register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int poe0_filter_level : 8; /**< Number of POE0 Filter Cycles. */ + unsigned int poe1_filter_level : 8; /**< Number of POE1 Filter Cycles. */ + unsigned int poe2_filter_level : 8; /**< Number of POE2 Filter Cycles. */ + unsigned int poe0_filter_en : 1; /**< POE0 filter enable, 0:enable, 1:enable. */ + unsigned int poe1_filter_en : 1; /**< POE1 filter enable, 0:enable, 1:enable. */ + unsigned int poe2_filter_en : 1; /**< POE2 filter enable, 0:enable, 1:enable. */ + unsigned int reserved : 5; + } BIT; +} volatile APT_POE_FILTER_REG; + +/** + * @brief APT_EVTIO_FILTER register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int apt_evtio4_filter_level : 8; /**< Number of APT EVTIO4 Filter Cycles. */ + unsigned int apt_evtio5_filter_level : 8; /**< Number of APT EVTIO5 Filter Cycles. */ + unsigned int reserved0 : 8; + unsigned int apt_evtio4_filter_en : 1; /**< APT EVTIO4 FILTER enable, 0:enable, 1:enable. */ + unsigned int apt_evtio5_filter_en : 1; /**< APT EVTIO5 FILTER enable, 0:enable, 1:enable. */ + unsigned int reserved1 : 6; + } BIT; +} volatile APT_EVTIO_FILTER_REG; + +/** + * @brief APT_EVTMP_FILTER register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int apt_evtmp4_filter_level : 8; /**< Number of APT EVTMP4 Filter Periods. */ + unsigned int apt_evtmp5_filter_level : 8; /**< Number of APT EVTMP5 Filter Periods. */ + unsigned int apt_evtmp6_filter_level : 8; /**< Number of APT EVTMP6 Filter Periods. */ + unsigned int apt_evtmp4_filter_en : 1; /**< APT EVTMP4 FILTER enable, 0:enable, 1:enable. */ + unsigned int apt_evtmp5_filter_en : 1; /**< APT EVTMP5 FILTER enable, 0:enable, 1:enable. */ + unsigned int apt_evtmp6_filter_en : 1; /**< APT EVTMP6 FILTER enable, 0:enable, 1:enable. */ + unsigned int reserved : 5; + } BIT; +} volatile APT_EVTMP_FILTER_REG; + +/** + * @brief XTAL_CFG register. + * + */ +typedef union { + unsigned int reg; + struct { + unsigned int osc_ds : 4; /**< Crystal I/O Drive Capability Configuration. */ + unsigned int ose_e : 1; /**< Crystal I/O resonance buffer enable, 0:disable, 1:enable. */ + unsigned int osc_ie : 1; /**< Crystal I/O clock input enable, 0:disable, 1:enable. */ + unsigned int reserved : 26; + } BIT; +} volatile XTAL_CFG_REG; + +/** + * @brief Dma request selection register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 8; + unsigned int dma_req8_sel : 1; /**< DMA8 request section, 0:unselect, 1:select. */ + unsigned int dma_req9_sel : 1; /**< DMA9 request section, 0:unselect, 1:select. */ + unsigned int dma_req10_sel : 1; /**< DMA10 request section, 0:unselect, 1:select. */ + unsigned int dma_req11_sel : 1; /**< DMA11 request section, 0:unselect, 1:select. */ + unsigned int dma_req12_sel : 1; /**< DMA12 request section, 0:unselect, 1:select. */ + unsigned int reserved1 : 19; + } BIT; +} volatile DMA_REQ_SEL_REG; + +/** + * @brief Sysram parity check register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int sysram_parity_err_clr : 1; /**< SYSRAM parity error status clear, write any value to clear. */ + unsigned int sysram0_parity_err : 1; /**< SYSRAM Parity Error Status, 0:no error, 1:error. */ + unsigned int sysram1_parity_err : 1; /**< SYSRAM Parity Error Status, 0:no error, 1:error. */ + unsigned int reserved : 29; + } BIT; +} volatile SYSRAM_ERR_REG; + +/** + * @brief Remap config register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int remap_en : 1; /**< Address remap enable, 0:disable, 1:enable. */ + unsigned int remap_mode : 2; /**< Address remap mode, 0:4kb, 1:8kb, 2:128kb, 3:256kb. */ + unsigned int reserved1 : 29; + } BIT; +} volatile REMAP_CFG_REG; + +/** + * @brief TCM_STATUS register. + * + */ +typedef union { + unsigned int reg; + struct { + unsigned int sysram_secure_access_err : 1; /**< SYSRAM DTCM Security Access Status, 0:legal, 1:illegal. */ + unsigned int flash_secure_access_err : 1; /**< FLASH DTCM secure access status. */ + unsigned int reserved0 : 6; + unsigned int sysram_secure_access_err_clr : 1; /**< SYSRAM DTCM Security Access Status. write 1 clear error */ + unsigned int flash_secure_access_err_clr : 1; /**< FLASH DTCM secure access status. write 1 clear error */ + unsigned int reserved1 : 22; + } BIT; +} volatile TCM_STATUS_REG; + +/** + * @brief PVD_STATUS register. + * + */ +typedef union { + unsigned int reg; + struct { + unsigned int pvd_toggle : 1; /**< PVD triggering flag. */ + unsigned int reserved : 31; + } BIT; +} volatile PVD_STATUS_REG; + +/** + * @brief CPU status register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 2; + unsigned int cpu_lockup_mode : 1; /**< CPU LOCKUP status. 0: non-lockup state, 1: lockup state. */ + unsigned int cpu_hard_fault_mode : 1; /**< Indicates the hard fault status of the CPU. 0: non-hard_fault state, + 1: hard_fault. */ + unsigned int cpu_debug_mode : 1; /**< Indicates the CPU debug status. 0: non-debug state, + 1: debug state. */ + unsigned int cpu_sleep_mode : 1; /**< CPU sleep status. 0: non-sleep state, 1: sleep state. */ + unsigned int reserved1 : 25; + unsigned int cpu_pc_valid : 1; /**< Valid status of the CPU PC value. 0: The PC value is invalid, + 1: The PC value is valid. */ + } BIT; +} volatile CPU_STATUS_REG; + +/** + * @brief SYSCTRL1 register. + */ +typedef struct _SYSCTRL1_RegStruct { + char space0[0x8000]; + APT_RUN_REG APT_RUN; /**< APT enable control register, offset address: 0x8000. */ + char space1[12]; + APT_POE_FILTER_REG APT_POE_FILTER; /**< APT PoE filtering control register, offset address: 0x8010. */ + APT_EVTIO_FILTER_REG APT_EVTIO_FILTER; /**< APT EVTIO filtering control register, offset address: 0x8014. */ + APT_EVTMP_FILTER_REG APT_EVTMP_FILTER; /**< APT EVTMP filtering control register, offset address: 0x8018. */ + char space2[228]; + XTAL_CFG_REG XTAL_CFG; /**< Crystal I/O control register, offset address: 0x8100. */ + char space3[252]; + DMA_REQ_SEL_REG DMA_REQ_SEL; /**< DMA request selection register, offset address: 0x8200. */ + char space4[252]; + SYSRAM_ERR_REG SYSRAM_ERR; /**< SYSRAM parity check status register, offset address: 0x8300. */ + char space5[4]; + REMAP_CFG_REG REMAP_CFG; /**< REMAP config register, offset address: 0x8308. */ + TCM_STATUS_REG TCM_STATUS; /**< TCM status register, offset address: 0x830c. */ + char space6[244]; + PVD_STATUS_REG PVD_STATUS; /**< PVD status register, offset address: 0x8404. */ + char space7[3064]; + CPU_STATUS_REG CPU_STATUS; /**< CPU status register, offset address: 0x9000. */ +} volatile SYSCTRL1_RegStruct; + +/** + * @brief Make system soft reset. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_SoftReset(void) +{ + SYSCTRL0->SC_SYS_RES.BIT.softresreq = 1; +} + +/** + * @brief Get number of soft resets. + * @param None + * @retval Number of soft resets. + */ +static inline unsigned short DCL_SYSCTRL_GetSoftResetConut(void) +{ + return SYSCTRL0->SC_RST_CNT0.BIT.soft_rst_cnt; +} + +/** + * @brief Get number of reset times of the RESETN pin. + * @param None + * @retval Number of reset times of the RESETN pin. + */ +static inline unsigned short DCL_SYSCTRL_GetPinResetConut(void) +{ + return SYSCTRL0->SC_RST_CNT0.BIT.ext_rst_cnt; +} + +/** + * @brief Get number of WDG resets. + * @param None + * @retval Number of WDG resets. + */ +static inline unsigned short DCL_SYSCTRL_GetWdgResetConut(void) +{ + return SYSCTRL0->SC_RST_CNT1.BIT.wdg_rst_cnt; +} + +/** + * @brief Get number of IWDG resets. + * @param None + * @retval Number of IWDG resets. + */ +static inline unsigned short DCL_SYSCTRL_GetIWdgResetConut(void) +{ + return SYSCTRL0->SC_RST_CNT1.BIT.iwdg_rst_cnt; +} + +/** + * @brief Set the write protection for SYSCTRL registers disable. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_ScWriteProtectionDisable(void) +{ + /* Set the corresponding bit without affecting the other bits and set the high 16 bits to EA51 to write to. */ + SYSCTRL0->SC_LOCKEN.reg = (SYSCTRL0->SC_LOCKEN.reg & SC_LOCKEN_SC_DISABLE_MASK) + SC_LOCKEN_VALID_HIGH_BIT; +} + +/** + * @brief Set the write protection for SYSCTRL registers enable. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_ScWriteProtectionEnable(void) +{ + /* Set the corresponding bit without affecting the other bits and set the high 16 bits to EA51 to write to. */ + SYSCTRL0->SC_LOCKEN.reg = ((SYSCTRL0->SC_LOCKEN.reg & SC_LOW_BIT_MASK) | SC_LOCKEN_SC_ENABLE_MASK) + + SC_LOCKEN_VALID_HIGH_BIT; +} + +/** + * @brief Set the write protection for CRG-related registers disable. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_CrgWriteProtectionDisable(void) +{ + /* Set the corresponding bit without affecting the other bits and set the high 16 bits to EA51 to write to. */ + SYSCTRL0->SC_LOCKEN.reg = (SYSCTRL0->SC_LOCKEN.reg & SC_LOCKEN_CRG_DISABLE_MASK) + SC_LOCKEN_VALID_HIGH_BIT; +} + +/** + * @brief Set the Set the write protection for CRG-related registers enable. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_CrgWriteProtectionEnable(void) +{ + /* Set the corresponding bit without affecting the other bits and set the high 16 bits to EA51 to write to. */ + SYSCTRL0->SC_LOCKEN.reg = ((SYSCTRL0->SC_LOCKEN.reg & SC_LOW_BIT_MASK) | SC_LOCKEN_CRG_ENABLE_MASK) + + SC_LOCKEN_VALID_HIGH_BIT; +} + +/** + * @brief Set software interrupt register, writing 1 generates a software interrupt. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_GenerateSoftInterrupt(void) +{ + SYSCTRL0->SC_SOFT_INT.BIT.software_int = 1; +} + +/** + * @brief Clear software interrupt register, writing 0 generates a software interrupt. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_ClearSoftInterrupt(void) +{ + SYSCTRL0->SC_SOFT_INT.BIT.software_int = 0; +} + +/** + * @brief Set Software interrupt event ID. + * @param id the software interrupt event ID. + * @retval None. + */ +static inline void DCL_SYSCTRL_SetSoftInterruptEventId(unsigned int id) +{ + SYSCTRL0->SC_SOFT_EVT_ID.BIT.swint_evt_id = id; +} + +/** + * @brief Get Software interrupt event ID. + * @param None + * @retval The value of software interrupt event ID. + */ +static inline unsigned int DCL_SYSCTRL_GetSoftInterruptEventId(void) +{ + return SYSCTRL0->SC_SOFT_EVT_ID.BIT.swint_evt_id; +} + +/** + * @brief Get SYSRAM Parity Error Status. + * @param None. + * @retval 0:no error, 1:error. + */ +static inline unsigned int DCL_SYSCTRL_GetSysramParityErrorStatus(void) +{ + return SYSCTRL1->SYSRAM_ERR.BIT.sysram0_parity_err; +} + +/** + * @brief Set SYSRAM parity error status clear. + * @param None. + * @retval None. + */ +static inline void DCL_SYSCTRL_ClearSysramParityError(void) +{ + SYSCTRL1->SYSRAM_ERR.BIT.sysram_parity_err_clr = 1; /* Write any value to clear. */ +} + +/** + * @brief Get CPU status. + * @param offset Bit offset of CPU status. + * @retval true or false + */ +static inline bool DCL_SYSCTRL_CheckCpuStatus(SYSCTRL_CPU_Status offset) +{ + return ((SYSCTRL1->CPU_STATUS.reg) & (1 << offset)) == 0 ? false : true; +} + +/** + * @brief Enable Remap function. + * @param None. + * @retval None. + */ +static inline void DCL_SYSCTRL_EnableRemap(void) +{ + DCL_SYSCTRL_ScWriteProtectionDisable(); + SYSCTRL1->REMAP_CFG.BIT.remap_en = BASE_CFG_SET; + DCL_SYSCTRL_ScWriteProtectionEnable(); + /* Clear the CPU pipeline and complete address remapping. */ + __asm__ volatile("fence"); + __asm__ volatile("fence"); + __asm__ volatile("fence"); + __asm__ volatile("fence"); +} + +/** + * @brief Disable Remap function. + * @param None. + * @retval None. + */ +static inline void DCL_SYSCTRL_DisableRemap(void) +{ + DCL_SYSCTRL_ScWriteProtectionDisable(); + SYSCTRL1->REMAP_CFG.BIT.remap_en = BASE_CFG_UNSET; + DCL_SYSCTRL_ScWriteProtectionEnable(); + /* Clear the CPU pipeline and complete address remapping. */ + __asm__ volatile("fence"); + __asm__ volatile("fence"); + __asm__ volatile("fence"); + __asm__ volatile("fence"); +} + +/** + * @brief Set Remap mode. + * @param remap mode. + * @retval None. + */ +static inline void DCL_SYSCTRL_SetRemapMode(SYSCTRL_RemapMode mode) +{ + DCL_SYSCTRL_ScWriteProtectionDisable(); + SYSCTRL1->REMAP_CFG.BIT.remap_mode = mode; + DCL_SYSCTRL_ScWriteProtectionEnable(); +} + +/** + * @brief Get Remap mode. + * @param remap mode. + * @retval None. + */ +static inline SYSCTRL_RemapMode DCL_SYSCTRL_GetRemapMode(void) +{ + return SYSCTRL1->REMAP_CFG.BIT.remap_mode; +} + +#endif /* McuMagicTag_SYSCTRL_H */ \ No newline at end of file diff --git a/src/chip/3065p/systick.h b/src/chip/3065p/systick.h new file mode 100644 index 0000000000000000000000000000000000000000..1d9f0c1ac033ed1e24f431b4495eca0e36eb68c5 --- /dev/null +++ b/src/chip/3065p/systick.h @@ -0,0 +1,118 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file systick.h + * @author MCU Driver Team + * @brief SYSTICK module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the SYSTICK. + * + SYSTICK register mapping structure + * + Get SysTick counter + */ + + +#ifndef McuMagicTag_SYSTICK_H +#define McuMagicTag_SYSTICK_H + +/* Includes ------------------------------------------------------------------*/ +#include "baseaddr.h" +#include "systickinit.h" +#include "feature.h" +/** + * @addtogroup SYSTICK + * @{ + */ + +/** + * @defgroup SYSTICK_IP SYSTICK_IP + * @brief SYSTICK_IP: systick + * @{ + */ + +/** + * @defgroup SYSTICK_Param_Def SYSTICK Parameters Definition + * @brief Definition of SYSTICK configuration parameters. + * @{ + */ +#ifdef NOS_TASK_SUPPORT +#ifndef CFG_SYSTICK_TICKINTERVAL_US +#define CFG_SYSTICK_TICKINTERVAL_US 100 +#endif +unsigned int SYSTICK_GetTickInterval(void); +#endif + +#define SYSTICK_MAX_VALUE 0xFFFFFFFFUL + +/** + * @} + */ + +/** + * @brief SYSTICK control register structure. + */ +typedef union { + unsigned int reg; + struct { + unsigned int enable : 1; /**< Mtimer enable. */ + unsigned int clksrc : 1; /**< Mtimer clock source select. */ + unsigned int stop_tmr_en : 1; /**< Counting stop control in debugging mode. */ + unsigned int reserved : 29; + } BIT; +} TIMER_CTRL_REG; + +/** + * @brief SYSTICK DIV control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int div : 10; /**< Timer frequency division control. */ + unsigned int reserved : 22; + } BIT; +} TIMER_DIV_REG; + +/** + * @brief SYSTICK register structure + */ +typedef struct { + TIMER_CTRL_REG TIMER_CTRL; /**< Mtimer control register. Offset address: 0x00000000U. */ + TIMER_DIV_REG TIMER_DIV; /**< Mtimer frequency divider register. Offset address: 0x00000004U. */ + unsigned int MTIME; /**< Mtimer count value lower 32-bit register. Offset address: 0x00000008U. */ + unsigned int MTIME_H; /**< Upper 32-bit register for Mtimer count value. Offset address: 0x0000000CU. */ + unsigned int MTIMECMP; /**< Mtimer comparison value lower 32-bit register. Offset address: 0x00000010U. */ + unsigned int MTIMECMP_H; /**< Upper 32-bit Mtimer comparison value register. Offset address: 0x00000014U. */ +} volatile SYSTICK_RegStruct; + +/** + * @} + */ + +/** + * @brief Get the systick + * @param None + * @retval The SysTick Value + */ +static inline unsigned int DCL_SYSTICK_GetTick(void) +{ + return SYSTICK->MTIME; /* Systick value(Lower 32bit register) */ +} + +unsigned int SYSTICK_GetTimeStampUs(void); +/** + * @} + */ +#endif /* McuMagicTag_SYSTICK_H */ \ No newline at end of file diff --git a/src/chip/3066m/anavref.h b/src/chip/3066m/anavref.h new file mode 100644 index 0000000000000000000000000000000000000000..47f74aa42d46049028ad1e22bbe653d87b02f75a --- /dev/null +++ b/src/chip/3066m/anavref.h @@ -0,0 +1,92 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file anavref.h + * @author MCU Driver Team + * @brief anavref register mapping structure + */ + +/* Macro definitions */ +#ifndef McuMagicTag_ANAVREF_IP_H +#define McuMagicTag_ANAVREF_IP_H + +#include "baseinc.h" + +/** + * @brief Define the union VREF_CTRL_REG0 + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_ref_enh : 1; /**< vref enable */ + unsigned int reserved0 : 31; + } BIT; +} volatile VREF_CTRL_REG0; + +/** + * @brief Define the union VREF_CTRL_REG1 + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_ref_chop_enh : 1; /**< vref chopping enable */ + unsigned int reserved0 : 15; + unsigned int da_ref_temp_trim_enh : 1; /**< vref High-precision mode enable */ + unsigned int reserved1 : 15; + } BIT; +} volatile VREF_CTRL_REG1; + + +/** + * @brief Define the union VREF_TRIM_REG0 + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_iref_trim : 8; /**< iref trim */ + unsigned int da_ref_vref_trim : 8; /**< IBIAS voltage trim */ + unsigned int da_ref_vbg_trim : 8; /**< vref voltage trim */ + unsigned int da_ref_buf_trim : 8; /**< vref buffer trim */ + } BIT; +} volatile VREF_TRIM_REG0; + +/** + * @brief Define the union VREF_TRIM_REG1 + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_ref_temp_trim3 : 8; /**< Benchmark temperature drift trim information */ + unsigned int da_ref_temp_trim2 : 8; /**< Benchmark temperature drift trim information */ + unsigned int da_ref_temp_trim1 : 8; /**< Benchmark temperature drift trim information */ + unsigned int da_ref_temp_trim0 : 8; /**< Benchmark temperature drift trim information */ + } BIT; +} volatile VREF_TRIM_REG1; + +/** + * @brief Define the VREF_RegStruct + */ +typedef struct { + VREF_CTRL_REG0 VREF_CTRL0; /**< Offset address: 0x0000000U*/ + unsigned int space0[7]; + VREF_CTRL_REG1 VREF_CTRL1; /**< Offset address: 0x0000020U*/ + unsigned int space1[7]; + VREF_TRIM_REG0 VREF_TRIM0; /**< Offset address: 0x0000040U*/ + VREF_TRIM_REG1 VREF_TRIM1; /**< Offset address: 0x0000044U*/ +} volatile VREF_RegStruct; + +#endif /* McuMagicTag_ANAVREF_IP_H */ \ No newline at end of file diff --git a/src/chip/3066m/baseaddr.h b/src/chip/3066m/baseaddr.h new file mode 100644 index 0000000000000000000000000000000000000000..5772833a5e50884b2c884ef3204fd641902f4e87 --- /dev/null +++ b/src/chip/3066m/baseaddr.h @@ -0,0 +1,235 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file baseaddr.h + * @author MCU Driver Team + * @brief Definition of MCU register baseaddress + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_BASEADDR_H +#define McuMagicTag_BASEADDR_H + +#define CRG_BASE (void *)0x10000000 +#define CMM_BASE (void *)0x10010000 +#define CFD_BASE (void *)0x10020000 +#define SYSCTRL0_BASE (void *)0x10100000 +#define SYSCTRL1_BASE (void *)0x10100000 /* The base address offset is configured in the register. */ +#define UART0_BASE (void *)0x14000000 +#define UART1_BASE (void *)0x14001000 +#define UART2_BASE (void *)0x14002000 +#define UART3_BASE (void *)0x14003000 +#define UART4_BASE (void *)0x14004000 + +#define I2C0_BASE (void *)0x14100000 +#define SPI0_BASE (void *)0x14200000 +#define SPI1_BASE (void *)0x14201000 +#define TIMER0_BASE (void *)0x14300000 +#define TIMER1_BASE (void *)0x14301000 +#define TIMER2_BASE (void *)0x14302000 +#define TIMER3_BASE (void *)0x14303000 + +#define SYSTICK_BASE (void *)0x14380000 +#define WWDG_BASE (void *)0x14400000 +#define IWDG_BASE (void *)0x14401000 +#define GPIO0_BASE (void *)0x14500000 +#define GPIO1_BASE (void *)0x14501000 +#define GPIO2_BASE (void *)0x14502000 +#define GPIO3_BASE (void *)0x14503000 +#define GPIO4_BASE (void *)0x14504000 +#define GPIO5_BASE (void *)0x14505000 +#define GPIO6_BASE (void *)0x14506000 +#define GPIO7_BASE (void *)0x14507000 +#define GPIO8_BASE (void *)0x14508000 +#define GPIO9_BASE (void *)0x14509000 +#define CAN_BASE (void *)0x14600000 +#define CAN1_BASE (void *)0x14601000 +#define GPT0_BASE (void *)0x14700000 +#define GPT1_BASE (void *)0x14701000 + +#define EFC_BASE (void *)0x14710000 +#define PMC_BASE (void *)0x147E0000 +#define IOCMG_BASE (void *)0x147F0000 +#define CRC_BASE (void *)0x14800000 +#define APT0_BASE (void *)0x14A00000 +#define APT1_BASE (void *)0x14A01000 +#define APT2_BASE (void *)0x14A02000 +#define APT3_BASE (void *)0x14A03000 +#define APT4_BASE (void *)0x14A04000 +#define APT5_BASE (void *)0x14A05000 +#define APT6_BASE (void *)0x14A06000 +#define APT7_BASE (void *)0x14A07000 +#define APT8_BASE (void *)0x14A08000 + +#define CAPM0_BASE (void *)0x14B00000 +#define CAPM1_BASE (void *)0x14B01000 +#define CAPM2_BASE (void *)0x14B02000 +#define CAPM_COMM_BASE (void *)0x14B03000 + +#define QDM0_BASE (void *)0x14C00000 +#define QDM1_BASE (void *)0x14C01000 +#define QDM2_BASE (void *)0x14C02000 +#define QDM3_BASE (void *)0x14C03000 +#define ADC0_BASE (void *)0x18000000 +#define ADC1_BASE (void *)0x18001000 +#define ADC2_BASE (void *)0x18002000 +#define VREF_BASE (void *)0x18100000 +#define PGA0_BASE (void *)0x18200000 +#define PGA1_BASE (void *)0x18201000 +#define PGA2_BASE (void *)0x18202000 +#define ACMP0_BASE (void *)0x18300000 +#define ACMP1_BASE (void *)0x18301000 +#define ACMP2_BASE (void *)0x18302000 +#define DAC0_BASE (void *)0x18400000 +#define DAC1_BASE (void *)0x18401000 +#define DAC2_BASE (void *)0x18402000 + +#define TSENSOR_BASE (void *)0x18500000 +#define ANA_CTRL_TOP_BASE (void *)0x18600000 + +#define DMA_BASE (void *)0x1C000000 +#define DMA_CHANNEL0_BASE (void *)0x1C000100 +#define DMA_CHANNEL1_BASE (void *)0x1C000120 +#define DMA_CHANNEL2_BASE (void *)0x1C000140 +#define DMA_CHANNEL3_BASE (void *)0x1C000160 +#define DMA_CHANNEL4_BASE (void *)0x1C000180 +#define DMA_CHANNEL5_BASE (void *)0x1C0001A0 + +#define CRG ((CRG_RegStruct *)CRG_BASE) +#define CMM ((CMM_RegStruct *)CMM_BASE) +#define CFD ((CFD_RegStruct *)CFD_BASE) +#define SYSCTRL0 ((SYSCTRL0_RegStruct *)SYSCTRL0_BASE) +#define SYSCTRL1 ((SYSCTRL1_RegStruct *)SYSCTRL1_BASE) +#define UART0 ((UART_RegStruct *)UART0_BASE) +#define UART1 ((UART_RegStruct *)UART1_BASE) +#define UART2 ((UART_RegStruct *)UART2_BASE) +#define UART3 ((UART_RegStruct *)UART3_BASE) +#define UART4 ((UART_RegStruct *)UART4_BASE) +#define I2C0 ((I2C_RegStruct *)I2C0_BASE) +#define SPI0 ((SPI_RegStruct *)SPI0_BASE) +#define SPI1 ((SPI_RegStruct *)SPI1_BASE) +#define TIMER0 ((TIMER_RegStruct *)TIMER0_BASE) +#define TIMER1 ((TIMER_RegStruct *)TIMER1_BASE) +#define TIMER2 ((TIMER_RegStruct *)TIMER2_BASE) +#define TIMER3 ((TIMER_RegStruct *)TIMER3_BASE) +#define SYSTICK ((SYSTICK_RegStruct *)SYSTICK_BASE) +#define WWDG ((WWDG_RegStruct *)WWDG_BASE) +#define IWDG ((IWDG_RegStruct *)IWDG_BASE) +#define GPIO0 ((GPIO_RegStruct *)GPIO0_BASE) +#define GPIO1 ((GPIO_RegStruct *)GPIO1_BASE) +#define GPIO2 ((GPIO_RegStruct *)GPIO2_BASE) +#define GPIO3 ((GPIO_RegStruct *)GPIO3_BASE) +#define GPIO4 ((GPIO_RegStruct *)GPIO4_BASE) +#define GPIO5 ((GPIO_RegStruct *)GPIO5_BASE) +#define GPIO6 ((GPIO_RegStruct *)GPIO6_BASE) +#define GPIO7 ((GPIO_RegStruct *)GPIO7_BASE) +#define GPIO8 ((GPIO_RegStruct *)GPIO8_BASE) +#define GPIO9 ((GPIO_RegStruct *)GPIO9_BASE) + +#define CAN ((CAN_RegStruct *)CAN_BASE) +#define CAN1 ((CAN_RegStruct *)CAN1_BASE) +#define GPT0 ((GPT_RegStruct *)GPT0_BASE) +#define GPT1 ((GPT_RegStruct *)GPT1_BASE) +#define EFC ((EFC_RegStruct *)EFC_BASE) +#define PMC ((PMC_RegStruct *)PMC_BASE) +#define CRC ((CRC_RegStruct *)CRC_BASE) +#define APT0 ((APT_RegStruct *)APT0_BASE) +#define APT1 ((APT_RegStruct *)APT1_BASE) +#define APT2 ((APT_RegStruct *)APT2_BASE) +#define APT3 ((APT_RegStruct *)APT3_BASE) +#define APT4 ((APT_RegStruct *)APT4_BASE) +#define APT5 ((APT_RegStruct *)APT5_BASE) +#define APT6 ((APT_RegStruct *)APT6_BASE) +#define APT7 ((APT_RegStruct *)APT7_BASE) +#define APT8 ((APT_RegStruct *)APT8_BASE) +#define CAPM0 ((CAPM_RegStruct *)CAPM0_BASE) +#define CAPM1 ((CAPM_RegStruct *)CAPM1_BASE) +#define CAPM2 ((CAPM_RegStruct *)CAPM2_BASE) +#define CAPM_COMM ((CAPM_COMM_RegStruct *)CAPM_COMM_BASE) +#define QDM0 ((QDM_RegStruct *)QDM0_BASE) +#define QDM1 ((QDM_RegStruct *)QDM1_BASE) +#define QDM2 ((QDM_RegStruct *)QDM2_BASE) +#define QDM3 ((QDM_RegStruct *)QDM3_BASE) +#define ADC0 ((ADC_RegStruct *)ADC0_BASE) +#define ADC1 ((ADC_RegStruct *)ADC1_BASE) +#define ADC2 ((ADC_RegStruct *)ADC2_BASE) +#define PGA0 ((PGA_RegStruct *)PGA0_BASE) +#define PGA1 ((PGA_RegStruct *)PGA1_BASE) +#define PGA2 ((PGA_RegStruct *)PGA2_BASE) +#define DAC0 ((DAC_RegStruct *)DAC0_BASE) +#define DAC1 ((DAC_RegStruct *)DAC1_BASE) +#define DAC2 ((DAC_RegStruct *)DAC2_BASE) +#define TSENSOR ((TSENSOR_RegStruct *)TSENSOR_BASE) +#define ACMP0 ((ACMP_RegStruct *)ACMP0_BASE) +#define ACMP1 ((ACMP_RegStruct *)ACMP1_BASE) +#define ACMP2 ((ACMP_RegStruct *)ACMP2_BASE) +#define DMA ((DMA_RegStruct *)DMA_BASE) +#define DMA_CHANNEL0 ((DMA_ChannelRegStruct *)DMA_CHANNEL0_BASE) +#define DMA_CHANNEL1 ((DMA_ChannelRegStruct *)DMA_CHANNEL1_BASE) +#define DMA_CHANNEL2 ((DMA_ChannelRegStruct *)DMA_CHANNEL2_BASE) +#define DMA_CHANNEL3 ((DMA_ChannelRegStruct *)DMA_CHANNEL3_BASE) +#define DMA_CHANNEL4 ((DMA_ChannelRegStruct *)DMA_CHANNEL4_BASE) +#define DMA_CHANNEL5 ((DMA_ChannelRegStruct *)DMA_CHANNEL5_BASE) +#define IOCMG ((IOConfig_RegStruct*)IOCMG_BASE) +#define VREF ((VREF_RegStruct *)VREF_BASE) + +#define IsCRGInstance(instance) ((instance) == CRG) +#define IsCMMInstance(instance) ((instance) == CMM) +#define IsCFDInstance(instance) ((instance) == CFD) +#define IsSYSCTRLInstance(instance) (((instance) == SYSCTRL0) || ((instance) == SYSCTRL1)) +#define IsUARTInstance(instance) (((instance) == UART0) || ((instance) == UART1) || \ + ((instance) == UART2) || ((instance) == UART3) || ((instance) == UART4)) +#define IsI2CInstance(instance) ((instance) == I2C0) +#define IsSPIInstance(instance) (((instance) == SPI0) || ((instance) == SPI1)) +#define IsTIMERInstance(instance) (((instance) == TIMER0) || ((instance) == TIMER1) || \ + ((instance) == TIMER2) || ((instance) == TIMER3)) +#define IsSYSTICKInstance(instance) ((instance) == SYSTICK) +#define IsWWDGInstance(instance) ((instance) == WWDG) +#define IsIWDGInstance(instance) ((instance) == IWDG) +#define IsGPIOInstance(instance) (((instance) == GPIO0) || ((instance) == GPIO1) || \ + ((instance) == GPIO2) || ((instance) == GPIO3) || \ + ((instance) == GPIO4) || ((instance) == GPIO5) || \ + ((instance) == GPIO6) || ((instance) == GPIO7) || \ + ((instance) == GPIO8) || ((instance) == GPIO9)) +#define IsCANInstance(instance) ((instance) == CAN || ((instance) == CAN1)) +#define IsGPTInstance(instance) (((instance) == GPT0) || ((instance) == GPT1)) +#define IsEFCInstance(instance) ((instance) == EFC) +#define IsPMCInstance(instance) ((instance) == PMC) +#define IsIOCMGInstance(instance) ((instance) == IOCMG) +#define IsCRCInstance(instance) ((instance) == CRC) +#define IsAPTInstance(instance) (((instance) == APT0) || ((instance) == APT1) || \ + ((instance) == APT2) || ((instance) == APT3) || \ + ((instance) == APT4) || ((instance) == APT5) || \ + ((instance) == APT6) || ((instance) == APT7) || ((instance) == APT8)) +#define IsCAPMInstance(instance) (((instance) == CAPM0) || ((instance) == CAPM1) || ((instance) == CAPM2)) +#define IsCAPMCOMMInstance(instance) ((instance) == CAPM_COMM) +#define IsQDMInstance(instance) (((instance) == QDM0) || ((instance) == QDM1) || \ + ((instance) == QDM2) || ((instance) == QDM3)) +#define IsADCInstance(instance) (((instance) == ADC0) || ((instance) == ADC1) || ((instance) == ADC2)) +#define IsPGAInstance(instance) (((instance) == PGA0) || ((instance) == PGA1) || ((instance) == PGA2)) +#define IsDACInstance(instance) (((instance) == DAC0) || ((instance) == DAC1) || ((instance) == DAC2)) +#define IsACMPInstance(instance) (((instance) == ACMP0) || ((instance) == ACMP1) || ((instance) == ACMP2)) +#define IsDMAInstance(instance) ((instance) == DMA) +#define IsDMACHXInstance(instance) (((instance) == DMA_CHANNEL0) || ((instance) == DMA_CHANNEL1) || \ + ((instance) == DMA_CHANNEL2) || ((instance) == DMA_CHANNEL3) || \ + ((instance) == DMA_CHANNEL4) || ((instance) == DMA_CHANNEL5)) +#define SRAM_START 0x2000000 +#define SRAM_END 0x2010000 +#define REGISTER_START 0x10000000 +#define REGISTER_END 0x1C000FFF + +#endif /* McuMagicTag_BASEADDR_H */ \ No newline at end of file diff --git a/src/chip/3066m/chipinc.h b/src/chip/3066m/chipinc.h new file mode 100644 index 0000000000000000000000000000000000000000..49666d0ffbc7453fa46604298e490131156650c6 --- /dev/null +++ b/src/chip/3066m/chipinc.h @@ -0,0 +1,37 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file chipinc.h + * @author MCU Driver Team + * @brief Contains chip-related header files. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_CHIPINC_H +#define McuMagicTag_CHIPINC_H + +/* Includes ------------------------------------------------------------------ */ +#include "feature.h" +#include "info.h" +#include "baseaddr.h" +#include "locktype.h" +#include "interrupt_ip.h" +#include "sysctrl.h" +#include "systick.h" +#include "ip_crg_common.h" + +#endif /* McuMagicTag_CHIPINC_H */ \ No newline at end of file diff --git a/src/chip/3066m/chipinit/anatrim/anatrim.c b/src/chip/3066m/chipinit/anatrim/anatrim.c new file mode 100644 index 0000000000000000000000000000000000000000..1c44273eee7ce7c329804f2d9b6757c93b007c15 --- /dev/null +++ b/src/chip/3066m/chipinit/anatrim/anatrim.c @@ -0,0 +1,259 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file anatrim.c + * @author MCU Driver Team + * @brief Chip Init modlue. + * @details Calibration of analog module parameters. + */ +#include "anatrim.h" + +float g_tsensorGain = 0.00418f; + +#ifdef FPGA +#else + +/** + * @brief Obtains the chip ID. + * @param None + * @retval None + */ +static bool CHIP_GetInfo(void) +{ + FOTP_INFO_RGN0_NUMBER_4 emptyData; + FOTP_INFO_RGN0_NUMBER_2 idData; + FOTP_InfoGet(FOTP_INFO_RNG0, 4U, (void *)&emptyData.comData); /* 4 is the number of fotp_empty_flag in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 2U, (void *)&idData.comData); /* 2 is the number of idData in otp */ + if (emptyData.REG.fotp_empty_flag != 0x5AA59669 || idData.REG.chip_id == 0xFFFFFFFF) { + return false; + } + return true; +} + +/** + * @brief VREF trim config. + * @param None + * @retval None + */ +static void VREF_Trim(void) +{ + FOTP_INFO_RGN0_NUMBER_20 trimData20; + FOTP_InfoGet(FOTP_INFO_RNG0, 20U, (void *)&trimData20.comData); /* 20 is the number of trim data in otp */ + /* VREF */ + VREF->VREF_TRIM0.BIT.da_iref_trim = trimData20.REG.data0.da_iref_trim; + VREF->VREF_TRIM0.BIT.da_ref_vref_trim = trimData20.REG.data0.da_ref_vref_trim; + VREF->VREF_TRIM0.BIT.da_ref_vbg_trim = trimData20.REG.data0.da_ref_vbg_trim; + unsigned int value = trimData20.REG.data1.da_ref_temp_trim3; + value |= (trimData20.REG.data1.da_ref_temp_trim2 << 8U); /* Shift left by 8 bits */ + value |= (trimData20.REG.data1.da_ref_temp_trim1 << 16U); /* Shift left by 16 bits */ + value |= (trimData20.REG.data0.da_ref_temp_trim0 << 24U); /* Shift left by 24 bits */ + VREF->VREF_TRIM1.reg = value; +} + +/** + * @brief TSENSOR trim config. + * @param None + * @retval None + */ +static void TSENSOR_Trim(void) +{ + HAL_CRG_IpEnableSet((void *)ADC1, IP_CLK_ENABLE); /* Enable the clock for calibration */ + FOTP_INFO_RGN0_NUMBER_20 trimData20; + FOTP_INFO_RGN0_NUMBER_21 trimData21; + FOTP_InfoGet(FOTP_INFO_RNG0, 20U, (void *)&trimData20.comData); /* 20 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 21U, (void *)&trimData21.comData); /* 21 is the number of trim data in otp */ + /* TSENSOR */ + TSENSOR->TSENSOR_TRIM.reg = trimData20.REG.data1.da_ref_vptat_trim; + ADC1->ADC_TSENSOR_TRIM.BIT.cfg_tsensor_ofst_trim = trimData21.REG.data1.ts_offset; + HAL_CRG_IpEnableSet((void *)ADC1, IP_CLK_DISABLE); /* The clock is disabled after calibration */ +} + +/** + * @brief PGA trim config. + * @param None + * @retval None + */ +static void PGA_Trim(void) +{ + HAL_CRG_IpEnableSet((void *)PGA0, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet((void *)PGA1, IP_CLK_ENABLE); + HAL_CRG_IpEnableSet((void *)PGA2, IP_CLK_ENABLE); + FOTP_INFO_RGN0_NUMBER_21 trimData21; + FOTP_InfoGet(FOTP_INFO_RNG0, 21U, (void *)&trimData21.comData); /* 21 is the number of trim data in otp */ + /* PGA */ + PGA0->PGA_TRIM.BIT.da_pga_vos_trim = trimData21.REG.data0.da_pga0_vos_trim; + PGA1->PGA_TRIM.BIT.da_pga_vos_trim = trimData21.REG.data0.da_pga1_vos_trim; + PGA2->PGA_TRIM.BIT.da_pga_vos_trim = trimData21.REG.data1.da_pga2_vos_trim; + HAL_CRG_IpEnableSet((void *)PGA0, IP_CLK_DISABLE); + HAL_CRG_IpEnableSet((void *)PGA1, IP_CLK_DISABLE); + HAL_CRG_IpEnableSet((void *)PGA2, IP_CLK_DISABLE); +} + +/** + * @brief ADC0 trim config. + * @param None + * @retval None + */ +static void ADC0_Trim(void) +{ + HAL_CRG_IpEnableSet((void *)ADC0, IP_CLK_ENABLE); /* Enable the clock for calibration */ + + FOTP_INFO_RGN0_NUMBER_21 trimData21; + FOTP_INFO_RGN0_NUMBER_22 trimData22; + FOTP_INFO_RGN0_NUMBER_23 trimData23; + FOTP_INFO_RGN0_NUMBER_24 trimData24; + FOTP_InfoGet(FOTP_INFO_RNG0, 21U, (void *)&trimData21.comData); /* 21 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 22U, (void *)&trimData22.comData); /* 22 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 23U, (void *)&trimData23.comData); /* 23 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 24U, (void *)&trimData24.comData); /* 24 is the number of trim data in otp */ + + ADC0->ADC_OEGE_TRIM.BIT.cfg_gain_cali_trim = trimData21.REG.data2.saradc0_gain; + ADC0->ADC_OEGE_TRIM.BIT.cfg_ofst_cali_trim = trimData21.REG.data2.saradc0_offset; + + ADC0->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_gain_trim2 = trimData22.REG.data2.saradc0_ain0_gain2; + ADC0->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_ofst_trim2 = trimData22.REG.data2.saradc0_ain0_offset2; + ADC0->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_gain_trim4 = trimData22.REG.data3.saradc0_ain0_gain4; + ADC0->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_ofst_trim4 = trimData22.REG.data3.saradc0_ain0_offset4; + ADC0->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_gain_trim8 = trimData23.REG.data0.saradc0_ain0_gain8; + ADC0->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_ofst_trim8 = trimData23.REG.data0.saradc0_ain0_offset8; + ADC0->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_gain_trim16 = trimData23.REG.data1.saradc0_ain0_gain16; + ADC0->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_ofst_trim16 = trimData23.REG.data1.saradc0_ain0_offset16; + + ADC0->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_gain_trim2 = trimData23.REG.data2.saradc0_ain1_gain2; + ADC0->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_ofst_trim2 = trimData23.REG.data2.saradc0_ain1_offset2; + ADC0->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_gain_trim4 = trimData23.REG.data3.saradc0_ain1_gain4; + ADC0->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_ofst_trim4 = trimData23.REG.data3.saradc0_ain1_offset4; + ADC0->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_gain_trim8 = trimData24.REG.data0.saradc0_ain1_gain8; + ADC0->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_ofst_trim8 = trimData24.REG.data0.saradc0_ain1_offset8; + ADC0->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_gain_trim16 = trimData24.REG.data1.saradc0_ain1_gain16; + ADC0->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_ofst_trim16 = trimData24.REG.data1.saradc0_ain1_offset16; + + HAL_CRG_IpEnableSet((void *)ADC0, IP_CLK_DISABLE); /* The clock is disabled after calibration */ +} + +/** + * @brief ADC1 trim config. + * @param None + * @retval None + */ +static void ADC1_Trim(void) +{ + HAL_CRG_IpEnableSet((void *)ADC1, IP_CLK_ENABLE); /* Enable the clock for calibration */ + + FOTP_INFO_RGN0_NUMBER_21 trimData21; + FOTP_INFO_RGN0_NUMBER_24 trimData24; + FOTP_INFO_RGN0_NUMBER_25 trimData25; + FOTP_INFO_RGN0_NUMBER_26 trimData26; + FOTP_InfoGet(FOTP_INFO_RNG0, 21U, (void *)&trimData21.comData); /* 21 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 24U, (void *)&trimData24.comData); /* 24 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 25U, (void *)&trimData25.comData); /* 25 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 26U, (void *)&trimData26.comData); /* 26 is the number of trim data in otp */ + + ADC1->ADC_OEGE_TRIM.BIT.cfg_gain_cali_trim = trimData21.REG.data3.saradc1_gain; + ADC1->ADC_OEGE_TRIM.BIT.cfg_ofst_cali_trim = trimData21.REG.data3.saradc1_offset; + + ADC1->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_gain_trim2 = trimData24.REG.data2.saradc1_ain0_gain2; + ADC1->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_ofst_trim2 = trimData24.REG.data2.saradc1_ain0_offset2; + ADC1->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_gain_trim4 = trimData24.REG.data3.saradc1_ain0_gain4; + ADC1->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_ofst_trim4 = trimData24.REG.data3.saradc1_ain0_offset4; + ADC1->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_gain_trim8 = trimData25.REG.data0.saradc1_ain0_gain8; + ADC1->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_ofst_trim8 = trimData25.REG.data0.saradc1_ain0_offset8; + ADC1->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_gain_trim16 = trimData25.REG.data1.saradc1_ain0_gain16; + ADC1->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_ofst_trim16 = trimData25.REG.data1.saradc1_ain0_offset16; + + ADC1->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_gain_trim2 = trimData25.REG.data2.saradc1_ain1_gain2; + ADC1->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_ofst_trim2 = trimData25.REG.data2.saradc1_ain1_offset2; + ADC1->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_gain_trim4 = trimData25.REG.data3.saradc1_ain1_gain4; + ADC1->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_ofst_trim4 = trimData25.REG.data3.saradc1_ain1_offset4; + ADC1->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_gain_trim8 = trimData26.REG.data0.saradc1_ain1_gain8; + ADC1->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_ofst_trim8 = trimData26.REG.data0.saradc1_ain1_offset8; + ADC1->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_gain_trim16 = trimData26.REG.data1.saradc1_ain1_gain16; + ADC1->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_ofst_trim16 = trimData26.REG.data1.saradc1_ain1_offset16; + + HAL_CRG_IpEnableSet((void *)ADC1, IP_CLK_DISABLE); /* The clock is disabled after calibration */ +} + +/** + * @brief ADC2 trim config. + * @param None + * @retval None + */ +static void ADC2_Trim(void) +{ + HAL_CRG_IpEnableSet((void *)ADC2, IP_CLK_ENABLE); /* Enable the clock for calibration */ + + FOTP_INFO_RGN0_NUMBER_22 trimData22; + FOTP_INFO_RGN0_NUMBER_26 trimData26; + FOTP_INFO_RGN0_NUMBER_27 trimData27; + FOTP_INFO_RGN0_NUMBER_28 trimData28; + FOTP_InfoGet(FOTP_INFO_RNG0, 22U, (void *)&trimData22.comData); /* 22 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 26U, (void *)&trimData26.comData); /* 26 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 27U, (void *)&trimData27.comData); /* 27 is the number of trim data in otp */ + FOTP_InfoGet(FOTP_INFO_RNG0, 28U, (void *)&trimData28.comData); /* 28 is the number of trim data in otp */ + + ADC2->ADC_OEGE_TRIM.BIT.cfg_gain_cali_trim = trimData22.REG.data0.saradc2_gain; + ADC2->ADC_OEGE_TRIM.BIT.cfg_ofst_cali_trim = trimData22.REG.data0.saradc2_offset; + + ADC2->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_gain_trim2 = trimData26.REG.data2.saradc2_ain0_gain2; + ADC2->ADC_AIN0_OEGE_TRIM0.BIT.cfg_ain0_ofst_trim2 = trimData26.REG.data2.saradc2_ain0_offset2; + ADC2->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_gain_trim4 = trimData26.REG.data3.saradc2_ain0_gain4; + ADC2->ADC_AIN0_OEGE_TRIM1.BIT.cfg_ain0_ofst_trim4 = trimData26.REG.data3.saradc2_ain0_offset4; + ADC2->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_gain_trim8 = trimData27.REG.data0.saradc2_ain0_gain8; + ADC2->ADC_AIN0_OEGE_TRIM2.BIT.cfg_ain0_ofst_trim8 = trimData27.REG.data0.saradc2_ain0_offset8; + ADC2->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_gain_trim16 = trimData27.REG.data1.saradc2_ain0_gain16; + ADC2->ADC_AIN0_OEGE_TRIM3.BIT.cfg_ain0_ofst_trim16 = trimData27.REG.data1.saradc2_ain0_offset16; + + ADC2->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_gain_trim2 = trimData27.REG.data2.saradc2_ain1_gain2; + ADC2->ADC_AIN1_OEGE_TRIM0.BIT.cfg_ain1_ofst_trim2 = trimData27.REG.data2.saradc2_ain1_offset2; + ADC2->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_gain_trim4 = trimData27.REG.data3.saradc2_ain1_gain4; + ADC2->ADC_AIN1_OEGE_TRIM1.BIT.cfg_ain1_ofst_trim4 = trimData27.REG.data3.saradc2_ain1_offset4; + ADC2->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_gain_trim8 = trimData28.REG.data0.saradc2_ain1_gain8; + ADC2->ADC_AIN1_OEGE_TRIM2.BIT.cfg_ain1_ofst_trim8 = trimData28.REG.data0.saradc2_ain1_offset8; + ADC2->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_gain_trim16 = trimData28.REG.data1.saradc2_ain1_gain16; + ADC2->ADC_AIN1_OEGE_TRIM3.BIT.cfg_ain1_ofst_trim16 = trimData28.REG.data1.saradc2_ain1_offset16; + + HAL_CRG_IpEnableSet((void *)ADC2, IP_CLK_DISABLE); /* The clock is disabled after calibration */ +} + +/** + * @brief Analog module trim. + * @param None + * @retval None + */ +static void CHIP_AnalogTrim(void) +{ + VREF_Trim(); /* VREF trim config */ + PGA_Trim(); /* PGA trim config */ + TSENSOR_Trim(); /* TSENSOR trim config */ + ADC0_Trim(); /* ADC0 trim config */ + ADC1_Trim(); /* ADC1 trim config */ + ADC2_Trim(); /* ADC2 trim config */ +} + +/** + * @brief Parameter calibration entry of the analog module. + * @param None + * @retval None + */ +void ANATRIM_Entry(void) +{ + if (CHIP_GetInfo() == false) { /* If the chip information is incorrect, calibration is not performed */ + return; + } + CHIP_AnalogTrim(); /* Analog trim config */ +} +#endif \ No newline at end of file diff --git a/src/chip/3066m/chipinit/anatrim/anatrim.h b/src/chip/3066m/chipinit/anatrim/anatrim.h new file mode 100644 index 0000000000000000000000000000000000000000..f5c709286ab07567e54a70994ee10864caa48077 --- /dev/null +++ b/src/chip/3066m/chipinit/anatrim/anatrim.h @@ -0,0 +1,39 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file anatrim.h + * @author MCU Driver Team + * @brief Chip Init modlue. + * @details Calibration of analog module parameters. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_ANATRIM_H +#define McuMagicTag_ANATRIM_H +#include "baseinc.h" +#ifdef FPGA +#else +#include "fotp_info_read.h" +#include "anavref.h" +#include "tsensor_ip.h" +#include "adc_ip.h" +#include "pga_ip.h" +#include "crg.h" +void ANATRIM_Entry(void); +#endif +extern float g_tsensorGain; +#endif /* McuMagicTag_ANATRIM_H */ \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/nos_idle.c b/src/chip/3066m/chipinit/anavrefinit/anavrefinit.c similarity index 73% rename from src/middleware/hisilicon/nostask/kernel/nos_idle.c rename to src/chip/3066m/chipinit/anavrefinit/anavrefinit.c index 523f4c693460ab0bb486da7e68bf3795465695f2..ee6a5ab86218ab939e746d045acd6fdca2f47249 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_idle.c +++ b/src/chip/3066m/chipinit/anavrefinit/anavrefinit.c @@ -15,42 +15,25 @@ * 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. - * @file nos_idle.c + * @file anavrefinit.c + * @author MCU Driver Team + * @brief anavref init modlue. + * @details anavref initialization function during startup */ -#include "nos_idle_external.h" -/* - * 描述: 单次Idle任务 - */ - INLINE void OsErrInHwiProc(void) -{ -} - -/* - * 描述: Idle任务 - */ -void OsIdleTaskExe(void) -{ - OsErrInHwiProc(); -} +#include "anavrefinit.h" -/* - * 描述: idle线程,循环执行“单次idle任务” - */ -void OsIdleThread(void) -{ - while (TRUE) { - /* 循环idle线程 */ - OsIdleTaskExe(); - } -} - -/* - * 描述: idle注册函数 +/** + * @brief Set Crg Core clock select + * @param None + * @retval None */ -void OsIdleReg(void); -void OsIdleReg(void) +void ANAVREF_Init(void) { - /* idle回调函数 */ - g_idleEntry = (OsVoidFunc)OsIdleThread; -} + HAL_CRG_IpEnableSet(VREF_BASE, IP_CLK_ENABLE); + VREF->VREF_CTRL1.BIT.da_ref_temp_trim_enh = 0x1; + VREF->VREF_CTRL0.BIT.da_ref_enh = BASE_CFG_ENABLE; + BASE_FUNC_DELAY_US(200); /* delay 200us */ + VREF->VREF_CTRL1.BIT.da_ref_chop_enh = BASE_CFG_ENABLE; + BASE_FUNC_DELAY_US(40); /* delay 40us */ +} \ No newline at end of file diff --git a/src/chip/3066m/chipinit/anavrefinit/anavrefinit.h b/src/chip/3066m/chipinit/anavrefinit/anavrefinit.h new file mode 100644 index 0000000000000000000000000000000000000000..56396fe15f156743be4fb513f098026cd0aff153 --- /dev/null +++ b/src/chip/3066m/chipinit/anavrefinit/anavrefinit.h @@ -0,0 +1,32 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file anavrefint.h + * @author MCU Driver Team + * @brief anavref init modlue. + * @details anavref initialization function during startup + */ + +#ifndef McuMagicTag_ANAVREF_H +#define McuMagicTag_ANAVREF_H + +#include "baseinc.h" +#include "crg.h" +#include "anavref.h" + +void ANAVREF_Init(void); +#endif \ No newline at end of file diff --git a/src/chip/3066m/chipinit/chipinit.c b/src/chip/3066m/chipinit/chipinit.c new file mode 100644 index 0000000000000000000000000000000000000000..a83ca3e4ba6cd138477b6e8844ffedaf1dec0fe3 --- /dev/null +++ b/src/chip/3066m/chipinit/chipinit.c @@ -0,0 +1,83 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file chipint.c + * @author MCU Driver Team + * @brief Chip Init modlue. + * @details Declare a function that needs to be executed as soon as the C + * runtime environment is ready + */ +#include "chipinc.h" +#include "crginit.h" +#include "systickinit.h" +#include "flashinit.h" +#include "crg.h" +#include "interrupt.h" +#ifdef NOS_TASK_SUPPORT +#include "nosinit.h" +#endif +#include "chipinit.h" + +#include "anavrefinit.h" +#ifndef FPGA /* Delete the compilation macro after the ASIC to release the header file. */ +#include "anatrim.h" +#endif + +/** + * @brief Chip Init Fail Process, deadloop if Chip Init fail + * @param None + * @retval None + */ +static inline void Chip_InitFail(void) +{ + while (1) { + ; + } +} + +/** + * @brief Chip Init + * @param None + * @retval None + */ +void Chip_Init(void) +{ + CRG_CoreClkSelect coreClkSelect; + /* Config CRG */ + if (CRG_Config(&coreClkSelect) != BASE_STATUS_OK) { + Chip_InitFail(); + } + + /* Config FLASH Clock */ + FLASH_ClockConfig(coreClkSelect); + IRQ_Init(); + SYSTICK_Init(); + /* Set CoreClock Select after FLASH Config Done */ + CRG_SetCoreClockSelect(coreClkSelect); +#ifdef NOS_TASK_SUPPORT + SYSTICK_IRQ_Enable(); +#endif + ANAVREF_Init(); +#ifndef FPGA /* Delete the compilation macro after the ASIC to release the header file. */ + ANATRIM_Entry(); +#endif + +#ifdef NOS_TASK_SUPPORT + NOS_Init(); +#endif + /* User Add Code Here */ +} \ No newline at end of file diff --git a/src/chip/3066m/chipinit/chipinit.h b/src/chip/3066m/chipinit/chipinit.h new file mode 100644 index 0000000000000000000000000000000000000000..a089414fc3dbd928b029c8e4540d1b545de63857 --- /dev/null +++ b/src/chip/3066m/chipinit/chipinit.h @@ -0,0 +1,31 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file chipinit.h + * @author MCU Driver Team + * @brief Chip Init modlue. + * @details Declare a function that needs to be executed as soon as the C + * runtime environment is ready + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_CHIPINIT_H +#define McuMagicTag_CHIPINIT_H + +void Chip_Init(void); + +#endif /* McuMagicTag_CHIPINIT_H */ \ No newline at end of file diff --git a/src/chip/3066m/chipinit/crginit/crginit.c b/src/chip/3066m/chipinit/crginit/crginit.c new file mode 100644 index 0000000000000000000000000000000000000000..a9e065666cec7246de4067bbdb679e6adbe3d22c --- /dev/null +++ b/src/chip/3066m/chipinit/crginit/crginit.c @@ -0,0 +1,65 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file crginit.c + * @author MCU Driver Team + * @brief crg init modlue. + * @details crg initialization function during startup + */ +#include "crginit.h" + +/** + * @brief CRG Config + * @param coreClkSelect OutPut core clock select value + * @retval None + */ +__weak BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + BASE_FUNC_ASSERT_PARAM(coreClkSelect != NULL); + + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllFbDiv = 0x30; /* PLL loop divider ratio = 0x30 */ + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_HOSC; /* ASIC need change as CRG_CORE_CLK_SELECT_PLL */ + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; /* Set the 1MHz clock select. */ + crg.handleEx.clk1MDiv = 0x18; /* 0x18 : ensure that the 1MHz clock frequency is 1 MHz. */ + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +/** + * @brief Set Crg Core clock select + * @param coreClkSelect Input core clock select value + * @retval None + */ +void CRG_SetCoreClockSelect(CRG_CoreClkSelect coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.coreClkSelect = coreClkSelect; + if (crg.coreClkSelect == CRG_CORE_CLK_SELECT_TCXO) { /* If an external crystal oscillator is selected. */ + BASE_FUNC_DELAY_MS(10); /* 10: delay 10ms, wait clokc stable. */ + } + HAL_CRG_SetCoreClockSelect(&crg); +} \ No newline at end of file diff --git a/src/chip/3066m/chipinit/crginit/crginit.h b/src/chip/3066m/chipinit/crginit/crginit.h new file mode 100644 index 0000000000000000000000000000000000000000..c61cee5beafe32c3089f471ec1e2061a50104526 --- /dev/null +++ b/src/chip/3066m/chipinit/crginit/crginit.h @@ -0,0 +1,33 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file crginit.h + * @author MCU Driver Team + * @brief crg init modlue. + * @details crg initialization function during startup + */ + +#ifndef McuMagicTag_CRGINIT_H +#define McuMagicTag_CRGINIT_H + +#include "baseinc.h" +#include "crg.h" + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void CRG_SetCoreClockSelect(CRG_CoreClkSelect coreClkSelect); + +#endif \ No newline at end of file diff --git a/src/chip/3066m/chipinit/flashinit/flashinit.c b/src/chip/3066m/chipinit/flashinit/flashinit.c new file mode 100644 index 0000000000000000000000000000000000000000..a8a890c39b70321059b22684d63a30b8ba4388c3 --- /dev/null +++ b/src/chip/3066m/chipinit/flashinit/flashinit.c @@ -0,0 +1,114 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flashinit.c + * @author MCU Driver Team + * @brief flash init modlue. + * @details flash initialization function during startup + */ +#include "chipinit.h" +#include "crg.h" +#include "flash_ip.h" +#include "flashinit.h" + +#define CHIP_MAX_FREQ (200 * 1000 * 1000) /* 200MHz. */ +#define FLASH_BASE_FREQ (375 * 100 * 1000) /* 37.5MHz. */ +#define FLASH_MAX_DIV 5 + +/** + * @brief Get the Rounding up value + * @param frequence frequnce + * @param div Output Divison + * @retval None + */ +static void SetFlashDiv(unsigned int frequency, unsigned int *nreadDiv) +{ + unsigned int div; + unsigned int freq = frequency; + /* Get frequency divider of flash. */ + if (freq < FLASH_BASE_FREQ) { + freq = FLASH_BASE_FREQ; + } + if (freq > CHIP_MAX_FREQ) { + freq = CHIP_MAX_FREQ; + } + + /* Get the flash frequency division based on the frequency. */ + if ((freq % FLASH_BASE_FREQ) == 0) { + div = freq / FLASH_BASE_FREQ; + } else { + div = (freq / FLASH_BASE_FREQ) + 1; + } + + /* Ensure the flash frequency division is valid. */ + if (div > FLASH_MAX_DIV) { + div = FLASH_MAX_DIV; + } + *nreadDiv = div; +} + +/** + * @brief Get the Rounding up value + * @param coreClkSelect Core Clock select + * @retval Frequency of Flash + */ +static unsigned int GetFlashFreq(CRG_CoreClkSelect coreClkSelect) +{ + unsigned int hclk; + /* Get frequency of flash. */ + switch (coreClkSelect) { + case CRG_CORE_CLK_SELECT_HOSC: + hclk = HOSC_FREQ; + break; + case CRG_CORE_CLK_SELECT_TCXO: + hclk = XTRAIL_FREQ; + break; + case CRG_CORE_CLK_SELECT_PLL: + hclk = HAL_CRG_GetPllFreq(); + break; + default: + hclk = LOSC_FREQ; + break; + } + return hclk; +} + +/** + * @brief Set flash clock frequence base on hclk + * @param coreClkSelect core clock select + * @retval None + */ +void FLASH_ClockConfig(CRG_CoreClkSelect coreClkSelect) +{ + EFC_RegStruct *efc = EFC; + EFLASH_CLK_CFG_REG cfg; + unsigned int hclk; + unsigned int nreadDiv; + + /* Step 1: Set nread_div */ + hclk = GetFlashFreq(coreClkSelect); + cfg.reg = efc->EFLASH_CLK_CFG.reg; + SetFlashDiv(hclk, &nreadDiv); + cfg.BIT.nread_div = nreadDiv; + cfg.BIT.busclk_sw_req = BASE_CFG_SET; + efc->EFLASH_CLK_CFG.reg = cfg.reg; + + /* Step 2: Wait Busclk_sw_req */ + while (efc->EFLASH_CLK_CFG.BIT.busclk_sw_req == BASE_CFG_SET) { + ; + } +} \ No newline at end of file diff --git a/src/chip/3066m/chipinit/flashinit/flashinit.h b/src/chip/3066m/chipinit/flashinit/flashinit.h new file mode 100644 index 0000000000000000000000000000000000000000..a1b86950537b8d50be988410be348afd4368d3ab --- /dev/null +++ b/src/chip/3066m/chipinit/flashinit/flashinit.h @@ -0,0 +1,32 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flashinit.h + * @author MCU Driver Team + * @brief flash init modlue. + * @details flash initialization function during startup + */ + +#ifndef McuMagicTag_FLASHINIT_H +#define McuMagicTag_FLASHINIT_H + +#include "baseinc.h" +#include "crg.h" + +void FLASH_ClockConfig(CRG_CoreClkSelect coreClkSelect); + +#endif \ No newline at end of file diff --git a/src/chip/3066m/chipinit/nosinit/nosinit.c b/src/chip/3066m/chipinit/nosinit/nosinit.c new file mode 100644 index 0000000000000000000000000000000000000000..c1794b8b7ead67639628b3137b26ce1dd4132c58 --- /dev/null +++ b/src/chip/3066m/chipinit/nosinit/nosinit.c @@ -0,0 +1,74 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file nosinit.c + * @author MCU Driver Team + * @brief nos init module. + * @details nos initialization function during startup + */ +#include "feature.h" +#ifdef NOS_TASK_SUPPORT +#include "nos_task.h" +#include "nosinit.h" +#include "systick.h" +#include "crg.h" + +#ifndef CFG_NOS_MAINTASK_STACKSIZE +#define CFG_NOS_MAINTASK_STACKSIZE 0x500 +#endif +#define CYCCLE_PERUS 200 +// User define the stack size of main task by CFG_NOS_MAINTASK_STACKSIZE +unsigned char __attribute__((aligned(16))) g_taskMainStackSpace[CFG_NOS_MAINTASK_STACKSIZE]; + +static unsigned int g_nosSysFreq; +// Get tick in real time +static unsigned long long NOS_GetTick(void) +{ + unsigned int cycle, cycleh; + asm volatile("csrr %0, cycle" : "=r"(cycle)); + asm volatile("csrr %0, cycleh" : "=r"(cycleh)); + unsigned long long longCycle = (unsigned long long)cycle + (unsigned long long)cycleh * 0xFFFFFFFF; + // tick = cycle/freq + return longCycle / g_nosSysFreq; +} + +/** + * @brief Init the Nos Task Schedule + * @param None + * @retval None + */ +void NOS_Init(void) +{ + unsigned int taskId; + NOS_SysConfig config = {}; + g_nosSysFreq = SYSTICK_GetCRGHZ() / CRG_FREQ_1MHz * CFG_SYSTICK_TICKINTERVAL_US; + config.usecPerTick = SYSTICK_GetTickInterval(); /* Set the tick size of Nos task schedule */ + config.getTickFunc = NOS_GetTick; + config.cyclePerUs = CYCCLE_PERUS; + NOS_TaskInit(&config); + NOS_TaskInitParam param = {}; + param.name = "mainTask"; + param.taskEntry = (NOS_TaskEntryFunc)main; /* Set the entry function by user define */ + param.param = 0; + param.priority = NOS_TASK_PRIORITY_LOWEST; + param.stackAddr = (unsigned int)g_taskMainStackSpace; + param.stackSize = sizeof(g_taskMainStackSpace); + param.privateData = 0; + (void)NOS_TaskCreate(¶m, &taskId); + (void)NOS_StartScheduler(); /* Nos task schedule start */ +} +#endif \ No newline at end of file diff --git a/src/chip/3066m/chipinit/nosinit/nosinit.h b/src/chip/3066m/chipinit/nosinit/nosinit.h new file mode 100644 index 0000000000000000000000000000000000000000..52fad8687d3f78a54d0db9534014369284a5faf5 --- /dev/null +++ b/src/chip/3066m/chipinit/nosinit/nosinit.h @@ -0,0 +1,35 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file nosinit.h + * @author MCU Driver Team + * @brief nos init module. + * @details nos initialization function during startup + */ + +#ifndef NOS_INIT_H +#define NOS_INIT_H + +#include "feature.h" + +#ifdef NOS_TASK_SUPPORT +extern int main(void); +extern void OsHwiDispatchTick(void); +void NOS_Init(void); +#endif + +#endif \ No newline at end of file diff --git a/src/chip/3066m/chipinit/systickinit/systickinit.c b/src/chip/3066m/chipinit/systickinit/systickinit.c new file mode 100644 index 0000000000000000000000000000000000000000..82bdf73d141ac955f5753a6e8fd7cbc117123827 --- /dev/null +++ b/src/chip/3066m/chipinit/systickinit/systickinit.c @@ -0,0 +1,102 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file systickinit.c + * @author MCU Driver Team + * @brief systick init modlue. + * @details systick initialization function during startup + */ +#include "baseaddr.h" +#include "crg.h" +#include "timer.h" +#include "systick.h" +#include "systickinit.h" +#include "feature.h" +#ifdef NOS_TASK_SUPPORT +#include "interrupt.h" +#include "nosinit.h" +#endif + +TIMER_Handle g_systickHandle; +#ifdef NOS_TASK_SUPPORT +#define NOS_TickPostDispatch OsHwiDispatchTick + +static void SYSTICK_Default_Callback(void *handle) +{ + /* The default systick callback when using th nos task */ + BASE_FUNC_UNUSED(handle); + NOS_TickPostDispatch(); +} + +void SYSTICK_IRQ_Enable(void) +{ + HAL_CRG_IpEnableSet(TIMER3_BASE, IP_CLK_ENABLE); + /* Choose the config to support GetTick and Delay */ + g_systickHandle.baseAddress = TIMER3; /* use timer module */ + g_systickHandle.load = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + g_systickHandle.bgLoad = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + g_systickHandle.mode = TIMER_MODE_RUN_PERIODIC; + g_systickHandle.prescaler = TIMERPRESCALER_NO_DIV; /* frequency not divition */ + g_systickHandle.size = TIMER_SIZE_32BIT; + g_systickHandle.interruptEn = BASE_CFG_ENABLE; + HAL_TIMER_Init(&g_systickHandle); + HAL_TIMER_RegisterCallback(&g_systickHandle, TIMER_PERIOD_FIN, SYSTICK_Default_Callback); /* nos task schedule */ + IRQ_SetPriority(IRQ_TIMER3, 1); /* interrupt priority 1 */ + IRQ_Register(IRQ_TIMER3, HAL_TIMER_IrqHandler, &g_systickHandle); + IRQ_EnableN(IRQ_TIMER3); + HAL_TIMER_Start(&g_systickHandle); /* start timer module */ +} + +unsigned int SYSTICK_GetTickInterval(void) +{ + /* Get the tick interval(the number of usecond per tick) */ + return CFG_SYSTICK_TICKINTERVAL_US; +} + +#endif + +unsigned int SYSTICK_GetTimeStampUs(void) +{ + /* Get the systick timestamp(convert from the systick value) */ + return DCL_SYSTICK_GetTick() / (SYSTICK_GetCRGHZ() / CRG_FREQ_1MHz); +} + +/** + * @brief Init the systick + * @param None + * @retval None + */ +void SYSTICK_Init(void) +{ + SYSTICK->TIMER_CTRL.reg = 0; + SYSTICK->TIMER_CTRL.BIT.enable = 1; +} + +/** + * @brief Get the Systick frep(Hz) + * @param None + * @retval Clock frep of systick(Hz) + */ +unsigned int SYSTICK_GetCRGHZ(void) +{ +#ifdef NOS_TASK_SUPPORT + return HAL_CRG_GetCoreClkFreq(); +#else + /* Get the Systick IP */ + return HAL_CRG_GetIpFreq(SYSTICK_BASE); +#endif +} \ No newline at end of file diff --git a/src/chip/3066m/chipinit/systickinit/systickinit.h b/src/chip/3066m/chipinit/systickinit/systickinit.h new file mode 100644 index 0000000000000000000000000000000000000000..38757f28c1975e141a26896f0e37ded85216c8eb --- /dev/null +++ b/src/chip/3066m/chipinit/systickinit/systickinit.h @@ -0,0 +1,35 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file systickinit.h + * @author MCU Driver Team + * @brief systick init modlue. + * @details systick initialization function during startup + */ + +#ifndef McuMagicTag_SYSTICKINIT_H +#define McuMagicTag_SYSTICKINIT_H + +#include "feature.h" + +void SYSTICK_Init(void); +unsigned int SYSTICK_GetCRGHZ(void); +#ifdef NOS_TASK_SUPPORT +void SYSTICK_IRQ_Enable(void); +#endif + +#endif \ No newline at end of file diff --git a/src/chip/3066m/codecopy.json b/src/chip/3066m/codecopy.json new file mode 100644 index 0000000000000000000000000000000000000000..83e496cbfb3be2e25ed62a569fad6ccc4f3db6c6 --- /dev/null +++ b/src/chip/3066m/codecopy.json @@ -0,0 +1,47 @@ +{ + "modules": [ + "application/user", + "build", + "chip/3066m", + "chip/target/userconfig_for_3066m.json", + "drivers/debug", + "generatecode", + "middleware/control_library", + "middleware/function_safety", + "middleware/hisilicon/libboundscheck_v1.1.16", + "middleware/thirdparty/sysroot", + "tools/uttest", + "bundle.json" + ], + + "ip_drive_file": ["acmp", "adc", "apt", "base", "can", "capm", "cfd", "cmm", "crc", "crg", + "dac", "dma", "flash", "gpio", "gpt", "i2c", "pga", "pmc", "qdm", "spi", + "timer", "tsensor", "uart", "iwdg", "iocmg", "wwdg", "smbus"], + "acmp" : ["common", "acmp_v2", "testcase_v2"], + "adc" : ["common", "adc_v1", "testcase_v1"], + "apt" : ["common", "apt_v2", "testcase_v1"], + "base" : ["common", "base_v0"], + "can" : ["common", "can_v0", "testcase_v0"], + "capm" : ["common", "capm_v1", "testcase_v1"], + "cfd" : ["common", "cfd_v0", "testcase_v0"], + "cmm" : ["common", "cmm_v2", "testcase_v2"], + "crc" : ["common", "crc_v1", "testcase_v1"], + "crg" : ["common", "crg_v3", "testcase_v3"], + "dac" : ["common", "dac_v1", "testcase_v1"], + "dma" : ["common", "dma_v1", "testcase_v1"], + "flash" : ["common", "flash_v3", "testcase_v1"], + "gpio" : ["common", "gpio_v0", "testcase_v0"], + "gpt" : ["common_v1", "gpt_v1", "testcase_v1"], + "i2c" : ["common", "i2c_v3", "testcase_v1"], + "pga" : ["common", "pga_v2", "testcase_v2"], + "pmc" : ["common", "pmc_v3", "testcase_v3"], + "qdm" : ["common", "qdm_v0", "testcase_v0"], + "spi" : ["common", "spi_v3", "testcase_v3"], + "timer" : ["common", "timer_v1", "testcase_v1"], + "tsensor" : ["common", "tsensor_v1", "testcase_v1"], + "uart" : ["common", "uart_v3", "testcase_v3"], + "iwdg" : ["common", "iwdg_v2", "testcase_v2"], + "iocmg" : ["common", "iocmg_v3", "testcase_v3"], + "wwdg" : ["common", "wwdg_v2", "testcase_v2"], + "smbus" : ["common", "smbus_v0", "testcase_v0"] +} \ No newline at end of file diff --git a/src/chip/3066m/flash.lds b/src/chip/3066m/flash.lds new file mode 100644 index 0000000000000000000000000000000000000000..5cf05c804707f750ceb7321927af490ac79c8208 --- /dev/null +++ b/src/chip/3066m/flash.lds @@ -0,0 +1,190 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flash.lds + * @author MCU Application Driver Team + * @brief RISCV flash link script + */ + +OUTPUT_ARCH( "riscv" ) +ENTRY(_start) + +SRAM_START = 0x2000000; +SRAM_END = 0x2000000 + 64K; + +RAM_CODE_START = 0x2000000; +RAM_CODE_SIZE = 0; + +RAM_RESERVE_DATA_START = SRAM_START + RAM_CODE_SIZE; +RAM_RESERVE_DATA_SIZE = 0; + +RAM_DIAGNOSE_BUF_START = RAM_RESERVE_DATA_START + RAM_RESERVE_DATA_SIZE; +RAM_DIAGNOSE_BUF_SIZE = 0x20; + +STACK_SRAM_BOUND_SIZE = 0x10; + +RAM_START = RAM_RESERVE_DATA_START + RAM_RESERVE_DATA_SIZE + RAM_DIAGNOSE_BUF_SIZE; +RAM_SIZE = 0x2800 - RAM_CODE_SIZE - RAM_RESERVE_DATA_SIZE - RAM_DIAGNOSE_BUF_SIZE - STACK_SRAM_BOUND_SIZE; +RAM_END = SRAM_END; + +STACK_SRAM_BOUND_START = RAM_START + RAM_SIZE; +STACK_START = STACK_SRAM_BOUND_START + STACK_SRAM_BOUND_SIZE; +STACK_SIZE = 6k - 1k; +NMI_STACK_SIZE = 1k; +INIT_STACK_SIZE = 1k; + +FLASH_START = 0x3000000; +FLASH_SIZE = 0x80000 - 4; + +MEMORY +{ + /* ram for code */ + RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE + + /* ram for reserved data */ + RAM_RESERVE_DATA(rw) : ORIGIN = RAM_RESERVE_DATA_START, LENGTH = RAM_RESERVE_DATA_SIZE + + /* ram for diagnose buf */ + RAM_DIAGNOSE_BUF(rw) : ORIGIN = RAM_DIAGNOSE_BUF_START, LENGTH = RAM_DIAGNOSE_BUF_SIZE + + /* ram for common bss and data */ + RAM_DATA(xrw) : ORIGIN = RAM_START, LENGTH = RAM_SIZE + + /* ram for common bss and data */ + STACK_SRAM_BOUND(xrw) : ORIGIN = STACK_SRAM_BOUND_START, LENGTH = STACK_SRAM_BOUND_SIZE + + /* ram for stack */ + RAM_STACK(xrw) : ORIGIN = STACK_START, LENGTH = STACK_SIZE + NMI_STACK_SIZE + + /*magic number */ + FLASH_MAGIC(rw) : ORIGIN = FLASH_START, LENGTH = 4 + + /* ram for target */ + FLASH_CODE(rx) : ORIGIN = FLASH_START + 4, LENGTH = FLASH_SIZE +} + +SECTIONS +{ + /* The startup code goes first into FLASH */ + .data.magic : ALIGN(4) + { + KEEP(*(.data.magic)) + } > FLASH_MAGIC + + /* The startup code goes first into FLASH_CODE */ + .text.entry : ALIGN(4) + { + KEEP(*(.text.entry)) + } > FLASH_CODE + + /* Stack in SRAM at Highest addresses */ + .stacks (NOLOAD) : + { + . = ALIGN(4); + __SYSTEM_STACK_BEGIN__ = ORIGIN(RAM_STACK); + KEEP(*(.stacks)) + __SYSTEM_STACK_END__ = ORIGIN(RAM_STACK) + STACK_SIZE; + . = ALIGN(0x20); + __INTERRUPT_STACK_BEGIN__ = __SYSTEM_STACK_END__; + . = ALIGN(0x20); + __NMI_STACK_BEGIN__ = __SYSTEM_STACK_END__; + __nmi_stack_bottom = .; + . += NMI_STACK_SIZE; + __nmi_stack_top = .; + } > RAM_STACK + __stack_top = __SYSTEM_STACK_END__; + __init_stack_top = __SYSTEM_STACK_BEGIN__ + INIT_STACK_SIZE; + __irq_stack_top = __SYSTEM_STACK_END__; + + .text.sram : ALIGN(4) + { + __sram_code_load_addr = LOADADDR(.text.sram); + __sram_code_start_addr = .; + *(.text.sram) + . = ALIGN(4); + __sram_code_end_addr = .; + } > RAM_CODE AT > FLASH_CODE + + .reserved.data : ALIGN(4) + { + __reserved_code_load_addr = LOADADDR(.reserved.data); + __reserved_code_start_addr = .; + *(.reserved.data*) + . = ALIGN(4); + __reserved_code_end_addr = .; + } > RAM_RESERVE_DATA AT > FLASH_CODE + + .text : ALIGN(4) + { + __start_addr = .; + *(.text*) + *(.ram.text*) + . = ALIGN(4); + __rodata_start = .; + *(.rodata*) + . = ALIGN(4); + __rodata_end = .; + *(.got*) + __text_end = .; + } > FLASH_CODE + + /* data section */ + .data : ALIGN(4) + { + __data_load = LOADADDR(.data); + __data_start = .; + *(.data*) + *(.sdata*) + . = ALIGN(4); + __data_end = .; + } > RAM_DATA AT> FLASH_CODE + __data_size = __data_end - __data_start; + + .stackBound : ALIGN(4) + { + __stack_sram_bound_data_load = LOADADDR(.stackBound); + __stack_sram_bound_data_start = .; + *(STACK_SRAM_BOUND) + . = ALIGN(4); + __stack_sram_bound_data_end = .; + } > STACK_SRAM_BOUND AT> FLASH_CODE + + .checkSum (NOLOAD) : ALIGN(4) + { + __checksum_addr = .; + *(CHECKSUM) + __checksum_end = .; + } > FLASH_CODE + + /* bss section */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_begin__ = .; + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM_DATA + __bss_size__ = __bss_end__ - __bss_begin__; + __global_pointer$ = __data_start + ((__data_size + __bss_size__) / 2); + + .ramBuf (NOLOAD) : ALIGN(4) + { + *(RAM_DIAGNOSE_BUF) + } > RAM_DIAGNOSE_BUF +} \ No newline at end of file diff --git a/src/chip/3066m/flashdefault.lds b/src/chip/3066m/flashdefault.lds new file mode 100644 index 0000000000000000000000000000000000000000..f5f6590113d6b15efd4e9edf363b0c24c15f4d11 --- /dev/null +++ b/src/chip/3066m/flashdefault.lds @@ -0,0 +1,85 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flash.lds + * @author MCU Application Driver Team + * @brief RISCV flash link script + */ + +OUTPUT_ARCH( "riscv" ) + +SRAM_START = 0x2000000; +SRAM_END = 0x2000000 + 64K; + +RAM_CODE_START = 0x2000000; +RAM_CODE_SIZE = 0; + +RAM_START = SRAM_START; +RAM_END = SRAM_END; +RAM_SIZE = 65536; + +FLASH_START = 0x3000000; +FLASH_SIZE = 0x80000; + +MEMORY +{ + /* ram for code */ + RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE + /* ram for common bss and data */ + RAM_DATA(xrw) : ORIGIN = RAM_START + RAM_CODE_SIZE, LENGTH = RAM_SIZE + /* ram for target */ + FLASH_CODE(rx) : ORIGIN = FLASH_START, LENGTH = FLASH_SIZE +} + +SECTIONS +{ + .text : ALIGN(4) + { + __start_addr = .; + *(.text*) + *(.ram.text*) + . = ALIGN(4); + __rodata_start = .; + *(.rodata*) + . = ALIGN(4); + __rodata_end = .; + *(.got*) + __text_end = .; + } > FLASH_CODE + + /* data section */ + .data : ALIGN(4) + { + __data_load = LOADADDR(.data); + __data_start = .; + *(.data*) + *(.sdata*) + . = ALIGN(4); + __data_end = .; + } > RAM_DATA AT> FLASH_CODE + + /* bss section */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_begin__ = .; + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM_DATA +} \ No newline at end of file diff --git a/src/chip/3066m/fotp/fotp.h b/src/chip/3066m/fotp/fotp.h new file mode 100644 index 0000000000000000000000000000000000000000..98ed53ac5051bd9452ce864767856ebed2d2762f --- /dev/null +++ b/src/chip/3066m/fotp/fotp.h @@ -0,0 +1,826 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file fotp.h + * @author MCU Driver Team + * @brief This file provides firmware functions to manage the following + * functionalities of the system control register. + * + Register Struct of FOTP RNG0 and FOTP RNG1 + */ +#ifndef McuMagicTag_FOTP_H +#define McuMagicTag_FOTP_H + +#define FOTP_INFO_REG_MAX_ID 251 /* Max index of fotp info rng 0 and rng 1 and rng 2 and rng 3 */ + +typedef enum { + FOTP_INFO_RNG0, + FOTP_INFO_RNG1, + FOTP_INFO_RNG2, + FOTP_INFO_RNG3, + FOTP_INFO_MAXTYPE, +} FOTP_InfoRngType; + +typedef struct { + unsigned int data[4]; +} FOTP_CommonData; + +/* + * FOTP INFO RNG0 + */ +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int DIEID_STD_VER : 3; + unsigned int MR_FLAG : 1; + unsigned int LOTID0 : 6; + unsigned int LOTID1 : 6; + unsigned int LOTID2 : 6; + unsigned int LOTID3 : 6; + unsigned int LOTID4 : 4; + } data0; + struct { + unsigned int LOTID4 : 2; + unsigned int LOTID5 : 6; + unsigned int WAFERID : 5; + unsigned int DIEX : 8; + unsigned int DIEY : 8; + unsigned int PASSFLAG_RT_CP : 1; + unsigned int reserved : 2; + } data1; + unsigned int reserved[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_0; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int YEAR : 6; + unsigned int MON : 4; + unsigned int DAY : 5; + unsigned int HOUR : 5; + unsigned int MIN : 6; + unsigned int SEC : 6; + } data0; + struct { + unsigned int LOSC_CTRIM : 9; + unsigned int HOSC_CTRM : 10; + unsigned int reserved : 1; + unsigned int PMU_BG_TRIM : 5; + unsigned int reserved1 : 1; + unsigned int PMU_CLDO_TRIM : 5; + unsigned int reserved2 : 1; + } data1; + unsigned int reserved[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_1; + +typedef union { + FOTP_CommonData comData; + struct { + unsigned int chip_id; + unsigned int reserved; + struct { + unsigned int version_id : 8; + unsigned int reserved : 24; + } data2; + unsigned int customer_id; + } REG; +} FOTP_INFO_RGN0_NUMBER_2; + +typedef union { + FOTP_CommonData comData; + struct { + unsigned int fotp_empty_flag; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_4; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn0_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn4_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN0_NUMBER_5; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int bootrom_debug_enable : 8; + unsigned int reserved : 24; + } data0; + struct { + unsigned int bootrom_hide_disable : 1; + unsigned int reserved : 31; + } data1; + struct { + unsigned int ef_bist_intf_enable : 1; + unsigned int reserved : 31; + } data2; + struct { + unsigned int dft_jtag_enable : 1; + unsigned int reserved : 31; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_6; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int cpu_fpu_enable : 1; + unsigned int reserved : 7; + unsigned int sysram_size_cfg : 3; + unsigned int reserved1 : 5; + unsigned int eflash_size_cfg : 10; + unsigned int reserved2 : 5; + unsigned int cpu_maxfreq_cfg : 1; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_7; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int adc0_enable : 1; + unsigned int adc1_enable : 1; + unsigned int adc2_enable : 1; + unsigned int dac0_enable : 1; + unsigned int dac1_enable : 1; + unsigned int dac2_enable : 1; + unsigned int pga0_enable : 1; + unsigned int pga1_enable : 1; + unsigned int pga2_enable : 1; + unsigned int acmp0_enable : 1; + unsigned int acmp1_enable : 1; + unsigned int acmp2_enable : 1; + unsigned int reserved : 20; + } data0; + unsigned int reserved0; + struct { + unsigned int apt0_hr_enable : 1; + unsigned int apt1_hr_enable : 1; + unsigned int apt2_hr_enable : 1; + unsigned int apt3_hr_enable : 1; + unsigned int apt4_hr_enable : 1; + unsigned int apt5_hr_enable : 1; + unsigned int apt6_hr_enable : 1; + unsigned int apt7_hr_enable : 1; + unsigned int apt8_hr_enable : 1; + unsigned int reserved : 23; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN0_NUMBER_8; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int apt0_enable : 1; + unsigned int apt1_enable : 1; + unsigned int apt2_enable : 1; + unsigned int apt3_enable : 1; + unsigned int apt4_enable : 1; + unsigned int apt5_enable : 1; + unsigned int apt6_enable : 1; + unsigned int apt7_enable : 1; + unsigned int apt8_enable : 1; + unsigned int reserved : 7; + unsigned int can0_enable : 1; + unsigned int can1_enable : 1; + unsigned int reserved1 : 14; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_9; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int IDDQ_DVDD : 8; + unsigned int IDDQ_AVDD : 8; + unsigned int reserved : 16; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_10; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int hpm_core : 16; + unsigned int reserved : 16; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_11; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int PASSFLAG_CP_RT : 1; + unsigned int reserved : 31; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_13; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int PASSFLAG_FT_HT : 1; + unsigned int reserved : 31; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_16; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int DVS_FLOW_FLAG : 1; + unsigned int DVS_PASS_FLAG : 1; + unsigned int reserved : 30; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_17; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int FAILFLAG_ALL : 2; + unsigned int reserved : 30; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_18; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int PASSFLAG_FT_RT : 1; + unsigned int reserved : 31; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_19; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int da_ref_vbg_trim : 8; + unsigned int da_ref_vref_trim : 8; + unsigned int da_iref_trim : 8; + unsigned int da_ref_temp_trim0 : 8; + } data0; + struct { + unsigned int da_ref_temp_trim1 : 8; + unsigned int da_ref_temp_trim2 : 8; + unsigned int da_ref_temp_trim3 : 8; + unsigned int da_ref_vptat_trim : 8; + } data1; + struct { + unsigned int da_ref_buf_trim : 8; + unsigned int reserved : 8; + unsigned int reserved1 : 8; + unsigned int reserved2 : 8; + } data2; + struct { + unsigned int reserved : 8; + unsigned int da_ana_top_trim0 : 8; + unsigned int da_ana_top_trim1 : 8; + unsigned int reserved1 : 8; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_20; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int da_pga0_vos_trim : 9; + unsigned int reserved : 7; + unsigned int da_pga1_vos_trim : 9; + unsigned int reserved1 : 7; + } data0; + struct { + unsigned int da_pga2_vos_trim : 9; + unsigned int reserved : 7; + unsigned int ts_offset : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc0_gain : 13; + unsigned int reserved : 3; + unsigned int saradc0_offset : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc1_gain : 13; + unsigned int reserved : 3; + unsigned int saradc1_offset : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_21; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc2_gain : 13; + unsigned int reserved : 3; + unsigned int saradc2_offset : 12; + unsigned int reserved1 : 4; + } data0; + unsigned int reserved0; + struct { + unsigned int saradc0_ain0_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain0_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc0_ain0_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain0_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_22; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc0_ain0_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain0_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc0_ain0_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain0_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc0_ain1_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain1_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc0_ain1_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain1_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_23; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc0_ain1_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain1_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc0_ain1_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc0_ain1_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc1_ain0_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain0_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc1_ain0_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain0_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_24; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc1_ain0_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain0_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc1_ain0_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain0_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc1_ain1_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain1_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc1_ain1_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain1_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_25; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc1_ain1_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain1_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc1_ain1_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc1_ain1_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc2_ain0_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain0_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc2_ain0_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain0_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_26; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc2_ain0_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain0_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc2_ain0_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain0_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + struct { + unsigned int saradc2_ain1_gain2 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain1_offset2 : 12; + unsigned int reserved1 : 4; + } data2; + struct { + unsigned int saradc2_ain1_gain4 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain1_offset4 : 12; + unsigned int reserved1 : 4; + } data3; + } REG; +} FOTP_INFO_RGN0_NUMBER_27; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int saradc2_ain1_gain8 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain1_offset8 : 12; + unsigned int reserved1 : 4; + } data0; + struct { + unsigned int saradc2_ain1_gain16 : 13; + unsigned int reserved : 3; + unsigned int saradc2_ain1_offset16 : 12; + unsigned int reserved1 : 4; + } data1; + unsigned int reserved[2]; + } REG; +} FOTP_INFO_RGN0_NUMBER_28; + +/* + * FOTP INFO RNG1 + */ +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int main_rgn0_0_protection_level : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + unsigned int reserved1[2]; + } REG; +} FOTP_INFO_RGN1_NUMBER_0; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int uart0_enable : 1; + unsigned int uart1_enable : 1; + unsigned int uart2_enable : 1; + unsigned int uart3_enable : 1; + unsigned int uart4_enable : 1; + unsigned int reserved : 3; + unsigned int IWDG_DEEPSLEEP : 1; + unsigned int reserved1 : 1; + unsigned int IWDG_SW : 1; + unsigned int reserved2 : 13; + unsigned int verify_disable : 1; + unsigned int reserved3 : 7; + } data0; + struct { + unsigned int func_jtag_enable : 8; + unsigned int sysram_parity_disable : 1; + unsigned int reserved : 23; + } data1; + struct { + unsigned int uart_boot_enable : 1; + unsigned int spi_boot_enable : 1; + unsigned int i2c_boot_enable : 1; + unsigned int can_boot_enable : 1; + unsigned int smbus_boot_enable : 1; + unsigned int reserved : 27; + } data2; + struct { + unsigned int main_rgn0_0_size : 10; + unsigned int reserved : 22; + } data3; + } REG; +} FOTP_INFO_RGN1_NUMBER_8; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn1_0_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn1_1_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN1_NUMBER_56; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn1_2_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn1_3_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN1_NUMBER_57; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn1_4_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn1_5_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN1_NUMBER_58; + +/* + * FOTP INFO RNG2 + */ +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int main_rgn0_1_start_addr : 10; + unsigned int reserved : 6; + unsigned int main_rgn0_1_end_addr : 10; + unsigned int reserved1 : 6; + } data0; + struct { + unsigned int main_rgn0_1_code_end : 10; + unsigned int reserved : 14; + unsigned int main_rgn0_1_protection_level : 8; + } data1; + struct { + unsigned int sram_rgn0_1_start_addr : 10; + unsigned int reserved : 6; + unsigned int sram_rgn0_1_end_addr : 10; + unsigned int reserved1 : 6; + } data2; + struct { + unsigned int sram_rgn0_1_cpsrc_addr : 10; + unsigned int reserved : 14; + unsigned int sram_rgn0_1_disable : 8; + } data3; + } REG; +} FOTP_INFO_RGN2_NUMBER_0; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn2_0_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn2_1_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN2_NUMBER_56; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn2_2_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn2_3_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN2_NUMBER_57; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn2_4_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn2_5_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN2_NUMBER_58; + +/* + * FOTP INFO RNG3 + */ +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int main_rgn0_2_start_addr : 10; + unsigned int reserved : 6; + unsigned int main_rgn0_2_end_addr : 10; + unsigned int reserved1 : 6; + } data0; + struct { + unsigned int main_rgn0_2_code_end : 10; + unsigned int reserved : 14; + unsigned int main_rgn0_2_protection_level : 8; + } data1; + struct { + unsigned int sram_rgn0_2_start_addr : 10; + unsigned int reserved : 6; + unsigned int sram_rgn0_2_end_addr : 10; + unsigned int reserved1 : 6; + } data2; + struct { + unsigned int sram : 10; + unsigned int reserved : 14; + unsigned int sram_rgn0_2_disable : 8; + } data3; + } REG; +} FOTP_INFO_RGN3_NUMBER_0; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn3_0_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn3_1_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN3_NUMBER_56; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn3_2_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn3_3_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN3_NUMBER_57; + +typedef union { + FOTP_CommonData comData; + struct { + struct { + unsigned int info_rgn3_4_unlock : 8; + unsigned int reserved : 24; + } data0; + unsigned int reserved0; + struct { + unsigned int info_rgn3_5_unlock : 8; + unsigned int reserved : 24; + } data2; + unsigned int reserved1; + } REG; +} FOTP_INFO_RGN3_NUMBER_58; + +#endif \ No newline at end of file diff --git a/src/chip/3066m/fotp/fotp_info_read.c b/src/chip/3066m/fotp/fotp_info_read.c new file mode 100644 index 0000000000000000000000000000000000000000..8e4976727fc1d2606795f83e484bb13576a4485e --- /dev/null +++ b/src/chip/3066m/fotp/fotp_info_read.c @@ -0,0 +1,141 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file fotp_info_read.c + * @author MCU Driver Team + * @brief This file provides firmware functions to manage the following + * functionalities of the fotp control register. + * + FOTP INFO Read API + */ +#include "chipinc.h" +#include "flash.h" +#include "fotp_info_read.h" +#define FOTP_INFO_RNG0_BASEADDR 0x800000 +#define FOTP_INFO_RNG1_BASEADDR 0x800400 +#define FOTP_INFO_RNG2_BASEADDR 0x800800 +#define FOTP_INFO_RNG3_BASEADDR 0x800C00 +#define REG_WORDS_NUM 16 +#define FLASH_READ_128BIT 1 + +/** + * @brief Read Four words of FOTP. + * @param efc Flash control register base address + * @retval BASE_STATUS_ERROR fail. + * @retval BASE_STATUS_OK success. + */ +static unsigned int FOTP_CheckReadStatus(EFC_RegStruct *efc) +{ + /* Check for errors in the flash reading process. */ + if (efc->INT_RAW_STATUS.BIT.int_raw_err_illegal || + efc->INT_RAW_STATUS.BIT.int_raw_err_ecc_corr || + efc->INT_RAW_STATUS.BIT.int_raw_err_ecc_chk) { + efc->INT_CLEAR.BIT.int_clr_err_ecc_corr = BASE_CFG_SET; + efc->INT_CLEAR.BIT.int_clr_err_illegal = BASE_CFG_SET; + efc->INT_CLEAR.BIT.int_clr_err_ecc_chk = BASE_CFG_SET; + efc->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; + return BASE_STATUS_ERROR; + } + return BASE_STATUS_OK; +} + +/** + * @brief Get the base address of the info Partition. + * @param type FOTP Range Type + * @retval the base address of info. + */ +static unsigned int GetInfoRegionAddr(FOTP_InfoRngType type) +{ + unsigned int addr; + switch (type) { + case FOTP_INFO_RNG0: + addr = FOTP_INFO_RNG0_BASEADDR; /* info0 base address. */ + break; + + case FOTP_INFO_RNG1: + addr = FOTP_INFO_RNG1_BASEADDR; /* info1 base address. */ + break; + + case FOTP_INFO_RNG2: + addr = FOTP_INFO_RNG2_BASEADDR; /* info2 base address. */ + break; + + case FOTP_INFO_RNG3: + addr = FOTP_INFO_RNG3_BASEADDR; /* info3 base address. */ + break; + + default: + addr = FOTP_INFO_RNG0_BASEADDR; + break; + } + return addr; +} + +/** + * @brief Read Four words of FOTP. + * @param type FOTP Range Type + * @param index FOTP register index + * @param buf Buffer of read data + * @retval BASE_STATUS_ERROR fail. + * @retval BASE_STATUS_OK success. + */ +unsigned int FOTP_InfoGet(FOTP_InfoRngType type, unsigned int index, FOTP_CommonData *buf) +{ + EFC_RegStruct *p = EFC; + unsigned int addr; + + if (buf == NULL) { + return BASE_STATUS_ERROR; + } + + if ((type >= FOTP_INFO_MAXTYPE) || (index > FOTP_INFO_REG_MAX_ID)) { + return BASE_STATUS_ERROR; + } + + /* If there is a read command, return */ + if (p->EFLASH_CMD.BIT.cmd_start) { + return BASE_STATUS_ERROR; + } + + p->MAGIC_LOCK = FLASH_KEY_REGISTER_UNLOCK_VALUE; + + /* Configure the read command parameters and start the read command */ + addr = GetInfoRegionAddr(type); + + addr += index * REG_WORDS_NUM; + p->EFLASH_ADDR.BIT.cmd_addr = addr >> 2; /* Right shift 2 bit change to word */ + p->EFLASH_CMD.BIT.cmd_code = FLASH_OPERATION_READ; + p->EFLASH_CMD.BIT.cmd_read_size = FLASH_READ_128BIT; + p->EFLASH_CMD.BIT.cmd_start = BASE_CFG_SET; + + while (p->EFLASH_CMD.BIT.cmd_start) { + ; + } + while (p->EFLASH_CMD.BIT.exec_state) { + ; + } + /* read error, clear interrupt and return */ + if (FOTP_CheckReadStatus(p) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + /* Read data from FIFO to buffer */ + for (unsigned int i = 0; i < sizeof(buf->data) / sizeof(buf->data[0]); ++i) { + buf->data[i] = p->FLASH_RDATA; + } + p->INT_CLEAR.BIT.int_clr_finish = BASE_CFG_SET; + p->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/chip/3066m/fotp/fotp_info_read.h b/src/chip/3066m/fotp/fotp_info_read.h new file mode 100644 index 0000000000000000000000000000000000000000..a7d36aafd85e08753b2b452d7a01a4384c74cdd4 --- /dev/null +++ b/src/chip/3066m/fotp/fotp_info_read.h @@ -0,0 +1,31 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file fotp_info_read.h + * @author MCU Driver Team + * @brief This file provides firmware functions to manage the following + * functionalities of the system control register. + * + FOTP Register Read API + */ +#ifndef McuMagicTag_FOTP_INFO_READ_H +#define McuMagicTag_FOTP_INFO_READ_H + +#include "fotp.h" + +unsigned int FOTP_InfoGet(FOTP_InfoRngType type, unsigned int index, FOTP_CommonData *buf); + +#endif diff --git a/src/chip/3066m/info.h b/src/chip/3066m/info.h new file mode 100644 index 0000000000000000000000000000000000000000..fde26d300289ff050fbb53b0e9a1422d9367f5a6 --- /dev/null +++ b/src/chip/3066m/info.h @@ -0,0 +1,30 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file info.h + * @author MCU Driver Team + * @brief Defines chip attributes. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_INFO_H +#define McuMagicTag_INFO_H + +#define CHIP_DELAY_CYCLES_PER_LOOP (4) /**< CPU cycles. Known number of this CPU cycles required to execute the \ + BASE_FUNC_delay() loop. */ + +#endif /* McuMagicTag_INFO_H */ \ No newline at end of file diff --git a/src/chip/3066m/interrupt_ip.h b/src/chip/3066m/interrupt_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..9d90b9f5fbcbbf0f01e544dc960a96b2b990ae13 --- /dev/null +++ b/src/chip/3066m/interrupt_ip.h @@ -0,0 +1,205 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file interrupt_ip.h + * @author MCU Driver Team + * @brief interrupt module driver. + * This file define the interrupt number + */ + +#ifndef MCUMagicTag_INTERRUPT_IP_H +#define MCUMagicTag_INTERRUPT_IP_H + +/* Typedef definitions -------------------------------------------------------*/ +#define MSTATUS_MIE 0x00000008U /**< mie in mstatus */ +#define MSTATUS_MPIE 0x00000080U /**< mpie in mstatus */ +#define UINT32_CUT_MASK 0xFFFFFFFFU + +#define IRQ_PRIO_HIGHEST 15 /**< Highest priority of a hardware interrupt. */ +#define IRQ_PRIO_LOWEST 1 /**< Lowest priority of a hardware interrupt. */ + +/** + * @brief Count of system interrupt vector. + * The number of standard interrupts inside the CPU. The interrupt number + * is 0~25. The software interrupt nesting scheme cannot use standard + * interrupts, which means that external system integration will ensure + * that no standard interrupts will be triggered. + */ +#define IRQ_VECTOR_CNT 26 + +/** + * @brief Count of local interrupt vector 0 - 5, enabled by CSR mie 26 -31 bit. + */ +#define IRQ_MIE_VECTOR_CNT 6 + +/** + * @brief Count of IRQ controlled by CSR mie + */ +#define IRQ_MIE_TOTAL_CNT (IRQ_VECTOR_CNT + IRQ_MIE_VECTOR_CNT) +#define IRQ_LOCIEN1_OFFSET 64 +#define IRQ_LOCIEN2_OFFSET 96 +#define IRQ_LOCIEN3_OFFSET 128 + +/** + * @brief rv_custom_csr + * locipri0~15 are registers that control the priority of interrupts, + * and every 4 bits control the priority of an interrupt + */ +#define LOCIPRI0 0xBC0 +#define LOCIPRI1 0xBC1 +#define LOCIPRI2 0xBC2 +#define LOCIPRI3 0xBC3 +#define LOCIPRI4 0xBC4 +#define LOCIPRI5 0xBC5 +#define LOCIPRI6 0xBC6 +#define LOCIPRI7 0xBC7 +#define LOCIPRI8 0xBC8 +#define LOCIPRI9 0xBC9 +#define LOCIPRI10 0xBCA +#define LOCIPRI11 0xBCB +#define LOCIPRI12 0xBCC +#define LOCIPRI13 0xBCD +#define LOCIPRI14 0xBCE +#define LOCIPRI15 0xBCF + +#define LOCIPRI(x) LOCIPRI##x + +/** + * @brief locien0~3 are registers that control interrupt enable + */ +#define LOCIEN0 0xBE0 +#define LOCIEN1 0xBE1 +#define LOCIEN2 0xBE2 +#define LOCIEN3 0xBE3 + +/** + * @brief locipd0~3 are registers that control the interrupt flag bit. Each bit + * controls an interrupt. If the corresponding bit bit is 1, it means the + * corresponding interrupt is triggered. + */ +#define LOCIPD0 0xBE8 +#define LOCIPD1 0xBE9 +#define LOCIPD2 0xBEA +#define LOCIPD3 0xBEB + +/** + * @brief Locipclr is the register that clears the interrupt flag bit, and the + * corresponding interrupt number is assigned to the locipclr register, + * and the hardware will clear the corresponding interrupt flag bit, that + * is, the corresponding locipd bit is set + */ +#define LOCIPCLR 0xBF0 + +/** + * @brief The maximum number of interrupts supported, excluding 26 internal standard + * interrupts, up to 230 external non-standard interrupts can be supported + */ +#define IRQ_NUM 256 + +/* ---------- Interrupt Number Definition ----------------------------------- */ +typedef enum { + IRQ_SOFTWARE = 26, /* The first 0~25 interrupts are the internal standard interrupts of the CPU, + and the customizable external non-standard interrupts start from 26 */ + IRQ_UART0 = 28, + IRQ_UART1 = 29, + IRQ_UART2 = 30, + IRQ_MTIMER = 31, + IRQ_TIMER0 = 32, + IRQ_TIMER1 = 33, + IRQ_TIMER2 = 34, + IRQ_TIMER3 = 35, + IRQ_GPT0_INT = 36, + IRQ_GPT0_PRD_INT = 37, + IRQ_GPT1_INT = 38, + IRQ_GPT1_PRD_INT = 39, + IRQ_WWDG = 40, + IRQ_IWDG = 41, + IRQ_I2C0 = 42, + IRQ_SPI0 = 44, + IRQ_SPI1 = 45, + IRQ_CAN = 46, + IRQ_CAN1 = 47, + IRQ_APT0_EVT = 48, + IRQ_APT0_TMR = 49, + IRQ_APT1_EVT = 50, + IRQ_APT1_TMR = 51, + IRQ_APT2_EVT = 52, + IRQ_APT2_TMR = 53, + IRQ_APT3_EVT = 54, + IRQ_APT3_TMR = 55, + IRQ_APT4_EVT = 56, + IRQ_APT4_TMR = 57, + IRQ_APT5_EVT = 58, + IRQ_APT5_TMR = 59, + IRQ_APT6_EVT = 60, + IRQ_APT6_TMR = 61, + IRQ_APT7_EVT = 62, + IRQ_APT7_TMR = 63, + IRQ_APT8_EVT = 64, + IRQ_APT8_TMR = 65, + IRQ_UART3 = 66, + IRQ_UART4 = 67, + IRQ_CMM = 68, + IRQ_CFD = 69, + IRQ_CAPM0 = 70, + IRQ_CAPM1 = 71, + IRQ_CAPM2 = 72, + IRQ_QDM0 = 73, + IRQ_QDM1 = 74, + IRQ_QDM2 = 75, + IRQ_QDM3 = 76, + IRQ_DMA_TC = 77, + IRQ_DMA_ERR = 78, + IRQ_SYSRAM_PARITY_ERR = 79, + IRQ_EFC = 81, + IRQ_EFC_ERR = 82, + IRQ_PVD = 85, + IRQ_ACMP0_INT = 86, + IRQ_ACMP1_INT = 87, + IRQ_ACMP2_INT = 88, + IRQ_ADC0_EVENT = 91, + IRQ_ADC0_ERR = 92, + IRQ_ADC0_INT0 = 93, + IRQ_ADC0_INT1 = 94, + IRQ_ADC0_INT2 = 95, + IRQ_ADC0_INT3 = 96, + IRQ_ADC1_EVENT = 97, + IRQ_ADC1_ERR = 98, + IRQ_ADC1_INT0 = 99, + IRQ_ADC1_INT1 = 100, + IRQ_ADC1_INT2 = 101, + IRQ_ADC1_INT3 = 102, + IRQ_ADC2_EVENT = 103, + IRQ_ADC2_ERR = 104, + IRQ_ADC2_INT0 = 105, + IRQ_ADC2_INT1 = 106, + IRQ_ADC2_INT2 = 107, + IRQ_ADC2_INT3 = 108, + IRQ_GPIO0 = 109, + IRQ_GPIO1 = 110, + IRQ_GPIO2 = 111, + IRQ_GPIO3 = 112, + IRQ_GPIO4 = 113, + IRQ_GPIO5 = 114, + IRQ_GPIO6 = 115, + IRQ_GPIO7 = 116, + IRQ_GPIO8 = 117, + IRQ_GPIO9 = 118, + IRQ_MAX, /**< The maximum number of interrupts currently supported */ +} IRQ_ID; + +#endif /* MCUMagicTag_INTERRUPT_IP_H */ \ No newline at end of file diff --git a/src/chip/3066m/ioconfig.h b/src/chip/3066m/ioconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..9f3a604b243165f9dacf3786034f9a199b5f66b6 --- /dev/null +++ b/src/chip/3066m/ioconfig.h @@ -0,0 +1,119 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file ioconfig.h + * @author MCU Driver Team + * @brief ioconfig module driver + * @details This file provides IOConfig register mapping structure. + */ + +/* Macro definitions */ +#ifndef McuMagicTag_IOCONFIG_H +#define McuMagicTag_IOCONFIG_H + +typedef union { + unsigned int reg; + struct { + unsigned int func : 4; /**< IO function selection. */ + unsigned int ds : 2; /**< Pin drive capability selection. */ + unsigned int reserved0 : 1; + unsigned int pd : 1; /**< Pin pull down control. */ + unsigned int pu : 1; /**< Pin pull up control. */ + unsigned int sr : 1; /**< Electrical level shift speed control. */ + unsigned int se : 1; /**< Schmidt input control. */ + unsigned int reserved1 : 1; /**< Reserved: Open drain control reserved. */ + unsigned int reserved2 : 20; + } BIT; +} volatile IOCMG_REG; + +typedef struct { + IOCMG_REG IOCFG_GPIO0_0; /**< Pin GPIO0_0 IO Config Register, offset address:0x000000U */ + IOCMG_REG IOCFG_GPIO0_1; /**< Pin GPIO0_1 IO Config Register, offset address:0x000004U */ + IOCMG_REG IOCFG_GPIO0_2; /**< Pin GPIO0_2 IO Config Register, offset address:0x000008U */ + IOCMG_REG IOCFG_GPIO0_3; /**< Pin GPIO0_3 IO Config Register, offset address:0x00000CU */ + IOCMG_REG IOCFG_GPIO0_4; /**< Pin GPIO0_4 IO Config Register, offset address:0x000010U */ + IOCMG_REG IOCFG_GPIO0_5; /**< Pin GPIO0_5 IO Config Register, offset address:0x000014U */ + IOCMG_REG IOCFG_GPIO0_6; /**< Pin GPIO0_6 IO Config Register, offset address:0x000018U */ + IOCMG_REG IOCFG_GPIO0_7; /**< Pin GPIO0_7 IO Config Register, offset address:0x00001CU */ + IOCMG_REG IOCFG_GPIO1_0; /**< Pin GPIO1_0 IO Config Register, offset address:0x000020U */ + IOCMG_REG IOCFG_GPIO1_1; /**< Pin GPIO1_1 IO Config Register, offset address:0x000024U */ + IOCMG_REG IOCFG_GPIO1_2; /**< Pin GPIO1_2 IO Config Register, offset address:0x000028U */ + IOCMG_REG IOCFG_GPIO1_3; /**< Pin GPIO1_3 IO Config Register, offset address:0x00002CU */ + IOCMG_REG IOCFG_GPIO1_4; /**< Pin GPIO1_4 IO Config Register, offset address:0x000030U */ + IOCMG_REG IOCFG_GPIO1_5; /**< Pin GPIO1_5 IO Config Register, offset address:0x000034U */ + IOCMG_REG IOCFG_GPIO1_6; /**< Pin GPIO1_6 IO Config Register, offset address:0x000038U */ + IOCMG_REG IOCFG_GPIO1_7; /**< Pin GPIO1_7 IO Config Register, offset address:0x00003CU */ + IOCMG_REG IOCFG_GPIO2_0; /**< Pin GPIO2_0 IO Config Register, offset address:0x000040U */ + IOCMG_REG IOCFG_GPIO2_1; /**< Pin GPIO2_1 IO Config Register, offset address:0x000044U */ + IOCMG_REG IOCFG_GPIO2_2; /**< Pin GPIO2_2 IO Config Register, offset address:0x000048U */ + IOCMG_REG IOCFG_GPIO2_3; /**< Pin GPIO2_3 IO Config Register, offset address:0x00004CU */ + IOCMG_REG IOCFG_GPIO2_4; /**< Pin GPIO2_4 IO Config Register, offset address:0x000050U */ + IOCMG_REG IOCFG_GPIO2_5; /**< Pin GPIO2_5 IO Config Register, offset address:0x000054U */ + IOCMG_REG IOCFG_GPIO2_6; /**< Pin GPIO2_6 IO Config Register, offset address:0x000058U */ + IOCMG_REG IOCFG_GPIO2_7; /**< Pin GPIO2_7 IO Config Register, offset address:0x00005CU */ + IOCMG_REG IOCFG_GPIO3_0; /**< Pin GPIO3_0 IO Config Register, offset address:0x000060U */ + IOCMG_REG IOCFG_GPIO3_1; /**< Pin GPIO3_1 IO Config Register, offset address:0x000064U */ + IOCMG_REG IOCFG_GPIO3_2; /**< Pin GPIO3_2 IO Config Register, offset address:0x000068U */ + IOCMG_REG IOCFG_GPIO3_3; /**< Pin GPIO3_3 IO Config Register, offset address:0x00006CU */ + IOCMG_REG IOCFG_GPIO3_4; /**< Pin GPIO3_4 IO Config Register, offset address:0x000070U */ + IOCMG_REG IOCFG_GPIO3_5; /**< Pin GPIO3_5 IO Config Register, offset address:0x000074U */ + IOCMG_REG IOCFG_GPIO3_6; /**< Pin GPIO3_6 IO Config Register, offset address:0x000078U */ + IOCMG_REG IOCFG_GPIO3_7; /**< Pin GPIO3_7 IO Config Register, offset address:0x00007CU */ + IOCMG_REG IOCFG_GPIO4_0; /**< Pin GPIO4_0 IO Config Register, offset address:0x000080U */ + IOCMG_REG IOCFG_GPIO4_1; /**< Pin GPIO4_1 IO Config Register, offset address:0x000084U */ + IOCMG_REG IOCFG_GPIO4_2; /**< Pin GPIO4_2 IO Config Register, offset address:0x000088U */ + IOCMG_REG IOCFG_GPIO4_3; /**< Pin GPIO4_3 IO Config Register, offset address:0x00008CU */ + IOCMG_REG IOCFG_GPIO4_4; /**< Pin GPIO4_4 IO Config Register, offset address:0x000090U */ + IOCMG_REG IOCFG_GPIO4_5; /**< Pin GPIO4_5 IO Config Register, offset address:0x000094U */ + IOCMG_REG IOCFG_GPIO4_6; /**< Pin GPIO4_6 IO Config Register, offset address:0x000098U */ + IOCMG_REG IOCFG_GPIO4_7; /**< Pin GPIO4_7 IO Config Register, offset address:0x00009CU */ + IOCMG_REG IOCFG_GPIO5_0; /**< Pin GPIO5_0 IO Config Register, offset address:0x0000A0U */ + IOCMG_REG IOCFG_GPIO5_1; /**< Pin GPIO5_1 IO Config Register, offset address:0x0000A4U */ + IOCMG_REG IOCFG_GPIO5_2; /**< Pin GPIO5_2 IO Config Register, offset address:0x0000A8U */ + IOCMG_REG IOCFG_GPIO5_3; /**< Pin GPIO5_3 IO Config Register, offset address:0x0000ACU */ + IOCMG_REG IOCFG_GPIO5_4; /**< Pin GPIO5_4 IO Config Register, offset address:0x0000B0U */ + IOCMG_REG IOCFG_GPIO5_5; /**< Pin GPIO5_5 IO Config Register, offset address:0x0000B4U */ + IOCMG_REG IOCFG_GPIO5_6; /**< Pin GPIO5_6 IO Config Register, offset address:0x0000B8U */ + IOCMG_REG IOCFG_GPIO5_7; /**< Pin GPIO5_7 IO Config Register, offset address:0x0000BCU */ + IOCMG_REG IOCFG_GPIO6_0; /**< Pin GPIO6_0 IO Config Register, offset address:0x0000C0U */ + IOCMG_REG IOCFG_GPIO6_1; /**< Pin GPIO6_1 IO Config Register, offset address:0x0000C4U */ + IOCMG_REG IOCFG_GPIO6_2; /**< Pin GPIO6_2 IO Config Register, offset address:0x0000C8U */ + IOCMG_REG IOCFG_GPIO6_3; /**< Pin GPIO6_3 IO Config Register, offset address:0x0000CCU */ + IOCMG_REG IOCFG_GPIO6_4; /**< Pin GPIO6_4 IO Config Register, offset address:0x0000D0U */ + IOCMG_REG IOCFG_GPIO6_5; /**< Pin GPIO6_5 IO Config Register, offset address:0x0000D4U */ + IOCMG_REG IOCFG_GPIO6_6; /**< Pin GPIO6_6 IO Config Register, offset address:0x0000D8U */ + IOCMG_REG IOCFG_GPIO6_7; /**< Pin GPIO6_7 IO Config Register, offset address:0x0000DCU */ + IOCMG_REG IOCFG_GPIO7_0; /**< Pin GPIO7_0 IO Config Register, offset address:0x0000E0U */ + IOCMG_REG IOCFG_GPIO7_1; /**< Pin GPIO7_1 IO Config Register, offset address:0x0000E4U */ + IOCMG_REG IOCFG_GPIO7_2; /**< Pin GPIO7_2 IO Config Register, offset address:0x0000E8U */ + IOCMG_REG IOCFG_GPIO7_3; /**< Pin GPIO7_3 IO Config Register, offset address:0x0000ECU */ + IOCMG_REG IOCFG_GPIO7_4; /**< Pin GPIO7_4 IO Config Register, offset address:0x0000F0U */ + IOCMG_REG IOCFG_GPIO7_5; /**< Pin GPIO7_5 IO Config Register, offset address:0x0000F4U */ + IOCMG_REG IOCFG_GPIO7_6; /**< Pin GPIO7_6 IO Config Register, offset address:0x0000F8U */ + IOCMG_REG IOCFG_GPIO7_7; /**< Pin GPIO7_7 IO Config Register, offset address:0x0000FCU */ + IOCMG_REG IOCFG_GPIO8_0; /**< Pin GPIO8_0 IO Config Register, offset address:0x000100U */ + IOCMG_REG IOCFG_GPIO8_1; /**< Pin GPIO8_1 IO Config Register, offset address:0x000104U */ + IOCMG_REG IOCFG_GPIO8_2; /**< Pin GPIO8_2 IO Config Register, offset address:0x000108U */ + IOCMG_REG IOCFG_GPIO8_3; /**< Pin GPIO8_3 IO Config Register, offset address:0x00010CU */ + IOCMG_REG IOCFG_GPIO8_4; /**< Pin GPIO8_4 IO Config Register, offset address:0x000110U */ + IOCMG_REG IOCFG_GPIO8_5; /**< Pin GPIO8_5 IO Config Register, offset address:0x000114U */ + IOCMG_REG IOCFG_GPIO8_6; /**< Pin GPIO8_6 IO Config Register, offset address:0x000118U */ + IOCMG_REG IOCFG_GPIO8_7; /**< Pin GPIO8_7 IO Config Register, offset address:0x00011CU */ + IOCMG_REG IOCFG_GPIO9_0; /**< Pin GPIO9_0 IO Config Register, offset address:0x000120U */ +} volatile IOConfig_RegStruct; + +#endif /* McuMagicTag_IOCONFIG_H */ \ No newline at end of file diff --git a/src/chip/3066m/iomap/iomap.h b/src/chip/3066m/iomap/iomap.h new file mode 100644 index 0000000000000000000000000000000000000000..b9a92e9b3124f3cbd7e1d8f6c3e32eec41099678 --- /dev/null +++ b/src/chip/3066m/iomap/iomap.h @@ -0,0 +1,581 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file iomap.h + * @author MCU Driver Team + * @brief Defines chip pin map and function mode. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_IOMAP_H +#define McuMagicTag_IOMAP_H + +/* get offset value of member in type struct */ +#define OFFSET_OF(type, member) (unsigned int)(&(((type *)0)->member)) + +#define IOCMG_PIN_MUX(regx, funcNum, regValueDefault) \ + (unsigned int)(((OFFSET_OF(IOConfig_RegStruct, regx) & 0x00000FFF) << 16) | \ + (((regValueDefault) & 0xFFFFFFF0) | (funcNum))) +/* pin function mode info ---------------------------------------------------- */ +#define GPIO0_0_AS_GPIO0_0 IOCMG_PIN_MUX(IOCFG_GPIO0_0, FUNC_MODE_0, 0x0a81) +#define GPIO0_0_AS_JTAG_TCK IOCMG_PIN_MUX(IOCFG_GPIO0_0, FUNC_MODE_1, 0x0a81) +#define GPIO0_0_AS_WAKEUP0 IOCMG_PIN_MUX(IOCFG_GPIO0_0, FUNC_MODE_3, 0x0a81) +#define GPIO0_0_AS_UART0_CTSN IOCMG_PIN_MUX(IOCFG_GPIO0_0, FUNC_MODE_4, 0x0a81) +#define GPIO0_0_AS_UART4_CTSN IOCMG_PIN_MUX(IOCFG_GPIO0_0, FUNC_MODE_5, 0x0a81) + +#define GPIO0_1_AS_GPIO0_1 IOCMG_PIN_MUX(IOCFG_GPIO0_1, FUNC_MODE_0, 0x0b21) +#define GPIO0_1_AS_JTAG_TMS IOCMG_PIN_MUX(IOCFG_GPIO0_1, FUNC_MODE_1, 0x0b21) +#define GPIO0_1_AS_WAKEUP1 IOCMG_PIN_MUX(IOCFG_GPIO0_1, FUNC_MODE_3, 0x0b21) +#define GPIO0_1_AS_UART0_RTSN IOCMG_PIN_MUX(IOCFG_GPIO0_1, FUNC_MODE_4, 0x0b21) +#define GPIO0_1_AS_UART4_RTSN IOCMG_PIN_MUX(IOCFG_GPIO0_1, FUNC_MODE_5, 0x0b21) + +#define GPIO0_2_AS_GPIO0_2 IOCMG_PIN_MUX(IOCFG_GPIO0_2, FUNC_MODE_0, 0x0a00) +#define GPIO0_2_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO0_2, FUNC_MODE_1, 0x0a00) +#define GPIO0_2_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO0_2, FUNC_MODE_2, 0x0a00) +#define GPIO0_2_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO0_2, FUNC_MODE_3, 0x0a00) +#define GPIO0_2_AS_UART4_RXD IOCMG_PIN_MUX(IOCFG_GPIO0_2, FUNC_MODE_4, 0x0a00) + +#define GPIO0_3_AS_GPIO0_3 IOCMG_PIN_MUX(IOCFG_GPIO0_3, FUNC_MODE_0, 0x0a00) +#define GPIO0_3_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO0_3, FUNC_MODE_2, 0x0a00) +#define GPIO0_3_AS_UART0_TXD IOCMG_PIN_MUX(IOCFG_GPIO0_3, FUNC_MODE_4, 0x0a00) +#define GPIO0_3_AS_XTAL_OUT IOCMG_PIN_MUX(IOCFG_GPIO0_3, FUNC_MODE_12, 0x0a00) + +#define GPIO0_4_AS_GPIO0_4 IOCMG_PIN_MUX(IOCFG_GPIO0_4, FUNC_MODE_0, 0x0a00) +#define GPIO0_4_AS_UART0_RXD IOCMG_PIN_MUX(IOCFG_GPIO0_4, FUNC_MODE_4, 0x0a00) +#define GPIO0_4_AS_XTAL_IN IOCMG_PIN_MUX(IOCFG_GPIO0_4, FUNC_MODE_12, 0x0a00) + +#define GPIO0_5_AS_GPIO0_5 IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_0, 0x0a00) +#define GPIO0_5_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_1, 0x0a00) +#define GPIO0_5_AS_APT_EVTMP5 IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_2, 0x0a00) +#define GPIO0_5_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_3, 0x0a00) +#define GPIO0_5_AS_QDM3_INDEX IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_4, 0x0a00) +#define GPIO0_5_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_6, 0x0a00) +#define GPIO0_5_AS_ADC_EXT_TRIG3 IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_7, 0x0a00) +#define GPIO0_5_AS_PMC2HOSC_PD IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_9, 0x0a00) +#define GPIO0_5_AS_PMC2CORE_POR_N IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_10, 0x0a00) +#define GPIO0_5_AS_EF_PSW_EN IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_11, 0x0a00) +#define GPIO0_5_AS_HOSC_TEST IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_12, 0x0a00) +#define GPIO0_5_AS_PLL_TEST IOCMG_PIN_MUX(IOCFG_GPIO0_5, FUNC_MODE_13, 0x0a00) + +#define GPIO0_6_AS_GPIO0_6 IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_0, 0x0a00) +#define GPIO0_6_AS_CAN_RX IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_1, 0x0a00) +#define GPIO0_6_AS_APT_EVTIO5 IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_2, 0x0a00) +#define GPIO0_6_AS_QDM3_A IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_3, 0x0a00) +#define GPIO0_6_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_4, 0x0a00) +#define GPIO0_6_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_5, 0x0a00) +#define GPIO0_6_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_6, 0x0a00) +#define GPIO0_6_AS_UART4_RXD IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_7, 0x0a00) +#define GPIO0_6_AS_UART2_CTSN IOCMG_PIN_MUX(IOCFG_GPIO0_6, FUNC_MODE_8, 0x0a00) + +#define GPIO0_7_AS_GPIO0_7 IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_0, 0x0a00) +#define GPIO0_7_AS_CAN_TX IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_1, 0x0a00) +#define GPIO0_7_AS_QDM3_B IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_3, 0x0a00) +#define GPIO0_7_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_4, 0x0a00) +#define GPIO0_7_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_5, 0x0a00) +#define GPIO0_7_AS_UART4_TXD IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_6, 0x0a00) +#define GPIO0_7_AS_UART2_RTSN IOCMG_PIN_MUX(IOCFG_GPIO0_7, FUNC_MODE_7, 0x0a00) + +#define GPIO1_0_AS_GPIO1_0 IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_0, 0x0a00) +#define GPIO1_0_AS_QDM0_A IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_1, 0x0a00) +#define GPIO1_0_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_2, 0x0a00) +#define GPIO1_0_AS_UART2_TXD IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_3, 0x0a00) +#define GPIO1_0_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_4, 0x0a00) +#define GPIO1_0_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_5, 0x0a00) +#define GPIO1_0_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_6, 0x0a00) +#define GPIO1_0_AS_UART4_CTSN IOCMG_PIN_MUX(IOCFG_GPIO1_0, FUNC_MODE_7, 0x0a00) + +#define GPIO1_1_AS_GPIO1_1 IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_0, 0x0a00) +#define GPIO1_1_AS_QDM0_B IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_1, 0x0a00) +#define GPIO1_1_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_2, 0x0a00) +#define GPIO1_1_AS_UART2_RXD IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_3, 0x0a00) +#define GPIO1_1_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_4, 0x0a00) +#define GPIO1_1_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_6, 0x0a00) +#define GPIO1_1_AS_UART4_RTSN IOCMG_PIN_MUX(IOCFG_GPIO1_1, FUNC_MODE_7, 0x0a00) + +#define GPIO1_2_AS_GPIO1_2 IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_0, 0x0e80) +#define GPIO1_2_AS_UPDATE_MO IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_1, 0x0e80) +#define GPIO1_2_AS_UART1_RTSN IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_4, 0x0e80) +#define GPIO1_2_AS_SMB0_SPND IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_6, 0x0e80) +#define GPIO1_2_AS_TEST_CLK IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_11, 0x0e80) +#define GPIO1_2_AS_PMU_TEST IOCMG_PIN_MUX(IOCFG_GPIO1_2, FUNC_MODE_12, 0x0e80) + +#define GPIO1_3_AS_GPIO1_3 IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_0, 0x0a21) +#define GPIO1_3_AS_JTAG_TDO IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_1, 0x0a21) +#define GPIO1_3_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_2, 0x0a21) +#define GPIO1_3_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_3, 0x0a21) +#define GPIO1_3_AS_UART1_RXD IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_4, 0x0a21) +#define GPIO1_3_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_5, 0x0a21) +#define GPIO1_3_AS_QDM1_A IOCMG_PIN_MUX(IOCFG_GPIO1_3, FUNC_MODE_6, 0x0a21) + +#define GPIO1_4_AS_GPIO1_4 IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_0, 0x0b01) +#define GPIO1_4_AS_JTAG_TDI IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_1, 0x0b01) +#define GPIO1_4_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_3, 0x0b01) +#define GPIO1_4_AS_UART1_TXD IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_4, 0x0b01) +#define GPIO1_4_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_5, 0x0b01) +#define GPIO1_4_AS_QDM1_B IOCMG_PIN_MUX(IOCFG_GPIO1_4, FUNC_MODE_6, 0x0b01) + +#define GPIO1_5_AS_GPIO1_5 IOCMG_PIN_MUX(IOCFG_GPIO1_5, FUNC_MODE_0, 0x0a00) +#define GPIO1_5_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO1_5, FUNC_MODE_1, 0x0a00) +#define GPIO1_5_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO1_5, FUNC_MODE_2, 0x0a00) +#define GPIO1_5_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO1_5, FUNC_MODE_3, 0x0a00) +#define GPIO1_5_AS_UART3_RXD IOCMG_PIN_MUX(IOCFG_GPIO1_5, FUNC_MODE_4, 0x0a00) + +#define GPIO1_6_AS_GPIO1_6 IOCMG_PIN_MUX(IOCFG_GPIO1_6, FUNC_MODE_0, 0x0a00) +#define GPIO1_6_AS_QDM0_INDEX IOCMG_PIN_MUX(IOCFG_GPIO1_6, FUNC_MODE_1, 0x0a00) +#define GPIO1_6_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO1_6, FUNC_MODE_2, 0x0a00) + +#define GPIO1_7_AS_GPIO1_7 IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_0, 0x0a81) +#define GPIO1_7_AS_JTAG_TRSTN IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_1, 0x0a81) +#define GPIO1_7_AS_UART3_CTSN IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_2, 0x0a81) +#define GPIO1_7_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_3, 0x0a81) +#define GPIO1_7_AS_UART1_CTSN IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_4, 0x0a81) +#define GPIO1_7_AS_SPI0_CSN0 IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_5, 0x0a81) +#define GPIO1_7_AS_ADC_EXT_TRIG1 IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_6, 0x0a81) +#define GPIO1_7_AS_QDM2_INDEX IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_7, 0x0a81) +#define GPIO1_7_AS_ADC1_ANA_A11 IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_12, 0x0a81) +#define GPIO1_7_AS_ACMP1_ANA_N2 IOCMG_PIN_MUX(IOCFG_GPIO1_7, FUNC_MODE_13, 0x0a81) + +#define GPIO2_0_AS_GPIO2_0 IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_0, 0x0a00) +#define GPIO2_0_AS_UART3_RXD IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_2, 0x0a00) +#define GPIO2_0_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_3, 0x0a00) +#define GPIO2_0_AS_SPI0_MOSI IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_5, 0x0a00) +#define GPIO2_0_AS_QDM2_A IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_6, 0x0a00) +#define GPIO2_0_AS_PVD_TOGGLE IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_10, 0x0a00) +#define GPIO2_0_AS_EF_BIST_SCK IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_11, 0x0a00) +#define GPIO2_0_AS_ADC1_ANA_A12 IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_12, 0x0a00) +#define GPIO2_0_AS_ADC0_ANA_A9 IOCMG_PIN_MUX(IOCFG_GPIO2_0, FUNC_MODE_13, 0x0a00) + +#define GPIO2_1_AS_GPIO2_1 IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_0, 0x0a00) +#define GPIO2_1_AS_UART3_TXD IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_2, 0x0a00) +#define GPIO2_1_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_3, 0x0a00) +#define GPIO2_1_AS_SPI0_MISO IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_5, 0x0a00) +#define GPIO2_1_AS_QDM2_B IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_6, 0x0a00) +#define GPIO2_1_AS_EF_BIST_SDI IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_11, 0x0a00) +#define GPIO2_1_AS_ADC1_ANA_A13 IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_12, 0x0a00) +#define GPIO2_1_AS_ADC0_ANA_A2 IOCMG_PIN_MUX(IOCFG_GPIO2_1, FUNC_MODE_13, 0x0a00) + +#define GPIO2_2_AS_GPIO2_2 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_0, 0x0a00) +#define GPIO2_2_AS_APT_EVTMP4 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_2, 0x0a00) +#define GPIO2_2_AS_UART1_RTSN IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_3, 0x0a00) +#define GPIO2_2_AS_UART3_RTSN IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_4, 0x0a00) +#define GPIO2_2_AS_SPI0_CSN1 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_5, 0x0a00) +#define GPIO2_2_AS_ADC1_STATUS IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_6, 0x0a00) +#define GPIO2_2_AS_EF_BIST_SDO IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_11, 0x0a00) +#define GPIO2_2_AS_ADC1_ANA_A8 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_12, 0x0a00) +#define GPIO2_2_AS_ACMP1_ANA_P2 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_13, 0x0a00) +#define GPIO2_2_AS_ADC0_ANA_A10 IOCMG_PIN_MUX(IOCFG_GPIO2_2, FUNC_MODE_14, 0x0a00) + +#define GPIO2_3_AS_GPIO2_3 IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_0, 0x0a00) +#define GPIO2_3_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_1, 0x0a00) +#define GPIO2_3_AS_SPI0_CLK IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_5, 0x0a00) +#define GPIO2_3_AS_EF_BIST_SCE IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_11, 0x0a00) +#define GPIO2_3_AS_ADC1_ANA_A2 IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_12, 0x0a00) +#define GPIO2_3_AS_PGA1_ANA_P0 IOCMG_PIN_MUX(IOCFG_GPIO2_3, FUNC_MODE_13, 0x0a00) + +#define GPIO2_4_AS_GPIO2_4 IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_0, 0x0a00) +#define GPIO2_4_AS_APT6_PWMA IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_3, 0x0a00) +#define GPIO2_4_AS_UART0_RXD IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_4, 0x0a00) +#define GPIO2_4_AS_QDM1_A IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_5, 0x0a00) +#define GPIO2_4_AS_ADC1_ANA_A10 IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_12, 0x0a00) +#define GPIO2_4_AS_PGA1_ANA_N0 IOCMG_PIN_MUX(IOCFG_GPIO2_4, FUNC_MODE_13, 0x0a00) + +#define GPIO2_5_AS_GPIO2_5 IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_0, 0x0a00) +#define GPIO2_5_AS_APT7_PWMA IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_3, 0x0a00) +#define GPIO2_5_AS_UART0_TXD IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_4, 0x0a00) +#define GPIO2_5_AS_QDM1_B IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_5, 0x0a00) +#define GPIO2_5_AS_PGA1_ANA_EXT0 IOCMG_PIN_MUX(IOCFG_GPIO2_5, FUNC_MODE_13, 0x0a00) + +#define GPIO2_6_AS_GPIO2_6 IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_0, 0x0a00) +#define GPIO2_6_AS_APT8_PWMA IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_3, 0x0a00) +#define GPIO2_6_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_4, 0x0a00) +#define GPIO2_6_AS_QDM1_INDEX IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_6, 0x0a00) +#define GPIO2_6_AS_ADC0_STATUS IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_7, 0x0a00) +#define GPIO2_6_AS_ADC1_ANA_A3 IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_12, 0x0a00) +#define GPIO2_6_AS_ADC2_ANA_A12 IOCMG_PIN_MUX(IOCFG_GPIO2_6, FUNC_MODE_13, 0x0a00) + +#define GPIO2_7_AS_GPIO2_7 IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_0, 0x0a00) +#define GPIO2_7_AS_ACMP1_OUT IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_2, 0x0a00) +#define GPIO2_7_AS_APT6_PWMB IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_3, 0x0a00) +#define GPIO2_7_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_4, 0x0a00) +#define GPIO2_7_AS_UART0_RTSN IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_5, 0x0a00) +#define GPIO2_7_AS_ADC1_ANA_A4 IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_12, 0x0a00) +#define GPIO2_7_AS_ADC2_ANA_A13 IOCMG_PIN_MUX(IOCFG_GPIO2_7, FUNC_MODE_13, 0x0a00) + +#define GPIO3_0_AS_GPIO3_0 IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_0, 0x0a00) +#define GPIO3_0_AS_APT7_PWMB IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_3, 0x0a00) +#define GPIO3_0_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_4, 0x0a00) +#define GPIO3_0_AS_UART0_CTSN IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_5, 0x0a00) +#define GPIO3_0_AS_ADC1_ANA_A5 IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_12, 0x0a00) +#define GPIO3_0_AS_ACMP1_ANA_N3 IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_13, 0x0a00) +#define GPIO3_0_AS_ADC0_ANA_A6 IOCMG_PIN_MUX(IOCFG_GPIO3_0, FUNC_MODE_14, 0x0a00) + +#define GPIO3_1_AS_GPIO3_1 IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_0, 0x0a00) +#define GPIO3_1_AS_APT8_PWMB IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_3, 0x0a00) +#define GPIO3_1_AS_QDM2_INDEX IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_5, 0x0a00) +#define GPIO3_1_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_6, 0x0a00) +#define GPIO3_1_AS_ADC1_ANA_A6 IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_12, 0x0a00) +#define GPIO3_1_AS_ACMP1_ANA_P3 IOCMG_PIN_MUX(IOCFG_GPIO3_1, FUNC_MODE_13, 0x0a00) + +#define GPIO3_2_AS_GPIO3_2 IOCMG_PIN_MUX(IOCFG_GPIO3_2, FUNC_MODE_0, 0x0a00) +#define GPIO3_2_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO3_2, FUNC_MODE_4, 0x0a00) +#define GPIO3_2_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO3_2, FUNC_MODE_5, 0x0a00) +#define GPIO3_2_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO3_2, FUNC_MODE_7, 0x0a00) + +#define GPIO3_3_AS_GPIO3_3 IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_0, 0x0a00) +#define GPIO3_3_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_1, 0x0a00) +#define GPIO3_3_AS_UART0_RXD IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_2, 0x0a00) +#define GPIO3_3_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_3, 0x0a00) +#define GPIO3_3_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_4, 0x0a00) +#define GPIO3_3_AS_UART3_CTSN IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_5, 0x0a00) +#define GPIO3_3_AS_SMB0_ALTN IOCMG_PIN_MUX(IOCFG_GPIO3_3, FUNC_MODE_6, 0x0a00) + +#define GPIO3_4_AS_GPIO3_4 IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_0, 0x0a00) +#define GPIO3_4_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_1, 0x0a00) +#define GPIO3_4_AS_UART0_TXD IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_2, 0x0a00) +#define GPIO3_4_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_3, 0x0a00) +#define GPIO3_4_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_4, 0x0a00) +#define GPIO3_4_AS_UART3_RTSN IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_6, 0x0a00) +#define GPIO3_4_AS_SMB0_SPNDN IOCMG_PIN_MUX(IOCFG_GPIO3_4, FUNC_MODE_7, 0x0a00) + +#define GPIO3_5_AS_GPIO3_5 IOCMG_PIN_MUX(IOCFG_GPIO3_5, FUNC_MODE_0, 0x0a00) +#define GPIO3_5_AS_APT0_PWMA IOCMG_PIN_MUX(IOCFG_GPIO3_5, FUNC_MODE_3, 0x0a00) +#define GPIO3_5_AS_UART2_TXD IOCMG_PIN_MUX(IOCFG_GPIO3_5, FUNC_MODE_4, 0x0a00) + +#define GPIO3_6_AS_GPIO3_6 IOCMG_PIN_MUX(IOCFG_GPIO3_6, FUNC_MODE_0, 0x0a00) +#define GPIO3_6_AS_APT1_PWMA IOCMG_PIN_MUX(IOCFG_GPIO3_6, FUNC_MODE_3, 0x0a00) +#define GPIO3_6_AS_UART2_RXD IOCMG_PIN_MUX(IOCFG_GPIO3_6, FUNC_MODE_4, 0x0a00) + +#define GPIO3_7_AS_GPIO3_7 IOCMG_PIN_MUX(IOCFG_GPIO3_7, FUNC_MODE_0, 0x0a00) +#define GPIO3_7_AS_APT2_PWMA IOCMG_PIN_MUX(IOCFG_GPIO3_7, FUNC_MODE_3, 0x0a00) +#define GPIO3_7_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO3_7, FUNC_MODE_4, 0x0a00) + +#define GPIO4_0_AS_GPIO4_0 IOCMG_PIN_MUX(IOCFG_GPIO4_0, FUNC_MODE_0, 0x0a00) +#define GPIO4_0_AS_APT0_PWMB IOCMG_PIN_MUX(IOCFG_GPIO4_0, FUNC_MODE_3, 0x0a00) +#define GPIO4_0_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO4_0, FUNC_MODE_4, 0x0a00) + +#define GPIO4_1_AS_GPIO4_1 IOCMG_PIN_MUX(IOCFG_GPIO4_1, FUNC_MODE_0, 0x0a00) +#define GPIO4_1_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO4_1, FUNC_MODE_2, 0x0a00) +#define GPIO4_1_AS_APT1_PWMB IOCMG_PIN_MUX(IOCFG_GPIO4_1, FUNC_MODE_3, 0x0a00) + +#define GPIO4_2_AS_GPIO4_2 IOCMG_PIN_MUX(IOCFG_GPIO4_2, FUNC_MODE_0, 0x0a00) +#define GPIO4_2_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO4_2, FUNC_MODE_2, 0x0a00) +#define GPIO4_2_AS_APT2_PWMB IOCMG_PIN_MUX(IOCFG_GPIO4_2, FUNC_MODE_3, 0x0a00) +#define GPIO4_2_AS_ANA_TEST IOCMG_PIN_MUX(IOCFG_GPIO4_2, FUNC_MODE_12, 0x0a00) + +#define GPIO4_3_AS_GPIO4_3 IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_0, 0x0a00) +#define GPIO4_3_AS_UART1_RXD IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_3, 0x0a00) +#define GPIO4_3_AS_QDM3_A IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_4, 0x0a00) +#define GPIO4_3_AS_ADC0_ANA_A7 IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_12, 0x0a00) +#define GPIO4_3_AS_PGA0_ANA_P0 IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_13, 0x0a00) +#define GPIO4_3_AS_ADC1_ANA_A14 IOCMG_PIN_MUX(IOCFG_GPIO4_3, FUNC_MODE_14, 0x0a00) + +#define GPIO4_4_AS_GPIO4_4 IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_0, 0x0a00) +#define GPIO4_4_AS_UART1_TXD IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_3, 0x0a00) +#define GPIO4_4_AS_QDM3_B IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_4, 0x0a00) +#define GPIO4_4_AS_ADC0_ANA_A8 IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_12, 0x0a00) +#define GPIO4_4_AS_PGA0_ANA_N0 IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_13, 0x0a00) +#define GPIO4_4_AS_ADC1_ANA_A15 IOCMG_PIN_MUX(IOCFG_GPIO4_4, FUNC_MODE_14, 0x0a00) + +#define GPIO4_5_AS_GPIO4_5 IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_0, 0x0a00) +#define GPIO4_5_AS_UART1_CTSN IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_3, 0x0a00) +#define GPIO4_5_AS_QDM3_INDEX IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_4, 0x0a00) +#define GPIO4_5_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_5, 0x0a00) +#define GPIO4_5_AS_PGA0_ANA_EXT0 IOCMG_PIN_MUX(IOCFG_GPIO4_5, FUNC_MODE_13, 0x0a00) + +#define GPIO4_6_AS_GPIO4_6 IOCMG_PIN_MUX(IOCFG_GPIO4_6, FUNC_MODE_0, 0x0a00) +#define GPIO4_6_AS_ADC_EXT_TRIG0 IOCMG_PIN_MUX(IOCFG_GPIO4_6, FUNC_MODE_6, 0x0a00) +#define GPIO4_6_AS_ADC0_ANA_A3 IOCMG_PIN_MUX(IOCFG_GPIO4_6, FUNC_MODE_12, 0x0a00) +#define GPIO4_6_AS_PGA1_ANA_P3 IOCMG_PIN_MUX(IOCFG_GPIO4_6, FUNC_MODE_13, 0x0a00) +#define GPIO4_6_AS_ADC2_ANA_A14 IOCMG_PIN_MUX(IOCFG_GPIO4_6, FUNC_MODE_14, 0x0a00) + +#define GPIO4_7_AS_GPIO4_7 IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_0, 0x0a00) +#define GPIO4_7_AS_CAN_RX IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_4, 0x0a00) +#define GPIO4_7_AS_UART1_RTSN IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_5, 0x0a00) +#define GPIO4_7_AS_UART0_RXD IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_6, 0x0a00) +#define GPIO4_7_AS_ADC0_ANA_A4 IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_12, 0x0a00) +#define GPIO4_7_AS_PGA1_ANA_N3 IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_13, 0x0a00) +#define GPIO4_7_AS_ACMP0_ANA_N1 IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_14, 0x0a00) +#define GPIO4_7_AS_ADC2_ANA_A15 IOCMG_PIN_MUX(IOCFG_GPIO4_7, FUNC_MODE_15, 0x0a00) + +#define GPIO5_0_AS_GPIO5_0 IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_0, 0x0a00) +#define GPIO5_0_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_1, 0x0a00) +#define GPIO5_0_AS_ACMP0_OUT IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_2, 0x0a00) +#define GPIO5_0_AS_APT_EVTMP4 IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_3, 0x0a00) +#define GPIO5_0_AS_CAN_TX IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_4, 0x0a00) +#define GPIO5_0_AS_ADC0_STATUS IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_5, 0x0a00) +#define GPIO5_0_AS_UART0_TXD IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_6, 0x0a00) +#define GPIO5_0_AS_PGA1_ANA_EXT1 IOCMG_PIN_MUX(IOCFG_GPIO5_0, FUNC_MODE_13, 0x0a00) + +#define GPIO5_1_AS_GPIO5_1 IOCMG_PIN_MUX(IOCFG_GPIO5_1, FUNC_MODE_0, 0x0a00) +#define GPIO5_1_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO5_1, FUNC_MODE_3, 0x0a00) +#define GPIO5_1_AS_SPI1_CSN0 IOCMG_PIN_MUX(IOCFG_GPIO5_1, FUNC_MODE_4, 0x0a00) +#define GPIO5_1_AS_UART1_TXD IOCMG_PIN_MUX(IOCFG_GPIO5_1, FUNC_MODE_5, 0x0a00) + +#define GPIO5_2_AS_GPIO5_2 IOCMG_PIN_MUX(IOCFG_GPIO5_2, FUNC_MODE_0, 0x0a00) +#define GPIO5_2_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO5_2, FUNC_MODE_3, 0x0a00) +#define GPIO5_2_AS_SPI1_MOSI IOCMG_PIN_MUX(IOCFG_GPIO5_2, FUNC_MODE_4, 0x0a00) +#define GPIO5_2_AS_UART1_RXD IOCMG_PIN_MUX(IOCFG_GPIO5_2, FUNC_MODE_5, 0x0a00) + +#define GPIO5_3_AS_GPIO5_3 IOCMG_PIN_MUX(IOCFG_GPIO5_3, FUNC_MODE_0, 0x0a00) +#define GPIO5_3_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO5_3, FUNC_MODE_2, 0x0a00) +#define GPIO5_3_AS_SPI1_MISO IOCMG_PIN_MUX(IOCFG_GPIO5_3, FUNC_MODE_4, 0x0a00) +#define GPIO5_3_AS_UART2_RXD IOCMG_PIN_MUX(IOCFG_GPIO5_3, FUNC_MODE_5, 0x0a00) + +#define GPIO5_4_AS_GPIO5_4 IOCMG_PIN_MUX(IOCFG_GPIO5_4, FUNC_MODE_0, 0x0a00) +#define GPIO5_4_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO5_4, FUNC_MODE_2, 0x0a00) +#define GPIO5_4_AS_SPI1_CLK IOCMG_PIN_MUX(IOCFG_GPIO5_4, FUNC_MODE_4, 0x0a00) +#define GPIO5_4_AS_UART2_TXD IOCMG_PIN_MUX(IOCFG_GPIO5_4, FUNC_MODE_5, 0x0a00) + +#define GPIO5_5_AS_GPIO5_5 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_0, 0x0a00) +#define GPIO5_5_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_2, 0x0a00) +#define GPIO5_5_AS_QDM1_INDEX IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_3, 0x0a00) +#define GPIO5_5_AS_SPI1_CSN1 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_4, 0x0a00) +#define GPIO5_5_AS_ADC0_GPIO0 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_9, 0x0a00) +#define GPIO5_5_AS_ADC1_GPIO0 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_10, 0x0a00) +#define GPIO5_5_AS_ADC2_GPIO0 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_11, 0x0a00) +#define GPIO5_5_AS_ADC2_ANA_A9 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_12, 0x0a00) +#define GPIO5_5_AS_PGA2_ANA_P0 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_13, 0x0a00) +#define GPIO5_5_AS_ACMP0_ANA_P1 IOCMG_PIN_MUX(IOCFG_GPIO5_5, FUNC_MODE_14, 0x0a00) + +#define GPIO5_6_AS_GPIO5_6 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_0, 0x0a00) +#define GPIO5_6_AS_UART2_CTSN IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_2, 0x0a00) +#define GPIO5_6_AS_QDM1_A IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_3, 0x0a00) +#define GPIO5_6_AS_UART4_CTSN IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_4, 0x0a00) +#define GPIO5_6_AS_ADC0_GPIO1 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_9, 0x0a00) +#define GPIO5_6_AS_ADC1_GPIO1 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_10, 0x0a00) +#define GPIO5_6_AS_ADC2_GPIO1 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_11, 0x0a00) +#define GPIO5_6_AS_ADC2_ANA_A6 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_12, 0x0a00) +#define GPIO5_6_AS_PGA2_ANA_N0 IOCMG_PIN_MUX(IOCFG_GPIO5_6, FUNC_MODE_13, 0x0a00) + +#define GPIO5_7_AS_GPIO5_7 IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_0, 0x0a00) +#define GPIO5_7_AS_UART2_RTSN IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_2, 0x0a00) +#define GPIO5_7_AS_QDM1_B IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_3, 0x0a00) +#define GPIO5_7_AS_UART4_RTSN IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_4, 0x0a00) +#define GPIO5_7_AS_ADC0_GPIO2 IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_9, 0x0a00) +#define GPIO5_7_AS_ADC1_GPIO2 IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_10, 0x0a00) +#define GPIO5_7_AS_ADC2_GPIO2 IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_11, 0x0a00) +#define GPIO5_7_AS_PGA2_ANA_EXT0 IOCMG_PIN_MUX(IOCFG_GPIO5_7, FUNC_MODE_13, 0x0a00) + +#define GPIO6_0_AS_GPIO6_0 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_0, 0x0a00) +#define GPIO6_0_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_1, 0x0a00) +#define GPIO6_0_AS_SPI1_CSN1 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_2, 0x0a00) +#define GPIO6_0_AS_UART2_TXD IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_3, 0x0a00) +#define GPIO6_0_AS_QDM0_A IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_4, 0x0a00) +#define GPIO6_0_AS_ADC0_GPIO3 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_9, 0x0a00) +#define GPIO6_0_AS_ADC1_GPIO3 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_10, 0x0a00) +#define GPIO6_0_AS_ADC2_GPIO3 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_11, 0x0a00) +#define GPIO6_0_AS_ADC2_ANA_A7 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_12, 0x0a00) +#define GPIO6_0_AS_ACMP2_ANA_N1 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_13, 0x0a00) +#define GPIO6_0_AS_ADC0_ANA_A13 IOCMG_PIN_MUX(IOCFG_GPIO6_0, FUNC_MODE_14, 0x0a00) + +#define GPIO6_1_AS_GPIO6_1 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_0, 0x0a00) +#define GPIO6_1_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_1, 0x0a00) +#define GPIO6_1_AS_SPI1_MOSI IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_2, 0x0a00) +#define GPIO6_1_AS_UART2_RXD IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_3, 0x0a00) +#define GPIO6_1_AS_QDM0_B IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_4, 0x0a00) +#define GPIO6_1_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_5, 0x0a00) +#define GPIO6_1_AS_ADC0_GPIO4 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_9, 0x0a00) +#define GPIO6_1_AS_ADC1_GPIO4 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_10, 0x0a00) +#define GPIO6_1_AS_ADC2_GPIO4 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_11, 0x0a00) +#define GPIO6_1_AS_ADC2_ANA_A8 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_12, 0x0a00) +#define GPIO6_1_AS_ACMP2_ANA_P1 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_13, 0x0a00) +#define GPIO6_1_AS_ADC1_ANA_A9 IOCMG_PIN_MUX(IOCFG_GPIO6_1, FUNC_MODE_14, 0x0a00) + +#define GPIO6_2_AS_GPIO6_2 IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_0, 0x0a00) +#define GPIO6_2_AS_ACMP2_OUT IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_2, 0x0a00) +#define GPIO6_2_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_3, 0x0a00) +#define GPIO6_2_AS_QDM0_INDEX IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_4, 0x0a00) +#define GPIO6_2_AS_SPI1_MISO IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_5, 0x0a00) +#define GPIO6_2_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_6, 0x0a00) +#define GPIO6_2_AS_ADC2_STATUS IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_7, 0x0a00) +#define GPIO6_2_AS_ADC2_ANA_A5 IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_12, 0x0a00) +#define GPIO6_2_AS_ADC1_ANA_A7 IOCMG_PIN_MUX(IOCFG_GPIO6_2, FUNC_MODE_13, 0x0a00) + +#define GPIO6_3_AS_GPIO6_3 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_0, 0x0a00) +#define GPIO6_3_AS_UART4_RXD IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_1, 0x0a00) +#define GPIO6_3_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_2, 0x0a00) +#define GPIO6_3_AS_CAN_RX IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_3, 0x0a00) +#define GPIO6_3_AS_SPI1_CSN0 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_4, 0x0a00) +#define GPIO6_3_AS_ADC_EXT_TRIG2 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_5, 0x0a00) +#define GPIO6_3_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_6, 0x0a00) +#define GPIO6_3_AS_SMB0_ALTN IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_7, 0x0a00) +#define GPIO6_3_AS_ANA_CTRL_GPIO0 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_11, 0x0a00) +#define GPIO6_3_AS_ADC2_ANA_A2 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_12, 0x0a00) +#define GPIO6_3_AS_ADC0_ANA_A14 IOCMG_PIN_MUX(IOCFG_GPIO6_3, FUNC_MODE_13, 0x0a00) + +#define GPIO6_4_AS_GPIO6_4 IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_0, 0x0a00) +#define GPIO6_4_AS_UART4_TXD IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_1, 0x0a00) +#define GPIO6_4_AS_APT_EVTMP6 IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_2, 0x0a00) +#define GPIO6_4_AS_CAN_TX IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_3, 0x0a00) +#define GPIO6_4_AS_SPI1_CLK IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_4, 0x0a00) +#define GPIO6_4_AS_SMB0_SPNDN IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_5, 0x0a00) +#define GPIO6_4_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_6, 0x0a00) +#define GPIO6_4_AS_ANA_CTRL_GPI IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_11, 0x0a00) +#define GPIO6_4_AS_ADC2_ANA_A10 IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_12, 0x0a00) +#define GPIO6_4_AS_ADC0_ANA_A15 IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_13, 0x0a00) +#define GPIO6_4_AS_DAC0_ANA_OUT IOCMG_PIN_MUX(IOCFG_GPIO6_4, FUNC_MODE_14, 0x0a00) + +#define GPIO6_5_AS_GPIO6_5 IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_0, 0x0a00) +#define GPIO6_5_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_1, 0x0a00) +#define GPIO6_5_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_2, 0x0a00) +#define GPIO6_5_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_3, 0x0a00) +#define GPIO6_5_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_5, 0x0a00) +#define GPIO6_5_AS_UART3_RXD IOCMG_PIN_MUX(IOCFG_GPIO6_5, FUNC_MODE_6, 0x0a00) + +#define GPIO6_6_AS_GPIO6_6 IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_0, 0x0a00) +#define GPIO6_6_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_1, 0x0a00) +#define GPIO6_6_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_2, 0x0a00) +#define GPIO6_6_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_3, 0x0a00) +#define GPIO6_6_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_4, 0x0a00) +#define GPIO6_6_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_5, 0x0a00) +#define GPIO6_6_AS_UART3_TXD IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_6, 0x0a00) +#define GPIO6_6_AS_EF_BIST_SCE IOCMG_PIN_MUX(IOCFG_GPIO6_6, FUNC_MODE_11, 0x0a00) + +#define GPIO6_7_AS_GPIO6_7 IOCMG_PIN_MUX(IOCFG_GPIO6_7, FUNC_MODE_0, 0x0a00) +#define GPIO6_7_AS_APT3_PWMA IOCMG_PIN_MUX(IOCFG_GPIO6_7, FUNC_MODE_1, 0x0a00) +#define GPIO6_7_AS_UART1_RXD IOCMG_PIN_MUX(IOCFG_GPIO6_7, FUNC_MODE_2, 0x0a00) + +#define GPIO7_0_AS_GPIO7_0 IOCMG_PIN_MUX(IOCFG_GPIO7_0, FUNC_MODE_0, 0x0a30) +#define GPIO7_0_AS_APT4_PWMA IOCMG_PIN_MUX(IOCFG_GPIO7_0, FUNC_MODE_1, 0x0a30) +#define GPIO7_0_AS_UART1_TXD IOCMG_PIN_MUX(IOCFG_GPIO7_0, FUNC_MODE_2, 0x0a30) +#define GPIO7_0_AS_EF_BIST_SDO IOCMG_PIN_MUX(IOCFG_GPIO7_0, FUNC_MODE_11, 0x0a30) + +#define GPIO7_1_AS_GPIO7_1 IOCMG_PIN_MUX(IOCFG_GPIO7_1, FUNC_MODE_0, 0x0a00) +#define GPIO7_1_AS_APT5_PWMA IOCMG_PIN_MUX(IOCFG_GPIO7_1, FUNC_MODE_1, 0x0a00) +#define GPIO7_1_AS_SPI0_CSN0 IOCMG_PIN_MUX(IOCFG_GPIO7_1, FUNC_MODE_3, 0x0a00) +#define GPIO7_1_AS_UART1_RTSN IOCMG_PIN_MUX(IOCFG_GPIO7_1, FUNC_MODE_4, 0x0a00) +#define GPIO7_1_AS_UART3_RTSN IOCMG_PIN_MUX(IOCFG_GPIO7_1, FUNC_MODE_5, 0x0a00) + +#define GPIO7_2_AS_GPIO7_2 IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_0, 0x0a00) +#define GPIO7_2_AS_APT3_PWMB IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_1, 0x0a00) +#define GPIO7_2_AS_SPI0_MOSI IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_3, 0x0a00) +#define GPIO7_2_AS_UART1_CTSN IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_4, 0x0a00) +#define GPIO7_2_AS_UART3_CTSN IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_5, 0x0a00) +#define GPIO7_2_AS_EF_BIST_SDI IOCMG_PIN_MUX(IOCFG_GPIO7_2, FUNC_MODE_11, 0x0a00) + +#define GPIO7_3_AS_GPIO7_3 IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_0, 0x0a00) +#define GPIO7_3_AS_APT4_PWMB IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_1, 0x0a00) +#define GPIO7_3_AS_SPI0_MISO IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_3, 0x0a00) +#define GPIO7_3_AS_UART2_RTSN IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_4, 0x0a00) +#define GPIO7_3_AS_UART4_RTSN IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_5, 0x0a00) +#define GPIO7_3_AS_SMB0_ALTN IOCMG_PIN_MUX(IOCFG_GPIO7_3, FUNC_MODE_6, 0x0a00) + +#define GPIO7_4_AS_GPIO7_4 IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_0, 0x0a00) +#define GPIO7_4_AS_APT5_PWMB IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_1, 0x0a00) +#define GPIO7_4_AS_QDM2_INDEX IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_2, 0x0a00) +#define GPIO7_4_AS_SPI0_CLK IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_3, 0x0a00) +#define GPIO7_4_AS_UART2_CTSN IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_4, 0x0a00) +#define GPIO7_4_AS_UART4_CTSN IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_5, 0x0a00) +#define GPIO7_4_AS_SMB0_SPNDN IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_6, 0x0a00) +#define GPIO7_4_AS_EF_BIST_SCK IOCMG_PIN_MUX(IOCFG_GPIO7_4, FUNC_MODE_11, 0x0a00) + +#define GPIO7_5_AS_GPIO7_5 IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_0, 0x0a00) +#define GPIO7_5_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_1, 0x0a00) +#define GPIO7_5_AS_CAN_TX IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_2, 0x0a00) +#define GPIO7_5_AS_SPI0_CSN1 IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_3, 0x0a00) +#define GPIO7_5_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_4, 0x0a00) +#define GPIO7_5_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_5, 0x0a00) +#define GPIO7_5_AS_UART4_TXD IOCMG_PIN_MUX(IOCFG_GPIO7_5, FUNC_MODE_6, 0x0a00) + +#define GPIO7_6_AS_GPIO7_6 IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_0, 0x0a00) +#define GPIO7_6_AS_UART2_TXD IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_1, 0x0a00) +#define GPIO7_6_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_2, 0x0a00) +#define GPIO7_6_AS_WAKEUP2 IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_3, 0x0a00) +#define GPIO7_6_AS_APT_EVTIO4 IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_4, 0x0a00) +#define GPIO7_6_AS_QDM2_A IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_5, 0x0a00) +#define GPIO7_6_AS_PMU_ALDO_OK IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_11, 0x0a00) +#define GPIO7_6_AS_ADC2_ANA_A3 IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_12, 0x0a00) +#define GPIO7_6_AS_DAC1_ANA_OUT IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_13, 0x0a00) +#define GPIO7_6_AS_ADC0_ANA_A12 IOCMG_PIN_MUX(IOCFG_GPIO7_6, FUNC_MODE_14, 0x0a00) + +#define GPIO7_7_AS_GPIO7_7 IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_0, 0x0a00) +#define GPIO7_7_AS_UART2_RXD IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_1, 0x0a00) +#define GPIO7_7_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_2, 0x0a00) +#define GPIO7_7_AS_WAKEUP3 IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_3, 0x0a00) +#define GPIO7_7_AS_QDM2_B IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_5, 0x0a00) +#define GPIO7_7_AS_PMU_CLDO_EN IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_11, 0x0a00) +#define GPIO7_7_AS_ADC2_ANA_A4 IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_12, 0x0a00) +#define GPIO7_7_AS_DAC2_ANA_OUT IOCMG_PIN_MUX(IOCFG_GPIO7_7, FUNC_MODE_13, 0x0a00) + +#define GPIO8_0_AS_GPIO8_0 IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_0, 0x0a00) +#define GPIO8_0_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_1, 0x0a00) +#define GPIO8_0_AS_CAN_RX IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_2, 0x0a00) +#define GPIO8_0_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_3, 0x0a00) +#define GPIO8_0_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_4, 0x0a00) +#define GPIO8_0_AS_UART4_RXD IOCMG_PIN_MUX(IOCFG_GPIO8_0, FUNC_MODE_5, 0x0a00) + +#define GPIO8_1_AS_GPIO8_1 IOCMG_PIN_MUX(IOCFG_GPIO8_1, FUNC_MODE_0, 0x0f01) +#define GPIO8_1_AS_RESETN IOCMG_PIN_MUX(IOCFG_GPIO8_1, FUNC_MODE_1, 0x0f01) +#define GPIO8_1_AS_SYS_RSTN_OUT IOCMG_PIN_MUX(IOCFG_GPIO8_1, FUNC_MODE_2, 0x0f01) +#define GPIO8_1_AS_PMU_CLDO_OK IOCMG_PIN_MUX(IOCFG_GPIO8_1, FUNC_MODE_11, 0x0f01) + +#define GPIO8_2_AS_GPIO8_2 IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_0, 0x0a00) +#define GPIO8_2_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_1, 0x0a00) +#define GPIO8_2_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_2, 0x0a00) +#define GPIO8_2_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_3, 0x0a00) +#define GPIO8_2_AS_UART3_TXD IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_4, 0x0a00) +#define GPIO8_2_AS_QDM1_INDEX IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_5, 0x0a00) +#define GPIO8_2_AS_UART1_CTSN IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_6, 0x0a00) +#define GPIO8_2_AS_SMB0_ALTN IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_7, 0x0a00) +#define GPIO8_2_AS_PLL_LOCK IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_9, 0x0a00) +#define GPIO8_2_AS_HOSC_LOCK IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_10, 0x0a00) +#define GPIO8_2_AS_EF_PORB IOCMG_PIN_MUX(IOCFG_GPIO8_2, FUNC_MODE_11, 0x0a00) + +#define GPIO8_3_AS_GPIO8_3 IOCMG_PIN_MUX(IOCFG_GPIO8_3, FUNC_MODE_0, 0x0a00) +#define GPIO8_3_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO8_3, FUNC_MODE_1, 0x0a00) +#define GPIO8_3_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_3, FUNC_MODE_2, 0x0a00) +#define GPIO8_3_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_3, FUNC_MODE_3, 0x0a00) + +#define GPIO8_4_AS_GPIO8_4 IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_0, 0x0a00) +#define GPIO8_4_AS_UART3_RXD IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_1, 0x0a00) +#define GPIO8_4_AS_CAN_RX IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_2, 0x0a00) +#define GPIO8_4_AS_QDM2_A IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_3, 0x0a00) +#define GPIO8_4_AS_POE0 IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_4, 0x0a00) +#define GPIO8_4_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_5, 0x0a00) +#define GPIO8_4_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_6, 0x0a00) +#define GPIO8_4_AS_CAPM0_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_4, FUNC_MODE_7, 0x0a00) + +#define GPIO8_5_AS_GPIO8_5 IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_0, 0x0a00) +#define GPIO8_5_AS_UART3_TXD IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_1, 0x0a00) +#define GPIO8_5_AS_CAN_TX IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_2, 0x0a00) +#define GPIO8_5_AS_QDM2_B IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_3, 0x0a00) +#define GPIO8_5_AS_POE1 IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_4, 0x0a00) +#define GPIO8_5_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_5, 0x0a00) +#define GPIO8_5_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_6, 0x0a00) +#define GPIO8_5_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_5, FUNC_MODE_7, 0x0a00) + +#define GPIO8_6_AS_GPIO8_6 IOCMG_PIN_MUX(IOCFG_GPIO8_6, FUNC_MODE_0, 0x0a00) +#define GPIO8_6_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_6, FUNC_MODE_1, 0x0a00) +#define GPIO8_6_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_6, FUNC_MODE_2, 0x0a00) +#define GPIO8_6_AS_POE2 IOCMG_PIN_MUX(IOCFG_GPIO8_6, FUNC_MODE_3, 0x0a00) +#define GPIO8_6_AS_UART4_TXD IOCMG_PIN_MUX(IOCFG_GPIO8_6, FUNC_MODE_4, 0x0a00) + +#define GPIO8_7_AS_GPIO8_7 IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_0, 0x0a00) +#define GPIO8_7_AS_CAN1_TX IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_1, 0x0a00) +#define GPIO8_7_AS_UART4_TXD IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_2, 0x0a00) +#define GPIO8_7_AS_I2C0_SDA IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_3, 0x0a00) +#define GPIO8_7_AS_GPT0_PWM IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_4, 0x0a00) +#define GPIO8_7_AS_CAPM1_SRC IOCMG_PIN_MUX(IOCFG_GPIO8_7, FUNC_MODE_5, 0x0a00) + +#define GPIO9_0_AS_GPIO9_0 IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_0, 0x0a00) +#define GPIO9_0_AS_CAN1_RX IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_1, 0x0a00) +#define GPIO9_0_AS_UART4_RXD IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_2, 0x0a00) +#define GPIO9_0_AS_I2C0_SCL IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_3, 0x0a00) +#define GPIO9_0_AS_GPT1_PWM IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_4, 0x0a00) +#define GPIO9_0_AS_CAPM2_SRC IOCMG_PIN_MUX(IOCFG_GPIO9_0, FUNC_MODE_5, 0x0a00) + +#endif /* McuMagicTag_IOMAP_H */ \ No newline at end of file diff --git a/src/chip/3066m/ip_crg/ip_crg_common.c b/src/chip/3066m/ip_crg/ip_crg_common.c new file mode 100644 index 0000000000000000000000000000000000000000..305c09fbead73b7e6020970d668bdaf0798a6e92 --- /dev/null +++ b/src/chip/3066m/ip_crg/ip_crg_common.c @@ -0,0 +1,124 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file ip_crg_common.c + * @author MCU Driver Team + * @brief Contains ip crg common header files. + */ + +/* Includes ----------------------------------------------------------------- */ +#include "baseaddr.h" +#include "ip_crg_common.h" + +/** + * @brief Get IP frequency by ip register base address + * @param ipBaseAddr The ip base address + * @retval The bus frequency where the IP is located + */ +#ifdef FPGA +unsigned int CHIP_GetIpFreqHz(const void *ipBaseAddr) +{ + if (ipBaseAddr == IWDG_BASE) { /* The IWDG working clock is LOSC clock. */ + return LOSC_FREQ; + } else { + return HOSC_FREQ; /* The base address does not match, return LOSC freq. */ + } +} +#endif + +static const CHIP_CrgIpMatchInfo g_crgIpMatch[] = { + {UART0_BASE, CRG_IP_NONE_CLK_SEL, 0x140, 0}, + {UART1_BASE, CRG_IP_NONE_CLK_SEL, 0x144, 0}, + {UART2_BASE, CRG_IP_NONE_CLK_SEL, 0x148, 0}, + {UART3_BASE, CRG_IP_NONE_CLK_SEL, 0x14C, 0}, + {UART4_BASE, CRG_IP_NONE_CLK_SEL, 0x150, 0}, + {TIMER0_BASE, CRG_IP_NONE_CLK_SEL, 0x240, 0}, + {TIMER1_BASE, CRG_IP_NONE_CLK_SEL, 0x244, 0}, + {TIMER2_BASE, CRG_IP_NONE_CLK_SEL, 0x248, 0}, + {TIMER3_BASE, CRG_IP_NONE_CLK_SEL, 0x24C, 0}, + {SYSTICK_BASE, CRG_IP_NONE_CLK_SEL, 0x40, 0}, + {SPI0_BASE, CRG_IP_NONE_CLK_SEL, 0x180, 0}, + {SPI1_BASE, CRG_IP_NONE_CLK_SEL, 0x184, 0}, + {I2C0_BASE, CRG_IP_NONE_CLK_SEL, 0x1C0, 0}, + {CAN_BASE, CRG_IP_CAN, 0x2C0, 0}, + {CAN1_BASE, CRG_IP_CAN, 0x2C4, 0}, + {GPT0_BASE, CRG_IP_NONE_CLK_SEL, 0x440, 0}, + {GPT1_BASE, CRG_IP_NONE_CLK_SEL, 0x444, 0}, + {WWDG_BASE, CRG_IP_WWDG, 0x200, 0}, + {CAPM0_BASE, CRG_IP_NONE_CLK_SEL, 0x280, 0}, + {CAPM1_BASE, CRG_IP_NONE_CLK_SEL, 0x284, 0}, + {CAPM2_BASE, CRG_IP_NONE_CLK_SEL, 0x288, 0}, + {DMA_BASE, CRG_IP_NONE_CLK_SEL, 0x300, 0}, + {GPIO0_BASE, CRG_IP_NONE_CLK_SEL, 0x480, 0}, + {GPIO1_BASE, CRG_IP_NONE_CLK_SEL, 0x484, 0}, + {GPIO2_BASE, CRG_IP_NONE_CLK_SEL, 0x488, 0}, + {GPIO3_BASE, CRG_IP_NONE_CLK_SEL, 0x48C, 0}, + {GPIO4_BASE, CRG_IP_NONE_CLK_SEL, 0x490, 0}, + {GPIO5_BASE, CRG_IP_NONE_CLK_SEL, 0x494, 0}, + {GPIO6_BASE, CRG_IP_NONE_CLK_SEL, 0x498, 0}, + {GPIO7_BASE, CRG_IP_NONE_CLK_SEL, 0x49C, 0}, + {GPIO8_BASE, CRG_IP_NONE_CLK_SEL, 0x4A0, 0}, + {GPIO9_BASE, CRG_IP_NONE_CLK_SEL, 0x4A4, 0}, + {IWDG_BASE, CRG_IP_IWDG, 0x3C0, 0}, + {QDM0_BASE, CRG_IP_NONE_CLK_SEL, 0x4C0, 0}, + {QDM1_BASE, CRG_IP_NONE_CLK_SEL, 0x4C4, 0}, + {QDM2_BASE, CRG_IP_NONE_CLK_SEL, 0x4C8, 0}, + {QDM3_BASE, CRG_IP_NONE_CLK_SEL, 0x4CC, 0}, + {CRC_BASE, CRG_IP_NONE_CLK_SEL, 0x380, 0}, + {APT0_BASE, CRG_IP_NONE_CLK_SEL, 0x400, 0}, + {APT1_BASE, CRG_IP_NONE_CLK_SEL, 0x404, 0}, + {APT2_BASE, CRG_IP_NONE_CLK_SEL, 0x408, 0}, + {APT3_BASE, CRG_IP_NONE_CLK_SEL, 0x40C, 0}, + {APT4_BASE, CRG_IP_NONE_CLK_SEL, 0x410, 0}, + {APT5_BASE, CRG_IP_NONE_CLK_SEL, 0x414, 0}, + {APT6_BASE, CRG_IP_NONE_CLK_SEL, 0x418, 0}, + {APT7_BASE, CRG_IP_NONE_CLK_SEL, 0x41C, 0}, + {APT8_BASE, CRG_IP_NONE_CLK_SEL, 0x420, 0}, + {CMM_BASE, CRG_IP_NONE_CLK_SEL, 0x0340, 0}, + {CFD_BASE, CRG_IP_NONE_CLK_SEL, 0x0344, 0}, + {VREF_BASE, CRG_IP_ANA, 0xA60, 0}, + {ACMP0_BASE, CRG_IP_ANA, 0xA70, 0}, + {ACMP1_BASE, CRG_IP_ANA, 0xA74, 0}, + {ACMP2_BASE, CRG_IP_ANA, 0xA78, 0}, + {DAC0_BASE, CRG_IP_ANA, 0xA80, 0}, + {DAC1_BASE, CRG_IP_ANA, 0xA84, 0}, + {DAC2_BASE, CRG_IP_ANA, 0xA88, 0}, + {PGA0_BASE, CRG_IP_ANA, 0xA90, 0}, + {PGA1_BASE, CRG_IP_ANA, 0xA94, 0}, + {PGA2_BASE, CRG_IP_ANA, 0xA98, 0}, + {ADC0_BASE, CRG_IP_ADC, 0xA00, 0}, + {ADC1_BASE, CRG_IP_ADC, 0xA08, 0}, + {ADC2_BASE, CRG_IP_ADC, 0xA10, 0}, + {EFC_BASE, CRG_IP_EFC, 0x500, 0}, +}; + +/** + * @brief Get IP Match Info, @see g_crgIpMatch + * @param baseAddr The ip base address + * @retval The Address(offset) in g_crgIpMatch if match success + * @retval 0 if match fail + */ +CHIP_CrgIpMatchInfo *GetCrgIpMatchInfo(const void *baseAddr) +{ + unsigned int i; + for (i = 0; i < sizeof(g_crgIpMatch) / sizeof(g_crgIpMatch[0]); ++i) { + if (baseAddr == g_crgIpMatch[i].ipBaseAddr) { + return (CHIP_CrgIpMatchInfo *)&g_crgIpMatch[i]; + } + } + return (CHIP_CrgIpMatchInfo *)0; /* The base address does not match, return 0. */ +} diff --git a/src/chip/3066m/ip_crg/ip_crg_common.h b/src/chip/3066m/ip_crg/ip_crg_common.h new file mode 100644 index 0000000000000000000000000000000000000000..7baae94dc164592e3d99dcad8f664ba65f8ffe80 --- /dev/null +++ b/src/chip/3066m/ip_crg/ip_crg_common.h @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file ip_crg_common.h + * @author MCU Driver Team + * @brief Contains crg ip common header files. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_IP_CRG_COMMON_H +#define McuMagicTag_IP_CRG_COMMON_H + +/** + * @brief define the frequence of hosc, losc and xtrail + */ +#define HOSC_FREQ 25000000U +#define LOSC_FREQ 32000U + +/** + * @brief CRG Ip Type, Sorting based on operable registers + */ +typedef enum { + CRG_IP_WWDG = 0x0, + CRG_IP_NONE_CLK_SEL = 0x01, + CRG_IP_CAN = 0x02, + CRG_IP_ADC = 0x03, + CRG_IP_EFC = 0x04, + CRG_IP_IWDG = 0x05, + CRG_IP_ANA = 0x06, + CRG_IP_MAX_TYPE = 0x07, +} CHIP_CrgIpType; + +/** + * @brief CRG register and IP address matching relationship table + */ +typedef struct { + void *ipBaseAddr; /**< Ip base address */ + CHIP_CrgIpType type; /**< Ip type, @see CHIP_CrgIpType */ + unsigned short regOffset; /**< Offset in CRG registers */ + unsigned char bitOffset; /**< Bit Offset in CRG register */ +} CHIP_CrgIpMatchInfo; + +unsigned int CHIP_GetIpFreqHz(const void *ipBaseAddr); +CHIP_CrgIpMatchInfo *GetCrgIpMatchInfo(const void *baseAddr); +extern unsigned int HAL_CRG_GetIpFreq(const void *baseAddress); + +#endif /* McuMagicTag_IP_CRG_COMMON_H */ diff --git a/src/chip/3066m/locktype.h b/src/chip/3066m/locktype.h new file mode 100644 index 0000000000000000000000000000000000000000..08b87ff323fa96916a32bd204b309d4d4d7bbc0f --- /dev/null +++ b/src/chip/3066m/locktype.h @@ -0,0 +1,43 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file locktype.h + * @author MCU Driver Team + * @brief This file lists all types that need to be locked on the chip. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_LOCKTYPE_H +#define McuMagicTag_LOCKTYPE_H + +/* Typedef definitions ------------------------------------------------------- */ +/** + * @brief This enum defines all hardware locks integrated by this MCU. + */ +typedef enum { + CHIP_LOCK_GPIO0 = 0, + CHIP_LOCK_GPIO1 = 1, + CHIP_LOCK_GPIO2 = 2, + CHIP_LOCK_GPIO3 = 3, + CHIP_LOCK_GPIO4 = 4, + CHIP_LOCK_GPIO5 = 5, + CHIP_LOCK_GPIO6 = 6, + CHIP_LOCK_GPIO7 = 7, + CHIP_LOCK_TOTAL +} CHIP_LockType; + +#endif /* McuMagicTag_LOCKTYPE_H */ \ No newline at end of file diff --git a/src/chip/3066m/startup.S b/src/chip/3066m/startup.S new file mode 100644 index 0000000000000000000000000000000000000000..8f90e449c122db1d5204e45af4ef2976ed2fbcfd --- /dev/null +++ b/src/chip/3066m/startup.S @@ -0,0 +1,848 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file startup.S + * @author MCU Application Driver Team + * @brief RISC-V trap handling and startup code + */ + +#ifndef ENTRY_S +#define ENTRY_S + +#include "feature.h" +#ifdef NOS_TASK_SUPPORT +.extern OsHwiPostHandle +.extern OsTaskTrueSwitch +#define NOS_HwiPostDispatch OsHwiPostHandle +#define NOS_TaskDispatch OsTaskTrueSwitch +#define NOS_TASK_SWITCH_MAGIC_NUM 0xACBCCCDC +#define TICK_IRQ_EN_BASE 0xBE0 +#define TICK_IRQ_EN_NUM 0x8 +#endif + +.extern __stack_top +.extern __irq_stack_top +.extern SysErrNmiEntry +.extern SysErrExcEntry +.extern trap_entry +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) +.extern g_RiscvPrivMode +#endif + +#ifdef __riscv64 +#define LREG ld +#define SREG sd +#define FLREG fld +#define FSREG fsd +#define REGBYTES 8 +#else +#define LREG lw +#define SREG sw +#define FLREG flw +#define FSREG fsw +#define REGBYTES 4 +#endif + +#define NESTED_IRQ_SUPPORT +#define COMPILE_LDM /**< Support stmia and ldmia instruction */ + +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs more stack to restore TickIRQEnable */ +#ifdef FLOAT_SUPPORT +#define TOTAL_INT_SIZE_ON_STACK (44 * REGBYTES) +#else +#define TOTAL_INT_SIZE_ON_STACK (24 * REGBYTES) +#endif +#else +#ifdef FLOAT_SUPPORT +#define TOTAL_INT_SIZE_ON_STACK (40 * REGBYTES) +#else +#define TOTAL_INT_SIZE_ON_STACK (20 * REGBYTES) +#endif +#endif + +#define SYSERR_INT_SIZE_ON_STACK (28 * REGBYTES) + +#define MSTATUS_MPP_MACHINE 0x00001800 +#define MCAUSE_ECALL_FROM_MMODE 11 +#define MCAUSE_ECALL_FROM_UMODE 8 +#define EXC_SIZE_ON_STACK (160) + +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_MPIE 0x00000080 +#define MCAUSE_MASK_INT_BIT 0x80000000 +#define MCAUSE_MASK_INT_NUM 0x000000FF + +#define locipri0 0xBC0 +#define locipri1 0xBC1 +#define locipri2 0xBC2 +#define locipri3 0xBC3 +#define locipri4 0xBC4 +#define locipri5 0xBC5 +#define locipri6 0xBC6 +#define locipri7 0xBC7 +#define locipri8 0xBC8 +#define locipri9 0xBC9 +#define locipri10 0xBCA +#define locipri11 0xBCB +#define locipri12 0xBCC +#define locipri13 0xBCD +#define locipri14 0xBCE +#define locipri15 0xBCF + +#define EFC_BASE_ADDR 0x14710000 /* efc base address */ +#define EFC_MAGIC_LOCK_RW 0x14710200 /* cmd operation magic word protection register */ +#define EFC_MAGIC_NUMBER 0xFEDCBA98 /* magic number */ +#define SYSRAM_ERROR 0x10108300 +#define SC_SYS_STAT_ADDR 0x10100018 /**< System state register address */ +#define TIMER0_CONTROL 0x14300008 +#define TIMER0_INTENABLE (1 << 5) +#define UART0_BASE_ADDR 0x14000000 +#define IBRD_OFFSET 0x24 +#define FBRD_OFFSET 0x28 +#define LCR_H_OFFSET 0x2C +#define CR_OFFSET 0x30 +#define DMACR_OFFSET 0x48 + +.equ cipri, 0x7ED +.equ prithd, 0xBFE + + .section .data.magic + .word 0xA37E95BD /* eflash magic number, bootrom will check it */ + + .section .text.entry + .global _start + .option norvc +_start: + j handle_reset + +.macro push_reg + addi sp, sp, -(TOTAL_INT_SIZE_ON_STACK) +#ifdef COMPILE_LDM + stmia {ra, t0-t2, a0-a7, t3-t6}, (sp) +#else + SREG ra, 0 * REGBYTES(sp) + SREG t0, 1 * REGBYTES(sp) + SREG t1, 2 * REGBYTES(sp) + SREG t2, 3 * REGBYTES(sp) + SREG a0, 4 * REGBYTES(sp) + SREG a1, 5 * REGBYTES(sp) + SREG a2, 6 * REGBYTES(sp) + SREG a3, 7 * REGBYTES(sp) + SREG a4, 8 * REGBYTES(sp) + SREG a5, 9 * REGBYTES(sp) + SREG a6, 10 * REGBYTES(sp) + SREG a7, 11 * REGBYTES(sp) + SREG t3, 12 * REGBYTES(sp) + SREG t4, 13 * REGBYTES(sp) + SREG t5, 14 * REGBYTES(sp) + SREG t6, 15 * REGBYTES(sp) +#endif + addi sp, sp, -(TOTAL_INT_SIZE_ON_STACK) +.endm + +.macro pop_reg + addi sp, sp, TOTAL_INT_SIZE_ON_STACK +#ifdef COMPILE_LDM + ldmia {ra, t0-t2, a0-a7, t3-t6},(sp) +#else + LREG ra, 0 * REGBYTES(sp) + LREG t0, 1 * REGBYTES(sp) + LREG t1, 2 * REGBYTES(sp) + LREG t2, 3 * REGBYTES(sp) + LREG a0, 4 * REGBYTES(sp) + LREG a1, 5 * REGBYTES(sp) + LREG a2, 6 * REGBYTES(sp) + LREG a3, 7 * REGBYTES(sp) + LREG a4, 8 * REGBYTES(sp) + LREG a5, 9 * REGBYTES(sp) + LREG a6, 10 * REGBYTES(sp) + LREG a7, 11 * REGBYTES(sp) + LREG t3, 12 * REGBYTES(sp) + LREG t4, 13 * REGBYTES(sp) + LREG t5, 14 * REGBYTES(sp) + LREG t6, 15 * REGBYTES(sp) +#endif + addi sp, sp, TOTAL_INT_SIZE_ON_STACK +.endm + +.macro SAVE_SYSERR_REGS + addi sp,sp,-(SYSERR_INT_SIZE_ON_STACK) + SREG s0, 16 * REGBYTES(sp) + SREG s1, 17 * REGBYTES(sp) + SREG s2, 18 * REGBYTES(sp) + SREG s3, 19 * REGBYTES(sp) + SREG s4, 20 * REGBYTES(sp) + SREG s5, 21 * REGBYTES(sp) + SREG s6, 22 * REGBYTES(sp) + SREG s7, 23 * REGBYTES(sp) + SREG s8, 24 * REGBYTES(sp) + SREG s9, 25 * REGBYTES(sp) + SREG s10, 26 * REGBYTES(sp) + SREG s11, 27 * REGBYTES(sp) + + addi a1, sp, (TOTAL_INT_SIZE_ON_STACK + SYSERR_INT_SIZE_ON_STACK) + SREG a1, 28 * REGBYTES(sp) /* save original sp */ + + SREG gp, 29 * REGBYTES(sp) + SREG tp, 30 * REGBYTES(sp) + + csrr a0, mepc + csrr a1, mstatus + csrr a2, mtval + csrr a3, mcause + # csrr a4, ccause + + SREG a0, 31 * REGBYTES(sp) /* mepc */ + SREG a1, 32 * REGBYTES(sp) /* mstatus */ + SREG a2, 33 * REGBYTES(sp) /* mtval */ + SREG a3, 34 * REGBYTES(sp) /* mcause */ + # SREG a4, 35 * REGBYTES(sp) /* ccause */ + mv a0,sp +.endm + +/* The interrupt vector table must be aligned with 4 bytes */ +.align 2 +TrapHandler: + j TrapVector /* trap and INT 0 */ + j TrapVector /* INT 1 */ + j TrapVector /* INT 2 */ + j TrapVector /* INT 3 */ + j TrapVector /* INT 4 */ + j TrapVector /* INT 5 */ + j TrapVector /* INT 6 */ + j TrapVector /* INT 7 */ + j TrapVector /* INT 8 */ + j TrapVector /* INT 9 */ + j TrapVector /* INT 10 */ + j TrapVector /* INT 11 */ + j TrapVector /* INT 12 */ + j TrapVector /* INT 13 */ + j TrapVector /* INT 14 */ + j TrapVector /* INT 15 */ + j TrapVector /* INT 16 */ + j TrapVector /* INT 17 */ + j TrapVector /* INT 18 */ + j TrapVector /* INT 19 */ + j TrapVector /* INT 20 */ + j TrapVector /* INT 21 */ + j TrapVector /* INT 22 */ + j TrapVector /* INT 23 */ + j TrapVector /* INT 24 */ + j TrapVector /* INT 25 */ + + j IntHandler /* INT 26 */ + j IntHandler /* INT 27 */ + j IntHandler /* INT 28 */ + j IntHandler /* INT 29 */ + j IntHandler /* INT 30 */ + j IntHandler /* INT 31 */ + j IntHandler /* INT 32 */ + j IntHandler /* INT 33 */ + j IntHandler /* INT 34 */ + j IntHandler /* INT 35 */ + j IntHandler /* INT 36 */ + j IntHandler /* INT 37 */ + j IntHandler /* INT 38 */ + j IntHandler /* INT 39 */ + j IntHandler /* INT 40 */ + j IntHandler /* INT 41 */ + j IntHandler /* INT 42 */ + j IntHandler /* INT 43 */ + j IntHandler /* INT 44 */ + j IntHandler /* INT 45 */ + j IntHandler /* INT 46 */ + j IntHandler /* INT 47 */ + j IntHandler /* INT 48 */ + j IntHandler /* INT 49 */ + j IntHandler /* INT 50 */ + j IntHandler /* INT 51 */ + j IntHandler /* INT 52 */ + j IntHandler /* INT 53 */ + j IntHandler /* INT 54 */ + j IntHandler /* INT 55 */ + j IntHandler /* INT 56 */ + j IntHandler /* INT 57 */ + j IntHandler /* INT 58 */ + j IntHandler /* INT 59 */ + j IntHandler /* INT 60 */ + j IntHandler /* INT 61 */ + j IntHandler /* INT 62 */ + j IntHandler /* INT 63 */ + j IntHandler /* INT 64 */ + j IntHandler /* INT 65 */ + j IntHandler /* INT 66 */ + j IntHandler /* INT 67 */ + j IntHandler /* INT 68 */ + j IntHandler /* INT 69 */ + j IntHandler /* INT 70 */ + j IntHandler /* INT 71 */ + j IntHandler /* INT 72 */ + j IntHandler /* INT 73 */ + j IntHandler /* INT 74 */ + j IntHandler /* INT 75 */ + j IntHandler /* INT 76 */ + j IntHandler /* INT 77 */ + j IntHandler /* INT 78 */ + j IntHandler /* INT 79 */ + j IntHandler /* INT 80 */ + j IntHandler /* INT 81 */ + j IntHandler /* INT 82 */ + j IntHandler /* INT 83 */ + j IntHandler /* INT 84 */ + j IntHandler /* INT 85 */ + j IntHandler /* INT 86 */ + j IntHandler /* INT 87 */ + j IntHandler /* INT 88 */ + j IntHandler /* INT 89 */ + j IntHandler /* INT 90 */ + j IntHandler /* INT 91 */ + j IntHandler /* INT 92 */ + j IntHandler /* INT 93 */ + j IntHandler /* INT 94 */ + j IntHandler /* INT 95 */ + j IntHandler /* INT 96 */ + j IntHandler /* INT 97 */ + j IntHandler /* INT 98 */ + j IntHandler /* INT 99 */ + j IntHandler /* INT 100 */ + j IntHandler /* INT 101 */ + j IntHandler /* INT 102 */ + j IntHandler /* INT 103 */ + j IntHandler /* INT 104 */ + j IntHandler /* INT 105 */ + j IntHandler /* INT 106 */ + j IntHandler /* INT 107 */ + j IntHandler /* INT 108 */ + j IntHandler /* INT 109 */ + j IntHandler /* INT 110 */ + j IntHandler /* INT 111 */ + j IntHandler /* INT 112 */ + j IntHandler /* INT 113 */ + j IntHandler /* INT 114 */ + j IntHandler /* INT 115 */ + j IntHandler /* INT 116 */ + j IntHandler /* INT 117 */ + j IntHandler /* INT 118 */ + j IntHandler /* INT 119 */ + j IntHandler /* INT 120 */ + j IntHandler /* INT 121 */ + +.align 2 +NmiEntry: + SAVE_SYSERR_REGS + call SysErrNmiEntry +deadLoop1: + tail deadLoop1 + nop + +.align 2 +TrapEntry: + SAVE_SYSERR_REGS + /* Exception run with interrupts masked */ + csrc mstatus, MSTATUS_MIE + call SysErrExcEntry +deadLoop2: + tail deadLoop2 + +.align 2 +IntHandler: + addi sp, sp, -(TOTAL_INT_SIZE_ON_STACK) + + SREG a0, 3 * REGBYTES(sp) + SREG a1, 4 * REGBYTES(sp) + +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) + la a0, g_RiscvPrivMode + lw a1, (a0) + addi a1, a1, 1 + sw a1, (a0) +#endif + +#if defined(HARD_NESTED_IRQ_SUPPORT) && (HARD_NESTED_IRQ_SUPPORT == 1) + csrr a0, mcause +#else + csrr a0, cipri + csrr a1, prithd + csrw prithd, a0 /* read prithd */ + SREG a1, 6 * REGBYTES(sp) /* save prithd */ + csrr a1, mstatus /* read mstatus */ + SREG a1, 7 * REGBYTES(sp) /* save mstatus */ + csrr a1, mepc /* read mepc */ + SREG a1, 8 * REGBYTES(sp) /* save mepc */ + + csrr a0, mcause + + li a1, (3<<11) + csrs mstatus, a1 +#ifndef NOS_TASK_SUPPORT /* When using NOS_TASK_SUPPORT, enable gloal irq after change to irq stack */ + la a1, custom_nested_irq_main_handler_entry + csrw mepc, a1 + mret +#endif /* #ifndef NOS_TASK */ +#endif + +.align 2 +custom_nested_irq_main_handler_entry: + SREG t0, 0 * REGBYTES(sp) + SREG t1, 1 * REGBYTES(sp) + SREG t2, 2 * REGBYTES(sp) + SREG a2, 5 * REGBYTES(sp) + SREG ra, 9 * REGBYTES(sp) + SREG a3, 10 * REGBYTES(sp) + SREG a4, 11 * REGBYTES(sp) + SREG a5, 12 * REGBYTES(sp) + SREG a6, 13 * REGBYTES(sp) + SREG a7, 14 * REGBYTES(sp) + SREG t3, 15 * REGBYTES(sp) + SREG t4, 16 * REGBYTES(sp) + SREG t5, 17 * REGBYTES(sp) + SREG t6, 18 * REGBYTES(sp) +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to save TickIRQEnable */ + csrr t0, TICK_IRQ_EN_BASE + andi t0, t0, TICK_IRQ_EN_NUM + SREG t0, 19 * REGBYTES(sp) +#endif + +#ifdef FLOAT_SUPPORT +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to save TickIRQEnable */ + FSREG f0, 23 * REGBYTES(sp) + FSREG f1, 24 * REGBYTES(sp) + FSREG f2, 25 * REGBYTES(sp) + FSREG f3, 26 * REGBYTES(sp) + FSREG f4, 27 * REGBYTES(sp) + FSREG f5, 28 * REGBYTES(sp) + FSREG f6, 29 * REGBYTES(sp) + FSREG f7, 30 * REGBYTES(sp) + FSREG f10, 31 * REGBYTES(sp) + FSREG f11, 32 * REGBYTES(sp) + FSREG f12, 33 * REGBYTES(sp) + FSREG f13, 34 * REGBYTES(sp) + FSREG f14, 35 * REGBYTES(sp) + FSREG f15, 36 * REGBYTES(sp) + FSREG f16, 37 * REGBYTES(sp) + FSREG f17, 38 * REGBYTES(sp) + FSREG f28, 39 * REGBYTES(sp) + FSREG f29, 40 * REGBYTES(sp) + FSREG f30, 41 * REGBYTES(sp) + FSREG f31, 42 * REGBYTES(sp) + frcsr t0 + SREG t0, 43 * REGBYTES(sp) +#else + FSREG f0, 19 * REGBYTES(sp) + FSREG f1, 20 * REGBYTES(sp) + FSREG f2, 21 * REGBYTES(sp) + FSREG f3, 22 * REGBYTES(sp) + FSREG f4, 23 * REGBYTES(sp) + FSREG f5, 24 * REGBYTES(sp) + FSREG f6, 25 * REGBYTES(sp) + FSREG f7, 26 * REGBYTES(sp) + FSREG f10, 27 * REGBYTES(sp) + FSREG f11, 28 * REGBYTES(sp) + FSREG f12, 29 * REGBYTES(sp) + FSREG f13, 30 * REGBYTES(sp) + FSREG f14, 31 * REGBYTES(sp) + FSREG f15, 32 * REGBYTES(sp) + FSREG f16, 33 * REGBYTES(sp) + FSREG f17, 34 * REGBYTES(sp) + FSREG f28, 35 * REGBYTES(sp) + FSREG f29, 36 * REGBYTES(sp) + FSREG f30, 37 * REGBYTES(sp) + FSREG f31, 38 * REGBYTES(sp) + frcsr t0 + SREG t0, 39 * REGBYTES(sp) /* save fcsr */ +#endif +#endif + +#ifdef NOS_TASK_SUPPORT + LREG a2, 6 * REGBYTES(sp) + bnez a2, IrqCallback /* Should determine whether need to switch stack */ + csrw mscratch, sp + la sp, __irq_stack_top - 16 + +IrqCallback: + addi sp, sp, -4 * REGBYTES + SREG a2, 0 * REGBYTES(sp) /* save prithd in irq stack */ + andi a0, a0, MCAUSE_MASK_INT_NUM + la a1, IrqCallbackNew /* When using NOS_TASK_SUPPORT, enable gloal irq after change to irq stack */ + csrw mepc, a1 + mret + +IrqCallbackNew: + call InterruptEntry + li a2, 0x8 + csrrc zero, mstatus, a2 /* When using NOS_TASK_SUPPORT, disable gloal irq before any stack operation */ + LREG a2, 0 * REGBYTES(sp) /* restore prithd in irq stack */ + addi sp, sp, 4 * REGBYTES + + bnez a2, BacktoIrq + csrr sp, mscratch + tail NOS_HwiPostDispatch /* Should determine whether need to reschedule */ +#else + andi a0, a0, MCAUSE_MASK_INT_NUM + call InterruptEntry +#endif + +BacktoIrq: + LREG t1, 1 * REGBYTES(sp) + LREG t2, 2 * REGBYTES(sp) + LREG a2, 5 * REGBYTES(sp) + LREG ra, 9 * REGBYTES(sp) + LREG a3, 10 * REGBYTES(sp) + LREG a4, 11 * REGBYTES(sp) + LREG a5, 12 * REGBYTES(sp) + LREG a6, 13 * REGBYTES(sp) + LREG a7, 14 * REGBYTES(sp) + LREG t3, 15 * REGBYTES(sp) + LREG t4, 16 * REGBYTES(sp) + LREG t5, 17 * REGBYTES(sp) + LREG t6, 18 * REGBYTES(sp) +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to restore TickIRQEnable */ + LREG t0, 19 * REGBYTES(sp) + andi t0, t0, TICK_IRQ_EN_NUM + csrs TICK_IRQ_EN_BASE, t0 +#endif + +#ifdef FLOAT_SUPPORT +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to save TickIRQEnable */ + FLREG f0, 23 * REGBYTES(sp) + FLREG f1, 24 * REGBYTES(sp) + FLREG f2, 25 * REGBYTES(sp) + FLREG f3, 26 * REGBYTES(sp) + FLREG f4, 27 * REGBYTES(sp) + FLREG f5, 28 * REGBYTES(sp) + FLREG f6, 29 * REGBYTES(sp) + FLREG f7, 30 * REGBYTES(sp) + FLREG f10, 31 * REGBYTES(sp) + FLREG f11, 32 * REGBYTES(sp) + FLREG f12, 33 * REGBYTES(sp) + FLREG f13, 34 * REGBYTES(sp) + FLREG f14, 35 * REGBYTES(sp) + FLREG f15, 36 * REGBYTES(sp) + FLREG f16, 37 * REGBYTES(sp) + FLREG f17, 38 * REGBYTES(sp) + FLREG f28, 39 * REGBYTES(sp) + FLREG f29, 40 * REGBYTES(sp) + FLREG f30, 41 * REGBYTES(sp) + FLREG f31, 42 * REGBYTES(sp) + LREG t0, 43 * REGBYTES(sp) + fscsr t0 +#else + FLREG f0, 19 * REGBYTES(sp) + FLREG f1, 20 * REGBYTES(sp) + FLREG f2, 21 * REGBYTES(sp) + FLREG f3, 22 * REGBYTES(sp) + FLREG f4, 23 * REGBYTES(sp) + FLREG f5, 24 * REGBYTES(sp) + FLREG f6, 25 * REGBYTES(sp) + FLREG f7, 26 * REGBYTES(sp) + FLREG f10, 27 * REGBYTES(sp) + FLREG f11, 28 * REGBYTES(sp) + FLREG f12, 29 * REGBYTES(sp) + FLREG f13, 30 * REGBYTES(sp) + FLREG f14, 31 * REGBYTES(sp) + FLREG f15, 32 * REGBYTES(sp) + FLREG f16, 33 * REGBYTES(sp) + FLREG f17, 34 * REGBYTES(sp) + FLREG f28, 35 * REGBYTES(sp) + FLREG f29, 36 * REGBYTES(sp) + FLREG f30, 37 * REGBYTES(sp) + FLREG f31, 38 * REGBYTES(sp) + LREG t0, 39 * REGBYTES(sp) /* restore fcsr */ + fscsr t0 +#endif +#endif + +quit_int: + /* + * Since the interrupt is already turned off when loading mstatus (after entering the interrupt, + * the hardware will turn off the interrupt, so when saving mstatus, the interrupt is already turned off), + * so there is no need to turn off the interrupt separately. + */ + +#if defined(HARD_NESTED_IRQ_SUPPORT) && (HARD_NESTED_IRQ_SUPPORT == 1) + LREG t0, 0 * REGBYTES(sp) +#else + LREG a0, 7 * REGBYTES(sp) /* load mstatus */ + LREG a1, 8 * REGBYTES(sp) /* load mepc */ +#ifndef NOS_TASK_SUPPORT /* When using NOS_TASK_SUPPORT, don't check mstatus */ + csrr t0, mstatus + andi t0, t0, MSTATUS_MIE + bnei t0, 0, restore_mstatus + andi a0, a0, ~(MSTATUS_MIE | MSTATUS_MPIE) +#endif +restore_mstatus: + csrw mstatus, a0 + + LREG t0, 0 * REGBYTES(sp) + csrw mepc, a1 + LREG a0, 6 * REGBYTES(sp) /* load prithd */ + csrw prithd, a0 +#endif + +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) + la a0, g_RiscvPrivMode + lw a1, (a0) + addi a1, a1, -1 + sw a1, (a0) +#endif + + LREG a1, 4 * REGBYTES(sp) /* 2 consecutive csrw instructions will have a bubble */ + + LREG a0, 3 * REGBYTES(sp) + + addi sp, sp, TOTAL_INT_SIZE_ON_STACK + + mret + +.align 2 +TrapVector: + +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to check mcause == ecall and a0 = magic word for taskSwitch */ + addi sp, sp, -8 + SREG a1, 0(sp) + SREG a2, 4(sp) + csrr a1, mcause + li a2, MCAUSE_ECALL_FROM_MMODE + bne a1, a2, IsTrap + li a2, NOS_TASK_SWITCH_MAGIC_NUM + bne a0, a2, IsTrap + LREG a2, 4(sp) + LREG a1, 0(sp) + addi sp, sp, 8 + tail NOS_TaskDispatch + +IsTrap: + LREG a2, 4(sp) + LREG a1, 0(sp) + addi sp, sp, 8 +#endif + + push_reg + csrr a0, mcause + li t1, MCAUSE_ECALL_FROM_MMODE +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) + beq a0, t1, switch_to_umode +#else + beq a0, t1, switch_to_mmode +#endif + li t1, MCAUSE_ECALL_FROM_UMODE + beq a0, t1, switch_to_mmode + + li a1, MCAUSE_MASK_INT_BIT + li a2, MCAUSE_MASK_INT_NUM + and a1, a0, a1 + and a0, a0, a2 + + li a2, 0xc + beq a0, a2, NmiEntry + beqz a1, TrapEntry + pop_reg + mret + +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) +.align 2 +switch_to_umode: + li t2, MSTATUS_MPP_MACHINE + csrc mstatus, t2 + csrr t0, mepc + addi t0, t0, 4 + csrw mepc, t0 + pop_reg + mret +#endif + +.align 2 +switch_to_mmode: + li t2, MSTATUS_MPP_MACHINE + csrs mstatus, t2 + csrr t0, mepc + addi t0, t0, 4 + csrw mepc, t0 + pop_reg + mret + +.align 2 +mem_cpy: + bge t0, t2, cpy_done + lw t3, (t1) + sw t3, (t0) + addi t0, t0, 4 + addi t1, t1, 4 + j mem_cpy +cpy_done: + ret + +.align 2 +handle_reset: + csrwi mstatus, 0 + csrwi mie, 0 + csrci mstatus, 0x08 + la t0, TrapHandler + addi t0, t0, 1 + csrw mtvec, t0 + +#ifndef UNLOCK_MTVEC /* When using UNLOCK_MTVEC, don't lock mtvec register. */ + csrwi 0x7EF, 0x1 /* lock mtvec */ +#endif + +#if defined(HARD_NESTED_IRQ_SUPPORT) && (HARD_NESTED_IRQ_SUPPORT == 1) + csrwi 0x7C8, 0x1 /* enable hardware nest interrupt support */ +#endif + +flash_init: +/* eflash prefetch enable */ + li t0, EFC_BASE_ADDR + lw t1, 0x120(t0) + ori t1, t1, 1 + sw t1, 0x120(t0) + +/* eflash cache enable */ + lw t1, 0x124(t0) + ori t1, t1, 1 + sw t1, 0x124(t0) + +/* enable flash cmd */ + li t0, EFC_MAGIC_NUMBER + li t1, EFC_MAGIC_LOCK_RW + sw t0, (t1) + +/* initialize global pointer */ + .option push + .option norelax + la gp, __global_pointer$ + .option pop + +/* initialize stack pointer */ +#ifdef NOS_TASK_SUPPORT /* Support Multi-task needs to use irq stack */ + la sp, __init_stack_top +#else + la sp, __stack_top +#endif + +/* perform the rest of initialization in C */ +clear_sram: + /* clear sysram parity error */ + li t0, SYSRAM_ERROR + lw t1, (t0) + ori t1, t1, 1 + sw t1, (t0) + + la t0, SRAM_START + la t1, SRAM_END + li t2, 0 + +clear_sram_loop: + sw t2, (t0) /* clear all sram */ + addi t0, t0, 4 /* increment clear index pointer */ + blt t0, t1, clear_sram_loop /* are we at the end yet, if not , contiue till the end */ + +start_coderom_code_copy: + la t0, __sram_code_start_addr /* SRAM addr */ + la t1, __sram_code_load_addr /* ROM addr */ + la t2, __sram_code_end_addr + jal mem_cpy + +start_reserved_data_copy: + la t0, __reserved_code_start_addr /* SRAM addr */ + la t1, __reserved_code_load_addr /* ROM addr */ + la t2, __reserved_code_end_addr + jal mem_cpy + +start_coderom_data_copy: + la t0, __data_start /* SRAM addr */ + la t1, __data_load /* ROM addr */ + la t2, __data_end + jal mem_cpy + +stack_sram_bound_data_copy: + la t0, __stack_sram_bound_data_start /* SRAM addr */ + la t1, __stack_sram_bound_data_load /* ROM addr */ + la t2, __stack_sram_bound_data_end + jal mem_cpy + +pmp_init: + li t0, 0xB00 + csrw pmpaddr0, t0 + li t0, 0x400400 /* 0x2C00~0x1000FFF, BOOTROM, enable R+X */ + csrw pmpaddr1, t0 + li t0, 0x800000 /* 0x1001000~0x1FFFFFF, Reserved: disable R+X+W */ + csrw pmpaddr2, t0 + li t0, 0x804000 /* 0x2000000~0x200FFFF, SYSRAM_ITCM */ + csrw pmpaddr3, t0 + li t0, 0xC00000 /* 0x2008000 ~ 0x2FFFFFF, Reserved: disable R+X+W */ + csrw pmpaddr4, t0 + li t0, 0x1000000 /* 0x3000000 ~ 0x03FFFFFF: EFLASH: enable R+X */ + csrw pmpaddr5, t0 + li t0, 0x1002000 /* 0x4000000 ~ 0x04007FFF: SYSTEM_DTCM enable R+W */ + csrw pmpaddr6, t0 + li t0, 0x7000400 /* 0x4008000 ~ 0x01C000FFF: REGISTER R+W */ + csrw pmpaddr7, t0 + + li t0,0xf3333333 /* register TOR-R-W */ + csrw 0x7d8,t0 +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) + li t0,0x0d080d8b /* 0x0d:TOR-R-X; 0x0b:TOR-R-W; 0x08:TOR; 0x0c:TOR-x; 0x09:TOR-R */ + csrw pmpcfg0,t0 + li t0,0x0b0b0d08 + csrw pmpcfg1,t0 +#else + li t0, 0x8F888D8B/* 0x0d:TOR-R-X; 0x0b:TOR-R-W; 0x08:TOR; 0x0c:TOR-x; 0x09:TOR-R */ + csrw pmpcfg0,t0 + li t0,0x8b8b8d88 + csrw pmpcfg1,t0 +#endif + +/* support float and mie */ + li t0,0x2008 + csrs mstatus,t0 + li t0,0x20 + csrs misa,t0 + +/* Interrupt set default priority = 1*/ + li t0, 0x11111111 + csrw locipri0, t0 + csrw locipri1, t0 + csrw locipri2, t0 + csrw locipri3, t0 + csrw locipri4, t0 + csrw locipri5, t0 + csrw locipri6, t0 + csrw locipri7, t0 + csrw locipri8, t0 + csrw locipri9, t0 + csrw locipri10, t0 + csrw locipri11, t0 + csrw locipri12, t0 + csrw locipri13, t0 + csrw locipri14, t0 + csrw locipri15, t0 + + ecall + +#ifdef NOS_TASK_SUPPORT + jal Chip_Init +#else + jal Chip_Init + +/* jump to C func. */ + jal main +#endif + +dead_loop: + j dead_loop + +#endif diff --git a/src/chip/3066m/sysctrl.h b/src/chip/3066m/sysctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..ddb5aa93c358a0e3d7f587971f78f0ed2dbcc2ca --- /dev/null +++ b/src/chip/3066m/sysctrl.h @@ -0,0 +1,665 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file sysctrl.h + * @author MCU Driver Team + * @brief This file provides firmware functions to manage the following + * functionalities of the system control register. + * + Register Struct of SYSCTRL + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSCTRL_H +#define McuMagicTag_SYSCTRL_H + +/* Includes ------------------------------------------------------------------ */ +#include "baseaddr.h" +#include "typedefs.h" + +/* Macro definitions ---------------------------------------------------------*/ +#define SC_LOCKEN_VALID_HIGH_BIT 0xEA510000U /**< Upper 16 active bits of the SC_LOCKEN register */ +#define SC_LOW_BIT_MASK 0x0000FFFFU /**< Obtains the mask of the lower 16 bits. */ +#define SC_LOCKEN_CRG_DISABLE_MASK 0x0000FFFEU /**< CRG write protection disable mask in SC_LOCKEN */ +#define SC_LOCKEN_CRG_ENABLE_MASK 0x00000001U /**< CRG write protection enable mask in SC_LOCKEN */ +#define SC_LOCKEN_SC_DISABLE_MASK 0x0000FFFDU /**< SC write protection disable mask in SC_LOCKEN */ +#define SC_LOCKEN_SC_ENABLE_MASK 0x00000002U /**< SC write protection enbale mask in SC_LOCKEN */ + + +/** + * @brief Records the offsets of various states in the CPU status register. + */ +typedef enum { + SYSCTRL_NMI_BIT = 0x00000000U, + SYSCTRL_LOCKUP_BIT = 0x00000002U, + SYSCTRL_HARD_FAULT_BIT = 0x00000003U, + SYSCTRL_DEBUG_BIT = 0x00000004U, + SYSCTRL_SLEEP_BIT = 0x00000005U, + SYSCTRL_PC_VALID_BIT = 0x0000001FU +} SYSCTRL_CPU_Status; + +/** + * @brief FUNC_JTAG_SEL_REG register function item. + */ +typedef enum { + SYSCTRL_FUNC_JTAG_CORESIGHT = 0x00000000U, + SYSCTRL_FUNC_JYAG_EFLASH = 0x00000001U +} SYSCTRL_FUNC_JTAG_Status; + +/** + * @brief REMAP_MODE register function item. + */ +typedef enum { + SYSCTRL_REMAP_MODE0 = 0x00000000U, + SYSCTRL_REMAP_MODE1 = 0x00000001U, + SYSCTRL_REMAP_MODE2 = 0x00000002U, + SYSCTRL_REMAP_MODE3 = 0x00000003U, +} SYSCTRL_RemapMode; + + +/** + * @brief System soft reset register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int softresreq : 1; /**< Set any value to make system soft reset. */ + unsigned int reserved : 31; + } BIT; +} volatile SC_SYS_RES_REG; + +/** + * @brief Record the number of resets(soft reset, pin reset). + */ +typedef union { + unsigned int reg; + struct { + unsigned int soft_rst_cnt : 16; /**< Number of soft resets. */ + unsigned int ext_rst_cnt : 16; /**< Number of reset times of the RESETN pin. */ + } BIT; +} volatile SC_RST_CNT0_REG; + +/** + * @brief Record the number of resets(wdg reset, iwdg reset). + */ +typedef union { + unsigned int reg; + struct { + unsigned int wdg_rst_cnt : 16; /**< Number of WDG resets. */ + unsigned int iwdg_rst_cnt : 16; /**< Number of IWDG resets. */ + } BIT; +} volatile SC_RST_CNT1_REG; + +/** + * @brief System status register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int update_mode_clear : 1; /**< System upgrade flag clear register, 0:not clear, 1:clear. */ + unsigned int reserved0 : 3; + unsigned int update_mode : 1; /**< System upgrade flag, 0:not upgrade, 1:upgrade. */ + unsigned int reserved1 : 27; + } BIT; +} volatile SC_SYS_STAT_REG; + +/** + * @brief Software interrupt register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int software_int : 1; /**< Software interrupt register, writing 1 generates a software interrupt. */ + unsigned int reserved : 31; + } BIT; +} volatile SC_SOFT_INT_REG; + +/** + * @brief Software interrupt event ID register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int swint_evt_id : 32; /**< Software interrupt event ID. */ + } BIT; +} volatile SC_SOFT_EVT_ID_REG; + +/** + * @brief Lock register of key registers. + */ +typedef union { + unsigned int reg; + struct { + unsigned int crg_cfg_lock : 1; /**< Write protection for CRG, 0: write enabled, 1: write disabled. */ + unsigned int sc_cfg_lock : 1; /**< Write protection for SYSCTRL, 0: write enabled, 1: write disabled. */ + unsigned int reserved : 30; + } BIT; +} volatile SC_LOCKEN_REG; + +/** + * @brief SC dedicated hard reset register 0. (CH) This register is not reset by a system soft reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int sc_hrst_reg0 : 32; /**< If the value is 0xA5A5A5, the CPU stops starting the system. */ + } BIT; +} volatile SC_HRST_REG0_REG; + +/** + * @brief User dedicated hard reset register 0. (CH) This register is not reset by a system soft reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_hrst_reg0 : 32; /**< User-dedicated hard reset register 0. */ + } BIT; +} volatile USER_HRST_REG0_REG; + +/** + * @brief User dedicated hard reset register 1. (CH) This register is not reset by a system soft reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_hrst_reg1 : 32; /**< User-dedicated hard reset register 1. */ + } BIT; +} volatile USER_HRST_REG1_REG; + +/** + * @brief User dedicated POR reset register 0. (CH) This register is reset only by a POR reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_por_reg0 : 32; /**< User dedicated POR reset register 0. */ + } BIT; +} volatile USER_POR_REG0_REG; + +/** + * @brief User dedicated POR reset register 1. (CH) This register is reset only by a POR reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_por_reg1 : 32; /**< User dedicated POR reset register 1. */ + } BIT; +} volatile USER_POR_REG1_REG; + +/** + * @brief User dedicated register 0. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_reg0 : 32; /**< User dedicated register 0. */ + } BIT; +} volatile USER_REG0_REG; + +/** + * @brief User dedicated register 1. + */ +typedef union { + unsigned int reg; + struct { + unsigned int user_reg1 : 32; /**< User dedicated register 1. */ + } BIT; +} volatile USER_REG1_REG; + +/** + * @brief SYSCTRL0 register. + */ +typedef struct _SYSCTRL0_Regstruct { + char space0[4]; + SC_SYS_RES_REG SC_SYS_RES; /**< System soft reset register, offset address: 0x0004. */ + SC_RST_CNT0_REG SC_RST_CNT0; /**< Reset count register 0, offset address: 0x0008. */ + SC_RST_CNT1_REG SC_RST_CNT1; /**< Reset count register 1, offset address: 0x000C. */ + char space1[8]; + SC_SYS_STAT_REG SC_SYS_STAT; /**< System boot mode register, offset address: 0x0018. */ + char space2[4]; + SC_SOFT_INT_REG SC_SOFT_INT; /**< Software interrupt register, offset address: 0x0020. */ + SC_SOFT_EVT_ID_REG SC_SOFT_EVT_ID; /**< Software interrupt event ID register, offset address: 0x0024. */ + char space3[28]; + SC_LOCKEN_REG SC_LOCKEN; /**< Lock register of key registers, offset address: 0x0044. */ + char space4[440]; + SC_HRST_REG0_REG SC_HRST_REG0; /**< SC dedicated hard reset register 0, offset address: 0x0200. */ + char space5[3068]; + USER_POR_REG0_REG USER_POR_REG0; /**< User dedicated POR reset register 0, offset address: 0x0E00. */ + USER_POR_REG1_REG USER_POR_REG1; /**< User dedicated POR reset register 1, offset address: 0x0E04. */ + char space6[56]; + USER_HRST_REG0_REG USER_HRST_REG0; /**< User dedicated hard reset register 0, offset address: 0x0E40. */ + USER_HRST_REG1_REG USER_HRST_REG1; /**< User dedicated hard reset register 1, offset address: 0x0E44. */ + char space7[56]; + USER_REG0_REG USER_REG0; /**< User dedicated register 0, offset address: 0x0E80. */ + USER_REG1_REG USER_REG1; /**< User dedicated register 1, offset address: 0x0E84. */ +} volatile SYSCTRL0_RegStruct; + +/** + * @brief APT enable register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int apt0_run : 1; /**< APT0 enable control, 0:enable, 1:enable. */ + unsigned int apt1_run : 1; /**< APT1 enable control, 0:enable, 1:enable. */ + unsigned int apt2_run : 1; /**< APT2 enable control, 0:enable, 1:enable. */ + unsigned int apt3_run : 1; /**< APT3 enable control, 0:enable, 1:enable. */ + unsigned int apt4_run : 1; /**< APT4 enable control, 0:enable, 1:enable. */ + unsigned int apt5_run : 1; /**< APT5 enable control, 0:enable, 1:enable. */ + unsigned int apt6_run : 1; /**< APT6 enable control, 0:enable, 1:enable. */ + unsigned int apt7_run : 1; /**< APT7 enable control, 0:enable, 1:enable. */ + unsigned int apt8_run : 1; /**< APT8 enable control, 0:enable, 1:enable. */ + unsigned int reserved : 23; + } BIT; +} volatile APT_RUN_REG; + +/** + * @brief Poe filter register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int poe0_filter_level : 8; /**< Number of POE0 Filter Cycles. */ + unsigned int poe1_filter_level : 8; /**< Number of POE1 Filter Cycles. */ + unsigned int poe2_filter_level : 8; /**< Number of POE2 Filter Cycles. */ + unsigned int poe0_filter_en : 1; /**< POE0 filter enable, 0:enable, 1:enable. */ + unsigned int poe1_filter_en : 1; /**< POE1 filter enable, 0:enable, 1:enable. */ + unsigned int poe2_filter_en : 1; /**< POE2 filter enable, 0:enable, 1:enable. */ + unsigned int reserved : 5; + } BIT; +} volatile APT_POE_FILTER_REG; + +/** + * @brief APT_EVTIO_FILTER register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int apt_evtio4_filter_level : 8; /**< Number of APT EVTIO4 Filter Cycles. */ + unsigned int apt_evtio5_filter_level : 8; /**< Number of APT EVTIO5 Filter Cycles. */ + unsigned int reserved0 : 8; + unsigned int apt_evtio4_filter_en : 1; /**< APT EVTIO4 FILTER enable, 0:enable, 1:enable. */ + unsigned int apt_evtio5_filter_en : 1; /**< APT EVTIO5 FILTER enable, 0:enable, 1:enable. */ + unsigned int reserved1 : 6; + } BIT; +} volatile APT_EVTIO_FILTER_REG; + +/** + * @brief APT_EVTMP_FILTER register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int apt_evtmp4_filter_level : 8; /**< Number of APT EVTMP4 Filter Periods. */ + unsigned int apt_evtmp5_filter_level : 8; /**< Number of APT EVTMP5 Filter Periods. */ + unsigned int apt_evtmp6_filter_level : 8; /**< Number of APT EVTMP6 Filter Periods. */ + unsigned int apt_evtmp4_filter_en : 1; /**< APT EVTMP4 FILTER enable, 0:enable, 1:enable. */ + unsigned int apt_evtmp5_filter_en : 1; /**< APT EVTMP5 FILTER enable, 0:enable, 1:enable. */ + unsigned int apt_evtmp6_filter_en : 1; /**< APT EVTMP6 FILTER enable, 0:enable, 1:enable. */ + unsigned int reserved : 5; + } BIT; +} volatile APT_EVTMP_FILTER_REG; + +/** + * @brief XTAL_CFG register. + * + */ +typedef union { + unsigned int reg; + struct { + unsigned int osc_ds : 4; /**< Crystal I/O Drive Capability Configuration. */ + unsigned int ose_e : 1; /**< Crystal I/O resonance buffer enable, 0:disable, 1:enable. */ + unsigned int osc_ie : 1; /**< Crystal I/O clock input enable, 0:disable, 1:enable. */ + unsigned int reserved : 26; + } BIT; +} volatile XTAL_CFG_REG; + +/** + * @brief Dma request selection register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 8; + unsigned int dma_req8_sel : 1; /**< DMA8 request section, 0:unselect, 1:select. */ + unsigned int dma_req9_sel : 1; /**< DMA9 request section, 0:unselect, 1:select. */ + unsigned int dma_req10_sel : 1; /**< DMA10 request section, 0:unselect, 1:select. */ + unsigned int dma_req11_sel : 1; /**< DMA11 request section, 0:unselect, 1:select. */ + unsigned int dma_req12_sel : 1; /**< DMA12 request section, 0:unselect, 1:select. */ + unsigned int reserved1 : 19; + } BIT; +} volatile DMA_REQ_SEL_REG; + +/** + * @brief Sysram parity check register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int sysram_parity_err_clr : 1; /**< SYSRAM parity error status clear, write any value to clear. */ + unsigned int sysram0_parity_err : 1; /**< SYSRAM Parity Error Status, 0:no error, 1:error. */ + unsigned int sysram1_parity_err : 1; /**< SYSRAM Parity Error Status, 0:no error, 1:error. */ + unsigned int reserved : 29; + } BIT; +} volatile SYSRAM_ERR_REG; + +/** + * @brief Remap config register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int remap_en : 1; /**< Address remap enable, 0:disable, 1:enable. */ + unsigned int remap_mode : 2; /**< Address remap mode, 0:4kb, 1:8kb, 2:128kb, 3:256kb. */ + unsigned int reserved1 : 29; + } BIT; +} volatile REMAP_CFG_REG; + +/** + * @brief TCM_STATUS register. + * + */ +typedef union { + unsigned int reg; + struct { + unsigned int sysram_secure_access_err : 1; /**< SYSRAM DTCM Security Access Status, 0:legal, 1:illegal. */ + unsigned int flash_secure_access_err : 1; /**< FLASH DTCM secure access status. */ + unsigned int reserved0 : 6; + unsigned int sysram_secure_access_err_clr : 1; /**< SYSRAM DTCM Security Access Status. write 1 clear error */ + unsigned int flash_secure_access_err_clr : 1; /**< FLASH DTCM secure access status. write 1 clear error */ + unsigned int reserved1 : 22; + } BIT; +} volatile TCM_STATUS_REG; + +/** + * @brief PVD_STATUS register. + * + */ +typedef union { + unsigned int reg; + struct { + unsigned int pvd_toggle : 1; /**< PVD triggering flag. */ + unsigned int reserved : 31; + } BIT; +} volatile PVD_STATUS_REG; + +/** + * @brief CPU status register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 2; + unsigned int cpu_lockup_mode : 1; /**< CPU LOCKUP status. 0: non-lockup state, 1: lockup state. */ + unsigned int cpu_hard_fault_mode : 1; /**< Indicates the hard fault status of the CPU. 0: non-hard_fault state, + 1: hard_fault. */ + unsigned int cpu_debug_mode : 1; /**< Indicates the CPU debug status. 0: non-debug state, + 1: debug state. */ + unsigned int cpu_sleep_mode : 1; /**< CPU sleep status. 0: non-sleep state, 1: sleep state. */ + unsigned int reserved1 : 25; + unsigned int cpu_pc_valid : 1; /**< Valid status of the CPU PC value. 0: The PC value is invalid, + 1: The PC value is valid. */ + } BIT; +} volatile CPU_STATUS_REG; + +/** + * @brief SYSCTRL1 register. + */ +typedef struct _SYSCTRL1_RegStruct { + char space0[0x8000]; + APT_RUN_REG APT_RUN; /**< APT enable control register, offset address: 0x8000. */ + char space1[12]; + APT_POE_FILTER_REG APT_POE_FILTER; /**< APT PoE filtering control register, offset address: 0x8010. */ + APT_EVTIO_FILTER_REG APT_EVTIO_FILTER; /**< APT EVTIO filtering control register, offset address: 0x8014. */ + APT_EVTMP_FILTER_REG APT_EVTMP_FILTER; /**< APT EVTMP filtering control register, offset address: 0x8018. */ + char space2[228]; + XTAL_CFG_REG XTAL_CFG; /**< Crystal I/O control register, offset address: 0x8100. */ + char space3[252]; + DMA_REQ_SEL_REG DMA_REQ_SEL; /**< DMA request selection register, offset address: 0x8200. */ + char space4[252]; + SYSRAM_ERR_REG SYSRAM_ERR; /**< SYSRAM parity check status register, offset address: 0x8300. */ + char space5[4]; + REMAP_CFG_REG REMAP_CFG; /**< REMAP config register, offset address: 0x8308. */ + TCM_STATUS_REG TCM_STATUS; /**< TCM status register, offset address: 0x830c. */ + char space6[244]; + PVD_STATUS_REG PVD_STATUS; /**< PVD status register, offset address: 0x8404. */ + char space7[3064]; + CPU_STATUS_REG CPU_STATUS; /**< CPU status register, offset address: 0x9000. */ +} volatile SYSCTRL1_RegStruct; + +/** + * @brief Make system soft reset. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_SoftReset(void) +{ + SYSCTRL0->SC_SYS_RES.BIT.softresreq = 1; +} + +/** + * @brief Get number of soft resets. + * @param None + * @retval Number of soft resets. + */ +static inline unsigned short DCL_SYSCTRL_GetSoftResetConut(void) +{ + return SYSCTRL0->SC_RST_CNT0.BIT.soft_rst_cnt; +} + +/** + * @brief Get number of reset times of the RESETN pin. + * @param None + * @retval Number of reset times of the RESETN pin. + */ +static inline unsigned short DCL_SYSCTRL_GetPinResetConut(void) +{ + return SYSCTRL0->SC_RST_CNT0.BIT.ext_rst_cnt; +} + +/** + * @brief Get number of WDG resets. + * @param None + * @retval Number of WDG resets. + */ +static inline unsigned short DCL_SYSCTRL_GetWdgResetConut(void) +{ + return SYSCTRL0->SC_RST_CNT1.BIT.wdg_rst_cnt; +} + +/** + * @brief Get number of IWDG resets. + * @param None + * @retval Number of IWDG resets. + */ +static inline unsigned short DCL_SYSCTRL_GetIWdgResetConut(void) +{ + return SYSCTRL0->SC_RST_CNT1.BIT.iwdg_rst_cnt; +} + +/** + * @brief Set the write protection for SYSCTRL registers disable. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_ScWriteProtectionDisable(void) +{ + /* Set the corresponding bit without affecting the other bits and set the high 16 bits to EA51 to write to. */ + SYSCTRL0->SC_LOCKEN.reg = (SYSCTRL0->SC_LOCKEN.reg & SC_LOCKEN_SC_DISABLE_MASK) + SC_LOCKEN_VALID_HIGH_BIT; +} + +/** + * @brief Set the write protection for SYSCTRL registers enable. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_ScWriteProtectionEnable(void) +{ + /* Set the corresponding bit without affecting the other bits and set the high 16 bits to EA51 to write to. */ + SYSCTRL0->SC_LOCKEN.reg = ((SYSCTRL0->SC_LOCKEN.reg & SC_LOW_BIT_MASK) | SC_LOCKEN_SC_ENABLE_MASK) + + SC_LOCKEN_VALID_HIGH_BIT; +} + +/** + * @brief Set the write protection for CRG-related registers disable. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_CrgWriteProtectionDisable(void) +{ + /* Set the corresponding bit without affecting the other bits and set the high 16 bits to EA51 to write to. */ + SYSCTRL0->SC_LOCKEN.reg = (SYSCTRL0->SC_LOCKEN.reg & SC_LOCKEN_CRG_DISABLE_MASK) + SC_LOCKEN_VALID_HIGH_BIT; +} + +/** + * @brief Set the Set the write protection for CRG-related registers enable. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_CrgWriteProtectionEnable(void) +{ + /* Set the corresponding bit without affecting the other bits and set the high 16 bits to EA51 to write to. */ + SYSCTRL0->SC_LOCKEN.reg = ((SYSCTRL0->SC_LOCKEN.reg & SC_LOW_BIT_MASK) | SC_LOCKEN_CRG_ENABLE_MASK) + + SC_LOCKEN_VALID_HIGH_BIT; +} + +/** + * @brief Set software interrupt register, writing 1 generates a software interrupt. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_GenerateSoftInterrupt(void) +{ + SYSCTRL0->SC_SOFT_INT.BIT.software_int = 1; +} + +/** + * @brief Clear software interrupt register, writing 0 generates a software interrupt. + * @param None + * @retval None. + */ +static inline void DCL_SYSCTRL_ClearSoftInterrupt(void) +{ + SYSCTRL0->SC_SOFT_INT.BIT.software_int = 0; +} + +/** + * @brief Set Software interrupt event ID. + * @param id the software interrupt event ID. + * @retval None. + */ +static inline void DCL_SYSCTRL_SetSoftInterruptEventId(unsigned int id) +{ + SYSCTRL0->SC_SOFT_EVT_ID.BIT.swint_evt_id = id; +} + +/** + * @brief Get Software interrupt event ID. + * @param None + * @retval The value of software interrupt event ID. + */ +static inline unsigned int DCL_SYSCTRL_GetSoftInterruptEventId(void) +{ + return SYSCTRL0->SC_SOFT_EVT_ID.BIT.swint_evt_id; +} + +/** + * @brief Get SYSRAM Parity Error Status. + * @param None. + * @retval 0:no error, 1:error. + */ +static inline unsigned int DCL_SYSCTRL_GetSysramParityErrorStatus(void) +{ + return SYSCTRL1->SYSRAM_ERR.BIT.sysram0_parity_err; +} + +/** + * @brief Set SYSRAM parity error status clear. + * @param None. + * @retval None. + */ +static inline void DCL_SYSCTRL_ClearSysramParityError(void) +{ + SYSCTRL1->SYSRAM_ERR.BIT.sysram_parity_err_clr = 1; /* Write any value to clear. */ +} + +/** + * @brief Get CPU status. + * @param offset Bit offset of CPU status. + * @retval true or false + */ +static inline bool DCL_SYSCTRL_CheckCpuStatus(SYSCTRL_CPU_Status offset) +{ + return ((SYSCTRL1->CPU_STATUS.reg) & (1 << offset)) == 0 ? false : true; +} + +/** + * @brief Enable Remap function. + * @param None. + * @retval None. + */ +static inline void DCL_SYSCTRL_EnableRemap(void) +{ + DCL_SYSCTRL_ScWriteProtectionDisable(); + SYSCTRL1->REMAP_CFG.BIT.remap_en = BASE_CFG_SET; + DCL_SYSCTRL_ScWriteProtectionEnable(); + /* Clear the CPU pipeline and complete address remapping. */ + __asm__ volatile("fence"); + __asm__ volatile("fence"); + __asm__ volatile("fence"); + __asm__ volatile("fence"); +} + +/** + * @brief Disable Remap function. + * @param None. + * @retval None. + */ +static inline void DCL_SYSCTRL_DisableRemap(void) +{ + DCL_SYSCTRL_ScWriteProtectionDisable(); + SYSCTRL1->REMAP_CFG.BIT.remap_en = BASE_CFG_UNSET; + DCL_SYSCTRL_ScWriteProtectionEnable(); + /* Clear the CPU pipeline and complete address remapping. */ + __asm__ volatile("fence"); + __asm__ volatile("fence"); + __asm__ volatile("fence"); + __asm__ volatile("fence"); +} + +/** + * @brief Set Remap mode. + * @param remap mode. + * @retval None. + */ +static inline void DCL_SYSCTRL_SetRemapMode(SYSCTRL_RemapMode mode) +{ + DCL_SYSCTRL_ScWriteProtectionDisable(); + SYSCTRL1->REMAP_CFG.BIT.remap_mode = mode; + DCL_SYSCTRL_ScWriteProtectionEnable(); +} + +/** + * @brief Get Remap mode. + * @param remap mode. + * @retval None. + */ +static inline SYSCTRL_RemapMode DCL_SYSCTRL_GetRemapMode(void) +{ + return SYSCTRL1->REMAP_CFG.BIT.remap_mode; +} + +#endif /* McuMagicTag_SYSCTRL_H */ \ No newline at end of file diff --git a/src/chip/3066m/systick.h b/src/chip/3066m/systick.h new file mode 100644 index 0000000000000000000000000000000000000000..b6549e88cfa99d348f05ee74940b45e175fae9d4 --- /dev/null +++ b/src/chip/3066m/systick.h @@ -0,0 +1,118 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file systick.h + * @author MCU Driver Team + * @brief SYSTICK module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the SYSTICK. + * + SYSTICK register mapping structure + * + Get SysTick counter + */ + + +#ifndef McuMagicTag_SYSTICK_H +#define McuMagicTag_SYSTICK_H + +/* Includes ------------------------------------------------------------------*/ +#include "baseaddr.h" +#include "systickinit.h" +#include "feature.h" +/** + * @addtogroup SYSTICK + * @{ + */ + +/** + * @defgroup SYSTICK_IP SYSTICK_IP + * @brief SYSTICK_IP: systick + * @{ + */ + +/** + * @defgroup SYSTICK_Param_Def SYSTICK Parameters Definition + * @brief Definition of SYSTICK configuration parameters. + * @{ + */ +#ifdef NOS_TASK_SUPPORT +#ifndef CFG_SYSTICK_TICKINTERVAL_US +#define CFG_SYSTICK_TICKINTERVAL_US 100 +#endif +unsigned int SYSTICK_GetTickInterval(void); +#endif + +#define SYSTICK_MAX_VALUE 0xFFFFFFFFUL + +/** + * @} + */ + +/** + * @brief SYSTICK control register structure. + */ +typedef union { + unsigned int reg; + struct { + unsigned int enable : 1; /**< Mtimer enable. */ + unsigned int clksrc : 1; /**< Mtimer clock source select. */ + unsigned int stop_tmr_en : 1; /**< Counting stop control in debugging mode. */ + unsigned int reserved : 29; + } BIT; +} TIMER_CTRL_REG; + +/** + * @brief SYSTICK DIV control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int div : 10; /**< Timer frequency division control. */ + unsigned int reserved : 22; + } BIT; +} TIMER_DIV_REG; + +/** + * @brief SYSTICK register structure + */ +typedef struct { + TIMER_CTRL_REG TIMER_CTRL; /**< Mtimer control register. Offset address: 0x00000000U. */ + TIMER_DIV_REG TIMER_DIV; /**< Mtimer frequency divider register. Offset address: 0x00000004U. */ + unsigned int MTIME; /**< Mtimer count value lower 32-bit register. Offset address: 0x00000008U. */ + unsigned int MTIME_H; /**< Upper 32-bit register for Mtimer count value. Offset address: 0x0000000CU. */ + unsigned int MTIMECMP; /**< Mtimer comparison value lower 32-bit register. Offset address: 0x00000010U. */ + unsigned int MTIMECMP_H; /**< Upper 32-bit Mtimer comparison value register. Offset address: 0x00000014U. */ +} volatile SYSTICK_RegStruct; + +/** + * @} + */ + +/** + * @brief Get the systick + * @param None + * @retval The SysTick Value + */ +static inline unsigned int DCL_SYSTICK_GetTick(void) +{ + return SYSTICK->MTIME; /* Systick value(Lower 32bit register) */ +} + +unsigned int SYSTICK_GetTimeStampUs(void); +/** + * @} + */ +#endif /* McuMagicTag_SYSTICK_H */ \ No newline at end of file diff --git a/src/chip/au/chipinit/chipinit.c b/src/chip/au/chipinit/chipinit.c index 690fa58d69736c35c62a804bf35dc4a768799455..ad952cba4a5a03d1ccc06635605389abc5222527 100644 --- a/src/chip/au/chipinit/chipinit.c +++ b/src/chip/au/chipinit/chipinit.c @@ -63,6 +63,7 @@ void Chip_Init(void) /* Config FLASH Clock */ FLASH_ClockConfig(coreClkSelect); + IRQ_Init(); SYSTICK_Init(); /* Set CoreClock Select after FLASH Config Done */ CRG_SetCoreClockSelect(coreClkSelect); @@ -71,9 +72,10 @@ void Chip_Init(void) if (HAL_CRG_GetCoreClkFreq() != HOSC_FREQ) { FLASH_WaitClockConfigDone(); } - - IRQ_Init(); - +#ifdef NOS_TASK_SUPPORT + /* Support IRQ to upload the totalCycle and detect the timeout lists */ + SYSTICK_IRQ_Enable(); +#endif ADC_InitVref(); TSENSOR_InitVrefList(); PGA_InitVref(); diff --git a/src/chip/au/chipinit/nosinit/nosinit.c b/src/chip/au/chipinit/nosinit/nosinit.c index 38dcd197144cd84c31a00ddabaa9a59a629bf2f9..722dcac760af0649763247b564b9cad72fb40502 100644 --- a/src/chip/au/chipinit/nosinit/nosinit.c +++ b/src/chip/au/chipinit/nosinit/nosinit.c @@ -20,7 +20,7 @@ * @brief nos init module. * @details nos initialization function during startup */ - +#include "feature.h" #ifdef NOS_TASK_SUPPORT #include "nos_task.h" #include "nosinit.h" @@ -36,7 +36,7 @@ unsigned char __attribute__((aligned(16))) g_taskMainStackSpace[CFG_NOS_MAINTASK static unsigned int g_nosSysFreq; // Get tick in real time -static unsigned long long NOS_GetTick() +static unsigned long long NOS_GetTick(void) { unsigned int cycle, cycleh; asm volatile("csrr %0, cycle" : "=r"(cycle)); @@ -65,7 +65,7 @@ void NOS_Init(void) param.taskEntry = (NOS_TaskEntryFunc)main; /* Set the entry function by user define */ param.param = 0; param.priority = NOS_TASK_PRIORITY_LOWEST; - param.stackAddr = g_taskMainStackSpace; + param.stackAddr = (unsigned int)g_taskMainStackSpace; param.stackSize = sizeof(g_taskMainStackSpace); param.privateData = 0; (void)NOS_TaskCreate(¶m, &taskId); diff --git a/src/chip/au/chipinit/nosinit/nosinit.h b/src/chip/au/chipinit/nosinit/nosinit.h index 81c83b4369c54cf8a41b184ee062e5fd8b4792d6..fa89d018048c5e7b0a4c49c36ca29c9dd4ebc906 100644 --- a/src/chip/au/chipinit/nosinit/nosinit.h +++ b/src/chip/au/chipinit/nosinit/nosinit.h @@ -21,6 +21,15 @@ * @details nos initialization function during startup */ +#ifndef NOS_INIT_H +#define NOS_INIT_H + +#include "feature.h" + #ifdef NOS_TASK_SUPPORT -int main(void); +extern int main(void); +extern void OsHwiDispatchTick(void); +void NOS_Init(void); +#endif + #endif \ No newline at end of file diff --git a/src/chip/au/chipinit/systickinit/systickinit.c b/src/chip/au/chipinit/systickinit/systickinit.c index 7f641067d7665995b36fe9d9bcf562e542e019c1..d7ba6471b8a35ccc5142939520530e3ffd8ea486 100644 --- a/src/chip/au/chipinit/systickinit/systickinit.c +++ b/src/chip/au/chipinit/systickinit/systickinit.c @@ -23,31 +23,38 @@ #include "baseaddr.h" #include "timer.h" #include "systick.h" -#include "systickinit.h" #include "crg.h" - -TIMER_Handle g_systickHandle; - +#include "systickinit.h" +#include "feature.h" #ifdef NOS_TASK_SUPPORT #include "interrupt.h" #include "systick.h" +#include "nosinit.h" +#endif + +TIMER_Handle g_systickHandle; +#ifdef NOS_TASK_SUPPORT #define NOS_TickPostDispatch OsHwiDispatchTick -void SYSTICK_Default_Callback(void) +static void SYSTICK_Default_Callback(void *handle) { /* The default systick callback when using th nos task */ - HAL_TIMER_IrqClear(&g_systickHandle); + BASE_FUNC_UNUSED(handle); NOS_TickPostDispatch(); } void SYSTICK_IRQ_Enable(void) { /* When Support NOS Task, Need to open the TickIRQ, us per tick will to update the load */ - g_systickHandle.irqNum = IRQ_TIMER3; + g_systickHandle.load = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + g_systickHandle.bgLoad = (HAL_CRG_GetIpFreq(SYSTICK_BASE) / CRG_FREQ_1MHz) * CFG_SYSTICK_TICKINTERVAL_US; + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_LOAD); /* config load value */ + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_BGLOAD); /* config bgLoad value */ g_systickHandle.interruptEn = BASE_CFG_ENABLE; - HAL_TIMER_RegisterCallback(&g_systickHandle, SYSTICK_Default_Callback); - HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_INTERRUPT); // enable the systickIRQ - IRQ_SetPriority(g_systickHandle.irqNum, 1); + HAL_TIMER_RegisterCallback(&g_systickHandle, TIMER_PERIOD_FIN, SYSTICK_Default_Callback); + HAL_TIMER_Config(&g_systickHandle, TIMER_CFG_INTERRUPT); /* enable the systickIRQ */ + IRQ_SetPriority(IRQ_TIMER3, 1); /* interrupt priority 1 */ + IRQ_Register(IRQ_TIMER3, HAL_TIMER_IrqHandler, &g_systickHandle); IRQ_EnableN(IRQ_TIMER3); } @@ -57,7 +64,7 @@ unsigned int SYSTICK_GetTickInterval(void) return CFG_SYSTICK_TICKINTERVAL_US; } -static inline unsigned int DCL_GetCpuCycle() +static inline unsigned int DCL_GetCpuCycle(void) { /* Get the Cpu Cycle Register(CSR) */ unsigned int cycle; @@ -99,7 +106,7 @@ unsigned int SYSTICK_GetTimeStampUs(void) * @param None * @retval None */ -void SYSTICK_Init() +void SYSTICK_Init(void) { /* Choose the config to support GetTick and Delay */ g_systickHandle.baseAddress = SYSTICK; diff --git a/src/chip/au/chipinit/systickinit/systickinit.h b/src/chip/au/chipinit/systickinit/systickinit.h index 7b7b1e0efd13e18d373f188b733768fd5ccf46bf..37588bdb5ec6e438ba646f440487f58d863cabe9 100644 --- a/src/chip/au/chipinit/systickinit/systickinit.h +++ b/src/chip/au/chipinit/systickinit/systickinit.h @@ -24,6 +24,11 @@ #ifndef McuMagicTag_SYSTICKINIT_H #define McuMagicTag_SYSTICKINIT_H +#include "feature.h" + void SYSTICK_Init(void); +#ifdef NOS_TASK_SUPPORT +void SYSTICK_IRQ_Enable(void); +#endif #endif \ No newline at end of file diff --git a/src/chip/au/codecopy.json b/src/chip/au/codecopy.json index 8827aa0e865d3dfb37f7c0bf15f171d2402fb84a..0454aa1284c26560d0eead355e5b69366d4b1893 100644 --- a/src/chip/au/codecopy.json +++ b/src/chip/au/codecopy.json @@ -16,7 +16,7 @@ "chip/au/systick.h", "chip/au/flash.lds", "chip/au/startup.S", - "chip/target", + "chip/target/userconfig_for_306xh.json", "drivers/debug", "generatecode", "middleware/control_library", diff --git a/src/chip/au/flash.lds b/src/chip/au/flash.lds index 4b8d720d508e4a1631217d0d253847331b06c4af..67a2f88ed338e08c373f9d4aa5596239fbce9eba 100644 --- a/src/chip/au/flash.lds +++ b/src/chip/au/flash.lds @@ -160,6 +160,7 @@ SECTIONS __data_load = LOADADDR(.data); __data_start = .; *(.data*) + *(.sdata*) . = ALIGN(4); __data_end = .; } > RAM_DATA AT> FLASH_CODE @@ -170,6 +171,7 @@ SECTIONS { __bss_begin__ = .; *(.bss*) + *(.sbss*) *(COMMON) . = ALIGN(4); __bss_end__ = .; diff --git a/src/chip/au/flashdefault.lds b/src/chip/au/flashdefault.lds new file mode 100644 index 0000000000000000000000000000000000000000..0fe0a41ea3c9628c9afbbf1b5156c84bc31499ee --- /dev/null +++ b/src/chip/au/flashdefault.lds @@ -0,0 +1,85 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flash.lds + * @author MCU Application Driver Team + * @brief RISCV flash link script + */ + +OUTPUT_ARCH( "riscv" ) + +SRAM_START = 0x4000000; +SRAM_END = 0x4000000 + 16K; + +RAM_CODE_START = 0x2000000; +RAM_CODE_SIZE = 0; + +RAM_START = SRAM_START; +RAM_END = SRAM_END; +RAM_SIZE = 16384; + +FLASH_START = 0x3000000; +FLASH_SIZE = 0x26000; + +MEMORY +{ + /* ram for code */ + RAM_CODE(xr) : ORIGIN = RAM_CODE_START, LENGTH = RAM_CODE_SIZE + /* ram for common bss and data */ + RAM_DATA(xrw) : ORIGIN = RAM_START + RAM_CODE_SIZE, LENGTH = RAM_SIZE + /* ram for target */ + FLASH_CODE(rx) : ORIGIN = FLASH_START, LENGTH = FLASH_SIZE +} + +SECTIONS +{ + .text : ALIGN(4) + { + __start_addr = .; + *(.text*) + *(.ram.text*) + . = ALIGN(4); + __rodata_start = .; + *(.rodata*) + . = ALIGN(4); + __rodata_end = .; + *(.got*) + __text_end = .; + } > FLASH_CODE + + /* data section */ + .data : ALIGN(4) + { + __data_load = LOADADDR(.data); + __data_start = .; + *(.data*) + *(.sdata*) + . = ALIGN(4); + __data_end = .; + } > RAM_DATA AT> FLASH_CODE + + /* bss section */ + .bss (NOLOAD) : ALIGN(4) + { + __bss_begin__ = .; + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM_DATA +} \ No newline at end of file diff --git a/src/chip/au/startup.S b/src/chip/au/startup.S index d32cdd64dc1067e2ee35143c361a08ef83657849..4e2a292288b0842d64fbe59c8a261c4ea696b239 100644 --- a/src/chip/au/startup.S +++ b/src/chip/au/startup.S @@ -767,6 +767,12 @@ coderom_data_copy: la t2, __data_end jal mem_cpy +stack_sram_bound_data_copy: + la t0, __stack_sram_bound_data_start /* SRAM addr */ + la t1, __stack_sram_bound_data_load /* ROM addr */ + la t2, __stack_sram_bound_data_end + jal mem_cpy + pmp_init: #if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) li t0, 0xB00 diff --git a/src/chip/au/sysctrl.h b/src/chip/au/sysctrl.h index 4a81ac4c28ac3de25ddea0c0107bb975801499b5..112e4efc6ffee87c62297ac0dc3078ee73074135 100644 --- a/src/chip/au/sysctrl.h +++ b/src/chip/au/sysctrl.h @@ -662,6 +662,15 @@ static inline void DCL_SYSCTRL_GenerateSoftInterrupt(void) { SYSCTRL0->SC_SOFT_INT.BIT.software_int = 1; } +/** + * @brief Clear software interrupt register, writing 0 clear software interrupt. + * @param None. + * @retval None. + */ +static inline void DCL_SYSCTRL_ClearSoftInterrupt(void) +{ + SYSCTRL0->SC_SOFT_INT.BIT.software_int = 0; +} /** * @brief Set Software interrupt event ID. diff --git a/src/chip/au/systick.h b/src/chip/au/systick.h index 1a72e8d430d5841cf8e16081208852e198626caa..172099f841784395fc44e9df1cc48ff2313b103d 100644 --- a/src/chip/au/systick.h +++ b/src/chip/au/systick.h @@ -29,7 +29,7 @@ #define McuMagicTag_SYSTICK_H /* Includes ------------------------------------------------------------------*/ - +#include "feature.h" /** * @addtogroup SYSTICK * @{ diff --git a/src/chip/target/userconfig_for_3061m.json b/src/chip/target/userconfig_for_3061m.json new file mode 100644 index 0000000000000000000000000000000000000000..d53592f509534964ba3453f7acbc449d6265e37c --- /dev/null +++ b/src/chip/target/userconfig_for_3061m.json @@ -0,0 +1,300 @@ +{ + "system": [ + { + "name": "compile", + "subsystem": [ + { + "name": "static_lib", + "component": [ + { + "name": "control_library_3061m", + "target_type": "static", + "sources": [ + "middleware/control_library/adc_calibr", + "middleware/control_library/brake", + "middleware/control_library/filter", + "middleware/control_library/foc_loop_ctrl", + "middleware/control_library/math", + "middleware/control_library/modulation", + "middleware/control_library/observer/mcs_fosmo.c", + "middleware/control_library/pfc", + "middleware/control_library/pid_controller", + "middleware/control_library/power", + "middleware/control_library/protection", + "middleware/control_library/ramp", + "middleware/control_library/utilities", + "middleware/control_library/vf" + ], + "includes": [ + "middleware/control_library", + "drivers", + "generatecode", + "chip" + ], + "define": [], + "libs": [], + "lds_scripts": [], + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ] + }, + { + "name": "function_safety_3061m", + "target_type": "static", + "sources": [ + "middleware/function_safety" + ], + "includes": [ + "middleware/function_safety", + "drivers", + "generatecode", + "chip" + ], + "define": [], + "libs": [], + "lds_scripts": [], + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ] + } + ] + }, + { + "name": "compile_frame", + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ], + "define": [ + "FLOAT_SUPPORT" + ], + "nocheck": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/chip/target/userconfig_for_3066m.json b/src/chip/target/userconfig_for_3066m.json new file mode 100644 index 0000000000000000000000000000000000000000..110c67f10c45d2c25a56803e33cdea05cddd6a83 --- /dev/null +++ b/src/chip/target/userconfig_for_3066m.json @@ -0,0 +1,312 @@ +{ + "system": [ + { + "name": "compile", + "subsystem": [ + { + "name": "static_lib", + "component": [ + { + "name": "", + "target_type": "static", + "sources": [], + "includes": [], + "define": [], + "libs": [], + "lds_scripts": [], + "cflags": [], + "asmflags": [], + "ldflags": [] + }, + { + "name": "control_library_3066m", + "target_type": "static", + "sources": [ + "middleware/control_library/adc_calibr", + "middleware/control_library/brake", + "middleware/control_library/filter", + "middleware/control_library/foc_loop_ctrl", + "middleware/control_library/math", + "middleware/control_library/modulation", + "middleware/control_library/observer/mcs_fosmo.c", + "middleware/control_library/pfc", + "middleware/control_library/pid_controller", + "middleware/control_library/power", + "middleware/control_library/protection", + "middleware/control_library/ramp", + "middleware/control_library/utilities", + "middleware/control_library/vf" + ], + "includes": [ + "middleware/control_library", + "drivers", + "generatecode", + "chip" + ], + "define": [], + "libs": [], + "lds_scripts": [], + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ] + }, + { + "name": "function_safety_3066m", + "target_type": "static", + "sources": [ + "middleware/function_safety" + ], + "includes": [ + "middleware/function_safety", + "drivers", + "generatecode", + "chip" + ], + "define": [], + "libs": [], + "lds_scripts": [], + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ] + } + ] + }, + { + "name": "compile_frame", + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ], + "define": [ + "FLOAT_SUPPORT" + ], + "nocheck": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/chip/target/userconfig_for_306xh.json b/src/chip/target/userconfig_for_306xh.json new file mode 100644 index 0000000000000000000000000000000000000000..e40ce098cd49e35d40f2f41f91f178389aec7b16 --- /dev/null +++ b/src/chip/target/userconfig_for_306xh.json @@ -0,0 +1,591 @@ +{ + "system": [ + { + "name": "compile", + "subsystem": [ + { + "name": "static_lib", + "component": [ + { + "name": "nostask", + "target_type": "static", + "sources": [ + "middleware/hisilicon/nostask" + ], + "includes": [ + "middleware/hisilicon/nostask" + ], + "define": [ + "OS_OPTION_306X" + ], + "libs": [], + "lds_scripts": [], + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ] + }, + { + "name": "mcs_smo_4th", + "target_type": "static", + "sources": [ + "middleware/control_library/observer/mcs_smo_4th.c" + ], + "includes": [ + "middleware/control_library", + "drivers/base", + "generatecode", + "chip" + ], + "define": [], + "libs": [], + "lds_scripts": [], + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ] + }, + { + "name": "control_library_306xh", + "target_type": "static", + "sources": [ + "middleware/control_library/adc_calibr", + "middleware/control_library/brake", + "middleware/control_library/filter", + "middleware/control_library/foc_loop_ctrl", + "middleware/control_library/math", + "middleware/control_library/modulation", + "middleware/control_library/observer/mcs_fosmo.c", + "middleware/control_library/pfc", + "middleware/control_library/pid_controller", + "middleware/control_library/power", + "middleware/control_library/protection", + "middleware/control_library/ramp", + "middleware/control_library/utilities", + "middleware/control_library/vf" + ], + "includes": [ + "middleware/control_library", + "drivers", + "generatecode", + "chip" + ], + "define": [], + "libs": [], + "lds_scripts": [], + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ] + }, + { + "name": "function_safety_306xh", + "target_type": "static", + "sources": [ + "middleware/function_safety" + ], + "includes": [ + "middleware/function_safety", + "drivers", + "generatecode", + "chip" + ], + "define": [], + "libs": [], + "lds_scripts": [], + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ] + }, + { + "name": "bounds_check", + "target_type": "static", + "sources": [ + "middleware/hisilicon/libboundscheck_v1.1.16" + ], + "includes": [ + "middleware/hisilicon/libboundscheck_v1.1.16" + ], + "define": [], + "libs": [], + "lds_scripts": [], + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ] + } + ] + }, + { + "name": "compile_frame", + "cflags": [ + "-Os", + "-fuse-ld", + "-pipe", + "-Wall", + "-Wextra", + "-Winit-self", + "-Wmissing-include-dirs", + "-Werror=undef", + "-Wpointer-arith", + "-Wstrict-prototypes", + "-Wmissing-prototypes", + "-Wformat=2", + "-Wfloat-equal", + "-Wdate-time", + "-Wswitch-default", + "-Wno-missing-declarations", + "-Wcast-align", + "-Wunused", + "-Wvla", + "-Wshadow", + "-std=gnu11", + "-fsigned-char", + "-fno-builtin", + "-ffreestanding", + "-nostdlib", + "-fno-exceptions", + "-fno-unwind-tables", + "-fno-short-enums", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-falign-functions=2", + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-msmall-data-limit=0", + "-mabi=ilp32f", + "-march=rv32imfc_xhimideer", + "--target=riscv32", + "-mllvm","-imm-compare", + "-mllvm","-emit-muliadd", + "-mllvm","-merge-immshf", + "-mllvm","-emit-uxtb-uxth", + "-mllvm","--enable-lli=true", + "-mllvm","-fldm-stm-optimize", + "-mllvm","-himideer-push-pop", + "-mllvm","--jump-is-expensive=false", + "-mllvm","--min-jump-table-entries=1000000", + "-mllvm","-enable-rodata-sections=true", + "-mllvm","-enable-branch-imm-no-zero=true", + "-mllvm","--riscv-enable-copyelim=true", + "-fvisibility=hidden", + "-cl-single-precision-constant", + "-mllvm","-unroll-runtime", + "-mllvm","-enable-loop-flatten=true", + "-mllvm","-enable-loop-fusion=true", + "-mllvm","-enable-small-loop-unroll=false", + "-mllvm","-enable-unroll-and-jam=true", + "-mllvm","-allow-unroll-and-jam=true", + "-mllvm","-unroll-and-jam-count=9", + "-mcpu=linx-rv32" + ], + "asmflags": [], + "ldflags": [ + "-fuse-ld", + "-nostdlib", + "-Wl,-Map,bin/target.map", + "-Wl,--gc-sections", + "-Wl,--enjal16", + "-Wl,--jal-relax", + "-Wl,--jal-transfer", + "-Wl,-Bsymbolic", + "-Wl,--no-undefined", + "-static", + "--target=riscv32", + "-lclang_rt.builtins-riscv32", + "-lc" + ], + "define": [ + "FLOAT_SUPPORT" + ], + "nocheck": [] + } + ] + }, + { + "name": "transplant", + "subsystem": [ + { + "name": "loaderboot", + "ext_component": { + "exec_path": "middleware/hisilicon/loaderboot", + "exec_cmd": "python build.py", + "includes": [] + } + } + ] + } + ] +} \ No newline at end of file diff --git "a/src/document/datasheet/1. 3061M\347\263\273\347\273\237\346\211\213\345\206\214/\350\212\257\347\211\207\350\265\204\346\226\231\351\223\276\346\216\245" "b/src/document/datasheet/1. 3061M\347\263\273\347\273\237\346\211\213\345\206\214/\350\212\257\347\211\207\350\265\204\346\226\231\351\223\276\346\216\245" deleted file mode 100644 index 515909ba8340c9d7913a10df75305ea0614ead92..0000000000000000000000000000000000000000 --- "a/src/document/datasheet/1. 3061M\347\263\273\347\273\237\346\211\213\345\206\214/\350\212\257\347\211\207\350\265\204\346\226\231\351\223\276\346\216\245" +++ /dev/null @@ -1 +0,0 @@ -芯片资料链接: https://pan.baidu.com/s/1lMXI-bZHIlNneN7-dl_-eQ?pwd=18ms 提取码: 18ms \ No newline at end of file diff --git "a/src/document/datasheet/3061M/\350\212\257\347\211\207\350\265\204\346\226\231\351\223\276\346\216\245.txt" "b/src/document/datasheet/3061M/\350\212\257\347\211\207\350\265\204\346\226\231\351\223\276\346\216\245.txt" new file mode 100644 index 0000000000000000000000000000000000000000..2b55e378bc87a8492aa30fe4255f4860b9b5c970 --- /dev/null +++ "b/src/document/datasheet/3061M/\350\212\257\347\211\207\350\265\204\346\226\231\351\223\276\346\216\245.txt" @@ -0,0 +1 @@ +芯片资料链接: https://pan.baidu.com/s/1EIFKVzhtVbBDsbv5maYF0g?pwd=cr4u 提取码: cr4u \ No newline at end of file diff --git "a/src/document/datasheet/3065A/3065A\347\263\273\345\210\227 \344\272\247\345\223\201\347\256\200\344\273\213 V01.pdf" "b/src/document/datasheet/3065A/3065A\347\263\273\345\210\227 \344\272\247\345\223\201\347\256\200\344\273\213 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..b5128dc653eafffde97eb66c6fc15341f90a4145 Binary files /dev/null and "b/src/document/datasheet/3065A/3065A\347\263\273\345\210\227 \344\272\247\345\223\201\347\256\200\344\273\213 V01.pdf" differ diff --git "a/src/document/datasheet/3065A/3065A\347\263\273\345\210\227 \346\212\200\346\234\257\345\217\202\350\200\203\346\214\207\345\215\227 V02.pdf" "b/src/document/datasheet/3065A/3065A\347\263\273\345\210\227 \346\212\200\346\234\257\345\217\202\350\200\203\346\214\207\345\215\227 V02.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..6a8176b4cacf337cd48e7cdb57c3846d015d05eb Binary files /dev/null and "b/src/document/datasheet/3065A/3065A\347\263\273\345\210\227 \346\212\200\346\234\257\345\217\202\350\200\203\346\214\207\345\215\227 V02.pdf" differ diff --git "a/src/document/datasheet/3065A/3065A\347\263\273\345\210\227 \346\225\260\346\215\256\346\211\213\345\206\214 V02.pdf" "b/src/document/datasheet/3065A/3065A\347\263\273\345\210\227 \346\225\260\346\215\256\346\211\213\345\206\214 V02.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..3bc6ae0507ff189ae46be91de36935edf9ab4e23 Binary files /dev/null and "b/src/document/datasheet/3065A/3065A\347\263\273\345\210\227 \346\225\260\346\215\256\346\211\213\345\206\214 V02.pdf" differ diff --git "a/src/document/datasheet/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \344\272\247\345\223\201\347\256\200\344\273\213 V00B03.pdf" "b/src/document/datasheet/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \344\272\247\345\223\201\347\256\200\344\273\213 V00B03.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..d4f744bbce6e8d625afb4e761e7a7a51e0806eb2 Binary files /dev/null and "b/src/document/datasheet/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \344\272\247\345\223\201\347\256\200\344\273\213 V00B03.pdf" differ diff --git "a/src/document/datasheet/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \346\212\200\346\234\257\345\217\202\350\200\203\346\214\207\345\215\227 V00B02.pdf" "b/src/document/datasheet/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \346\212\200\346\234\257\345\217\202\350\200\203\346\214\207\345\215\227 V00B02.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..87ba643123c1cbdab36dbdfcf79c0512d1749e67 Binary files /dev/null and "b/src/document/datasheet/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \346\212\200\346\234\257\345\217\202\350\200\203\346\214\207\345\215\227 V00B02.pdf" differ diff --git "a/src/document/datasheet/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \346\225\260\346\215\256\346\211\213\345\206\214 V00B02.pdf" "b/src/document/datasheet/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \346\225\260\346\215\256\346\211\213\345\206\214 V00B02.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..906d9aeaac347e3f95f962519bfde4d0d6f4565a Binary files /dev/null and "b/src/document/datasheet/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \346\225\260\346\215\256\346\211\213\345\206\214 V00B02.pdf" differ diff --git "a/src/document/hardware/2. 3061/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V1.0.xlsx" "b/src/document/hardware/2. 3061/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V1.0.xlsx" deleted file mode 100644 index d572ce3b467a84c0862c90333b3c3116419eba19..0000000000000000000000000000000000000000 Binary files "a/src/document/hardware/2. 3061/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V1.0.xlsx" and /dev/null differ diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/1.ECBMCU201MPC_VER.B Reference Board SCH/ORCAD/ECBMCU201MPC_VER_B.DSN" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/1.ECBMCU201MPC_VER.B Reference Board SCH/ORCAD/ECBMCU201MPC_VER_B.DSN" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/1.ECBMCU201MPC_VER.B Reference Board SCH/ORCAD/ECBMCU201MPC_VER_B.DSN" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/1.ECBMCU201MPC_VER.B Reference Board SCH/ORCAD/ECBMCU201MPC_VER_B.DSN" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/1.ECBMCU201MPC_VER.B Reference Board SCH/PDF/ECBMCU201MPC_VER_B.pdf" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/1.ECBMCU201MPC_VER.B Reference Board SCH/PDF/ECBMCU201MPC_VER_B.pdf" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/1.ECBMCU201MPC_VER.B Reference Board SCH/PDF/ECBMCU201MPC_VER_B.pdf" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/1.ECBMCU201MPC_VER.B Reference Board SCH/PDF/ECBMCU201MPC_VER_B.pdf" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/Allegro/ECBMCU201MPC_VER_B_Allegro.brd" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/Allegro/ECBMCU201MPC_VER_B_Allegro.brd" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/Allegro/ECBMCU201MPC_VER_B_Allegro.brd" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/Allegro/ECBMCU201MPC_VER_B_Allegro.brd" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/PADS/ECBMCU201MPC_VER_B_PCB.asc" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/PADS/ECBMCU201MPC_VER_B_PCB.asc" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/PADS/ECBMCU201MPC_VER_B_PCB.asc" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/PADS/ECBMCU201MPC_VER_B_PCB.asc" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/PADS/ECBMCU201MPC_VER_B_PCB.pcb" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/PADS/ECBMCU201MPC_VER_B_PCB.pcb" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/PADS/ECBMCU201MPC_VER_B_PCB.pcb" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/2.ECBMCU201MPC_VER.B Reference Board PCB/PADS/ECBMCU201MPC_VER_B_PCB.pcb" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/3.ECBMCU201MPC_VER.B Reference Board BOM/ECBMCU201MPC_VB_BOM.xlsx" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/3.ECBMCU201MPC_VER.B Reference Board BOM/ECBMCU201MPC_VB_BOM.xlsx" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/3.ECBMCU201MPC_VER.B Reference Board BOM/ECBMCU201MPC_VB_BOM.xlsx" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/3.ECBMCU201MPC_VER.B Reference Board BOM/ECBMCU201MPC_VB_BOM.xlsx" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/Allegro footprint.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/Allegro footprint.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/Allegro footprint.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/Allegro footprint.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/ORCAD symbol.rar" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/ORCAD symbol.rar" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/ORCAD symbol.rar" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/ORCAD symbol.rar" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/pads.rar" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/pads.rar" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/pads.rar" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP32/pads.rar" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/Allegro footprint.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/Allegro footprint.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/Allegro footprint.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/Allegro footprint.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/ORCAD symbol.rar" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/ORCAD symbol.rar" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/ORCAD symbol.rar" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/ORCAD symbol.rar" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/pads.rar" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/pads.rar" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/pads.rar" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/LQFP48/pads.rar" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/Allegro footprint.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/Allegro footprint.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/Allegro footprint.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/Allegro footprint.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/ORCAD symbol.rar" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/ORCAD symbol.rar" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/ORCAD symbol.rar" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/ORCAD symbol.rar" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/pads.rar" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/pads.rar" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/pads.rar" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN32/pads.rar" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/Allegro footprint.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/Allegro footprint.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/Allegro footprint.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/Allegro footprint.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/ORCAD symbol.rar" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/ORCAD symbol.rar" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/ORCAD symbol.rar" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/ORCAD symbol.rar" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/pads.rar" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/pads.rar" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/pads.rar" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/4.SCH&PCB symbol/QFN48/pads.rar" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/Gerber/ECBMCU201MPC_CAM_VB.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/Gerber/ECBMCU201MPC_CAM_VB.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/Gerber/ECBMCU201MPC_CAM_VB.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/Gerber/ECBMCU201MPC_CAM_VB.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\347\273\223\346\236\204\350\246\201\347\264\240\345\233\276/ECBMCU201MPC_JG_VB.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\347\273\223\346\236\204\350\246\201\347\264\240\345\233\276/ECBMCU201MPC_JG_VB.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\347\273\223\346\236\204\350\246\201\347\264\240\345\233\276/ECBMCU201MPC_JG_VB.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\347\273\223\346\236\204\350\246\201\347\264\240\345\233\276/ECBMCU201MPC_JG_VB.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_ASM_VB.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_ASM_VB.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_ASM_VB.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_ASM_VB.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_ICT_VB.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_ICT_VB.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_ICT_VB.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_ICT_VB.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_SMD_VB.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_SMD_VB.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_SMD_VB.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/5.ECBMCU201MPC_VER.B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMCU201MPC_SMD_VB.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/ECBMCU201MPC Hardware Version Update Record.xlsx" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/ECBMCU201MPC Hardware Version Update Record.xlsx" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/ECBMCU201MPC Hardware Version Update Record.xlsx" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\346\240\270\345\277\203\346\235\277-\347\224\265\346\234\272\346\216\247\345\210\266\346\235\277-ECBMCU201MPC_VER.B/ECBMCU201MPC Hardware Version Update Record.xlsx" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/1.ECBMOTORA_VER_B Reference Board SCH/ORCAD/ECBMOTORA_VER_B_SCH.DSN" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/1.ECBMOTORA_VER_B Reference Board SCH/ORCAD/ECBMOTORA_VER_B_SCH.DSN" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/1.ECBMOTORA_VER_B Reference Board SCH/ORCAD/ECBMOTORA_VER_B_SCH.DSN" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/1.ECBMOTORA_VER_B Reference Board SCH/ORCAD/ECBMOTORA_VER_B_SCH.DSN" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/1.ECBMOTORA_VER_B Reference Board SCH/PDF/ECBMOTORA_VER_B_SCH.pdf" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/1.ECBMOTORA_VER_B Reference Board SCH/PDF/ECBMOTORA_VER_B_SCH.pdf" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/1.ECBMOTORA_VER_B Reference Board SCH/PDF/ECBMOTORA_VER_B_SCH.pdf" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/1.ECBMOTORA_VER_B Reference Board SCH/PDF/ECBMOTORA_VER_B_SCH.pdf" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/Allegro/ECBMOTORA_VER_B_Allegro.brd" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/Allegro/ECBMOTORA_VER_B_Allegro.brd" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/Allegro/ECBMOTORA_VER_B_Allegro.brd" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/Allegro/ECBMOTORA_VER_B_Allegro.brd" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/PADs/ECBMOTORA_VER_B_PCB.asc" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/PADs/ECBMOTORA_VER_B_PCB.asc" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/PADs/ECBMOTORA_VER_B_PCB.asc" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/PADs/ECBMOTORA_VER_B_PCB.asc" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/PADs/ECBMOTORA_VER_B_PCB.pcb" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/PADs/ECBMOTORA_VER_B_PCB.pcb" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/PADs/ECBMOTORA_VER_B_PCB.pcb" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/2.ECBMOTORA_VER_B Reference Board PCB/PADs/ECBMOTORA_VER_B_PCB.pcb" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/3.ECBMOTORA_VER_B Reference Board BOM/ECBMOTORA_VB_BOM.xls" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/3.ECBMOTORA_VER_B Reference Board BOM/ECBMOTORA_VB_BOM.xls" similarity index 97% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/3.ECBMOTORA_VER_B Reference Board BOM/ECBMOTORA_VB_BOM.xls" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/3.ECBMOTORA_VER_B Reference Board BOM/ECBMOTORA_VB_BOM.xls" index d592b37fcaf55381ed84f6de92ca52aba8feb7f7..cc0c62558f1fc212635c2fb4d33f9175223c9c67 100644 Binary files "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/3.ECBMOTORA_VER_B Reference Board BOM/ECBMOTORA_VB_BOM.xls" and "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/3.ECBMOTORA_VER_B Reference Board BOM/ECBMOTORA_VB_BOM.xls" differ diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/Gerber/ECBMOTORA_CAM_VB.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/Gerber/ECBMOTORA_CAM_VB.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/Gerber/ECBMOTORA_CAM_VB.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/Gerber/ECBMOTORA_CAM_VB.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\347\273\223\346\236\204\350\246\201\347\264\240\345\233\276/ECBMOTORA_JG_VB.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\347\273\223\346\236\204\350\246\201\347\264\240\345\233\276/ECBMOTORA_JG_VB.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\347\273\223\346\236\204\350\246\201\347\264\240\345\233\276/ECBMOTORA_JG_VB.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\347\273\223\346\236\204\350\246\201\347\264\240\345\233\276/ECBMOTORA_JG_VB.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_ASM_VB.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_ASM_VB.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_ASM_VB.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_ASM_VB.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_ICT_VB.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_ICT_VB.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_ICT_VB.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_ICT_VB.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_SMD_VB.zip" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_SMD_VB.zip" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_SMD_VB.zip" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/4.ECBMOTORA_VER_B Reference Board Manufacturing/\350\264\264\347\211\207\345\235\220\346\240\207\346\226\207\344\273\266/ECBMOTORA_SMD_VB.zip" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/ECBMOTORA Hardware Version Update Record.xlsx" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/ECBMOTORA Hardware Version Update Record.xlsx" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/ECBMOTORA Hardware Version Update Record.xlsx" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/2.\346\211\251\345\261\225\346\235\277-\347\224\265\346\234\272\351\251\261\345\212\250\346\235\277-ECBMOTORA_VER.B/ECBMOTORA Hardware Version Update Record.xlsx" diff --git "a/src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/3061M\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 00B01.pdf" "b/src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/3061M\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 00B01.pdf" similarity index 100% rename from "src/document/hardware/2. 3061/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/3061M\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 00B01.pdf" rename to "src/document/hardware/3061M/1. 3061 \347\224\237\346\200\201\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/3061M\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 00B01.pdf" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/1.AD201MPCHVVA_VER.A Reference Board SCH/ORCAD/AD201MPCHVVA_VER_A_SCH.DSN" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/1.AD201MPCHVVA_VER.A Reference Board SCH/ORCAD/AD201MPCHVVA_VER_A_SCH.DSN" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/1.AD201MPCHVVA_VER.A Reference Board SCH/ORCAD/AD201MPCHVVA_VER_A_SCH.DSN" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/1.AD201MPCHVVA_VER.A Reference Board SCH/ORCAD/AD201MPCHVVA_VER_A_SCH.DSN" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/1.AD201MPCHVVA_VER.A Reference Board SCH/PDF/AD201MPCHVVA_VER_A.pdf" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/1.AD201MPCHVVA_VER.A Reference Board SCH/PDF/AD201MPCHVVA_VER_A.pdf" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/1.AD201MPCHVVA_VER.A Reference Board SCH/PDF/AD201MPCHVVA_VER_A.pdf" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/1.AD201MPCHVVA_VER.A Reference Board SCH/PDF/AD201MPCHVVA_VER_A.pdf" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/Allegro/AD201MPCHVVA_VER_A_Allegro.brd" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/Allegro/AD201MPCHVVA_VER_A_Allegro.brd" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/Allegro/AD201MPCHVVA_VER_A_Allegro.brd" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/Allegro/AD201MPCHVVA_VER_A_Allegro.brd" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/PADS/AD201MPCHVVA_VER_A_PCB.asc" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/PADS/AD201MPCHVVA_VER_A_PCB.asc" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/PADS/AD201MPCHVVA_VER_A_PCB.asc" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/PADS/AD201MPCHVVA_VER_A_PCB.asc" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/PADS/AD201MPCHVVA_VER_A_PCB.pcb" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/PADS/AD201MPCHVVA_VER_A_PCB.pcb" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/PADS/AD201MPCHVVA_VER_A_PCB.pcb" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/2.AD201MPCHVVA_VER.A Reference Board PCB/PADS/AD201MPCHVVA_VER_A_PCB.pcb" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/3.AD201MPCHVVA_VER.A Reference Board BOM/AD201MPCHVVA_VA_BOM.xlsx" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/3.AD201MPCHVVA_VER.A Reference Board BOM/AD201MPCHVVA_VA_BOM.xlsx" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/3.AD201MPCHVVA_VER.A Reference Board BOM/AD201MPCHVVA_VA_BOM.xlsx" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/3.AD201MPCHVVA_VER.A Reference Board BOM/AD201MPCHVVA_VA_BOM.xlsx" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/Allegro footprint.zip" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/Allegro footprint.zip" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/Allegro footprint.zip" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/Allegro footprint.zip" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/ORCAD symbol.rar" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/ORCAD symbol.rar" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/ORCAD symbol.rar" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/ORCAD symbol.rar" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/pads.rar" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/pads.rar" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/pads.rar" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP32/pads.rar" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/Allegro footprint.zip" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/Allegro footprint.zip" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/Allegro footprint.zip" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/Allegro footprint.zip" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/ORCAD symbol.rar" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/ORCAD symbol.rar" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/ORCAD symbol.rar" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/ORCAD symbol.rar" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/pads.rar" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/pads.rar" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/pads.rar" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/LQFP48/pads.rar" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/Allegro footprint.zip" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/Allegro footprint.zip" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/Allegro footprint.zip" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/Allegro footprint.zip" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/ORCAD symbol.rar" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/ORCAD symbol.rar" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/ORCAD symbol.rar" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/ORCAD symbol.rar" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/pads.rar" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/pads.rar" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/pads.rar" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN32/pads.rar" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/Allegro footprint.zip" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/Allegro footprint.zip" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/Allegro footprint.zip" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/Allegro footprint.zip" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/ORCAD symbol.rar" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/ORCAD symbol.rar" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/ORCAD symbol.rar" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/ORCAD symbol.rar" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/pads.rar" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/pads.rar" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/pads.rar" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/4.SCH&PCB symbol/QFN48/pads.rar" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/AD201MPCHVVA Hardware Version Update Record.xlsx" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/AD201MPCHVVA Hardware Version Update Record.xlsx" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/AD201MPCHVVA Hardware Version Update Record.xlsx" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/AD201MPCHVVA Hardware Version Update Record.xlsx" diff --git "a/src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/AD201MPCHVVA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V00B01.pdf" "b/src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/AD201MPCHVVA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V00B01.pdf" similarity index 100% rename from "src/document/hardware/2. 3061/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/AD201MPCHVVA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V00B01.pdf" rename to "src/document/hardware/3061M/2. 3061 \350\241\214\344\270\232\346\235\277\345\217\202\350\200\203\350\256\276\350\256\241/1.\350\241\214\344\270\232\345\217\202\350\200\203\350\256\276\350\256\2411-AD201MPCHVVA_VER.A/AD201MPCHVVA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V00B01.pdf" diff --git "a/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \345\213\230\350\257\257\346\211\213\345\206\214 V01.pdf" "b/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \345\213\230\350\257\257\346\211\213\345\206\214 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..b3bfd890b787494ced4d6c5101577184e544ef3e Binary files /dev/null and "b/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \345\213\230\350\257\257\346\211\213\345\206\214 V01.pdf" differ diff --git "a/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V01.xlsx" "b/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V01.xlsx" new file mode 100644 index 0000000000000000000000000000000000000000..d743b04605417defc3b223e2f801f937a9e791b3 Binary files /dev/null and "b/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V01.xlsx" differ diff --git "a/src/document/hardware/2. 3061/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V00B01.pdf" "b/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V01.pdf" similarity index 43% rename from "src/document/hardware/2. 3061/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V00B01.pdf" rename to "src/document/hardware/3061M/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V01.pdf" index a421aa0af6db5fca8449edc6b56704519f8655ab..0fbc29b17abbb444aa394f59bd6b50847ae55afa 100644 Binary files "a/src/document/hardware/2. 3061/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V00B01.pdf" and "b/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277FAQ V01.pdf" "b/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277FAQ V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..3ab18971a82c376581591a8279b76cf288659baa Binary files /dev/null and "b/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277FAQ V01.pdf" differ diff --git "a/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 V01.pdf" "b/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..556fba56a9adba80cbd88ea0027e3c1d6dcaf1be Binary files /dev/null and "b/src/document/hardware/3061M/3061M\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 V01.pdf" differ diff --git "a/src/document/hardware/3061M/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD201MPCHVVA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" "b/src/document/hardware/3061M/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD201MPCHVVA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..409a9f2ccbaf75b8733fc0c8670c4910173a4a6b Binary files /dev/null and "b/src/document/hardware/3061M/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD201MPCHVVA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/hardware/3061M/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD201MPKDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" "b/src/document/hardware/3061M/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD201MPKDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..74682eb411fbaa01e8463ad6199582f67850a003 Binary files /dev/null and "b/src/document/hardware/3061M/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD201MPKDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/hardware/3065A/3065A \345\213\230\350\257\257\346\211\213\345\206\214 V01.pdf" "b/src/document/hardware/3065A/3065A \345\213\230\350\257\257\346\211\213\345\206\214 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..a13268ff3c9957f50e3c67c8c8b34a59b5c19726 Binary files /dev/null and "b/src/document/hardware/3065A/3065A \345\213\230\350\257\257\346\211\213\345\206\214 V01.pdf" differ diff --git "a/src/document/hardware/3065A/3065A \347\241\254\344\273\266\350\256\276\350\256\241Checklist V01.xlsx" "b/src/document/hardware/3065A/3065A \347\241\254\344\273\266\350\256\276\350\256\241Checklist V01.xlsx" new file mode 100644 index 0000000000000000000000000000000000000000..4f0efe7130afd472c60a123a06ad67336102b8c3 Binary files /dev/null and "b/src/document/hardware/3065A/3065A \347\241\254\344\273\266\350\256\276\350\256\241Checklist V01.xlsx" differ diff --git "a/src/document/hardware/3065A/3065A \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V01.pdf" "b/src/document/hardware/3065A/3065A \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..f2a2a2f35efdee3744675f83ceff41c160139049 Binary files /dev/null and "b/src/document/hardware/3065A/3065A \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/hardware/3065A/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD105ADMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" "b/src/document/hardware/3065A/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD105ADMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..74805afe109a593ddf7fd8e69bf4a7aa1794eb1f Binary files /dev/null and "b/src/document/hardware/3065A/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD105ADMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/hardware/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V1.0.xlsx" "b/src/document/hardware/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V1.0.xlsx" new file mode 100644 index 0000000000000000000000000000000000000000..75dfb8f10eb6df00de5eb27bd50dc6b774161c80 Binary files /dev/null and "b/src/document/hardware/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V1.0.xlsx" differ diff --git "a/src/document/hardware/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V00B01.pdf" "b/src/document/hardware/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V00B01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..267634d56e050c1e3209e2b6dddd8ca61bbca74c Binary files /dev/null and "b/src/document/hardware/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V00B01.pdf" differ diff --git "a/src/document/hardware/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 V00B01.pdf" "b/src/document/hardware/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 V00B01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..d0479a23d05b90ee634b79abe57b9ac6d76f6671 Binary files /dev/null and "b/src/document/hardware/3066M\357\274\2173065P/3066M\357\274\2173065P\347\263\273\345\210\227 \351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 V00B01.pdf" differ diff --git "a/src/document/hardware/3066M\357\274\2173065P/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD406MDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V00B01.pdf" "b/src/document/hardware/3066M\357\274\2173065P/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD406MDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V00B01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..8face07339b23d99a48a413b5d632957ba32d735 Binary files /dev/null and "b/src/document/hardware/3066M\357\274\2173065P/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD406MDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V00B01.pdf" differ diff --git "a/src/document/hardware/1. 3065/3065H\351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 V03.pdf" "b/src/document/hardware/306xH/3065H\351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 V03.pdf" similarity index 100% rename from "src/document/hardware/1. 3065/3065H\351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 V03.pdf" rename to "src/document/hardware/306xH/3065H\351\200\232\347\224\250\347\224\237\346\200\201\346\235\277\347\224\250\346\210\267\346\211\213\345\206\214 V03.pdf" diff --git "a/src/document/hardware/306xH/306xH\347\263\273\345\210\227 \345\213\230\350\257\257\346\211\213\345\206\214 V01.pdf" "b/src/document/hardware/306xH/306xH\347\263\273\345\210\227 \345\213\230\350\257\257\346\211\213\345\206\214 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..0b7c2f86d918bd3563e0079b9fad38e20f92f73e Binary files /dev/null and "b/src/document/hardware/306xH/306xH\347\263\273\345\210\227 \345\213\230\350\257\257\346\211\213\345\206\214 V01.pdf" differ diff --git "a/src/document/hardware/306xH/306xH\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V01.xlsx" "b/src/document/hardware/306xH/306xH\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V01.xlsx" new file mode 100644 index 0000000000000000000000000000000000000000..e5ed6e28e9d4fcca3e0ff0fd913af2b0e24f6750 Binary files /dev/null and "b/src/document/hardware/306xH/306xH\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241Checklist V01.xlsx" differ diff --git "a/src/document/hardware/306xH/306xH\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V03.pdf" "b/src/document/hardware/306xH/306xH\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V03.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..8b85c5f07cd3e446b8d86750c074e0633123fbcd Binary files /dev/null and "b/src/document/hardware/306xH/306xH\347\263\273\345\210\227 \347\241\254\344\273\266\350\256\276\350\256\241\346\214\207\345\215\227 V03.pdf" differ diff --git "a/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD101HDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" "b/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD101HDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..ef6c25a562889a6d63801336078a4df08c44e0e2 Binary files /dev/null and "b/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD101HDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD101LDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" "b/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD101LDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..d94eaff543193cfac3633c3eb28c7d60f0bd946c Binary files /dev/null and "b/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD101LDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD101LDMB \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" "b/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD101LDMB \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..71ac63d529c8acab548c2770f27f7adb54257beb Binary files /dev/null and "b/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD101LDMB \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD105HDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" "b/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD105HDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..53758b17c82b4b78f30b401cbd0e31de585bcba4 Binary files /dev/null and "b/src/document/hardware/306xH/\345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227/AD105HDMA \345\215\225\346\235\277\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/release notes/HiSparkStudio \347\211\210\346\234\254\346\217\217\350\277\260\346\226\207\344\273\266 V00B03.pdf" "b/src/document/release notes/HiSparkStudio \347\211\210\346\234\254\346\217\217\350\277\260\346\226\207\344\273\266 V00B03.pdf" deleted file mode 100644 index cc5f017625e383c95823c5ff7f7cf2c6a3fd9ec5..0000000000000000000000000000000000000000 Binary files "a/src/document/release notes/HiSparkStudio \347\211\210\346\234\254\346\217\217\350\277\260\346\226\207\344\273\266 V00B03.pdf" and /dev/null differ diff --git "a/src/document/release notes/HiSparkStudio \347\211\210\346\234\254\346\217\217\350\277\260\346\226\207\344\273\266 V01.pdf" "b/src/document/release notes/HiSparkStudio \347\211\210\346\234\254\346\217\217\350\277\260\346\226\207\344\273\266 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..f5543aa0d1d7978386902fed7afc5b4333d03553 Binary files /dev/null and "b/src/document/release notes/HiSparkStudio \347\211\210\346\234\254\346\217\217\350\277\260\346\226\207\344\273\266 V01.pdf" differ diff --git a/src/document/release notes/Open Source Software Notice.docx b/src/document/release notes/Open Source Software Notice.docx deleted file mode 100644 index ee2ef9ed98c57dccf660a23a810e11ef825d8b81..0000000000000000000000000000000000000000 Binary files a/src/document/release notes/Open Source Software Notice.docx and /dev/null differ diff --git a/src/document/release notes/Open Source Software Notice.pdf b/src/document/release notes/Open Source Software Notice.pdf new file mode 100644 index 0000000000000000000000000000000000000000..297e17bf6b6d59a9de35975433fb6df1716611f3 Binary files /dev/null and b/src/document/release notes/Open Source Software Notice.pdf differ diff --git "a/src/document/release notes/SolarA\302\262 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V05.pdf" "b/src/document/release notes/SolarA\302\262 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V01.pdf" similarity index 42% rename from "src/document/release notes/SolarA\302\262 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V05.pdf" rename to "src/document/release notes/SolarA\302\262 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V01.pdf" index 7e9b76d504b78660f45f86eb3596464afcd29f85..d389b584bc71676161209fa86eda66846a5175bc 100644 Binary files "a/src/document/release notes/SolarA\302\262 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V05.pdf" and "b/src/document/release notes/SolarA\302\262 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V01.pdf" differ diff --git "a/src/document/release notes/SolarA\302\262 \347\211\210\346\234\254\346\217\217\350\277\260\346\226\207\344\273\266 V01.pdf" "b/src/document/release notes/SolarA\302\262 \347\211\210\346\234\254\346\217\217\350\277\260\346\226\207\344\273\266 V01.pdf" index 1b43c658d73309ba2df83d4043958db5f091c1fe..2de611123034d6cbcbde8d71915c4b3bb326b44a 100644 Binary files "a/src/document/release notes/SolarA\302\262 \347\211\210\346\234\254\346\217\217\350\277\260\346\226\207\344\273\266 V01.pdf" and "b/src/document/release notes/SolarA\302\262 \347\211\210\346\234\254\346\217\217\350\277\260\346\226\207\344\273\266 V01.pdf" differ diff --git "a/src/document/release notes/\345\267\245\345\205\267\350\275\257\344\273\266 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V00B01.pdf" "b/src/document/release notes/\345\267\245\345\205\267\350\275\257\344\273\266 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V01.pdf" similarity index 34% rename from "src/document/release notes/\345\267\245\345\205\267\350\275\257\344\273\266 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V00B01.pdf" rename to "src/document/release notes/\345\267\245\345\205\267\350\275\257\344\273\266 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V01.pdf" index e0ea511405a147367a411c8c7c49d06c5e807b02..a93bdcdcce26c1b6a166a2038398a67886fd7cb9 100644 Binary files "a/src/document/release notes/\345\267\245\345\205\267\350\275\257\344\273\266 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V00B01.pdf" and "b/src/document/release notes/\345\267\245\345\205\267\350\275\257\344\273\266 \344\272\214\346\254\241\345\274\200\345\217\221\347\275\221\347\273\234\345\256\211\345\205\250\346\263\250\346\204\217\344\272\213\351\241\271 V01.pdf" differ diff --git "a/src/document/software/ARMCC\350\277\201\347\247\273\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\346\214\207\345\215\227 V01.pdf" "b/src/document/software/ARMCC\350\277\201\347\247\273\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..ade69ee041452a382b7e867e294b67cb7eff6c54 Binary files /dev/null and "b/src/document/software/ARMCC\350\277\201\347\247\273\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/software/HiSpark-Trace\347\241\254\344\273\266\345\267\245\345\205\267\346\234\254\344\275\223\350\275\257\344\273\266\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274 V01.pdf" "b/src/document/software/HiSpark-Trace\347\241\254\344\273\266\345\267\245\345\205\267\346\234\254\344\275\223\350\275\257\344\273\266\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..879a6fc99c5b793110dc5ced85caef59a5ce1d93 Binary files /dev/null and "b/src/document/software/HiSpark-Trace\347\241\254\344\273\266\345\267\245\345\205\267\346\234\254\344\275\223\350\275\257\344\273\266\347\274\226\350\257\221\346\236\204\345\273\272\346\214\207\345\257\274 V01.pdf" differ diff --git "a/src/document/software/IAR\350\277\201\347\247\273\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\346\214\207\345\215\227 V01.pdf" "b/src/document/software/IAR\350\277\201\347\247\273\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..61f2c6b0dae7725e87a721ae36faecd69403ae02 Binary files /dev/null and "b/src/document/software/IAR\350\277\201\347\247\273\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/software/RISCV32 GCC\347\274\226\350\257\221\345\231\250\345\210\207\346\215\242\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\350\277\201\347\247\273\346\214\207\345\215\227 V01.pdf" "b/src/document/software/RISCV32 GCC\347\274\226\350\257\221\345\231\250\345\210\207\346\215\242\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\350\277\201\347\247\273\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..01c17127258898ba4935d516ed0427dd8c9817c5 Binary files /dev/null and "b/src/document/software/RISCV32 GCC\347\274\226\350\257\221\345\231\250\345\210\207\346\215\242\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\350\277\201\347\247\273\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/software/SolarA\302\262 \344\273\2163065\345\210\2603066M\357\274\2173065P\350\212\257\347\211\207\347\247\273\346\244\215\345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" "b/src/document/software/SolarA\302\262 \344\273\2163065\345\210\2603066M\357\274\2173065P\350\212\257\347\211\207\347\247\273\346\244\215\345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..8a72a889ed57b03513d421a517e455c8ec681870 Binary files /dev/null and "b/src/document/software/SolarA\302\262 \344\273\2163065\345\210\2603066M\357\274\2173065P\350\212\257\347\211\207\347\247\273\346\244\215\345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/software/SolarA\302\262 \344\273\216ARM-M\345\220\221RISC-V\347\247\273\346\244\215\345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" "b/src/document/software/SolarA\302\262 \344\273\216ARM-M\345\220\221RISC-V\347\247\273\346\244\215\345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..93bfd013c74bde9535cb47e89e5abb83f9713573 Binary files /dev/null and "b/src/document/software/SolarA\302\262 \344\273\216ARM-M\345\220\221RISC-V\347\247\273\346\244\215\345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/software/SolarA\302\262 \345\256\232\346\227\266\344\273\273\345\212\241\345\274\200\345\217\221\346\214\207\345\215\227 V02.pdf" "b/src/document/software/SolarA\302\262 \345\256\232\346\227\266\344\273\273\345\212\241\345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" similarity index 45% rename from "src/document/software/SolarA\302\262 \345\256\232\346\227\266\344\273\273\345\212\241\345\274\200\345\217\221\346\214\207\345\215\227 V02.pdf" rename to "src/document/software/SolarA\302\262 \345\256\232\346\227\266\344\273\273\345\212\241\345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" index b7b092a305dce4dcd04eaf9216f21778787815c0..43c6169e7cf8748926fbea960f88096b2ecabc06 100644 Binary files "a/src/document/software/SolarA\302\262 \345\256\232\346\227\266\344\273\273\345\212\241\345\274\200\345\217\221\346\214\207\345\215\227 V02.pdf" and "b/src/document/software/SolarA\302\262 \345\256\232\346\227\266\344\273\273\345\212\241\345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/software/SolarA\302\262 \345\270\270\350\247\201\351\227\256\351\242\230FAQ V01.pdf" "b/src/document/software/SolarA\302\262 \345\270\270\350\247\201\351\227\256\351\242\230FAQ V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..e2b1e2eb060356a024f1f98933d81c2ab7b0b609 Binary files /dev/null and "b/src/document/software/SolarA\302\262 \345\270\270\350\247\201\351\227\256\351\242\230FAQ V01.pdf" differ diff --git "a/src/document/software/SolarA\302\262 \345\270\270\350\247\201\351\227\256\351\242\230FAQ V04.pdf" "b/src/document/software/SolarA\302\262 \345\270\270\350\247\201\351\227\256\351\242\230FAQ V04.pdf" deleted file mode 100644 index ae3285bc20f62911019cc57ddfaf2a8a2403cc38..0000000000000000000000000000000000000000 Binary files "a/src/document/software/SolarA\302\262 \345\270\270\350\247\201\351\227\256\351\242\230FAQ V04.pdf" and /dev/null differ diff --git "a/src/document/software/SolarA\302\262 \345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" "b/src/document/software/SolarA\302\262 \345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..e02d3cfd2db94287cec2fb969313f83db53d2800 Binary files /dev/null and "b/src/document/software/SolarA\302\262 \345\274\200\345\217\221\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/software/SolarA\302\262 \345\277\253\351\200\237\345\205\245\351\227\250\346\214\207\345\215\227 V01.pdf" "b/src/document/software/SolarA\302\262 \345\277\253\351\200\237\345\205\245\351\227\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..3289503f718620603dd21744f8cba67350a21cd9 Binary files /dev/null and "b/src/document/software/SolarA\302\262 \345\277\253\351\200\237\345\205\245\351\227\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/software/SolarA\302\262 HAL\345\222\214\345\272\225\345\261\202\351\251\261\345\212\250\347\250\213\345\272\217\350\257\264\346\230\216 V00B06.pdf" "b/src/document/software/SolarA\302\262 \351\251\261\345\212\250\347\250\213\345\272\217\350\257\264\346\230\216 V01.pdf" similarity index 35% rename from "src/document/software/SolarA\302\262 HAL\345\222\214\345\272\225\345\261\202\351\251\261\345\212\250\347\250\213\345\272\217\350\257\264\346\230\216 V00B06.pdf" rename to "src/document/software/SolarA\302\262 \351\251\261\345\212\250\347\250\213\345\272\217\350\257\264\346\230\216 V01.pdf" index d14ffcfae9a4678463d1ad9b5d6bb17003c2ac4c..f14e20092eb1d50e16b7e87f1cbbf916f44173a6 100644 Binary files "a/src/document/software/SolarA\302\262 HAL\345\222\214\345\272\225\345\261\202\351\251\261\345\212\250\347\250\213\345\272\217\350\257\264\346\230\216 V00B06.pdf" and "b/src/document/software/SolarA\302\262 \351\251\261\345\212\250\347\250\213\345\272\217\350\257\264\346\230\216 V01.pdf" differ diff --git "a/src/document/software/TI cl2000\350\277\201\347\247\273\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\346\214\207\345\215\227 V01.pdf" "b/src/document/software/TI cl2000\350\277\201\347\247\273\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..847bb665fab71a37ecd6c1120b4144fe052cdf7e Binary files /dev/null and "b/src/document/software/TI cl2000\350\277\201\347\247\273\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/software/\345\237\272\344\272\216\345\217\214\347\224\265\351\230\273\347\224\265\346\265\201\351\207\207\346\240\267\347\232\204\347\224\265\346\234\272\346\227\240\346\204\237FOC\350\260\203\351\200\237\347\263\273\347\273\237\345\272\224\347\224\250 V06.pdf" "b/src/document/software/\345\237\272\344\272\216\345\217\214\347\224\265\351\230\273\347\224\265\346\265\201\351\207\207\346\240\267\347\232\204\347\224\265\346\234\272\346\227\240\346\204\237FOC\350\260\203\351\200\237\347\263\273\347\273\237\345\272\224\347\224\250 V01.pdf" similarity index 50% rename from "src/document/software/\345\237\272\344\272\216\345\217\214\347\224\265\351\230\273\347\224\265\346\265\201\351\207\207\346\240\267\347\232\204\347\224\265\346\234\272\346\227\240\346\204\237FOC\350\260\203\351\200\237\347\263\273\347\273\237\345\272\224\347\224\250 V06.pdf" rename to "src/document/software/\345\237\272\344\272\216\345\217\214\347\224\265\351\230\273\347\224\265\346\265\201\351\207\207\346\240\267\347\232\204\347\224\265\346\234\272\346\227\240\346\204\237FOC\350\260\203\351\200\237\347\263\273\347\273\237\345\272\224\347\224\250 V01.pdf" index e923d75030654e1aff371751b1848fe2c64bb2b6..f055623f6848e0f7b744c57345a1ce0921c8d7b5 100644 Binary files "a/src/document/software/\345\237\272\344\272\216\345\217\214\347\224\265\351\230\273\347\224\265\346\265\201\351\207\207\346\240\267\347\232\204\347\224\265\346\234\272\346\227\240\346\204\237FOC\350\260\203\351\200\237\347\263\273\347\273\237\345\272\224\347\224\250 V06.pdf" and "b/src/document/software/\345\237\272\344\272\216\345\217\214\347\224\265\351\230\273\347\224\265\346\265\201\351\207\207\346\240\267\347\232\204\347\224\265\346\234\272\346\227\240\346\204\237FOC\350\260\203\351\200\237\347\263\273\347\273\237\345\272\224\347\224\250 V01.pdf" differ diff --git "a/src/document/software/\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" "b/src/document/software/\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..c67cdb17ffc6aa39fc2ecd3c6cf7d06d38d79054 Binary files /dev/null and "b/src/document/software/\346\257\225\346\230\207\347\274\226\350\257\221\345\231\250\344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\345\237\272\347\241\200\347\256\227\346\263\225\345\272\223API\350\257\264\346\230\216 V00B07.pdf" "b/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\345\237\272\347\241\200\347\256\227\346\263\225\345\272\223API\350\257\264\346\230\216 V00B07.pdf" deleted file mode 100644 index 20d793847db8509f37bf285cee38ee1757026a7b..0000000000000000000000000000000000000000 Binary files "a/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\345\237\272\347\241\200\347\256\227\346\263\225\345\272\223API\350\257\264\346\230\216 V00B07.pdf" and /dev/null differ diff --git "a/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\345\237\272\347\241\200\347\256\227\346\263\225\345\272\223API\350\257\264\346\230\216 V03.pdf" "b/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\345\237\272\347\241\200\347\256\227\346\263\225\345\272\223API\350\257\264\346\230\216 V03.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..0506edd4289ee4db2f1653c443ad02288fbfbd2f Binary files /dev/null and "b/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\345\237\272\347\241\200\347\256\227\346\263\225\345\272\223API\350\257\264\346\230\216 V03.pdf" differ diff --git "a/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\344\270\211\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V00B02.pdf" "b/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\344\270\211\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V01.pdf" similarity index 42% rename from "src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\344\270\211\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V00B02.pdf" rename to "src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\344\270\211\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V01.pdf" index a97cbeb899d9d62bbf461ab18d92a9e4a133625a..ea391062ff0bcf276819c2880360f76513c75911 100644 Binary files "a/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\344\270\211\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V00B02.pdf" and "b/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\344\270\211\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V01.pdf" differ diff --git "a/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\345\215\225\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V00B02.pdf" "b/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\345\215\225\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V01.pdf" similarity index 48% rename from "src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\345\215\225\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V00B02.pdf" rename to "src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\345\215\225\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V01.pdf" index 4065f3bcff4bb079f6ece835fe6c072b4a19541c..26ffd181c25851c404282b5b1f3dc87197fe1df2 100644 Binary files "a/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\345\215\225\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V00B02.pdf" and "b/src/document/software/\347\224\265\346\234\272\346\216\247\345\210\266\347\256\227\346\263\225\346\240\267\344\276\213\345\217\202\350\200\203\346\211\213\345\206\214-\345\215\225\347\224\265\351\230\273\351\207\207\346\240\267FOC\347\256\227\346\263\225 V01.pdf" differ diff --git "a/src/document/tools/HiSparkStudio \344\275\277\347\224\250\346\214\207\345\215\227 V00B05.pdf" "b/src/document/tools/HiSparkStudio \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" similarity index 45% rename from "src/document/tools/HiSparkStudio \344\275\277\347\224\250\346\214\207\345\215\227 V00B05.pdf" rename to "src/document/tools/HiSparkStudio \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" index 11d72ad42118c8fbbfae3a82d1c3e0f318697a02..96943cba2f2f1367a3af5ce71802d9819e60de1d 100644 Binary files "a/src/document/tools/HiSparkStudio \344\275\277\347\224\250\346\214\207\345\215\227 V00B05.pdf" and "b/src/document/tools/HiSparkStudio \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/tools/HiSpark\350\260\203\350\257\225\345\231\250\347\263\273\345\210\227 \344\275\277\347\224\250\346\214\207\345\215\227 V00B03.pdf" "b/src/document/tools/HiSpark\350\260\203\350\257\225\345\231\250\347\263\273\345\210\227 \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" similarity index 69% rename from "src/document/tools/HiSpark\350\260\203\350\257\225\345\231\250\347\263\273\345\210\227 \344\275\277\347\224\250\346\214\207\345\215\227 V00B03.pdf" rename to "src/document/tools/HiSpark\350\260\203\350\257\225\345\231\250\347\263\273\345\210\227 \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" index 8b99138e892e4adf00af85027a12d67671f64cfa..937a640ecf1f0e362782cc7cb82859a306f701ae 100644 Binary files "a/src/document/tools/HiSpark\350\260\203\350\257\225\345\231\250\347\263\273\345\210\227 \344\275\277\347\224\250\346\214\207\345\215\227 V00B03.pdf" and "b/src/document/tools/HiSpark\350\260\203\350\257\225\345\231\250\347\263\273\345\210\227 \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/tools/Motor Control Workbench \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" "b/src/document/tools/Motor Control Workbench \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..b1ef4ed7fd31764c2eacec5dda45c89e06803503 Binary files /dev/null and "b/src/document/tools/Motor Control Workbench \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/tools/Programmer \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" "b/src/document/tools/Programmer \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..5bcc4c7023547d6f583894a75cf38fa60bf985d4 Binary files /dev/null and "b/src/document/tools/Programmer \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git "a/src/document/tools/VariableTrace \344\275\277\347\224\250\346\214\207\345\215\227 V00B04.pdf" "b/src/document/tools/VariableTrace \344\275\277\347\224\250\346\214\207\345\215\227 V00B04.pdf" deleted file mode 100644 index 6e7e3e87ddd1ffb070d359408156c9813d3ef91b..0000000000000000000000000000000000000000 Binary files "a/src/document/tools/VariableTrace \344\275\277\347\224\250\346\214\207\345\215\227 V00B04.pdf" and /dev/null differ diff --git "a/src/document/tools/VariableTrace \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" "b/src/document/tools/VariableTrace \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..d7f1ead253b48650be3f31bbbbb8e089c2f1290e Binary files /dev/null and "b/src/document/tools/VariableTrace \344\275\277\347\224\250\346\214\207\345\215\227 V01.pdf" differ diff --git a/src/drivers/acmp/acmp_v1/inc/acmp_ip.h b/src/drivers/acmp/acmp_v1/inc/acmp_ip.h index 16c8de9401fd3f83159001189ce5ea655897d938..91c10ad9a94195b50a5424d9a578dc262d7deca4 100644 --- a/src/drivers/acmp/acmp_v1/inc/acmp_ip.h +++ b/src/drivers/acmp/acmp_v1/inc/acmp_ip.h @@ -140,9 +140,9 @@ typedef enum { /** * @brief ACMP output selection * @details Description: - * + ACMP_RESULT_SIMULATION ---- Simulate the original comparison result. - * + ACMP_RESULT_FILTER ---- Digital Filtering Comparison Results. - * + ACMP_RESULT_FILTER_BLOCK ---- Digital Filtering and Blocking Comparison Results. + * + ACMP_RESULT_SIMULATION ---- Original comparison results. + * + ACMP_RESULT_FILTER ---- Resulter after filtering. + * + ACMP_RESULT_FILTER_BLOCK ---- Result after masking. */ typedef enum { ACMP_RESULT_SIMULATION = 0x00000000U, diff --git a/src/drivers/acmp/acmp_v1/src/acmp.c b/src/drivers/acmp/acmp_v1/src/acmp.c index 4112f18c84520c2ca3f6838567e8dbde43c1d9f0..580d81bb5cbef65bf782f737a339e3ee8a254892 100644 --- a/src/drivers/acmp/acmp_v1/src/acmp.c +++ b/src/drivers/acmp/acmp_v1/src/acmp.c @@ -167,7 +167,7 @@ BASE_StatusType HAL_ACMP_DeInit(ACMP_Handle *acmpHandle) acmpHandle->baseAddress->ACMP_CTRL0.reg = BASE_CFG_DISABLE; /* Disable ACMP. */ acmpHandle->baseAddress->ACMP_CTRL1.reg = BASE_CFG_DISABLE; /* Clears the input and output status. */ acmpHandle->baseAddress->ACMP_CTRL2.reg = BASE_CFG_DISABLE; /* Clears the comparison result selection. */ - acmpHandle->baseAddress->ACMP_INTR.reg = BASE_CFG_DISABLE; /* Clear all interrrupt. */ + acmpHandle->baseAddress->ACMP_INTR.reg = ACMP_INTERRUPT_ENABLE; /* Write 1 to Clear all interrrupt. */ acmpHandle->userCallBack.AcmpEdgedCallBack = NULL; /* Clears all user callback functions. */ acmpHandle->userCallBack.AcmpNegativeCallBack = NULL; acmpHandle->userCallBack.AcmpPositiveCallBack = NULL; @@ -234,8 +234,7 @@ BASE_StatusType HAL_ACMP_ResultSelect(ACMP_Handle *acmpHandle, ACMP_ResultSelect acmpHandle->baseAddress->ACMP_CTRL2.BIT.cfg_acmp_out_sel = 0x1; /* 0x1: Resulter after filtering. */ break; case ACMP_RESULT_FILTER_BLOCK: - acmpHandle->baseAddress->ACMP_CTRL2.BIT.cfg_acmp_out_sel = 0x2; /* 0x2: Resulter after filtering - and blocking. */ + acmpHandle->baseAddress->ACMP_CTRL2.BIT.cfg_acmp_out_sel = 0x2; /* 0x2: Result after masking. */ break; default: return BASE_STATUS_ERROR; @@ -285,7 +284,7 @@ void HAL_ACMP_IrqHandler(void *handle) * @brief Register the callback function of ACMP handle. * @param acmpHandle Acmp Handle * @param typeID CallBack function type of user, @ref ACMP_CallBackFun_Type - * @param callBackFunc CallBack function of user, @ref ACMM_CallBackType + * @param callBackFunc CallBack function of user, @ref ACMP_CallBackType * @retval BASE_STATUS_OK Success * @retval BASE_STATUS_ERROR Parameter check fail */ diff --git a/src/drivers/acmp/acmp_v2/inc/acmp_ex.h b/src/drivers/acmp/acmp_v2/inc/acmp_ex.h new file mode 100644 index 0000000000000000000000000000000000000000..8b1b25a0076daa746957001990204ae4d2dd4c1d --- /dev/null +++ b/src/drivers/acmp/acmp_v2/inc/acmp_ex.h @@ -0,0 +1,51 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file acmp_ex.h + * @author MCU Driver Team + * @brief ACMP module driver. + * @details This file provides extend functions declaration of the acmp, + * + Set trim value. + */ + +/* Includes ------------------------------------------------------------------*/ +#ifndef McuMagicTag_ACMP_EX_H +#define McuMagicTag_ACMP_EX_H + +#include "acmp.h" + +/** + * @addtogroup ACMP_IP + * @{ + */ + +/** + * @defgroup ACMP_EX_API_Declaration ACMP HAL API EX + * @{ + */ + +/* ACMP trim value setting. */ +BASE_StatusType HAL_ACMP_SetTrimValueEx(ACMP_Handle *acmpHandle, unsigned char trimValue); + +/** + * @} + */ + +/** + * @} + */ +#endif /* McuMagicTag_ACMP_EX_H */ \ No newline at end of file diff --git a/src/drivers/acmp/acmp_v2/inc/acmp_ip.h b/src/drivers/acmp/acmp_v2/inc/acmp_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..b8b8f97ba101dc6c93bd58671e46325e3068728f --- /dev/null +++ b/src/drivers/acmp/acmp_v2/inc/acmp_ip.h @@ -0,0 +1,688 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file acmp_ip.h + * @author MCU Driver Team + * @brief ACMP module driver. + * This file provides DCL functions to manage ACMP and Definitions of specific parameters. + * + Definition of ACMP configuration parameters. + * + ACMP register mapping structure. + * + Parameters check functions. + * + Direct configuration layer interface. + */ + +#ifndef McuMagicTag_ACMP_IP_H +#define McuMagicTag_ACMP_IP_H + +#include "baseinc.h" + +#ifdef ACMP_PARAM_CHECK +#define ACMP_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM +#define ACMP_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET +#define ACMP_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else +#define ACMP_ASSERT_PARAM(para) ((void)0U) +#define ACMP_PARAM_CHECK_NO_RET(para) ((void)0U) +#define ACMP_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) +#endif + +#define ACMP_FILTER_STEP_MAX_VALUE 0x00000FFFEU + +/** + * @addtogroup ACMP + * @{ + */ + +/** + * @defgroup ACMP_IP ACMP_IP + * @brief ACMP_IP: acmp_v2. + * @{ + */ + +/** + * @defgroup ACMP_Param_Def ACMP Parameters Definition + * @brief Definition of ACMP configuration parameters + * @{ + */ + +/** + * @brief Comparator blking source type + * @details Description: + * + ACMP_BLKING_SRC_SOFT ---- The software configuration masks the window. + * + ACMP_BLKING_SRC_APT0 ---- APT0 output mask window. + * + ACMP_BLKING_SRC_APT1 ---- APT1 output mask window. + * + ACMP_BLKING_SRC_APT2 ---- APT2 output mask window. + * + ACMP_BLKING_SRC_APT3 ---- APT3 output mask window. + * + ACMP_BLKING_SRC_APT4 ---- APT4 output mask window. + * + ACMP_BLKING_SRC_APT5 ---- APT5 output mask window. + * + ACMP_BLKING_SRC_APT6 ---- APT6 output mask window. + * + ACMP_BLKING_SRC_APT7 ---- APT7 output mask window. + * + ACMP_BLKING_SRC_APT8 ---- APT8 output mask window. + */ +typedef enum { + ACMP_BLKING_SRC_SOFT = 0x00000000U, + ACMP_BLKING_SRC_APT0 = 0x00000001U, + ACMP_BLKING_SRC_APT1 = 0x00000002U, + ACMP_BLKING_SRC_APT2 = 0x00000003U, + ACMP_BLKING_SRC_APT3 = 0x00000004U, + ACMP_BLKING_SRC_APT4 = 0x00000005U, + ACMP_BLKING_SRC_APT5 = 0x00000006U, + ACMP_BLKING_SRC_APT6 = 0x00000007U, + ACMP_BLKING_SRC_APT7 = 0x00000008U, + ACMP_BLKING_SRC_APT8 = 0x00000009U, +} ACMP_BlkingSrcType; + +/** + * @brief Comparator hysteresis voltage + * @details Description: + * + ACMP_HYS_VOL_ZERO ---- Hysteresis voltage 0 mv. + * + ACMP_HYS_VOL_10MV ---- Hysteresis voltage 10 mv. + * + ACMP_HYS_VOL_20MV ---- Hysteresis voltage 20 mv. + * + ACMP_HYS_VOL_30MV ---- Hysteresis voltage 30 mv. + */ +typedef enum { + ACMP_HYS_VOL_ZERO = 0x00000000U, + ACMP_HYS_VOL_10MV = 0x00000001U, + ACMP_HYS_VOL_20MV = 0x00000002U, + ACMP_HYS_VOL_30MV = 0x00000003U, +} ACMP_HystVol; + +/** + * @brief ACMP P port input select. + * @details Description: + * + ACMP_INPUT_P_SELECT0 ---- Signal source PGA0_OUT. + * + ACMP_INPUT_P_SELECT1 ---- Signal source PGA1_OUT. + * + ACMP_INPUT_P_SELECT2 ---- From pin (GPIO0_5). + * + ACMP_INPUT_P_SELECT3 ---- From pin (GPIO2_5). + * + ACMP_INPUT_P_SELECT4 ---- From pin (GPIO3_5). + * + ACMP_INPUT_P_SELECT5 ---- Signal source DAC_OUT. + */ +typedef enum { + ACMP_INPUT_P_SELECT0 = 0x00000000U, + ACMP_INPUT_P_SELECT1 = 0x00000001U, + ACMP_INPUT_P_SELECT2 = 0x00000002U, + ACMP_INPUT_P_SELECT3 = 0x00000003U, + ACMP_INPUT_P_SELECT4 = 0x00000004U, + ACMP_INPUT_P_SELECT5 = 0x00000005U, +} ACMP_InputPSel; + +/** + * @brief ACMP N port input select. + * @details Description: + * + ACMP_INPUT_N_SELECT0 ---- Signal source DAC_OUT. + * + ACMP_INPUT_N_SELECT1 ---- None. + * + ACMP_INPUT_N_SELECT2 ---- From pin (GPIO0_6). + * + ACMP_INPUT_N_SELECT3 ---- From pin (GPIO2_6). + * + ACMP_INPUT_N_SELECT4 ---- From pin (GPIO3_6). + * + ACMP_INPUT_N_SELECT5 ---- Signal source DAC_OUT. + */ +typedef enum { + ACMP_INPUT_N_SELECT0 = 0x00000000U, + ACMP_INPUT_N_SELECT1 = 0x00000001U, + ACMP_INPUT_N_SELECT2 = 0x00000002U, + ACMP_INPUT_N_SELECT3 = 0x00000003U, + ACMP_INPUT_N_SELECT4 = 0x00000004U, + ACMP_INPUT_N_SELECT5 = 0x00000005U, +} ACMP_InputNSel; + +/** + * @brief Comparator output polarity + */ +typedef enum { + ACMP_OUT_NOT_INVERT = 0x00000000U, + ACMP_OUT_INVERT = 0x00000001U, +} ACMP_OutputPolarity; + +/** + * @brief ACMP output selection + * @details Description: + * + ACMP_RESULT_SIMULATION ---- Simulate the original comparison result. + * + ACMP_RESULT_FILTER ---- Digital Filtering Comparison Results. + * + ACMP_RESULT_FILTER_BLOCK ---- Digital Filtering and Blocking Comparison Results. + */ +typedef enum { + ACMP_RESULT_SIMULATION = 0x00000000U, + ACMP_RESULT_FILTER = 0x00000001U, + ACMP_RESULT_FILTER_BLOCK = 0x00000002U, +} ACMP_ResultSelect; + +/** + * @brief Comparator filter mode + * @details Description: + * + ACMP_FILTER_NONE ---- Raw analog comparison. + * + ACMP_FILTER_BLOCK ---- Blocking function. + * + ACMP_FILTER_FILTER ---- Filtering funciton. + * + ACMP_FILTER_BOTH ---- Filtering and Blocking function. + */ +typedef enum { + ACMP_FILTER_NONE = 0x00000000U, + ACMP_FILTER_BLOCK = 0x00000001U, + ACMP_FILTER_FILTER = 0x00000002U, + ACMP_FILTER_BOTH = 0x00000003U, +} ACMP_FilterMode; + +/** + * @brief Comparator filter control structure + */ +typedef struct { + ACMP_FilterMode filterMode; /**< ACMP filter mode. */ + ACMP_BlkingSrcType blkingSrcSelect; /**< Blocking source select.*/ + unsigned short filterStep; /**< Filter Step. */ + bool blkingPorty; /**< Polarity select of the mask window. */ +} ACMP_FilterCtrl; + +/** + * @brief Comparator input and output configuration structure + */ +typedef struct { + ACMP_OutputPolarity polarity; /**< output polarity settings */ + ACMP_InputPSel inputPNum; /**< ACMP input positive number */ + ACMP_InputNSel inputNNum; /**< ACMP input negative number */ +} ACMP_InOutConfig; + +/** + * @brief ACMP user callback function type. + */ +typedef enum { + ACMP_POS_INT = 0x00000000U, + ACMP_NEG_INT = 0x00000001U, + ACMP_EDGE_INT = 0x00000002U, +} ACMP_CallBackFun_Type; + +/** + * @brief ACMP user interrupt callback function. + */ +typedef struct { + void (* AcmpPositiveCallBack)(void *handle); /**< Rising edge interrupt callback function. */ + void (* AcmpNegativeCallBack)(void *handle); /**< Falling edge interrupt callback function. */ + void (* AcmpEdgedCallBack)(void *handle); /**< Flip edge interrupt callback function. */ +} ACMP_UserCallBack; + +/** + * @brief ACMP extend configure. + */ +typedef struct { +} ACMP_ExtendHandle; + +/** + * @} + */ + +/** + * @defgroup ACMP_REG_Definition ACMP Register Structure. + * @brief ACMP Register Structure Definition. + * @{ + */ + +/** + * @brief ACMP control reg 0. + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_acmp_enh : 1; /**< Comparator enable signal. */ + unsigned int reserved_0 : 31; + } BIT; +} volatile ACMP_CTRL_REG0; + +/** + * @brief ACMP control reg 1. + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_acmp_input_psel : 3; /**< Input P vin selection */ + unsigned int da_acmp_input_nsel : 3; /**< Input N vin selection */ + unsigned int reserved_0 : 26; + } BIT; +} volatile ACMP_CTRL_REG1; + +/** + * @brief ACMP control reg 2. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cfg_acmp_out_sel : 2; /**< Comparator output result selection: + 0: original comparison result; + 1: result after filtering; + 2: masked result; + 3: reversed. */ + unsigned int cfg_acmp_out_inv : 1; /**< Comparator result polarity selection: + 0: The result is not reversed. + 1: The result is reversed. */ + unsigned int reserved_0 : 29; + } BIT; +} volatile ACMP_CTRL_REG2; + +/** + * @brief ACMP filtering control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cfg_acmp_filter_en : 1; /**< Comparator filtering enable: + 0: disabled; + 1: enabled. */ + unsigned int cfg_acmp_filter_step : 16; /**< Filter step size of the comparator. */ + unsigned int reserved_0 : 15; + } BIT; +} volatile ACMP_CTRL_REG3; + +/** + * @brief ACMP mask control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cfg_acmp_blk_en : 1; /**< Comparator mask enable: + 0: disabled; + 1: enabled. */ + unsigned int reserved_0 : 7; + unsigned int cfg_acmp_blk_sel : 4; /**< Comparator Mask Window Selection: + 0: The window is masked by software. + 1: APT0 output mask window; + 2: APT1 output mask window; + 3: APT2 output mask window; + 4: APT3 output mask window; + 5: APT4 output mask window; + 6: APT5 output mask window; + 7: APT6 output mask window; + 8: APT7 output mask window; + 9: APT8 output mask window; + else: reversed. */ + unsigned int reserved_1 : 4; + unsigned int cfg_acmp_blk_win : 1; /**< The software configuration mask window is displayed. */ + unsigned int reserved_2 : 7; + unsigned int cfg_acmp_blk_pol_sel : 1; /**< Select the polarity of the mask window. + 0: The high-level mask window is valid. + 1: The low-level shielding window is valid. */ + unsigned int cfg_acmp_blk_rslt_pol : 1; /**< Polarity selection of the masking result: + 0: The masking result is low level. + 1: The masking result is high level. */ + unsigned int reserved_3 : 6; + } BIT; +} volatile ACMP_CTRL_REG4; + + +/** + * @brief ACMP interrupt raw status register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int intr_acmp_edge : 1; /**< Comparison result reversal edge interrupt status. */ + unsigned int intr_acmp_neg : 1; /**< Comparison result falling edge interrupt status. */ + unsigned int intr_acmp_pos : 1; /**< Interrupt status on the rising edge of comparison result. */ + unsigned int reserved : 29; + } BIT; +} volatile ACMP_INTR_REG; + + +/** + * @brief Masked ACMP interrupt status register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int intr_acmp_edge_msk : 1; /**< Status of comparison result reversal edge masked interrupt. */ + unsigned int intr_acmp_neg_msk : 1; /**< Int status after falling edge of comparison result is masked. */ + unsigned int intr_acmp_pos_msk : 1; /**< Int status after rising edge of comparison result is masked. */ + unsigned int reserved : 29; + } BIT; +} volatile ACMP_INTR_MSK_REG; + + +/** + * @brief ACMP interrupt mask. + */ +typedef union { + unsigned int reg; + struct { + unsigned int intr_acmp_edge_mask : 1; /**< Comparison result reversal edge interrupt mask register: + 0: mask interrupts. + 1: not masked. */ + unsigned int intr_acmp_neg_mask : 1; /**< Comparison result falling edge interrupt mask register: + 0: mask interrupts. + 1: not masked. */ + unsigned int intr_acmp_pos_mask : 1; /**< Comparison result rising edge interrupt mask register: + 0: mask interrupts. + 1: not masked. */ + unsigned int reserved : 29; + } BIT; +} volatile ACMP_INTR_MASK_REG; + + +/** + * @brief ACMP result register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cmp_ana_rslt : 1; /**< Original comparison result. */ + unsigned int cmp_filter_rslt : 1; /**< Filtered result of the comparator. */ + unsigned int cmp_blk_rslt : 1; /**< Result after the comparator is masked. */ + unsigned int reserved : 29; + } BIT; +} volatile ACMP_RSLT_REG; + +/** + * @brief ACMP enable delay register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cfg_acmp_en_dly : 8; /**< Indicates the delay for enabling ACMP (us). */ + unsigned int reserved : 24; + } BIT; +} volatile ACMP_EN_DLY_REG; + +/** + * @brief ACMP test register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_acmp_test_enh : 1; /**< Test enable signal: + 0: disabled; + 1: enabled. */ + unsigned int da_acmp_test_sel : 4; /**< Test signal strobe. */ + unsigned int reserved : 27; + } BIT; +} volatile ACMP_TEST_REG; + + +/** + * @brief ACMP TRIM register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_acmp_trim : 8; /**< ACMP TIRM register. */ + unsigned int reserved : 24; + } BIT; +} volatile ACMP_TRIM_REG; + + +/** + * @brief ACMP reserved register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_acmp_rsv : 2; /**< Reserved comparator register: + <1: 0>: The hysteresis voltage is selected. */ + unsigned int reserved : 30; + } BIT; +} volatile ACMP_RSV_REG; + +/** + * @brief ACMP registers definition structure. + */ +typedef struct _ACMP_RegStruct { + ACMP_CTRL_REG0 ACMP_CTRL0; /**< ACMP control register 0. Offset address: 0x00000000U. */ + ACMP_CTRL_REG1 ACMP_CTRL1; /**< ACMP control register 1. Offset address: 0x00000004U. */ + ACMP_CTRL_REG2 ACMP_CTRL2; /**< ACMP control register 2. Offset address: 0x00000008U. */ + char space0[52]; + ACMP_CTRL_REG3 ACMP_CTRL3; /**< ACMP filtering control register. Offset address: 0x00000040U. */ + ACMP_CTRL_REG4 ACMP_CTRL4; /**< ACMP mask control register. Offset address: 0x00000044U. */ + char space1[8]; + ACMP_INTR_REG ACMP_INTR; /**< ACMP interrupt raw status register. Offset address: 0x00000050U. */ + ACMP_INTR_MSK_REG ACMP_INTR_MSK; /**< Masked ACMP interrupt status register. Offset address: 0x00000054U. */ + ACMP_INTR_MASK_REG ACMP_INTR_MASK; /**< ACMP interrupt mask register. Offset address: 0x00000058U. */ + char space2[20]; + ACMP_RSLT_REG ACMP_RSLT; /**< ACMP result register. Offset address: 0x00000070U. */ + char space3[12]; + ACMP_EN_DLY_REG ACMP_EN_DLY; /**< ACMP enable delay register. Offset address: 0x00000080U. */ + char space4[4]; + ACMP_TRIM_REG ACMP_TRIM; /**< ACMP TRIM register. Offset address: 0x00000088U. */ + ACMP_RSV_REG ACMP_RSV; /**< ACMP reserved register. Offset address: 0x0000008CU. */ +} volatile ACMP_RegStruct; + +/* Parameter Check------------------------------------------------------------------ */ +/** + * @brief Verify ACMP output polarity configuration. + * @param polarity: ACMP output polarity + * @retval true + * @retval false + */ +static inline bool IsACMPOutputPolarity(ACMP_OutputPolarity polarity) +{ + return ((polarity == ACMP_OUT_NOT_INVERT) || (polarity == ACMP_OUT_INVERT)); +} + +/** + * @brief Verify ACMP input P number. + * @param pNumber: ACMP output source select + * @retval true + * @retval false + */ +static inline bool IsACMPInputPNumber(ACMP_InputPSel pNumber) +{ + return (pNumber <= ACMP_INPUT_P_SELECT5); +} + +/** + * @brief Verify ACMP input N number. + * @param NNumber: ACMP output source select + * @retval true + * @retval false + */ +static inline bool IsACMPInputNNumber(ACMP_InputNSel NNumber) +{ + return (NNumber <= ACMP_INPUT_N_SELECT5); +} + +/** + * @brief Verify ACMP blocking source type. + * @param BlkingSrcType: ACMP output source select + * @retval true + * @retval false + */ +static inline bool IsACMPBlkingSrcType(ACMP_BlkingSrcType BlkingSrcType) +{ + return (BlkingSrcType <= ACMP_BLKING_SRC_APT8); +} + +/** + * @brief Verify ACMP output result selection + * @param resultSelection: ACMP output source selection. + * @retval true + * @retval false + */ +static inline bool IsACMPResultSeletion(ACMP_ResultSelect resultSelection) +{ + return (resultSelection <= ACMP_RESULT_FILTER_BLOCK); +} + +/* Direct configuration layer ------------------------------------------------*/ +/** + * @brief Set input switch + * @param acmpx: ACMP register base address. + * @param inputP: ACMP inputP selection. @ref ACMP_VinSel + * @param inputN: ACMP inputN selection. @ref ACMP_VinSel + * @retval None. + */ +static inline void DCL_ACMP_SetInputSwith(ACMP_RegStruct *acmpx, ACMP_InputPSel inputP, ACMP_InputNSel inputN) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + ACMP_PARAM_CHECK_NO_RET(inputP >= ACMP_INPUT_P_SELECT0); + ACMP_PARAM_CHECK_NO_RET(inputP <= ACMP_INPUT_P_SELECT5); + ACMP_PARAM_CHECK_NO_RET(inputN >= ACMP_INPUT_N_SELECT0); + ACMP_PARAM_CHECK_NO_RET(inputN <= ACMP_INPUT_N_SELECT5); + acmpx->ACMP_CTRL1.BIT.da_acmp_input_nsel = inputN; /* Input port on the P side. */ + acmpx->ACMP_CTRL1.BIT.da_acmp_input_psel = inputP; /* Input port on the N side. */ +} + +/** + * @brief ACMP output(deshark and synchronize) source. + * @param acmp: ACMP register base address. + * @param resultSelection: config value. @ref ACMP_ResultSelect + * @retval None. + */ +static inline void DCL_ACMP_SetCmpOutputSrc(ACMP_RegStruct *acmpx, ACMP_ResultSelect resultSelection) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + ACMP_PARAM_CHECK_NO_RET(resultSelection >= ACMP_RESULT_SIMULATION); + ACMP_PARAM_CHECK_NO_RET(resultSelection <= ACMP_RESULT_FILTER_BLOCK); + acmpx->ACMP_CTRL2.BIT.cfg_acmp_out_sel = resultSelection; /* ACMP output result select. */ +} + +/** + * @brief Comparator enable blking function + * @param acmpx: ACMP register base address. + * @retval None. + */ +static inline void DCL_ACMP_EnableCmpBlking(ACMP_RegStruct *acmpx) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + acmpx->ACMP_CTRL4.BIT.cfg_acmp_blk_en = BASE_CFG_ENABLE; +} + +/** + * @brief Comparator disable blking function + * @param acmpx: ACMP register base address. + * @retval None. + */ +static inline void DCL_ACMP_DisableCmpBlking(ACMP_RegStruct *acmpx) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + acmpx->ACMP_CTRL4.BIT.cfg_acmp_blk_en = BASE_CFG_DISABLE; +} + +/** + * @brief Enable the software masking window. + * @param acmpx: ACMP register base address. + * @retval None. + */ +static inline void DCL_ACMP_EnableSoftBlking(ACMP_RegStruct *acmpx) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + acmpx->ACMP_CTRL4.BIT.cfg_acmp_blk_win = BASE_CFG_ENABLE; +} + +/** + * @brief Disable the software masking window. + * @param acmpx: ACMP register base address. + * @retval None. + */ +static inline void DCL_ACMP_DisableSoftBlking(ACMP_RegStruct *acmpx) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + acmpx->ACMP_CTRL4.BIT.cfg_acmp_blk_win = BASE_CFG_DISABLE; +} + +/** + * @brief Set blking source. + * @param acmpx: ACMP register base address. + * @param source: Source of blking. @ref ACMP_BlkingSrcType + * @retval None. + */ +static inline void DCL_ACMP_SetCmpBlkingSource(ACMP_RegStruct *acmpx, ACMP_BlkingSrcType source) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + ACMP_PARAM_CHECK_NO_RET(source >= ACMP_BLKING_SRC_SOFT); + ACMP_PARAM_CHECK_NO_RET(source <= ACMP_BLKING_SRC_APT8); + acmpx->ACMP_CTRL4.BIT.cfg_acmp_blk_sel = source; +} + +/** + * @brief Set comparator hysteresis voltage. + * @param acmpx: ACMP register base address. + * @param volSelect: Hysteresis voltage selection. @ref ACMP_HystVol + * @retval None. + */ +static inline void DCL_ACMP_SetCmpHysteresisVoltage(ACMP_RegStruct *acmpx, ACMP_HystVol volSelect) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + ACMP_PARAM_CHECK_NO_RET(volSelect >= ACMP_HYS_VOL_ZERO); + ACMP_PARAM_CHECK_NO_RET(volSelect <= ACMP_HYS_VOL_30MV); + acmpx->ACMP_RSV.BIT.da_acmp_rsv = volSelect; +} + +/** + * @brief Set comparator's output polarity + * @param acmp: ACMP register base address. + * @param polarity: output polarity. @ref ACMP_OutputPolarity + * @retval None. + */ +static inline void DCL_ACMP_SetCmpOutputPolarity(ACMP_RegStruct *acmpx, ACMP_OutputPolarity polarity) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + ACMP_PARAM_CHECK_NO_RET(polarity >= ACMP_OUT_NOT_INVERT); + ACMP_PARAM_CHECK_NO_RET(polarity <= ACMP_OUT_INVERT); + acmpx->ACMP_CTRL2.BIT.cfg_acmp_out_inv = polarity; +} + +/** + * @brief Reading compare result after blocking. + * @param acmp: ACMP register base address. + * @retval Blocked result. + */ +static inline unsigned int DCL_ACMP_GetCmpOutValueAfterBlking(ACMP_RegStruct *acmpx) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + return acmpx->ACMP_RSLT.BIT.cmp_blk_rslt; +} + +/** + * @brief Reading compare result after filtering. + * @param acmp: ACMP register base address. + * @retval filtered result. + */ +static inline unsigned int DCL_ACMP_GetCmpOutValueAfterFilter(ACMP_RegStruct *acmpx) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + return acmpx->ACMP_RSLT.BIT.cmp_filter_rslt; +} + +/** + * @brief Reading original compare result + * @param acmp: ACMP register base address. + * @retval original result. + */ +static inline unsigned int DCL_ACMP_GetCmpOutValueOriginal(ACMP_RegStruct *acmpx) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + return acmpx->ACMP_RSLT.BIT.cmp_ana_rslt; +} + +/** + * @brief Set deshark step by clock. + * @param acmp: ACMP register base address. + * @param step: ACMP filter step. + * @retval None. + */ +static inline void DCL_ACMP_SetFilterStep(ACMP_RegStruct *acmpx, unsigned short step) +{ + ACMP_ASSERT_PARAM(IsACMPInstance(acmpx)); + ACMP_PARAM_CHECK_NO_RET(step <= ACMP_FILTER_STEP_MAX_VALUE); + acmpx->ACMP_CTRL3.BIT.cfg_acmp_filter_step = step; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif diff --git a/src/drivers/acmp/acmp_v2/src/acmp.c b/src/drivers/acmp/acmp_v2/src/acmp.c new file mode 100644 index 0000000000000000000000000000000000000000..f22d099fbe8a62b35887ff73da6da546c229a5ae --- /dev/null +++ b/src/drivers/acmp/acmp_v2/src/acmp.c @@ -0,0 +1,313 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file acmp.c + * @author MCU Driver Team. + * @brief ACMP HAL level module driver. + * This file provides firmware functions to manage the following + * functionalities of ACMP. + * + Comparator's Initialization and de-initialization functions + * + Set Comparator's hysteresis voltage function + * + Set software blking valid function + * + Set software blking invalid function + */ +#include "acmp.h" +#include "assert.h" + + +/* Define -------------- */ +#define ACMP_INTERRUPT_ENABLE 0b111 +#define ACMP_POS_INTERUPT 0b100 +#define ACMP_NEG_INTERUPT 0b010 +#define ACMP_EDGE_INTERRUPT 0b001 + + +/** + * @brief Input and output initialization of comparator + * @param acmpHandle: ACMP handle. + * @retval None. + */ +static void ACMP_InputOutputInit(ACMP_Handle *acmpHandle) +{ + ACMP_ASSERT_PARAM(acmpHandle != NULL); + ACMP_ASSERT_PARAM(IsACMPInstance(acmpHandle->baseAddress)); + ACMP_PARAM_CHECK_NO_RET(IsACMPOutputPolarity(acmpHandle->inOutConfig.polarity)); + /* Check input multiplexing selection and input switch selection */ + ACMP_PARAM_CHECK_NO_RET(IsACMPInputPNumber(acmpHandle->inOutConfig.inputPNum)); + ACMP_PARAM_CHECK_NO_RET(IsACMPInputNNumber(acmpHandle->inOutConfig.inputNNum)); + /* input positive selection */ + acmpHandle->baseAddress->ACMP_CTRL1.BIT.da_acmp_input_psel = acmpHandle->inOutConfig.inputPNum; + /* input negative selection */ + acmpHandle->baseAddress->ACMP_CTRL1.BIT.da_acmp_input_nsel = acmpHandle->inOutConfig.inputNNum; + /* output polarity selection */ + acmpHandle->baseAddress->ACMP_CTRL2.BIT.cfg_acmp_out_inv = acmpHandle->inOutConfig.polarity; +} + +/** + * @brief Filter initialization of comparator + * @param acmpHandle: ACMP handle. + * @retval None. + */ +static void ACMP_FilterInit(ACMP_Handle *acmpHandle) +{ + ACMP_ASSERT_PARAM(acmpHandle != NULL); + ACMP_ASSERT_PARAM(IsACMPInstance(acmpHandle->baseAddress)); + unsigned short blkingSrc; + switch (acmpHandle->filterCtrl.filterMode) { + case ACMP_FILTER_NONE: /* The filtering function is not applicable. */ + acmpHandle->baseAddress->ACMP_CTRL3.BIT.cfg_acmp_filter_en = BASE_CFG_DISABLE; /* Disable filtering */ + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_en = BASE_CFG_DISABLE; /* Disable blocking */ + + acmpHandle->baseAddress->ACMP_CTRL2.BIT.cfg_acmp_out_sel = 0x0; /* 0x0: Output raw comparison result. */ + break; + case ACMP_FILTER_BLOCK: /* Use the blockinng function. */ + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_en = BASE_CFG_ENABLE; /* Enable blocking. */ + blkingSrc = acmpHandle->filterCtrl.blkingSrcSelect; + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_sel = blkingSrc; /* Setting Blking source */ + if (blkingSrc == ACMP_BLKING_SRC_SOFT) { + /* Sets the polarity of the window.. */ + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_pol_sel = acmpHandle->filterCtrl.blkingPorty; + } else { + /* Blocking source from apt window. */ + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_pol_sel = BASE_CFG_ENABLE; + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_rslt_pol = BASE_CFG_DISABLE; + } + acmpHandle->baseAddress->ACMP_CTRL2.BIT.cfg_acmp_out_sel = 0x2; /* 0x2: Outputs digital filtered and + masked comparison results */ + break; + case ACMP_FILTER_FILTER: /* Set the filtering function. */ + acmpHandle->baseAddress->ACMP_CTRL3.BIT.cfg_acmp_filter_en = BASE_CFG_ENABLE; /* Enable filtering. */ + /* Filter length setting. */ + acmpHandle->baseAddress->ACMP_CTRL3.BIT.cfg_acmp_filter_step = acmpHandle->filterCtrl.filterStep; + + acmpHandle->baseAddress->ACMP_CTRL2.BIT.cfg_acmp_out_sel = 0x1; /* 0x1: Outputs filtering result. */ + break; + case ACMP_FILTER_BOTH: /* Use filtering and shielding functions. */ + acmpHandle->baseAddress->ACMP_CTRL3.BIT.cfg_acmp_filter_en = BASE_CFG_ENABLE; /* Enable filtering. */ + acmpHandle->baseAddress->ACMP_CTRL3.BIT.cfg_acmp_filter_step = acmpHandle->filterCtrl.filterStep; + + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_en = BASE_CFG_ENABLE; /* Enable blocking. */ + blkingSrc = acmpHandle->filterCtrl.blkingSrcSelect; + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_sel = blkingSrc; /* Setting blocking source. */ + if (blkingSrc == ACMP_BLKING_SRC_SOFT) { + /* Setting Blking source from software. */ + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_pol_sel = acmpHandle->filterCtrl.blkingPorty; + } else { + /* Blocking source from apt window. */ + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_pol_sel = BASE_CFG_ENABLE; + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_rslt_pol = BASE_CFG_DISABLE; + } + acmpHandle->baseAddress->ACMP_CTRL2.BIT.cfg_acmp_out_sel = 0x2; /* 0x2: Outputs digital filtered and + masked comparison results */ + break; + default: + acmpHandle->baseAddress->ACMP_CTRL3.BIT.cfg_acmp_filter_en = BASE_CFG_DISABLE; /* Disable filtering. */ + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_en = BASE_CFG_DISABLE; /* Disable blocking. */ + break; + } +} + +/** + * @brief Comparator HAL Init + * @param acmpHandle: ACMP handle. + * @retval BASE_StatusType: OK, ERROR + */ +BASE_StatusType HAL_ACMP_Init(ACMP_Handle *acmpHandle) +{ + ACMP_ASSERT_PARAM(acmpHandle != NULL); + ACMP_ASSERT_PARAM(IsACMPInstance(acmpHandle->baseAddress)); + /* Parameter macro check. */ + ACMP_PARAM_CHECK_WITH_RET(acmpHandle->hysteresisVol >= ACMP_HYS_VOL_ZERO, BASE_STATUS_ERROR); + ACMP_PARAM_CHECK_WITH_RET(acmpHandle->hysteresisVol <= ACMP_HYS_VOL_30MV, BASE_STATUS_ERROR); + ACMP_PARAM_CHECK_WITH_RET(acmpHandle->filterCtrl.filterStep >= 0, BASE_STATUS_ERROR); + ACMP_PARAM_CHECK_WITH_RET(acmpHandle->filterCtrl.filterStep <= ACMP_FILTER_STEP_MAX_VALUE, BASE_STATUS_ERROR); + ACMP_PARAM_CHECK_WITH_RET(IsACMPBlkingSrcType(acmpHandle->filterCtrl.blkingSrcSelect), BASE_STATUS_ERROR); + /* Enable ACMP. */ + acmpHandle->baseAddress->ACMP_CTRL0.BIT.da_acmp_enh = BASE_CFG_ENABLE; + /* Enable ACMP interrupt. */ + if (acmpHandle->interruptEn == BASE_CFG_SET) { + acmpHandle->baseAddress->ACMP_INTR_MASK.reg = ACMP_INTERRUPT_ENABLE; /* Configure acmp interrupt. */ + } else { + acmpHandle->baseAddress->ACMP_INTR_MASK.reg = BASE_CFG_UNSET; /* Disable acmp interrupt. */ + } + /* ACMP input and output settings. */ + ACMP_InputOutputInit(acmpHandle); + /* ACMP comparison filtering function. */ + ACMP_FilterInit(acmpHandle); + /* Set hysteresis voltage */ + HAL_ACMP_SetHystVol(acmpHandle, acmpHandle->hysteresisVol); + + BASE_FUNC_DELAY_US(150); /* After the configuration is complete, a delay of 150 us is required. */ + return BASE_STATUS_OK; +} + +/** + * @brief Comparator HAL DeInit + * @param acmpHandle: ACMP handle. + * @retval BASE_StatusType: OK, ERROR + */ +BASE_StatusType HAL_ACMP_DeInit(ACMP_Handle *acmpHandle) +{ + ACMP_ASSERT_PARAM(acmpHandle != NULL); + ACMP_ASSERT_PARAM(IsACMPInstance(acmpHandle->baseAddress)); + acmpHandle->baseAddress->ACMP_CTRL0.reg = BASE_CFG_DISABLE; /* Disable ACMP. */ + acmpHandle->baseAddress->ACMP_CTRL1.reg = BASE_CFG_DISABLE; /* Clears the input and output status. */ + acmpHandle->baseAddress->ACMP_CTRL2.reg = BASE_CFG_DISABLE; /* Clears the comparison result selection. */ + acmpHandle->baseAddress->ACMP_INTR.reg = ACMP_INTERRUPT_ENABLE; /* Write 1 to Clear all interrrupt. */ + acmpHandle->userCallBack.AcmpEdgedCallBack = NULL; /* Clears all user callback functions. */ + acmpHandle->userCallBack.AcmpNegativeCallBack = NULL; + acmpHandle->userCallBack.AcmpPositiveCallBack = NULL; + return BASE_STATUS_OK; +} + +/** + * @brief Set hysteresis Voltage + * @param acmpHandle: ACMP handle. + * @param voltage: hysteresis voltage to be set. @ref ACMP_HystVol + * @retval None. + */ +void HAL_ACMP_SetHystVol(ACMP_Handle *acmpHandle, ACMP_HystVol voltage) +{ + ACMP_ASSERT_PARAM(acmpHandle != NULL); + ACMP_ASSERT_PARAM(IsACMPInstance(acmpHandle->baseAddress)); + ACMP_PARAM_CHECK_NO_RET(voltage >= ACMP_HYS_VOL_ZERO); + ACMP_PARAM_CHECK_NO_RET(voltage <= ACMP_HYS_VOL_30MV); + acmpHandle->baseAddress->ACMP_RSV.BIT.da_acmp_rsv = voltage; /* Hysteresis voltage setting. */ +} + +/** + * @brief Set blocking valid + * @param acmpHandle: ACMP handle. + * @retval None. + */ +void HAL_ACMP_BlkingValid(ACMP_Handle *acmpHandle) +{ + ACMP_ASSERT_PARAM(acmpHandle != NULL); + ACMP_ASSERT_PARAM(IsACMPInstance(acmpHandle->baseAddress)); + /* Enable Blocking function. */ + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_en = BASE_CFG_ENABLE; +} + +/** + * @brief Set blocking invalid + * @param acmpHandle: ACMP handle. + * @retval None. + */ +void HAL_ACMP_BlkingInvalid(ACMP_Handle *acmpHandle) +{ + ACMP_ASSERT_PARAM(acmpHandle != NULL); + ACMP_ASSERT_PARAM(IsACMPInstance(acmpHandle->baseAddress)); + acmpHandle->baseAddress->ACMP_CTRL4.BIT.cfg_acmp_blk_en = BASE_CFG_DISABLE; /* Disable blocking function. */ +} + +/** + * @brief Sets the output result of ACMP. + * @param acmpHandle: ACMP handle. + * @param resultSelect: ACMP result output options. + * @retval BASE_StatusType: OK, ERROR. + */ +BASE_StatusType HAL_ACMP_ResultSelect(ACMP_Handle *acmpHandle, ACMP_ResultSelect resultSelect) +{ + ACMP_ASSERT_PARAM(acmpHandle != NULL); + ACMP_ASSERT_PARAM(IsACMPInstance(acmpHandle->baseAddress)); + ACMP_PARAM_CHECK_WITH_RET(IsACMPResultSeletion(resultSelect), BASE_STATUS_ERROR); + /* Output result selection of the comparator. */ + switch (resultSelect) { + case ACMP_RESULT_SIMULATION: + acmpHandle->baseAddress->ACMP_CTRL2.BIT.cfg_acmp_out_sel = 0x0; /* 0x0: Original comparison results. */ + break; + case ACMP_RESULT_FILTER: + acmpHandle->baseAddress->ACMP_CTRL2.BIT.cfg_acmp_out_sel = 0x1; /* 0x1: Resulter after filtering. */ + break; + case ACMP_RESULT_FILTER_BLOCK: + acmpHandle->baseAddress->ACMP_CTRL2.BIT.cfg_acmp_out_sel = 0x2; /* 0x2: Resulter after filtering + and blocking. */ + break; + default: + return BASE_STATUS_ERROR; + } + return BASE_STATUS_OK; +} + +/** + * @brief ACMP Interrupt service processing function. + * @param handle ACMP handle. + * @retval None. + */ +void HAL_ACMP_IrqHandler(void *handle) +{ + ACMP_ASSERT_PARAM(handle != NULL); + ACMP_Handle *acmpHandle = (ACMP_Handle *)handle; + ACMP_ASSERT_PARAM(IsACMPInstance(acmpHandle->baseAddress)); + /* Check interrupt type */ + if (acmpHandle->baseAddress->ACMP_INTR_MSK.BIT.intr_acmp_pos_msk == BASE_CFG_ENABLE) { + /* Rising Edge Interrupt. */ + acmpHandle->baseAddress->ACMP_INTR.reg = ACMP_POS_INTERUPT; /* Clears the rising edge interrupt. */ + /* Call the rising edge user interrupt function. */ + if (acmpHandle->userCallBack.AcmpPositiveCallBack != NULL) { + acmpHandle->userCallBack.AcmpPositiveCallBack(acmpHandle); + } + } + if (acmpHandle->baseAddress->ACMP_INTR_MSK.BIT.intr_acmp_neg_msk == BASE_CFG_ENABLE) { + /* Falling Edge Interrupt. */ + acmpHandle->baseAddress->ACMP_INTR.reg = ACMP_NEG_INTERUPT; /* Clears falling Edge Interrupt. */ + /* Call the falling edge user interrupt function. */ + if (acmpHandle->userCallBack.AcmpNegativeCallBack != NULL) { + acmpHandle->userCallBack.AcmpNegativeCallBack(acmpHandle); + } + } + if (acmpHandle->baseAddress->ACMP_INTR_MSK.BIT.intr_acmp_edge_msk == BASE_CFG_ENABLE) { + /* Flip edge interrupt. */ + acmpHandle->baseAddress->ACMP_INTR.reg = ACMP_EDGE_INTERRUPT; /* Clears Flip edge interrupt. */ + /* Call flip edge user interrupt function. */ + if (acmpHandle->userCallBack.AcmpEdgedCallBack != NULL) { + acmpHandle->userCallBack.AcmpEdgedCallBack(acmpHandle); + } + } + return; +} + +/** + * @brief Register the callback function of ACMP handle. + * @param acmpHandle Acmp Handle + * @param typeID CallBack function type of user, @ref ACMP_CallBackFun_Type + * @param callBackFunc CallBack function of user, @ref ACMP_CallBackType + * @retval BASE_STATUS_OK Success + * @retval BASE_STATUS_ERROR Parameter check fail + */ +BASE_StatusType HAL_ACMP_RegisterCallBack(ACMP_Handle *acmpHandle, ACMP_CallBackFun_Type typeID, + ACMP_CallBackType callBackFunc) +{ + ACMP_ASSERT_PARAM(acmpHandle != NULL); + ACMP_ASSERT_PARAM(callBackFunc != NULL); + ACMP_ASSERT_PARAM(IsACMPInstance(acmpHandle->baseAddress)); + /* Registers user callback function. */ + switch (typeID) { + case ACMP_POS_INT: /* Register rising edge user callback function */ + acmpHandle->userCallBack.AcmpPositiveCallBack = callBackFunc; + break; + case ACMP_NEG_INT: /* Register failing edge user callback function */ + acmpHandle->userCallBack.AcmpNegativeCallBack = callBackFunc; + break; + case ACMP_EDGE_INT: /* Register fliping edge user callback function */ + acmpHandle->userCallBack.AcmpEdgedCallBack = callBackFunc; + break; + default: + return BASE_STATUS_ERROR; + } + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/drivers/acmp/acmp_v2/src/acmp_ex.c b/src/drivers/acmp/acmp_v2/src/acmp_ex.c new file mode 100644 index 0000000000000000000000000000000000000000..745bdb525865eac2007a869771101ff53c7925fe --- /dev/null +++ b/src/drivers/acmp/acmp_v2/src/acmp_ex.c @@ -0,0 +1,45 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file acmp_ex.c + * @author MCU Driver Team + * @brief ACMP module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the acmp. + * + Set ACMP trim value functions. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "acmp_ex.h" + +/* Macro definitions ---------------------------------------------------------*/ +#define TRIM_MAX_VALUE 255 + +/** + * @brief Trim value setting + * @param acmpHandle acmp handle. + * @param trimValue trim value. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_ACMP_SetTrimValueEx(ACMP_Handle *acmpHandle, unsigned char trimValue) +{ + ACMP_ASSERT_PARAM(acmpHandle != NULL); + ACMP_ASSERT_PARAM(IsACMPInstance(acmpHandle->baseAddress)); + ACMP_PARAM_CHECK_WITH_RET((trimValue < TRIM_MAX_VALUE), BASE_STATUS_ERROR); + acmpHandle->baseAddress->ACMP_TRIM.BIT.da_acmp_trim = trimValue; /* Trim value setting. */ + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/drivers/acmp/common/inc/acmp.h b/src/drivers/acmp/common/inc/acmp.h index 6f894dcf7d2a58a7811ea54e2f9efddceb583be2..3cbc30db89f32a17e1563b2c34c795ef7e11ed8d 100644 --- a/src/drivers/acmp/common/inc/acmp.h +++ b/src/drivers/acmp/common/inc/acmp.h @@ -71,22 +71,40 @@ typedef void (* ACMP_CallBackType)(void *handle); */ /** - * @defgroup ACMP_API_Declaration ACMP HAL API + * @defgroup ACMP_API_Declaration + * @brief ACMP HAL API. * @{ */ + BASE_StatusType HAL_ACMP_Init(ACMP_Handle *acmpHandle); BASE_StatusType HAL_ACMP_DeInit(ACMP_Handle *acmpHandle); void HAL_ACMP_SetHystVol(ACMP_Handle *acmpHandle, ACMP_HystVol voltage); void HAL_ACMP_BlkingValid(ACMP_Handle *acmpHandle); void HAL_ACMP_BlkingInvalid(ACMP_Handle *acmpHandle); -/* ACMP output result selection. */ +/** + * @defgroup ACMP_API_Declaration + * @brief ACMP output result selection. + * @{ + */ + BASE_StatusType HAL_ACMP_ResultSelect(ACMP_Handle *acmpHandle, ACMP_ResultSelect resultSelect); +/** + * @} + */ + +/** + * @defgroup ACMP_API_Declaration + * @brief ACMP interrupt function. + * @{ + */ -/* ACMP interrupt service function and user callback registration function. */ void HAL_ACMP_IrqHandler(void *handle); -BASE_StatusType HAL_ACMP_RegisterCallBack(ACMP_Handle *uartHandle, ACMP_CallBackFun_Type typeID, - ACMP_CallBackType pCallback); +BASE_StatusType HAL_ACMP_RegisterCallBack(ACMP_Handle *acmpHandle, ACMP_CallBackFun_Type typeID, + ACMP_CallBackType callBackFunc); +/** + * @} + */ /** * @} */ diff --git a/src/drivers/adc/adc_v0/inc/adc_ip.h b/src/drivers/adc/adc_v0/inc/adc_ip.h index c33545171ac40ffe6680173665874552e3ebbe80..ab7d305962769964988a8572b4c1ef965d403aa6 100644 --- a/src/drivers/adc/adc_v0/inc/adc_ip.h +++ b/src/drivers/adc/adc_v0/inc/adc_ip.h @@ -1335,7 +1335,7 @@ typedef enum { ADC_CALLBACK_INT2 = 0x00000001U, ADC_CALLBACK_INT3 = 0x00000002U, ADC_CALLBACK_INT4 = 0x00000003U, - ADC_CALLBACK_DMA = 0x000000004U, + ADC_CALLBACK_DMA = 0x00000004U, ADC_CALLBACK_INTOVER = 0x00000005U, ADC_CALLBACK_DMAOVER = 0x00000006U, ADC_CALLBACK_TRIGOVER = 0x00000007U, @@ -1650,7 +1650,7 @@ static inline bool IsADCVrefBufType(ADC_VrefType vrefBuf) */ static inline bool IsADCGainType(ADC_GainType gain) { - return (gain >= ADC_GAIN_1) || (gain <= ADC_GAIN_0P6); + return (gain <= ADC_GAIN_0P6); } /** @@ -2041,7 +2041,7 @@ static inline void DCL_ADC_ResetPollPoint(ADC_RegStruct * const adcx) /** - * @brief Set the specified SOC as the DAM request trigger source. + * @brief Set the specified SOC as the DMA request trigger source. * @param adcx ADC register base address. * @param socx Number of SOC, @ref ADC_SOCNumber. * @retval None. diff --git a/src/drivers/adc/adc_v0/src/adc.c b/src/drivers/adc/adc_v0/src/adc.c index 17f2702400c0bf4326314896b5e0b45fc9dc7487..cf02ddd30b9f28ac05cde7757e33c877ca254658 100644 --- a/src/drivers/adc/adc_v0/src/adc.c +++ b/src/drivers/adc/adc_v0/src/adc.c @@ -215,7 +215,7 @@ BASE_StatusType HAL_ADC_StartDma(ADC_Handle *adcHandle, unsigned int startSoc, ADC_PARAM_CHECK_WITH_RET(IsDmaChannelNum(adcHandle->adcDmaChn) == true, BASE_STATUS_ERROR); unsigned int dmaSOCx = 0; unsigned int dataLength = endSoc - startSoc + 1; - for (int i = 0; i < SOC_MAX_NUM; i++) { + for (unsigned int i = 0; i < SOC_MAX_NUM; i++) { if (adcHandle->ADC_SOCxParam[i].finishMode == ADC_SOCFINISH_DMA) { dmaSOCx = i; } diff --git a/src/drivers/adc/adc_v1/inc/adc_ex.h b/src/drivers/adc/adc_v1/inc/adc_ex.h index afe259321ae32bf5ae78674c44d81bdaff4689a2..ec9b500fc147e3ce73b88c9bb8b56201135203f3 100644 --- a/src/drivers/adc/adc_v1/inc/adc_ex.h +++ b/src/drivers/adc/adc_v1/inc/adc_ex.h @@ -26,6 +26,7 @@ #define McuMagicTag_ADC_EX_H #include "adc.h" +#define ANA_RSV_REG0_ADDR 0x18600008 #define ADC_ANA_MUX ((ADC_ANA_MUX_APB_RegStruct *)0x18003000) /** diff --git a/src/drivers/adc/adc_v1/inc/adc_ip.h b/src/drivers/adc/adc_v1/inc/adc_ip.h index 80882def2f720e53d1c3615f339e5bb8719c2146..60c9d54674b55cfb5b563d4a907c226b81b5300c 100644 --- a/src/drivers/adc/adc_v1/inc/adc_ip.h +++ b/src/drivers/adc/adc_v1/inc/adc_ip.h @@ -1331,6 +1331,19 @@ typedef union { } BIT; } volatile ADC_ANA_CTRL0_REG; +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) +/** + * @brief Define the union ADC_ANA_CK_REG + */ +typedef union { + unsigned int reg; + struct { + unsigned int cfg_sar_cksel : 8; + unsigned int reserved0 : 24; + } BIT; +} volatile ADC_ANA_CK_REG; +#endif /** * @brief Define the union ADC_AVDD_EN_REG */ @@ -1367,108 +1380,108 @@ typedef union { } volatile ADC_OEGE_TRIM_REG; /** - * @brief Define the union ADC_PGA0_OEGE_TRIM0_REG + * @brief Define the union ADC_AIN0_OEGE_TRIM0_REG */ typedef union { unsigned int reg; struct { - unsigned int cfg_pga0_ofst_trim2 : 12; /**< Gain calibration trim value */ + unsigned int cfg_ain0_ofst_trim2 : 12; /**< Offset calibration trim value */ unsigned int reserved0 : 4; - unsigned int cfg_pga0_gain_trim2 : 13; /**< Offset calibration trim value */ + unsigned int cfg_ain0_gain_trim2 : 13; /**< Gain calibration trim value */ unsigned int reserved1 : 3; } BIT; -} volatile ADC_PGA0_OEGE_TRIM0_REG; +} volatile ADC_AIN0_OEGE_TRIM0_REG; /** - * @brief Define the union ADC_PGA0_OEGE_TRIM1_REG + * @brief Define the union ADC_AIN0_OEGE_TRIM1_REG */ typedef union { unsigned int reg; struct { - unsigned int cfg_pga0_ofst_trim4 : 12; /**< Gain calibration trim value */ + unsigned int cfg_ain0_ofst_trim4 : 12; /**< Offset calibration trim value */ unsigned int reserved0 : 4; - unsigned int cfg_pga0_gain_trim4 : 13; /**< Offset calibration trim value */ + unsigned int cfg_ain0_gain_trim4 : 13; /**< Gain calibration trim value */ unsigned int reserved1 : 3; } BIT; -} volatile ADC_PGA0_OEGE_TRIM1_REG; +} volatile ADC_AIN0_OEGE_TRIM1_REG; /** - * @brief Define the union ADC_PGA0_OEGE_TRIM2_REG + * @brief Define the union ADC_AIN0_OEGE_TRIM2_REG */ typedef union { unsigned int reg; struct { - unsigned int cfg_pga0_ofst_trim8 : 12; /**< Gain calibration trim value */ + unsigned int cfg_ain0_ofst_trim8 : 12; /**< Offset calibration trim value */ unsigned int reserved0 : 4; - unsigned int cfg_pga0_gain_trim8 : 13; /**< Offset calibration trim value */ + unsigned int cfg_ain0_gain_trim8 : 13; /**< Gain calibration trim value */ unsigned int reserved1 : 3; } BIT; -} volatile ADC_PGA0_OEGE_TRIM2_REG; +} volatile ADC_AIN0_OEGE_TRIM2_REG; /** - * @brief Define the union ADC_PGA0_OEGE_TRIM3_REG + * @brief Define the union ADC_AIN0_OEGE_TRIM3_REG */ typedef union { unsigned int reg; struct { - unsigned int cfg_pga0_ofst_trim16 : 12; /**< Gain calibration trim value */ + unsigned int cfg_ain0_ofst_trim16 : 12; /**< Offset calibration trim value */ unsigned int reserved0 : 4; - unsigned int cfg_pga0_gain_trim16 : 13; /**< Offset calibration trim value */ + unsigned int cfg_ain0_gain_trim16 : 13; /**< Gain calibration trim value */ unsigned int reserved1 : 3; } BIT; -} volatile ADC_PGA0_OEGE_TRIM3_REG; +} volatile ADC_AIN0_OEGE_TRIM3_REG; /** - * @brief Define the union ADC_PGA1_OEGE_TRIM0_REG + * @brief Define the union ADC_AIN1_OEGE_TRIM0_REG */ typedef union { unsigned int reg; struct { - unsigned int cfg_pga1_ofst_trim2 : 12; /**< Gain calibration trim value */ + unsigned int cfg_ain1_ofst_trim2 : 12; /**< Offset calibration trim value */ unsigned int reserved0 : 4; - unsigned int cfg_pga1_gain_trim2 : 13; /**< Offset calibration trim value */ + unsigned int cfg_ain1_gain_trim2 : 13; /**< Gain calibration trim value */ unsigned int reserved1 : 3; } BIT; -} volatile ADC_PGA1_OEGE_TRIM0_REG; +} volatile ADC_AIN1_OEGE_TRIM0_REG; /** - * @brief Define the union ADC_PGA1_OEGE_TRIM1_REG + * @brief Define the union ADC_AIN1_OEGE_TRIM1_REG */ typedef union { unsigned int reg; struct { - unsigned int cfg_pga1_ofst_trim4 : 12; /**< Gain calibration trim value */ + unsigned int cfg_ain1_ofst_trim4 : 12; /**< Offset calibration trim value */ unsigned int reserved0 : 4; - unsigned int cfg_pga1_gain_trim4 : 13; /**< Offset calibration trim value */ + unsigned int cfg_ain1_gain_trim4 : 13; /**< Gain calibration trim value */ unsigned int reserved1 : 3; } BIT; -} volatile ADC_PGA1_OEGE_TRIM1_REG; +} volatile ADC_AIN1_OEGE_TRIM1_REG; /** - * @brief Define the union ADC_PGA1_OEGE_TRIM2_REG + * @brief Define the union ADC_AIN1_OEGE_TRIM2_REG */ typedef union { unsigned int reg; struct { - unsigned int cfg_pga1_ofst_trim8 : 12; /**< Gain calibration trim value */ + unsigned int cfg_ain1_ofst_trim8 : 12; /**< Offset calibration trim value */ unsigned int reserved0 : 4; - unsigned int cfg_pga1_gain_trim8 : 13; /**< Offset calibration trim value */ + unsigned int cfg_ain1_gain_trim8 : 13; /**< Gain calibration trim value */ unsigned int reserved1 : 3; } BIT; -} volatile ADC_PGA1_OEGE_TRIM2_REG; +} volatile ADC_AIN1_OEGE_TRIM2_REG; /** - * @brief Define the union ADC_PGA1_OEGE_TRIM3_REG + * @brief Define the union ADC_AIN1_OEGE_TRIM3_REG */ typedef union { unsigned int reg; struct { - unsigned int cfg_pga1_ofst_trim16 : 12; /**< Gain calibration trim value */ + unsigned int cfg_ain1_ofst_trim16 : 12; /**< Offset calibration trim value */ unsigned int reserved0 : 4; - unsigned int cfg_pga1_gain_trim16 : 13; /**< Offset calibration trim value */ + unsigned int cfg_ain1_gain_trim16 : 13; /**< Gain calibration trim value */ unsigned int reserved1 : 3; } BIT; -} volatile ADC_PGA1_OEGE_TRIM3_REG; +} volatile ADC_AIN1_OEGE_TRIM3_REG; /** * @brief Define the union ADC_ANA_TRIM_REG @@ -1596,21 +1609,27 @@ typedef struct { ADC_CAP_TRG_REG ADC_CAP_TRG; /**< Offset address: 0x00000540U, Calibration enable register */ unsigned int space17[3]; ADC_CAP_M1_REG ADC_CAP_M1; /**< Offset address: 0x00000550U, Capacitor calibration register */ +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + unsigned int space18[63]; + ADC_ANA_CK_REG ADC_ANA_CK; /**< Offset address: 0x00000650U, ADC clock init register */ + #else unsigned int space18[64]; + #endif ADC_ANA_CTRL0_REG ADC_ANA_CTRL0; /**< Offset address: 0x00000654U, Analog register0 */ ADC_AVDD_EN_REG ADC_AVDD_EN; /**< Offset address: 0x00000658U, AVDD/3 enable register0 */ - unsigned int space19[106]; + unsigned int space19[105]; ADC_TSENSOR_TRIM_REG ADC_TSENSOR_TRIM; /**< Offset address: 0x00000800U, Tsensor trim register */ ADC_OEGE_TRIM_REG ADC_OEGE_TRIM; /**< Offset address: 0x00000804U, OE and GE common trim register */ unsigned int space20[2]; - ADC_PGA0_OEGE_TRIM0_REG ADC_PGA0_OEGE_TRIM0; /**< Offset address: 0x00000810U, PGA0 OE and GE trim register0 */ - ADC_PGA0_OEGE_TRIM1_REG ADC_PGA0_OEGE_TRIM1; /**< Offset address: 0x00000814U, PGA0 OE and GE trim register1 */ - ADC_PGA0_OEGE_TRIM2_REG ADC_PGA0_OEGE_TRIM2; /**< Offset address: 0x00000818U, PGA0 OE and GE trim register2 */ - ADC_PGA0_OEGE_TRIM3_REG ADC_PGA0_OEGE_TRIM3; /**< Offset address: 0x0000081CU, PGA0 OE and GE trim register3 */ - ADC_PGA1_OEGE_TRIM0_REG ADC_PGA1_OEGE_TRIM0; /**< Offset address: 0x00000820U, PGA1 OE and GE trim register0 */ - ADC_PGA1_OEGE_TRIM1_REG ADC_PGA1_OEGE_TRIM1; /**< Offset address: 0x00000824U, PGA1 OE and GE trim register1 */ - ADC_PGA1_OEGE_TRIM2_REG ADC_PGA1_OEGE_TRIM2; /**< Offset address: 0x00000828U, PGA1 OE and GE trim register2 */ - ADC_PGA1_OEGE_TRIM3_REG ADC_PGA1_OEGE_TRIM3; /**< Offset address: 0x0000082CU, PGA1 OE and GE trim register3 */ + ADC_AIN0_OEGE_TRIM0_REG ADC_AIN0_OEGE_TRIM0; /**< Offset address: 0x00000810U, PGA0 OE and GE trim register0 */ + ADC_AIN0_OEGE_TRIM1_REG ADC_AIN0_OEGE_TRIM1; /**< Offset address: 0x00000814U, PGA0 OE and GE trim register1 */ + ADC_AIN0_OEGE_TRIM2_REG ADC_AIN0_OEGE_TRIM2; /**< Offset address: 0x00000818U, PGA0 OE and GE trim register2 */ + ADC_AIN0_OEGE_TRIM3_REG ADC_AIN0_OEGE_TRIM3; /**< Offset address: 0x0000081CU, PGA0 OE and GE trim register3 */ + ADC_AIN1_OEGE_TRIM0_REG ADC_AIN1_OEGE_TRIM0; /**< Offset address: 0x00000820U, PGA1 OE and GE trim register0 */ + ADC_AIN1_OEGE_TRIM1_REG ADC_AIN1_OEGE_TRIM1; /**< Offset address: 0x00000824U, PGA1 OE and GE trim register1 */ + ADC_AIN1_OEGE_TRIM2_REG ADC_AIN1_OEGE_TRIM2; /**< Offset address: 0x00000828U, PGA1 OE and GE trim register2 */ + ADC_AIN1_OEGE_TRIM3_REG ADC_AIN1_OEGE_TRIM3; /**< Offset address: 0x0000082CU, PGA1 OE and GE trim register3 */ unsigned int space21[4]; ADC_ANA_TRIM_REG ADC_ANA_TRIM; /**< Offset address: 0x00000840U, Analog trim register */ } volatile ADC_RegStruct; @@ -1712,27 +1731,61 @@ typedef enum { * @brief ADC supports peripherals trigger source. */ typedef enum { - ADC_TRIGSOC_SOFT = 0x00000000U, - ADC_TRIGSOC_APT0_SOCA = 0x00000001U, - ADC_TRIGSOC_APT0_SOCB = 0x00000002U, - ADC_TRIGSOC_APT1_SOCA = 0x00000003U, - ADC_TRIGSOC_APT1_SOCB = 0x00000004U, - ADC_TRIGSOC_APT2_SOCA = 0x00000005U, - ADC_TRIGSOC_APT2_SOCB = 0x00000006U, - ADC_TRIGSOC_APT3_SOCA = 0x00000007U, - ADC_TRIGSOC_APT3_SOCB = 0x00000008U, - ADC_TRIGSOC_GPT0 = 0x00000009U, - ADC_TRIGSOC_GPT1 = 0x0000000AU, - ADC_TRIGSOC_GPT2 = 0x0000000BU, - ADC_TRIGSOC_GPT3 = 0x0000000CU, - ADC_TRIGSOC_TIMER0 = 0x000000DU, - ADC_TRIGSOC_TIMER1 = 0x000000EU, - ADC_TRIGSOC_TIMER2 = 0x000000FU, - ADC_TRIGSOC_TIMER3 = 0x00000010U, - ADC_TRIGSOC_GPIOPD5 = 0x00000011U, - ADC_TRIGSOC_GPIOPF3 = 0x00000012U, - ADC_TRIGSOC_GPIOPF2 = 0x00000013U, - ADC_TRIGSOC_GPIOPF1 = 0x00000014U, +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + ADC_TRIGSOC_SOFT = 0x00000000U, + ADC_TRIGSOC_APT0_SOCA = 0x00000001U, + ADC_TRIGSOC_APT0_SOCB = 0x00000002U, + ADC_TRIGSOC_APT1_SOCA = 0x00000003U, + ADC_TRIGSOC_APT1_SOCB = 0x00000004U, + ADC_TRIGSOC_APT2_SOCA = 0x00000005U, + ADC_TRIGSOC_APT2_SOCB = 0x00000006U, + ADC_TRIGSOC_APT3_SOCA = 0x00000007U, + ADC_TRIGSOC_APT3_SOCB = 0x00000008U, + ADC_TRIGSOC_APT4_SOCA = 0x00000009U, + ADC_TRIGSOC_APT4_SOCB = 0x0000000AU, + ADC_TRIGSOC_APT5_SOCA = 0x0000000BU, + ADC_TRIGSOC_APT5_SOCB = 0x0000000CU, + ADC_TRIGSOC_APT6_SOCA = 0x0000000DU, + ADC_TRIGSOC_APT6_SOCB = 0x0000000EU, + ADC_TRIGSOC_APT7_SOCA = 0x0000000FU, + ADC_TRIGSOC_APT7_SOCB = 0x00000010U, + ADC_TRIGSOC_APT8_SOCA = 0x00000011U, + ADC_TRIGSOC_APT8_SOCB = 0x00000012U, + ADC_TRIGSOC_TIMER0 = 0x00000013U, + ADC_TRIGSOC_TIMER1 = 0x00000014U, + ADC_TRIGSOC_TIMER2 = 0x00000015U, + ADC_TRIGSOC_TIMER3 = 0x00000016U, + ADC_TRIGSOC_GPT0 = 0x00000017U, + ADC_TRIGSOC_GPT1 = 0x00000018U, + ADC_TRIGSOC_GPIOK22 = 0x00000019U, + ADC_TRIGSOC_GPIOX4 = 0x0000001AU, + ADC_TRIGSOC_GPIOA15 = 0x0000001BU, + ADC_TRIGSOC_GPIOK1 = 0x0000001CU, + #else + ADC_TRIGSOC_SOFT = 0x00000000U, + ADC_TRIGSOC_APT0_SOCA = 0x00000001U, + ADC_TRIGSOC_APT0_SOCB = 0x00000002U, + ADC_TRIGSOC_APT1_SOCA = 0x00000003U, + ADC_TRIGSOC_APT1_SOCB = 0x00000004U, + ADC_TRIGSOC_APT2_SOCA = 0x00000005U, + ADC_TRIGSOC_APT2_SOCB = 0x00000006U, + ADC_TRIGSOC_APT3_SOCA = 0x00000007U, + ADC_TRIGSOC_APT3_SOCB = 0x00000008U, + ADC_TRIGSOC_GPT0 = 0x00000009U, + ADC_TRIGSOC_GPT1 = 0x0000000AU, + ADC_TRIGSOC_GPT2 = 0x0000000BU, + ADC_TRIGSOC_GPT3 = 0x0000000CU, + ADC_TRIGSOC_TIMER0 = 0x000000DU, + ADC_TRIGSOC_TIMER1 = 0x000000EU, + ADC_TRIGSOC_TIMER2 = 0x000000FU, + ADC_TRIGSOC_TIMER3 = 0x00000010U, + ADC_TRIGSOC_GPIOPD5 = 0x00000011U, + ADC_TRIGSOC_GPIOPF3 = 0x00000012U, + ADC_TRIGSOC_GPIOPF2 = 0x00000013U, + ADC_TRIGSOC_GPIOPF1 = 0x00000014U, + #endif + ADC_TRIGSOC_MAX } ADC_TrigSource; /** @@ -1901,11 +1954,11 @@ typedef enum { ADC_CALLBACK_INT1 = 0x00000001U, ADC_CALLBACK_INT2 = 0x00000002U, ADC_CALLBACK_INT3 = 0x00000003U, - ADC_CALLBACK_DMA = 0x000000004U, - ADC_CALLBACK_DMAERROR = 0x000000005U, + ADC_CALLBACK_DMA = 0x00000004U, + ADC_CALLBACK_DMAERROR = 0x00000005U, ADC_CALLBACK_DMAOVER = 0x00000006U, ADC_CALLBACK_TRIGOVER = 0x00000007U, - ADC_CALLBACK_EVENT_OVERSAMPLING = 0x000000008U, + ADC_CALLBACK_EVENT_OVERSAMPLING = 0x00000008U, ADC_CALLBACK_EVENT_PPB0_ZERO = 0x00000010U, ADC_CALLBACK_EVENT_PPB0_UP = 0x00000011U, ADC_CALLBACK_EVENT_PPB0_DOWN = 0x00000012U, @@ -2093,7 +2146,7 @@ static inline bool IsADCIntx(ADC_IntNumber intx) */ static inline bool IsADCTrigSource(ADC_TrigSource trig) { - return (trig >= ADC_TRIGSOC_SOFT) && (trig <= ADC_TRIGSOC_GPIOPF1); + return (trig >= ADC_TRIGSOC_SOFT) && (trig < ADC_TRIGSOC_MAX); } /** @@ -2335,9 +2388,6 @@ static inline void DCL_ADC_SOCxSelectChannel(ADC_RegStruct * const adcx, ADC_SOC unsigned int addr = ADC_GetCTRLAddr(adcx, socx); /* Get the Address After Translation */ soc = (ADC_SOC0_CFG_REG *)(void *)(uintptr_t)addr; soc->BIT.cfg_soc0_ch_sel = (unsigned int)input; - if (input == ADC_CH_ADCINA18) { - DCL_ADC_EnableAvddChannel(adcx); - } } /** @@ -2437,7 +2487,7 @@ static inline void DCL_ADC_ResetPollPoint(ADC_RegStruct * const adcx) } /** - * @brief Set the specified SOC as the DAM request trigger source. + * @brief Set the specified SOC as the DMA request trigger source. * @param adcx ADC register base address. * @param socx Number of SOC, @ref ADC_SOCNumber. * @retval None. @@ -2759,7 +2809,7 @@ static inline void DCL_ADC_SetOversamplingParam(ADC_RegStruct * const adcx, ADC_ { ADC_ASSERT_PARAM(IsADCInstance(adcx)); ADC_PARAM_CHECK_NO_RET(IsADCOversamplingMultiple(multiple)); - ADC_PARAM_CHECK_NO_RET(IsADCOversamplingMultiple(rightShift)); + ADC_PARAM_CHECK_NO_RET(IsADCOversamplingRightShift(rightShift)); adcx->ADC_OVERSAMP.BIT.cfg_oversamp_n = multiple; /* Configuring the Oversampling Multiple */ adcx->ADC_OVERSAMP.BIT.cfg_oversamp_m = rightShift; /* Configuring the Bits Shifted Right in Oversampling */ } diff --git a/src/drivers/adc/adc_v1/src/adc.c b/src/drivers/adc/adc_v1/src/adc.c index fd90dde466d90607d761b02972d528a9721f972b..886d3a132860f2afa408ebe1e52c7f1e1df59644 100644 --- a/src/drivers/adc/adc_v1/src/adc.c +++ b/src/drivers/adc/adc_v1/src/adc.c @@ -47,6 +47,10 @@ BASE_StatusType HAL_ADC_Init(ADC_Handle *adcHandle) DCL_ADC_SOCxSetPriority(adcHandle->baseAddress, adcHandle->socPriority); adcHandle->baseAddress->ADC_ANA_CTRL0.BIT.cfg_sar_samp_cap_sel = 0x4; /* Set the Number of Sampling Capacitors */ adcHandle->baseAddress->ADC_EN.reg = BASE_CFG_ENABLE; /* Enable ADC Controller */ +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + adcHandle->baseAddress->ADC_ANA_CK.BIT.cfg_sar_cksel = BASE_CFG_ENABLE; /* ANA clock initial enable */ + #endif BASE_FUNC_DelayUs(100); /* Wait for 100 us until the ADC controller is stable */ return BASE_STATUS_OK; } @@ -146,7 +150,7 @@ BASE_StatusType HAL_ADC_StartDma(ADC_Handle *adcHandle, unsigned int startSoc, ADC_PARAM_CHECK_WITH_RET(IsDmaChannelNum(adcHandle->adcDmaChn) == true, BASE_STATUS_ERROR); unsigned int dmaSOCx = 0; unsigned int dataLength = endSoc - startSoc + 1; - for (int i = 0; i < SOC_MAX_NUM; i++) { /* The DMA request is generated by the last SOC */ + for (unsigned int i = 0; i < SOC_MAX_NUM; i++) { /* The DMA request is generated by the last SOC */ if (adcHandle->ADC_SOCxParam[i].finishMode == ADC_SOCFINISH_DMA) { dmaSOCx = i; } @@ -332,7 +336,11 @@ void HAL_ADC_IrqHandlerOver(void *handle) } } -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) || defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNPIK8) +#if defined (CHIP_3061MNPICA) || defined(CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNNIKA) || defined (CHIP_3061MNPIC8) || defined(CHIP_3061MNNIC8) || \ + defined (CHIP_3061MNPIK8) || defined (CHIP_3061MNNIK8) || \ + defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) /** * @brief ADC Interrupt0 service processing function. * @param handle ADC handle. @@ -527,8 +535,6 @@ BASE_StatusType HAL_ADC_InitForVdda(ADC_RegStruct *adcx, ADC_SOCNumber soc, DAC_ ADC_ASSERT_PARAM(IsADCInstance(adcx)); ADC_ASSERT_PARAM(IsDACInstance(dacx)); ADC_PARAM_CHECK_WITH_RET(IsADCSOCx(soc) == true, BASE_STATUS_ERROR); - HAL_CRG_IpEnableSet(DAC0_BASE, IP_CLK_ENABLE); /* DAC0 clock enable. */ - HAL_CRG_IpClkSelectSet(DAC0_BASE, 0); DAC_Handle dac = {0}; dac.baseAddress = dacx; /* DAC cannot be full scale, otherwise ADC will not sense the power supply fluctuation of AVDD */ @@ -545,7 +551,22 @@ BASE_StatusType HAL_ADC_InitForVdda(ADC_RegStruct *adcx, ADC_SOCNumber soc, DAC_ ADC_Handle adc = {0}; adc.baseAddress = adcx; SOC_Param socParam = {0}; - socParam.adcInput = ADC_CH_ADCINA17; /* DAC input */ +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + if (adc.baseAddress == ADC0) { + socParam.adcInput = ADC_CH_ADCINA18; /* DAC input */ + } else if (adc.baseAddress == ADC1) { + if (dac.baseAddress == DAC0) { /* DAC0 input */ + socParam.adcInput = ADC_CH_ADCINA19; + } else if (dac.baseAddress == DAC1) { /* DAC1 input */ + socParam.adcInput = ADC_CH_ADCINA18; + } + } else if (adc.baseAddress == ADC2) { + socParam.adcInput = ADC_CH_ADCINA19; /* DAC input */ + } + #else + socParam.adcInput = ADC_CH_ADCINA17; /* DAC input */ + #endif socParam.sampleTotalTime = ADC_SOCSAMPLE_500CLK; /* adc sample total time set as 500 cycle */ socParam.trigSource = ADC_TRIGSOC_SOFT; socParam.continueMode = BASE_CFG_DISABLE; diff --git a/src/drivers/adc/adc_v1/src/adc_ex.c b/src/drivers/adc/adc_v1/src/adc_ex.c index adf8fd5255d56e571abd1fbfef0fcfc15f06095f..56b3d83461e7b50920e50687e6431c961f53be63 100644 --- a/src/drivers/adc/adc_v1/src/adc_ex.c +++ b/src/drivers/adc/adc_v1/src/adc_ex.c @@ -279,7 +279,7 @@ unsigned int HAL_ADC_GetPPBxDelayCntEx(ADC_Handle *adcHandle, ADC_PPBNumber ppb) } /** - * @brief Initialize the ADC for VDDA/3. + * @brief Initialize the ADC for VDDA/3 or VDDA/9/7. * Note: * (1) Ensure that the ADC clock is turned on and the ADC has been initialized using before use. * (2) The soc parameter must be set to an SOC that is not occupied in the ADC. @@ -294,7 +294,15 @@ BASE_StatusType HAL_ADC_InitForVddaEx(ADC_RegStruct *adcx, ADC_SOCNumber soc) ADC_Handle adc = {0}; adc.baseAddress = adcx; SOC_Param socParam = {0}; - socParam.adcInput = ADC_CH_ADCINA18; /* VDD/3 input */ + +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + socParam.adcInput = ADC_CH_ADCINA17; /* 7*VDD/9 input */ + *(unsigned int *)ANA_RSV_REG0_ADDR = 0x0E; /* Config VDDA channel voltage 0x0E:7/9VDDA */ + #else + socParam.adcInput = ADC_CH_ADCINA18; /* VDD/3 input */ + DCL_ADC_EnableAvddChannel(adcx); + #endif socParam.sampleTotalTime = ADC_SOCSAMPLE_500CLK; /* adc sample total time set as 500 cycle */ socParam.trigSource = ADC_TRIGSOC_SOFT; socParam.continueMode = BASE_CFG_DISABLE; @@ -332,7 +340,13 @@ float HAL_ADC_GetVddaEx(ADC_RegStruct *adcx, ADC_SOCNumber soc) return 0.0f; /* convert fail */ } float ori = (float)ret / (float)count; - /* 3.0, 3.33333 and 4096.0 are used to convert the voltage, VDD/3 */ - voltage = 3.0 *3.33333f * ori / 4096.0f; + #if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + /* 3.33333 and 4096.0 are used to convert the voltage, 7*VDD/9 */ + voltage = 9.0f * 3.33333f * ori / 4096.0f / 7.0f; + #else + /* 3.0, 3.33333 and 4096.0 are used to convert the voltage, VDD/3 */ + voltage = 3.0f * 3.33333f * ori / 4096.0f; + #endif return voltage; } diff --git a/src/drivers/adc/common/inc/adc.h b/src/drivers/adc/common/inc/adc.h index c32b8cae599b02f6af3e520218b617685a2257c6..02b0453f2f0a765d1d3a9854fbf0c570b8abb4bc 100644 --- a/src/drivers/adc/common/inc/adc.h +++ b/src/drivers/adc/common/inc/adc.h @@ -102,7 +102,11 @@ void HAL_ADC_RegisterCallBack(ADC_Handle *adcHandle, ADC_CallbackFunType typeID, BASE_StatusType HAL_ADC_InitForVdda(ADC_RegStruct *adcx, ADC_SOCNumber soc, DAC_RegStruct *dacx, bool useDac); float HAL_ADC_GetVddaByDac(ADC_RegStruct *adcx, ADC_SOCNumber soc, DAC_RegStruct *dacx, bool useDac); unsigned int HAL_ADC_GetTransResultByVdda(ADC_RegStruct *adcx, ADC_SOCNumber soc, float vdda); -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) || defined (CHIP_3061MNPIC8) || defined (CHIP_3061MNPIK8) +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNNIKA) || defined (CHIP_3061MNPIC8) || defined(CHIP_3061MNNIC8) || \ + defined (CHIP_3061MNPIK8) || defined (CHIP_3061MNNIK8) || \ + defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) void HAL_ADC_IrqHandlerInt0(void *handle); #endif void HAL_ADC_IrqHandlerInt1(void *handle); diff --git a/src/drivers/apt/apt_v0/inc/apt_ip.h b/src/drivers/apt/apt_v0/inc/apt_ip.h index 47d316180657825d0524cf009aebac699a704984..03e885c57202111b0dc02a5d08b62723fd0c1ce5 100644 --- a/src/drivers/apt/apt_v0/inc/apt_ip.h +++ b/src/drivers/apt/apt_v0/inc/apt_ip.h @@ -87,6 +87,7 @@ /* Values that can be passed to DCL_APT_SetCompareLoadEvent() as the loadEvent parameter. */ #define APT_COMPARE_LOAD_EVENT_ZERO 0x00000001U #define APT_COMPARE_LOAD_EVENT_PERIOD 0x00000002U +#define APT_COMPARE_LOAD_EVENT_ZERO_PERIOD 0x00000003U #define APT_COMPARE_LOAD_EVENT_A1 0x00000004U #define APT_COMPARE_LOAD_EVENT_B1 0x00000008U #define APT_COMPARE_LOAD_EVENT_SYNC 0x00000010U @@ -349,7 +350,7 @@ typedef enum { */ typedef enum { APT_OUT_CTRL_ONE_SHOT = 0x00000000U, - APT_OUT_CTRL_CYCLE_BY_CYBLE = 0x00000001U, + APT_OUT_CTRL_CYCLE_BY_CYCLE = 0x00000001U, } APT_OutCtrlMode; /** @@ -2695,11 +2696,11 @@ static inline void DCL_APT_SetOutCtrlEventMode(APT_RegStruct *aptx, APT_ASSERT_PARAM(IsAPTInstance(aptx)); APT_PARAM_CHECK_NO_RET((ocEvent >= APT_OC_NO_EVENT) && (ocEvent <= APT_OC_COMBINE_EVENT_B2)); APT_PARAM_CHECK_NO_RET(ocEventMode >= APT_OUT_CTRL_ONE_SHOT); - APT_PARAM_CHECK_NO_RET(ocEventMode <= APT_OUT_CTRL_CYCLE_BY_CYBLE); + APT_PARAM_CHECK_NO_RET(ocEventMode <= APT_OUT_CTRL_CYCLE_BY_CYCLE); unsigned ocModeOffset = 16; /* Offset of output control mode setting */ if (ocEventMode == APT_OUT_CTRL_ONE_SHOT) { aptx->OC_MODE.reg &= (~(ocEvent << ocModeOffset)); /* Set rg_oc_mode_evtx to 0 */ - } else if (ocEventMode == APT_OUT_CTRL_CYCLE_BY_CYBLE) { + } else if (ocEventMode == APT_OUT_CTRL_CYCLE_BY_CYCLE) { aptx->OC_MODE.reg |= (ocEvent << ocModeOffset); /* Set rg_oc_mode_evtx to 1 */ } } @@ -3597,7 +3598,7 @@ static inline bool DCL_APT_GetValleyEdgeStatus(APT_RegStruct *aptx, APT_ValleyCo APT_PARAM_CHECK_WITH_RET(edge <= APT_VALLEY_COUNT_STOP_EDGE, false); if (edge == APT_VALLEY_COUNT_START_EDGE) { return (aptx->EM_VCAP_STS2.BIT.ro_vcap_sta_edgsts); - } else if (edge == APT_VALLEY_COUNT_STOP_EDGE) { + } else { return (aptx->EM_VCAP_STS2.BIT.ro_vcap_stp_edgsts); } } @@ -3915,4 +3916,263 @@ static inline void DCL_APT_ForceEvent(APT_RegStruct *aptx, APT_ForceEvtType frcE /** * @} */ +#define EM_OUT_EVT_FILTER_EN 0x0f +#define EM_CMB_MODE_OFFSET 16 +#define EM_CMB_MODE_INTERVAL 4 +#define EM_CMB_SRC_SEL_INTERVAL 4 +#define EM_OR_INTERVAL 16 +#define EM_CMB_EVT_NUM 4 +#define EM_COMBINE_A1_SRC_ENABLE_ALL 0xF +/** + * @defgroup APT APT + * @brief APT module. + * @{ + */ + + +/** + * @defgroup APT_Common APT Common + * @brief APT common external module. + * @{ + */ + +/** + * @defgroup APT_Handle_Definition APT Handle Definition + * @{ + */ + +/* + Basic type AHBL ALBH AHBH ALBL + ___ __ __ ___ __ __ + ChannelA __| |__ |___| __| |__ |___| + __ __ ___ ___ __ __ + ChannelB |___| __| |__ __| |__ |___| +*/ +/** + * @brief Basic PWM waveform type. + * @details waveform type: + * + APT_PWM_BASIC_A_HIGH_B_LOW -- Basic PWM waveform type 1. + * + APT_PWM_BASIC_A_LOW_B_HIGH -- Basic PWM waveform type 2. + * + APT_PWM_BASIC_A_HIGH_B_HIGH -- Basic PWM waveform type 3. + * + APT_PWM_BASIC_A_LOW_B_LOW -- Basic PWM waveform type 4. + */ +typedef enum { + APT_PWM_BASIC_A_HIGH_B_LOW = 0x00000000U, + APT_PWM_BASIC_A_LOW_B_HIGH = 0x00000001U, + APT_PWM_BASIC_A_HIGH_B_HIGH = 0x00000002U, + APT_PWM_BASIC_A_LOW_B_LOW = 0x00000003U, +} APT_PWMBasicType; + +/** + * @brief The actual outputs of PWM channelA and channelB. + * @details Output: + * + APT_PWM_OUT_BASIC_TYPE = 0x00000000U -- PWM channel output the waveform according to basic PWM type. + * + APT_PWM_OUT_ALWAYS_LOW = 0x00000001U -- PWM channel output low level. + * + APT_PWM_OUT_ALWAYS_HIGH = 0x00000002U -- PWM channel output high level. + */ +typedef enum { + APT_PWM_OUT_BASIC_TYPE = 0x00000000U, + APT_PWM_OUT_ALWAYS_LOW = 0x00000001U, + APT_PWM_OUT_ALWAYS_HIGH = 0x00000002U, +} APT_PWMChannelOutType; + +/** + * @brief PWM waveform configuration handle of APT module. + */ +typedef struct { + APT_PWMBasicType basicType; /**< Basic PWM waveform type. */ + APT_PWMChannelOutType chAOutType; /**< Actual output of PWM channelA. */ + APT_PWMChannelOutType chBOutType; /**< Actual output of PWM channelB. */ + APT_CountMode cntMode; /**< Count mode of APT time-base counter. */ + unsigned short dividerFactor; /**< Divider factor. The range is 0~4095. */ + unsigned short timerPeriod; /**< Count period of APT time-base timer. */ + unsigned short divInitVal; /**< Initial value of divider. */ + unsigned short cntInitVal; /**< Initial value of time-base counter */ + unsigned short cntCmpLeftEdge; /**< Count compare point of the left edge of PWM waveform. */ + unsigned short cntCmpRightEdge; /**< Count compare point of the right edge of PWM waveform. */ + APT_BufferLoadMode cntCmpLoadMode; /**< Buffer load mode of PWM waveform count compare value. */ + unsigned int cntCmpLoadEvt; /**< Buffer load event of PWM waveform count compare value. */ + unsigned short deadBandCnt; /**< Count value of dead-band counter. In units of APT clock. */ +} APT_PWMWaveForm; + +/** + * @brief ADC trigger configuration handle of APT module. + */ +typedef struct { + bool trgEnSOCA; /**< Enable of ADC trigger source SOCA. */ + APT_ADCTriggerSource trgSrcSOCA; /**< Source of ADC trigger source SOCA. */ + unsigned short trgScaleSOCA; /**< Scale of ADC trigger source SOCA. */ + unsigned short cntCmpSOCA; /**< Count compare point of ADC trigger source SOCA when using CMPA */ + bool trgEnSOCB; /**< Enable of ADC trigger source SOCB. */ + APT_ADCTriggerSource trgSrcSOCB; /**< Source of ADC trigger source SOCB. */ + unsigned short trgScaleSOCB; /**< Scale of ADC trigger source SOCB. */ + unsigned short cntCmpSOCB; /**< Count compare point of ADC trigger source SOCB when using CMPB */ + APT_BufferLoadMode cntCmpLoadMode; /**< Buffer load mode of ADC trigger count compare value. */ + unsigned int cntCmpLoadEvt; /**< Buffer load event of ADC trigger count compare value. */ +} APT_ADCTrigger; + +/** + * @brief Timer interrupt configuration handle of APT module. + */ +typedef struct { + bool tmrInterruptEn; /**< Enable of APT module timer interrupt. */ + APT_TimerInterruptSrc tmrInterruptSrc; /**< Source of APT module timer interrupt. */ + unsigned short tmrInterruptScale; /**< Scale of APT module timer interrupt. */ +} APT_TimerInterrupt; + +/** + * @brief Output control protection configuration handle of APT module. + */ +typedef struct { + bool ocEventEn; /**< Enable of output control event. */ + APT_OutCtrlEvent ocEvent; /**< Output control event. Limited to IO events or system events. */ + APT_OutCtrlMode ocEventMode; /**< Output control protection mode. */ + APT_CBCClearMode cbcClrMode; /**< Event clear mode when using cycle-by-cycle mode. */ + APT_EMEventPolarity evtPolarity; /**< Event effective polarity. */ + APT_OutCtrlAction ocAction; /**< Output control protection action. */ + APT_EmulationMode emMode; /**< emulation mode */ + bool ocEvtInterruptEn; /**< Enable of output control event interrupt. */ +} APT_OutCtrlProtect; + +/** + * @brief Source event of event magnagement. + */ +typedef enum { + APT_EM_ORIGINAL_SRC_POE0 = 0x00000001U, + APT_EM_ORIGINAL_SRC_POE1 = 0x00000002U, + APT_EM_ORIGINAL_SRC_POE2 = 0x00000004U, + APT_EM_ORIGINAL_SRC_ACMP0 = 0x00000008U, + APT_EM_ORIGINAL_SRC_ACMP1 = 0x00000010U, + APT_EM_ORIGINAL_SRC_ACMP2 = 0x00000020U, + APT_EM_ORIGINAL_SRC_EVTMP4 = 0x00000040U, + APT_EM_ORIGINAL_SRC_EVTMP5 = 0x00000080U, + APT_EM_ORIGINAL_SRC_EVTMP6 = 0x00000100U, +} APT_EMOriginalEvtSrc; + +/** + * @brief Filter mask bit. + */ +typedef enum { + APT_EM_POE0_INVERT_BIT = 0x00000001U, + APT_EM_POE1_INVERT_BIT = 0x00000002U, + APT_EM_POE2_INVERT_BIT = 0x00000004U, + APT_EM_ACMP0_INVERT_BIT = 0x00000008U, + APT_EM_ACMP1_INVERT_BIT = 0x00000010U, + APT_EM_ACMP2_INVERT_BIT = 0x00000020U, + APT_EM_EVTMP4_INVERT_BIT = 0x00000040U, + APT_EM_EVTMP5_INVERT_BIT = 0x00000080U, + APT_EM_EVTMP6_INVERT_BIT = 0x00000100U, +} APT_EMPolarityMskBit; + +/** + * @brief System protect event; + */ +typedef enum { + APT_SYS_EVT_DEBUG = 0x00000010U, + APT_SYS_EVT_CLK = 0x00000020U, + APT_SYS_EVT_MEM = 0x00000040U, +} APT_SysOcEvent; + +/** + * @brief Output control protection configuration handle of APT module. + */ +typedef struct { + bool ocEventEnEx; /**< Oc event enable */ + APT_OutCtrlMode ocEventModeEx; /**< Output control protection mode. */ + APT_CBCClearMode cbcClrModeEx; /**< Event clear mode when using cycle-by-cycle mode. */ + APT_OutCtrlAction ocActionEx; /**< Output control protection channel A action. */ + APT_OutCtrlAction ocActionBEx; /**< Output control protection channel B action. */ + bool ocEvtInterruptEnEx; /**< Enable of output control event interrupt. */ + APT_SysOcEvent ocSysEvent; /**< System protect event */ + APT_EMOriginalEvtSrc originalEvtEx; /**< Event management's event source */ + APT_EMPolarityMskBit evtPolarityMaskEx; /**< Event effective polarity. */ + unsigned char filterCycleNumEx; /**< input source event filter */ +} APT_OutCtrlProtectEx; + +/** + * @brief struct of EM conbine event + */ +typedef struct { + APT_EMCombineEvtSrc emEvtSrc; /**< Combine event selection */ + APT_EMCombineEvtMode emEvtCombineMode; /**< Event combine mode */ + APT_EMEventPolarity emEvtPolar; /**< Event source polarity */ + unsigned int emEvtOrEnBits; /**< Event logic or enable bits */ +} APT_CombineEvt; + +/** + * @brief Shield window and capture configurations + */ +typedef struct { + bool wdEnable; /**< Shield windows enable bit */ + bool emCapEnable; /**< Enable EM captrue functions */ + APT_EMCombineEvent eventSel; /**< Window source event selection */ + APT_MaskWinResetMode wdStartAndCapClr; /**< Window's offset start count and EM capture clear condition */ + unsigned short wdOffset; /**< Window's offset value */ + unsigned short wdWidth; /**< Window's width value */ + APT_MaskWinPolarity wdPolar; /**< Window's polarity */ +} APT_WdAndCap; + + +/** + * @brief Valley switch configurations + */ +typedef struct { + bool vsEnable; /**< Valley switch enable */ + APT_EMEdgeFilterMode vsFilerEdgeSel; /**< Filter edge selection */ + unsigned char vsFilterCnt; /**< Filter edge count */ + APT_ValleyCapRstType vsClrType; /**< Clear type */ + APT_ValleyCountEdge vsCapEdgeSel; /**< Capture edge selection */ + unsigned char vsCapStartEdge; /**< Capture start edge */ + unsigned char vsCapEndEdge; /**< Capture end edge */ + APT_ValleyDelayMode vsCapDelayMode; /**< Capture delay mode */ + unsigned short vsCapSoftDelay; /**< Capture software calibrate value */ +} APT_ValleySw; + +/** + * @brief Event management handle of APT module + */ +typedef struct { + bool emEnable; /**< Enable bit of event management */ + APT_CombineEvt emEvt[EM_CMB_EVT_NUM]; /**< Combine events configuration */ + APT_WdAndCap emWdAndCap; /**< Shield windows and capture configuration */ + APT_ValleySw emValleySw; /**< Valley switch configuration */ +} APT_EventManage; + +/** + * @brief Synchronization handle of slave APT module. + */ +typedef struct { + unsigned short divPhase; /**< Divider phase when receiving APT synchronization pulse. */ + unsigned short cntPhase; /**< Counter phase when receiving APT synchronization pulse. */ + APT_SyncCountMode syncCntMode; /**< Count mode when receiving APT synchronization pulse. */ + APT_SyncInSrc syncInSrc; /**< Sync-in source of APT module */ + unsigned short cntrSyncSrc; + /**< Sync-in source of time-base counter synchronization + A logical OR of valid values can be passed as the cntrSyncSrc parameter. + Valid values for cntrSyncSrc are: + APT_CNTR_SYNC_SRC_COMBINE_EVENT_A1 - Enable combine event A1 as the counter synchronization source. + APT_CNTR_SYNC_SRC_COMBINE_EVENT_B1 - Enable combine event B1 as the counter synchronization source. + APT_CNTR_SYNC_SRC_SYNCIN - Enable Sync-In source as the counter synchronization source. */ +} APT_SlaveSyncIn; + +/** + * @brief Definition of callback function type. + */ +typedef void (* APT_CallbackType)(void *aptHandle); + +/** + * @brief Definition of callback function type. + */ +typedef struct { + void (* EvtInterruptCallBack)(void *handle); + void (* TmrInterruptCallBack)(void *handle); +} APT_UserCallBack; + +/** + * @brief Definition of callback function ID. + */ +typedef enum { + APT_TIMER_INTERRUPT = 0x00000000U, + APT_EVENT_INTERRUPT = 0x00000001U, +} APT_InterruputType; #endif /* McuMagicTag_APT_IP_H */ diff --git a/src/drivers/apt/apt_v0/src/apt.c b/src/drivers/apt/apt_v0/src/apt.c index de47e2cd9eec1d53150b215b56d33773954e95c9..fa8c695ad96724ad2d0cdc478f2c8836a5f02c70 100644 --- a/src/drivers/apt/apt_v0/src/apt.c +++ b/src/drivers/apt/apt_v0/src/apt.c @@ -358,10 +358,10 @@ BASE_StatusType HAL_APT_PWMInit(APT_Handle *aptHandle) APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.dividerFactor <= DIVIDER_FACTOR_MAX, BASE_STATUS_ERROR); APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.divInitVal <= aptHandle->waveform.dividerFactor, BASE_STATUS_ERROR); APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntInitVal < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpLeftEdge > 0, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpLeftEdge < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpRightEdge > 0, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpRightEdge < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpLeftEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpLeftEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpRightEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpRightEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); APT_PARAM_CHECK_WITH_RET(aptHandle->adcTrg.cntCmpSOCA >= 0, BASE_STATUS_ERROR); APT_PARAM_CHECK_WITH_RET(aptHandle->adcTrg.cntCmpSOCA < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); APT_PARAM_CHECK_WITH_RET(aptHandle->adcTrg.cntCmpSOCB >= 0, BASE_STATUS_ERROR); @@ -413,7 +413,7 @@ static void APT_SetOutCtrlProtectMode(APT_Handle *aptHandle, APT_OutCtrlProtect unsigned int cbcClrOffsetPrd = 16; if (protect->ocEventMode == APT_OUT_CTRL_ONE_SHOT) { aptHandle->baseAddress->OC_MODE.reg &= (~(protect->ocEvent << ocModeOffset)); - } else if (protect->ocEventMode == APT_OUT_CTRL_CYCLE_BY_CYBLE) { + } else if (protect->ocEventMode == APT_OUT_CTRL_CYCLE_BY_CYCLE) { aptHandle->baseAddress->OC_MODE.reg |= (protect->ocEvent << ocModeOffset); if ((protect->cbcClrMode & APT_CLEAR_CBC_ON_CNTR_ZERO) ==APT_CLEAR_CBC_ON_CNTR_ZERO) { aptHandle->baseAddress->OC_PRD_CLR.reg |= protect->ocEvent; @@ -618,7 +618,7 @@ static void APT_SetProtectSrcEventPolarityEx(APT_Handle *aptHandle, unsigned int unsigned int curMpEventNum; /* System Compare Event Sources */ unsigned int curIoEventNum; /* I/O Event Source */ /* Sets the polarity of the trigger source. */ - for (int i = 0; i <= APT_EM_COMBINE_SRC_EVT_MP_6; i++) { + for (unsigned int i = 0; i <= APT_EM_COMBINE_SRC_EVT_MP_6; i++) { curEvent = i; curPolarity = (polarityMask >> curEvent) & 0x01; if (curEvent >= APT_EM_COMBINE_SRC_EVT_MP_1) { @@ -648,7 +648,7 @@ static void APT_SetSysEventProtectModeEx(APT_Handle *aptHandle, APT_OutCtrlProte unsigned int cbcClrOffsetPrd = 16; if (protect->ocEventModeEx == APT_OUT_CTRL_ONE_SHOT) { aptHandle->baseAddress->OC_MODE.reg &= (~(protect->ocSysEvent << ocModeOffset)); - } else if (protect->ocEventModeEx == APT_OUT_CTRL_CYCLE_BY_CYBLE) { + } else if (protect->ocEventModeEx == APT_OUT_CTRL_CYCLE_BY_CYCLE) { aptHandle->baseAddress->OC_MODE.reg |= (protect->ocSysEvent << ocModeOffset); if ((protect->cbcClrModeEx & APT_CLEAR_CBC_ON_CNTR_ZERO) ==APT_CLEAR_CBC_ON_CNTR_ZERO) { aptHandle->baseAddress->OC_PRD_CLR.reg |= protect->ocSysEvent; @@ -695,7 +695,7 @@ BASE_StatusType HAL_APT_ProtectInitEx(APT_Handle *aptHandle, APT_OutCtrlProtectE APT_PARAM_CHECK_WITH_RET(protect->originalEvtEx <= 0x1FF, BASE_STATUS_ERROR); /* 0x1FF : all event enable */ unsigned int cbcClrOffsetPrd = 16; aptHandle->baseAddress->OC_MODE.reg = 0x0; /* clear OC_MODE resgiter */ - aptHandle->baseAddress->TC_MODE.BIT.rg_emu_stop = 0x0; /* don't stop APT when emulation */ + aptHandle->baseAddress->TC_MODE.BIT.rg_emu_stop = 0x2; /* stop APT when emulation */ aptHandle->baseAddress->OC_PRD_CLR.reg = 0x0; /* clear OC_PRD_CLR register */ APT_SysProtectInitEx(aptHandle, protect); /* event management configuration */ @@ -935,7 +935,7 @@ void HAL_APT_EMSetWdOffsetAndWidth(APT_Handle *aptHandle, unsigned short offset, * @param calibrate Delay calibration. * @retval None. */ -void HAL_APT_EMSetValleySwithSoftDelay(APT_Handle *aptHandle, unsigned short calibrate) +void HAL_APT_EMSetValleySwitchSoftDelay(APT_Handle *aptHandle, unsigned short calibrate) { APT_ASSERT_PARAM(aptHandle != NULL); APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); @@ -1052,10 +1052,10 @@ BASE_StatusType HAL_APT_SetPWMDuty(APT_Handle *aptHandle, unsigned short cntCmpL { APT_ASSERT_PARAM(aptHandle != NULL); APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); - APT_PARAM_CHECK_WITH_RET(cntCmpLeftEdge > 0, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(cntCmpLeftEdge < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(cntCmpRightEdge > 0, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(cntCmpRightEdge < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpLeftEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpLeftEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpRightEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpRightEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); TC_REFC_REG tmpC; TC_REFD_REG tmpD; tmpC = aptHandle->baseAddress->TC_REFC; @@ -1077,20 +1077,21 @@ BASE_StatusType HAL_APT_SetPWMDutyByNumber(APT_Handle *aptHandle, unsigned int d { APT_ASSERT_PARAM(aptHandle != NULL); APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); - APT_PARAM_CHECK_WITH_RET(duty < MAX_DUTY, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(duty > 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(duty <= MAX_DUTY, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(duty >= 0, BASE_STATUS_ERROR); unsigned int cntCmpLeftEdge, cntCmpRightEdge; TC_REFC_REG tmpC; TC_REFD_REG tmpD; if (aptHandle->waveform.cntMode == APT_COUNT_MODE_UP_DOWN) { - cntCmpLeftEdge = aptHandle->waveform.timerPeriod - \ - (int)(((float)aptHandle->waveform.timerPeriod / MAX_DUTY) * duty); + cntCmpLeftEdge = (unsigned int)((1.0f - (float)duty / (float)MAX_DUTY) * \ + (float)aptHandle->waveform.timerPeriod); cntCmpRightEdge = cntCmpLeftEdge; } else { cntCmpLeftEdge = 1; - cntCmpRightEdge = (int)(((float)aptHandle->waveform.timerPeriod / MAX_DUTY) * duty + cntCmpLeftEdge); + cntCmpRightEdge = (unsigned int)((float)aptHandle->waveform.timerPeriod / (float)MAX_DUTY) * duty + \ + cntCmpLeftEdge; } tmpC = aptHandle->baseAddress->TC_REFC; tmpC.BIT.rg_cnt_refch = cntCmpLeftEdge; @@ -1423,4 +1424,33 @@ BASE_StatusType HAL_APT_ConfigRefDot(APT_Handle *aptHandle, APT_RefDotSelect ref APT_ConfigRefC, APT_ConfigRefD}; return APT_RefDotConfigTable[refDotSelect](aptHandle, refDotParameters); /* Configure reference point. */ +} + + +/** + * @brief Set APT period. + * @param aptHandle APT module handle. + * @param newPeriod New period. + * @param prdLoadMode Buffer load mode, recommend: APT_BUFFER_INDEPENDENT_LOAD. + * @param prdLoadEvt Period event load mode, recommend: APT_PERIOD_LOAD_EVENT_ZERO. + * @retval BASE_StatusType: OK, ERROR. + */ +BASE_StatusType HAL_APT_SetTimerPeriod(APT_Handle *aptHandle, unsigned short newPeriod, \ + APT_BufferLoadMode prdLoadMode, unsigned int prdLoadEvt) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_PARAM_CHECK_WITH_RET(prdLoadMode >= APT_BUFFER_DISABLE, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(prdLoadMode <= APT_BUFFER_GLOBAL_LOAD, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(prdLoadEvt >= APT_PERIOD_LOAD_EVENT_ZERO, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(prdLoadEvt <= APT_PERIOD_LOAD_EVENT_SYNC, BASE_STATUS_ERROR); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + /* Sets the period value of the member variable. */ + aptHandle->waveform.timerPeriod = newPeriod; + /* Set period load mode, recommend APT_BUFFER_INDEPENDENT_LOAD. */ + DCL_APT_SetPeriodLoadMode(aptHandle->baseAddress, prdLoadMode); + /* Set period load event, recommend APT_PERIOD_LOAD_EVENT_ZERO. */ + DCL_APT_SetPeriodLoadEvent(aptHandle->baseAddress, prdLoadEvt); + /* Set period register. */ + DCL_APT_SetTimeBasePeriod(aptHandle->baseAddress, newPeriod); + return BASE_STATUS_OK; } \ No newline at end of file diff --git a/src/drivers/apt/apt_v1/inc/apt_ip.h b/src/drivers/apt/apt_v1/inc/apt_ip.h index dfba827111c152557eaa037dbe132302670b9b0c..5ea76f6f51ae1016f560e8618bbe2e4ce654821d 100644 --- a/src/drivers/apt/apt_v1/inc/apt_ip.h +++ b/src/drivers/apt/apt_v1/inc/apt_ip.h @@ -82,6 +82,7 @@ /* Values that can be passed to DCL_APT_SetCompareLoadEvent() as the loadEvent parameter. */ #define APT_COMPARE_LOAD_EVENT_ZERO 0x00000001U #define APT_COMPARE_LOAD_EVENT_PERIOD 0x00000002U +#define APT_COMPARE_LOAD_EVENT_ZERO_PERIOD 0x00000003U #define APT_COMPARE_LOAD_EVENT_A1 0x00000004U #define APT_COMPARE_LOAD_EVENT_B1 0x00000008U #define APT_COMPARE_LOAD_EVENT_SYNC 0x00000010U @@ -344,7 +345,7 @@ typedef enum { */ typedef enum { APT_OUT_CTRL_ONE_SHOT = 0x00000000U, - APT_OUT_CTRL_CYCLE_BY_CYBLE = 0x00000001U, + APT_OUT_CTRL_CYCLE_BY_CYCLE = 0x00000001U, } APT_OutCtrlMode; /** @@ -664,11 +665,6 @@ typedef enum { APT_SYNCIN_SRC_APT1_SYNCOUT = 0x00000001U, APT_SYNCIN_SRC_APT2_SYNCOUT = 0x00000002U, APT_SYNCIN_SRC_APT3_SYNCOUT = 0x00000003U, - APT_SYNCIN_SRC_APT4_SYNCOUT = 0x00000004U, - APT_SYNCIN_SRC_APT5_SYNCOUT = 0x00000005U, - APT_SYNCIN_SRC_APT6_SYNCOUT = 0x00000006U, - APT_SYNCIN_SRC_APT7_SYNCOUT = 0x00000007U, - APT_SYNCIN_SRC_APT8_SYNCOUT = 0x00000008U, APT_SYNCIN_SRC_CAPM0_SYNCOUT = 0x00000009U, APT_SYNCIN_SRC_CAPM1_SYNCOUT = 0x0000000AU, APT_SYNCIN_SRC_CAPM2_SYNCOUT = 0x0000000BU, @@ -2556,11 +2552,11 @@ static inline void DCL_APT_SetOutCtrlEventMode(APT_RegStruct *aptx, APT_ASSERT_PARAM(IsAPTInstance(aptx)); APT_PARAM_CHECK_NO_RET((ocEvent >= APT_OC_NO_EVENT) && (ocEvent <= APT_OC_COMBINE_EVENT_B2)); APT_PARAM_CHECK_NO_RET(ocEventMode >= APT_OUT_CTRL_ONE_SHOT); - APT_PARAM_CHECK_NO_RET(ocEventMode <= APT_OUT_CTRL_CYCLE_BY_CYBLE); + APT_PARAM_CHECK_NO_RET(ocEventMode <= APT_OUT_CTRL_CYCLE_BY_CYCLE); unsigned ocModeOffset = 16; /* Offset of output control mode setting */ if (ocEventMode == APT_OUT_CTRL_ONE_SHOT) { aptx->OC_MODE.reg &= (~(ocEvent << ocModeOffset)); /* Set rg_oc_mode_evtx to 0 */ - } else if (ocEventMode == APT_OUT_CTRL_CYCLE_BY_CYBLE) { + } else if (ocEventMode == APT_OUT_CTRL_CYCLE_BY_CYCLE) { aptx->OC_MODE.reg |= (ocEvent << ocModeOffset); /* Set rg_oc_mode_evtx to 1 */ } } @@ -3467,4 +3463,263 @@ static inline void DCL_APT_ForceEvent(APT_RegStruct *aptx, APT_ForceEvtType frcE /** * @} */ +#define EM_OUT_EVT_FILTER_EN 0x0f +#define EM_CMB_MODE_OFFSET 16 +#define EM_CMB_MODE_INTERVAL 4 +#define EM_CMB_SRC_SEL_INTERVAL 4 +#define EM_OR_INTERVAL 16 +#define EM_CMB_EVT_NUM 4 +#define EM_COMBINE_A1_SRC_ENABLE_ALL 0xF +/** + * @defgroup APT APT + * @brief APT module. + * @{ + */ + + +/** + * @defgroup APT_Common APT Common + * @brief APT common external module. + * @{ + */ + +/** + * @defgroup APT_Handle_Definition APT Handle Definition + * @{ + */ + +/* + Basic type AHBL ALBH AHBH ALBL + ___ __ __ ___ __ __ + ChannelA __| |__ |___| __| |__ |___| + __ __ ___ ___ __ __ + ChannelB |___| __| |__ __| |__ |___| +*/ +/** + * @brief Basic PWM waveform type. + * @details waveform type: + * + APT_PWM_BASIC_A_HIGH_B_LOW -- Basic PWM waveform type 1. + * + APT_PWM_BASIC_A_LOW_B_HIGH -- Basic PWM waveform type 2. + * + APT_PWM_BASIC_A_HIGH_B_HIGH -- Basic PWM waveform type 3. + * + APT_PWM_BASIC_A_LOW_B_LOW -- Basic PWM waveform type 4. + */ +typedef enum { + APT_PWM_BASIC_A_HIGH_B_LOW = 0x00000000U, + APT_PWM_BASIC_A_LOW_B_HIGH = 0x00000001U, + APT_PWM_BASIC_A_HIGH_B_HIGH = 0x00000002U, + APT_PWM_BASIC_A_LOW_B_LOW = 0x00000003U, +} APT_PWMBasicType; + +/** + * @brief The actual outputs of PWM channelA and channelB. + * @details Output: + * + APT_PWM_OUT_BASIC_TYPE = 0x00000000U -- PWM channel output the waveform according to basic PWM type. + * + APT_PWM_OUT_ALWAYS_LOW = 0x00000001U -- PWM channel output low level. + * + APT_PWM_OUT_ALWAYS_HIGH = 0x00000002U -- PWM channel output high level. + */ +typedef enum { + APT_PWM_OUT_BASIC_TYPE = 0x00000000U, + APT_PWM_OUT_ALWAYS_LOW = 0x00000001U, + APT_PWM_OUT_ALWAYS_HIGH = 0x00000002U, +} APT_PWMChannelOutType; + +/** + * @brief PWM waveform configuration handle of APT module. + */ +typedef struct { + APT_PWMBasicType basicType; /**< Basic PWM waveform type. */ + APT_PWMChannelOutType chAOutType; /**< Actual output of PWM channelA. */ + APT_PWMChannelOutType chBOutType; /**< Actual output of PWM channelB. */ + APT_CountMode cntMode; /**< Count mode of APT time-base counter. */ + unsigned short dividerFactor; /**< Divider factor. The range is 0~4095. */ + unsigned short timerPeriod; /**< Count period of APT time-base timer. */ + unsigned short divInitVal; /**< Initial value of divider. */ + unsigned short cntInitVal; /**< Initial value of time-base counter */ + unsigned short cntCmpLeftEdge; /**< Count compare point of the left edge of PWM waveform. */ + unsigned short cntCmpRightEdge; /**< Count compare point of the right edge of PWM waveform. */ + APT_BufferLoadMode cntCmpLoadMode; /**< Buffer load mode of PWM waveform count compare value. */ + unsigned int cntCmpLoadEvt; /**< Buffer load event of PWM waveform count compare value. */ + unsigned short deadBandCnt; /**< Count value of dead-band counter. In units of APT clock. */ +} APT_PWMWaveForm; + +/** + * @brief ADC trigger configuration handle of APT module. + */ +typedef struct { + bool trgEnSOCA; /**< Enable of ADC trigger source SOCA. */ + APT_ADCTriggerSource trgSrcSOCA; /**< Source of ADC trigger source SOCA. */ + unsigned short trgScaleSOCA; /**< Scale of ADC trigger source SOCA. */ + unsigned short cntCmpSOCA; /**< Count compare point of ADC trigger source SOCA when using CMPA */ + bool trgEnSOCB; /**< Enable of ADC trigger source SOCB. */ + APT_ADCTriggerSource trgSrcSOCB; /**< Source of ADC trigger source SOCB. */ + unsigned short trgScaleSOCB; /**< Scale of ADC trigger source SOCB. */ + unsigned short cntCmpSOCB; /**< Count compare point of ADC trigger source SOCB when using CMPB */ + APT_BufferLoadMode cntCmpLoadMode; /**< Buffer load mode of ADC trigger count compare value. */ + unsigned int cntCmpLoadEvt; /**< Buffer load event of ADC trigger count compare value. */ +} APT_ADCTrigger; + +/** + * @brief Timer interrupt configuration handle of APT module. + */ +typedef struct { + bool tmrInterruptEn; /**< Enable of APT module timer interrupt. */ + APT_TimerInterruptSrc tmrInterruptSrc; /**< Source of APT module timer interrupt. */ + unsigned short tmrInterruptScale; /**< Scale of APT module timer interrupt. */ +} APT_TimerInterrupt; + +/** + * @brief Output control protection configuration handle of APT module. + */ +typedef struct { + bool ocEventEn; /**< Enable of output control event. */ + APT_OutCtrlEvent ocEvent; /**< Output control event. Limited to IO events or system events. */ + APT_OutCtrlMode ocEventMode; /**< Output control protection mode. */ + APT_CBCClearMode cbcClrMode; /**< Event clear mode when using cycle-by-cycle mode. */ + APT_EMEventPolarity evtPolarity; /**< Event effective polarity. */ + APT_OutCtrlAction ocAction; /**< Output control protection action. */ + APT_EmulationMode emMode; /**< emulation mode */ + bool ocEvtInterruptEn; /**< Enable of output control event interrupt. */ +} APT_OutCtrlProtect; + +/** + * @brief Source event of event magnagement. + */ +typedef enum { + APT_EM_ORIGINAL_SRC_POE0 = 0x00000001U, + APT_EM_ORIGINAL_SRC_POE1 = 0x00000002U, + APT_EM_ORIGINAL_SRC_POE2 = 0x00000004U, + APT_EM_ORIGINAL_SRC_ACMP0 = 0x00000008U, + APT_EM_ORIGINAL_SRC_ACMP1 = 0x00000010U, + APT_EM_ORIGINAL_SRC_ACMP2 = 0x00000020U, + APT_EM_ORIGINAL_SRC_EVTMP4 = 0x00000040U, + APT_EM_ORIGINAL_SRC_EVTMP5 = 0x00000080U, + APT_EM_ORIGINAL_SRC_EVTMP6 = 0x00000100U, +} APT_EMOriginalEvtSrc; + +/** + * @brief Filter mask bit. + */ +typedef enum { + APT_EM_POE0_INVERT_BIT = 0x00000001U, + APT_EM_POE1_INVERT_BIT = 0x00000002U, + APT_EM_POE2_INVERT_BIT = 0x00000004U, + APT_EM_ACMP0_INVERT_BIT = 0x00000008U, + APT_EM_ACMP1_INVERT_BIT = 0x00000010U, + APT_EM_ACMP2_INVERT_BIT = 0x00000020U, + APT_EM_EVTMP4_INVERT_BIT = 0x00000040U, + APT_EM_EVTMP5_INVERT_BIT = 0x00000080U, + APT_EM_EVTMP6_INVERT_BIT = 0x00000100U, +} APT_EMPolarityMskBit; + +/** + * @brief System protect event; + */ +typedef enum { + APT_SYS_EVT_DEBUG = 0x00000010U, + APT_SYS_EVT_CLK = 0x00000020U, + APT_SYS_EVT_MEM = 0x00000040U, +} APT_SysOcEvent; + +/** + * @brief Output control protection configuration handle of APT module. + */ +typedef struct { + bool ocEventEnEx; /**< Oc event enable */ + APT_OutCtrlMode ocEventModeEx; /**< Output control protection mode. */ + APT_CBCClearMode cbcClrModeEx; /**< Event clear mode when using cycle-by-cycle mode. */ + APT_OutCtrlAction ocActionEx; /**< Output control protection channel A action. */ + APT_OutCtrlAction ocActionBEx; /**< Output control protection channel B action. */ + bool ocEvtInterruptEnEx; /**< Enable of output control event interrupt. */ + APT_SysOcEvent ocSysEvent; /**< System protect event */ + APT_EMOriginalEvtSrc originalEvtEx; /**< Event management's event source */ + APT_EMPolarityMskBit evtPolarityMaskEx; /**< Event effective polarity. */ + unsigned char filterCycleNumEx; /**< input source event filter */ +} APT_OutCtrlProtectEx; + +/** + * @brief struct of EM conbine event + */ +typedef struct { + APT_EMCombineEvtSrc emEvtSrc; /**< Combine event selection */ + APT_EMCombineEvtMode emEvtCombineMode; /**< Event combine mode */ + APT_EMEventPolarity emEvtPolar; /**< Event source polarity */ + unsigned int emEvtOrEnBits; /**< Event logic or enable bits */ +} APT_CombineEvt; + +/** + * @brief Shield window and capture configurations + */ +typedef struct { + bool wdEnable; /**< Shield windows enable bit */ + bool emCapEnable; /**< Enable EM captrue functions */ + APT_EMCombineEvent eventSel; /**< Window source event selection */ + APT_MaskWinResetMode wdStartAndCapClr; /**< Window's offset start count and EM capture clear condition */ + unsigned short wdOffset; /**< Window's offset value */ + unsigned short wdWidth; /**< Window's width value */ + APT_MaskWinPolarity wdPolar; /**< Window's polarity */ +} APT_WdAndCap; + + +/** + * @brief Valley switch configurations + */ +typedef struct { + bool vsEnable; /**< Valley switch enable */ + APT_EMEdgeFilterMode vsFilerEdgeSel; /**< Filter edge selection */ + unsigned char vsFilterCnt; /**< Filter edge count */ + APT_ValleyCapRstType vsClrType; /**< Clear type */ + APT_ValleyCountEdge vsCapEdgeSel; /**< Capture edge selection */ + unsigned char vsCapStartEdge; /**< Capture start edge */ + unsigned char vsCapEndEdge; /**< Capture end edge */ + APT_ValleyDelayMode vsCapDelayMode; /**< Capture delay mode */ + unsigned short vsCapSoftDelay; /**< Capture software calibrate value */ +} APT_ValleySw; + +/** + * @brief Event management handle of APT module + */ +typedef struct { + bool emEnable; /**< Enable bit of event management */ + APT_CombineEvt emEvt[EM_CMB_EVT_NUM]; /**< Combine events configuration */ + APT_WdAndCap emWdAndCap; /**< Shield windows and capture configuration */ + APT_ValleySw emValleySw; /**< Valley switch configuration */ +} APT_EventManage; + +/** + * @brief Synchronization handle of slave APT module. + */ +typedef struct { + unsigned short divPhase; /**< Divider phase when receiving APT synchronization pulse. */ + unsigned short cntPhase; /**< Counter phase when receiving APT synchronization pulse. */ + APT_SyncCountMode syncCntMode; /**< Count mode when receiving APT synchronization pulse. */ + APT_SyncInSrc syncInSrc; /**< Sync-in source of APT module */ + unsigned short cntrSyncSrc; + /**< Sync-in source of time-base counter synchronization + A logical OR of valid values can be passed as the cntrSyncSrc parameter. + Valid values for cntrSyncSrc are: + APT_CNTR_SYNC_SRC_COMBINE_EVENT_A1 - Enable combine event A1 as the counter synchronization source. + APT_CNTR_SYNC_SRC_COMBINE_EVENT_B1 - Enable combine event B1 as the counter synchronization source. + APT_CNTR_SYNC_SRC_SYNCIN - Enable Sync-In source as the counter synchronization source. */ +} APT_SlaveSyncIn; + +/** + * @brief Definition of callback function type. + */ +typedef void (* APT_CallbackType)(void *aptHandle); + +/** + * @brief Definition of callback function type. + */ +typedef struct { + void (* EvtInterruptCallBack)(void *handle); + void (* TmrInterruptCallBack)(void *handle); +} APT_UserCallBack; + +/** + * @brief Definition of callback function ID. + */ +typedef enum { + APT_TIMER_INTERRUPT = 0x00000000U, + APT_EVENT_INTERRUPT = 0x00000001U, +} APT_InterruputType; #endif /* McuMagicTag_APT_IP_H */ diff --git a/src/drivers/apt/apt_v1/src/apt.c b/src/drivers/apt/apt_v1/src/apt.c index e0ac4efddc38afd1eeffba63f1cc088dac1eb659..8efb600f5f67494786b6792a57f51eedbfd54ab7 100644 --- a/src/drivers/apt/apt_v1/src/apt.c +++ b/src/drivers/apt/apt_v1/src/apt.c @@ -352,10 +352,10 @@ BASE_StatusType HAL_APT_PWMInit(APT_Handle *aptHandle) APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.dividerFactor <= DIVIDER_FACTOR_MAX, BASE_STATUS_ERROR); APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.divInitVal <= aptHandle->waveform.dividerFactor, BASE_STATUS_ERROR); APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntInitVal < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpLeftEdge > 0, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpLeftEdge < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpRightEdge > 0, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpRightEdge < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpLeftEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpLeftEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpRightEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpRightEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); APT_PARAM_CHECK_WITH_RET(aptHandle->adcTrg.cntCmpSOCA >= 0, BASE_STATUS_ERROR); APT_PARAM_CHECK_WITH_RET(aptHandle->adcTrg.cntCmpSOCA < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); APT_PARAM_CHECK_WITH_RET(aptHandle->adcTrg.cntCmpSOCB >= 0, BASE_STATUS_ERROR); @@ -409,7 +409,7 @@ static void APT_SetOutCtrlProtectMode(APT_Handle *aptHandle, APT_OutCtrlProtect unsigned int cbcClrOffsetPrd = 16; if (protect->ocEventMode == APT_OUT_CTRL_ONE_SHOT) { aptHandle->baseAddress->OC_MODE.reg &= (~(protect->ocEvent << ocModeOffset)); - } else if (protect->ocEventMode == APT_OUT_CTRL_CYCLE_BY_CYBLE) { + } else if (protect->ocEventMode == APT_OUT_CTRL_CYCLE_BY_CYCLE) { aptHandle->baseAddress->OC_MODE.reg |= (protect->ocEvent << ocModeOffset); if ((protect->cbcClrMode & APT_CLEAR_CBC_ON_CNTR_ZERO) ==APT_CLEAR_CBC_ON_CNTR_ZERO) { aptHandle->baseAddress->OC_PRD_CLR.reg |= protect->ocEvent; @@ -614,7 +614,7 @@ static void APT_SetProtectSrcEventPolarityEx(APT_Handle *aptHandle, unsigned int unsigned int curMpEventNum; /* System Compare Event Sources */ unsigned int curIoEventNum; /* I/O Event Source */ /* Sets the polarity of the trigger source. */ - for (int i = 0; i <= APT_EM_COMBINE_SRC_EVT_MP_6; i++) { + for (unsigned int i = 0; i <= APT_EM_COMBINE_SRC_EVT_MP_6; i++) { curEvent = i; curPolarity = (polarityMask >> curEvent) & 0x01; if (curEvent >= APT_EM_COMBINE_SRC_EVT_MP_1) { @@ -644,7 +644,7 @@ static void APT_SetSysEventProtectModeEx(APT_Handle *aptHandle, APT_OutCtrlProte unsigned int cbcClrOffsetPrd = 16; if (protect->ocEventModeEx == APT_OUT_CTRL_ONE_SHOT) { aptHandle->baseAddress->OC_MODE.reg &= (~(protect->ocSysEvent << ocModeOffset)); - } else if (protect->ocEventModeEx == APT_OUT_CTRL_CYCLE_BY_CYBLE) { + } else if (protect->ocEventModeEx == APT_OUT_CTRL_CYCLE_BY_CYCLE) { aptHandle->baseAddress->OC_MODE.reg |= (protect->ocSysEvent << ocModeOffset); if ((protect->cbcClrModeEx & APT_CLEAR_CBC_ON_CNTR_ZERO) ==APT_CLEAR_CBC_ON_CNTR_ZERO) { aptHandle->baseAddress->OC_PRD_CLR.reg |= protect->ocSysEvent; @@ -691,7 +691,7 @@ BASE_StatusType HAL_APT_ProtectInitEx(APT_Handle *aptHandle, APT_OutCtrlProtectE APT_PARAM_CHECK_WITH_RET(protect->originalEvtEx <= 0x1FF, BASE_STATUS_ERROR); /* 0x1FF : all event enable */ unsigned int cbcClrOffsetPrd = 16; aptHandle->baseAddress->OC_MODE.reg = 0x0; /* clear OC_MODE resgiter */ - aptHandle->baseAddress->TC_MODE.BIT.rg_emu_stop = 0x0; /* don't stop APT when emulation */ + aptHandle->baseAddress->TC_MODE.BIT.rg_emu_stop = 0x2; /* stop APT when emulation */ aptHandle->baseAddress->OC_PRD_CLR.reg = 0x0; /* clear OC_PRD_CLR register */ APT_SysProtectInitEx(aptHandle, protect); /* event management configuration */ @@ -926,7 +926,7 @@ unsigned short HAL_APT_EMGetCapValue(APT_Handle *aptHandle) * @param calibrate Delay calibration. * @retval None. */ -void HAL_APT_EMSetValleySwithSoftDelay(APT_Handle *aptHandle, unsigned short calibrate) +void HAL_APT_EMSetValleySwitchSoftDelay(APT_Handle *aptHandle, unsigned short calibrate) { APT_ASSERT_PARAM(aptHandle != NULL); APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); @@ -1044,10 +1044,10 @@ BASE_StatusType HAL_APT_SetPWMDuty(APT_Handle *aptHandle, unsigned short cntCmpL { APT_ASSERT_PARAM(aptHandle != NULL); APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); - APT_PARAM_CHECK_WITH_RET(cntCmpLeftEdge > 0, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(cntCmpLeftEdge < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(cntCmpRightEdge > 0, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(cntCmpRightEdge < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpLeftEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpLeftEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpRightEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpRightEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); TC_REFC_REG tmpC; TC_REFD_REG tmpD; tmpC = aptHandle->baseAddress->TC_REFC; @@ -1069,20 +1069,21 @@ BASE_StatusType HAL_APT_SetPWMDutyByNumber(APT_Handle *aptHandle, unsigned int d { APT_ASSERT_PARAM(aptHandle != NULL); APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); - APT_PARAM_CHECK_WITH_RET(duty < MAX_DUTY, BASE_STATUS_ERROR); - APT_PARAM_CHECK_WITH_RET(duty > 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(duty <= MAX_DUTY, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(duty >= 0, BASE_STATUS_ERROR); unsigned int cntCmpLeftEdge, cntCmpRightEdge; TC_REFC_REG tmpC; TC_REFD_REG tmpD; if (aptHandle->waveform.cntMode == APT_COUNT_MODE_UP_DOWN) { - cntCmpLeftEdge = aptHandle->waveform.timerPeriod - \ - (int)(((float)aptHandle->waveform.timerPeriod / MAX_DUTY) * duty); + cntCmpLeftEdge = (unsigned int)((1.0f - (float)duty / (float)MAX_DUTY) * \ + (float)aptHandle->waveform.timerPeriod); cntCmpRightEdge = cntCmpLeftEdge; } else { cntCmpLeftEdge = 1; - cntCmpRightEdge = (int)(((float)aptHandle->waveform.timerPeriod / MAX_DUTY) * duty + cntCmpLeftEdge); + cntCmpRightEdge = (unsigned int)((float)aptHandle->waveform.timerPeriod / (float)MAX_DUTY) * duty + \ + cntCmpLeftEdge; } tmpC = aptHandle->baseAddress->TC_REFC; tmpC.BIT.rg_cnt_refc = cntCmpLeftEdge; @@ -1429,4 +1430,32 @@ BASE_StatusType HAL_APT_ConfigRefDot(APT_Handle *aptHandle, APT_RefDotSelect ref APT_ConfigRefC, APT_ConfigRefD}; return APT_RefDotConfigTable[refDotSelect](aptHandle, refDotParameters); /* Configure reference point. */ +} + +/** + * @brief Set APT period. + * @param aptHandle APT module handle. + * @param newPeriod New period. + * @param prdLoadMode Buffer load mode, recommend: APT_BUFFER_INDEPENDENT_LOAD. + * @param prdLoadEvt Period event load mode, recommend: APT_PERIOD_LOAD_EVENT_ZERO. + * @retval BASE_StatusType: OK, ERROR. + */ +BASE_StatusType HAL_APT_SetTimerPeriod(APT_Handle *aptHandle, unsigned short newPeriod, \ + APT_BufferLoadMode prdLoadMode, unsigned int prdLoadEvt) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_PARAM_CHECK_WITH_RET(prdLoadMode >= APT_BUFFER_DISABLE, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(prdLoadMode <= APT_BUFFER_GLOBAL_LOAD, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(prdLoadEvt >= APT_PERIOD_LOAD_EVENT_ZERO, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(prdLoadEvt <= APT_PERIOD_LOAD_EVENT_SYNC, BASE_STATUS_ERROR); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + /* Sets the period value of the member variable. */ + aptHandle->waveform.timerPeriod = newPeriod; + /* Set period load mode, recommend APT_BUFFER_INDEPENDENT_LOAD. */ + DCL_APT_SetPeriodLoadMode(aptHandle->baseAddress, prdLoadMode); + /* Set period load event, recommend APT_PERIOD_LOAD_EVENT_ZERO. */ + DCL_APT_SetPeriodLoadEvent(aptHandle->baseAddress, prdLoadEvt); + /* Set period register. */ + DCL_APT_SetTimeBasePeriod(aptHandle->baseAddress, newPeriod); + return BASE_STATUS_OK; } \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/arch/include/os_cpu_riscv_external.h b/src/drivers/apt/apt_v2/inc/apt_ex.h similarity index 61% rename from src/middleware/hisilicon/nostask/arch/include/os_cpu_riscv_external.h rename to src/drivers/apt/apt_v2/inc/apt_ex.h index ce8af8a0c0623a8d13e4e90e068429aab104f5ca..09a13f41ebb6532be2aa911d9ca9f37eb738b91e 100644 --- a/src/middleware/hisilicon/nostask/arch/include/os_cpu_riscv_external.h +++ b/src/drivers/apt/apt_v2/inc/apt_ex.h @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,37 +15,43 @@ * 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. - * @file os_cpu_riscv_external.h + * @file apt_ex.c + * @author MCU Driver Team + * @brief apt module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the apt. + * + high resolution of pwm setting. */ -#ifndef OS_CPU_RISCV_EXTERNAL_H -#define OS_CPU_RISCV_EXTERNAL_H +#ifndef McuMagicTag_APT_EX_H +#define McuMagicTag_APT_EX_H +#include "apt.h" -#include "nos_buildef.h" - -#define OS_TSK_STACK_SIZE_ALIGN 16 -#define OS_TSK_MIN_STACK_SIZE 0x100 - -/* Previous Privilege Mode - Machine Mode */ -#define MSTATUS_MPP_M_MODE (3U << 11) -/* Interrupt Enable Bit in Previous Privilege Mode */ -#define MSTATUS_MPIE (1U << 7) +/** + * @addtogroup APT_IP + * @{ + */ +typedef enum { + APT_POE0 = 0, + APT_POE1, + APT_POE2, +} APT_POEx; +/** + * @defgroup APT_EX_API_Declaration APT HAL API EX + * @{ + */ -#define MSTATUS_FS (1U << 13) +BASE_StatusType HAL_APT_SetHRPWM(APT_Handle *aptHandle, APT_PWMChannel pwmChannel, + APT_PWMDelayStep riseDelayStep, APT_PWMDelayStep fallDelayStep); -/* - * Default MSTATUS register value to restore from stack - * upon scheduling a thread for the first time - */ -#define MSTATUS_DEF_RESTORE (MSTATUS_MPP_M_MODE | MSTATUS_MPIE | MSTATUS_FS) +APT_PoeStatus HAL_APT_GetPoeStatus(APT_Handle *aptHandle, APT_POEx poex); -extern void OsTskContextLoad(uintptr_t tcbAddr); -extern void OsTaskSwitch(void); -extern unsigned int OsGetLMB1(unsigned int value); +APT_PwmStatus HAL_APT_GetPwmStatus(APT_Handle *aptHandle, APT_PWMChannel pwmChannel); -/* task switch */ -INLINE void OsTaskTrap(void) -{ - OsTaskSwitch(); -} +/** + * @} + */ -#endif /* OS_CPU_RISCV_EXTERNAL_H */ +/** + * @} + */ +#endif /* McuMagicTag_APT_EX_H */ \ No newline at end of file diff --git a/src/drivers/apt/apt_v2/inc/apt_ip.h b/src/drivers/apt/apt_v2/inc/apt_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..0a2302f4610aebaeb2231edcc7181348a944363d --- /dev/null +++ b/src/drivers/apt/apt_v2/inc/apt_ip.h @@ -0,0 +1,4119 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file apt_ip.h + * @author MCU Driver Team + * @brief Header file containing APT module DCL driver functions. + * This file provides functions to manage the following functionalities of APT module. + * + Definition of APT configuration parameters. + * + APT registers mapping structure. + * + Direct Configuration Layer driver functions. + */ + +#ifndef McuMagicTag_APT_IP_H +#define McuMagicTag_APT_IP_H + +#include "baseinc.h" + +#ifdef APT_PARAM_CHECK + #define APT_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM + #define APT_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET + #define APT_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else + #define APT_ASSERT_PARAM(para) ((void)0U) + #define APT_PARAM_CHECK_NO_RET(para) ((void)0U) + #define APT_PARAM_CHECK_WITH_RET(param, ret) ((void)0U) +#endif + +/** + * @addtogroup APT + * @{ + */ + +/** + * @defgroup APT_IP APT_IP + * @brief APT_IP: apt_v1. + * @{ + */ + +/** + * @defgroup APT_Param_Def APT Parameters Definition + * @brief Definition of APT configuration parameters + * @{ + */ + +/* Bitmask of the aptx_run bits in SYSCTRL1 register. */ +#define RUN_APT0 0x00000001U +#define RUN_APT1 0x00000002U +#define RUN_APT2 0x00000004U +#define RUN_APT3 0x00000008U +#define RUN_APT4 0x00000010U +#define RUN_APT5 0x00000020U +#define RUN_APT6 0x00000040U +#define RUN_APT7 0x00000080U +#define RUN_APT8 0x00000100U + +/* Limited values for some configuration items of APT module. */ +#define DIVIDER_FACTOR_MAX 0x00000FFFU +#define TIMEBASE_COUNTER_MAX 0x0000FFFFU +#define TIMER_INTERRUPT_CNT_MAX 0x0000000FU +#define ADC_CONVERSION_START_CNT_MAX 0x0000000FU +#define VCAP_STARY_STOP_EDGE_CNT_MAX 0x0000000FU +#define EDGE_FILTER_EDGE_CNT_MAX 0x0000000FU +#define CNTR_SYNC_SOURCE_MAX 0x00000007U +#define SYNC_OUT_SOURCE_MAX 0x000000FFU +#define GLOBAL_LOAD_CNT_MAX 0x0000000FU + +/* Values that can be passed to DCL_APT_SetPeriodLoadEvent() as the loadEvent parameter. */ +#define APT_PERIOD_LOAD_EVENT_ZERO 0x00000001U +#define APT_PERIOD_LOAD_EVENT_A1 0x00000004U +#define APT_PERIOD_LOAD_EVENT_B1 0x00000008U +#define APT_PERIOD_LOAD_EVENT_SYNC 0x00000010U + +/* Values that can be passed to DCL_APT_SetCompareLoadEvent() as the loadEvent parameter. */ +#define APT_COMPARE_LOAD_EVENT_ZERO 0x00000001U +#define APT_COMPARE_LOAD_EVENT_PERIOD 0x00000002U +#define APT_COMPARE_LOAD_EVENT_ZERO_PERIOD 0x00000003U +#define APT_COMPARE_LOAD_EVENT_A1 0x00000004U +#define APT_COMPARE_LOAD_EVENT_B1 0x00000008U +#define APT_COMPARE_LOAD_EVENT_SYNC 0x00000010U + +/* Values that can be returned by DCL_APT_GetCounterDirection(). */ +#define APT_COUNTER_STATUS_COUNT_DOWN 0x00000000U +#define APT_COUNTER_STATUS_COUNT_UP 0x00000001U + +/* Values that can be passed to DCL_APT_SetPWMActionLoadEvent() and + * DCL_APT_SetSwContActionLoadEvent() as the loadEvent parameter. */ +#define APT_ACTION_LOAD_EVENT_ZERO 0x00000001U +#define APT_ACTION_LOAD_EVENT_PERIOD 0x00000002U +#define APT_ACTION_LOAD_EVENT_A1 0x00000004U +#define APT_ACTION_LOAD_EVENT_B1 0x00000008U +#define APT_ACTION_LOAD_EVENT_SYNC 0x00000010U + + +/* Values that can be passed to DCL_APT_SetDGConfigLoadEvent(), DCL_APT_SetREDCounterLoadEvent() and + * DCL_APT_SetFEDCounterLoadEvent() as the loadEvent parameter. */ + +#define APT_DEAD_BAND_LOAD_EVENT_ZERO 0x00000001U +#define APT_DEAD_BAND_LOAD_EVENT_PERIOD 0x00000002U + +/* Values that can be passed to DCL_APT_SetEMEventOR() as the event1OREn and event1OREn parameter. */ +#define APT_EM_OR_EN_GPIO_EVENT_1 0x00000001U +#define APT_EM_OR_EN_GPIO_EVENT_2 0x00000002U +#define APT_EM_OR_EN_GPIO_EVENT_3 0x00000004U +#define APT_EM_OR_EN_MXU_EVENT_1 0x00000008U +#define APT_EM_OR_EN_MXU_EVENT_2 0x00000010U +#define APT_EM_OR_EN_MXU_EVENT_3 0x00000020U +#define APT_EM_OR_EN_MXU_EVENT_4 0x00000040U +#define APT_EM_OR_EN_MXU_EVENT_5 0x00000080U +#define APT_EM_OR_EN_MXU_EVENT_6 0x00000100U +#define APT_EM_OR_EN_MXU_EVENT_7 0x00000200U +#define APT_EM_OR_EN_MXU_EVENT_8 0x00000400U +#define APT_EM_OR_EN_MXU_EVENT_9 0x00000800U +#define APT_EM_OR_EN_MXU_EVENT_10 0x00001000U +#define APT_EM_OR_EN_MXU_EVENT_11 0x00002000U +#define APT_EM_OR_EN_MXU_EVENT_12 0x00004000U + +/* Values that can be passed to DCL_APT_SetTimeBaseCounterSyncSrc() as the cntrSyncSrc parameter. */ +#define APT_CNTR_SYNC_SRC_COMBINE_EVENT_A1 0x00000001U +#define APT_CNTR_SYNC_SRC_COMBINE_EVENT_B1 0x00000002U +#define APT_CNTR_SYNC_SRC_SYNCIN 0x00000004U + +/* Values that can be passed to DCL_APT_SetSyncOutPulseSrc() as the syncOutSrc parameter. */ +#define APT_SYNC_OUT_ON_CNTR_ZERO 0x00000001U +#define APT_SYNC_OUT_ON_CNTR_PERIOD 0x00000002U +#define APT_SYNC_OUT_ON_COMBINE_EVENT_A1 0x00000004U +#define APT_SYNC_OUT_ON_COMBINE_EVENT_B1 0x00000008U +#define APT_SYNC_OUT_ON_CNTR_CMPB 0x00000020U +#define APT_SYNC_OUT_ON_CNTR_CMPC 0x00000040U +#define APT_SYNC_OUT_ON_CNTR_CMPD 0x00000080U + +/* Values that can be passed to DCL_APT_SetGlobalLoadPrescale() as the glbLoadEvt parameter. */ +#define APT_GLB_LOAD_ON_CNTR_ZERO 0x00000001U +#define APT_GLB_LOAD_ON_CNTR_PERIOD 0x00000002U +#define APT_GLB_LOAD_ON_CNTR_SYNC 0x00000004U + +/* APT high-resolution edge delay Events. */ +#define APT_CNT_LOAD_EVENT_ZERO 0x00000001U +#define APT_CNT_LOAD_EVENT_PERIOD 0x00000002U +#define APT_CNT_LOAD_EVENT_A1 0x00000004U +#define APT_CNT_LOAD_EVENT_B1 0x00000008U +#define APT_CNT_LOAD_EVENT_SYNC 0x00000010U +/* APT high resolution definition */ +#define HRPWM_LOAD_SHIFT (8) +#define HRPWM_LOAD_EVNETS (0x1F) +#define HR_EDGE_BUFFER_SHIFT (4) +/** + * @brief APT Extra Handle. + */ +typedef struct { + ; +} APT_ExtendHandle; + +/** + * @brief Emulation stop mode of APT module. + */ +typedef enum { + APT_EMULATION_NO_STOP = 0x00000001U, + APT_EMULATION_STOP_COUNTER = 0x00000002U, + APT_EMULATION_STOP_APT = 0x00000003U, +} APT_EmulationMode; + +/** + * @brief Count mode of time-base counter. + */ +typedef enum { + APT_COUNT_MODE_UP = 0x00000000U, + APT_COUNT_MODE_DOWN = 0x00000001U, + APT_COUNT_MODE_UP_DOWN = 0x00000002U, + APT_COUNT_MODE_FREEZE = 0x00000003U, +} APT_CountMode; + +/** + * @brief Count mode after synchronization for slave APT module. + */ +typedef enum { + APT_COUNT_MODE_AFTER_SYNC_DOWN = 0x00000000U, + APT_COUNT_MODE_AFTER_SYNC_UP = 0x00000001U, +} APT_SyncCountMode; + +/** + * @brief Count compare reference of time-base counter. + */ +typedef enum { + APT_COMPARE_REFERENCE_A = 0x00000000U, + APT_COMPARE_REFERENCE_B = 0x00000001U, + APT_COMPARE_REFERENCE_C = 0x00000002U, + APT_COMPARE_REFERENCE_D = 0x00000003U, +} APT_CompareRef; + +/** + * @brief Buffer load mode of the registers that support buffer register. + * @details Load mode: + * + APT_BUFFER_DISABLE -- Disable register buffer + * + APT_BUFFER_INDEPENDENT_LOAD -- Enable register buffer and load independently + * + APT_BUFFER_GLOBAL_LOAD -- enable register buffer and load globally + */ +typedef enum { + APT_BUFFER_DISABLE = 0x00000000U, + APT_BUFFER_INDEPENDENT_LOAD = 0x00000001U, + APT_BUFFER_GLOBAL_LOAD = 0x00000003U, +} APT_BufferLoadMode; + +/** + * @brief PWM waveform output channel. + */ +typedef enum { + APT_PWM_CHANNEL_A = 0x00000000U, + APT_PWM_CHANNEL_B = 0x00000001U, +} APT_PWMChannel; + +/** + * @brief PWM waveform action on PWM action events. + */ +typedef enum { + APT_PWM_ACTION_HOLD = 0x00000000U, + APT_PWM_ACTION_LOW = 0x00000001U, + APT_PWM_ACTION_HIGH = 0x00000002U, + APT_PWM_ACTION_TOGGLE = 0x00000003U, +} APT_PWMAction; + +/** + * @brief Count compare event for generating PWM waveform actions. + * The enumeration values are the register bit field offset of the corresponding action events. + */ +typedef enum { + APT_PWM_ACTION_ON_TIMEBASE_ZERO = 0U, + APT_PWM_ACTION_ON_TIMEBASE_PERIOD = 2U, + APT_PWM_ACTION_ON_CMPA_COUNT_UP = 4U, + APT_PWM_ACTION_ON_CMPA_COUNT_DOWN = 6U, + APT_PWM_ACTION_ON_CMPB_COUNT_UP = 8U, + APT_PWM_ACTION_ON_CMPB_COUNT_DOWN = 10U, + APT_PWM_ACTION_ON_CMPC_COUNT_UP = 12U, + APT_PWM_ACTION_ON_CMPC_COUNT_DOWN = 14U, + APT_PWM_ACTION_ON_CMPD_COUNT_UP = 16U, + APT_PWM_ACTION_ON_CMPD_COUNT_DOWN = 18U, + APT_PWM_ACTION_ON_C1_COUNT_UP = 20U, + APT_PWM_ACTION_ON_C1_COUNT_DOWN = 22U, + APT_PWM_ACTION_ON_C2_COUNT_UP = 24U, + APT_PWM_ACTION_ON_C2_COUNT_DOWN = 26U, +} APT_PWMActionEvent; + +/** + * @brief PWM action when using software continuous action. + */ +typedef enum { + APT_PWM_CONTINUOUS_ACTION_HOLD = 0x00000000U, + APT_PWM_CONTINUOUS_ACTION_LOW = 0x00000001U, + APT_PWM_CONTINUOUS_ACTION_HIGH = 0x00000002U, +} APT_PWMContAction; + +/** + * @brief PWM Generation event C1 and C2. + */ +typedef enum { + APT_PWM_GENERATION_EVENT_C1 = 0x00000000U, + APT_PWM_GENERATION_EVENT_C2 = 0x00000001U, +} APT_PGEventCx; + +/** + * @brief Source of PWM Generation event C1 and C2. + */ +typedef enum { + APT_PG_EVT_C_FORBIDDEN = 0x00000000U, + APT_PG_EVT_C_COMBINE_EVENT_A1 = 0x00000001U, + APT_PG_EVT_C_COMBINE_EVENT_A2 = 0x00000002U, + APT_PG_EVT_C_COMBINE_EVENT_B1 = 0x00000003U, + APT_PG_EVT_C_COMBINE_EVENT_B2 = 0x00000004U, + APT_PG_EVT_C_COMBINE_EVENT_FILT = 0x00000005U, + APT_PG_EVT_C_IO_EVENT1 = 0x00000006U, + APT_PG_EVT_C_IO_EVENT2 = 0x00000007U, + APT_PG_EVT_C_IO_EVENT3 = 0x00000008U, + APT_PG_EVT_C_SYNC_IN = 0x00000009U, +} APT_PGEventCxSrc; + +/** + * @brief Input source of Dead-Band rising edge delay counter. + * @details Input source: + * + APT_DB_RED_INPUT_PWM_A -- Dead-Band rising edge delay input is PWM channel A + * + APT_DB_RED_INPUT_PWM_B -- Dead-Band rising edge delay input is PWM channel B + */ +typedef enum { + APT_DB_RED_INPUT_PWM_A = 0x00000000U, + APT_DB_RED_INPUT_PWM_B = 0x00000001U, +} APT_REDInput; + +/** + * @brief Output mode of Dead-Band rising edge delay counter. + * @details Output mode: + * + APT_DB_RED_OUTPUT_NOT_INVERT -- Dead-Band rising edge delay output is not inverted + * + APT_DB_RED_OUTPUT_INVERT -- Dead-Band rising edge delay output is inverted + * + APT_DB_RED_OUTPUT_PWM_A -- Dead-Band rising edge delay is bypassed + */ +typedef enum { + APT_DB_RED_OUTPUT_NOT_INVERT = 0x00000000U, + APT_DB_RED_OUTPUT_INVERT = 0x00000002U, + APT_DB_RED_OUTPUT_PWM_A = 0x00000003U, +} APT_REDOutMode; + +/** + * @brief Input source of Dead-Band falling edge delay counter. + * @details Input source: + * + APT_DB_FED_INPUT_PWM_B -- Dead-Band falling edge delay input is PWM channel B + * + APT_DB_FED_INPUT_PWM_A -- Dead-Band falling edge delay input is PWM channel A + * + APT_DB_FED_INPUT_RED_OUT -- Falling edge delay input is rising edge delay output + * + APT_DB_FED_INPUT_ZERO -- Dead-Band falling edge delay input is 0 + */ +typedef enum { + APT_DB_FED_INPUT_PWM_B = 0x00000000U, + APT_DB_FED_INPUT_PWM_A = 0x00000001U, + APT_DB_FED_INPUT_RED_OUT = 0x00000002U, + APT_DB_FED_INPUT_ZERO = 0x00000003U, +} APT_FEDInput; + +/** + * @brief Output mode of Dead-Band falling edge delay counter. + * @details Output mode: + * + APT_DB_FED_OUTPUT_NOT_INVERT -- Dead-Band falling edge delay output is not inverted + * + APT_DB_FED_OUTPUT_INVERT -- Dead-Band falling edge delay output is inverted + * + APT_DB_FED_OUTPUT_PWM_B -- Dead-Band falling edge delay is bypassed + */ +typedef enum { + APT_DB_FED_OUTPUT_NOT_INVERT = 0x00000000U, /**< Dead-Band falling edge delay output is not inverted */ + APT_DB_FED_OUTPUT_INVERT = 0x00000002U, /**< Dead-Band falling edge delay output is inverted */ + APT_DB_FED_OUTPUT_PWM_B = 0x00000003U, /**< Dead-Band falling edge delay is bypassed */ +} APT_FEDOutMode; + +/** + * @brief Output control events. + */ +typedef enum { + APT_OC_NO_EVENT = 0x00000000U, + APT_OC_GPIO_EVENT_1 = 0x00000001U, + APT_OC_GPIO_EVENT_2 = 0x00000002U, + APT_OC_GPIO_EVENT_3 = 0x00000004U, + APT_OC_SYSTEM_EVENT_1 = 0x00000010U, + APT_OC_SYSTEM_EVENT_2 = 0x00000020U, + APT_OC_SYSTEM_EVENT_3 = 0x00000040U, + APT_OC_COMBINE_EVENT_A1 = 0x00000100U, + APT_OC_COMBINE_EVENT_A2 = 0x00000200U, + APT_OC_COMBINE_EVENT_B1 = 0x00000400U, + APT_OC_COMBINE_EVENT_B2 = 0x00000800U, +} APT_OutCtrlEvent; + +/** + * @brief Output control event mode. + */ +typedef enum { + APT_OUT_CTRL_ONE_SHOT = 0x00000000U, + APT_OUT_CTRL_CYCLE_BY_CYCLE = 0x00000001U, +} APT_OutCtrlMode; + +/** + * @brief Advanced output control events take into consideration of the direction of time-base counter. + * The enumeration values are the register bit field offset of the corresponding output control events. + */ +typedef enum { + APT_OC_EVT_GPIO_OR_SYSTEM_UP = 0U, + APT_OC_EVT_COMBINE_EVENT_A1_UP = 3U, + APT_OC_EVT_COMBINE_EVENT_A2_UP = 6U, + APT_OC_EVT_COMBINE_EVENT_B1_UP = 9U, + APT_OC_EVT_COMBINE_EVENT_B2_UP = 12U, + APT_OC_EVT_GPIO_OR_SYSTEM_DOWN = 16U, + APT_OC_EVT_COMBINE_EVENT_A1_DOWN = 19U, + APT_OC_EVT_COMBINE_EVENT_A2_DOWN = 22U, + APT_OC_EVT_COMBINE_EVENT_B1_DOWN = 25U, + APT_OC_EVT_COMBINE_EVENT_B2_DOWN = 28U, +} APT_OutCtrlEventDir; + +/** + * @brief Output control action. + * @details Control action: + * + APT_OUT_CTRL_ACTION_DISABLE -- Disable output protect control. Output PWM directly + * + APT_OUT_CTRL_ACTION_LOW -- Output low level + * + APT_OUT_CTRL_ACTION_HIGH -- Output high level + * + APT_OUT_CTRL_ACTION_HOLD -- Hold the current output state + * + APT_OUT_CTRL_ACTION_TOGGLE -- Toggle the current output state + * + APT_OUT_CTRL_ACTION_HIGH_Z -- High-impedance output + */ +typedef enum { + APT_OUT_CTRL_ACTION_DISABLE = 0x00000000U, + APT_OUT_CTRL_ACTION_LOW = 0x00000001U, + APT_OUT_CTRL_ACTION_HIGH = 0x00000002U, + APT_OUT_CTRL_ACTION_HOLD = 0x00000003U, + APT_OUT_CTRL_ACTION_TOGGLE = 0x00000004U, + APT_OUT_CTRL_ACTION_HIGH_Z = 0x00000005U, +} APT_OutCtrlAction; + +/** + * @brief Event latch clear mode of cycle-by-cycle output control mode. + */ +typedef enum { + APT_CLEAR_CBC_ON_CNTR_ZERO = 0x00000001U, + APT_CLEAR_CBC_ON_CNTR_PERIOD = 0x00000002U, + APT_CLEAR_CBC_ON_CNTR_ZERO_PERIOD = 0x00000003U, +} APT_CBCClearMode; + +/** + * @brief Source of timer interrupt. + */ +typedef enum { + APT_INT_SRC_CNTR_DISABLE = 0x00000000U, + APT_INT_SRC_CNTR_ZERO = 0x00000001U, + APT_INT_SRC_CNTR_PERIOD = 0x00000002U, + APT_INT_SRC_CNTR_ZERO_PERIOD = 0x00000003U, + APT_INT_SRC_CNTR_CMPA_UP = 0x00000004U, + APT_INT_SRC_CNTR_CMPA_DOWN = 0x00000005U, + APT_INT_SRC_CNTR_CMPB_UP = 0x00000006U, + APT_INT_SRC_CNTR_CMPB_DOWN = 0x00000007U, + APT_INT_SRC_CNTR_CMPC_UP = 0x00000008U, + APT_INT_SRC_CNTR_CMPC_DOWN = 0x00000009U, + APT_INT_SRC_CNTR_CMPD_UP = 0x0000000AU, + APT_INT_SRC_CNTR_CMPD_DOWN = 0x0000000BU, +} APT_TimerInterruptSrc; + +/** + * @brief ADC trigger channels. + */ +typedef enum { + APT_ADC_CONVERSION_START_A = 0x00000001U, + APT_ADC_CONVERSION_START_B = 0x00000002U, +} APT_ADCTriggerChannel; + +/** + * @brief Source of ADC trigger channels. + */ +typedef enum { + APT_CS_SRC_COMBINE_EVENT_A1 = 0x00000000U, + APT_CS_SRC_CNTR_ZERO = 0x00000001U, + APT_CS_SRC_CNTR_PERIOD = 0x00000002U, + APT_CS_SRC_CNTR_ZERO_PERIOD = 0x00000003U, + APT_CS_SRC_CNTR_CMPA_UP = 0x00000004U, + APT_CS_SRC_CNTR_CMPA_DOWN = 0x00000005U, + APT_CS_SRC_CNTR_CMPB_UP = 0x00000006U, + APT_CS_SRC_CNTR_CMPB_DOWN = 0x00000007U, + APT_CS_SRC_CNTR_CMPC_UP = 0x00000008U, + APT_CS_SRC_CNTR_CMPC_DOWN = 0x00000009U, + APT_CS_SRC_CNTR_CMPD_UP = 0x0000000AU, + APT_CS_SRC_CNTR_CMPD_DOWN = 0x0000000BU, +} APT_ADCTriggerSource; + +/** + * @brief DMA request source of ADC Converter Start submodule. + */ +typedef enum { + APT_CS_DMA_REQ_SRC_DISABLE = 0x00000000U, + APT_CS_DMA_REQ_SRC_CHANNEL_A = 0x00000001U, + APT_CS_DMA_REQ_SRC_CHANNEL_B = 0x00000002U, +} APT_ADCTrgDMAReqSrc; + +/** + * @brief DMA request type of ADC Converter Start submodule. + */ +typedef enum { + APT_CS_DMA_SINGLE_REQUEST = 0x00000000U, + APT_CS_DMA_BURST_REQUEST = 0x00000002U, +} APT_ADCTrgDMAReqType; + +/** + * @brief Polarity of the events of Event Management submodule. + * @details Polarity: + * + APT_EM_EVENT_POLARITY_NOT_INVERT -- High active. + * + APT_EM_EVENT_POLARITY_INVERT -- Low active. + * + APT_EM_EVENT_POLARITY_FORCE_LOW -- Force event to low level. + * + APT_EM_EVENT_POLARITY_FORCE_HIGH -- Force event to high level. + */ +typedef enum { + APT_EM_EVENT_POLARITY_NOT_INVERT = 0x00000000U, + APT_EM_EVENT_POLARITY_INVERT = 0x00000001U, + APT_EM_EVENT_POLARITY_FORCE_LOW = 0x00000002U, + APT_EM_EVENT_POLARITY_FORCE_HIGH = 0x00000003U, +} APT_EMEventPolarity; + +/** + * @brief GPIO events and system events of Event Management submodule. + * The enumeration values are the register bit field offset of the corresponding GPIO/system events. + */ +typedef enum { + APT_EM_GPIO_EVENT_1 = 0U, + APT_EM_GPIO_EVENT_2 = 2U, + APT_EM_GPIO_EVENT_3 = 4U, + APT_EM_GPIO_EVENT_4 = 6U, + APT_EM_GPIO_EVENT_5 = 8U, + APT_EM_SYSTEM_EVENT_1 = 16U, + APT_EM_SYSTEM_EVENT_2 = 18U, + APT_EM_SYSTEM_EVENT_3 = 20U, +} APT_EMIOSysEvent; + +/** + * @brief Multiplexing events of Event Management submodule. + * The enumeration values are the register bit field offset of the corresponding multiplexing events. + */ +typedef enum { + APT_EM_MP_EVENT_1 = 0U, + APT_EM_MP_EVENT_2 = 2U, + APT_EM_MP_EVENT_3 = 4U, + APT_EM_MP_EVENT_4 = 6U, + APT_EM_MP_EVENT_5 = 8U, + APT_EM_MP_EVENT_6 = 10U, +} APT_EMMuxEvent; + +/** + * @brief Event Module of Event Management submodule. + */ +typedef enum { + APT_EM_MODULE_A = 0x00000000U, + APT_EM_MODULE_B = 0x00000001U, +} APT_EMGroup; + +/** + * @brief Group of combine event source input. + */ +typedef enum { + APT_EM_COMBINE_SRC_GRP_A1 = 0x00000000U, + APT_EM_COMBINE_SRC_GRP_A2 = 0x00000001U, + APT_EM_COMBINE_SRC_GRP_B1 = 0x00000002U, + APT_EM_COMBINE_SRC_GRP_B2 = 0x00000003U, +} APT_EMCombineEvtSrcGrp; + +/** + * @brief Source of combine events A1, A2, B1, B2. + */ +typedef enum { + APT_EM_COMBINE_SRC_EVT_1 = 0x00000000U, + APT_EM_COMBINE_SRC_EVT_2 = 0x00000001U, + APT_EM_COMBINE_SRC_EVT_3 = 0x00000002U, + APT_EM_COMBINE_SRC_EVT_MP_1 = 0x00000003U, + APT_EM_COMBINE_SRC_EVT_MP_2 = 0x00000004U, + APT_EM_COMBINE_SRC_EVT_MP_3 = 0x00000005U, + APT_EM_COMBINE_SRC_EVT_MP_4 = 0x00000006U, + APT_EM_COMBINE_SRC_EVT_MP_5 = 0x00000007U, + APT_EM_COMBINE_SRC_EVT_MP_6 = 0x00000008U, + APT_EM_COMBINE_SRC_ALL_EVENT_OR = 0x0000000FU, /* based on EM_AOR_EN/EM_BOR_EN */ +} APT_EMCombineEvtSrc; + +/** + * @brief Combine events of Event Management submodule. + */ +typedef enum { + APT_EM_COMBINE_EVENT_A1 = 0x00000000U, + APT_EM_COMBINE_EVENT_A2 = 0x00000001U, + APT_EM_COMBINE_EVENT_B1 = 0x00000002U, + APT_EM_COMBINE_EVENT_B2 = 0x00000003U, +} APT_EMCombineEvent; + +/** + * @brief Combine Mode of combine events A1, A2, B1, B2. + * @details combine mode: + * + The combine result is set output to low level + * + The combine result is qual to event 1 + * + The combine result is the logical AND of group event 1 high level and group event 2 low level + * + The combine result is the logical AND of group event 1 high level and group event 2 low level + * + The combine result is the logical AND of group event 1 high level and group event 2 high level + * + The combine result is the logical AND of group event 1 low level and group event 2 low level + */ +typedef enum { + APT_EM_COMBINE_LOW_LEVEL = 0x00000000U, + APT_EM_COMBINE_EVT1 = 0x00000001U, + APT_EM_COMBINE_EVT1_H_AND_EVT2_L = 0x00000002U, + APT_EM_COMBINE_EVT1_H_AND_EVT2_H = 0x00000003U, + APT_EM_COMBINE_EVT1_L_AND_EVT2_H = 0x00000004U, + APT_EM_COMBINE_EVT2 = 0x00000005U, +} APT_EMCombineEvtMode; + +/** + * @brief Output type of combine events. + * @details Output type: + * +APT_EM_COMBINE_EVENT_OUT_ORIG_SIGNAL -- The source of combine event is unfiltered + * +APT_EM_COMBINE_EVENT_OUT_FILT_SIGNAL -- The source of combine event is filtered + */ +typedef enum { + APT_EM_COMBINE_EVENT_OUT_ORIG_SIGNAL = 0x00000000U, + APT_EM_COMBINE_EVENT_OUT_FILT_SIGNAL = 0x00000001U, +} APT_EMCombineEventOut; + +/** + * @brief Polarity of mask window. + */ +typedef enum { + APT_BLANK_EVENT_INSIDE_MASK_WIN = 0x00000000U, + APT_BLANK_EVENT_OUTSIDE_MASK_WIN = 0x00000001U, +} APT_MaskWinPolarity; + +/** + * @brief Reset mode of mask window and count capture. + */ +typedef enum { + APT_RESET_MASK_WIN_DISABLE = 0x00000000U, + APT_RESET_MASK_WIN_CNTR_ZERO = 0x00000001U, + APT_RESET_MASK_WIN_CNTR_PERIOD = 0x00000002U, + APT_RESET_MASK_WIN_CNTR_ZERO_PERIOD = 0x00000003U, +} APT_MaskWinResetMode; + +/** + * @brief Clock source of valley capture. + */ +typedef enum { + APT_VALLY_CAP_USE_MAIN_CLOCK = 0x00000000U, + APT_VALLEY_CAP_USE_DIVIDER_CLOCK = 0x00000001U, +} APT_ValleyCapClkMode; + +/** + * @brief Trigger source of valley capture. + */ +typedef enum { + APT_VALLEY_CAP_SRC_DISABLE = 0x00000000U, + APT_VALLEY_CAP_SRC_CNTR_ZERO = 0x00000001U, + APT_VALLEY_CAP_SRC_CNTR_PERIOD = 0x00000002U, + APT_VALLEY_CAP_SRC_CNTR_ZERO_PERIOD = 0x00000003U, + APT_VALLEY_CAP_SRC_COMBINE_EVENT_A1 = 0x00000004U, + APT_VALLEY_CAP_SRC_COMBINE_EVENT_A2 = 0x00000005U, + APT_VALLEY_CAP_SRC_COMBINE_EVENT_B1 = 0x00000006U, + APT_VALLEY_CAP_SRC_COMBINE_EVENT_B2 = 0x00000007U, +} APT_ValleyCapRstType; + +/** + * @brief Edge type of valley capture. + */ +typedef enum { + APT_VALLEY_CAP_RISING_EDGE = 0x00000000U, + APT_VALLEY_CAP_FALLING_EDGE = 0x00000001U, +} APT_ValleyCapEdgeType; + +/** + * @brief Delay calibration of valley capture. + * @details Delay calibration: + * + APT_VCAP_SW_DELAY -- Delay value = software delay value + * + APT_VCAP_VCNT_DELAY_DIVIDE_1_SW_DELAY -- Delay value = capture count value + software delay value + * + APT_VCAP_VCNT_DELAY_DIVIDE_2_SW_DELAY -- Delay value = capture count value / 2 + software delay value + * + APT_VCAP_VCNT_DELAY_DIVIDE_4_SW_DELAY -- Delay value = capture count value / 4 + software delay value + * + APT_VCAP_VCNT_DELAY_DIVIDE_8_SW_DELAY -- Delay value = capture count value / 8 + software delay value + * + APT_VCAP_VCNT_DELAY_DIVIDE_16_SW_DELAY -- Delay value = capture count value / 16 + software delay value + * + APT_VCAP_VCNT_DELAY_DIVIDE_32_SW_DELAY -- Delay value = capture count value / 32 + software delay value + */ +typedef enum { + APT_VCAP_SW_DELAY = 0x00000000U, + APT_VCAP_VCNT_DELAY_DIVIDE_1_SW_DELAY = 0x00000001U, + APT_VCAP_VCNT_DELAY_DIVIDE_2_SW_DELAY = 0x00000002U, + APT_VCAP_VCNT_DELAY_DIVIDE_4_SW_DELAY = 0x00000003U, + APT_VCAP_VCNT_DELAY_DIVIDE_8_SW_DELAY = 0x00000004U, + APT_VCAP_VCNT_DELAY_DIVIDE_16_SW_DELAY = 0x00000005U, + APT_VCAP_VCNT_DELAY_DIVIDE_32_SW_DELAY = 0x00000006U, +} APT_ValleyDelayMode; + +/** + * @brief Start and stop edge of valley capture. + */ +typedef enum { + APT_VALLEY_COUNT_START_EDGE = 0x00000000U, + APT_VALLEY_COUNT_STOP_EDGE = 0x00000001U, +} APT_ValleyCountEdge; + +/** + * @brief Edge filter mode of Event Management submodule. + */ +typedef enum { + APT_EM_EDGEFILTER_MODE_RISING = 0x00000000U, + APT_EM_EDGEFILTER_MODE_FALLING = 0x00000002U, + APT_EM_EDGEFILTER_MODE_BOTH = 0x00000003U, +} APT_EMEdgeFilterMode; + +/** + * @brief Sync-in source of slave APT module. + */ +typedef enum { + APT_SYNCIN_SRC_APT0_SYNCOUT = 0x00000000U, + APT_SYNCIN_SRC_APT1_SYNCOUT = 0x00000001U, + APT_SYNCIN_SRC_APT2_SYNCOUT = 0x00000002U, + APT_SYNCIN_SRC_APT3_SYNCOUT = 0x00000003U, + APT_SYNCIN_SRC_APT4_SYNCOUT = 0x00000004U, + APT_SYNCIN_SRC_APT5_SYNCOUT = 0x00000005U, + APT_SYNCIN_SRC_APT6_SYNCOUT = 0x00000006U, + APT_SYNCIN_SRC_APT7_SYNCOUT = 0x00000007U, + APT_SYNCIN_SRC_APT8_SYNCOUT = 0x00000008U, + APT_SYNCIN_SRC_CAPM0_SYNCOUT = 0x00000009U, + APT_SYNCIN_SRC_CAPM1_SYNCOUT = 0x0000000AU, + APT_SYNCIN_SRC_CAPM2_SYNCOUT = 0x0000000BU, + APT_SYNCIN_SRC_GPIO_EVENT_4 = 0x0000000CU, + APT_SYNCIN_SRC_GPIO_EVENT_5 = 0x0000000DU, + APT_SYNCIN_SRC_DISABLE = 0x0000000EU, +} APT_SyncInSrc; + +/** + * @brief Sync-out mode of master APT module. + * @details Sync-out mode: + * + APT_SYNCOUT_ONE_SHOT_MODE -- One-Shot synchronization mode + * + APT_SYNCOUT_MULTIPLE_MODE -- Multiple synchronization mode + */ +typedef enum { + APT_SYNCOUT_ONE_SHOT_MODE = 0x00000000U, + APT_SYNCOUT_MULTIPLE_MODE = 0x00000001U, +} APT_SyncOutMode; + +/** + * @brief Selection of sync-out latch when using one-shot sync-out mode. + * @details Sync-out latch: + * + APT_SYNCOUT_LATCH_SET_ON_SW_FORCE -- Select rg_latset_otsyn as the latch set condition + * + APT_SYNCOUT_LATCH_SET_ON_GLB_LOAD -- Select rg_latset_otgld as the latch set condition + */ +typedef enum { + APT_SYNCOUT_LATCH_SET_ON_SW_FORCE = 0x00000000U, + APT_SYNCOUT_LATCH_SET_ON_GLB_LOAD = 0x00000001U, +} APT_SyncOutLatSetSel; + +/** + * @brief Source of peripheral synchronization. + */ +typedef enum { + APT_PER_SYNCOUT_SRC_DISABLE = 0x00000000U, + APT_PER_SYNCOUT_SRC_CNTR_ZERO = 0x00000001U, + APT_PER_SYNCOUT_SRC_CNTR_PERIOD = 0x00000002U, + APT_PER_SYNCOUT_SRC_CNTR_ZERO_PERIOD = 0x00000003U, + APT_PER_SYNCOUT_SRC_CNTR_CMPC_UP = 0x00000004U, + APT_PER_SYNCOUT_SRC_CNTR_CMPC_DOWN = 0x00000005U, + APT_PER_SYNCOUT_SRC_CNTR_CMPD_UP = 0x00000006U, + APT_PER_SYNCOUT_SRC_CNTR_CMPD_DOWN = 0x00000007U, +} APT_PeriphSyncOutSrc; + +/** + * @brief Global buffer load mode. + */ +typedef enum { + APT_GLB_LOAD_ONE_SHOT_MODE = 0x00000000U, + APT_GLB_LOAD_MULTIPLE_MODE = 0x00000001U, +} APT_GlobalLoadMode; + +/** + * @brief The buffer of the registers that support buffer register. + */ +typedef enum { + APT_REG_BUFFER_TC_PRD = 0x00000001U, + APT_REG_BUFFER_TC_REFA = 0x00000002U, + APT_REG_BUFFER_TC_REFB = 0x00000004U, + APT_REG_BUFFER_TC_REFC = 0x00000008U, + APT_REG_BUFFER_TC_REFD = 0x00000010U, + APT_REG_BUFFER_PG_ACT_A = 0x00000040U, + APT_REG_BUFFER_PG_ACT_B = 0x00000080U, + APT_REG_BUFFER_PG_OUT_FRC = 0x00000100U, + APT_REG_BUFFER_DG_RED = 0x00000400U, + APT_REG_BUFFER_DG_FED = 0x00000800U, + APT_REG_BUFFER_DG_CFG = 0x00001000U, +} APT_RegBuffer; + +/** + * @brief Software force events. + */ +typedef enum { + APT_FORCE_EVENT_COUNTER_SYNC = 0x00000001U, + APT_FORCE_EVENT_SYNCOUT = 0x00000010U, + APT_FORCE_EVENT_SYNC_PERIPH = 0x00000100U, + APT_FORCE_EVENT_GLOBAL_LOAD = 0x00001000U, + APT_FORCE_EVENT_VALLEY_CAP_RST = 0x00010000U, + APT_FORCE_EVENT_ADC_START_A = 0x00100000U, + APT_FORCE_EVENT_ADC_START_B = 0x00200000U, + APT_FORCE_EVENT_TIMER_INTERRUPT = 0x01000000U, + APT_FORCE_EVENT_PWM_ACTION_BUF_LOAD = 0x10000000U, +} APT_ForceEvtType; + +/** + * @brief Software force events. + * @details Reference point selection. + * + APT_REFERENCE_DOTA -- Select referece dot A as action trigger point. + * + APT_REFERENCE_DOTB -- Select referece dot B as action trigger point. + * + APT_REFERENCE_DOTC -- Select referece dot C as action trigger point. + * + APT_REFERENCE_DOTD -- Select referece dot D as action trigger point. + */ +typedef enum { + APT_REFERENCE_DOTA = 0x00000000U, + APT_REFERENCE_DOTB = 0x00000001U, + APT_REFERENCE_DOTC = 0x00000002U, + APT_REFERENCE_DOTD = 0x00000003U, +} APT_RefDotSelect; + +/** + * @brief HRPWM Delay Step. + */ +typedef enum { + DELAY_0_STEP = 0x00000000U, + DELAY_1_STEP = 0x00000001U, + DELAY_2_STEP = 0x00000002U, + DELAY_3_STEP = 0x00000003U, + DELAY_4_STEP = 0x00000004U, + DELAY_5_STEP = 0x00000005U, + DELAY_6_STEP = 0x00000006U, + DELAY_7_STEP = 0x00000007U, + DELAY_8_STEP = 0x00000008U, + DELAY_9_STEP = 0x00000009U, + DELAY_10_STEP = 0x00000010U, + DELAY_11_STEP = 0x00000011U, +} APT_PWMDelayStep; + +/** + * @brief PWM output status + */ +typedef enum { + APT_PWM_LOW_LEVEL = 0x00000000U, + APT_PWM_HIGH_LEVEL = 0x00000001U, + APT_PWM_HIGH_RESISTANCE = 0x00000002U, +} APT_PwmStatus; + +/** + * @brief Protection pin level status. + */ +typedef enum { + APT_POE_LOW_LEVEL = 0x00000000U, + APT_POE_HIGH_LEVEL = 0x00000001U, +} APT_PoeStatus; + +/** + * @brief Edge of High resolution PWM. + */ +typedef enum { + APT_CHANNEL_A_RISE = 0x00000000U, + APT_CHANNEL_A_FALL = 0x00000001U, + APT_CHANNEL_B_RISE = 0x00000002U, + APT_CHANNEL_B_FALL = 0x00000003U, +} APT_HrPwmEdge; + +/** + * @brief Configure action point parameters. + * @details Property of the action point. + * + refDotValue -- the action point value. + * + refDotDivValue -- frequency division value of the action point. + * + pwmChannel -- number of channels for which the action point needs to be changed. @ref APT_PWMChannel + * + actionEvent -- action event configure of reference point. @ref APT_PWMActionEvent + * + action -- triggle action of reference point. @ref APT_PWMAction + * @note: the value of Reference Point must be less than or equal to the value of period. + */ +typedef struct { + unsigned int refDotValue; + APT_PWMChannel pwmChannel; /* PWM channel selection. */ + APT_PWMActionEvent actionEvent; /* Point triggle action event. */ + APT_PWMAction action; /* Point action. */ +} APT_RefDotParameters; +/** + * @} + */ + +/** + * @defgroup APT_REG_Definition APT Register Structure. + * @brief APT Register Structure Definition. + * @{ + */ +typedef union { + unsigned int reg; + struct { + unsigned int sub_version : 4; /**< ip subversion */ + unsigned int main_version : 4; /**< ip main verison */ + unsigned int reserved0 : 24; + } BIT; +} volatile VER_INFO_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_cnt_mode : 2; /**< timer work mode */ + unsigned int reserved0 : 14; + unsigned int rg_div_fac : 12; /**< divider factor */ + unsigned int rg_emu_stop : 2; /**< emulation stop mode */ + unsigned int reserved1 : 2; + } BIT; +} volatile TC_MODE_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_cnt_phs : 16; /**< timer's phase */ + unsigned int reserved0 : 15; + unsigned int rg_cnt_dir : 1; /**< timer count direction */ + } BIT; +} volatile TC_PHS_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_cnt_ovrid : 16; /**< timer count init value */ + unsigned int reserved0 : 15; + unsigned int rg_cnt_ovrid_en : 1; /**< timer and divider init enable */ + } BIT; +} volatile TC_OVRID_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_cnt_prd : 16; /* count period */ + unsigned int reserved0 : 16; + } BIT; +} volatile TC_PRD_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_cnt_refa : 16; /* reference A counter value */ + unsigned int reserved0 : 16; + } BIT; +} volatile TC_REFA_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_cnt_refb : 16; /* reference B counter value */ + unsigned int reserved0 : 16; + } BIT; +} volatile TC_REFB_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_cnt_refc : 16; /* reference C counter value */ + unsigned int reserved0 : 16; + } BIT; +} volatile TC_REFC_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_cnt_refd : 16; /* reference D counter value */ + unsigned int reserved0 : 16; + } BIT; +} volatile TC_REFD_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_prd_buf_en : 1; /**< period buffer enable */ + unsigned int rg_prd_gld_en : 1; /**< period global buffer enable */ + unsigned int reserved0 : 2; + unsigned int rg_refa_buf_en : 1; /**< reference A buffer enable */ + unsigned int rg_refa_gld_en : 1; /**< reference A global buffer enable */ + unsigned int rg_refb_buf_en : 1; /**< reference B buffer enable */ + unsigned int rg_refb_gld_en : 1; /**< reference B global buffer enable */ + unsigned int rg_refc_buf_en : 1; /**< reference C buffer enable */ + unsigned int rg_refc_gld_en : 1; /**< reference C global buffer enable */ + unsigned int rg_refd_buf_en : 1; /**< reference D buffer enable */ + unsigned int rg_refd_gld_en : 1; /**< reference D global buffer enable */ + unsigned int reserved1 : 20; + } BIT; +} volatile TC_BUF_EN_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_prd_ld_zroen : 1; /**< period value register load at zero */ + unsigned int reserved0 : 1; + unsigned int rg_prd_ld_a1en : 1; /**< period value load at evt_a1 */ + unsigned int rg_prd_ld_b1en : 1; /**< period value load at evt_b1 */ + unsigned int rg_prd_ld_synen : 1; /**< period value load at sync signal input */ + unsigned int reserved1 : 27; + } BIT; +} volatile TC_PRD_LOAD_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_refa_ld_zroen : 1; /**< reference A value load at zero */ + unsigned int rg_refa_ld_prden : 1; /**< reference A value load at period */ + unsigned int rg_refa_ld_a1en : 1; /**< reference A value load at evt_a1 */ + unsigned int rg_refa_ld_b1en : 1; /**< reference A value load at evt_b1 */ + unsigned int rg_refa_ld_synen : 1; /**< reference A value load at sync signal input */ + unsigned int reserved0 : 3; + unsigned int rg_refb_ld_zroen : 1; /**< reference B value load at zero */ + unsigned int rg_refb_ld_prden : 1; /**< reference B value load at period */ + unsigned int rg_refb_ld_a1en : 1; /**< reference B value load at evt_a1 */ + unsigned int rg_refb_ld_b1en : 1; /**< reference B value load at evt_b1 */ + unsigned int rg_refb_ld_synen : 1; /**< reference B value load at sync signal input */ + unsigned int reserved1 : 3; + unsigned int rg_refc_ld_zroen : 1; /**< reference C value load at zero */ + unsigned int rg_refc_ld_prden : 1; /**< reference C value load at period */ + unsigned int rg_refc_ld_a1en : 1; /**< reference C value load at evt_a1 */ + unsigned int rg_refc_ld_b1en : 1; /**< reference C value load at evt_b1 */ + unsigned int rg_refc_ld_synen : 1; /**< reference C value load at sync signal input */ + unsigned int reserved2 : 3; + unsigned int rg_refd_ld_zroen : 1; /**< reference D value load at zero */ + unsigned int rg_refd_ld_prden : 1; /**< reference D value load at period */ + unsigned int rg_refd_ld_a1en : 1; /**< reference D value load at evt_a1 */ + unsigned int rg_refd_ld_b1en : 1; /**< reference D value load at evt_b1 */ + unsigned int rg_refd_ld_synen : 1; /**< reference D value load at sync signal input */ + unsigned int reserved3 : 3; + } BIT; +} volatile TC_REF_LOAD_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_mskwd_psel : 1; /**< mask window polarity */ + unsigned int reserved0 : 30; + unsigned int rg_mskwd_en : 1; /**< mask window enable */ + } BIT; +} volatile TC_MWD_EN_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_mwd_refa : 16; /**< mask window reference value A */ + unsigned int reserved0 : 16; + } BIT; +} volatile TC_MWDREFA_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_mwd_refb : 16; /**< mask window reference value B */ + unsigned int reserved0 : 16; + } BIT; +} volatile TC_MWDREFB_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_mwdrefa_act_inc : 2; /**< action at reference A increase */ + unsigned int rg_mwdrefa_act_dec : 2; /**< action at reference A decrease */ + unsigned int rg_mwdrefb_act_inc : 2; /**< action at reference B increase */ + unsigned int rg_mwdrefb_act_dec : 2; /**< action at reference B decrease */ + unsigned int reserved0 : 24; + } BIT; +} volatile TC_MWD_ACT_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_mwdrefa_buf_en : 1; /**< mask window reference A buffer enable */ + unsigned int rg_mwdrefa_gld_en : 1; /**< mask window reference A global buffer enable */ + unsigned int rg_mwdrefb_buf_en : 1; /**< mask window reference B buffer enable */ + unsigned int rg_mwdrefb_gld_en : 1; /**< mask window reference B global buffer enable */ + unsigned int rg_mwd_act_buf_en : 1; /**< mask window action buffer enable */ + unsigned int rg_mwd_act_gld_en : 1; /**< mask window action global buffer enable */ + unsigned int reserved0 : 26; + } BIT; +} volatile TC_MWD_BUF_EN_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_mwdrefa_ld_zroen : 1; /**< mask window refrence A load at zero enable */ + unsigned int rg_mwdrefa_ld_prden : 1; /**< mask window refrence A load at period enable */ + unsigned int reserved0 : 1; + unsigned int rg_mwdrefb_ld_zroen : 1; /**< mask window refrence B load at zero enable */ + unsigned int rg_mwdrefb_ld_prden : 1; /**< mask window refrence B load at period enable */ + unsigned int reserved1 : 1; + unsigned int rg_mwd_act_ld_zroen : 1; /**< mask window action register load at zero enable */ + unsigned int rg_mwd_act_ld_prden : 1; /**< mask window action register load at period enable */ + unsigned int reserved2 : 24; + } BIT; +} volatile TC_MWD_LOAD_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int ro_cnt_val : 16; /**< counter value */ + unsigned int ro_div_cnt : 12; /**< divider value */ + unsigned int reserved0 : 3; + unsigned int ro_cnt_dir : 1; /**< count direction */ + } BIT; +} volatile TC_STS_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_pga_act_zro : 2; /**< PG channel A action at zero */ + unsigned int rg_pga_act_prd : 2; /**< PG channel A action at period */ + unsigned int rg_pga_act_refa_inc : 2; /**< PG channel A action at reference A increase */ + unsigned int rg_pga_act_refa_dec : 2; /**< PG channel A action at reference A decrease */ + unsigned int rg_pga_act_refb_inc : 2; /**< PG channel A action at reference B increase */ + unsigned int rg_pga_act_refb_dec : 2; /**< PG channel A action at reference B decrease */ + unsigned int rg_pga_act_refc_inc : 2; /**< PG channel A action at reference C increase */ + unsigned int rg_pga_act_refc_dec : 2; /**< PG channel A action at reference C decrease */ + unsigned int rg_pga_act_refd_inc : 2; /**< PG channel A action at reference D increase */ + unsigned int rg_pga_act_refd_dec : 2; /**< PG channel A action at reference D decrease */ + unsigned int rg_pga_act_evtc1_inc : 2; /**< PG channel A action at evt_c1 increase */ + unsigned int rg_pga_act_evtc1_dec : 2; /**< PG channel A action at evt_c1 decrease */ + unsigned int rg_pga_act_evtc2_inc : 2; /**< PG channel A action at evt_c2 increase */ + unsigned int rg_pga_act_evtc2_dec : 2; /**< PG channel A action at evt_c2 decrease */ + unsigned int reserved0 : 4; + } BIT; +} volatile PG_ACT_A_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_pgb_act_zro : 2; /**< PG channel A action at zero */ + unsigned int rg_pgb_act_prd : 2; /**< PG channel A action at period */ + unsigned int rg_pgb_act_refa_inc : 2; /**< PG channel A action at reference A increase */ + unsigned int rg_pgb_act_refa_dec : 2; /**< PG channel A action at reference A decrease */ + unsigned int rg_pgb_act_refb_inc : 2; /**< PG channel A action at reference B increase */ + unsigned int rg_pgb_act_refb_dec : 2; /**< PG channel A action at reference B decrease */ + unsigned int rg_pgb_act_refc_inc : 2; /**< PG channel A action at reference C increase */ + unsigned int rg_pgb_act_refc_dec : 2; /**< PG channel A action at reference C decrease */ + unsigned int rg_pgb_act_refd_inc : 2; /**< PG channel A action at reference D increase */ + unsigned int rg_pgb_act_refd_dec : 2; /**< PG channel A action at reference D decrease */ + unsigned int rg_pgb_act_evtc1_inc : 2; /**< PG channel A action at evt_c1 increase */ + unsigned int rg_pgb_act_evtc1_dec : 2; /**< PG channel A action at evt_c1 decrease */ + unsigned int rg_pgb_act_evtc2_inc : 2; /**< PG channel A action at evt_c2 increase */ + unsigned int rg_pgb_act_evtc2_dec : 2; /**< PG channel A action at evt_c2 decrease */ + unsigned int reserved0 : 4; + } BIT; +} volatile PG_ACT_B_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_pga_act_evt_frc : 2; /**< channel A force action select */ + unsigned int rg_pga_evt_frc : 1; /**< enable a force action at channel A */ + unsigned int reserved0 : 1; + unsigned int rg_pgb_act_evt_frc : 2; /**< channel A force action select */ + unsigned int rg_pgb_evt_frc : 1; /**< enable a force action at channel A */ + unsigned int reserved1 : 25; + } BIT; +} volatile PG_ACT_FRC_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_pga_frc_act : 2; /**< channel A force output action select */ + unsigned int rg_pga_frc_en : 1; /**< channel A force output action enable */ + unsigned int reserved0 : 1; + unsigned int rg_pgb_frc_act : 2; /**< channel A force output action select */ + unsigned int rg_pgb_frc_en : 1; /**< channel A force output action enable */ + unsigned int reserved1 : 25; + } BIT; +} volatile PG_OUT_FRC_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_acta_buf_en : 1; /**< channel A action value buffer enable */ + unsigned int rg_acta_gld_en : 1; /**< channel A action value global buffer enable */ + unsigned int rg_actb_buf_en : 1; /**< channel B action value buffer enable */ + unsigned int rg_actb_gld_en : 1; /**< channel B action value global buffer enable */ + unsigned int rg_frc_buf_en : 1; /**< force output config buffer enable */ + unsigned int rg_frc_gld_en : 1; /**< force output config global buffer enable */ + unsigned int reserved0 : 26; + } BIT; +} volatile PG_BUF_EN_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_pga_actld_zroen : 1; /**< enable PG channel A action value independent load at zero */ + unsigned int rg_pga_actld_prden : 1; /**< enable PG channel A action value independent load at period */ + unsigned int rg_pga_actld_a1en : 1; /**< enable PG channel A action value independent load at evt_a1 */ + unsigned int rg_pga_actld_b1en : 1; /**< enable PG channel A action value independent load at evt_b1 */ + unsigned int rg_pga_actld_synen : 1; /**< enable PG channel A action value independent load at sync signal */ + unsigned int reserved0 : 3; + unsigned int rg_pgb_actld_zroen : 1; /**< enable PG channel B action value independent load at zero */ + unsigned int rg_pgb_actld_prden : 1; /**< enable PG channel B action value independent load at period */ + unsigned int rg_pgb_actld_a1en : 1; /**< enable PG channel B action value independent load at evt_a1 */ + unsigned int rg_pgb_actld_b1en : 1; /**< enable PG channel B action value independent load at evt_b1 */ + unsigned int rg_pgb_actld_synen : 1; /**< enable PG channel B action value independent load at sync signal */ + unsigned int reserved1 : 3; + unsigned int rg_pg_frcld_zroen : 1; /**< enable force action config value independent load at zero */ + unsigned int rg_pg_frcld_prden : 1; /**< enable force action config value independent load at period */ + unsigned int reserved2 : 2; + unsigned int rg_pg_frcld_synen : 1; /**< enable force action config value independent load at sync signal */ + unsigned int reserved3 : 3; + unsigned int reserved4 : 8; + } BIT; +} volatile PG_ACT_LD_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_pga_evtc1_sel : 4; /**< pga_evtc1 source select */ + unsigned int rg_pga_evtc2_sel : 4; /**< pga_evtc2 source select */ + unsigned int rg_pgb_evtc1_sel : 4; /**< pgb_evtc1 source select */ + unsigned int rg_pgb_evtc2_sel : 4; /**< pgb_evtc2 source select */ + unsigned int reserved0 : 16; + } BIT; +} volatile PG_EVTC_SEL_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_dg_red : 16; /**< deadband time at rising edge */ + unsigned int reserved0 : 16; + } BIT; +} volatile DG_RED_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_dg_fed : 16; /**< deadband timer at falling edge */ + unsigned int reserved0 : 16; + } BIT; +} volatile DG_FED_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_dg_red_isel : 2; /**< rising edge delay source input select */ + unsigned int rg_dg_fed_isel : 2; /**< falling edge delay source input select */ + unsigned int rg_dg_red_osel : 2; /**< rising edge delay polarity select */ + unsigned int rg_dg_fed_osel : 2; /**< falling edge delay polarity select */ + unsigned int rg_dga_osel : 1; /**< dga output waveform swap select */ + unsigned int rg_dgb_osel : 1; /**< dgb output waveform swap select */ + unsigned int reserved0 : 22; + } BIT; +} volatile DG_CFG_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_red_buf_en : 1; /**< rising edge delay value buffer enable */ + unsigned int rg_red_gld_en : 1; /**< rising edge delay value global buffer enable */ + unsigned int rg_fed_buf_en : 1; /**< falling edge delay value buffer enable */ + unsigned int rg_fed_gld_en : 1; /**< falling edge delay value global buffer enable */ + unsigned int rg_cfg_buf_en : 1; /**< deadband config buffer enable */ + unsigned int rg_cfg_gld_en : 1; /**< deadband config global enable */ + unsigned int reserved0 : 26; + } BIT; +} volatile DG_BUF_EN_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_red_ld_zroen : 1; /**< rising edge delay value load independent at zero */ + unsigned int rg_red_ld_prden : 1; /**< rising edge delay value load independent at period */ + unsigned int reserved0 : 6; + unsigned int rg_fed_ld_zroen : 1; /**< falling edge delay value load independent at zero */ + unsigned int rg_fed_ld_prden : 1; /**< falling edge delay value load independent at period */ + unsigned int reserved1 : 6; + unsigned int rg_cfg_ld_zroen : 1; /**< deadband config register value load independent at zero */ + unsigned int rg_cfg_ld_prden : 1; /**< deadband config register value load independent at period */ + unsigned int reserved2 : 14; + } BIT; +} volatile DG_BUF_LOAD_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_oc_en_evt1 : 1; /**< evtio1 output control enable */ + unsigned int rg_oc_en_evt2 : 1; /**< evtio2 output control enable */ + unsigned int rg_oc_en_evt3 : 1; /**< evtio3 output control enable */ + unsigned int reserved0 : 1; + unsigned int rg_oc_en_evts1 : 1; /**< evts1 output control enable */ + unsigned int rg_oc_en_evts2 : 1; /**< evts2 output control enable */ + unsigned int rg_oc_en_evts3 : 1; /**< evts3 output control enable */ + unsigned int reserved1 : 1; + unsigned int rg_oc_en_evta1 : 1; /**< evta1 output control enable */ + unsigned int rg_oc_en_evta2 : 1; /**< evta2 output control enable */ + unsigned int rg_oc_en_evtb1 : 1; /**< evtb1 output control enable */ + unsigned int rg_oc_en_evtb2 : 1; /**< evtb2 output control enable */ + unsigned int reserved2 : 4; + unsigned int rg_oc_mode_evt1 : 1; /**< evtio1 output mode select */ + unsigned int rg_oc_mode_evt2 : 1; /**< evtio2 output mode select */ + unsigned int rg_oc_mode_evt3 : 1; /**< evtio3 output mode select */ + unsigned int reserved3 : 1; + unsigned int rg_oc_mode_evts1 : 1; /**< evts1 output mode select */ + unsigned int rg_oc_mode_evts2 : 1; /**< evts2 output mode select */ + unsigned int rg_oc_mode_evts3 : 1; /**< evts3 output mode select */ + unsigned int reserved4 : 1; + unsigned int rg_oc_mode_evta1 : 1; /**< evta1 output mode select */ + unsigned int rg_oc_mode_evta2 : 1; /**< evta2 output mode select */ + unsigned int rg_oc_mode_evtb1 : 1; /**< evtb1 output mode select */ + unsigned int rg_oc_mode_evtb2 : 1; /**< evtb2 output mode select */ + unsigned int reserved5 : 4; + } BIT; +} volatile OC_MODE_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_oc_laten_evt1 : 1; /**< output control evtio1 latch event enable */ + unsigned int rg_oc_laten_evt2 : 1; /**< output control evtio2 latch event enable */ + unsigned int rg_oc_laten_evt3 : 1; /**< output control evtio3 latch event enable */ + unsigned int reserved0 : 1; + unsigned int rg_oc_laten_evts1 : 1; /**< output control evtis1 latch event enable */ + unsigned int rg_oc_laten_evts2 : 1; /**< output control evtis2 latch event enable */ + unsigned int rg_oc_laten_evts3 : 1; /**< output control evtis3 latch event enable */ + unsigned int reserved1 : 1; + unsigned int rg_oc_laten_evta1 : 1; /**< output control evtia1 latch event enable */ + unsigned int rg_oc_laten_evta2 : 1; /**< output control evtia2 latch event enable */ + unsigned int rg_oc_laten_evtb1 : 1; /**< output control evtib1 latch event enable */ + unsigned int rg_oc_laten_evtb2 : 1; /**< output control evtib2 latch event enable */ + unsigned int reserved2 : 20; + } BIT; +} volatile OC_LAT_EN_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_oca_evtio_inc : 3; /**< channel A output control action at evtio increase */ + unsigned int rg_oca_evta1_inc : 3; /**< channel A output control action at evta1 increase */ + unsigned int rg_oca_evta2_inc : 3; /**< channel A output control action at evta2 increase */ + unsigned int rg_oca_evtb1_inc : 3; /**< channel A output control action at evtb1 increase */ + unsigned int rg_oca_evtb2_inc : 3; /**< channel A output control action at evtb2 increase */ + unsigned int reserved0 : 1; + unsigned int rg_oca_evtio_dec : 3; /**< channel A output control action at evtio decrease */ + unsigned int rg_oca_evta1_dec : 3; /**< channel A output control action at evta1 decrease */ + unsigned int rg_oca_evta2_dec : 3; /**< channel A output control action at evta2 decrease */ + unsigned int rg_oca_evtb1_dec : 3; /**< channel A output control action at evtb1 decrease */ + unsigned int rg_oca_evtb2_dec : 3; /**< channel A output control action at evtb2 decrease */ + unsigned int reserved1 : 1; + } BIT; +} volatile OC_ACT_A_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_ocb_evtio_inc : 3; /**< channel B output control action at evtio increase */ + unsigned int rg_ocb_evta1_inc : 3; /**< channel B output control action at evta1 increase */ + unsigned int rg_ocb_evta2_inc : 3; /**< channel B output control action at evta2 increase */ + unsigned int rg_ocb_evtb1_inc : 3; /**< channel B output control action at evtb1 increase */ + unsigned int rg_ocb_evtb2_inc : 3; /**< channel B output control action at evtb2 increase */ + unsigned int reserved0 : 1; + unsigned int rg_ocb_evtio_dec : 3; /**< channel B output control action at evtio decrease */ + unsigned int rg_ocb_evta1_dec : 3; /**< channel B output control action at evta1 decrease */ + unsigned int rg_ocb_evta2_dec : 3; /**< channel B output control action at evta2 decrease */ + unsigned int rg_ocb_evtb1_dec : 3; /**< channel B output control action at evtb1 decrease */ + unsigned int rg_ocb_evtb2_dec : 3; /**< channel B output control action at evtb2 decrease */ + unsigned int reserved1 : 1; + } BIT; +} volatile OC_ACT_B_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int ro_oc_flag_evt1 : 1; /**< output control evtio1 flag */ + unsigned int ro_oc_flag_evt2 : 1; /**< output control evtio2 flag */ + unsigned int ro_oc_flag_evt3 : 1; /**< output control evtio3 flag */ + unsigned int reserved0 : 1; + unsigned int ro_oc_flag_evts1 : 1; /**< output control evts1 flag */ + unsigned int ro_oc_flag_evts2 : 1; /**< output control evts2 flag */ + unsigned int ro_oc_flag_evts3 : 1; /**< output control evts3 flag */ + unsigned int reserved1 : 1; + unsigned int ro_oc_flag_evta1 : 1; /**< output control evta1 flag */ + unsigned int ro_oc_flag_evta2 : 1; /**< output control evta2 flag */ + unsigned int ro_oc_flag_evtb1 : 1; /**< output control evtb1 flag */ + unsigned int ro_oc_flag_evtb2 : 1; /**< output control evtb2 flag */ + unsigned int reserved2 : 3; + unsigned int ro_int_flag_evt : 1; /**< output control event interrupt flag */ + unsigned int rg_oc_clr_evt1 : 1; /**< output control evtio1 clear bit */ + unsigned int rg_oc_clr_evt2 : 1; /**< output control evtio2 clear bit */ + unsigned int rg_oc_clr_evt3 : 1; /**< output control evtio3 clear bit */ + unsigned int reserved3 : 1; + unsigned int rg_oc_clr_evts1 : 1; /**< output control evts1 clear bit */ + unsigned int rg_oc_clr_evts2 : 1; /**< output control evts2 clear bit */ + unsigned int rg_oc_clr_evts3 : 1; /**< output control evts3 clear bit */ + unsigned int reserved4 : 1; + unsigned int rg_oc_clr_evta1 : 1; /**< output control evta1 clear bit */ + unsigned int rg_oc_clr_evta2 : 1; /**< output control evta2 clear bit */ + unsigned int rg_oc_clr_evtb1 : 1; /**< output control evtb1 clear bit */ + unsigned int rg_oc_clr_evtb2 : 1; /**< output control evtb2 clear bit */ + unsigned int reserved5 : 3; + unsigned int rg_int_clr_evt : 1; /**< output control event interrupt clear bit */ + } BIT; +} volatile OC_EVT_FLAG_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_oc_clr_zroen_evt1 : 1; /**< enable clear evtio1 at zero */ + unsigned int rg_oc_clr_zroen_evt2 : 1; /**< enable clear evtio2 at zero */ + unsigned int rg_oc_clr_zroen_evt3 : 1; /**< enable clear evtio3 at zero */ + unsigned int reserved0 : 1; + unsigned int rg_oc_clr_zroen_evts1 : 1; /**< enable clear evts1 at zero */ + unsigned int rg_oc_clr_zroen_evts2 : 1; /**< enable clear evts2 at zero */ + unsigned int rg_oc_clr_zroen_evts3 : 1; /**< enable clear evts3 at zero */ + unsigned int reserved1 : 1; + unsigned int rg_oc_clr_zroen_evta1 : 1; /**< enable clear evta1 at zero */ + unsigned int rg_oc_clr_zroen_evta2 : 1; /**< enable clear evta2 at zero */ + unsigned int rg_oc_clr_zroen_evtb1 : 1; /**< enable clear evtb1 at zero */ + unsigned int rg_oc_clr_zroen_evtb2 : 1; /**< enable clear evtb2 at zero */ + unsigned int reserved2 : 4; + unsigned int rg_oc_clr_prden_evt1 : 1; /**< enable clear evtio1 at period */ + unsigned int rg_oc_clr_prden_evt2 : 1; /**< enable clear evtio2 at period */ + unsigned int rg_oc_clr_prden_evt3 : 1; /**< enable clear evtio3 at period */ + unsigned int reserved3 : 1; + unsigned int rg_oc_clr_prden_evts1 : 1; /**< enable clear evts1 at period */ + unsigned int rg_oc_clr_prden_evts2 : 1; /**< enable clear evts2 at period */ + unsigned int rg_oc_clr_prden_evts3 : 1; /**< enable clear evts3 at period */ + unsigned int reserved4 : 1; + unsigned int rg_oc_clr_prden_evta1 : 1; /**< enable clear evta1 at period */ + unsigned int rg_oc_clr_prden_evta2 : 1; /**< enable clear evta2 at period */ + unsigned int rg_oc_clr_prden_evtb1 : 1; /**< enable clear evtb1 at period */ + unsigned int rg_oc_clr_prden_evtb2 : 1; /**< enable clear evtb2 at period */ + unsigned int reserved5 : 4; + } BIT; +} volatile OC_PRD_CLR_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_oc_frc_evt1 : 1; /**< force enable evtio1 event */ + unsigned int rg_oc_frc_evt2 : 1; /**< force enable evtio2 event */ + unsigned int rg_oc_frc_evt3 : 1; /**< force enable evtio3 event */ + unsigned int reserved0 : 1; + unsigned int rg_oc_frc_evts1 : 1; /**< force enable evts1 event */ + unsigned int rg_oc_frc_evts2 : 1; /**< force enable evts2 event */ + unsigned int rg_oc_frc_evts3 : 1; /**< force enable evts3 event */ + unsigned int reserved1 : 1; + unsigned int rg_oc_frc_evta1 : 1; /**< force enable evta1 event */ + unsigned int rg_oc_frc_evta2 : 1; /**< force enable evta2 event */ + unsigned int rg_oc_frc_evtb1 : 1; /**< force enable evtb1 event */ + unsigned int rg_oc_frc_evtb2 : 1; /**< force enable evtb2 event */ + unsigned int reserved2 : 20; + } BIT; +} volatile OC_FRC_EVT_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_int_en_evt1 : 1; /**< enable evtio1 intterrupt */ + unsigned int rg_int_en_evt2 : 1; /**< enable evtio2 intterrupt */ + unsigned int rg_int_en_evt3 : 1; /**< enable evtio3 intterrupt */ + unsigned int reserved0 : 1; + unsigned int rg_int_en_evts1 : 1; /**< enable evts1 intterrupt */ + unsigned int rg_int_en_evts2 : 1; /**< enable evts2 intterrupt */ + unsigned int rg_int_en_evts3 : 1; /**< enable evts3 intterrupt */ + unsigned int reserved1 : 1; + unsigned int rg_int_en_evta1 : 1; /**< enable evta1 intterrupt */ + unsigned int rg_int_en_evta2 : 1; /**< enable evta2 intterrupt */ + unsigned int rg_int_en_evtb1 : 1; /**< enable evtb1 intterrupt */ + unsigned int rg_int_en_evtb2 : 1; /**< enable evtb2 intterrupt */ + unsigned int reserved2 : 20; + } BIT; +} volatile INT_EVT_EN_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_int_en_tmr : 1; /**< enable timer interrupt */ + unsigned int reserved0 : 31; + } BIT; +} volatile INT_TMR_EN_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int ro_int_flag_tmr : 1; /**< timer interrupt clear bit */ + unsigned int reserved0 : 15; + unsigned int rg_int_clr_tmr : 1; /**< timer interrupt flag */ + unsigned int reserved1 : 15; + } BIT; +} volatile INT_TMR_FLAG_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_int_tmr_sel : 4; /**< timer interrupt source select */ + unsigned int reserved0 : 28; + } BIT; +} volatile INT_TMR_SEL_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_int_prsc_prd : 4; /**< timer interrupt scale ratio */ + unsigned int reserved0 : 4; + unsigned int ro_int_prsc_cnt : 4; /**< timer interrupt scale ratio value read register */ + unsigned int reserved1 : 4; + unsigned int rg_int_prsc_phs : 4; /**< timer interrupt scale ratio phase value */ + unsigned int reserved2 : 4; + unsigned int rg_int_prsc_synen : 1; /**< timer interrupt scale ratio phase value */ + unsigned int rg_int_prsc_frc : 1; + unsigned int reserved3 : 6; + } BIT; +} volatile INT_PRSC_CFG_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_csa_tmr_sel : 4; /**< timer condition to trigger adc sample through SOCA */ + unsigned int reserved0 : 12; + unsigned int rg_csa_en_cs : 1; /**< timer trigger adc sample through SOCA enable */ + unsigned int reserved1 : 15; + } BIT; +} volatile CS_TMR_SELA_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_csb_tmr_sel : 4; /**< timer condition to trigger adc sample through SOCB */ + unsigned int reserved0 : 12; + unsigned int rg_csb_en_cs : 1; /**< timer trigger adc sample through SOCB enable */ + unsigned int reserved1 : 15; + } BIT; +} volatile CS_TMR_SELB_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_csa_prsc_prd : 4; /**< trigger adc scale ratio through SOCB */ + unsigned int reserved0 : 12; + unsigned int rg_csa_prsc_phs : 4; /**< trigger adc scale ratio phase value through SOCB */ + unsigned int reserved1 : 4; + unsigned int rg_csa_prsc_synen : 1; /**< trigger adc scale ratio phase value sync enable through SOCB */ + unsigned int rg_csa_prsc_frc : 1; /**< trigger adc scale ratio phase value force enable through SOCB */ + unsigned int reserved2 : 6; + } BIT; +} volatile CS_PRSCA_CFG_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_csb_prsc_prd : 4; /**< trigger adc scale ratio through SOCB */ + unsigned int reserved0 : 12; + unsigned int rg_csb_prsc_phs : 4; /**< trigger adc scale ratio phase value through SOCB */ + unsigned int reserved1 : 4; + unsigned int rg_csb_prsc_synen : 1; /**< trigger adc scale ratio phase value sync enable through SOCB */ + unsigned int rg_csb_prsc_frc : 1; /**< trigger adc scale ratio phase value force enable through SOCB */ + unsigned int reserved2 : 6; + } BIT; +} volatile CS_PRSCB_CFG_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int ro_csa_flag : 1; /**< SOCA adc start sample flag */ + unsigned int ro_csb_flag : 1; /**< SOCB adc start sample flag */ + unsigned int reserved0 : 14; + unsigned int rg_csa_clr_flag : 1; /**< SOCA adc start sample flag clear bit */ + unsigned int rg_csb_clr_flag : 1; /**< SOCB adc start sample flag clear bit */ + unsigned int reserved1 : 14; + } BIT; +} volatile CS_FLAG_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_dma_breq_sel : 2; /**< DMA Burst request source select */ + unsigned int rg_dma_sreq_sel : 2; /**< DMA single request source select */ + unsigned int reserved0 : 28; + } BIT; +} volatile CS_DMA_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_evtio1_psel : 2; /**< evtio1's polarity */ + unsigned int rg_evtio2_psel : 2; /**< evtio2's polarity */ + unsigned int rg_evtio3_psel : 2; /**< evtio3's polarity */ + unsigned int rg_evtio4_psel : 2; /**< evtio4's polarity */ + unsigned int rg_evtio5_psel : 2; /**< evtio5's polarity */ + unsigned int reserved0 : 6; + unsigned int rg_evtsys1_psel : 2; /**< evts1's polarity */ + unsigned int rg_evtsys2_psel : 2; /**< evts2's polarity */ + unsigned int rg_evtsys3_psel : 2; /**< evts3's polarity */ + unsigned int reserved1 : 10; + } BIT; +} volatile EM_EVTIO_PSEL_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_evtmp1_psel : 2; /**< evtmp1's polarity */ + unsigned int rg_evtmp2_psel : 2; /**< evtmp2's polarity */ + unsigned int rg_evtmp3_psel : 2; /**< evtmp3's polarity */ + unsigned int rg_evtmp4_psel : 2; /**< evtmp4's polarity */ + unsigned int rg_evtmp5_psel : 2; /**< evtmp5's polarity */ + unsigned int rg_evtmp6_psel : 2; /**< evtmp6's polarity */ + unsigned int reserved0 : 20; + } BIT; +} volatile EM_EVTMP_PSEL_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_em_a1_oren : 9; /**< group A event 1 logic OR source enable */ + unsigned int reserved0 : 7; + unsigned int rg_em_a2_oren : 9; /**< group A event 2 logic OR source enable */ + unsigned int reserved1 : 7; + } BIT; +} volatile EM_AOR_EN_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_em_b1_oren : 9; /**< group B event 1 logic OR source enable */ + unsigned int reserved0 : 7; + unsigned int rg_em_b2_oren : 9; /**< group B event 2 logic OR source enable */ + unsigned int reserved1 : 7; + } BIT; +} volatile EM_BOR_EN_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_em_a1_sel : 4; /**< group A event 1 source select */ + unsigned int rg_em_a2_sel : 4; /**< group A event 2 source select */ + unsigned int rg_em_b1_sel : 4; /**< group B event 1 source select */ + unsigned int rg_em_b2_sel : 4; /**< group B event 2 source select */ + unsigned int rg_evta1t_sel : 3; /**< evta1t source select */ + unsigned int reserved0 : 1; + unsigned int rg_evta2t_sel : 3; /**< evta2t source select */ + unsigned int reserved1 : 1; + unsigned int rg_evtb1t_sel : 3; /**< evtb1t source select */ + unsigned int reserved2 : 1; + unsigned int rg_evtb2t_sel : 3; /**< evtb2t source select */ + unsigned int reserved3 : 1; + } BIT; +} volatile EM_MRG_SEL_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_evta1_sel : 1; /**< em_evta1 event source select */ + unsigned int rg_evta2_sel : 1; /**< em_evta2 event source select */ + unsigned int rg_evtb1_sel : 1; /**< em_evtb1 event source select */ + unsigned int rg_evtb2_sel : 1; /**< em_evtb2 event source select */ + unsigned int rg_evtfilt_sel : 2; /**< em_evfilt event source select */ + unsigned int reserved0 : 26; + } BIT; +} volatile EM_OUT_SEL_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_syni_sel : 4; /**< em_evt_syni source select */ + unsigned int reserved0 : 12; + unsigned int ro_syni_flag : 1; /**< em_evt_syni event active flag */ + unsigned int reserved1 : 3; + unsigned int rg_syni_clr : 1; /**< em_evt_syni event active flag clear bit */ + unsigned int reserved2 : 11; + } BIT; +} volatile SYNI_CFG_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_syncnt_a1en : 1; /**< TC value sync at em_evta1_pulse */ + unsigned int rg_syncnt_b1en : 1; /**< TC value sync at em_evtb1_pulse */ + unsigned int rg_syncnt_synien : 1; /**< TC value sync at em_synci_pulse */ + unsigned int reserved0 : 29; + } BIT; +} volatile SYNCNT_CFG_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_syno_zroen : 1; /**< sync out at zero enable */ + unsigned int rg_syno_prden : 1; /**< sync out at period enable */ + unsigned int rg_syno_a1en : 1; /**< sync out at a1 enable */ + unsigned int rg_syno_b1en : 1; /**< sync out at b1 enable */ + unsigned int reserved0 : 1; + unsigned int rg_syno_refben : 1; /**< sync out at reference B match enable */ + unsigned int rg_syno_refcen : 1; /**< sync out at reference C match enable */ + unsigned int rg_syno_refden : 1; /**< sync out at reference D match enable */ + unsigned int rg_mode_syno : 1; /**< sync out mode select */ + unsigned int rg_latset_sel : 1; /**< latch condition */ + unsigned int rg_latset_otsyn : 1; /**< control a sync out latch bit enable */ + unsigned int reserved1 : 21; + } BIT; +} volatile SYNO_CFG_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_gld_zroen : 1; /**< enable global load when count zero */ + unsigned int rg_gld_prden : 1; /**< enable global load when count period */ + unsigned int rg_gld_cntsynen : 1; /**< enable global load when em_cnt_syn enable */ + unsigned int reserved0 : 5; + unsigned int rg_gld_prsc_prd : 4; /**< global load scale ratio */ + unsigned int rg_mode_gld : 1; /**< buffer global load mode select */ + unsigned int reserved1 : 3; + unsigned int rg_latset_otgld : 1; /**< control a global latch bit enable */ + unsigned int reserved2 : 15; + } BIT; +} volatile GLB_LOAD_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int tc_prd_ld_sts : 1; /**< count period buffer status */ + unsigned int tc_refa_ld_sts : 1; /**< reference A buffer status */ + unsigned int tc_refb_ld_sts : 1; /**< reference B buffer status */ + unsigned int tc_refc_ld_sts : 1; /**< reference C buffer status */ + unsigned int tc_refd_ld_sts : 1; /**< reference D buffer status */ + unsigned int reserved0 : 3; + unsigned int pg_act_a_ld_sts : 1; /**< channel A action buffer status */ + unsigned int pg_act_b_ld_sts : 1; /**< channel B buffer status */ + unsigned int pg_out_frc_ld_sts : 1; /**< PG putput force buffer status */ + unsigned int reserved1 : 1; + unsigned int dg_red_ld_sts : 1; /**< DG rising edge buffer status */ + unsigned int dg_fed_ld_sts : 1; /**< DG falling edge buffer status */ + unsigned int dg_cfg_ld_sts : 1; /**< DG config buffer status */ + unsigned int reserved2 : 1; + unsigned int tc_mwdrefa_ld_sts : 1; + unsigned int tc_mwdrefb_ld_sts : 1; + unsigned int tc_mwd_act_ld_sts : 1; + unsigned int reserved3 : 13; + } BIT; +} volatile LOAD_STS_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_syncnt_frc : 1; /**< force an em_cnt_syn event */ + unsigned int reserved0 : 3; + unsigned int rg_syno_frc : 1; /**< force an apt_syno event */ + unsigned int reserved1 : 3; + unsigned int reserved2 : 4; + unsigned int rg_gld_frc : 1; /**< force an em_glb_ld event*/ + unsigned int reserved3 : 3; + unsigned int reserved4 : 4; + unsigned int rg_csa_syn_frc : 1; /**< force a SOCA trigger */ + unsigned int rg_csb_syn_frc : 1; /**< force a SOCB trigger */ + unsigned int reserved5 : 2; + unsigned int rg_int_syn_frc : 1; /**< force timer interrupt scale load sync init value */ + unsigned int reserved6 : 3; + unsigned int rg_synpg_frc : 1; /**< force create waveform buffer indepent load trigger event */ + unsigned int reserved7 : 3; + } BIT; +} volatile SYN_FRC_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int ro_pwma_oen_status : 1; /**< APT_PWMA_OEN output status. */ + unsigned int ro_pwma_status : 1; /**< APT_PWMA output status. */ + unsigned int reserved0 : 6; + unsigned int ro_pwmb_oen_status : 1; /**< APT_PWMB_OEN output status. */ + unsigned int ro_pwmb_status : 1; /**< APT_PWMB output status. */ + unsigned int reserved1 : 22; + } BIT; +} volatile PWM_STATUS_REG; + + +typedef union { + unsigned int reg; + struct { + unsigned int ro_poe0_flag : 1; /**< POE0 event flag. */ + unsigned int ro_poe1_flag : 1; /**< POE1 event flag. */ + unsigned int ro_poe2_flag : 1; /**< POE2 event flag. */ + unsigned int reserved0 : 29; + } BIT; +} volatile APT_POE_FLAG_REG; + + +typedef union { + unsigned int reg; + struct { + unsigned int rg_hrpwma_en : 1; /**< High-precision PWM output enable for channel A. */ + unsigned int reserved0 : 31; + } BIT; +} volatile HRPWMA_EN_REG; + + +typedef union { + unsigned int reg; + struct { + unsigned int rg_hrpwma_rstep : 4; /**< Channel A high precision PWM rising edge delay step register. */ + unsigned int reserved0 : 28; + } BIT; +} volatile HRPWMA_RSTEP_REG; + + +typedef union { + unsigned int reg; + struct { + unsigned int rg_hrpwma_fstep : 4; /**< Channel A high accuracy PWM falling edge delay step register. */ + unsigned int reserved0 : 28; + } BIT; +} volatile HRPWMA_FSTEP_REG; + + +typedef union { + unsigned int reg; + struct { + unsigned int rg_hrpwmb_en : 1; /**< High-precision PWM output enable for channel B. */ + unsigned int reserved0 : 31; + } BIT; +} volatile HRPWMB_EN_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_hrpwmb_rstep : 4; /**< Channel A high precision PWM rising edge delay step register. */ + unsigned int reserved0 : 28; + } BIT; +} volatile HRPWMB_RSTEP_REG; + + +typedef union { + unsigned int reg; + struct { + unsigned int rg_hrpwmb_fstep : 4; /**< Channel A high accuracy PWM falling edge delay step register. */ + unsigned int reserved0 : 28; + } BIT; +} volatile HRPWMB_FSTEP_REG; + +typedef union { + unsigned int reg; + struct { + unsigned int rg_hrpwma_rstep_buf_en : 1; /**< Buffer enable for the high precision PWM rising edge delay + register of channel A. */ + unsigned int rg_hrpwma_rstep_gld_en : 1; /**< Global loading enable for the high-precision PWM rising edge + delay register of channel A. */ + unsigned int reserved0 : 1; + unsigned int rg_hrpwma_fstep_buf_en : 1; /**< Buffer enable for channel A high precision PWM falling + edge delay register. */ + unsigned int rg_hrpwma_fstep_gld_en : 1; /**< Global loading enable for the high-precision PWM falling + edge delay register of channel A. */ + unsigned int reserved1 : 1; + unsigned int rg_hrpwmb_rstep_buf_en : 1; /**< Buffer enable for the high-precision PWM rising edge + delay register of channel B. */ + unsigned int rg_hrpwmb_rstep_gld_en : 1; /**< Global loading enable for the high-precision PWM rising edge + delay register of channel B. */ + unsigned int reserved2 : 1; + unsigned int rg_hrpwmb_fstep_buf_en : 1; /**< Buffer enable for the high precision PWM falling edge delay + register of channel B. */ + unsigned int rg_hrpwmb_fstep_gld_en : 1; /**< Global loading enable for the high-precision PWM falling edge + delay register of channel B. */ + unsigned int reserved3 : 18; + } BIT; +} volatile HRPWM_BUF_EN_REG; + + +typedef union { + unsigned int reg; + struct { + unsigned int rg_hrpwma_rstep_ld_zroen : 1; /**< Whether to enable independent loading of the HRPWMA_RSTEP + register when CNT_ZERO is valid. */ + unsigned int rg_hrpwma_rstep_ld_prden : 1; /**< Whether to enable independent loading of the HRPWMA_RSTEP + register when CNT_PRD is valid. */ + unsigned int rg_hrpwma_rstep_ld_a1en : 1; /**< Whether to enable independent loading of the HRPWMA_RSTEP + register when EMEVTA1 is valid. */ + unsigned int rg_hrpwma_rstep_ld_b1en : 1; /**< Whether to enable independent loading of the HRPWMA_RSTEP + register when EMEVTB1 is valid. */ + unsigned int rg_hrpwma_rstep_ld_synen : 1; /**< Independent loading enable for the HRPWMA_RSTEP register + when APTxSYNCI is valid. */ + unsigned int reserved0 : 3; /**< Reserved0. */ + + unsigned int rg_hrpwma_fstep_ld_zroen : 1; /**< Whether to enable independent loading of the HRPWMA_FSTEP + register when CNT_ZERO is valid. */ + unsigned int rg_hrpwma_fstep_ld_prden : 1; /**< Whether to enable independent loading of the HRPWMA_FSTEP + register when CNT_PRD is valid. */ + unsigned int rg_hrpwma_fstep_ld_a1en : 1; /**< Whether to enable independent loading of the HRPWMA_FSTEP + register when EMEVTA1 is valid. */ + unsigned int rg_hrpwma_fstep_ld_b1en : 1; /**< Whether to enable independent loading of the HRPWMA_FSTEP + register when EMEVTB1 is valid. */ + unsigned int rg_hrpwma_fstep_ld_synen : 1; /**< Whether to enable independent loading of the HRPWMA_FSTEP + register when APTxSYNCI is valid. */ + unsigned int reserved1 : 3; /**< Reserved1 */ + + unsigned int rg_hrpwmb_rstep_ld_zroen : 1; /**< Whether to enable independent loading of the HRPWMB_RSTEP + register when CNT_ZERO is valid. */ + unsigned int rg_hrpwmb_rstep_ld_prden : 1; /**< Whether to enable independent loading of the HRPWMB_RSTEP + register when CNT_PRD is valid. */ + unsigned int rg_hrpwmb_rstep_ld_a1en : 1; /**< Whether to enable independent loading of the HRPWMB_RSTEP + register when EMEVTA1 is valid. */ + unsigned int rg_hrpwmb_rstep_ld_b1en : 1; /**< Whether to enable independent loading of the HRPWMB_RSTEP + register when EMEVTB1 is valid. */ + unsigned int rg_hrpwmb_rstep_ld_synen : 1; /**< Independent loading enable for the HRPWMB_RSTEP register + when APTxSYNCI is valid. */ + unsigned int reserved2 : 3; /**< Reserved2 */ + + unsigned int rg_hrpwmb_fstep_ld_zroen : 1; /**< Whether to enable independent loading of the HRPWMB_FSTEP + register when CNT_ZERO is valid. */ + unsigned int rg_hrpwmb_fstep_ld_prden : 1; /**< Whether to enable independent loading of the HRPWMB_FSTEP + register when CNT_PRD is valid. */ + unsigned int rg_hrpwmb_fstep_ld_a1en : 1; /**< Whether to enable independent loading of the HRPWMB_FSTEP + register when EMEVTA1 is valid. */ + unsigned int rg_hrpwmb_fstep_ld_b1en : 1; /**< Whether to enable independent loading of the HRPWMB_FSTEP + register when EMEVTB1 is valid. */ + unsigned int rg_hrpwmb_fstep_ld_synen : 1; /**< Whether to enable independent loading of the HRPWMB_FSTEP + register when APTxSYNCI is valid. */ + unsigned int reserved3 : 3; /**< Reserved3 */ + } BIT; +} volatile HRPWM_LOAD_REG; + +/** + * @brief APT registers definition structure. + */ +typedef struct { + VER_INFO_REG VER_INFO; /**< VER_INFO_REG. Offset address 0x00000000U. */ + unsigned int reserved0[3]; + TC_MODE_REG TC_MODE; /**< TC_MODE_REG. Offset address 0x00000010U. */ + TC_PHS_REG TC_PHS; /**< TC_PHS_REG. Offset address 0x00000014U. */ + TC_OVRID_REG TC_OVRID; /**< TC_OVRID_REG. Offset address 0x00000018U. */ + unsigned int reserved1; + TC_PRD_REG TC_PRD; /**< TC_PRD_REG. Offset address 0x00000020U. */ + unsigned int reserved2[3]; + TC_REFA_REG TC_REFA; /**< TC_REFA_REG. Offset address 0x00000030U. */ + TC_REFB_REG TC_REFB; /**< TC_REFB_REG. Offset address 0x00000034U. */ + TC_REFC_REG TC_REFC; /**< TC_REFC_REG. Offset address 0x00000038U. */ + TC_REFD_REG TC_REFD; /**< TC_REFD_REG. Offset address 0x0000003CU. */ + unsigned int reserved3[4]; + TC_BUF_EN_REG TC_BUF_EN; /**< TC_BUF_EN_REG. Offset address 0x00000040U. */ + TC_PRD_LOAD_REG TC_PRD_LOAD; /**< TC_PRD_LOAD_REG. Offset address 0x00000050U. */ + TC_REF_LOAD_REG TC_REF_LOAD; /**< TC_REF_LOAD_REG. Offset address 0x00000054U. */ + TC_MWD_EN_REG TC_MWD_EN; /**< TC_MWD_EN_REG. Offset address 0x0000005CU. */ + TC_MWDREFA_REG TC_MWDREFA; /**< TC_MWDREFA_REG. Offset address 0x00000060U. */ + TC_MWDREFB_REG TC_MWDREFB; /**< TC_MWDREFB_REG. Offset address 0x00000064U. */ + TC_MWD_ACT_REG TC_MWD_ACT; /**< TC_MWD_ACT_REG. Offset address 0x00000068U. */ + TC_MWD_BUF_EN_REG TC_MWD_BUF_EN; /**< TC_MWD_BUF_EN_REG. Offset address 0x0000006cU. */ + TC_MWD_LOAD_REG TC_MWD_LOAD; /**< TC_MWD_LOAD_REG. Offset address 0x00000070U. */ + TC_STS_REG TC_STS; /**< TC_STS_REG. Offset address 0x00000060U. */ + unsigned int reserved4[34]; + PG_ACT_A_REG PG_ACT_A; /**< PG_ACT_A_REG. Offset address 0x00000100U. */ + PG_ACT_B_REG PG_ACT_B; /**< PG_ACT_B_REG. Offset address 0x00000104U. */ + unsigned int reserved5[2]; + PG_ACT_FRC_REG PG_ACT_FRC; /**< PG_ACT_FRC_REG. Offset address 0x00000110U. */ + PG_OUT_FRC_REG PG_OUT_FRC; /**< PG_OUT_FRC_REG. Offset address 0x00000114U. */ + unsigned int reserved6[2]; + PG_BUF_EN_REG PG_BUF_EN; /**< PG_BUF_EN_REG. Offset address 0x00000120U. */ + unsigned int reserved7[3]; + PG_ACT_LD_REG PG_ACT_LD; /**< PG_ACT_LD_REG. Offset address 0x00000130U. */ + unsigned int reserved8[3]; + PG_EVTC_SEL_REG PG_EVTC_SEL; /**< PG_EVTC_SEL_REG. Offset address 0x00000140U. */ + unsigned int reserved9[47]; + DG_RED_REG DG_RED; /**< DG_RED_REG. Offset address 0x00000200U. */ + DG_FED_REG DG_FED; /**< DG_FED_REG. Offset address 0x00000204U. */ + DG_CFG_REG DG_CFG; /**< DG_CFG_REG. Offset address 0x00000208U. */ + unsigned int reserved10; + DG_BUF_EN_REG DG_BUF_EN; /**< DG_BUF_EN_REG. Offset address 0x00000210U. */ + DG_BUF_LOAD_REG DG_BUF_LOAD; /**< DG_BUF_LOAD_REG. Offset address 0x00000214U. */ + unsigned int reserved11[58]; + OC_MODE_REG OC_MODE; /**< OC_MODE_REG. Offset address 0x00000300U. */ + OC_LAT_EN_REG OC_LAT_EN; /**< OC_LAT_EN_REG. Offset address 0x00000304U. */ + unsigned int reserved12[2]; + OC_ACT_A_REG OC_ACT_A; /**< OC_ACT_A_REG. Offset address 0x00000310U. */ + OC_ACT_B_REG OC_ACT_B; /**< OC_ACT_B_REG. Offset address 0x00000314U. */ + unsigned int reserved13[2]; + OC_EVT_FLAG_REG OC_EVT_FLAG; /**< OC_EVT_FLAG_REG. Offset address 0x00000320U. */ + OC_PRD_CLR_REG OC_PRD_CLR; /**< OC_PRD_CLR_REG. Offset address 0x00000324U. */ + unsigned int reserved14[2]; + OC_FRC_EVT_REG OC_FRC_EVT; /**< OC_FRC_EVT_REG. Offset address 0x00000330U. */ + unsigned int reserved15[55]; + INT_EVT_EN_REG INT_EVT_EN; /**< INT_EVT_EN_REG. Offset address 0x00000410U. */ + INT_TMR_EN_REG INT_TMR_EN; /**< INT_TMR_EN_REG. Offset address 0x00000414U. */ + unsigned int reserved16[2]; + INT_TMR_FLAG_REG INT_TMR_FLAG; /**< INT_TMR_FLAG_REG. Offset address 0x00000420U. */ + INT_TMR_SEL_REG INT_TMR_SEL; /**< INT_TMR_SEL_REG. Offset address 0x00000424U. */ + INT_PRSC_CFG_REG INT_PRSC_CFG; /**< INT_PRSC_CFG_REG. Offset address 0x00000428U. */ + unsigned int reserved17[53]; + CS_TMR_SELA_REG CS_TMR_SELA; /**< CS_TMR_SELA_REG. Offset address 0x00000500U. */ + CS_TMR_SELB_REG CS_TMR_SELB; /**< CS_TMR_SELB_REG. Offset address 0x00000504U. */ + CS_PRSCA_CFG_REG CS_PRSCA_CFG; /**< CS_PRSCA_CFG_REG. Offset address 0x00000508U. */ + CS_PRSCB_CFG_REG CS_PRSCB_CFG; /**< CS_PRSCB_CFG_REG. Offset address 0x0000050CU. */ + CS_FLAG_REG CS_FLAG; /**< CS_FLAG_REG. Offset address 0x00000510U. */ + unsigned int reserved18[3]; + CS_DMA_REG CS_DMA; /**< CS_DMA_REG. Offset address 0x00000520U. */ + unsigned int reserved19[55]; + EM_EVTIO_PSEL_REG EM_EVTIO_PSEL; /**< EM_EVTIO_PSEL_REG. Offset address 0x00000600U. */ + EM_EVTMP_PSEL_REG EM_EVTMP_PSEL; /**< EM_EVTMP_PSEL_REG. Offset address 0x00000604U. */ + EM_AOR_EN_REG EM_AOR_EN; /**< EM_AOR_EN_REG. Offset address 0x00000608U. */ + EM_BOR_EN_REG EM_BOR_EN; /**< EM_BOR_EN_REG. Offset address 0x0000060CU. */ + EM_MRG_SEL_REG EM_MRG_SEL; /**< EM_MRG_SEL_REG. Offset address 0x00000610U. */ + EM_OUT_SEL_REG EM_OUT_SEL; /**< EM_OUT_SEL_REG. Offset address 0x00000614U. */ + unsigned int reserved20[58]; + SYNI_CFG_REG SYNI_CFG; /**< SYNI_CFG_REG. Offset address 0x00000700U. */ + SYNCNT_CFG_REG SYNCNT_CFG; /**< SYNCNT_CFG_REG. Offset address 0x00000704U. */ + SYNO_CFG_REG SYNO_CFG; /**< SYNO_CFG_REG. Offset address 0x00000708U. */ + unsigned int reserved21; + GLB_LOAD_REG GLB_LOAD; /**< GLB_LOAD_REG. Offset address 0x000000710U. */ + unsigned int reserved22[3]; + LOAD_STS_REG LOAD_STS; /**< LOAD_STS_REG. Offset address 0x000000720U. */ + unsigned int reserved23[3]; + SYN_FRC_REG SYN_FRC; /**< SYN_FRC_REG. Offset address 0x00000730U. */ + unsigned int reserved24[51]; + PWM_STATUS_REG PWM_STATUS; /**< PWM_STATUS_REG. Offset address 0x00000800U. */ + APT_POE_FLAG_REG APT_POE_FLAG; /**< APT_POE_FLAG_REG. Offset address 0x00000804U. */ + unsigned int reserved25[62]; + HRPWMA_EN_REG HRPWMA_EN; /**< HRPWMA_EN_REG. Offset address 0x00000900U. */ + HRPWMA_RSTEP_REG HRPWMA_RSTEP; /**< HRPWMA_RSTEP_REG. Offset address 0x00000904U. */ + HRPWMA_FSTEP_REG HRPWMA_FSTEP; /**< HRPWMA_FSTEP_REG. Offset address 0x00000908U. */ + HRPWMB_EN_REG HRPWMB_EN; /**< HRPWMB_EN_REG. Offset address 0x0000090CU. */ + HRPWMB_RSTEP_REG HRPWMB_RSTEP; /**< HRPWMB_RSTEP_REG. Offset address 0x00000910U. */ + HRPWMB_FSTEP_REG HRPWMB_FSTEP; /**< HRPWMB_FSTEP_REG. Offset address 0x00000914U. */ + unsigned int reserved26[2]; + HRPWM_BUF_EN_REG HRPWM_BUF_EN; /**< HRPWM_BUF_EN_REG. Offset address 0x00000920U. */ + HRPWM_LOAD_REG HRPWM_LOAD; /**< HRPWM_LOAD_REG. Offset address 0x00000924U. */ +} volatile APT_RegStruct; + +/** + * @brief Set the emulation stop mode of APT module. + * @param aptx APT register base address. + * @param emuMode Emulation stop mode. + * @retval None. + */ +static inline void DCL_APT_SetEmulationMode(APT_RegStruct *aptx, APT_EmulationMode emuMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(emuMode <= APT_EMULATION_STOP_APT); + aptx->TC_MODE.BIT.rg_emu_stop = emuMode; +} + +/** + * @brief Set the time-base divider factor. + * @param aptx APT register base address. + * @param divFactor Time-base divider factor. + * @retval None. + */ +static inline void DCL_APT_SetDividerFactor(APT_RegStruct *aptx, unsigned short divFactor) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(divFactor <= DIVIDER_FACTOR_MAX); + aptx->TC_MODE.BIT.rg_div_fac = divFactor; +} + +/** + * @brief Get the time-base divider factor. + * @param aptx APT register base address. + * @retval unsigned short: time-base divider factor. + */ +static inline unsigned short DCL_APT_GetDividerFactor(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return (aptx->TC_MODE.BIT.rg_div_fac); +} + +/** + * @brief Set the count mode of time-base counter. + * @param aptx APT register base address. + * @param cntMode Count mode. + * @retval None. + */ +static inline void DCL_APT_SetTimeBaseCountMode(APT_RegStruct *aptx, APT_CountMode cntMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(cntMode <= APT_COUNT_MODE_FREEZE); + aptx->TC_MODE.BIT.rg_cnt_mode = cntMode; +} + +/** + * @brief Set the period of time-base counter. + * @param aptx APT register base address. + * @param periodCnt Time-base counter period. + * @retval None. + */ +static inline void DCL_APT_SetTimeBasePeriod(APT_RegStruct *aptx, unsigned short periodCnt) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->TC_PRD.BIT.rg_cnt_prd = periodCnt; +} + +/** + * @brief Get the period of time-base counter. + * @param aptx APT register base address. + * @retval unsigned short: time-base counter period + */ +static inline unsigned short DCL_APT_GetTimeBasePeriod(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return (aptx->TC_PRD.BIT.rg_cnt_prd); +} + +/** + * @brief Set the count mode of slave APT module after synchronization. + * @param aptx APT register base address. + * @param syncCntMode Count mode after synchronization. + * @retval None. + */ +static inline void DCL_APT_SetCountModeAfterSync(APT_RegStruct *aptx, APT_SyncCountMode syncCntMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(syncCntMode >= APT_COUNT_MODE_AFTER_SYNC_DOWN); + APT_PARAM_CHECK_NO_RET(syncCntMode <= APT_COUNT_MODE_AFTER_SYNC_UP); + aptx->TC_PHS.BIT.rg_cnt_dir = syncCntMode; +} + +/** + * @brief Set the counter phase after synchronization. + * @param aptx APT register base address. + * @param cntPhase Counter phase after synchronization. + * @retval None. + */ +static inline void DCL_APT_SetCounterPhase(APT_RegStruct *aptx, unsigned short cntPhase) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + TC_PHS_REG tmp = aptx->TC_PHS; + tmp.BIT.rg_cnt_phs = cntPhase; + aptx->TC_PHS = tmp; +} + +/** + * @brief Set the software override value of time-base counter. + * @param aptx APT register base address. + * @param cntOvrid Software override value of time-base counter. + * @retval None. + */ +static inline void DCL_APT_SetCounterOverride(APT_RegStruct *aptx, unsigned short cntOvrid) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + TC_OVRID_REG tmp = aptx->TC_OVRID; + tmp.BIT.rg_cnt_ovrid = cntOvrid; + aptx->TC_OVRID = tmp; +} + +/** + * @brief Force software override on time-base divider and counter. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_ForceOverride(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->TC_OVRID.BIT.rg_cnt_ovrid_en = BASE_CFG_SET; +} + +/** + * @brief Set the count compare reference value of time-base counter. + * @param aptx APT register base address. + * @param ref Count compare reference. + * @param cntCmp Count compare reference value of counter. + * @retval None. + */ +static inline void DCL_APT_SetCounterCompare(APT_RegStruct *aptx, APT_CompareRef ref, unsigned short cntCmp) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ref >= APT_COMPARE_REFERENCE_A); + APT_PARAM_CHECK_NO_RET(ref <= APT_COMPARE_REFERENCE_D); + TC_REFA_REG tmpA; + TC_REFB_REG tmpB; + TC_REFC_REG tmpC; + TC_REFD_REG tmpD; + switch (ref) { + case APT_COMPARE_REFERENCE_A: + tmpA = aptx->TC_REFA; + tmpA.BIT.rg_cnt_refa = cntCmp; + aptx->TC_REFA = tmpA; + break; + case APT_COMPARE_REFERENCE_B: + tmpB = aptx->TC_REFB; + tmpB.BIT.rg_cnt_refb = cntCmp; + aptx->TC_REFB = tmpB; + break; + case APT_COMPARE_REFERENCE_C: + tmpC = aptx->TC_REFC; + tmpC.BIT.rg_cnt_refc = cntCmp; + aptx->TC_REFC = tmpC; + break; + case APT_COMPARE_REFERENCE_D: + tmpD = aptx->TC_REFD; + tmpD.BIT.rg_cnt_refd = cntCmp; + aptx->TC_REFD = tmpD; + break; + default: + break; + } +} + +/** + * @brief Get the count compare reference value of time-base counter. + * @param aptx APT register base address. + * @param ref Count compare reference. + * @retval unsigned short: Count compare reference value of counter. + */ +static inline unsigned short DCL_APT_GetCounterCompare(APT_RegStruct *aptx, APT_CompareRef ref) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_WITH_RET(ref >= APT_COMPARE_REFERENCE_A, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(ref <= APT_COMPARE_REFERENCE_D, BASE_STATUS_ERROR); + switch (ref) { + case APT_COMPARE_REFERENCE_A: + return (aptx->TC_REFA.BIT.rg_cnt_refa); + case APT_COMPARE_REFERENCE_B: + return (aptx->TC_REFB.BIT.rg_cnt_refb); + case APT_COMPARE_REFERENCE_C: + return (aptx->TC_REFC.BIT.rg_cnt_refc); + case APT_COMPARE_REFERENCE_D: + return (aptx->TC_REFD.BIT.rg_cnt_refd); + default: + return 0; + } +} + +/** + * @brief Set the buffer load mode of time-base period register. + * @param aptx APT register base address. + * @param prdLoadMode Buffer load mode of time-base period register. + * @retval None. + */ +static inline void DCL_APT_SetPeriodLoadMode(APT_RegStruct *aptx, APT_BufferLoadMode prdLoadMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(prdLoadMode >= APT_BUFFER_DISABLE); + APT_PARAM_CHECK_NO_RET(prdLoadMode <= APT_BUFFER_GLOBAL_LOAD); + aptx->TC_BUF_EN.reg &= (~0b11); /* Clear rg_prd_buf_en and rg_prd_gld_en */ + aptx->TC_BUF_EN.reg |= prdLoadMode; /* Write rg_prd_buf_en and rg_prd_gld_en */ +} + +/** + * @brief Enable the buffer load events of TC_PRD register + * @param aptx APT register base address. + * @param loadEvent The buffer load events of TC_PRD register + * A logical OR of valid values that can be passed as the loadEvent parameter + * Valid values for loadEvent are: + * APT_PERIOD_LOAD_EVENT_ZERO - When counter value equal to zeor + * APT_PERIOD_LOAD_EVENT_A1 - When combined event A1 is valid + * APT_PERIOD_LOAD_EVENT_B1 - When combined event B1 is valid + * APT_PERIOD_LOAD_EVENT_SYNC - When synchronization event is valid + * @retval None. + */ +static inline void DCL_APT_SetPeriodLoadEvent(APT_RegStruct *aptx, unsigned int prdLoadEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->TC_PRD_LOAD.reg = prdLoadEvent; +} + +/** + * @brief Set the buffer load mode of count compare reference register. + * @param aptx APT register base address. + * @param ref Count compare reference. + * @param cmpLoadMode Buffer load mode of count compare reference register. + * @retval None. + */ +static inline void DCL_APT_SetCompareLoadMode(APT_RegStruct *aptx, + APT_CompareRef ref, + APT_BufferLoadMode cmpLoadMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ref >= APT_COMPARE_REFERENCE_A); + APT_PARAM_CHECK_NO_RET(ref <= APT_COMPARE_REFERENCE_D); + APT_PARAM_CHECK_NO_RET(cmpLoadMode >= APT_BUFFER_DISABLE); + APT_PARAM_CHECK_NO_RET(cmpLoadMode <= APT_BUFFER_GLOBAL_LOAD); + unsigned int offsetA = 4; /* Buffer mode control bits offset of reference A */ + unsigned int tcBufField = 2; /* Field width of buffer load mode setting */ + unsigned int offset = offsetA + ref * tcBufField; + aptx->TC_BUF_EN.reg &= (~(0b11 << offset)); /* Clear rg_refx_gld_en and rg_refx_buf_en */ + aptx->TC_BUF_EN.reg |= (cmpLoadMode << offset); /* Write rg_refx_gld_en and rg_refx_buf_en */ +} + +/** + * @brief Enable the buffer load events of TC_REFA, TC_REFB, TC_REFC, TC_REFD register + * @param aptx APT register base address. + * @param ref Count compare reference + * @param loadEvent The buffer load events of TC_REFA, TC_REFB, TC_REFC, TC_REFD register + * A logical OR of valid values can be passed as the loadEvent parameter + * Valid values for loadEvent are: + * APT_COMPARE_LOAD_EVENT_ZERO - When counter value equal to zero + * APT_COMPARE_LOAD_EVENT_PERIOD - When counter value equal to period + * APT_COMPARE_LOAD_EVENT_A1 - When combined event A1 is valid + * APT_COMPARE_LOAD_EVENT_B1 - When combined event B1 is valid + * APT_COMPARE_LOAD_EVENT_SYNC - When synchronization event is valid + * @retval None. + */ +static inline void DCL_APT_SetCompareLoadEvent(APT_RegStruct *aptx, APT_CompareRef ref, unsigned int cmpLoadEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ref >= APT_COMPARE_REFERENCE_A); + APT_PARAM_CHECK_NO_RET(ref <= APT_COMPARE_REFERENCE_D); + unsigned int refBufField = 8; /* Field width of compare reference load event setting */ + aptx->TC_REF_LOAD.reg &= (~(0x1F << (ref * refBufField))); /* Clear bit field for load event selection */ + aptx->TC_REF_LOAD.reg |= (cmpLoadEvent << (ref * refBufField)); +} + +/** + * @brief Get the value of time-base divider. + * @param aptx APT register base address. + * @retval unsigned short: The value of time-base divider value. + */ +static inline unsigned short DCL_APT_GetDividerValue(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return (aptx->TC_STS.BIT.ro_div_cnt); +} + +/** + * @brief Get the value of time-base counter. + * @param aptx APT register base address. + * @retval unsigned short: The value of time-base counter. + */ +static inline unsigned short DCL_APT_GetCounterValue(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return (aptx->TC_STS.BIT.ro_cnt_val); +} + +/** + * @brief Return time base counter direction + * @param aptx APT register base address. + * @retval unsigned short: The direction of time base counter + * Valid return values are: + * APT_COUNTER_STATUS_COUNT_DOWN - The counter is counting down + * APT_COUNTER_STATUS_COUNT_UP - The counter is counting up + */ +static inline unsigned short DCL_APT_GetCounterDirection(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return (aptx->TC_STS.BIT.ro_cnt_dir); +} + +/* --------------------------------------------------------------------------------------------- */ +/* PWM Generation (PG) submodule Direct Configuration Layer functions -------------------------- */ +/* --------------------------------------------------------------------------------------------- */ +/** + * @brief Set PWM waveform action on corresponding event. + * @param aptx APT register base address. + * @param channel PWM output channel. + * @param actEvent PWM waveform action event. + * @param action PWM waveform action. + * @retval None. + */ +static inline void DCL_APT_SetPWMAction(APT_RegStruct *aptx, + APT_PWMChannel channel, + APT_PWMActionEvent actEvent, + APT_PWMAction action) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(channel >= APT_PWM_CHANNEL_A); + APT_PARAM_CHECK_NO_RET(channel <= APT_PWM_CHANNEL_B); + APT_PARAM_CHECK_NO_RET(actEvent >= APT_PWM_ACTION_ON_TIMEBASE_ZERO); + APT_PARAM_CHECK_NO_RET(actEvent <= APT_PWM_ACTION_ON_C2_COUNT_DOWN); + APT_PARAM_CHECK_NO_RET(action <= APT_PWM_ACTION_TOGGLE); + if (channel == APT_PWM_CHANNEL_A) { + aptx->PG_ACT_A.reg &= (~(0b11 << actEvent)); + aptx->PG_ACT_A.reg |= (action << actEvent); + } else if (channel == APT_PWM_CHANNEL_B) { + aptx->PG_ACT_B.reg &= (~(0b11 << actEvent)); + aptx->PG_ACT_B.reg |= (action << actEvent); + } +} + +/** + * @brief Select the event source of PWM Generation event C1 or C2. + * This function is only used when C1 or C2 event is selected as PWM action event. + * @param aptx APT register base address. + * @param channel PWM output channel. + * @param eventCx The PWM Generation event, should be C1 or C2. + * @param eventCxSrc The trigger source of PWM Generation event C1 or C2. + * @retval None. + */ +static inline void DCL_APT_SelectCxEventSource(APT_RegStruct *aptx, + APT_PWMChannel channel, + APT_PGEventCx eventCx, + APT_PGEventCxSrc eventCxSrc) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET((channel >= APT_PWM_CHANNEL_A) && (channel <= APT_PWM_CHANNEL_B)); + APT_PARAM_CHECK_NO_RET(eventCx >= APT_PWM_GENERATION_EVENT_C1); + APT_PARAM_CHECK_NO_RET(eventCx <= APT_PWM_GENERATION_EVENT_C2); + APT_PARAM_CHECK_NO_RET(eventCxSrc >= APT_PG_EVT_C_FORBIDDEN); + APT_PARAM_CHECK_NO_RET(eventCxSrc <= APT_PG_EVT_C_SYNC_IN); + unsigned int chOffset = 8; /* Bit field offset of PWM output channel */ + unsigned int cxOffset = 4; /* Bit field offset of event Cx */ + aptx->PG_EVTC_SEL.reg &= (~(0b1111 << (channel * chOffset + eventCx * cxOffset))); + aptx->PG_EVTC_SEL.reg |= eventCxSrc << (channel * chOffset + eventCx * cxOffset); +} + +/** + * @brief Set the buffer load mode of PWM action register. + * @param aptx APT register base address. + * @param channel PWM output channel. + * @param loadMode Buffer load mode. + * @retval None. + */ +static inline void DCL_APT_SetPWMActionLoadMode(APT_RegStruct *aptx, + APT_PWMChannel channel, + APT_BufferLoadMode loadMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(channel >= APT_PWM_CHANNEL_A); + APT_PARAM_CHECK_NO_RET(channel <= APT_PWM_CHANNEL_B); + APT_PARAM_CHECK_NO_RET(loadMode >= APT_BUFFER_DISABLE); + APT_PARAM_CHECK_NO_RET(loadMode <= APT_BUFFER_GLOBAL_LOAD); + unsigned int bufFieldWidth = 2; /* Bit field width of buffer load mode setting */ + aptx->PG_BUF_EN.reg &= (~(0b11 << (channel * bufFieldWidth))); /* Clear rg_actx_gld_en and rg_actx_buf_en */ + aptx->PG_BUF_EN.reg |= (loadMode << (channel * bufFieldWidth)); /* Write rg_actx_gld_en and rg_actx_buf_en */ +} + +/** + * @brief Enable the buffer load events of PG_ACT_A or PG_ACT_B register + * @param aptx APT register base address. + * @param channel PWM output channel. + * @param loadEvent The buffer load events of PG_ACT_A or PG_ACT_B register + * A logical OR of valid values can be passed as the loadEvent parameter + * Valid values for loadEvent are: + * APT_ACTION_LOAD_EVENT_ZERO - When counter value equal to zero + * APT_ACTION_LOAD_EVENT_PERIOD - When counter value equal to period + * APT_ACTION_LOAD_EVENT_A1 - When combined event A1 is valid + * APT_ACTION_LOAD_EVENT_B1 - When combined event B1 is valid + * APT_ACTION_LOAD_EVENT_SYNC - When synchronization event is valid + * @retval None. + */ +static inline void DCL_APT_SetPWMActionLoadEvent(APT_RegStruct *aptx, + APT_PWMChannel channel, + unsigned int loadEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(channel >= APT_PWM_CHANNEL_A); + APT_PARAM_CHECK_NO_RET(channel <= APT_PWM_CHANNEL_B); + unsigned int actBufField = 8; /* Field width of PWM action load event setting */ + aptx->PG_ACT_LD.reg &= (~(0x1F << (channel * actBufField))); + aptx->PG_ACT_LD.reg |= (loadEvent << (channel * actBufField)); +} + +/** + * @brief Set the PWM waveform action on one-shot action software event. + * @param aptx APT register base address. + * @param channel PWM output channel. + * @param action PWM waveform action. + * @retval None. + */ +static inline void DCL_APT_SetSwOneShotPWMAction(APT_RegStruct *aptx, APT_PWMChannel channel, APT_PWMAction action) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(channel >= APT_PWM_CHANNEL_A); + APT_PARAM_CHECK_NO_RET(channel <= APT_PWM_CHANNEL_B); + APT_PARAM_CHECK_NO_RET(action >= APT_PWM_ACTION_HOLD); + APT_PARAM_CHECK_NO_RET(action <= APT_PWM_ACTION_TOGGLE); + if (channel == APT_PWM_CHANNEL_A) { + aptx->PG_ACT_FRC.BIT.rg_pga_act_evt_frc = action; + } else if (channel == APT_PWM_CHANNEL_B) { + aptx->PG_ACT_FRC.BIT.rg_pgb_act_evt_frc = action; + } +} + +/** + * @brief Force one-shot software event. + * @param aptx APT register base address. + * @param channel PWM output channel. + * @retval None. + */ +static inline void DCL_APT_ForceSwOneShotPWMAction(APT_RegStruct *aptx, APT_PWMChannel channel) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(channel >= APT_PWM_CHANNEL_A); + APT_PARAM_CHECK_NO_RET(channel <= APT_PWM_CHANNEL_B); + if (channel == APT_PWM_CHANNEL_A) { + aptx->PG_ACT_FRC.BIT.rg_pga_evt_frc = BASE_CFG_SET; + } else if (channel == APT_PWM_CHANNEL_B) { + aptx->PG_ACT_FRC.BIT.rg_pgb_evt_frc = BASE_CFG_SET; + } +} + +/** + * @brief Set the PWM waveform action on continuous action software event. + * @param aptx APT register base address. + * @param channel PWM output channel. + * @param action PWM waveform action + * @retval None. + */ +static inline void DCL_APT_SetSwContPWMAction(APT_RegStruct *aptx, APT_PWMChannel channel, APT_PWMContAction action) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(channel >= APT_PWM_CHANNEL_A); + APT_PARAM_CHECK_NO_RET(channel <= APT_PWM_CHANNEL_B); + APT_PARAM_CHECK_NO_RET(action >= APT_PWM_CONTINUOUS_ACTION_HOLD); + APT_PARAM_CHECK_NO_RET(action <= APT_PWM_CONTINUOUS_ACTION_HIGH); + if (channel == APT_PWM_CHANNEL_A) { + aptx->PG_OUT_FRC.BIT.rg_pga_frc_act = action; + } else if (channel == APT_PWM_CHANNEL_B) { + aptx->PG_OUT_FRC.BIT.rg_pgb_frc_act = action; + } +} + +static void APT_ForcePWMAOutputLow(APT_RegStruct *aptx) +{ + unsigned int risingOutSelect = aptx->DG_CFG.BIT.rg_dg_red_osel; + unsigned int fallingOutSelect = aptx->DG_CFG.BIT.rg_dg_fed_osel; + unsigned int risingInSelect = aptx->DG_CFG.BIT.rg_dg_red_isel; + unsigned int fallingInSelect = aptx->DG_CFG.BIT.rg_dg_fed_isel; + /* Enable force output. */ + aptx->PG_OUT_FRC.BIT.rg_pga_frc_en = BASE_CFG_ENABLE; + /* if PWMA invert */ + if (((risingOutSelect == APT_DB_RED_OUTPUT_INVERT) && (risingInSelect == APT_DB_RED_INPUT_PWM_A)) || \ + ((fallingOutSelect == APT_DB_FED_OUTPUT_INVERT) && (fallingInSelect == APT_DB_FED_INPUT_PWM_A))) { + aptx->PG_OUT_FRC.BIT.rg_pga_frc_act = APT_PWM_CONTINUOUS_ACTION_HIGH; /* if invert, set high */ + } else { /* if PWMA not invert */ + aptx->PG_OUT_FRC.BIT.rg_pga_frc_act = APT_PWM_CONTINUOUS_ACTION_LOW; /* if not invert, set low */ + } + return; +} + +static void APT_ForcePWMBOutputLow(APT_RegStruct *aptx) +{ + unsigned int risingOutSelect = aptx->DG_CFG.BIT.rg_dg_red_osel; + unsigned int fallingOutSelect = aptx->DG_CFG.BIT.rg_dg_fed_osel; + unsigned int risingInSelect = aptx->DG_CFG.BIT.rg_dg_red_isel; + unsigned int fallingInSelect = aptx->DG_CFG.BIT.rg_dg_fed_isel; + /* Enable force output */ + aptx->PG_OUT_FRC.BIT.rg_pgb_frc_en = BASE_CFG_ENABLE; + /* if PWMB invert */ + if (((risingOutSelect == APT_DB_RED_OUTPUT_INVERT) && (risingInSelect == APT_DB_RED_INPUT_PWM_B)) || \ + ((fallingOutSelect == APT_DB_FED_OUTPUT_INVERT) && (fallingInSelect == APT_DB_FED_INPUT_PWM_B))) { + aptx->PG_OUT_FRC.BIT.rg_pgb_frc_act = APT_PWM_CONTINUOUS_ACTION_HIGH; /* if invert, set high */ + } else { /* if PWMB not invert */ + aptx->PG_OUT_FRC.BIT.rg_pgb_frc_act = APT_PWM_CONTINUOUS_ACTION_LOW; /* if not invert, set low */ + } + return; +} + +/** + * @brief Both PWMA and PWMB output low level. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_ForcePWMOutputLow(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + + APT_ForcePWMAOutputLow(aptx); + APT_ForcePWMBOutputLow(aptx); + + return; +} + +/** + * @brief Set the buffer load mode of continuous aciton software event register. + * @param aptx APT register base address. + * @param loadMode Buffer load mode. + * @retval None. + */ +static inline void DCL_APT_SetSwContActionLoadMode(APT_RegStruct *aptx, APT_BufferLoadMode loadMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(loadMode >= APT_BUFFER_DISABLE); + APT_PARAM_CHECK_NO_RET(loadMode <= APT_BUFFER_GLOBAL_LOAD); + unsigned int bufFieldWidth = 4; /* Bit field width of buffer load mode setting */ + aptx->PG_BUF_EN.reg &= (~(0b11 << bufFieldWidth)); /* Clear rg_frc_gld_en and rg_frc_buf_en */ + aptx->PG_BUF_EN.reg |= (loadMode << bufFieldWidth); /* Write rg_frc_gld_en and rg_frc_buf_en */ +} + +/** + * @brief Enable the buffer load events of PG_OUT_FRC register + * @param aptx APT register base address. + * @param channel PWM output channel + * @param loadEvent The buffer load events of PG_OUT_FRC register + * A logical OR of valid values can be passed as the loadEvent parameter + * Valid values for loadEvent are: + * APT_ACTION_LOAD_EVENT_ZERO - When counter value equal to zero + * APT_ACTION_LOAD_EVENT_PERIOD - When counter value equal to period + * APT_ACTION_LOAD_EVENT_SYNC - When synchronization event is valid + * @retval None. + */ +static inline void DCL_APT_SetSwContActionLoadEvent(APT_RegStruct *aptx, unsigned int loadEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + unsigned int actBufField = 16; /* Field width of continuous PWM action load event setting */ + aptx->PG_ACT_LD.reg &= (~(0x1F << actBufField)); + aptx->PG_ACT_LD.reg |= (loadEvent << actBufField); +} + +/** + * @brief Enable continuous action software event. + * @param aptx APT register base address. + * @param channel PWM output channel. + * @retval None. + */ +static inline void DCL_APT_EnableSwContPWMAction(APT_RegStruct *aptx, APT_PWMChannel channel) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(channel >= APT_PWM_CHANNEL_A); + APT_PARAM_CHECK_NO_RET(channel <= APT_PWM_CHANNEL_B); + if (channel == APT_PWM_CHANNEL_A) { + aptx->PG_OUT_FRC.BIT.rg_pga_frc_en = BASE_CFG_SET; + } else if (channel == APT_PWM_CHANNEL_B) { + aptx->PG_OUT_FRC.BIT.rg_pgb_frc_en = BASE_CFG_SET; + } +} + +/** + * @brief Disable continuous action software event. + * @param aptx APT register base address. + * @param channel PWM output channel. + * @retval None. + */ +static inline void DCL_APT_DisableSwContPWMAction(APT_RegStruct *aptx, APT_PWMChannel channel) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(channel >= APT_PWM_CHANNEL_A); + APT_PARAM_CHECK_NO_RET(channel <= APT_PWM_CHANNEL_B); + if (channel == APT_PWM_CHANNEL_A) { + aptx->PG_OUT_FRC.BIT.rg_pga_frc_en = BASE_CFG_UNSET; + } else if (channel == APT_PWM_CHANNEL_B) { + aptx->PG_OUT_FRC.BIT.rg_pgb_frc_en = BASE_CFG_UNSET; + } +} + +/* --------------------------------------------------------------------------------------------- */ +/* Dead-Band Generation (DG) submodule Direct Configuration Layer functions -------------------- */ +/* --------------------------------------------------------------------------------------------- */ +/** + * @brief Configure the rising edge delay (RED) of Dead-Band Generation. + * @param aptx APT register base address. + * @param redInput The input source of RED counter. + * @param redOutMode The output of RED counter. + * @param dgaOutSwap The swap mode of Dead-Band Generation output signal A. + * true - Select the output of FED counter. + * false - Select the output of RED counter. + * @param redCount The count value of RED counter, in units of APT clock. + * @retval None. + */ +static inline void DCL_APT_SetDeadBandRisingEdge(APT_RegStruct *aptx, + APT_REDInput redInput, + APT_REDOutMode redOutMode, + bool dgaOutSwap, + unsigned short redCount) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(redInput >= APT_DB_RED_INPUT_PWM_A); + APT_PARAM_CHECK_NO_RET(redInput <= APT_DB_RED_INPUT_PWM_B); + APT_PARAM_CHECK_NO_RET(redOutMode >= APT_DB_RED_OUTPUT_NOT_INVERT); + APT_PARAM_CHECK_NO_RET(redOutMode <= APT_DB_RED_OUTPUT_PWM_A); + aptx->DG_CFG.BIT.rg_dg_red_isel = redInput; + aptx->DG_CFG.BIT.rg_dg_red_osel = redOutMode; + aptx->DG_CFG.BIT.rg_dga_osel = dgaOutSwap; + aptx->DG_RED.BIT.rg_dg_red = redCount; +} + +/** + * @brief Configure the falling edge delay (FED) of Dead-Band Generation. + * @param aptx APT register base address. + * @param fedInput The input source of FED counter. + * @param fedOutMode The output of FED counter. + * @param dgbOutSwap The swap mode of Dead-Band Generation output signal B. + * true - Select the output of RED counter. + * false - Select the output of FED counter. + * @param fedCount The count value of FED counter, in units of APT clock. + * @retval None. + */ +static inline void DCL_APT_SetDeadBandFallingEdge(APT_RegStruct *aptx, + APT_FEDInput fedInput, + APT_FEDOutMode fedOutMode, + bool dgbOutSwap, + unsigned short fedCount) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(fedInput >= APT_DB_FED_INPUT_PWM_B); + APT_PARAM_CHECK_NO_RET(fedInput <= APT_DB_FED_INPUT_ZERO); + APT_PARAM_CHECK_NO_RET(fedOutMode >= APT_DB_FED_OUTPUT_NOT_INVERT); + APT_PARAM_CHECK_NO_RET(fedOutMode <= APT_DB_FED_OUTPUT_PWM_B); + aptx->DG_CFG.BIT.rg_dg_fed_isel = fedInput; + aptx->DG_CFG.BIT.rg_dg_fed_osel = fedOutMode; + aptx->DG_CFG.BIT.rg_dgb_osel = dgbOutSwap; + aptx->DG_FED.BIT.rg_dg_fed = fedCount; +} + +/** + * @brief Set buffer load mode of Dead-Band configuration register. + * @param aptx APT register base address. + * @param dgCfgLoadMode Buffer load mode. + * @retval None. + */ +static inline void DCL_APT_SetDGConfigLoadMode(APT_RegStruct *aptx, APT_BufferLoadMode dgCfgLoadMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(dgCfgLoadMode >= APT_BUFFER_DISABLE); + APT_PARAM_CHECK_NO_RET(dgCfgLoadMode <= APT_BUFFER_GLOBAL_LOAD); + unsigned int bufFieldWidth = 4; /* Bit field width of buffer load mode setting */ + aptx->DG_BUF_EN.reg &= (~(0b11 << bufFieldWidth)); /* Clear rg_cfg_gld_en and rg_cfg_buf_en */ + aptx->DG_BUF_EN.reg |= (dgCfgLoadMode << bufFieldWidth); /* Write rg_cfg_gld_en and rg_cfg_buf_en */ +} + +/** + * @brief Enable the buffer load events of DG_CFG register. + * @param aptx APT register base address. + * @param loadEvent The buffer load events of DG_CFG register. + * A logical OR of valid values can be passed as the loadEvent parameter. + * Valid values for loadEvent are: + * APT_DEAD_BAND_LOAD_EVENT_ZERO - When time base counter value equal to zero. + * APT_DEAD_BAND_LOAD_EVENT_PERIOD - When time base counter value equal to period. + * @retval None. + */ +static inline void DCL_APT_SetDGConfigLoadEvent(APT_RegStruct *aptx, unsigned int dgCfgLoadEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + unsigned int dgBufField = 16; /* Field width of continuous PWM action load event setting */ + aptx->DG_BUF_LOAD.reg &= (~(0b11 << dgBufField)); + aptx->DG_BUF_LOAD.reg |= (dgCfgLoadEvent << dgBufField); +} + +/** + * @brief Set buffer load mode of Dead-Band rising edge delay counter register. + * @param aptx APT register base address. + * @param redCntLoadMode Buffer load mode. + * @retval None. + */ +static inline void DCL_APT_SetREDCounterLoadMode(APT_RegStruct *aptx, APT_BufferLoadMode redCntLoadMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(redCntLoadMode >= APT_BUFFER_DISABLE); + APT_PARAM_CHECK_NO_RET(redCntLoadMode <= APT_BUFFER_GLOBAL_LOAD); + aptx->DG_BUF_EN.reg &= (~(0b11 << 0)); /* Clear rg_red_gld_en and rg_red_buf_en */ + aptx->DG_BUF_EN.reg |= (redCntLoadMode << 0); /* Write rg_red_gld_en and rg_red_buf_en */ +} + +/** + * @brief Enable the buffer load events of DG_RED register + * @param aptx APT register base address. + * @param loadEvent The buffer load events of DG_RED register. + * A logical OR of valid values can be passed as the loadEvent parameter. + * Valid values for loadEvent are: + * APT_DEAD_BAND_LOAD_EVENT_ZERO - When time base counter value equal to zero. + * APT_DEAD_BAND_LOAD_EVENT_PERIOD - When time base counter value equal to period. + * @retval None. + */ +static inline void DCL_APT_SetREDCounterLoadEvent(APT_RegStruct *aptx, unsigned int redCntLoadEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->DG_BUF_LOAD.reg &= (~(0b11 << 0)); + aptx->DG_BUF_LOAD.reg |= (redCntLoadEvent << 0); +} + +/** + * @brief Set buffer load mode of Dead-Band falling edge delay counter register. + * @param aptx APT register base address. + * @param fedCntLoadMode Buffer load mode. + * @retval None. + */ +static inline void DCL_APT_SetFEDCounterLoadMode(APT_RegStruct *aptx, APT_BufferLoadMode fedCntLoadMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(fedCntLoadMode >= APT_BUFFER_DISABLE); + APT_PARAM_CHECK_NO_RET(fedCntLoadMode <= APT_BUFFER_GLOBAL_LOAD); + unsigned int bufFieldWidth = 2; /* Bit field width of buffer load mode setting */ + aptx->DG_BUF_EN.reg &= (~(0b11 << bufFieldWidth)); /* Clear rg_fed_gld_en and rg_fed_buf_en */ + aptx->DG_BUF_EN.reg |= (fedCntLoadMode << bufFieldWidth); /* Write rg_fed_gld_en and rg_fed_buf_en */ +} + +/** + * @brief Enable the buffer load events of DG_FED register. + * @param aptx APT register base address. + * @param loadEvent The buffer load events of DG_FED register. + * A logical OR of valid values can be passed as the loadEvent parameter. + * Valid values for loadEvent are: + * APT_DEAD_BAND_LOAD_EVENT_ZERO - When time base counter value equal to zero. + * APT_DEAD_BAND_LOAD_EVENT_PERIOD - When time base counter value equal to period. + * @retval None. + */ +static inline void DCL_APT_SetFEDCounterLoadEvent(APT_RegStruct *aptx, unsigned int fedCntLoadEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + unsigned int dgBufField = 8; /* Field width of continuous PWM action load event setting */ + aptx->DG_BUF_LOAD.reg &= (~(0b11 << dgBufField)); + aptx->DG_BUF_LOAD.reg |= (fedCntLoadEvent << dgBufField); +} + +/* --------------------------------------------------------------------------------------------- */ +/* Output Control (OC) submodule Direct Configuration Layer functions -------------------------- */ +/* --------------------------------------------------------------------------------------------- */ +/** + * @brief Enable an output control event. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @retval None. + */ +static inline void DCL_APT_EnableOutCtrlEvent(APT_RegStruct *aptx, APT_OutCtrlEvent ocEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ocEvent >= APT_OC_NO_EVENT); + APT_PARAM_CHECK_NO_RET(ocEvent <= APT_OC_COMBINE_EVENT_B2); + aptx->OC_MODE.reg |= ocEvent; +} + +/** + * @brief Disable an output control event. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @retval None. + */ +static inline void DCL_APT_DisableOutCtrlEvent(APT_RegStruct *aptx, APT_OutCtrlEvent ocEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ocEvent >= APT_OC_NO_EVENT); + APT_PARAM_CHECK_NO_RET(ocEvent <= APT_OC_COMBINE_EVENT_B2); + aptx->OC_MODE.reg &= ~ocEvent; +} + +/** + * @brief Clear OC_MODE register. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_ClearOCEventReg(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->OC_MODE.reg = 0; +} + +/** + * @brief Set output control mode of an output control event. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @param ocEventMode Output control mode. + * @retval None. + */ +static inline void DCL_APT_SetOutCtrlEventMode(APT_RegStruct *aptx, + APT_OutCtrlEvent ocEvent, + APT_OutCtrlMode ocEventMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET((ocEvent >= APT_OC_NO_EVENT) && (ocEvent <= APT_OC_COMBINE_EVENT_B2)); + APT_PARAM_CHECK_NO_RET(ocEventMode >= APT_OUT_CTRL_ONE_SHOT); + APT_PARAM_CHECK_NO_RET(ocEventMode <= APT_OUT_CTRL_CYCLE_BY_CYCLE); + unsigned ocModeOffset = 16; /* Offset of output control mode setting */ + if (ocEventMode == APT_OUT_CTRL_ONE_SHOT) { + aptx->OC_MODE.reg &= (~(ocEvent << ocModeOffset)); /* Set rg_oc_mode_evtx to 0 */ + } else if (ocEventMode == APT_OUT_CTRL_CYCLE_BY_CYCLE) { + aptx->OC_MODE.reg |= (ocEvent << ocModeOffset); /* Set rg_oc_mode_evtx to 1 */ + } +} + +/** + * @brief Set output control action of an output control event. + * @param aptx APT register base address. + * @param channel PWM output channel. + * @param ocEvtDir Output control event that takes into consideration of counter direction. + * @param ocAction Output control action. + * @retval None. + */ +static inline void DCL_APT_SetOutCtrlAction(APT_RegStruct *aptx, + APT_PWMChannel channel, + APT_OutCtrlEventDir ocEvtDir, + APT_OutCtrlAction ocAction) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(channel >= APT_PWM_CHANNEL_A); + APT_PARAM_CHECK_NO_RET(channel <= APT_PWM_CHANNEL_B); + APT_PARAM_CHECK_NO_RET(ocEvtDir >= APT_OC_EVT_GPIO_OR_SYSTEM_UP); + APT_PARAM_CHECK_NO_RET(ocEvtDir <= APT_OC_EVT_COMBINE_EVENT_B2_DOWN); + APT_PARAM_CHECK_NO_RET(ocAction >= APT_OUT_CTRL_ACTION_DISABLE); + APT_PARAM_CHECK_NO_RET(ocAction <= APT_OUT_CTRL_ACTION_HIGH_Z); + if (channel == APT_PWM_CHANNEL_A) { + aptx->OC_ACT_A.reg &= (~(0b111 << ocEvtDir)); + aptx->OC_ACT_A.reg |= (ocAction << ocEvtDir); + } else if (channel == APT_PWM_CHANNEL_B) { + aptx->OC_ACT_B.reg &= (~(0b111 << ocEvtDir)); + aptx->OC_ACT_B.reg |= (ocAction << ocEvtDir); + } +} + +/** + * @brief Get the flag of an output control event. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @retval bool: true, false. + */ +static inline bool DCL_APT_GetOutCtrlEventFlag(APT_RegStruct *aptx, APT_OutCtrlEvent ocEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_WITH_RET(ocEvent >= APT_OC_NO_EVENT, false); + APT_PARAM_CHECK_WITH_RET(ocEvent <= APT_OC_COMBINE_EVENT_B2, false); + return ((aptx->OC_EVT_FLAG.reg & ocEvent) == ocEvent); +} + +/** + * @brief Clear the flag of an output control event. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @retval None. + */ +static inline void DCL_APT_ClearOutCtrlEventFlag(APT_RegStruct *aptx, APT_OutCtrlEvent ocEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ocEvent >= APT_OC_NO_EVENT); + APT_PARAM_CHECK_NO_RET(ocEvent <= APT_OC_COMBINE_EVENT_B2); + unsigned int ocFlgOffset = 16; /* Offset of output control flag clear */ + aptx->OC_EVT_FLAG.reg |= (ocEvent << ocFlgOffset); +} + +/** + * @brief Enable the event latch of an output control event. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @retval None. + */ +static inline void DCL_APT_EnableOutCtrlEventLatch(APT_RegStruct *aptx, APT_OutCtrlEvent ocEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ocEvent >= APT_OC_NO_EVENT); + APT_PARAM_CHECK_NO_RET(ocEvent <= APT_OC_COMBINE_EVENT_B2); + aptx->OC_LAT_EN.reg |= ocEvent; +} + +/** + * @brief Disable the event latch of an output control event. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @retval None. + */ +static inline void DCL_APT_DisableOutCtrlEventLatch(APT_RegStruct *aptx, APT_OutCtrlEvent ocEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ocEvent >= APT_OC_NO_EVENT); + APT_PARAM_CHECK_NO_RET(ocEvent <= APT_OC_COMBINE_EVENT_B2); + aptx->OC_LAT_EN.reg &= ~ocEvent; +} + +/** + * @brief Set cycle-by-cycle event latch clear event. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @param clrMode Latche clear event of cycle-by-cycle event. + * @retval None. + */ +static inline void DCL_APT_SetCBCLatchClearEvent(APT_RegStruct *aptx, + APT_OutCtrlEvent ocEvent, + APT_CBCClearMode clrMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ocEvent >= APT_OC_NO_EVENT); + APT_PARAM_CHECK_NO_RET(ocEvent <= APT_OC_COMBINE_EVENT_B2); + APT_PARAM_CHECK_NO_RET(clrMode >= APT_CLEAR_CBC_ON_CNTR_ZERO); + APT_PARAM_CHECK_NO_RET(clrMode <= APT_CLEAR_CBC_ON_CNTR_ZERO_PERIOD); + unsigned int cbcClrOffsetZero = 0; /* Offset of CBC latch clear on counter equal to 0 */ + unsigned int cbcClrOffsetPrd = 16; /* Offset of CBC latch clear on counter euqal to period */ + unsigned int mask = (ocEvent << cbcClrOffsetPrd) | (ocEvent << cbcClrOffsetZero); + mask &= clrMode; + aptx->OC_PRD_CLR.reg |= mask; +} + +/** + * @brief Enable a software output control event. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @retval None. + */ +static inline void DCL_APT_EnableSwOutCtrlEvent(APT_RegStruct *aptx, APT_OutCtrlEvent ocEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ocEvent >= APT_OC_NO_EVENT); + APT_PARAM_CHECK_NO_RET(ocEvent <= APT_OC_COMBINE_EVENT_B2); + aptx->OC_FRC_EVT.reg |= ocEvent; +} + +/** + * @brief Disable a software output control event. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @retval None. + */ +static inline void DCL_APT_DisableSwOutCtrlEvent(APT_RegStruct *aptx, APT_OutCtrlEvent ocEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ocEvent >= APT_OC_NO_EVENT); + APT_PARAM_CHECK_NO_RET(ocEvent <= APT_OC_COMBINE_EVENT_B2); + aptx->OC_FRC_EVT.reg &= (~ocEvent); +} + +/* --------------------------------------------------------------------------------------------- */ +/* Interrupt Generation (IG) submodule Direct Configuration Layer functions -------------------- */ +/* --------------------------------------------------------------------------------------------- */ +/** + * @brief Enable the output control event to generate an event interrupt. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @retval None. + */ +static inline void DCL_APT_EnableEventInterrupt(APT_RegStruct *aptx, APT_OutCtrlEvent ocEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ocEvent >= APT_OC_NO_EVENT); + APT_PARAM_CHECK_NO_RET(ocEvent <= APT_OC_COMBINE_EVENT_B2); + aptx->INT_EVT_EN.reg |= ocEvent; +} + +/** + * @brief Disable the output control event to generate an event interrupt.. + * @param aptx APT register base address. + * @param ocEvent Output control event. + * @retval None. + */ +static inline void DCL_APT_DisableEventInterrupt(APT_RegStruct *aptx, APT_OutCtrlEvent ocEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ocEvent >= APT_OC_NO_EVENT); + APT_PARAM_CHECK_NO_RET(ocEvent <= APT_OC_COMBINE_EVENT_B2); + aptx->INT_EVT_EN.reg &= (~ocEvent); +} + +/** + * @brief Enable timer interrupt of APT module. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_EnableTimerInterrupt(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->INT_TMR_EN.BIT.rg_int_en_tmr = BASE_CFG_SET; +} + +/** + * @brief Disable timer interrupt of APT module. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_DisableTimerInterrupt(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->INT_TMR_EN.BIT.rg_int_en_tmr = BASE_CFG_UNSET; +} + +/** + * @brief Get the event interrupt flag. + * @param aptx APT register base address. + * @retval bool: true, false. + */ +static inline bool DCL_APT_GetEventInterruptFlag(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return (aptx->OC_EVT_FLAG.BIT.ro_int_flag_evt); +} + +/** + * @brief Clear the event interrupt flag. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_ClearEventInterruptFlag(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->OC_EVT_FLAG.BIT.rg_int_clr_evt = BASE_CFG_SET; +} + +/** + * @brief Get the timer interrupt flag. + * @param aptx APT register base address. + * @retval bool: true, false. + */ +static inline bool DCL_APT_GetTimerInterruptFlag(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return (aptx->INT_TMR_FLAG.BIT.ro_int_flag_tmr); +} + +/** + * @brief Clear the timer interrupt flag. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_ClearTimerInterruptFlag(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->INT_TMR_FLAG.BIT.rg_int_clr_tmr = BASE_CFG_SET; +} + +/** + * @brief Select the source of timer interrupt. + * @param aptx APT register base address. + * @param tmrIntSrc Source of timer interrupt. + * @retval None. + */ +static inline void DCL_APT_SetTimerInterruptSrc(APT_RegStruct *aptx, APT_TimerInterruptSrc tmrIntSrc) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(tmrIntSrc >= APT_INT_SRC_CNTR_DISABLE); + APT_PARAM_CHECK_NO_RET(tmrIntSrc <= APT_INT_SRC_CNTR_CMPD_DOWN); + aptx->INT_TMR_SEL.BIT.rg_int_tmr_sel = tmrIntSrc; +} + +/** + * @brief Enable the synchronization of timer interrupt scale initial count value. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_EnableTimerInterruptCountSyncInit(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->INT_PRSC_CFG.BIT.rg_int_prsc_synen = BASE_CFG_SET; +} + +/** + * @brief Disable the synchronization of timer interrupt scale initial count value. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_DisableTimerInterruptCountSyncInit(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->INT_PRSC_CFG.BIT.rg_int_prsc_synen = BASE_CFG_UNSET; +} + +/** + * @brief Set the initial count value of timer interrupt scale. + * @param aptx APT register base address. + * @param intCntInitVal Initial count value of timer interrupt scale. + * @retval None. + */ +static inline void DCL_APT_SetTimerInterruptCountSyncInitVal(APT_RegStruct *aptx, unsigned short intCntInitVal) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(intCntInitVal <= TIMER_INTERRUPT_CNT_MAX); + aptx->INT_PRSC_CFG.BIT.rg_int_prsc_phs = intCntInitVal; +} + +/** + * @brief Set the count period of timer interrupt scale. + * @param aptx APT register base address. + * @param intCntPeriod Count period of timer interrupt scale. + * @retval None. + */ +static inline void DCL_APT_SetTimerInterruptCountPeriod(APT_RegStruct *aptx, unsigned short intCntPeriod) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(intCntPeriod <= TIMER_INTERRUPT_CNT_MAX); + aptx->INT_PRSC_CFG.BIT.rg_int_prsc_prd = intCntPeriod; +} + +/** + * @brief Get the count value of timer interrupt scale. + * @param aptx APT register base address. + * @retval unsigned short: Count value of timer interrupt scale. + */ +static inline unsigned short DCL_APT_GetTimerInterruptCount(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return (aptx->INT_PRSC_CFG.BIT.ro_int_prsc_cnt); +} + +/** + * @brief Force the count value of timer interrupt scale to increase. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_ForceTimerInterruptCountIncr(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->INT_PRSC_CFG.BIT.rg_int_prsc_frc = BASE_CFG_SET; +} + +/* --------------------------------------------------------------------------------------------- */ +/* ADC Converter Start (CS) submodule Direct Configuration Layer functions --------------------- */ +/* --------------------------------------------------------------------------------------------- */ +/** + * @brief Enable the ADC trigger channel. + * @param aptx APT register base address. + * @param csTrgCh ADC trigger channel. + * @retval None. + */ +static inline void DCL_APT_EnableADCTrigger(APT_RegStruct *aptx, APT_ADCTriggerChannel csTrgCh) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(csTrgCh >= APT_ADC_CONVERSION_START_A); + APT_PARAM_CHECK_NO_RET(csTrgCh <= APT_ADC_CONVERSION_START_B); + if (csTrgCh == APT_ADC_CONVERSION_START_A) { + aptx->CS_TMR_SELA.BIT.rg_csa_en_cs = BASE_CFG_SET; + } else if (csTrgCh == APT_ADC_CONVERSION_START_B) { + aptx->CS_TMR_SELB.BIT.rg_csb_en_cs = BASE_CFG_SET; + } +} + +/** + * @brief Disable the ADC trigger channel. + * @param aptx APT register base address. + * @param csTrgCh ADC trigger channel. + * @retval None. + */ +static inline void DCL_APT_DisableADCTrigger(APT_RegStruct *aptx, APT_ADCTriggerChannel csTrgCh) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(csTrgCh >= APT_ADC_CONVERSION_START_A); + APT_PARAM_CHECK_NO_RET(csTrgCh <= APT_ADC_CONVERSION_START_B); + if (csTrgCh == APT_ADC_CONVERSION_START_A) { + aptx->CS_TMR_SELA.BIT.rg_csa_en_cs = BASE_CFG_UNSET; + } else if (csTrgCh == APT_ADC_CONVERSION_START_B) { + aptx->CS_TMR_SELB.BIT.rg_csb_en_cs = BASE_CFG_UNSET; + } +} + +/** + * @brief Select the source of ADC trigger channel. + * @param aptx APT register base address. + * @param csTrgCh ADC trigger channel. + * @param csTrgSrc Source of ADC trigger. + * @retval None. + */ +static inline void DCL_APT_SetADCTriggerSrc(APT_RegStruct *aptx, + APT_ADCTriggerChannel csTrgCh, + APT_ADCTriggerSource csTrgSrc) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(csTrgCh >= APT_ADC_CONVERSION_START_A); + APT_PARAM_CHECK_NO_RET(csTrgCh <= APT_ADC_CONVERSION_START_B); + APT_PARAM_CHECK_NO_RET(csTrgSrc <= APT_CS_SRC_CNTR_CMPD_DOWN); + if (csTrgCh == APT_ADC_CONVERSION_START_A) { + aptx->CS_TMR_SELA.BIT.rg_csa_tmr_sel = csTrgSrc; + } else if (csTrgCh == APT_ADC_CONVERSION_START_B) { + aptx->CS_TMR_SELB.BIT.rg_csb_tmr_sel = csTrgSrc; + } +} + +/** + * @brief Enable synchronization of ADC trigger scale initial count value. + * @param aptx APT register base address. + * @param csTrgCh ADC trigger channel. + * @retval None. + */ +static inline void DCL_APT_EnableADCTriggerCountSyncInit(APT_RegStruct *aptx, APT_ADCTriggerChannel csTrgCh) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(csTrgCh >= APT_ADC_CONVERSION_START_A); + APT_PARAM_CHECK_NO_RET(csTrgCh <= APT_ADC_CONVERSION_START_B); + if (csTrgCh == APT_ADC_CONVERSION_START_A) { + aptx->CS_PRSCA_CFG.BIT.rg_csa_prsc_synen = BASE_CFG_SET; + } else if (csTrgCh == APT_ADC_CONVERSION_START_B) { + aptx->CS_PRSCB_CFG.BIT.rg_csb_prsc_synen = BASE_CFG_SET; + } +} + +/** + * @brief Disable synchronization of ADC trigger scale initial count value. + * @param aptx APT register base address. + * @param csTrgCh ADC trigger channel. + * @retval None. + */ +static inline void DCL_APT_DisableADCTriggerCountSyncInit(APT_RegStruct *aptx, APT_ADCTriggerChannel csTrgCh) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(csTrgCh >= APT_ADC_CONVERSION_START_A); + APT_PARAM_CHECK_NO_RET(csTrgCh <= APT_ADC_CONVERSION_START_B); + if (csTrgCh == APT_ADC_CONVERSION_START_A) { + aptx->CS_PRSCA_CFG.BIT.rg_csa_prsc_synen = BASE_CFG_UNSET; + } else if (csTrgCh == APT_ADC_CONVERSION_START_B) { + aptx->CS_PRSCB_CFG.BIT.rg_csb_prsc_synen = BASE_CFG_UNSET; + } +} + +/** + * @brief Set the initial count value of ADC trigger scale. + * @param aptx APT register base address. + * @param csTrgCh ADC trigger channel. + * @param csCntInitVal Initial count value of ADC trigger scale. + * @retval None. + */ +static inline void DCL_APT_SetADCTriggerCountSyncInitVal(APT_RegStruct *aptx, + APT_ADCTriggerChannel csTrgCh, + unsigned short csCntInitVal) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(csTrgCh >= APT_ADC_CONVERSION_START_A); + APT_PARAM_CHECK_NO_RET(csTrgCh <= APT_ADC_CONVERSION_START_B); + APT_PARAM_CHECK_NO_RET(csCntInitVal <= ADC_CONVERSION_START_CNT_MAX); + if (csTrgCh == APT_ADC_CONVERSION_START_A) { + aptx->CS_PRSCA_CFG.BIT.rg_csa_prsc_phs = csCntInitVal; + } else if (csTrgCh == APT_ADC_CONVERSION_START_B) { + aptx->CS_PRSCB_CFG.BIT.rg_csb_prsc_phs = csCntInitVal; + } +} + +/** + * @brief Set the count period of ADC trigger scale. + * @param aptx APT register base address. + * @param csTrgCh ADC trigger channel. + * @param csCntPeriod Count period of ADC trigger scale. + * @retval None. + */ +static inline void DCL_APT_SetADCTriggerCountPeriod(APT_RegStruct *aptx, + APT_ADCTriggerChannel csTrgCh, + unsigned short csCntPeriod) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(csTrgCh >= APT_ADC_CONVERSION_START_A); + APT_PARAM_CHECK_NO_RET(csTrgCh <= APT_ADC_CONVERSION_START_B); + APT_PARAM_CHECK_NO_RET(csCntPeriod <= ADC_CONVERSION_START_CNT_MAX); + if (csTrgCh == APT_ADC_CONVERSION_START_A) { + aptx->CS_PRSCA_CFG.BIT.rg_csa_prsc_prd = csCntPeriod; + } else if (csTrgCh == APT_ADC_CONVERSION_START_B) { + aptx->CS_PRSCB_CFG.BIT.rg_csb_prsc_prd = csCntPeriod; + } +} + +/** + * @brief Force the count value of ADC trigger scale to increase. + * @param aptx APT register base address. + * @param csTrgCh ADC trigger channel. + * @retval None. + */ +static inline void DCL_APT_ForceADCTriggerCountIncr(APT_RegStruct *aptx, APT_ADCTriggerChannel csTrgCh) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(csTrgCh >= APT_ADC_CONVERSION_START_A); + APT_PARAM_CHECK_NO_RET(csTrgCh <= APT_ADC_CONVERSION_START_B); + if (csTrgCh == APT_ADC_CONVERSION_START_A) { + aptx->CS_PRSCA_CFG.BIT.rg_csa_prsc_frc = BASE_CFG_SET; + } else if (csTrgCh == APT_ADC_CONVERSION_START_B) { + aptx->CS_PRSCB_CFG.BIT.rg_csb_prsc_frc = BASE_CFG_SET; + } +} + +/** + * @brief Get the flag of ADC trigger. + * @param aptx APT register base address. + * @param csTrgCh ADC trigger channel. + * @retval bool: true, false. + */ +static inline bool DCL_APT_GetADCTriggerFlag(APT_RegStruct *aptx, APT_ADCTriggerChannel csTrgCh) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_WITH_RET(csTrgCh >= APT_ADC_CONVERSION_START_A, false); + APT_PARAM_CHECK_WITH_RET(csTrgCh <= APT_ADC_CONVERSION_START_B, false); + return ((aptx->CS_FLAG.reg & csTrgCh) == csTrgCh); +} + +/** + * @brief Clear the flag of ADC trigger. + * @param aptx APT register base address. + * @param csTrgCh ADC trigger channel. + * @retval None. + */ +static inline void DCL_APT_ClearADCTriggerFlag(APT_RegStruct *aptx, APT_ADCTriggerChannel csTrgCh) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(csTrgCh >= APT_ADC_CONVERSION_START_A); + APT_PARAM_CHECK_NO_RET(csTrgCh <= APT_ADC_CONVERSION_START_B); + unsigned int trgFlgOffset = 16; /* Offset of ADC trigget flag clear */ + aptx->CS_FLAG.reg |= (csTrgCh << trgFlgOffset); +} + +/** + * @brief Configure the DMA request of ADC trigger. + * @param aptx APT register base address. + * @param csDMAReqSrc DMA request source of ADC Converter Start submodule. + * @param csDMAType DMA request type of ADC Converter Start submodule. + * @retval None. + */ +static inline void DCL_APT_SetADCTriggerDMAReq(APT_RegStruct *aptx, + APT_ADCTrgDMAReqSrc csDMAReqSrc, + APT_ADCTrgDMAReqType csDMAType) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(csDMAReqSrc >= APT_CS_DMA_REQ_SRC_DISABLE); + APT_PARAM_CHECK_NO_RET(csDMAReqSrc <= APT_CS_DMA_REQ_SRC_CHANNEL_B); + APT_PARAM_CHECK_NO_RET(csDMAType <= APT_CS_DMA_SINGLE_REQUEST); + APT_PARAM_CHECK_NO_RET(csDMAType <= APT_CS_DMA_BURST_REQUEST); + aptx->CS_DMA.reg &= (~(0b11 << csDMAType)); + aptx->CS_DMA.reg |= (csDMAReqSrc << csDMAType); +} + +/* --------------------------------------------------------------------------------------------- */ +/* Event Management (EM) submodule Direct Configuration Layer functions ------------------------ */ +/* --------------------------------------------------------------------------------------------- */ +/** + * @brief Set the polarity of GPIO/system event. + * @param aptx APT register base address. + * @param ioSysEvt GPIO or system event. + * @param ioSysEvtPolar Event polarity. + * @retval None. + */ +static inline void DCL_APT_SetIOSysEventPolarity(APT_RegStruct *aptx, + APT_EMIOSysEvent ioSysEvt, + APT_EMEventPolarity ioSysEvtPolar) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(ioSysEvt >= APT_EM_GPIO_EVENT_1); + APT_PARAM_CHECK_NO_RET(ioSysEvt <= APT_EM_SYSTEM_EVENT_3); + APT_PARAM_CHECK_NO_RET(ioSysEvtPolar >= APT_EM_EVENT_POLARITY_NOT_INVERT); + APT_PARAM_CHECK_NO_RET(ioSysEvtPolar <= APT_EM_EVENT_POLARITY_FORCE_HIGH); + aptx->EM_EVTIO_PSEL.reg &= (~(0b11 << ioSysEvt)); + aptx->EM_EVTIO_PSEL.reg |= (ioSysEvtPolar << ioSysEvt); +} + +/** + * @brief Set the polarity of multiplexing event. + * @param aptx APT register base address. + * @param mpEvt Multiplexing event. + * @param mpEvtPolar Event polarity. + * @retval None. + */ +static inline void DCL_APT_SetMpEventPolarity(APT_RegStruct *aptx, + APT_EMMuxEvent mpEvt, + APT_EMEventPolarity mpEvtPolar) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(mpEvt >= APT_EM_MP_EVENT_1); + APT_PARAM_CHECK_NO_RET(mpEvt <= APT_EM_MP_EVENT_6); + APT_PARAM_CHECK_NO_RET(mpEvtPolar >= APT_EM_EVENT_POLARITY_NOT_INVERT); + APT_PARAM_CHECK_NO_RET(mpEvtPolar <= APT_EM_EVENT_POLARITY_FORCE_HIGH); + aptx->EM_EVTMP_PSEL.reg &= (~(0b11 << mpEvt)); + aptx->EM_EVTMP_PSEL.reg |= (mpEvtPolar << mpEvt); +} + +/** + * @brief When the logicial OR result of GPIO events and MUX events is selected as the source of EM group event, + * this function is called to enable which events can participate in the logical OR operation. + * @param aptx APT register base address. + * @param emGroup The group of Event Management, which can be APT_EM_MODULE_A or APT_EM_MODULE_B. + * Each EM group has 2 events. All the 4 group events are enumerated in APT_EMGroupEvent. + * @param event1OREn The logical OR operation source of group event 1. + * @param event2OREn The logical OR operation source of group event 2. + * event1OREn and event2ORE are the logical OR of some valid values. + * Each valid values indicates that the corresponding event is enabled to participate in the + * logical OR operation of EM group event source. These valid values are: + * APT_EM_OR_EN_GPIO_EVENT_1 - GPIO event 1 is enabled + * APT_EM_OR_EN_GPIO_EVENT_2 - GPIO event 2 is enabled + * APT_EM_OR_EN_GPIO_EVENT_3 - GPIO event 3 is enabled + * APT_EM_OR_EN_MUX_EVENT_1 - MUX event 1 is enabled + * APT_EM_OR_EN_MUX_EVENT_2 - MUX event 2 is enabled + * APT_EM_OR_EN_MUX_EVENT_3 - MUX event 3 is enabled + * APT_EM_OR_EN_MUX_EVENT_4 - MUX event 4 is enabled + * APT_EM_OR_EN_MUX_EVENT_5 - MUX event 5 is enabled + * APT_EM_OR_EN_MUX_EVENT_6 - MUX event 6 is enabled + * @retval None. + */ +static inline void DCL_APT_SetEMEventOR(APT_RegStruct *aptx, + APT_EMGroup emGroup, + unsigned short event1OREn, + unsigned short event2OREn) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(emGroup >= APT_EM_MODULE_A); + APT_PARAM_CHECK_NO_RET(emGroup <= APT_EM_MODULE_B); + if (emGroup == APT_EM_MODULE_A) { + aptx->EM_AOR_EN.BIT.rg_em_a1_oren = event1OREn; + aptx->EM_AOR_EN.BIT.rg_em_a2_oren = event2OREn; + } else if (emGroup == APT_EM_MODULE_B) { + aptx->EM_BOR_EN.BIT.rg_em_b1_oren = event1OREn; + aptx->EM_BOR_EN.BIT.rg_em_b2_oren = event2OREn; + } +} + +/** + * @brief Select the combine event source of GRP_A1, GRP_A2, GRP_B1, GRP_B2. + * @param aptx APT register base address. + * @param evtGroup Combine event source group. + * @param combineEvtSrc Combine event source. + * @retval None. + */ +static inline void DCL_APT_SetCombineGroupSrc(APT_RegStruct *aptx, + APT_EMCombineEvtSrcGrp evtGroup, + APT_EMCombineEvtSrc combineEvtSrc) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(evtGroup >= APT_EM_COMBINE_SRC_GRP_A1); + APT_PARAM_CHECK_NO_RET(evtGroup <= APT_EM_COMBINE_SRC_GRP_B2); + APT_PARAM_CHECK_NO_RET(combineEvtSrc >= APT_EM_COMBINE_SRC_EVT_1); + APT_PARAM_CHECK_NO_RET(combineEvtSrc <= APT_EM_COMBINE_SRC_ALL_EVENT_OR); + unsigned int grpEvtFieldWidth = 4; /* Bit field width of combine event group input source setting */ + aptx->EM_MRG_SEL.reg &= (~(0b1111 << (evtGroup * grpEvtFieldWidth))); + aptx->EM_MRG_SEL.reg |= (combineEvtSrc << (evtGroup * grpEvtFieldWidth)); +} + +/** + * @brief Select Combine Mode + * @param aptx APT register base address. + * @param cmbEvt Combine event. + * @param cmbMode Combine mode. + * @retval None. + */ +static inline void DCL_APT_SetCombineEventSrc(APT_RegStruct *aptx, + APT_EMCombineEvent cmbEvt, + APT_EMCombineEvtMode cmbMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(cmbEvt >= APT_EM_COMBINE_EVENT_A1); + APT_PARAM_CHECK_NO_RET(cmbEvt <= APT_EM_COMBINE_EVENT_B2); + APT_PARAM_CHECK_NO_RET(cmbMode >= APT_EM_COMBINE_LOW_LEVEL); + APT_PARAM_CHECK_NO_RET(cmbMode <= APT_EM_COMBINE_EVT2); + unsigned int cmbModeOffset = 16; /* Offset of combine mode */ + unsigned int cmbModeFieldWidth = 4; /* Bit field width of combine mode */ + aptx->EM_MRG_SEL.reg &= (~(0b111 << (cmbModeOffset + cmbEvt * cmbModeFieldWidth))); + aptx->EM_MRG_SEL.reg |= (cmbMode << (cmbModeOffset + cmbEvt * cmbModeFieldWidth)); +} + +/** + * @brief Select the source of Event Management submodule filter event. + * @param aptx APT register base address. + * @param cmbEvt Combine event. + * @retval None. + */ +static inline void DCL_APT_SelectFilterEventInput(APT_RegStruct *aptx, APT_EMCombineEvent cmbEvt) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(cmbEvt >= APT_EM_COMBINE_EVENT_A1); + APT_PARAM_CHECK_NO_RET(cmbEvt <= APT_EM_COMBINE_EVENT_B2); + aptx->EM_OUT_SEL.BIT.rg_evtfilt_sel = cmbEvt; +} + +/** + * @brief Set the output type of combine event. + * @param aptx APT register base address. + * @param cmbEvt Combine event. + * @param filter Whether the output of combine event is filtered. + * @retval None. + */ +static inline void DCL_APT_SetCombineEventOut(APT_RegStruct *aptx, + APT_EMCombineEvent cmbEvt, + APT_EMCombineEventOut filter) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(cmbEvt >= APT_EM_COMBINE_EVENT_A1); + APT_PARAM_CHECK_NO_RET(cmbEvt <= APT_EM_COMBINE_EVENT_B2); + APT_PARAM_CHECK_NO_RET(filter >= APT_EM_COMBINE_EVENT_OUT_ORIG_SIGNAL); + APT_PARAM_CHECK_NO_RET(filter <= APT_EM_COMBINE_EVENT_OUT_FILT_SIGNAL); + aptx->EM_OUT_SEL.reg &= (~(0b1 << cmbEvt)); + aptx->EM_OUT_SEL.reg |= (filter << cmbEvt); +} + +/** + * @brief Select the sync-in source of slave APT module. + * @param aptx APT register base address. + * @param syncInSrc Sync-in source of slave APT module. + * @retval None. + */ +static inline void DCL_APT_SelectSyncInPulseSrc(APT_RegStruct *aptx, APT_SyncInSrc syncInSrc) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(syncInSrc >= APT_SYNCIN_SRC_APT0_SYNCOUT); + APT_PARAM_CHECK_NO_RET(syncInSrc <= APT_SYNCIN_SRC_DISABLE); + aptx->SYNI_CFG.BIT.rg_syni_sel = syncInSrc; +} + +/** + * @brief Get the flag of sync-in pulse. + * @param aptx APT register base address. + * @retval bool: true, false. + */ +static inline bool DCL_APT_GetSyncInPulseFlag(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return (aptx->SYNI_CFG.BIT.ro_syni_flag); +} + +/** + * @brief Clear the flag of sync-in pulse. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_ClearSyncInPulseFlag(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->SYNI_CFG.BIT.rg_syni_clr = BASE_CFG_SET; +} + +/** + * @brief Select the synchronization source of the time-base counter. + * @param aptx APT register base address. + * @param cntrSyncSrc The selection of synchronization source for the time-base counter. + * A logical OR of valid values can be passed as the cntrSyncSrc parameter. + * Valid values for cntrSyncSrc are: + * APT_CNTR_SYNC_SRC_COMBINE_EVENT_A1 - Enable combine event A1 as the counter synchronization source. + * APT_CNTR_SYNC_SRC_COMBINE_EVENT_B1 - Enable combine event B1 as the counter synchronization source. + * APT_CNTR_SYNC_SRC_SYNCIN - Enable Sync-In source as the counter synchronization source. + * @retval None. + */ +static inline void DCL_APT_SetTimeBaseCounterSyncSrc(APT_RegStruct *aptx, unsigned short cntrSyncSrc) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(cntrSyncSrc <= CNTR_SYNC_SOURCE_MAX); + aptx->SYNCNT_CFG.reg = cntrSyncSrc; +} + +/** + * @brief Select the source of synchronization out pulse. + * @param aptx APT register base address. + * @param syncOutSrc The source of synchronization out pulse. + * A logical OR of valid values can be passed as the syncOutSrc parameter. + * Valid values for syncOutSrc are: + * APT_SYNC_OUT_ON_CNTR_ZERO - Generate a sync out pulse when counter equals zero. + * APT_SYNC_OUT_ON_CNTR_PERIOD - Generate a sync out pulse when counter equals period. + * APT_SYNC_OUT_ON_COMBINE_EVENT_A1 - Generate a sync out pulse when combine event A1 happens. + * APT_SYNC_OUT_ON_COMBINE_EVENT_B1 - Generate a sync out pulse when combine event B1 happens. + * APT_SYNC_OUT_ON_CNTR_CMPB - Generate a sync out pulse when counter equals CMPB. + * APT_SYNC_OUT_ON_CNTR_CMPC - Generate a sync out pulse when counter equals CMPC. + * APT_SYNC_OUT_ON_CNTR_CMPD - Generate a sync out pulse when counter equals CMPD. + * @retval None. + */ +static inline void DCL_APT_SetSyncOutPulseSrc(APT_RegStruct *aptx, unsigned short syncOutSrc) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(syncOutSrc <= SYNC_OUT_SOURCE_MAX); + aptx->SYNO_CFG.reg &= (~(0xFF << 0)); + aptx->SYNO_CFG.reg |= (syncOutSrc << 0); +} + +/** + * @brief Set synchronization mode of master APT module. + * @param aptx APT register base address. + * @param syncOutMode Synchronization mode of master APT module. + * @retval None. + */ +static inline void DCL_APT_SetSyncOutMode(APT_RegStruct *aptx, APT_SyncOutMode syncOutMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(syncOutMode >= APT_SYNCOUT_ONE_SHOT_MODE); + APT_PARAM_CHECK_NO_RET(syncOutMode <= APT_SYNCOUT_MULTIPLE_MODE); + aptx->SYNO_CFG.BIT.rg_mode_syno = syncOutMode; +} + +/** + * @brief Select the latch source of one-shot sync-out mode. + * @param aptx APT register base address. + * @param latSetSel Latch source of one-shot sync-out mode. + * @retval None. + */ +static inline void DCL_APT_SelectSyncOutOneShotLatch(APT_RegStruct *aptx, APT_SyncOutLatSetSel latSetSel) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(latSetSel >= APT_SYNCOUT_LATCH_SET_ON_SW_FORCE); + APT_PARAM_CHECK_NO_RET(latSetSel <= APT_SYNCOUT_LATCH_SET_ON_GLB_LOAD); + aptx->SYNO_CFG.BIT.rg_latset_sel = latSetSel; +} + +/** + * @brief When in one-shot sync out mode and rg_latset_otsyn is selected as the latch set condition, + * this function is called to turn the one-shot latch condition ON. + * Upon occurrence of a chosen sync out source event, a sync out pulse is generated and the latch + * will be cleared. Hence writing 1 to rg_latset_otsyn will allow a sync out event to pass through + * and block other sync out source event. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_SetSyncOutOneShotLatch(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->SYNO_CFG.BIT.rg_latset_otsyn = BASE_CFG_SET; +} + +/** + * @brief Select the pulse that causes global buffer load. + * @param aptx APT register base address. + * @param glbLoadEvt The pulse that causes global buffer load. + * A logical OR of valid values can be passed as the syncOutSrc parameter. + * Valid values for gloLoadTrg are: + * APT_GLB_LOAD_ON_CNTR_ZERO - Global buffer load when counter equals zero. + * APT_GLB_LOAD_ON_CNTR_PERIOD - Global buffer load when counter equals period. + * APT_GLB_LOAD_ON_CNTR_SYNC - Global buffer load when counter sync is effective. + * @retval None. + */ +static inline void DCL_APT_SetGlobalLoadEvent(APT_RegStruct *aptx, unsigned short glbLoadEvt) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->GLB_LOAD.reg &= (~(0b111 << 0)); + aptx->GLB_LOAD.reg |= (glbLoadEvt << 0); +} + +/** + * @brief Set the prescale value of multiple global buffer load mode. + * @param aptx APT register base address. + * @param gldCntPeriod Prescale value of multiple global buffer load mode. + * @retval None. + */ +static inline void DCL_APT_SetGlobalLoadPrescale(APT_RegStruct *aptx, unsigned short gldCntPeriod) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(gldCntPeriod <= GLOBAL_LOAD_CNT_MAX); + aptx->GLB_LOAD.BIT.rg_gld_prsc_prd = gldCntPeriod; +} + +/** + * @brief Set the global buffer load mode. + * @param aptx APT register base address. + * @param glbLoadMode Global buffer load mode. + * @retval None. + */ +static inline void DCL_APT_SetGlobalLoadMode(APT_RegStruct *aptx, APT_GlobalLoadMode glbLoadMode) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(glbLoadMode >= APT_GLB_LOAD_ONE_SHOT_MODE); + APT_PARAM_CHECK_NO_RET(glbLoadMode <= APT_GLB_LOAD_MULTIPLE_MODE); + aptx->GLB_LOAD.BIT.rg_mode_gld = glbLoadMode; +} + +/** + * @brief When in one-shot global buffer load mode, this function is called to turn the one-shot latch condition ON. + * Upon occurrence of a chosen global buffer load event, the registers that is set to global buffer load mode + * will load the buffer, and the one-shot latch will be cleared. Hence writing 1 to rg_latset_otgld will + * allow a global buffer load event to pass through and block other global buffer load event. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_SetGlobalLoadOneShotLatch(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->GLB_LOAD.BIT.rg_latset_otgld = BASE_CFG_SET; +} + +/** + * @brief Get buffer status of the registers that enable buffer load. + * @param aptx The base address of APT module. + * @param regBuf The buffer of the registers that enable buffer load. + * @retval true: The register buffer is full. + * @retval false: The register buffer is not full. + */ +static inline bool DCL_APT_GetRegBufferStatus(APT_RegStruct *aptx, APT_RegBuffer regBuf) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_WITH_RET(regBuf <= APT_REG_BUFFER_DG_CFG, false); + return ((aptx->LOAD_STS.reg & regBuf) == regBuf); +} + +/** + * @brief Generate a synchronization force event. + * @param aptx The base address of APT module. + * @param frcEvt Synchronization force event. + * @retval None. + */ +static inline void DCL_APT_ForceEvent(APT_RegStruct *aptx, APT_ForceEvtType frcEvt) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(frcEvt <= APT_FORCE_EVENT_PWM_ACTION_BUF_LOAD); + aptx->SYN_FRC.reg |= frcEvt; +} +/** + * @brief PWM Channel A output status. + * @param aptx The base address of APT module. + * @retval APT_PwmStatus: Status of PWM. + */ +static inline APT_PwmStatus DCL_APT_GetPWMAStatus(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + if (aptx->PWM_STATUS.BIT.ro_pwma_oen_status == BASE_CFG_DISABLE) { + return aptx->PWM_STATUS.BIT.ro_pwma_status; + } + return APT_PWM_HIGH_RESISTANCE; +} + +/** + * @brief PWM Channel B output status. + * @param aptx The base address of APT module. + * @retval APT_PwmStatus: Status of PWM. + */ +static inline APT_PwmStatus DCL_APT_GetPWMBStatus(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + if (aptx->PWM_STATUS.BIT.ro_pwmb_oen_status == BASE_CFG_DISABLE) { + return aptx->PWM_STATUS.BIT.ro_pwmb_status; + } + return APT_PWM_HIGH_RESISTANCE; +} + +/** + * @brief Protect of POE0 flag. + * @param aptx The base address of APT module. + * @retval APT_PoeStatus: Status of POE0. + */ +static inline APT_PoeStatus DCL_APT_GetPoe0Status(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return aptx->APT_POE_FLAG.BIT.ro_poe0_flag; +} + +/** + * @brief Protect of POE1 flag. + * @param aptx The base address of APT module. + * @retval APT_PoeStatus: Status of POE1. + */ +static inline APT_PoeStatus DCL_APT_GetPoe1Status(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return aptx->APT_POE_FLAG.BIT.ro_poe1_flag; +} + +/** + * @brief Protect of POE2 flag. + * @param aptx The base address of APT module. + * @retval APT_PoeStatus: Status of POE2. + */ +static inline APT_PoeStatus DCL_APT_GetPoe2Status(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + return aptx->APT_POE_FLAG.BIT.ro_poe2_flag; +} + +/** + * @brief PWMA high-resolution output of PWMA. This register can be configured + * only when `otp_apt_hr_enable` is 1. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_EnableHRPWMA(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->HRPWMA_EN.reg = BASE_CFG_ENABLE; +} + + +/** + * @brief Disable PWMA high-resolution output + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_DisableHRPWMA(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->HRPWMA_EN.reg = BASE_CFG_DISABLE; +} + +/** + * @brief PWMB high-resolution output of PWMA. This register can be configured + * only when `otp_apt_hr_enable` is 1. + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_EnableHRPWMB(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->HRPWMB_EN.reg = BASE_CFG_ENABLE; +} + +/** + * @brief Disable PWMB high-resolution output + * @param aptx APT register base address. + * @retval None. + */ +static inline void DCL_APT_DisableHRPWMB(APT_RegStruct *aptx) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + aptx->HRPWMB_EN.reg = BASE_CFG_DISABLE; +} + +/** + * @brief Buffer Load Setting of high-resolution PWM. + * @param aptx APT register base address. + * @param pwmEdge Edge of High resolution PWM + * @retval None. + */ +static inline void DCL_APT_HRPWMBufferLoad(APT_RegStruct *aptx, APT_HrPwmEdge pwmEdge) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(pwmEdge >= APT_CHANNEL_A_RISE); + APT_PARAM_CHECK_NO_RET(pwmEdge <= APT_CHANNEL_B_FALL); + if (pwmEdge == APT_CHANNEL_A_RISE) { /* Channel Judgment */ + aptx->HRPWM_BUF_EN.reg |= 1; + } else { + aptx->HRPWM_BUF_EN.reg |= (1 << (pwmEdge * HR_EDGE_BUFFER_SHIFT)); /* Enable Bufferload of channel edge. */ + } +} + +/** + * @brief Global Load Setting of high-resolution PWM. + * @param aptx APT register base address. + * @param pwmEdge Edge of High resolution PWM + * @retval None. + */ +static inline void DCL_APT_HRPWMGlobalLoad(APT_RegStruct *aptx, APT_HrPwmEdge pwmEdge) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(pwmEdge >= APT_CHANNEL_A_RISE); + APT_PARAM_CHECK_NO_RET(pwmEdge <= APT_CHANNEL_B_FALL); + aptx->HRPWM_BUF_EN.reg |= (1 << (pwmEdge * HR_EDGE_BUFFER_SHIFT + 1)); +} + +/** + * @brief Depend Load Setting of high-resolution PWM. + * @param aptx APT register base address. + * @param pwmEdge Edge of High resolution PWM + * @param loadEvent High resolution PWM edge load Event. + * Valid values for depend load are: + * APT_CNT_LOAD_EVENT_ZERO - Depend buffer load when counter equals zero. + * APT_CNT_LOAD_EVENT_PERIOD - Depend buffer load when counter equals period. + * APT_CNT_LOAD_EVENT_A1 - Depend buffer load when COMB A1 is effective. + * APT_CNT_LOAD_EVENT_B1 - Depend buffer load when COMB B1 is effective. + * APT_CNT_LOAD_EVENT_SYNC - Depend buffer load when counter sync is effective. + * @retval None. + */ +static inline void DCL_APT_HRPWMDependLoad(APT_RegStruct *aptx, APT_HrPwmEdge pwmEdge, unsigned int loadEvent) +{ + APT_ASSERT_PARAM(IsAPTInstance(aptx)); + APT_PARAM_CHECK_NO_RET(pwmEdge >= APT_CHANNEL_A_RISE); /* Channel Edge Range Check */ + APT_PARAM_CHECK_NO_RET(pwmEdge <= APT_CHANNEL_B_FALL); + aptx->HRPWM_LOAD.reg &= (~(HRPWM_LOAD_EVNETS << (pwmEdge * HRPWM_LOAD_SHIFT))); /* Loading event enable. */ + aptx->HRPWM_LOAD.reg |= loadEvent << (pwmEdge * HRPWM_LOAD_SHIFT); +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#define EM_OUT_EVT_FILTER_EN 0x0f +#define EM_CMB_MODE_OFFSET 16 +#define EM_CMB_MODE_INTERVAL 4 +#define EM_CMB_SRC_SEL_INTERVAL 4 +#define EM_OR_INTERVAL 16 +#define EM_CMB_EVT_NUM 4 +#define EM_COMBINE_A1_SRC_ENABLE_ALL 0xF +/** + * @defgroup APT APT + * @brief APT module. + * @{ + */ + + +/** + * @defgroup APT_Common APT Common + * @brief APT common external module. + * @{ + */ + +/** + * @defgroup APT_Handle_Definition APT Handle Definition + * @{ + */ + +/* + Basic type AHBL ALBH AHBH ALBL + ___ __ __ ___ __ __ + ChannelA __| |__ |___| __| |__ |___| + __ __ ___ ___ __ __ + ChannelB |___| __| |__ __| |__ |___| +*/ +/** + * @brief Basic PWM waveform type. + * @details waveform type: + * + APT_PWM_BASIC_A_HIGH_B_LOW -- Basic PWM waveform type 1. + * + APT_PWM_BASIC_A_LOW_B_HIGH -- Basic PWM waveform type 2. + * + APT_PWM_BASIC_A_HIGH_B_HIGH -- Basic PWM waveform type 3. + * + APT_PWM_BASIC_A_LOW_B_LOW -- Basic PWM waveform type 4. + */ +typedef enum { + APT_PWM_BASIC_A_HIGH_B_LOW = 0x00000000U, + APT_PWM_BASIC_A_LOW_B_HIGH = 0x00000001U, + APT_PWM_BASIC_A_HIGH_B_HIGH = 0x00000002U, + APT_PWM_BASIC_A_LOW_B_LOW = 0x00000003U, +} APT_PWMBasicType; + +/** + * @brief The actual outputs of PWM channelA and channelB. + * @details Output: + * + APT_PWM_OUT_BASIC_TYPE = 0x00000000U -- PWM channel output the waveform according to basic PWM type. + * + APT_PWM_OUT_ALWAYS_LOW = 0x00000001U -- PWM channel output low level. + * + APT_PWM_OUT_ALWAYS_HIGH = 0x00000002U -- PWM channel output high level. + */ +typedef enum { + APT_PWM_OUT_BASIC_TYPE = 0x00000000U, + APT_PWM_OUT_ALWAYS_LOW = 0x00000001U, + APT_PWM_OUT_ALWAYS_HIGH = 0x00000002U, +} APT_PWMChannelOutType; + +/** + * @brief PWM waveform configuration handle of APT module. + */ +typedef struct { + APT_PWMBasicType basicType; /**< Basic PWM waveform type. */ + APT_PWMChannelOutType chAOutType; /**< Actual output of PWM channelA. */ + APT_PWMChannelOutType chBOutType; /**< Actual output of PWM channelB. */ + APT_CountMode cntMode; /**< Count mode of APT time-base counter. */ + unsigned short dividerFactor; /**< Divider factor. The range is 0~4095. */ + unsigned short timerPeriod; /**< Count period of APT time-base timer. */ + unsigned short divInitVal; /**< Initial value of divider. */ + unsigned short cntInitVal; /**< Initial value of time-base counter */ + unsigned short cntCmpLeftEdge; /**< Count compare point of the left edge of PWM waveform. */ + unsigned short cntCmpRightEdge; /**< Count compare point of the right edge of PWM waveform. */ + APT_BufferLoadMode cntCmpLoadMode; /**< Buffer load mode of PWM waveform count compare value. */ + unsigned int cntCmpLoadEvt; /**< Buffer load event of PWM waveform count compare value. */ + unsigned short deadBandCnt; /**< Count value of dead-band counter. In units of APT clock. */ +} APT_PWMWaveForm; + +/** + * @brief ADC trigger configuration handle of APT module. + */ +typedef struct { + bool trgEnSOCA; /**< Enable of ADC trigger source SOCA. */ + APT_ADCTriggerSource trgSrcSOCA; /**< Source of ADC trigger source SOCA. */ + unsigned short trgScaleSOCA; /**< Scale of ADC trigger source SOCA. */ + unsigned short cntCmpSOCA; /**< Count compare point of ADC trigger source SOCA when using CMPA */ + bool trgEnSOCB; /**< Enable of ADC trigger source SOCB. */ + APT_ADCTriggerSource trgSrcSOCB; /**< Source of ADC trigger source SOCB. */ + unsigned short trgScaleSOCB; /**< Scale of ADC trigger source SOCB. */ + unsigned short cntCmpSOCB; /**< Count compare point of ADC trigger source SOCB when using CMPB */ + APT_BufferLoadMode cntCmpLoadMode; /**< Buffer load mode of ADC trigger count compare value. */ + unsigned int cntCmpLoadEvt; /**< Buffer load event of ADC trigger count compare value. */ +} APT_ADCTrigger; + +/** + * @brief Timer interrupt configuration handle of APT module. + */ +typedef struct { + bool tmrInterruptEn; /**< Enable of APT module timer interrupt. */ + APT_TimerInterruptSrc tmrInterruptSrc; /**< Source of APT module timer interrupt. */ + unsigned short tmrInterruptScale; /**< Scale of APT module timer interrupt. */ +} APT_TimerInterrupt; + +/** + * @brief Output control protection configuration handle of APT module. + */ +typedef struct { + bool ocEventEn; /**< Enable of output control event. */ + APT_OutCtrlEvent ocEvent; /**< Output control event. Limited to IO events or system events. */ + APT_OutCtrlMode ocEventMode; /**< Output control protection mode. */ + APT_CBCClearMode cbcClrMode; /**< Event clear mode when using cycle-by-cycle mode. */ + APT_EMEventPolarity evtPolarity; /**< Event effective polarity. */ + APT_OutCtrlAction ocAction; /**< Output control protection action. */ + APT_EmulationMode emMode; /**< emulation mode */ + bool ocEvtInterruptEn; /**< Enable of output control event interrupt. */ +} APT_OutCtrlProtect; + +/** + * @brief Source event of event magnagement. + */ +typedef enum { + APT_EM_ORIGINAL_SRC_POE0 = 0x00000001U, + APT_EM_ORIGINAL_SRC_POE1 = 0x00000002U, + APT_EM_ORIGINAL_SRC_POE2 = 0x00000004U, + APT_EM_ORIGINAL_SRC_ACMP0 = 0x00000008U, + APT_EM_ORIGINAL_SRC_ACMP1 = 0x00000010U, + APT_EM_ORIGINAL_SRC_ACMP2 = 0x00000020U, + APT_EM_ORIGINAL_SRC_EVTMP4 = 0x00000040U, + APT_EM_ORIGINAL_SRC_EVTMP5 = 0x00000080U, + APT_EM_ORIGINAL_SRC_EVTMP6 = 0x00000100U, +} APT_EMOriginalEvtSrc; + +/** + * @brief Filter mask bit. + */ +typedef enum { + APT_EM_POE0_INVERT_BIT = 0x00000001U, + APT_EM_POE1_INVERT_BIT = 0x00000002U, + APT_EM_POE2_INVERT_BIT = 0x00000004U, + APT_EM_ACMP0_INVERT_BIT = 0x00000008U, + APT_EM_ACMP1_INVERT_BIT = 0x00000010U, + APT_EM_ACMP2_INVERT_BIT = 0x00000020U, + APT_EM_EVTMP4_INVERT_BIT = 0x00000040U, + APT_EM_EVTMP5_INVERT_BIT = 0x00000080U, + APT_EM_EVTMP6_INVERT_BIT = 0x00000100U, +} APT_EMPolarityMskBit; + +/** + * @brief System protect event; + */ +typedef enum { + APT_SYS_EVT_DEBUG = 0x00000010U, + APT_SYS_EVT_CLK = 0x00000020U, + APT_SYS_EVT_MEM = 0x00000040U, +} APT_SysOcEvent; + +/** + * @brief Output control protection configuration handle of APT module. + */ +typedef struct { + bool ocEventEnEx; /**< Oc event enable */ + APT_OutCtrlMode ocEventModeEx; /**< Output control protection mode. */ + APT_CBCClearMode cbcClrModeEx; /**< Event clear mode when using cycle-by-cycle mode. */ + APT_OutCtrlAction ocActionEx; /**< Output control protection channel A action. */ + APT_OutCtrlAction ocActionBEx; /**< Output control protection channel B action. */ + bool ocEvtInterruptEnEx; /**< Enable of output control event interrupt. */ + APT_SysOcEvent ocSysEvent; /**< System protect event */ + APT_EMOriginalEvtSrc originalEvtEx; /**< Event management's event source */ + APT_EMPolarityMskBit evtPolarityMaskEx; /**< Event effective polarity. */ + unsigned char filterCycleNumEx; /**< input source event filter */ +} APT_OutCtrlProtectEx; + +/** + * @brief struct of EM conbine event + */ +typedef struct { + APT_EMCombineEvtSrc emEvtSrc; /**< Combine event selection */ + APT_EMCombineEvtMode emEvtCombineMode; /**< Event combine mode */ + APT_EMEventPolarity emEvtPolar; /**< Event source polarity */ + unsigned int emEvtOrEnBits; /**< Event logic or enable bits */ +} APT_CombineEvt; + +/** + * @brief Shield window and capture configurations + */ +typedef struct { + bool wdEnable; /**< Shield windows enable bit */ + bool emCapEnable; /**< Enable EM captrue functions */ + APT_EMCombineEvent eventSel; /**< Window source event selection */ + APT_MaskWinResetMode wdStartAndCapClr; /**< Window's offset start count and EM capture clear condition */ + unsigned short wdOffset; /**< Window's offset value */ + unsigned short wdWidth; /**< Window's width value */ + APT_MaskWinPolarity wdPolar; /**< Window's polarity */ +} APT_WdAndCap; + + +/** + * @brief Valley switch configurations + */ +typedef struct { + bool vsEnable; /**< Valley switch enable */ + APT_EMEdgeFilterMode vsFilerEdgeSel; /**< Filter edge selection */ + unsigned char vsFilterCnt; /**< Filter edge count */ + APT_ValleyCapRstType vsClrType; /**< Clear type */ + APT_ValleyCountEdge vsCapEdgeSel; /**< Capture edge selection */ + unsigned char vsCapStartEdge; /**< Capture start edge */ + unsigned char vsCapEndEdge; /**< Capture end edge */ + APT_ValleyDelayMode vsCapDelayMode; /**< Capture delay mode */ + unsigned short vsCapSoftDelay; /**< Capture software calibrate value */ +} APT_ValleySw; + +/** + * @brief Event management handle of APT module + */ +typedef struct { + bool emEnable; /**< Enable bit of event management */ + APT_CombineEvt emEvt[EM_CMB_EVT_NUM]; /**< Combine events configuration */ + APT_WdAndCap emWdAndCap; /**< Shield windows and capture configuration */ + APT_ValleySw emValleySw; /**< Valley switch configuration */ +} APT_EventManage; + +/** + * @brief Synchronization handle of slave APT module. + */ +typedef struct { + unsigned short divPhase; /**< Divider phase when receiving APT synchronization pulse. */ + unsigned short cntPhase; /**< Counter phase when receiving APT synchronization pulse. */ + APT_SyncCountMode syncCntMode; /**< Count mode when receiving APT synchronization pulse. */ + APT_SyncInSrc syncInSrc; /**< Sync-in source of APT module */ + unsigned short cntrSyncSrc; + /**< Sync-in source of time-base counter synchronization + A logical OR of valid values can be passed as the cntrSyncSrc parameter. + Valid values for cntrSyncSrc are: + APT_CNTR_SYNC_SRC_COMBINE_EVENT_A1 - Enable combine event A1 as the counter synchronization source. + APT_CNTR_SYNC_SRC_COMBINE_EVENT_B1 - Enable combine event B1 as the counter synchronization source. + APT_CNTR_SYNC_SRC_SYNCIN - Enable Sync-In source as the counter synchronization source. */ +} APT_SlaveSyncIn; + +/** + * @brief Definition of callback function type. + */ +typedef void (* APT_CallbackType)(void *aptHandle); + +/** + * @brief Definition of callback function type. + */ +typedef struct { + void (* EvtInterruptCallBack)(void *handle); + void (* TmrInterruptCallBack)(void *handle); +} APT_UserCallBack; + +/** + * @brief Definition of callback function ID. + */ +typedef enum { + APT_TIMER_INTERRUPT = 0x00000000U, + APT_EVENT_INTERRUPT = 0x00000001U, +} APT_InterruputType; +#endif /* McuMagicTag_APT_IP_H */ diff --git a/src/drivers/apt/apt_v2/src/apt.c b/src/drivers/apt/apt_v2/src/apt.c new file mode 100644 index 0000000000000000000000000000000000000000..6eb3c2fab7a371cad3ba33382fe3280fb9858007 --- /dev/null +++ b/src/drivers/apt/apt_v2/src/apt.c @@ -0,0 +1,1461 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file apt.c + * @author MCU Driver Team + * @brief APT module driver. + * @details This file provides firmware functions to manage the following functionalities of APT module. + * + Initialization and de-initialization functions + * + APT module synchronization functions. + * + PWM waveform configuration and ADC trigger time configuration functions. + * + Interrupt callback function and user registration function + */ + +#include "apt.h" +#include "crg.h" +#define MAX_DUTY 100 +#define ALL_EVT_INT_FLAGS 0xf770000U +#define RERF 4 +/** + * @brief The parameters of PWM waveform. + */ +typedef struct { + APT_PWMAction leftEdgeActA; /**< Action on the left edge of PWM channel A. */ + APT_PWMAction rightEdgeActA; /**< Action on the right edge of PWM channel A. */ + APT_PWMAction leftEdgeActB; /**< Action on the left edge of PWM channel B. */ + APT_PWMAction rightEdgeActB; /**< Action on the right edge of PWM channel B. */ + APT_REDInput redInput; /**< Input source of Dead-Band rising edge delay counter. */ + APT_REDOutMode redOutMode; /**< Output mode of Dead-Band rising edge delay counter. */ + APT_FEDInput fedInput; /**< Input source of Dead-Band falling edge delay counter. */ + APT_FEDOutMode fedOutMode; /**< Output mode of Dead-Band falling edge delay counter. */ +} APT_WaveformPara; + +/** + * @brief Initialize the time-base counter of APT module. + * @param aptHandle APT module handle. + * @retval None. + */ +static void APT_TimeBaseInit(APT_Handle *aptHandle) +{ + aptHandle->baseAddress->TC_MODE.BIT.rg_cnt_mode = aptHandle->waveform.cntMode; + aptHandle->baseAddress->TC_MODE.BIT.rg_div_fac = aptHandle->waveform.dividerFactor; + /* Disable buffer mode of TC_PRD */ + aptHandle->baseAddress->TC_BUF_EN.reg &= (~(0b11 << 0)); + aptHandle->baseAddress->TC_PRD.BIT.rg_cnt_prd = aptHandle->waveform.timerPeriod; + /* Set the override value of divier and timebase counter */ + aptHandle->baseAddress->TC_OVRID.BIT.rg_cnt_ovrid = aptHandle->waveform.cntInitVal; + aptHandle->baseAddress->TC_OVRID.BIT.rg_cnt_ovrid_en = 1; +} + +/** + * @brief Initialize the count compare points for PWM waveform generation. + * @param aptHandle APT module handle. + * @retval None. + */ +static void APT_SetPWMCompareVal(APT_Handle *aptHandle) +{ + /* Configure the compare point along the left and right edges of PWM waveform */ + TC_REFC_REG tmpC; + TC_REFD_REG tmpD; + /* Set the value of the active register of CMPC and CMPD */ + tmpC = aptHandle->baseAddress->TC_REFC; + tmpC.BIT.rg_cnt_refc = aptHandle->waveform.cntCmpLeftEdge; + aptHandle->baseAddress->TC_REFC = tmpC; + tmpD = aptHandle->baseAddress->TC_REFD; + tmpD.BIT.rg_cnt_refd = aptHandle->waveform.cntCmpRightEdge; + aptHandle->baseAddress->TC_REFD = tmpD; + /* Set the buffer load mode of CMPC and CMPD */ + if (aptHandle->waveform.cntCmpLoadMode == APT_BUFFER_DISABLE) { + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refc_buf_en = 0; + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refd_buf_en = 0; + } else { + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refc_buf_en = 1; + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refd_buf_en = 1; + unsigned int gldLdEn = (aptHandle->waveform.cntCmpLoadMode == APT_BUFFER_GLOBAL_LOAD) ? 1 : 0; + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refc_gld_en = gldLdEn; + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refd_gld_en = gldLdEn; + /* Set buffer load event */ + unsigned int refBufField = 8; /* reference buffer field */ + aptHandle->baseAddress->TC_REF_LOAD.reg &= (~(0x1F << (APT_COMPARE_REFERENCE_C * refBufField))); + aptHandle->baseAddress->TC_REF_LOAD.reg &= (~(0x1F << (APT_COMPARE_REFERENCE_D * refBufField))); + aptHandle->baseAddress->TC_REF_LOAD.reg |= + (aptHandle->waveform.cntCmpLoadEvt << (APT_COMPARE_REFERENCE_C * refBufField)); + aptHandle->baseAddress->TC_REF_LOAD.reg |= + (aptHandle->waveform.cntCmpLoadEvt << (APT_COMPARE_REFERENCE_D * refBufField)); + /* Set the value of the buffer register of CMPC and CMPD */ + tmpC = aptHandle->baseAddress->TC_REFC; /* read register */ + tmpC.BIT.rg_cnt_refc = aptHandle->waveform.cntCmpLeftEdge; + aptHandle->baseAddress->TC_REFC = tmpC; /* write back changed data back to register */ + tmpD = aptHandle->baseAddress->TC_REFD; /* read register */ + tmpD.BIT.rg_cnt_refd = aptHandle->waveform.cntCmpRightEdge; + aptHandle->baseAddress->TC_REFD = tmpD; /* write back changed data back to register */ + } +} + +/** + * @brief Configure the basic PWM A waveform output according to the waveform parameters. + * @param aptHandle APT module handle. + * @param wavePara PWM waveform parameter. + * @retval None. + */ +static void APT_SetOutputABasicType(APT_Handle *aptHandle, const APT_WaveformPara *wavePara) +{ + switch (aptHandle->waveform.cntMode) { + case APT_COUNT_MODE_UP: + aptHandle->baseAddress->PG_ACT_A.BIT.rg_pga_act_refc_inc = wavePara->leftEdgeActA; + aptHandle->baseAddress->PG_ACT_A.BIT.rg_pga_act_refd_inc = wavePara->rightEdgeActA; + break; + case APT_COUNT_MODE_DOWN: + aptHandle->baseAddress->PG_ACT_A.BIT.rg_pga_act_refc_dec = wavePara->rightEdgeActA; + aptHandle->baseAddress->PG_ACT_A.BIT.rg_pga_act_refd_dec = wavePara->leftEdgeActA; + break; + case APT_COUNT_MODE_UP_DOWN: + aptHandle->baseAddress->PG_ACT_A.BIT.rg_pga_act_refc_inc = wavePara->leftEdgeActA; + aptHandle->baseAddress->PG_ACT_A.BIT.rg_pga_act_refd_dec = wavePara->rightEdgeActA; + break; + default: + break; + } + return; +} + +/** + * @brief Configure the basic PWM B waveform output according to the waveform parameters. + * @param aptHandle APT module handle. + * @param wavePara PWM waveform parameter. + * @retval None. + */ +static void APT_SetOutputBBasicType(APT_Handle *aptHandle, const APT_WaveformPara *wavePara) +{ + switch (aptHandle->waveform.cntMode) { + case APT_COUNT_MODE_UP: + aptHandle->baseAddress->PG_ACT_B.BIT.rg_pgb_act_refc_inc = wavePara->leftEdgeActB; + aptHandle->baseAddress->PG_ACT_B.BIT.rg_pgb_act_refd_inc = wavePara->rightEdgeActB; + break; + case APT_COUNT_MODE_DOWN: + aptHandle->baseAddress->PG_ACT_B.BIT.rg_pgb_act_refc_dec = wavePara->rightEdgeActB; + aptHandle->baseAddress->PG_ACT_B.BIT.rg_pgb_act_refd_dec = wavePara->leftEdgeActB; + break; + case APT_COUNT_MODE_UP_DOWN: + aptHandle->baseAddress->PG_ACT_B.BIT.rg_pgb_act_refc_inc = wavePara->leftEdgeActB; + aptHandle->baseAddress->PG_ACT_B.BIT.rg_pgb_act_refd_dec = wavePara->rightEdgeActB; + break; + default: + break; + } + return; +} + +/** + * @brief Configure the basic PWM waveform output according to the waveform parameters. + * @param aptHandle APT module handle. + * @param wavePara PWM waveform parameter. + * @retval None. + */ +static void APT_SetPWMBasicType(APT_Handle *aptHandle, const APT_WaveformPara *wavePara) +{ + /* Configure PWM waveform of PWM channel A */ + if (aptHandle->waveform.chAOutType == APT_PWM_OUT_BASIC_TYPE) { + APT_SetOutputABasicType(aptHandle, wavePara); + } + /* Configure PWM waveform of PWM channel B */ + if (aptHandle->waveform.chBOutType == APT_PWM_OUT_BASIC_TYPE) { + APT_SetOutputBBasicType(aptHandle, wavePara); + } + /* Configure dead band of PWM channel A and channel B */ + if (aptHandle->waveform.chAOutType == APT_PWM_OUT_BASIC_TYPE && + aptHandle->waveform.chBOutType == APT_PWM_OUT_BASIC_TYPE) { + aptHandle->baseAddress->DG_CFG.BIT.rg_dg_red_isel = wavePara->redInput; + aptHandle->baseAddress->DG_CFG.BIT.rg_dg_red_osel = wavePara->redOutMode; + aptHandle->baseAddress->DG_RED.BIT.rg_dg_red = aptHandle->waveform.deadBandCnt; + aptHandle->baseAddress->DG_CFG.BIT.rg_dg_fed_isel = wavePara->fedInput; + aptHandle->baseAddress->DG_CFG.BIT.rg_dg_fed_osel = wavePara->fedOutMode; + aptHandle->baseAddress->DG_FED.BIT.rg_dg_fed = aptHandle->waveform.deadBandCnt; + } +} + +/** + * @brief Set the actual outputs of PWM channelA and channelB when basic PWM waveform type is not used. + * @param aptHandle APT module handle. + * @retval None. + */ +static void APT_SetContWaveform(APT_Handle *aptHandle) +{ + if (aptHandle->waveform.chAOutType != APT_PWM_OUT_BASIC_TYPE) { + unsigned int contActA = (aptHandle->waveform.chAOutType == APT_PWM_OUT_ALWAYS_LOW) ? 0b01 : 0b10; + aptHandle->baseAddress->PG_ACT_A.BIT.rg_pga_act_zro = contActA; + } + if (aptHandle->waveform.chBOutType != APT_PWM_OUT_BASIC_TYPE) { + unsigned int contActB = (aptHandle->waveform.chBOutType == APT_PWM_OUT_ALWAYS_LOW) ? 0b01 : 0b10; + aptHandle->baseAddress->PG_ACT_B.BIT.rg_pgb_act_zro = contActB; + } +} + +/** + * @brief Initialize the PWM waveform parameters according to the selected PWM basic type. + * @param aptHandle APT module handle. + * @retval None. + */ +static void APT_SetPWMWaveform(APT_Handle *aptHandle) +{ + APT_SetContWaveform(aptHandle); + /* Configure the basic type of PWM waveform */ + APT_WaveformPara wavePara = {0, 0, 0, 0, 0, 0, 0, 0}; + switch (aptHandle->waveform.basicType) { + case APT_PWM_BASIC_A_HIGH_B_LOW: + wavePara.leftEdgeActA = APT_PWM_ACTION_HIGH; + wavePara.rightEdgeActA = APT_PWM_ACTION_LOW; + wavePara.leftEdgeActB = APT_PWM_ACTION_HIGH; + wavePara.rightEdgeActB = APT_PWM_ACTION_LOW; + wavePara.redInput = APT_DB_RED_INPUT_PWM_A; + wavePara.redOutMode = APT_DB_RED_OUTPUT_NOT_INVERT; + wavePara.fedInput = APT_DB_FED_INPUT_PWM_B; + wavePara.fedOutMode = APT_DB_FED_OUTPUT_INVERT; + break; + case APT_PWM_BASIC_A_LOW_B_HIGH: + wavePara.leftEdgeActA = APT_PWM_ACTION_LOW; + wavePara.rightEdgeActA = APT_PWM_ACTION_HIGH; + wavePara.leftEdgeActB = APT_PWM_ACTION_LOW; + wavePara.rightEdgeActB = APT_PWM_ACTION_HIGH; + wavePara.fedInput = APT_DB_FED_INPUT_PWM_A; + wavePara.fedOutMode = APT_DB_FED_OUTPUT_INVERT; + wavePara.redInput = APT_DB_RED_INPUT_PWM_B; + wavePara.redOutMode = APT_DB_RED_OUTPUT_NOT_INVERT; + break; + case APT_PWM_BASIC_A_HIGH_B_HIGH: + wavePara.leftEdgeActA = APT_PWM_ACTION_HIGH; + wavePara.rightEdgeActA = APT_PWM_ACTION_LOW; + wavePara.leftEdgeActB = APT_PWM_ACTION_HIGH; + wavePara.rightEdgeActB = APT_PWM_ACTION_LOW; + wavePara.redInput = APT_DB_RED_INPUT_PWM_A; + wavePara.redOutMode = APT_DB_RED_OUTPUT_NOT_INVERT; + wavePara.fedInput = APT_DB_FED_INPUT_PWM_B; + wavePara.fedOutMode = APT_DB_FED_OUTPUT_NOT_INVERT; + break; + case APT_PWM_BASIC_A_LOW_B_LOW: + wavePara.leftEdgeActA = APT_PWM_ACTION_LOW; + wavePara.rightEdgeActA = APT_PWM_ACTION_HIGH; + wavePara.leftEdgeActB = APT_PWM_ACTION_LOW; + wavePara.rightEdgeActB = APT_PWM_ACTION_HIGH; + wavePara.fedInput = APT_DB_FED_INPUT_PWM_A; + wavePara.fedOutMode = APT_DB_FED_OUTPUT_NOT_INVERT; + wavePara.redInput = APT_DB_RED_INPUT_PWM_B; + wavePara.redOutMode = APT_DB_RED_OUTPUT_NOT_INVERT; + break; + default: + break; + } + APT_SetPWMBasicType(aptHandle, &wavePara); +} + +/** + * @brief Initialize the count compare points for triggering ADC sampling. + * @param aptHandle APT module handle. + * @retval None. + */ +static void APT_SetADCTrgCompareVal(APT_Handle *aptHandle) +{ + /* Configure the count compare point for triggering SOCA and SOCB */ + TC_REFA_REG tmpA; + TC_REFB_REG tmpB; + /* Set the value of active register for CMPA and CMPB */ + tmpA = aptHandle->baseAddress->TC_REFA; /* read register */ + tmpA.BIT.rg_cnt_refa = aptHandle->adcTrg.cntCmpSOCA; + aptHandle->baseAddress->TC_REFA = tmpA; /* write back changed data to register */ + tmpB = aptHandle->baseAddress->TC_REFB; + tmpB.BIT.rg_cnt_refb = aptHandle->adcTrg.cntCmpSOCB; + aptHandle->baseAddress->TC_REFB = tmpB; + /* Set the buffer load mode of CMPA and CMPB */ + if (aptHandle->adcTrg.cntCmpLoadMode == APT_BUFFER_DISABLE) { + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refa_buf_en = 0; /* disable buffer function */ + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refb_buf_en = 0; /* disable buffer function */ + } else { + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refa_buf_en = 1; + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refb_buf_en = 1; + /* Set global buffer */ + unsigned int gldLdEn = (aptHandle->adcTrg.cntCmpLoadMode == APT_BUFFER_GLOBAL_LOAD) ? 1 : 0; + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refa_gld_en = gldLdEn; + aptHandle->baseAddress->TC_BUF_EN.BIT.rg_refb_gld_en = gldLdEn; + /* Set buffer load event */ + unsigned int refBufField = 8; + aptHandle->baseAddress->TC_REF_LOAD.reg &= (~(0x1F << (APT_COMPARE_REFERENCE_A * refBufField))); + aptHandle->baseAddress->TC_REF_LOAD.reg &= (~(0x1F << (APT_COMPARE_REFERENCE_B * refBufField))); + aptHandle->baseAddress->TC_REF_LOAD.reg |= + (aptHandle->adcTrg.cntCmpLoadEvt << (APT_COMPARE_REFERENCE_A * refBufField)); + aptHandle->baseAddress->TC_REF_LOAD.reg |= + (aptHandle->adcTrg.cntCmpLoadEvt << (APT_COMPARE_REFERENCE_B * refBufField)); + /* Set the value of buffer register for CMPA and CMPB */ + tmpA = aptHandle->baseAddress->TC_REFA; + tmpA.BIT.rg_cnt_refa = aptHandle->adcTrg.cntCmpSOCA; + aptHandle->baseAddress->TC_REFA = tmpA; + tmpB = aptHandle->baseAddress->TC_REFB; + tmpB.BIT.rg_cnt_refb = aptHandle->adcTrg.cntCmpSOCB; + aptHandle->baseAddress->TC_REFB = tmpB; + } +} + +/** + * @brief Initialize the ADC trigger function of APT module. + * @param aptHandle APT module handle + * @retval None. + */ +static void APT_SetADCTrigger(APT_Handle *aptHandle) +{ + APT_PARAM_CHECK_NO_RET(aptHandle->adcTrg.trgScaleSOCA <= ADC_CONVERSION_START_CNT_MAX); + APT_PARAM_CHECK_NO_RET(aptHandle->adcTrg.trgScaleSOCB <= ADC_CONVERSION_START_CNT_MAX); + /* Configure ADC trigger source SOCA */ + aptHandle->baseAddress->CS_TMR_SELA.BIT.rg_csa_tmr_sel = aptHandle->adcTrg.trgSrcSOCA; + aptHandle->baseAddress->CS_PRSCA_CFG.BIT.rg_csa_prsc_prd = aptHandle->adcTrg.trgScaleSOCA; + aptHandle->baseAddress->CS_TMR_SELA.BIT.rg_csa_en_cs = aptHandle->adcTrg.trgEnSOCA; + /* Configure ADC trigger source SOCB */ + aptHandle->baseAddress->CS_TMR_SELB.BIT.rg_csb_tmr_sel = aptHandle->adcTrg.trgSrcSOCB; + aptHandle->baseAddress->CS_PRSCB_CFG.BIT.rg_csb_prsc_prd = aptHandle->adcTrg.trgScaleSOCB; + aptHandle->baseAddress->CS_TMR_SELB.BIT.rg_csb_en_cs = aptHandle->adcTrg.trgEnSOCB; +} + +/** + * @brief Initialize the timer interrupt of APT module. + * @param aptHandle APT module handle. + * @retval None. + */ +static void APT_SetTimerInterrupt(APT_Handle *aptHandle) +{ + APT_PARAM_CHECK_NO_RET(aptHandle->tmrInterrupt.tmrInterruptScale <= TIMER_INTERRUPT_CNT_MAX); + aptHandle->baseAddress->INT_TMR_SEL.BIT.rg_int_tmr_sel = aptHandle->tmrInterrupt.tmrInterruptSrc; + aptHandle->baseAddress->INT_PRSC_CFG.BIT.rg_int_prsc_prd = aptHandle->tmrInterrupt.tmrInterruptScale; + aptHandle->baseAddress->INT_TMR_EN.BIT.rg_int_en_tmr = aptHandle->tmrInterrupt.tmrInterruptEn; +} + +/** + * @brief Initialize the APT hardware configuration based on the APT module handle. + * @param aptHandle APT module handle. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_PWMInit(APT_Handle *aptHandle) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.dividerFactor <= DIVIDER_FACTOR_MAX, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.divInitVal <= aptHandle->waveform.dividerFactor, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntInitVal < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpLeftEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpLeftEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpRightEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->waveform.cntCmpRightEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->adcTrg.cntCmpSOCA >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->adcTrg.cntCmpSOCA < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->adcTrg.cntCmpSOCB >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptHandle->adcTrg.cntCmpSOCB < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_TimeBaseInit(aptHandle); + APT_SetPWMCompareVal(aptHandle); + APT_SetPWMWaveform(aptHandle); + APT_SetADCTrgCompareVal(aptHandle); + APT_SetADCTrigger(aptHandle); + APT_SetTimerInterrupt(aptHandle); + return BASE_STATUS_OK; +} + +/** + * @brief Deinitialize the APT hardware configuration. + * @param aptHandle APT module handle. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_PWMDeInit(APT_Handle *aptHandle) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + /* CallBack function set null. */ + aptHandle->userCallBack.EvtInterruptCallBack = NULL; + aptHandle->userCallBack.TmrInterruptCallBack = NULL; + /* Reset the Interrupt register. */ + aptHandle->baseAddress->INT_TMR_EN.BIT.rg_int_en_tmr = BASE_CFG_UNSET; + aptHandle->baseAddress->CS_TMR_SELA.BIT.rg_csa_en_cs = BASE_CFG_UNSET; + aptHandle->baseAddress->CS_TMR_SELB.BIT.rg_csb_en_cs = BASE_CFG_UNSET; + /* Reset reference points of APT. */ + aptHandle->baseAddress->TC_BUF_EN.reg = 0x0; + aptHandle->baseAddress->TC_REFA.reg = 0x0; + aptHandle->baseAddress->TC_REFB.reg = 0x0; + aptHandle->baseAddress->TC_REFC.reg = 0x0; + aptHandle->baseAddress->TC_REFD.reg = 0x0; + aptHandle->baseAddress->TC_PRD.BIT.rg_cnt_prd = 0x2710; /* 0x2710: default value */ + aptHandle->baseAddress->PG_ACT_A.reg = 0x0; /* Clear action register. */ + aptHandle->baseAddress->PG_ACT_B.reg = 0x0; + return BASE_STATUS_OK; +} + +/** + * @brief Configure output control protection mode. + * @param aptHandle APT module handle. + * @param protect Output control protection event handle. + * @retval None. + */ +static void APT_SetOutCtrlProtectMode(APT_Handle *aptHandle, APT_OutCtrlProtect *protect) +{ + /* Set output control protect mode */ + unsigned int ocModeOffset = 16; + unsigned int cbcClrOffsetPrd = 16; + if (protect->ocEventMode == APT_OUT_CTRL_ONE_SHOT) { + aptHandle->baseAddress->OC_MODE.reg &= (~(protect->ocEvent << ocModeOffset)); + } else if (protect->ocEventMode == APT_OUT_CTRL_CYCLE_BY_CYCLE) { + aptHandle->baseAddress->OC_MODE.reg |= (protect->ocEvent << ocModeOffset); + if ((protect->cbcClrMode & APT_CLEAR_CBC_ON_CNTR_ZERO) ==APT_CLEAR_CBC_ON_CNTR_ZERO) { + aptHandle->baseAddress->OC_PRD_CLR.reg |= protect->ocEvent; + } + if ((protect->cbcClrMode & APT_CLEAR_CBC_ON_CNTR_PERIOD) == APT_CLEAR_CBC_ON_CNTR_PERIOD) { + aptHandle->baseAddress->OC_PRD_CLR.reg |= (protect->ocEvent << cbcClrOffsetPrd); + } + } +} + +/** + * @brief Output control protection action selection. + * @param aptHandle APT module handle. + * @param ocAction Out control action. + * @param protect Output control protection event handle. + * @param outCtrlEvent output settings. + * @retval None. + */ +static void APT_SetOutCtrlAction(APT_Handle *aptHandle, APT_OutCtrlAction ocAction, APT_OutCtrlEventDir outCtrlEvent) +{ + /* Set output control action when counting up */ + aptHandle->baseAddress->OC_ACT_A.reg &= (~(0b111 << outCtrlEvent)); + aptHandle->baseAddress->OC_ACT_A.reg |= (ocAction << outCtrlEvent); + aptHandle->baseAddress->OC_ACT_B.reg &= (~(0b111 << outCtrlEvent)); + aptHandle->baseAddress->OC_ACT_B.reg |= (ocAction << outCtrlEvent); +} + +/** + * @brief Indicates the configuration of protection actions for different channels(PWMA and PWMB output action). + * @param aptHandle APT module handle. @ref APT_Handle + * @param ocActionA PWMA output action control. @ref APT_OutCtrlAction + * @param ocActionB PWMB output action control. @ref APT_OutCtrlAction + * @param outCtrlEvent Action configuration in different counting directions. @ref APT_OutCtrlEventDir + * @retval None. + */ +static void APT_SetOutCtrlActionEx(APT_Handle *aptHandle, APT_OutCtrlAction ocActionA, APT_OutCtrlAction ocActionB, + APT_OutCtrlEventDir outCtrlEvent) +{ + /* Set output control action when counting up */ + aptHandle->baseAddress->OC_ACT_A.reg &= (~(0b111 << outCtrlEvent)); + aptHandle->baseAddress->OC_ACT_A.reg |= (ocActionA << outCtrlEvent); + aptHandle->baseAddress->OC_ACT_B.reg &= (~(0b111 << outCtrlEvent)); + aptHandle->baseAddress->OC_ACT_B.reg |= (ocActionB << outCtrlEvent); +} + +/** + * @brief Change APT's OC Event to EM Event. + * @param ocEvent OC Event. + * @param emEvent EM Event. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType APT_ChangeOcEventToEmEvent(APT_OutCtrlEvent ocEvent, APT_EMIOSysEvent *emEvent) +{ + APT_ASSERT_PARAM(emEvent != NULL); + switch (ocEvent) { + case APT_OC_GPIO_EVENT_1: + *emEvent = APT_EM_GPIO_EVENT_1; + break; + case APT_OC_GPIO_EVENT_2: + *emEvent = APT_EM_GPIO_EVENT_2; + break; + case APT_OC_GPIO_EVENT_3: + *emEvent = APT_EM_GPIO_EVENT_3; + break; + case APT_OC_SYSTEM_EVENT_1: + *emEvent = APT_EM_SYSTEM_EVENT_1; + break; + case APT_OC_SYSTEM_EVENT_2: + *emEvent = APT_EM_SYSTEM_EVENT_2; + break; + case APT_OC_SYSTEM_EVENT_3: + *emEvent = APT_EM_SYSTEM_EVENT_3; + break; + default: + return BASE_STATUS_ERROR; + } + + return BASE_STATUS_OK; +} + +/** + * @brief Set combine event out control action. + * @param aptHandle APT module handle. + * @param protect Output control protection event handle. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType APT_SetCombieEvtOutCtrl(APT_Handle *aptHandle, APT_OutCtrlProtect *protect) +{ + switch (protect->ocEvent) { + case APT_OC_COMBINE_EVENT_A1: + APT_SetOutCtrlAction(aptHandle, protect->ocAction, APT_OC_EVT_COMBINE_EVENT_A1_UP); + APT_SetOutCtrlAction(aptHandle, protect->ocAction, APT_OC_EVT_COMBINE_EVENT_A1_DOWN); + break; + case APT_OC_COMBINE_EVENT_A2: + APT_SetOutCtrlAction(aptHandle, protect->ocAction, APT_OC_EVT_COMBINE_EVENT_A2_UP); + APT_SetOutCtrlAction(aptHandle, protect->ocAction, APT_OC_EVT_COMBINE_EVENT_A2_DOWN); + break; + case APT_OC_COMBINE_EVENT_B1: + APT_SetOutCtrlAction(aptHandle, protect->ocAction, APT_OC_EVT_COMBINE_EVENT_B1_UP); + APT_SetOutCtrlAction(aptHandle, protect->ocAction, APT_OC_EVT_COMBINE_EVENT_B1_DOWN); + break; + case APT_OC_COMBINE_EVENT_B2: + APT_SetOutCtrlAction(aptHandle, protect->ocAction, APT_OC_EVT_COMBINE_EVENT_B2_UP); + APT_SetOutCtrlAction(aptHandle, protect->ocAction, APT_OC_EVT_COMBINE_EVENT_B2_DOWN); + break; + default: + return BASE_STATUS_ERROR; + } + + return BASE_STATUS_OK; +} + +/** + * @brief Setting emulation mode of APT module. + * @param aptHandle APT module handle. + * @param protect Output control protection event handle. + * @retval None. + */ +static void APT_OcSetEmulation(APT_Handle *aptHandle, APT_OutCtrlProtect *protect) +{ + aptHandle->baseAddress->TC_MODE.BIT.rg_emu_stop = protect->emMode; + if (protect->emMode > APT_EMULATION_NO_STOP) { + aptHandle->baseAddress->OC_MODE.reg |= APT_OC_SYSTEM_EVENT_1; + } +} + +/** + * @brief Initialize the output control protection event of APT module. + * @param aptHandle APT module handle. + * @param protect Output control protection event handle. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_ProtectInit(APT_Handle *aptHandle, APT_OutCtrlProtect *protect) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(protect != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + APT_PARAM_CHECK_WITH_RET(protect->ocEvent >= APT_OC_GPIO_EVENT_1, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(protect->ocEvent <= APT_OC_COMBINE_EVENT_B2, BASE_STATUS_ERROR); + APT_SetOutCtrlProtectMode(aptHandle, protect); + /* Emultion settings */ + APT_OcSetEmulation(aptHandle, protect); + + if ((protect->ocEvent >= APT_OC_COMBINE_EVENT_A1) && (protect->ocEvent <= APT_OC_COMBINE_EVENT_B2)) { + if (APT_SetCombieEvtOutCtrl(aptHandle, protect) == BASE_STATUS_ERROR) { + return BASE_STATUS_ERROR; + } + } else { + /* Set IO event polarity */ + APT_EMIOSysEvent ioSysEvt; + if (APT_ChangeOcEventToEmEvent(protect->ocEvent, &ioSysEvt) == BASE_STATUS_OK) { + aptHandle->baseAddress->EM_EVTIO_PSEL.reg &= (~(0b11 << ioSysEvt)); + aptHandle->baseAddress->EM_EVTIO_PSEL.reg |= (protect->evtPolarity << ioSysEvt); + } + /* Set output control action when counting up */ + APT_SetOutCtrlAction(aptHandle, protect->ocAction, APT_OC_EVT_GPIO_OR_SYSTEM_UP); + /* Set output control action when counting down */ + APT_SetOutCtrlAction(aptHandle, protect->ocAction, APT_OC_EVT_GPIO_OR_SYSTEM_DOWN); + } + if (protect->ocEventEn == BASE_CFG_ENABLE) { + aptHandle->baseAddress->OC_MODE.reg |= (protect->ocEvent); + } else { + aptHandle->baseAddress->OC_MODE.reg &= (~(protect->ocEvent)); + } + if (protect->ocEvtInterruptEn == BASE_CFG_ENABLE) { + aptHandle->baseAddress->INT_EVT_EN.reg |= (protect->ocEvent); + } else { + aptHandle->baseAddress->INT_EVT_EN.reg &= (~(protect->ocEvent)); + } + return BASE_STATUS_OK; +} + +/** + * @brief Setting protect source event filter, only support the same filter value. + * @param filterNum filter cycle number. + * @retval None. + */ +static void APT_SetEMEventFilterEx(unsigned char filterNum) +{ + unsigned int srcEvent; + unsigned int enableOffset = 24; + unsigned int valueShift = 8; + unsigned int maxEventNum = 3; /* every register can config 3 event's filer */ + for (srcEvent = 0; srcEvent < maxEventNum; srcEvent++) { + SYSCTRL1->APT_POE_FILTER.reg |= 0x1 << (enableOffset + srcEvent); + SYSCTRL1->APT_POE_FILTER.reg |= (((unsigned int)filterNum & 0xff) << (valueShift * srcEvent)); + SYSCTRL1->APT_EVTMP_FILTER.reg |= 0x1 << (enableOffset + srcEvent); + SYSCTRL1->APT_EVTMP_FILTER.reg |= (((unsigned int)filterNum & 0xff) << (valueShift * srcEvent)); + } +} + +/** + * @brief Set protect source event polarity. + * @param aptHandle APT module handle. + * @param polarityMask polarity bit mask. + * @retval None. + */ +static void APT_SetProtectSrcEventPolarityEx(APT_Handle *aptHandle, unsigned int polarityMask) +{ + unsigned int curEvent; + unsigned int curPolarity; + unsigned int curMpEventNum; /* System Compare Event Sources */ + unsigned int curIoEventNum; /* I/O Event Source */ + /* Sets the polarity of the trigger source. */ + for (unsigned int i = 0; i <= APT_EM_COMBINE_SRC_EVT_MP_6; i++) { + curEvent = i; + curPolarity = (polarityMask >> curEvent) & 0x01; + if (curEvent >= APT_EM_COMBINE_SRC_EVT_MP_1) { + curMpEventNum = (curEvent - APT_EM_COMBINE_SRC_EVT_MP_1) << 1; + /* set ACMP0~2 and EVTMP4~6 event polarity */ + aptHandle->baseAddress->EM_EVTMP_PSEL.reg &= (~(0b11 << curMpEventNum)); + aptHandle->baseAddress->EM_EVTMP_PSEL.reg |= (curPolarity << curMpEventNum); + } else { + /* set IO event polarity */ + curIoEventNum = curEvent << 1; + aptHandle->baseAddress->EM_EVTIO_PSEL.reg &= (~(0b11 << curIoEventNum)); + aptHandle->baseAddress->EM_EVTIO_PSEL.reg |= (curPolarity << curIoEventNum); + } + } +} + +/** + * @brief Configure output control protection mode. + * @param aptHandle APT module handle. + * @param protect Output control protection event handle. + * @retval None. + */ +static void APT_SetSysEventProtectModeEx(APT_Handle *aptHandle, APT_OutCtrlProtectEx *protect) +{ + /* Set output control protect mode */ + unsigned int ocModeOffset = 16; + unsigned int cbcClrOffsetPrd = 16; + if (protect->ocEventModeEx == APT_OUT_CTRL_ONE_SHOT) { + aptHandle->baseAddress->OC_MODE.reg &= (~(protect->ocSysEvent << ocModeOffset)); + } else if (protect->ocEventModeEx == APT_OUT_CTRL_CYCLE_BY_CYCLE) { + aptHandle->baseAddress->OC_MODE.reg |= (protect->ocSysEvent << ocModeOffset); + if ((protect->cbcClrModeEx & APT_CLEAR_CBC_ON_CNTR_ZERO) ==APT_CLEAR_CBC_ON_CNTR_ZERO) { + aptHandle->baseAddress->OC_PRD_CLR.reg |= protect->ocSysEvent; + } + if ((protect->cbcClrModeEx & APT_CLEAR_CBC_ON_CNTR_PERIOD) == APT_CLEAR_CBC_ON_CNTR_PERIOD) { + aptHandle->baseAddress->OC_PRD_CLR.reg |= (protect->ocSysEvent << cbcClrOffsetPrd); + } + } +} + +/** + * @brief System event protect initialize. + * @param aptHandle APT module handle. + * @param protect Output control protection event data. + * @retval None. + */ +static void APT_SysProtectInitEx(APT_Handle *aptHandle, APT_OutCtrlProtectEx *protect) +{ + APT_SetSysEventProtectModeEx(aptHandle, protect); + if (protect->ocEventEnEx == BASE_CFG_ENABLE) { + aptHandle->baseAddress->OC_MODE.reg |= protect->ocSysEvent; + } else { + aptHandle->baseAddress->OC_MODE.reg &= (~(protect->ocSysEvent)); + } + if (protect->ocEvtInterruptEnEx == BASE_CFG_ENABLE) { + aptHandle->baseAddress->INT_EVT_EN.reg |= protect->ocSysEvent; + } else { + aptHandle->baseAddress->INT_EVT_EN.reg &= (~(protect->ocSysEvent)); + } +} + +/** + * @brief Initialize the output control protection event of APT module (Extended interface). + * @param aptHandle APT module handle. + * @param protect Output control protection event data. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_ProtectInitEx(APT_Handle *aptHandle, APT_OutCtrlProtectEx *protect) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(protect != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + APT_PARAM_CHECK_WITH_RET(protect->originalEvtEx >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(protect->originalEvtEx <= 0x1FF, BASE_STATUS_ERROR); /* 0x1FF : all event enable */ + unsigned int cbcClrOffsetPrd = 16; + aptHandle->baseAddress->OC_MODE.reg = 0x0; /* clear OC_MODE resgiter */ + aptHandle->baseAddress->TC_MODE.BIT.rg_emu_stop = 0x2; /* stop APT when emulation */ + aptHandle->baseAddress->OC_PRD_CLR.reg = 0x0; /* clear OC_PRD_CLR register */ + APT_SysProtectInitEx(aptHandle, protect); + /* event management configuration */ + aptHandle->baseAddress->EM_MRG_SEL.BIT.rg_em_a1_sel = EM_COMBINE_A1_SRC_ENABLE_ALL; /* open logic OR */ + aptHandle->baseAddress->EM_AOR_EN.BIT.rg_em_a1_oren = protect->originalEvtEx; /* open selected event */ + APT_SetProtectSrcEventPolarityEx(aptHandle, protect->evtPolarityMaskEx); + APT_SetEMEventFilterEx(protect->filterCycleNumEx); + aptHandle->baseAddress->EM_MRG_SEL.BIT.rg_evta1t_sel= APT_EM_COMBINE_EVT1; /* all event input to combine event A1 */ + /* out control configuration */ + APT_SetOutCtrlActionEx(aptHandle, protect->ocActionEx, protect->ocActionBEx, APT_OC_EVT_COMBINE_EVENT_A1_UP); + APT_SetOutCtrlActionEx(aptHandle, protect->ocActionEx, protect->ocActionBEx, APT_OC_EVT_COMBINE_EVENT_A1_DOWN); + /* system event protect setting. */ + APT_SetOutCtrlActionEx(aptHandle, protect->ocActionEx, protect->ocActionBEx, APT_OC_EVT_GPIO_OR_SYSTEM_UP); + APT_SetOutCtrlActionEx(aptHandle, protect->ocActionEx, protect->ocActionBEx, APT_OC_EVT_GPIO_OR_SYSTEM_DOWN); + aptHandle->baseAddress->OC_MODE.BIT.rg_oc_mode_evta1 = protect->ocEventModeEx; /* set protect mode */ + if ((protect->cbcClrModeEx & APT_CLEAR_CBC_ON_CNTR_ZERO) ==APT_CLEAR_CBC_ON_CNTR_ZERO) { + aptHandle->baseAddress->OC_PRD_CLR.reg |= APT_OC_COMBINE_EVENT_A1; /* set CBC clear mode */ + } + if ((protect->cbcClrModeEx & APT_CLEAR_CBC_ON_CNTR_PERIOD) == APT_CLEAR_CBC_ON_CNTR_PERIOD) { + aptHandle->baseAddress->OC_PRD_CLR.reg |= (APT_OC_COMBINE_EVENT_A1 << cbcClrOffsetPrd); + } + if (protect->ocEventEnEx == BASE_CFG_ENABLE) { + aptHandle->baseAddress->OC_MODE.reg |= APT_OC_COMBINE_EVENT_A1; /* OC input combine event A1 */ + } else { + aptHandle->baseAddress->OC_MODE.reg &= (~(APT_OC_COMBINE_EVENT_A1)); + } + if (protect->ocEvtInterruptEnEx == BASE_CFG_ENABLE) { + aptHandle->baseAddress->INT_EVT_EN.reg |= (APT_OC_COMBINE_EVENT_A1); + } else { + aptHandle->baseAddress->INT_EVT_EN.reg &= (~(APT_OC_COMBINE_EVENT_A1)); /* enable combine event A1 interrupt */ + } + return BASE_STATUS_OK; +} + +/** + * @brief De-initialize the output control protection event of APT module (Extended interface). + * @param aptHandle APT module handle. + * @param protect Output control protection event handle. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_ProtectDeInitEx(APT_Handle *aptHandle, APT_OutCtrlProtectEx *protect) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(protect != NULL); + protect->ocEventEnEx = BASE_CFG_DISABLE; + aptHandle->baseAddress->OC_MODE.reg = 0x700070; /* 0x7000070: default value */ + + return BASE_STATUS_OK; +} + +/** + * @brief De-initialize the output control protection event of APT module. + * @param aptHandle APT module handle. + * @param protect Output control protection event handle. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_ProtectDeInit(APT_Handle *aptHandle, APT_OutCtrlProtect *protect) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(protect != NULL); + protect->ocEventEn = BASE_CFG_DISABLE; + aptHandle->baseAddress->OC_MODE.reg = 0x700070; /* 0x7000070: default value */ + + return BASE_STATUS_OK; +} + +/** + * @brief Set event management's source events polarity. + * @param aptHandle APT module handle. + * @param emEvtSrc Source event selection. + * @param emEvtPolar Event polarity. + * @retval None. + */ +static void APT_SetEMInputEvtPolarity(APT_Handle *aptHandle, APT_EMCombineEvtSrc emEvtSrc, + APT_EMEventPolarity emEvtPolar) +{ + unsigned int eventPolarity; + if (emEvtSrc >= APT_EM_COMBINE_SRC_EVT_MP_1) { + /* set multiplex event polarity */ + eventPolarity = (emEvtSrc - APT_EM_COMBINE_SRC_EVT_MP_1) << 1; + aptHandle->baseAddress->EM_EVTMP_PSEL.reg &= (~(0b11 << eventPolarity)); + aptHandle->baseAddress->EM_EVTMP_PSEL.reg |= (emEvtPolar << eventPolarity); + } else { + /* set io event polarity */ + eventPolarity = (emEvtSrc) << 1; + aptHandle->baseAddress->EM_EVTIO_PSEL.reg &= (~(0b11 << eventPolarity)); + aptHandle->baseAddress->EM_EVTIO_PSEL.reg |= (emEvtPolar << eventPolarity); + } +} + + +/** + * @brief Set event management's source events input and event combine. + * (if enable logic or function, it do not support setting polarity, need use DCL to set polarity.) + * @param aptHandle APT module handle. + * @param emEvent EM event handle. + * @retval None. + */ +static void APT_EMCombineEventInit(APT_Handle *aptHandle, APT_CombineEvt *emEvent) +{ + unsigned int evtNum; + for (evtNum = 0; evtNum < EM_CMB_EVT_NUM; evtNum++) { + /* if select logical or */ + aptHandle->baseAddress->EM_MRG_SEL.reg |= emEvent[evtNum].emEvtSrc << (evtNum * EM_CMB_SRC_SEL_INTERVAL); + if (emEvent[evtNum].emEvtSrc == APT_EM_COMBINE_SRC_ALL_EVENT_OR) { + /* enable logical or events */ + if (evtNum < APT_EM_COMBINE_EVENT_B1) { + aptHandle->baseAddress->EM_AOR_EN.reg |= (emEvent[evtNum].emEvtOrEnBits << (evtNum * EM_OR_INTERVAL)); + } else { + aptHandle->baseAddress->EM_BOR_EN.reg |= (emEvent[evtNum].emEvtOrEnBits << \ + ((evtNum - APT_EM_COMBINE_EVENT_B1) * EM_OR_INTERVAL)); + } + } else { + /* set input event's polarity */ + APT_SetEMInputEvtPolarity(aptHandle, emEvent[evtNum].emEvtSrc, emEvent[evtNum].emEvtPolar); + } + aptHandle->baseAddress->EM_MRG_SEL.reg |= (emEvent[evtNum].emEvtCombineMode << \ + (evtNum * EM_CMB_MODE_INTERVAL)) << EM_CMB_MODE_OFFSET; + } +} + +/* + * @brief Initialize mask window and capture function of event management at up down mode. + * (do not support across cycles mask window). + * @param aptHandle APT module handle. + * @param emWdAndCp Mask window and capture configuration handle. + * @param totalWidth offset add window size value. + * @retval None. + */ +static void APT_EMWdAndCapUpDownModeInit(APT_Handle *aptHandle, APT_WdAndCap *emWdAndCap, unsigned int totalWidth) +{ + unsigned int pointA; /* window left point */ + unsigned int pointB; /* window right point */ + + if (totalWidth <= (aptHandle->waveform.timerPeriod)) { /* total width is little than period value */ + aptHandle->baseAddress->TC_MWDREFB.reg = totalWidth; + aptHandle->baseAddress->TC_MWD_ACT.BIT.rg_mwdrefa_act_inc = APT_PWM_ACTION_HIGH; + aptHandle->baseAddress->TC_MWD_ACT.BIT.rg_mwdrefb_act_inc = APT_PWM_ACTION_LOW; + } else { /* total width bigger than period */ + /* left point smaller or equal than period */ + if ((emWdAndCap->wdOffset) <= (aptHandle->waveform.timerPeriod)) { + /* 2: up down mode waveform period is (timer period * 2) */ + pointB = (2 * aptHandle->waveform.timerPeriod) - totalWidth; + aptHandle->baseAddress->TC_MWDREFB.reg = pointB; + aptHandle->baseAddress->TC_MWD_ACT.BIT.rg_mwdrefa_act_inc = APT_PWM_ACTION_HIGH; + aptHandle->baseAddress->TC_MWD_ACT.BIT.rg_mwdrefb_act_dec = APT_PWM_ACTION_LOW; + } else { /* left point bigger than period */ + /* 2: up down mode waveform period is (timer period * 2) */ + pointA = (2 * aptHandle->waveform.timerPeriod) - emWdAndCap->wdOffset; + aptHandle->baseAddress->TC_MWDREFA.reg = pointA; + aptHandle->baseAddress->TC_MWD_ACT.BIT.rg_mwdrefa_act_dec = APT_PWM_ACTION_HIGH; + aptHandle->baseAddress->TC_MWD_ACT.BIT.rg_mwdrefb_act_dec = APT_PWM_ACTION_LOW; + } + } +} + +/* + * @brief Initialize mask window and capture function of event management(do not support across cycles mask window). + * @param aptHandle APT module handle. + * @param emWdAndCp Mask window and capture configuration handle. + * @retval None. + */ +static void APT_EMWdAndCapInit(APT_Handle *aptHandle, APT_WdAndCap *emWdAndCap) +{ + unsigned int totalWidth; + if (emWdAndCap->wdEnable == true) { + /* filter source select */ + aptHandle->baseAddress->EM_OUT_SEL.BIT.rg_evtfilt_sel = emWdAndCap->eventSel; + /* enable mask window */ + aptHandle->baseAddress->TC_MWD_EN.BIT.rg_mskwd_en = BASE_CFG_ENABLE; + /* set polarity */ + aptHandle->baseAddress->TC_MWD_EN.BIT.rg_mskwd_psel = emWdAndCap->wdPolar; + /* set compare value */ + aptHandle->baseAddress->TC_MWDREFA.reg = emWdAndCap->wdOffset; + totalWidth = emWdAndCap->wdOffset + emWdAndCap->wdWidth; + if (aptHandle->waveform.cntMode == APT_COUNT_MODE_UP_DOWN) { + APT_EMWdAndCapUpDownModeInit(aptHandle, emWdAndCap, totalWidth); + } else if (aptHandle->waveform.cntMode == APT_COUNT_MODE_UP) { + aptHandle->baseAddress->TC_MWDREFB.reg = totalWidth; + aptHandle->baseAddress->TC_MWD_ACT.BIT.rg_mwdrefa_act_inc = APT_PWM_ACTION_HIGH; + aptHandle->baseAddress->TC_MWD_ACT.BIT.rg_mwdrefb_act_inc = APT_PWM_ACTION_LOW; + } else if (aptHandle->waveform.cntMode == APT_COUNT_MODE_DOWN) { + aptHandle->baseAddress->TC_MWDREFB.reg = totalWidth; + aptHandle->baseAddress->TC_MWD_ACT.BIT.rg_mwdrefa_act_dec = APT_PWM_ACTION_HIGH; + aptHandle->baseAddress->TC_MWD_ACT.BIT.rg_mwdrefb_act_dec = APT_PWM_ACTION_LOW; + } else { + return; + } + } + return; +} + +/** + * @brief Event management initialization interface. + * @param aptHandle APT module handle. + * @param eventManage Event management handle. + * @retval None. + */ +BASE_StatusType HAL_APT_EMInit(APT_Handle *aptHandle, APT_EventManage *eventManage) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(eventManage != NULL); + if (eventManage->emEnable == true) { /* event manage enable */ + APT_EMCombineEventInit(aptHandle, eventManage->emEvt); /* init combine event */ + if (eventManage->emWdAndCap.wdEnable == true) { + aptHandle->baseAddress->EM_OUT_SEL.reg |= EM_OUT_EVT_FILTER_EN; + APT_EMWdAndCapInit(aptHandle, &(eventManage->emWdAndCap)); + } + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + + +/** + * @brief Get capture value of Event management. + * @param aptHandle APT module handle. + * @retval unsigned short capture counting value. + */ +unsigned short HAL_APT_EMGetCapValue(APT_Handle *aptHandle) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + BASE_FUNC_UNUSED(aptHandle); + unsigned short capValue = 0; + return capValue; /* v1 don't have this function return 0 */ +} + +/** + * @brief Set vallet switch's software calibrate of Event management. + * @param aptHandle APT module handle. + * @param calibrate Delay calibration. + * @retval None. + */ +void HAL_APT_EMSetValleySwitchSoftDelay(APT_Handle *aptHandle, unsigned short calibrate) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + BASE_FUNC_UNUSED(aptHandle); /* v1 don't have this function */ + BASE_FUNC_UNUSED(calibrate); /* v1 don't have this function */ + return; +} + +/** + * @brief Disable PWMA and PWMB output. PWMA and PWMB output low level. + * @param aptHandle APT module handle. + * @retval None. + */ +void HAL_APT_ForcePWMOutputLow(APT_Handle *aptHandle) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + DCL_APT_ForcePWMOutputLow(aptHandle->baseAddress); + + return; +} + +/** + * @brief Initialize the master APT module when using multiple sync-out mode. + * @param aptHandle APT module handle. + * @param syncOutSrc Master APT module synchronization source. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_MasterSyncInit(APT_Handle *aptHandle, unsigned short syncOutSrc) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + APT_PARAM_CHECK_WITH_RET(syncOutSrc <= SYNC_OUT_SOURCE_MAX, BASE_STATUS_ERROR); + /* Configure the sync-out pulse source of APT module synchronization */ + aptHandle->baseAddress->SYNO_CFG.reg &= (~(0xFF << 0)); + aptHandle->baseAddress->SYNO_CFG.reg |= (syncOutSrc << 0); + aptHandle->baseAddress->SYNO_CFG.BIT.rg_mode_syno = APT_SYNCOUT_MULTIPLE_MODE; + return BASE_STATUS_OK; +} + +/** + * @brief Initialize the slave APT module. + * @param aptHandle APT module handle. + * @param slaveSyncIn Slave APT module synchronization handle. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_SlaveSyncInit(APT_Handle *aptHandle, APT_SlaveSyncIn *slaveSyncIn) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(slaveSyncIn != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + APT_PARAM_CHECK_WITH_RET(slaveSyncIn->divPhase <= aptHandle->waveform.dividerFactor, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(slaveSyncIn->cntPhase < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(slaveSyncIn->cntrSyncSrc <= CNTR_SYNC_SOURCE_MAX, BASE_STATUS_ERROR); + + aptHandle->baseAddress->TC_PHS.BIT.rg_cnt_dir = slaveSyncIn->syncCntMode; + TC_PHS_REG tmp = aptHandle->baseAddress->TC_PHS; + tmp.BIT.rg_cnt_phs = slaveSyncIn->cntPhase; + aptHandle->baseAddress->TC_PHS = tmp; + + aptHandle->baseAddress->SYNI_CFG.BIT.rg_syni_sel = slaveSyncIn->syncInSrc; + aptHandle->baseAddress->SYNCNT_CFG.reg = slaveSyncIn->cntrSyncSrc; + return BASE_STATUS_OK; +} + +/** + * @brief Start all of the used APT modules simultaneously. + * @param aptRunMask A logical OR of valid values that can be passed as the aptRunMask. + * Valid values for aptRunMask are: + * RUN_APT0 - apt0_run bit in SYSCTRL1 register. + * RUN_APT1 - apt1_run bit in SYSCTRL1 register. + * RUN_APT2 - apt2_run bit in SYSCTRL1 register. + * RUN_APT3 - apt3_run bit in SYSCTRL1 register. + * RUN_APT4 - apt4_run bit in SYSCTRL1 register. + * RUN_APT5 - apt5_run bit in SYSCTRL1 register. + * RUN_APT6 - apt6_run bit in SYSCTRL1 register. + * RUN_APT7 - apt7_run bit in SYSCTRL1 register. + * RUN_APT8 - apt8_run bit in SYSCTRL1 register. + * @retval None. + */ +void HAL_APT_StartModule(unsigned int aptRunMask) +{ + SYSCTRL1->APT_RUN.reg |= aptRunMask; +} + +/** + * @brief Stop all of the used APT modules simultaneously. + * @param aptRunMask A logical OR of valid values that can be passed as the aptRunMask. + * Valid values for aptRunMask are: + * RUN_APT0 - apt0_run bit in SYSCTRL1 register. + * RUN_APT1 - apt1_run bit in SYSCTRL1 register. + * RUN_APT2 - apt2_run bit in SYSCTRL1 register. + * RUN_APT3 - apt3_run bit in SYSCTRL1 register. + * RUN_APT4 - apt4_run bit in SYSCTRL1 register. + * RUN_APT5 - apt5_run bit in SYSCTRL1 register. + * RUN_APT6 - apt6_run bit in SYSCTRL1 register. + * RUN_APT7 - apt7_run bit in SYSCTRL1 register. + * RUN_APT8 - apt8_run bit in SYSCTRL1 register. + * @retval None. + */ +void HAL_APT_StopModule(unsigned int aptRunMask) +{ + SYSCTRL1->APT_RUN.reg &= (~aptRunMask); +} + +/** + * @brief Set the count compare points along the left and right edges of PWM waveform. + * @param aptHandle APT module handle. + * @param cntCmpLeftEdge The count compare point of the left edge of PWM waveform. Pull High on left edge. + * @param cntCmpRightEdge The count compare point of the right edge of PWM waveform. Pull Low on right edge. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_SetPWMDuty(APT_Handle *aptHandle, unsigned short cntCmpLeftEdge, \ + unsigned short cntCmpRightEdge) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + APT_PARAM_CHECK_WITH_RET(cntCmpLeftEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpLeftEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpRightEdge >= 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpRightEdge <= aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + TC_REFC_REG tmpC; + TC_REFD_REG tmpD; + tmpC = aptHandle->baseAddress->TC_REFC; + tmpC.BIT.rg_cnt_refc = cntCmpLeftEdge; + aptHandle->baseAddress->TC_REFC = tmpC; + tmpD = aptHandle->baseAddress->TC_REFD; + tmpD.BIT.rg_cnt_refd = cntCmpRightEdge; + aptHandle->baseAddress->TC_REFD = tmpD; + return BASE_STATUS_OK; +} + +/** + * @brief Set the count compare points along the left and right edges of PWM waveform. + * @param aptHandle APT module handle. + * @param duty PWM duty. Range: 1 ~ 99. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_SetPWMDutyByNumber(APT_Handle *aptHandle, unsigned int duty) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + APT_PARAM_CHECK_WITH_RET(duty <= MAX_DUTY, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(duty >= 0, BASE_STATUS_ERROR); + + unsigned int cntCmpLeftEdge, cntCmpRightEdge; + TC_REFC_REG tmpC; + TC_REFD_REG tmpD; + + if (aptHandle->waveform.cntMode == APT_COUNT_MODE_UP_DOWN) { + cntCmpLeftEdge = (unsigned int)((1.0f - (float)duty / (float)MAX_DUTY) * \ + (float)aptHandle->waveform.timerPeriod); + cntCmpRightEdge = cntCmpLeftEdge; + } else { + cntCmpLeftEdge = 1; + cntCmpRightEdge = (unsigned int)((float)aptHandle->waveform.timerPeriod / (float)MAX_DUTY) * duty + \ + cntCmpLeftEdge; + } + tmpC = aptHandle->baseAddress->TC_REFC; + tmpC.BIT.rg_cnt_refc = cntCmpLeftEdge; + aptHandle->baseAddress->TC_REFC = tmpC; + tmpD = aptHandle->baseAddress->TC_REFD; + tmpD.BIT.rg_cnt_refd = cntCmpRightEdge; + aptHandle->baseAddress->TC_REFD = tmpD; + return BASE_STATUS_OK; +} + +/** + * @brief Set the count compare points to trigger the ADC sampling. + * @param aptHandle APT module handle. + * @param cntCmpSOCA The count compare point for triggering SOCA. + * @param cntCmpSOCB The count compare point for triggering SOCB. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_SetADCTriggerTime(APT_Handle *aptHandle, unsigned short cntCmpSOCA, unsigned short cntCmpSOCB) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + APT_PARAM_CHECK_WITH_RET(cntCmpSOCA > 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpSOCA < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpSOCB > 0, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(cntCmpSOCB < aptHandle->waveform.timerPeriod, BASE_STATUS_ERROR); + TC_REFA_REG tmpA; + TC_REFB_REG tmpB; + tmpA = aptHandle->baseAddress->TC_REFA; + tmpA.BIT.rg_cnt_refa = cntCmpSOCA; + aptHandle->baseAddress->TC_REFA = tmpA; + tmpB = aptHandle->baseAddress->TC_REFB; + tmpB.BIT.rg_cnt_refb = cntCmpSOCB; + aptHandle->baseAddress->TC_REFB = tmpB; + return BASE_STATUS_OK; +} + +/** + * @brief set outputs of channelA when use APT_PWM_BASIC_A_HIGH_B_HIGH. + * @param aptHandle APT module handle. + * @param aptAction output action type. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType APT_SetActionChannelA(APT_Handle *aptHandle, APT_PWMChannelOutType aptAction) +{ + switch (aptAction) { + case APT_PWM_OUT_BASIC_TYPE: + aptHandle->baseAddress->PG_OUT_FRC.BIT.rg_pga_frc_en = BASE_CFG_UNSET; /* disable force action */ + break; + case APT_PWM_OUT_ALWAYS_LOW: + aptHandle->baseAddress->PG_OUT_FRC.BIT.rg_pga_frc_act = APT_PWM_OUT_ALWAYS_LOW; /* force output low */ + aptHandle->baseAddress->PG_OUT_FRC.BIT.rg_pga_frc_en = BASE_CFG_SET; + break; + case APT_PWM_OUT_ALWAYS_HIGH: + aptHandle->baseAddress->PG_OUT_FRC.BIT.rg_pga_frc_act = APT_PWM_OUT_ALWAYS_HIGH; /* force output high */ + aptHandle->baseAddress->PG_OUT_FRC.BIT.rg_pga_frc_en = BASE_CFG_SET; + break; + default: + return BASE_STATUS_ERROR; + } + return BASE_STATUS_OK; +} + +/** + * @brief set outputs of channelB when use APT_PWM_BASIC_A_HIGH_B_HIGH. + * @param aptHandle APT module handle. + * @param aptAction output action type. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +static BASE_StatusType APT_SetActionChannelB(APT_Handle *aptHandle, APT_PWMChannelOutType aptAction) +{ + switch (aptAction) { + case APT_PWM_OUT_BASIC_TYPE: + aptHandle->baseAddress->PG_OUT_FRC.BIT.rg_pgb_frc_en = BASE_CFG_UNSET; /* disable force action */ + break; + case APT_PWM_OUT_ALWAYS_LOW: + aptHandle->baseAddress->PG_OUT_FRC.BIT.rg_pgb_frc_act = APT_PWM_OUT_ALWAYS_LOW; /* force output low */ + aptHandle->baseAddress->PG_OUT_FRC.BIT.rg_pgb_frc_en = BASE_CFG_SET; + break; + case APT_PWM_OUT_ALWAYS_HIGH: + aptHandle->baseAddress->PG_OUT_FRC.BIT.rg_pgb_frc_act = APT_PWM_OUT_ALWAYS_HIGH; /* force output high */ + aptHandle->baseAddress->PG_OUT_FRC.BIT.rg_pgb_frc_en = BASE_CFG_SET; + break; + default: + return BASE_STATUS_ERROR; + } + return BASE_STATUS_OK; +} + +/** + * @brief Change outputs of channelA and channelB when use APT_PWM_BASIC_A_HIGH_B_HIGH. + * @param aptHandle APT module handle. + * @param channel channel number. + * @param aptAction output action type. + * @retval BASE_StatusType: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_APT_ChangeOutputType(APT_Handle *aptHandle, APT_PWMChannel channel, APT_PWMChannelOutType aptAction) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(aptHandle->baseAddress != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + APT_PARAM_CHECK_WITH_RET(channel >= APT_PWM_CHANNEL_A, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(channel <= APT_PWM_CHANNEL_B, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptAction >= APT_PWM_OUT_BASIC_TYPE, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(aptAction <= APT_PWM_OUT_ALWAYS_HIGH, BASE_STATUS_ERROR); + /* only use in APT_PWM_BASIC_A_HIGH_B_HIGH mode */ + if (aptHandle->waveform.basicType != APT_PWM_BASIC_A_HIGH_B_HIGH) { + return BASE_STATUS_ERROR; + } + if (channel == APT_PWM_CHANNEL_A) { + return APT_SetActionChannelA(aptHandle, aptAction); /* set channnelA's action */ + } else if (channel == APT_PWM_CHANNEL_B) { + return APT_SetActionChannelB(aptHandle, aptAction); /* set channelB's action */ + } else { + return BASE_STATUS_ERROR; /* error channnel number */ + } +} + +/** + * @brief APT event interrupt service processing function. + * @param handle APT module handle. + * @retval None. + */ +void HAL_APT_EventIrqHandler(void *handle) +{ + APT_ASSERT_PARAM(handle != NULL); + APT_Handle *aptHandle = (APT_Handle *)handle; + /* Continuous protection cannot clear the event flag. Clear the event flag by users. */ + if (aptHandle->baseAddress->OC_MODE.BIT.rg_oc_mode_evta1 == 0x1) { /* Protection by period. */ + /* Interrupt of the periodic protection clear event. */ + aptHandle->baseAddress->OC_EVT_FLAG.reg |= ALL_EVT_INT_FLAGS; + } + aptHandle->baseAddress->OC_EVT_FLAG.BIT.rg_int_clr_evt = 1; /* clear event flag */ + if (aptHandle->userCallBack.EvtInterruptCallBack != NULL) { + aptHandle->userCallBack.EvtInterruptCallBack(aptHandle); + } +} + +/** + * @brief APT timer interrupt service processing function. + * @param handle APT module handle. + * @retval None. + */ +void HAL_APT_TimerIrqHandler(void *handle) +{ + APT_ASSERT_PARAM(handle != NULL); + APT_Handle *aptHandle = (APT_Handle *)handle; + aptHandle->baseAddress->INT_TMR_FLAG.BIT.rg_int_clr_tmr = 1; /* clear timer interrupt flag */ + if (aptHandle->userCallBack.TmrInterruptCallBack != NULL) { + aptHandle->userCallBack.TmrInterruptCallBack(aptHandle); + } +} + +/** + * @brief Interrupt callback functions registration interface. + * @param aptHandle APT module handle. + * @param typeID ID of callback function type. + * @param pCallback Pointer for the user callback function. + * @retval None. + */ +void HAL_APT_RegisterCallBack(APT_Handle *aptHandle, APT_InterruputType typeID, APT_CallbackType pCallback) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + switch (typeID) { + case APT_TIMER_INTERRUPT: + aptHandle->userCallBack.TmrInterruptCallBack = pCallback; /* register timer interrupt callback */ + break; + case APT_EVENT_INTERRUPT: + aptHandle->userCallBack.EvtInterruptCallBack = pCallback; /* register event interrupt callback */ + break; + default: + break; + } +} + +/** + * @brief Set window's offset and width of Event management. + * @param aptHandle APT module handle. + * @param offset Window's offset. + * @param width Window's width. + * @note Not support this function in this version. Empty Function. + * @retval None. + */ +void HAL_APT_EMSetWdOffsetAndWidth(APT_Handle *aptHandle, unsigned short offset, unsigned short width) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + BASE_FUNC_UNUSED(aptHandle); /* Not support this function */ + BASE_FUNC_UNUSED(offset); + BASE_FUNC_UNUSED(width); + return; +} + +/** + * @brief Attribute configuration of the reference point. + * @param aptHandle APT module handle. + * @param refDotParameters Attribute structure of a reference point. + * @retval BASE_StatusType: OK, ERROR. + */ +static BASE_StatusType APT_ConfigAction(APT_Handle *aptHandle, APT_RefDotParameters *refDotParameters) +{ + /* Action configuration of the reference point of channel B. */ + if (refDotParameters->pwmChannel == APT_PWM_CHANNEL_B) { + aptHandle->baseAddress->PG_ACT_B.reg &= (~(0b11 << refDotParameters->actionEvent)); /* Reset configuration */ + aptHandle->baseAddress->PG_ACT_B.reg |= (refDotParameters->action << refDotParameters->actionEvent); + return BASE_STATUS_OK; + } + /* Action configuration of the reference point of channel A. */ + if (refDotParameters->pwmChannel == APT_PWM_CHANNEL_A) { + aptHandle->baseAddress->PG_ACT_A.reg &= (~(0b11 << refDotParameters->actionEvent)); /* Reset configuration */ + aptHandle->baseAddress->PG_ACT_A.reg |= (refDotParameters->action << refDotParameters->actionEvent); + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Configure the value and action of the reference point A. + * @param aptHandle APT module handle. + * @param refDotParameters Reference point A configuration property set. + * @retval BASE_StatusType: OK, ERROR. + */ +BASE_StatusType APT_ConfigRefA(APT_Handle *aptHandle, APT_RefDotParameters *refDotParameters) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(aptHandle->baseAddress != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + /* Check the attributes of the reference point A: PWM Channel. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->pwmChannel >= APT_PWM_CHANNEL_A, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(refDotParameters->pwmChannel <= APT_PWM_CHANNEL_B, BASE_STATUS_ERROR); + /* Check the attributes of the reference point A: triggle action event. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->actionEvent >= APT_PWM_ACTION_ON_TIMEBASE_ZERO, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(refDotParameters->actionEvent <= APT_PWM_ACTION_ON_C2_COUNT_DOWN, BASE_STATUS_ERROR); + /* Check the attributes of the reference point A: triggle action. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->action <= APT_PWM_ACTION_TOGGLE, BASE_STATUS_ERROR); + /* Change reference dot A value and division value. */ + aptHandle->baseAddress->TC_REFA.BIT.rg_cnt_refa = refDotParameters->refDotValue; + /* Reference dot A triggle event and action */ + return APT_ConfigAction(aptHandle, refDotParameters); +} + +/** + * @brief Configure the value and action of the reference point B. + * @param aptHandle APT module handle. + * @param refDotParameters Reference point B configuration property set. + * @retval BASE_StatusType: OK, ERROR. + */ +BASE_StatusType APT_ConfigRefB(APT_Handle *aptHandle, APT_RefDotParameters *refDotParameters) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(aptHandle->baseAddress != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + /* Check the attributes of the reference point B: PWM Channel. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->pwmChannel >= APT_PWM_CHANNEL_A, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(refDotParameters->pwmChannel <= APT_PWM_CHANNEL_B, BASE_STATUS_ERROR); + /* Check the attributes of the reference point B: triggle action event. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->actionEvent >= APT_PWM_ACTION_ON_TIMEBASE_ZERO, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(refDotParameters->actionEvent <= APT_PWM_ACTION_ON_C2_COUNT_DOWN, BASE_STATUS_ERROR); + /* Check the attributes of the reference point B: triggle action. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->action <= APT_PWM_ACTION_TOGGLE, BASE_STATUS_ERROR); + /* Change reference dot B value and division value. */ + aptHandle->baseAddress->TC_REFB.BIT.rg_cnt_refb = refDotParameters->refDotValue; + /* Reference dot B triggle event and action. */ + return APT_ConfigAction(aptHandle, refDotParameters); +} + +/** + * @brief Configure the value and action of the reference point C. + * @param aptHandle APT module handle. + * @param refDotParameters Reference point C configuration property set. + * @retval BASE_StatusType: OK, ERROR. + */ +BASE_StatusType APT_ConfigRefC(APT_Handle *aptHandle, APT_RefDotParameters *refDotParameters) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(aptHandle->baseAddress != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + /* Check the attributes of the reference point C: PWM Channel. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->pwmChannel >= APT_PWM_CHANNEL_A, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(refDotParameters->pwmChannel <= APT_PWM_CHANNEL_B, BASE_STATUS_ERROR); + /* Check the attributes of the reference point C: triggle action event. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->actionEvent >= APT_PWM_ACTION_ON_TIMEBASE_ZERO, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(refDotParameters->actionEvent <= APT_PWM_ACTION_ON_C2_COUNT_DOWN, BASE_STATUS_ERROR); + /* Check the attributes of the reference point C: triggle action. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->action <= APT_PWM_ACTION_TOGGLE, BASE_STATUS_ERROR); + /* Change reference dot C value and division value. */ + aptHandle->baseAddress->TC_REFC.BIT.rg_cnt_refc = refDotParameters->refDotValue; + /* Reference dot C triggle event and action. */ + return APT_ConfigAction(aptHandle, refDotParameters); +} + +/** + * @brief Configure the value and action of the reference point D. + * @param aptHandle APT module handle. + * @param refDotParameters Reference point D configuration property set. + * @retval BASE_StatusType: OK, ERROR. + */ +BASE_StatusType APT_ConfigRefD(APT_Handle *aptHandle, APT_RefDotParameters *refDotParameters) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(aptHandle->baseAddress != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + /* Check the attributes of the reference point D: PWM Channel. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->pwmChannel >= APT_PWM_CHANNEL_A, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(refDotParameters->pwmChannel <= APT_PWM_CHANNEL_B, BASE_STATUS_ERROR); + /* Check the attributes of the reference point D: triggle action event. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->actionEvent >= APT_PWM_ACTION_ON_TIMEBASE_ZERO, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(refDotParameters->actionEvent <= APT_PWM_ACTION_ON_C2_COUNT_DOWN, BASE_STATUS_ERROR); + /* Check the attributes of the reference point D: triggle action. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->action <= APT_PWM_ACTION_TOGGLE, BASE_STATUS_ERROR); + /* Change reference dot D value and division value. */ + aptHandle->baseAddress->TC_REFD.BIT.rg_cnt_refd = refDotParameters->refDotValue; + /* Reference dot D triggle event and action. */ + return APT_ConfigAction(aptHandle, refDotParameters); +} + + +/** + * @brief Attribute configuration of any reference point. + * @param aptHandle APT module handle. + * @param refDotSelect Selection of reference points. + * @param refDotParameters The properties of the reference point. + * @retval BASE_StatusType: OK, ERROR. + */ +BASE_StatusType HAL_APT_ConfigRefDot(APT_Handle *aptHandle, APT_RefDotSelect refDotSelect, + APT_RefDotParameters *refDotParameters) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(aptHandle->baseAddress != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + /* Reference point configuration, which must be point A, point B, point C, and point D. */ + APT_PARAM_CHECK_WITH_RET(refDotSelect >= APT_REFERENCE_DOTA, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(refDotSelect <= APT_REFERENCE_DOTD, BASE_STATUS_ERROR); + /* Channels A and B are optional. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->pwmChannel >= APT_PWM_CHANNEL_A, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(refDotParameters->pwmChannel <= APT_PWM_CHANNEL_B, BASE_STATUS_ERROR); + /* Trigger event type check. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->actionEvent >= APT_PWM_ACTION_ON_TIMEBASE_ZERO, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(refDotParameters->actionEvent <= APT_PWM_ACTION_ON_C2_COUNT_DOWN, BASE_STATUS_ERROR); + /* There are four types of trigger actions. */ + APT_PARAM_CHECK_WITH_RET(refDotParameters->action <= APT_PWM_ACTION_TOGGLE, BASE_STATUS_ERROR); + /* Transfer table for setting reference dot. */ + BASE_StatusType (* APT_RefDotConfigTable[RERF])(APT_Handle *, APT_RefDotParameters *) = {APT_ConfigRefA, + APT_ConfigRefB, + APT_ConfigRefC, + APT_ConfigRefD}; + return APT_RefDotConfigTable[refDotSelect](aptHandle, refDotParameters); /* Configure reference point. */ +} + +/** + * @brief Set APT period. + * @param aptHandle APT module handle. + * @param newPeriod New period. + * @param prdLoadMode Buffer load mode, recommend: APT_BUFFER_INDEPENDENT_LOAD. + * @param prdLoadEvt Period event load mode, recommend: APT_PERIOD_LOAD_EVENT_ZERO. + * @retval BASE_StatusType: OK, ERROR. + */ +BASE_StatusType HAL_APT_SetTimerPeriod(APT_Handle *aptHandle, unsigned short newPeriod, \ + APT_BufferLoadMode prdLoadMode, unsigned int prdLoadEvt) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_PARAM_CHECK_WITH_RET(prdLoadMode >= APT_BUFFER_DISABLE, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(prdLoadMode <= APT_BUFFER_GLOBAL_LOAD, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(prdLoadEvt >= APT_PERIOD_LOAD_EVENT_ZERO, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(prdLoadEvt <= APT_PERIOD_LOAD_EVENT_SYNC, BASE_STATUS_ERROR); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + /* Sets the period value of the member variable. */ + aptHandle->waveform.timerPeriod = newPeriod; + /* Set period load mode, recommend APT_BUFFER_INDEPENDENT_LOAD. */ + DCL_APT_SetPeriodLoadMode(aptHandle->baseAddress, prdLoadMode); + /* Set period load event, recommend APT_PERIOD_LOAD_EVENT_ZERO. */ + DCL_APT_SetPeriodLoadEvent(aptHandle->baseAddress, prdLoadEvt); + /* Set period register. */ + DCL_APT_SetTimeBasePeriod(aptHandle->baseAddress, newPeriod); + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/drivers/apt/apt_v2/src/apt_ex.c b/src/drivers/apt/apt_v2/src/apt_ex.c new file mode 100644 index 0000000000000000000000000000000000000000..38ab59feac495fc813465d5c88862009e9996b2b --- /dev/null +++ b/src/drivers/apt/apt_v2/src/apt_ex.c @@ -0,0 +1,100 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file apt_ex.c + * @author MCU Driver Team + * @brief apt module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the apt. + * + high resolution of pwm setting. + */ + +#include "apt_ex.h" +/** + * @brief HRPWM delay setting + * @param aptHandle APT module handle. + * @param pwmChannel Channel of HRPMWM. + * @param riseDelayStep Rising Edge Delay Step. + * @param fallDelayStep Falling Edge Delay Step. + * @retval BASE_StatusType: OK, ERROR. + */ +BASE_StatusType HAL_APT_SetHRPWM(APT_Handle *aptHandle, APT_PWMChannel pwmChannel, + APT_PWMDelayStep riseDelayStep, APT_PWMDelayStep fallDelayStep) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + APT_ASSERT_PARAM(aptHandle->baseAddress != NULL); + APT_ASSERT_PARAM(IsAPTInstance(aptHandle->baseAddress)); + /* PWM Channel Check */ + APT_PARAM_CHECK_WITH_RET(pwmChannel >= APT_PWM_CHANNEL_A, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(pwmChannel <= APT_PWM_CHANNEL_B, BASE_STATUS_ERROR); + /* PWM Delay Step Check */ + APT_PARAM_CHECK_WITH_RET(riseDelayStep >= DELAY_0_STEP, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(riseDelayStep <= DELAY_11_STEP, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(fallDelayStep >= DELAY_0_STEP, BASE_STATUS_ERROR); + APT_PARAM_CHECK_WITH_RET(fallDelayStep <= DELAY_11_STEP, BASE_STATUS_ERROR); + if (pwmChannel == APT_PWM_CHANNEL_A) { + DCL_APT_EnableHRPWMA(aptHandle->baseAddress); + aptHandle->baseAddress->HRPWMA_RSTEP.reg = riseDelayStep; /* HrPwm A channel PWM Delay Setting. */ + aptHandle->baseAddress->HRPWMA_FSTEP.reg = fallDelayStep; + return BASE_STATUS_OK; + } + if (pwmChannel == APT_PWM_CHANNEL_B) { + DCL_APT_EnableHRPWMB(aptHandle->baseAddress); + aptHandle->baseAddress->HRPWMB_RSTEP.reg = riseDelayStep; /* HrPwm B channel PWM Delay Setting. */ + aptHandle->baseAddress->HRPWMB_FSTEP.reg = fallDelayStep; + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Protect of POEx flag. + * @param aptHandle APT module handle. + * @retval APT_PoeStatus: Status of POE. + */ +APT_PoeStatus HAL_APT_GetPoeStatus(APT_Handle *aptHandle, APT_POEx poex) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + /* POE Channel Check */ + APT_ASSERT_PARAM(poex >= APT_POE0); + APT_ASSERT_PARAM(poex <= APT_POE2); + /* POE select */ + if (poex == APT_POE0) { + return DCL_APT_GetPoe0Status(aptHandle->baseAddress); + } else if (poex == APT_POE1) { + return DCL_APT_GetPoe1Status(aptHandle->baseAddress); + } else if (poex == APT_POE2) { + return DCL_APT_GetPoe2Status(aptHandle->baseAddress); + } + return APT_POE_LOW_LEVEL; +} + +/** + * @brief Get PWM Channelx output status. + * @param aptHandle APT module handle. + * @param pwmChannel Channel of HRPMWM. + * @retval APT_PwmStatus: Status of PWM. + */ +APT_PwmStatus HAL_APT_GetPwmStatus(APT_Handle *aptHandle, APT_PWMChannel pwmChannel) +{ + APT_ASSERT_PARAM(aptHandle != NULL); + /* PWM Channel Check */ + APT_ASSERT_PARAM(pwmChannel >= APT_PWM_CHANNEL_A); + APT_ASSERT_PARAM(pwmChannel <= APT_PWM_CHANNEL_B); + return (pwmChannel == APT_PWM_CHANNEL_A)? DCL_APT_GetPWMAStatus(aptHandle->baseAddress)\ + : DCL_APT_GetPWMBStatus(aptHandle->baseAddress); +} diff --git a/src/drivers/apt/common/inc/apt.h b/src/drivers/apt/common/inc/apt.h index 331709f574796885759d5a269f567b33c4d269fe..b8433bb13c3e3896a6326be2def456cc07f66c80 100644 --- a/src/drivers/apt/common/inc/apt.h +++ b/src/drivers/apt/common/inc/apt.h @@ -29,258 +29,6 @@ #include "apt_ip.h" -#define EM_OUT_EVT_FILTER_EN 0x0f -#define EM_CMB_MODE_OFFSET 16 -#define EM_CMB_MODE_INTERVAL 4 -#define EM_CMB_SRC_SEL_INTERVAL 4 -#define EM_OR_INTERVAL 16 -#define EM_CMB_EVT_NUM 4 -#define EM_COMBINE_A1_SRC_ENABLE_ALL 0xF -/** - * @defgroup APT APT - * @brief APT module. - * @{ - */ - - -/** - * @defgroup APT_Common APT Common - * @brief APT common external module. - * @{ - */ - -/** - * @defgroup APT_Handle_Definition APT Handle Definition - * @{ - */ - -/* - Basic type AHBL ALBH AHBH ALBL - ___ __ __ ___ __ __ - ChannelA __| |__ |___| __| |__ |___| - __ __ ___ ___ __ __ - ChannelB |___| __| |__ __| |__ |___| -*/ -/** - * @brief Basic PWM waveform type. - * @details waveform type: - * + APT_PWM_BASIC_A_HIGH_B_LOW -- Basic PWM waveform type 1. - * + APT_PWM_BASIC_A_LOW_B_HIGH -- Basic PWM waveform type 2. - * + APT_PWM_BASIC_A_HIGH_B_HIGH -- Basic PWM waveform type 3. - * + APT_PWM_BASIC_A_LOW_B_LOW -- Basic PWM waveform type 4. - */ -typedef enum { - APT_PWM_BASIC_A_HIGH_B_LOW = 0x00000000U, - APT_PWM_BASIC_A_LOW_B_HIGH = 0x00000001U, - APT_PWM_BASIC_A_HIGH_B_HIGH = 0x00000002U, - APT_PWM_BASIC_A_LOW_B_LOW = 0x00000003U, -} APT_PWMBasicType; - -/** - * @brief The actual outputs of PWM channelA and channelB. - * @details Output: - * + APT_PWM_OUT_BASIC_TYPE = 0x00000000U -- PWM channel output the waveform according to basic PWM type. - * + APT_PWM_OUT_ALWAYS_LOW = 0x00000001U -- PWM channel output low level. - * + APT_PWM_OUT_ALWAYS_HIGH = 0x00000002U -- PWM channel output high level. - */ -typedef enum { - APT_PWM_OUT_BASIC_TYPE = 0x00000000U, - APT_PWM_OUT_ALWAYS_LOW = 0x00000001U, - APT_PWM_OUT_ALWAYS_HIGH = 0x00000002U, -} APT_PWMChannelOutType; - -/** - * @brief PWM waveform configuration handle of APT module. - */ -typedef struct { - APT_PWMBasicType basicType; /**< Basic PWM waveform type. */ - APT_PWMChannelOutType chAOutType; /**< Actual output of PWM channelA. */ - APT_PWMChannelOutType chBOutType; /**< Actual output of PWM channelB. */ - APT_CountMode cntMode; /**< Count mode of APT time-base counter. */ - unsigned short dividerFactor; /**< Divider factor. The range is 0~4095. */ - unsigned short timerPeriod; /**< Count period of APT time-base timer. */ - unsigned short divInitVal; /**< Initial value of divider. */ - unsigned short cntInitVal; /**< Initial value of time-base counter */ - unsigned short cntCmpLeftEdge; /**< Count compare point of the left edge of PWM waveform. */ - unsigned short cntCmpRightEdge; /**< Count compare point of the right edge of PWM waveform. */ - APT_BufferLoadMode cntCmpLoadMode; /**< Buffer load mode of PWM waveform count compare value. */ - unsigned int cntCmpLoadEvt; /**< Buffer load event of PWM waveform count compare value. */ - unsigned short deadBandCnt; /**< Count value of dead-band counter. In units of APT clock. */ -} APT_PWMWaveForm; - -/** - * @brief ADC trigger configuration handle of APT module. - */ -typedef struct { - bool trgEnSOCA; /**< Enable of ADC trigger source SOCA. */ - APT_ADCTriggerSource trgSrcSOCA; /**< Source of ADC trigger source SOCA. */ - unsigned short trgScaleSOCA; /**< Scale of ADC trigger source SOCA. */ - unsigned short cntCmpSOCA; /**< Count compare point of ADC trigger source SOCA when using CMPA */ - bool trgEnSOCB; /**< Enable of ADC trigger source SOCB. */ - APT_ADCTriggerSource trgSrcSOCB; /**< Source of ADC trigger source SOCB. */ - unsigned short trgScaleSOCB; /**< Scale of ADC trigger source SOCB. */ - unsigned short cntCmpSOCB; /**< Count compare point of ADC trigger source SOCB when using CMPB */ - APT_BufferLoadMode cntCmpLoadMode; /**< Buffer load mode of ADC trigger count compare value. */ - unsigned int cntCmpLoadEvt; /**< Buffer load event of ADC trigger count compare value. */ -} APT_ADCTrigger; - -/** - * @brief Timer interrupt configuration handle of APT module. - */ -typedef struct { - bool tmrInterruptEn; /**< Enable of APT module timer interrupt. */ - APT_TimerInterruptSrc tmrInterruptSrc; /**< Source of APT module timer interrupt. */ - unsigned short tmrInterruptScale; /**< Scale of APT module timer interrupt. */ -} APT_TimerInterrupt; - -/** - * @brief Output control protection configuration handle of APT module. - */ -typedef struct { - bool ocEventEn; /**< Enable of output control event. */ - APT_OutCtrlEvent ocEvent; /**< Output control event. Limited to IO events or system events. */ - APT_OutCtrlMode ocEventMode; /**< Output control protection mode. */ - APT_CBCClearMode cbcClrMode; /**< Event clear mode when using cycle-by-cycle mode. */ - APT_EMEventPolarity evtPolarity; /**< Event effective polarity. */ - APT_OutCtrlAction ocAction; /**< Output control protection action. */ - APT_EmulationMode emMode; /**< emulation mode */ - bool ocEvtInterruptEn; /**< Enable of output control event interrupt. */ -} APT_OutCtrlProtect; - -/** - * @brief Source event of event magnagement. - */ -typedef enum { - APT_EM_ORIGINAL_SRC_POE0 = 0x00000001U, - APT_EM_ORIGINAL_SRC_POE1 = 0x00000002U, - APT_EM_ORIGINAL_SRC_POE2 = 0x00000004U, - APT_EM_ORIGINAL_SRC_ACMP0 = 0x00000008U, - APT_EM_ORIGINAL_SRC_ACMP1 = 0x00000010U, - APT_EM_ORIGINAL_SRC_ACMP2 = 0x00000020U, - APT_EM_ORIGINAL_SRC_EVTMP4 = 0x00000040U, - APT_EM_ORIGINAL_SRC_EVTMP5 = 0x00000080U, - APT_EM_ORIGINAL_SRC_EVTMP6 = 0x00000100U, -} APT_EMOriginalEvtSrc; - -/** - * @brief Filter mask bit. - */ -typedef enum { - APT_EM_POE0_INVERT_BIT = 0x00000001U, - APT_EM_POE1_INVERT_BIT = 0x00000002U, - APT_EM_POE2_INVERT_BIT = 0x00000004U, - APT_EM_ACMP0_INVERT_BIT = 0x00000008U, - APT_EM_ACMP1_INVERT_BIT = 0x00000010U, - APT_EM_ACMP2_INVERT_BIT = 0x00000020U, - APT_EM_EVTMP4_INVERT_BIT = 0x00000040U, - APT_EM_EVTMP5_INVERT_BIT = 0x00000080U, - APT_EM_EVTMP6_INVERT_BIT = 0x00000100U, -} APT_EMPolarityMskBit; - -/** - * @brief System protect event; - */ -typedef enum { - APT_SYS_EVT_DEBUG = 0x00000010U, - APT_SYS_EVT_CLK = 0x00000020U, - APT_SYS_EVT_MEM = 0x00000040U, -} APT_SysOcEvent; - -/** - * @brief Output control protection configuration handle of APT module. - */ -typedef struct { - bool ocEventEnEx; /**< oc event enable */ - APT_OutCtrlMode ocEventModeEx; /**< Output control protection mode. */ - APT_CBCClearMode cbcClrModeEx; /**< Event clear mode when using cycle-by-cycle mode. */ - APT_OutCtrlAction ocActionEx; /**< Output control protection channel A action. */ - APT_OutCtrlAction ocActionBEx; /**< Output control protection channel B action. */ - bool ocEvtInterruptEnEx; /**< Enable of output control event interrupt. */ - APT_SysOcEvent ocSysEvent; /**< System protect event */ - APT_EMOriginalEvtSrc originalEvtEx; /**< Event management's event source */ - APT_EMPolarityMskBit evtPolarityMaskEx; /**< Event effective polarity. */ - unsigned char filterCycleNumEx; /**< input source event filter */ -} APT_OutCtrlProtectEx; - -/** - * @brief struct of EM conbine event - */ -typedef struct { - APT_EMCombineEvtSrc emEvtSrc; /**< combine event selection */ - APT_EMCombineEvtMode emEvtCombineMode; /**< event combine mode */ - APT_EMEventPolarity emEvtPolar; /**< event source polarity */ - unsigned int emEvtOrEnBits; /**< event logic or enable bits */ -} APT_CombineEvt; - -/** - * @brief Shield window and capture configurations - */ -typedef struct { - bool wdEnable; /**< Shield windows enable bit */ - bool emCapEnable; /**< Enable EM captrue functions */ - APT_EMCombineEvent eventSel; /**< Window source event selection */ - APT_MaskWinResetMode wdStartAndCapClr; /**< Window's offset start count and EM capture clear condition */ - unsigned short wdOffset; /**< Window's offset value */ - unsigned short wdWidth; /**< Window's width value */ - APT_MaskWinPolarity wdPolar; /**< Window's polarity */ -} APT_WdAndCap; - - -/** - * @brief Valley switch configurations - */ -typedef struct { - bool vsEnable; /**< Valley switch enable */ - APT_EMEdgeFilterMode vsFilerEdgeSel; /**< Filter edge selection */ - unsigned char vsFilterCnt; /**< Filter edge count */ - APT_ValleyCapRstType vsClrType; /**< Clear type */ - APT_ValleyCountEdge vsCapEdgeSel; /**< Capture edge selection */ - unsigned char vsCapStartEdge; /**< Capture start edge */ - unsigned char vsCapEndEdge; /**< Capture end edge */ - APT_ValleyDelayMode vsCapDelayMode; /**< Capture delay mode */ - unsigned short vsCapSoftDelay; /**< Capture software calibrate value */ -} APT_ValleySw; - -/** - * @brief Event management handle of APT module - */ -typedef struct { - bool emEnable; /**< Enable bit of event management */ - APT_CombineEvt emEvt[EM_CMB_EVT_NUM]; /**< Combine events configuration */ - APT_WdAndCap emWdAndCap; /**< Shield windows and capture configuration */ - APT_ValleySw emValleySw; /**< Valley switch configuration */ -} APT_EventManage; - -/** - * @brief Synchronization handle of slave APT module. - */ -typedef struct { - unsigned short divPhase; /**< Divider phase when receiving APT synchronization pulse. */ - unsigned short cntPhase; /**< Counter phase when receiving APT synchronization pulse. */ - APT_SyncCountMode syncCntMode; /**< Count mode when receiving APT synchronization pulse. */ - APT_SyncInSrc syncInSrc; /**< Sync-in source of APT module */ - unsigned short cntrSyncSrc; - /**< Sync-in source of time-base counter synchronization - A logical OR of valid values can be passed as the cntrSyncSrc parameter. - Valid values for cntrSyncSrc are: - APT_CNTR_SYNC_SRC_COMBINE_EVENT_A1 - Enable combine event A1 as the counter synchronization source. - APT_CNTR_SYNC_SRC_COMBINE_EVENT_B1 - Enable combine event B1 as the counter synchronization source. - APT_CNTR_SYNC_SRC_SYNCIN - Enable Sync-In source as the counter synchronization source. */ -} APT_SlaveSyncIn; - -/** - * @brief Definition of callback function type. - */ -typedef void (* APT_CallbackType)(void *aptHandle); - -/** - * @brief Definition of callback function type. - */ -typedef struct { - void (* EvtInterruptCallBack)(void *handle); - void (* TmrInterruptCallBack)(void *handle); -} APT_UserCallBack; - /** * @brief The definition of the APT handle structure. */ @@ -292,22 +40,18 @@ typedef struct _APT_Handle { APT_UserCallBack userCallBack; /**< Interrupt callback function when APT event happens. */ APT_ExtendHandle handleEx; /**< extra handle */ } APT_Handle; -/** - * @} - */ /** * @defgroup APT_API_Declaration APT HAL API * @{ */ + /** - * @brief Definition of callback function ID. + * @defgroup APT_API_Declaration + * @brief APT HAL API. + * @{ */ -typedef enum { - APT_TIMER_INTERRUPT = 0x00000000U, - APT_EVENT_INTERRUPT = 0x00000001U, -} APT_InterruputType; BASE_StatusType HAL_APT_PWMInit(APT_Handle *aptHandle); BASE_StatusType HAL_APT_PWMDeInit(APT_Handle *aptHandle); @@ -330,19 +74,43 @@ void HAL_APT_RegisterCallBack(APT_Handle *aptHandle, APT_InterruputType typeID, BASE_StatusType HAL_APT_EMInit(APT_Handle *aptHandle, APT_EventManage *eventManage); unsigned short HAL_APT_EMGetCapValue(APT_Handle *aptHandle); void HAL_APT_EMSetWdOffsetAndWidth(APT_Handle *aptHandle, unsigned short offset, unsigned short width); -void HAL_APT_EMSetValleySwithSoftDelay(APT_Handle *aptHandle, unsigned short calibrate); +void HAL_APT_EMSetValleySwitchSoftDelay(APT_Handle *aptHandle, unsigned short calibrate); BASE_StatusType HAL_APT_ChangeOutputType(APT_Handle *aptHandle, APT_PWMChannel channel, APT_PWMChannelOutType aptAction); +/** + * @defgroup APT_API_Declaration + * @brief Attribute configuration of each reference point. + * @{ + */ -/* Attribute configuration of each reference point. */ BASE_StatusType APT_ConfigRefA(APT_Handle *aptHandle, APT_RefDotParameters *refDotParameters); BASE_StatusType APT_ConfigRefB(APT_Handle *aptHandle, APT_RefDotParameters *refDotParameters); BASE_StatusType APT_ConfigRefC(APT_Handle *aptHandle, APT_RefDotParameters *refDotParameters); BASE_StatusType APT_ConfigRefD(APT_Handle *aptHandle, APT_RefDotParameters *refDotParameters); -/* Combination configuration of reference point attributes. */ +/** + * @} + */ + +/** + * @defgroup APT_API_Declaration + * @brief Combination configuration of reference point attributes. + * @{ + */ + BASE_StatusType HAL_APT_ConfigRefDot(APT_Handle *aptHandle, APT_RefDotSelect refDotSelect, APT_RefDotParameters *refDotParameters); + +BASE_StatusType HAL_APT_SetTimerPeriod(APT_Handle *aptHandle, unsigned short newPeriod, \ + APT_BufferLoadMode prdLoadMode, unsigned int prdLoadEvt); +/** + * @} + */ + +/** + * @} + */ + /** * @} */ diff --git a/src/drivers/base/base_v0/inc/generalfunc.h b/src/drivers/base/base_v0/inc/generalfunc.h index 06ef81bbb2b9a396f1318cf988ff61fdeabdcaa4..c055745872499813d0121d734812a9e0f11cee8f 100644 --- a/src/drivers/base/base_v0/inc/generalfunc.h +++ b/src/drivers/base/base_v0/inc/generalfunc.h @@ -94,6 +94,11 @@ float BASE_FUNC_GetSlipAverageVal(unsigned int index, float val); void BASE_FUNC_AverageDeInit(unsigned int index); void BASE_FSM_FunRegister(BASE_FSM_Status index, FunType funAddress); void BASE_FSM_Run(unsigned int delayTime, BASE_DelayUnit delayUnit); + +#ifdef MEASURE_SUPPORT +void BASE_FUNC_MeasurementStart(unsigned int id); +void BASE_FUNC_MeasurementStop(unsigned int id); +#endif /** * @} */ diff --git a/src/drivers/base/base_v0/inc/interrupt.h b/src/drivers/base/base_v0/inc/interrupt.h index 1fa09615b9f1968f63a7edd416f1996e8dad5c63..c4f72c0b57591cbfacaf99877fe0611111af2beb 100644 --- a/src/drivers/base/base_v0/inc/interrupt.h +++ b/src/drivers/base/base_v0/inc/interrupt.h @@ -80,7 +80,9 @@ */ /** - * @brief Read standard csr registers + * @brief Read standard CSR registers. + * @param csrReg standard CSR registers name. + * @retval CSR register value. */ #define READ_CSR(csrReg) ({ \ unsigned int tmp_; \ @@ -90,7 +92,10 @@ /** - * @brief Write standard csr registers + * @brief Write standard CSR registers. + * @param csrReg standard CSR registers name. + * @param csrVal Configuration value of the CSR register. + * @retval None. */ #define WRITE_CSR(csrReg, csrVal) do { \ if (__builtin_constant_p(csrVal) && ((unsigned int)(csrVal) < 32)) { \ @@ -101,7 +106,10 @@ } while (0) /** - * @brief Set standard csr registers + * @brief Set standard CSR registers. + * @param csrReg standard CSR registers name. + * @param csrBit Configuration bit value of the CSR register. + * @retval None */ #define SET_CSR(csrReg, csrBit) do { \ unsigned int tmp_; \ @@ -114,7 +122,10 @@ } while (0) /** - * @brief Clear standard csr registers + * @brief Clear standard CSR registers. + * @param csrReg standard CSR registers name. + * @param csrBit Configuration bit value of the CSR register. + * @retval None */ #define CLEAR_CSR(csrReg, csrBit) do { \ unsigned int tmp_; \ @@ -127,7 +138,9 @@ } while (0) /** - * @brief Read the custom defined registers of the chip + * @brief Read the custom defined CSR registers of the chip. + * @param csrReg custom defined CSR registers address of the chip. + * @retval CSR register value. */ #define READ_CUSTOM_CSR(csrReg) ({ \ unsigned int tmp_; \ @@ -136,7 +149,10 @@ }) /** - * @brief Write the custom defined registers of the chip + * @brief Write the custom defined CSR registers of the chip. + * @param csrRegAddr custom defined CSR registers address of the chip. + * @param csrVal Configuration value of the CSR register.. + * @retval None */ #define WRITE_CUSTOM_CSR_VAL(csrRegAddr, csrVal) do { \ if (__builtin_constant_p(csrVal)) { \ @@ -148,7 +164,10 @@ } while (0) /** - * @brief Set the custom defined registers of the chip + * @brief Set the custom defined CSR registers of the chip. + * @param csrRegAddr custom defined CSR registers address of the chip. + * @param csrBit Configuration bit value of the CSR register. + * @retval None */ #define SET_CUSTOM_CSR(csrRegAddr, csrBit) do { \ if (__builtin_constant_p(csrBit) && ((unsigned int)(csrBit) < 32)) { \ @@ -160,7 +179,10 @@ } while (0) /** - * @brief Clear the custom defined registers of the chip + * @brief Clear the custom defined CSR registers of the chip. + * @param csrRegAddr custom defined CSR registers address of the chip. + * @param csrBit Configuration bit value of the CSR register. + * @retval None */ #define CLEAR_CUSTOM_CSR(csrRegAddr, csrBit) do { \ if (__builtin_constant_p(csrBit) && ((unsigned int)(csrBit) < 32)) { \ diff --git a/src/drivers/base/base_v0/inc/lock.h b/src/drivers/base/base_v0/inc/lock.h index 451ca83fd0d143803499a528936fa98156d03ebc..98eeebee9d0d09e41e291205676d56c2578ce63e 100644 --- a/src/drivers/base/base_v0/inc/lock.h +++ b/src/drivers/base/base_v0/inc/lock.h @@ -67,8 +67,8 @@ typedef enum { /* Exported global functions ------------------------------------------------- */ bool BASE_FUNC_SoftwareLock(unsigned int * const addr); void BASE_FUNC_SoftwareUnLock(unsigned int * const addr); -bool BASE_FUNC_HardwareLock(CHIP_LockType const hwIndex); -void BASE_FUNC_HardwareUnLock(CHIP_LockType const hwIndex); +bool BASE_FUNC_HardwareLock(const CHIP_LockType hwIndex); +void BASE_FUNC_HardwareUnLock(const CHIP_LockType hwIndex); /** * @} */ diff --git a/src/drivers/base/base_v0/inc/typedefs.h b/src/drivers/base/base_v0/inc/typedefs.h index 2af04be5ad6e5248e3504be4c1e21e9e1e561546..9a718e0f87f63980a299e1318cef030e6293232d 100644 --- a/src/drivers/base/base_v0/inc/typedefs.h +++ b/src/drivers/base/base_v0/inc/typedefs.h @@ -59,7 +59,7 @@ #endif /* NULL */ #ifndef FLT_EPSILON -#define FLT_EPSILON 0.000001 +#define FLT_EPSILON 0.000001f #endif /* float min error definition */ #ifndef INT16_MAX diff --git a/src/drivers/base/base_v0/src/base_math.c b/src/drivers/base/base_v0/src/base_math.c index 05a2063e628d16b96df27e70a8692409bc1c0445..c7d1397e3411962a274f0d5804c29861413018f5 100644 --- a/src/drivers/base/base_v0/src/base_math.c +++ b/src/drivers/base/base_v0/src/base_math.c @@ -99,13 +99,13 @@ #define BASE_MATH_ANGLED90_180 0x0300u /**< Mask value of sincos ranging from 90 to 180 degrees */ #define BASE_MATH_ANGLED180_270 0x0000u /**< Mask value of sincos ranging from 180 to 270 degrees */ #define BASE_MATH_ANGLED270_360 0x0100u /**< Mask value of sincos ranging from 270 to 360 degrees */ -#define BASE_MATH_PAI 3.141592653 -#define BASE_MATH_FACTORIAL3_RECIPROCAL 0.166666667 /**< 1/6. */ -#define BASE_MATH_FACTORIAL5_RECIPROCAL 0.008333333 /**< 1/120. */ -#define BASE_MATH_FACTORIAL7_RECIPROCAL 0.000198413 /**< 1/5040. */ +#define BASE_MATH_PAI 3.141592653f +#define BASE_MATH_FACTORIAL3_RECIPROCAL 0.166666667f /**< 1/6. */ +#define BASE_MATH_FACTORIAL5_RECIPROCAL 0.008333333f /**< 1/120. */ +#define BASE_MATH_FACTORIAL7_RECIPROCAL 0.000198413f /**< 1/5040. */ #define BASE_MATH_ANGLE90 90 #define BASE_MATH_ANGLE180 180 -#define BASE_MATH_ANGLE180_RECIPROCAL 0.005555556 /**< 1/180. */ +#define BASE_MATH_ANGLE180_RECIPROCAL 0.005555556f /**< 1/180. */ #define BASE_MATH_ANGLE270 270 #define BASE_MATH_ANGLE360 360 @@ -203,9 +203,9 @@ float BASE_MATH_GetSin(float angle) } /** - * @brief Using Taylor Expansion to Calculate Sin Values for Any Angle. + * @brief Using Taylor Expansion to Calculate Cos Values for Any Angle. * @param angle Angle value to be calculated. - * @retval float Calculated sin value. + * @retval float Calculated Cos value. */ float BASE_MATH_GetCos(float angle) { diff --git a/src/drivers/base/base_v0/src/generalfunc.c b/src/drivers/base/base_v0/src/generalfunc.c index 91c2d2fc2ab38218af936aa99e53618748561738..383dbc66627a27595caa4d9af2f0741f95680809 100644 --- a/src/drivers/base/base_v0/src/generalfunc.c +++ b/src/drivers/base/base_v0/src/generalfunc.c @@ -41,12 +41,40 @@ */ /* Includes ------------------------------------------------------------------ */ +#include "systick.h" #include "generalfunc.h" +/* Macro definitions ---------------------------------------------------------*/ +#define MEA_MAX_NUM 2 /* the num of the measurement group */ +#define AVE_MAX_NUM 10 /* the num of the saving current ticks */ + +/* Typedef definitions -------------------------------------------------------*/ +typedef enum { + STOP, + START +} MeasureStatus; + +typedef struct { + unsigned int startTick; /* start tick */ + unsigned int stopTick; /* stop tick */ + unsigned int curr; /* current tick, value is (stopTick - startTick) */ + unsigned int peak; /* maximum tick value */ + unsigned int valley; /* minimum tick value */ + unsigned int average; /* average value of the ave[AVE_MAX_NUM] */ + unsigned int ave[AVE_MAX_NUM]; /* save current tick for average */ + unsigned char size; /* the size of the ave[AVE_MAX_NUM] */ + unsigned char index; /* the index of the ave[AVE_MAX_NUM] */ + MeasureStatus status; /* the status of the measurement(start or stop) */ +} Measurement; + /* Private variables --------------------------------------------------------- */ BASE_AverageHandle g_averageHandle[BASE_DEFINE_SLIPAVERAGE_NUM]; BASE_FSM_Handle g_fsmHandle; +#ifdef MEASURE_SUPPORT +static Measurement g_measure[MEA_MAX_NUM]; +#endif + /** * @brief Obtains the current tick value. * @retval unsigned int. Current tick value. @@ -220,4 +248,92 @@ void BASE_FSM_Run(unsigned int delayTime, BASE_DelayUnit delayUnit) } BASE_FUNC_Delay(delayTime, delayUnit); } -} \ No newline at end of file +} + +#ifdef MEASURE_SUPPORT +/** + * @brief Start Measurement. Get the systick for Measurement. + * @param id Selecting a measurement group + * @retval None + */ +void BASE_FUNC_MeasurementStart(unsigned int id) +{ + if (id >= MEA_MAX_NUM) { + return; + } + + Measurement *measure = &g_measure[id]; + if (measure->status == START) { + /* START and STOP must appear in pairs. Drop the superfluous START. */ + return; + } + + measure->status = START; + measure->startTick = DCL_SYSTICK_GetTick(); +} + +/** + * @brief Average measurement. + * @param measure a measurement group + * @retval None + */ +static void BASE_FUNC_MeasurementAve(Measurement *measure) +{ + if (measure == NULL) { + return; + } + /* Add cur value into average queue */ + if (measure->index < AVE_MAX_NUM) { + measure->ave[measure->index] = measure->curr; + if (measure->size < AVE_MAX_NUM) { + measure->size++; + } + measure->index = (measure->index + 1) % AVE_MAX_NUM; + } + + /* Calculate the average in the queue */ + unsigned long long tmp = 0; + for (int i = 0; i < measure->size; i++) { + tmp += measure->ave[i]; + } + if (measure->size != 0) { + float f = (float)tmp / (float)measure->size; + measure->average = (unsigned int)f; + } +} + +/** + * @brief Stop measurement. Get the systick and statistic the systick. + * @param id Selecting a measurement group + * @retval None + */ +void BASE_FUNC_MeasurementStop(unsigned int id) +{ + unsigned int tick = DCL_SYSTICK_GetTick(); + if (id >= MEA_MAX_NUM) { + return; + } + + Measurement *measure = &g_measure[id]; + if (measure->status == STOP) { + /* START and STOP must appear in pairs. Drop the superfluous STOP. */ + return; + } + + measure->status = STOP; + measure->stopTick = tick; + measure->curr = + tick > measure->startTick ? tick - measure->startTick : SYSTICK_MAX_VALUE - measure->startTick + tick; + /* max measurement. */ + if (measure->curr > measure->peak) { + measure->peak = measure->curr; + } + + /* min measurement. */ + if (measure->curr < measure->valley || measure->valley == 0) { + measure->valley = measure->curr; + } + + BASE_FUNC_MeasurementAve(measure); +} +#endif \ No newline at end of file diff --git a/src/drivers/base/base_v0/src/lock.c b/src/drivers/base/base_v0/src/lock.c index 764a7cf2827ab69694f446d9c6f0b5ed55a10122..e7d8880c7f9beba8ec0b11df25b504700f38350c 100644 --- a/src/drivers/base/base_v0/src/lock.c +++ b/src/drivers/base/base_v0/src/lock.c @@ -64,7 +64,7 @@ void BASE_FUNC_SoftwareUnLock(unsigned int * const addr) * @retval true, Succeeded in obtaining the Hardware Resource lock. * @retval false, Failed to obtain the Hardware Resource lock. The resource has been locked. */ -bool BASE_FUNC_HardwareLock(CHIP_LockType const hwIndex) +bool BASE_FUNC_HardwareLock(const CHIP_LockType hwIndex) { BASE_FUNC_PARAMCHECK_WITH_RET((hwIndex >= 0 && hwIndex < CHIP_LOCK_TOTAL), false); return BASE_FUNC_SoftwareLock(&g_baseLock[hwIndex]); @@ -75,7 +75,7 @@ bool BASE_FUNC_HardwareLock(CHIP_LockType const hwIndex) * @param hwIndex Hardware Resource ID. * @retval None. */ -void BASE_FUNC_HardwareUnLock(CHIP_LockType const hwIndex) +void BASE_FUNC_HardwareUnLock(const CHIP_LockType hwIndex) { BASE_FUNC_PARAMCHECK_NO_RET(hwIndex >= 0 && hwIndex < CHIP_LOCK_TOTAL); BASE_FUNC_SoftwareUnLock(&g_baseLock[hwIndex]); diff --git a/src/drivers/can/can_v0/src/can.c b/src/drivers/can/can_v0/src/can.c index 13a403cecbdfe15a30ce7e054d3c7cb194e84114..0f5a7e3242eefd7c6e074dfc782776e6348bf016 100644 --- a/src/drivers/can/can_v0/src/can.c +++ b/src/drivers/can/can_v0/src/can.c @@ -111,7 +111,7 @@ BASE_StatusType HAL_CAN_Init(CAN_Handle *canHandle) /* Step2: configuration command mask register, set 0xF3 to write into packet objects */ canHandle->baseAddress->IF1_COMMAND_MASK.reg = 0xF3; /* Step3 ~ 4: init packet object 1 ~ 32 */ - for (int i = 1; i <= CAN_OBJ_MAXNUM; i++) { + for (unsigned int i = 1; i <= CAN_OBJ_MAXNUM; i++) { canHandle->baseAddress->IF1_COMMAND_REQUEST.reg = i; do { busy = canHandle->baseAddress->IF1_COMMAND_REQUEST.BIT.BUSY; @@ -158,7 +158,8 @@ BASE_StatusType HAL_CAN_DeInit(CAN_Handle *canHandle) { CAN_ASSERT_PARAM(canHandle != NULL); CAN_ASSERT_PARAM(IsCANInstance(canHandle->baseAddress)); - canHandle->baseAddress->CAN_CONTROL.reg = BASE_CFG_DISABLE; /* Disables the control register. */ + /* Configuration 1: CAN enters the initialization state and cannot transmit or receive data. */ + canHandle->baseAddress->CAN_CONTROL.reg = BASE_CFG_ENABLE; canHandle->baseAddress->CAN_STATUS.reg = BASE_CFG_DISABLE; /* Clear the status of the CAN. */ canHandle->userCallBack.ReadFinishCallBack = NULL; /* Clear all user call back function. */ canHandle->userCallBack.TransmitErrorCallBack = NULL; @@ -314,7 +315,7 @@ BASE_StatusType HAL_CAN_Write(CAN_Handle *canHandle, CANFrame *data) canHandle->state = CAN_STATE_BUSY_TX; unsigned int objId = 0; unsigned int id; - for (int i = BOUND_ID + 1; i <= CAN_OBJ_MAXNUM; i++) { + for (unsigned int i = BOUND_ID + 1; i <= CAN_OBJ_MAXNUM; i++) { if (g_msgObj[i - 1] == 0) { g_msgObj[i - 1] = 1; objId = i; @@ -378,7 +379,7 @@ static BASE_StatusType CAN_ReadCallback(CAN_Handle *canHandle, unsigned int objI CAN_ASSERT_PARAM(canHandle != NULL); CAN_ASSERT_PARAM(IsCANInstance(canHandle->baseAddress)); CAN_PARAM_CHECK_WITH_RET(canHandle->rxFrame != NULL, BASE_STATUS_ERROR); - CAN_PARAM_CHECK_WITH_RET((objID >= MESSAGE_NUMBER_MIN) && (objID <= MESSAGE_NUMBER_MAX), BASE_STATUS_ERROR); + CAN_PARAM_CHECK_WITH_RET((objId >= MESSAGE_NUMBER_MIN) && (objId <= MESSAGE_NUMBER_MAX), BASE_STATUS_ERROR); unsigned int busy, id, idLow, idHigh, extendedFrame, remoteFrame; /* Step1: setting request transfer to packet object */ canHandle->baseAddress->IF2_COMMAND_MASK.reg = 0x7F; /* 0x7F indicates reading data from the packet object */ diff --git a/src/drivers/can/common/inc/can.h b/src/drivers/can/common/inc/can.h index b9f2e930a1821f22107b5972ca0e7ca4d72ed459..c2ad12c659c8be974d4f26278e00fc4b26782014 100644 --- a/src/drivers/can/common/inc/can.h +++ b/src/drivers/can/common/inc/can.h @@ -77,21 +77,36 @@ typedef void (* CAN_CallbackType)(void *handle); */ /** - * @defgroup CAN_API_Declaration CAN HAL API + * @defgroup CAN_API_Declaration + * @brief CAN HAL API. * @{ */ + BASE_StatusType HAL_CAN_Init(CAN_Handle *canHandle); BASE_StatusType HAL_CAN_DeInit(CAN_Handle *canHandle); BASE_StatusType HAL_CAN_ReadIT(CAN_Handle *canHandle, CANFrame *data, CAN_FilterConfigure *filterConfigure); BASE_StatusType HAL_CAN_Write(CAN_Handle *canHandle, CANFrame *data); +/** + * @defgroup CAN_API_Declaration + * @brief CAN status. + * @{ + */ -/* CAN status */ CAN_ErrorStatus HAL_CAN_GetErrorStatus(CAN_Handle *canHandle); unsigned int HAL_CAN_GetErrorStatusCode(CAN_Handle *canHandle); CAN_BusOffStatus HAL_CAN_GetBusOffStatus(CAN_Handle *canHandle); CAN_MessageReceiveStatus HAL_CAN_MessageReceiveStatus(CAN_Handle *canHandle); CAN_MessageSendStatus HAL_CAN_MessageSendStatus(CAN_Handle *canHandle); -/* CAN interrupt service funciton. */ +/** + * @} + */ + +/** + * @defgroup CAN_API_Declaration + * @brief CAN interrupt service funciton. + * @{ + */ + void HAL_CAN_IrqHandler(void *handle); BASE_StatusType HAL_CAN_RegisterCallBack(CAN_Handle *canHandle, CAN_CallBackFunType typeID, CAN_CallbackType pCallback); @@ -104,6 +119,10 @@ BASE_StatusType HAL_CAN_RegisterCallBack(CAN_Handle *canHandle, CAN_CallBackFunT * @} */ +/** + * @} + */ + /** * @} */ diff --git a/src/drivers/capm/capm_v0/inc/capm_ip.h b/src/drivers/capm/capm_v0/inc/capm_ip.h index e708e9737872544e09d4b18868b9e80d4822de9d..1c7579fd15d90c4aabfeb28b1091f61a18f5840d 100644 --- a/src/drivers/capm/capm_v0/inc/capm_ip.h +++ b/src/drivers/capm/capm_v0/inc/capm_ip.h @@ -106,7 +106,6 @@ typedef enum { CAPM_REG3CAP = 0x00000004U, CAPM_REG4CAP = 0x00000008U, CAPM_TSROVF = 0x00000010U, - CAPM_ECROVF = 0x00000020U, CAPM_EARCMPMATCH = 0x00000040U, CAPM_EAROVF = 0x00000080U, CAPM_DMAREQOVF = 0x00000100U, @@ -318,11 +317,11 @@ typedef union { unsigned int evt3_en : 1; /**< Event3 interrupt enable. */ unsigned int evt4_en : 1; /**< Event4 interrupt enable. */ unsigned int tsr_ovf_en : 1; /**< TSR overflow interrupt enable. */ - unsigned int ecr_ovf_en : 1; /**< Capture overflow interrupt enable. */ + unsigned int reserved0 : 1; unsigned int earcmp_match_en : 1; /**< Edge count compare match interrupt enable. */ unsigned int ear_ovf_en : 1; /**< Edge count overflow interrupt enable. */ unsigned int dmareq_ovf_en : 1; /**< DMA request overflow interrupt enable. */ - unsigned int reserved : 23; + unsigned int reserved1 : 23; } BIT; } volatile INTENR_REG; @@ -337,11 +336,11 @@ typedef union { unsigned int evt3_raw : 1; /**< Event3 initial interrupt. */ unsigned int evt4_raw : 1; /**< Event4 initial interrupt. */ unsigned int tsr_ovf_raw : 1; /**< TSR overflow initial interrupt. */ - unsigned int ecr_ovf_raw : 1; /**< Capture overflow initial interrupt. */ + unsigned int reserved0 : 1; unsigned int earcmp_match_raw : 1; /**< Edge count compare match initial interrupt. */ unsigned int ear_ovf_raw : 1; /**< Edge count overflow initial interrupt. */ unsigned int dmareq_ovf_raw : 1; /**< DMA request overflow initial interrupt. */ - unsigned int reserved : 23; + unsigned int reserved1 : 23; } BIT; } volatile INTRAWR_REG; @@ -356,11 +355,11 @@ typedef union { unsigned int evt3_inj : 1; /**< Event3 interrupt injection. */ unsigned int evt4_inj : 1; /**< Event4 interrupt injection. */ unsigned int tsr_ovf_inj : 1; /**< TSR overflow interrupt injection. */ - unsigned int ecr_ovf_inj : 1; /**< Capture overflow interrupt injection. */ + unsigned int reserved0 : 1; unsigned int earcmp_match_inj : 1; /**< Edge count compare match interrupt injection. */ unsigned int ear_ovf_inj : 1; /**< Edge count overflow interrupt injection. */ unsigned int dmareq_ovf_inj : 1; /**< DMA request overflow interrupt injection. */ - unsigned int reserved : 23; + unsigned int reserved1 : 23; } BIT; } volatile INTINJR_REG; @@ -375,11 +374,11 @@ typedef union { unsigned int evt3_int : 1; /**< Event3 interrupt status. */ unsigned int evt4_int : 1; /**< Event4 interrupt status. */ unsigned int tsr_ovf_int : 1; /**< TSR overflow interrupt status. */ - unsigned int ecr_ovf_int : 1; /**< Capture overflow interrupt status. */ + unsigned int reserved0 : 1; unsigned int earcmp_match_int : 1; /**< Edge count compare match interrupt status. */ unsigned int ear_ovf_int : 1; /**< Edge count overflow interrupt status. */ unsigned int dmareq_ovf_int : 1; /**< DMA request overflow interrupt status. */ - unsigned int reserved : 23; + unsigned int reserved1 : 23; } BIT; } volatile INTFLGR_REG; @@ -392,7 +391,6 @@ typedef enum { CAPM_INTREG3CAP = 0x00000002U, CAPM_INTREG4CAP = 0x00000003U, CAPM_INTTSROVF = 0x00000004U, - CAPM_INTECROVF = 0x00000005U, CAPM_INTEARCMPMATCH = 0x00000006U, CAPM_INTEAROVF = 0x00000007U, CAPM_INTDMAREQOVF = 0x00000008U, @@ -1533,30 +1531,6 @@ static inline void DCL_CAPM_DisableTsrovfInter(CAPM_RegStruct * const capmx) return; } -/** - * @brief Enable ECR overflow interrupt. - * @param capmx: CAPM register base address. - * @retval None. - */ -static inline void DCL_CAPM_EnableEcrovfInter(CAPM_RegStruct * const capmx) -{ - CAPM_ASSERT_PARAM(IsCAPMInstance(capmx)); - capmx->INTENR.BIT.ecr_ovf_en = BASE_CFG_ENABLE; - return; -} - -/** - * @brief Disable ECR overflow interrupt. - * @param capmx: CAPM register base address. - * @retval None. - */ -static inline void DCL_CAPM_DisableEcrovfInter(CAPM_RegStruct * const capmx) -{ - CAPM_ASSERT_PARAM(IsCAPMInstance(capmx)); - capmx->INTENR.BIT.ecr_ovf_en = BASE_CFG_DISABLE; - return; -} - /** * @brief Enable EAR compare match interrupt. * @param capmx: CAPM register base address. @@ -1713,18 +1687,6 @@ static inline void DCL_CAPM_IngectTsrovfInter(CAPM_RegStruct * const capmx) return; } -/** - * @brief Inject ECR overflow interrupt. - * @param capmx: CAPM register base address. - * @retval None. - */ -static inline void DCL_CAPM_InjectEcrovfInter(CAPM_RegStruct * const capmx) -{ - CAPM_ASSERT_PARAM(IsCAPMInstance(capmx)); - capmx->INTINJR.BIT.ecr_ovf_inj |= 0x01; - return; -} - /** * @brief Inject EAR overflow interrupt. * @param capmx: CAPM register base address. diff --git a/src/drivers/capm/capm_v0/src/capm.c b/src/drivers/capm/capm_v0/src/capm.c index 578969a0b45a26d32c0c22c7442a30686451dd6f..94e3fb6c278c9143cf5af87d9ede1f17a105f599 100644 --- a/src/drivers/capm/capm_v0/src/capm.c +++ b/src/drivers/capm/capm_v0/src/capm.c @@ -94,6 +94,19 @@ static BASE_StatusType CAPM_SetDeburrNum(CAPM_Handle *handle) return BASE_STATUS_OK; } +/** + * @brief Clear EAR when interrupt is CAPM_INTEARCMPMATCH or CAPM_INTEAROVF. + * @param handle: CAPM handle. + * @param intBit: Specific interrupt. + * @retval None + */ +static void CAPM_ClearEar(CAPM_Handle *handle, unsigned int intBit) +{ + if (intBit == (0x1 << CAPM_INTEARCMPMATCH) || intBit == (0x1 << CAPM_INTEAROVF)) { + handle->baseAddress->EAR.BIT.ear = 0; + } +} + /** * @brief IRQ Handler * @param handle: CAPM handle. @@ -108,9 +121,16 @@ void HAL_CAPM_IrqHandler(void *handle) /* Get interrupt flag. */ unsigned int intMask = DCL_CAPM_GetInterFlag(useHandle->baseAddress); unsigned int intBit; + for (unsigned int i = 0; i <= CAPM_INTDMAREQOVF; i++) { + /* 5:skip the capture interrupt overflow flag. */ + if (i == 5) { + continue; + } if (((intMask >> i) & 0x1) == 0x1) { intBit = (intMask & (0x1 << i)); + /* Clear ear when interrupt is CAPM_INTEARCMPMATCH or CAPM_INTEAROVF. */ + CAPM_ClearEar(useHandle, intBit); /* Clear interrupt. */ DCL_CAPM_ClearInter(useHandle->baseAddress, intBit); useHandle->userCallBack.EvtFinishCallback(useHandle, i); @@ -303,7 +323,7 @@ BASE_StatusType HAL_CAPM_Init(CAPM_Handle *handle) CAPM_SetDeburrNum(handle); /* Init CAPM prescale. */ DCL_CAPM_SetPreScale(handle->baseAddress, handle->preScale); - DCL_CAPM_SetDMATriggleReg(handle->baseAddress, handle->useCapNum - 1); + DCL_CAPM_SetDMATriggleReg(handle->baseAddress, handle->triggleDmaReg); CAPM_SetRegCaptureEvent(handle); CAPM_SyncInit(handle); if (CAPM_InputSel(handle) == BASE_STATUS_ERROR) { @@ -346,7 +366,7 @@ BASE_StatusType HAL_CAPM_DeInit(CAPM_Handle *handle) unsigned int HAL_CAPM_GetECRValue(CAPM_Handle *handle, CAPM_ECRNum ecrNum) { CAPM_ASSERT_PARAM(handle != NULL); - CAPM_PARAM_CHECK_WITH_RET(ecrNum > 0, BASE_STATUS_ERROR); + CAPM_PARAM_CHECK_WITH_RET(ecrNum >= 0, BASE_STATUS_ERROR); CAPM_PARAM_CHECK_WITH_RET(ecrNum < CAPM_MAX_CAP_REG_NUM, BASE_STATUS_ERROR); switch (ecrNum) { case CAPM_ECR_NUM1: @@ -411,16 +431,16 @@ unsigned int HAL_CAPM_GetSyncPhs(CAPM_Handle *handle) /** * @brief Get ECR register value by DMA. * @param handle: CAPM handle. - * @param distAddr: Distance address. + * @param saveData: Destination address. * @param dataLength: CAPM handle. * @retval BASE status type: BASE_STATUS_OK, BASE_STATUS_ERROR. */ -BASE_StatusType HAL_CAPM_GetECRValueDMA(CAPM_Handle *handle, unsigned int *distAddr, +BASE_StatusType HAL_CAPM_GetECRValueDMA(CAPM_Handle *handle, unsigned int *saveData, unsigned int dataLength) { CAPM_ASSERT_PARAM(handle != NULL); CAPM_ASSERT_PARAM(handle->dmaHandle != NULL); - CAPM_ASSERT_PARAM(distAddr != NULL); + CAPM_ASSERT_PARAM(saveData != NULL); CAPM_PARAM_CHECK_WITH_RET(dataLength > 0, BASE_STATUS_ERROR); unsigned int channel; channel = handle->dmaChannel; @@ -432,7 +452,7 @@ BASE_StatusType HAL_CAPM_GetECRValueDMA(CAPM_Handle *handle, unsigned int *distA handle->dmaHandle->userCallBack.DMA_CallbackFuns[channel].ChannelErrorCallBack = CAPM_DmaErrorIRQService; /* Get ECR value by DMA. */ if (HAL_DMA_StartIT(handle->dmaHandle, (unsigned int)(uintptr_t)(void *)&(handle->baseAddress->ECR1), - (unsigned int)(uintptr_t)(void *)distAddr, dataLength, channel) != BASE_STATUS_OK) { + (unsigned int)(uintptr_t)(void *)saveData, dataLength, channel) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } return BASE_STATUS_OK; diff --git a/src/drivers/capm/capm_v1/inc/capm_ip.h b/src/drivers/capm/capm_v1/inc/capm_ip.h index 7fa19345f545f69ead15d6e970d41e4c0bfb56a3..01d7c8b264a1b6053750b24c4e255652bd1473f2 100644 --- a/src/drivers/capm/capm_v1/inc/capm_ip.h +++ b/src/drivers/capm/capm_v1/inc/capm_ip.h @@ -29,6 +29,7 @@ #include "baseinc.h" #include "baseaddr.h" +#include "feature.h" #ifdef CAPM_PARAM_CHECK #define CAPM_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM @@ -94,7 +95,6 @@ typedef enum { * + CAPM_REG3CAP -- ECR2 interrupt * + CAPM_REG4CAP -- ECR3 interrupt * + CAPM_TSROVF -- TSR register overflow interrupt - * + CAPM_ECROVF -- ECR register overflow interrupt * + CAPM_EARCMPMATCH -- EAR compare match interrupt * + CAPM_EAROVF -- EAR register overflow interrupt * + CAPM_DMAREQOVF -- DMA require overflow interrupt @@ -105,7 +105,6 @@ typedef enum { CAPM_REG3CAP = 0x00000004U, CAPM_REG4CAP = 0x00000008U, CAPM_TSROVF = 0x00000010U, - CAPM_ECROVF = 0x00000020U, CAPM_EARCMPMATCH = 0x00000040U, CAPM_EAROVF = 0x00000080U, CAPM_DMAREQOVF = 0x00000100U, @@ -174,11 +173,14 @@ typedef enum { CAPM_SYNC_SRC_APT1 = 0x00000002U, CAPM_SYNC_SRC_APT2 = 0x00000003U, CAPM_SYNC_SRC_APT3 = 0x00000004U, +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) CAPM_SYNC_SRC_APT4 = 0x00000005U, CAPM_SYNC_SRC_APT5 = 0x00000006U, CAPM_SYNC_SRC_APT6 = 0x00000007U, CAPM_SYNC_SRC_APT7 = 0x00000008U, CAPM_SYNC_SRC_APT8 = 0x00000009U, +#endif } CAPM_SyncSrc; /** @@ -317,11 +319,11 @@ typedef union { unsigned int evt2_en : 1; /**< Event2 interrupt enable. */ unsigned int evt3_en : 1; /**< Event3 interrupt enable. */ unsigned int tsr_ovf_en : 1; /**< TSR overflow interrupt enable. */ - unsigned int ecr_ovf_en : 1; /**< Capture overflow interrupt enable. */ + unsigned int reserved0 : 1; unsigned int earcmp_match_en : 1; /**< Edge count compare match interrupt enable. */ unsigned int ear_ovf_en : 1; /**< Edge count overflow interrupt enable. */ unsigned int dmareq_ovf_en : 1; /**< DMA request overflow interrupt enable. */ - unsigned int reserved : 23; + unsigned int reserved1 : 23; } BIT; } volatile INTENR_REG; @@ -336,11 +338,11 @@ typedef union { unsigned int evt2_raw : 1; /**< Event2 initial interrupt. */ unsigned int evt3_raw : 1; /**< Event3 initial interrupt. */ unsigned int tsr_ovf_raw : 1; /**< TSR overflow initial interrupt. */ - unsigned int ecr_ovf_raw : 1; /**< Capture overflow initial interrupt. */ + unsigned int reserved0 : 1; unsigned int earcmp_match_raw : 1; /**< Edge count compare match initial interrupt. */ unsigned int ear_ovf_raw : 1; /**< Edge count overflow initial interrupt. */ unsigned int dmareq_ovf_raw : 1; /**< DMA request overflow initial interrupt. */ - unsigned int reserved : 23; + unsigned int reserved1 : 23; } BIT; } volatile INTRAWR_REG; @@ -355,11 +357,11 @@ typedef union { unsigned int evt2_inj : 1; /**< Event2 interrupt injection. */ unsigned int evt3_inj : 1; /**< Event3 interrupt injection. */ unsigned int tsr_ovf_inj : 1; /**< TSR overflow interrupt injection. */ - unsigned int ecr_ovf_inj : 1; /**< Capture overflow interrupt injection. */ + unsigned int reserved0 : 1; unsigned int earcmp_match_inj : 1; /**< Edge count compare match interrupt injection. */ unsigned int ear_ovf_inj : 1; /**< Edge count overflow interrupt injection. */ unsigned int dmareq_ovf_inj : 1; /**< DMA request overflow interrupt injection. */ - unsigned int reserved : 23; + unsigned int reserved1 : 23; } BIT; } volatile INTINJR_REG; @@ -374,11 +376,11 @@ typedef union { unsigned int evt2_int : 1; /**< Event2 interrupt status. */ unsigned int evt3_int : 1; /**< Event3 interrupt status. */ unsigned int tsr_ovf_int : 1; /**< TSR overflow interrupt status. */ - unsigned int ecr_ovf_int : 1; /**< Capture overflow interrupt status. */ + unsigned int reserved0 : 1; unsigned int earcmp_match_int : 1; /**< Edge count compare match interrupt status. */ unsigned int ear_ovf_int : 1; /**< Edge count overflow interrupt status. */ unsigned int dmareq_ovf_int : 1; /**< DMA request overflow interrupt status. */ - unsigned int reserved : 23; + unsigned int reserved1 : 23; } BIT; } volatile INTFLGR_REG; @@ -391,7 +393,6 @@ typedef enum { CAPM_INTREG3CAP = 0x00000002U, CAPM_INTREG4CAP = 0x00000003U, CAPM_INTTSROVF = 0x00000004U, - CAPM_INTECROVF = 0x00000005U, CAPM_INTEARCMPMATCH = 0x00000006U, CAPM_INTEAROVF = 0x00000007U, CAPM_INTDMAREQOVF = 0x00000008U, @@ -1522,30 +1523,6 @@ static inline void DCL_CAPM_DisableTsrovfInter(CAPM_RegStruct * const capmx) return; } -/** - * @brief Enable ECR overflow interrupt. - * @param capmx: CAPM register base address. - * @retval None. - */ -static inline void DCL_CAPM_EnableEcrovfInter(CAPM_RegStruct * const capmx) -{ - CAPM_ASSERT_PARAM(IsCAPMInstance(capmx)); - capmx->INTENR.BIT.ecr_ovf_en = BASE_CFG_ENABLE; - return; -} - -/** - * @brief Disable ECR overflow interrupt. - * @param capmx: CAPM register base address. - * @retval None. - */ -static inline void DCL_CAPM_DisableEcrovfInter(CAPM_RegStruct * const capmx) -{ - CAPM_ASSERT_PARAM(IsCAPMInstance(capmx)); - capmx->INTENR.BIT.ecr_ovf_en = BASE_CFG_DISABLE; - return; -} - /** * @brief Enable EAR compare match interrupt. * @param capmx: CAPM register base address. @@ -1702,18 +1679,6 @@ static inline void DCL_CAPM_IngectTsrovfInter(CAPM_RegStruct * const capmx) return; } -/** - * @brief Inject ECR overflow interrupt. - * @param capmx: CAPM register base address. - * @retval None. - */ -static inline void DCL_CAPM_InjectEcrovfInter(CAPM_RegStruct * const capmx) -{ - CAPM_ASSERT_PARAM(IsCAPMInstance(capmx)); - capmx->INTINJR.BIT.ecr_ovf_inj |= 0x01; - return; -} - /** * @brief Inject EAR overflow interrupt. * @param capmx: CAPM register base address. @@ -1808,7 +1773,14 @@ static inline void DCL_CAPM_SetSyncInput0(CAPM_COMM_RegStruct * const capmComm, { CAPM_ASSERT_PARAM(IsCAPMCOMMInstance(capmComm)); CAPM_PARAM_CHECK_NO_RET(src >= CAPM_SYNC_SRC_NONE); +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + /* 3066 */ CAPM_PARAM_CHECK_NO_RET(src <= CAPM_SYNC_SRC_APT8); +#else + /* 3061 */ + CAPM_PARAM_CHECK_NO_RET(src <= CAPM_SYNC_SRC_APT3); +#endif capmComm->SYNC_SELR0.BIT.capm0_sync_sel = src; } @@ -1822,7 +1794,14 @@ static inline void DCL_CAPM_SetSyncInput1(CAPM_COMM_RegStruct * const capmComm, { CAPM_ASSERT_PARAM(IsCAPMCOMMInstance(capmComm)); CAPM_PARAM_CHECK_NO_RET(src >= CAPM_SYNC_SRC_NONE); +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + /* 3066 */ CAPM_PARAM_CHECK_NO_RET(src <= CAPM_SYNC_SRC_APT8); +#else + /* 3061 */ + CAPM_PARAM_CHECK_NO_RET(src <= CAPM_SYNC_SRC_APT3); +#endif capmComm->SYNC_SELR1.BIT.capm1_sync_sel = src; } @@ -1836,7 +1815,14 @@ static inline void DCL_CAPM_SetSyncInput2(CAPM_COMM_RegStruct * const capmComm, { CAPM_ASSERT_PARAM(IsCAPMCOMMInstance(capmComm)); CAPM_PARAM_CHECK_NO_RET(src >= CAPM_SYNC_SRC_NONE); +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + /* 3066 */ CAPM_PARAM_CHECK_NO_RET(src <= CAPM_SYNC_SRC_APT8); +#else + /* 3061 */ + CAPM_PARAM_CHECK_NO_RET(src <= CAPM_SYNC_SRC_APT3); +#endif capmComm->SYNC_SELR2.BIT.capm2_sync_sel = src; } diff --git a/src/drivers/capm/capm_v1/src/capm.c b/src/drivers/capm/capm_v1/src/capm.c index 0372e3915882e3234a61dbdc0b292a29af7e1b63..26a563586c9a1919407ff32530a95b2736649e07 100644 --- a/src/drivers/capm/capm_v1/src/capm.c +++ b/src/drivers/capm/capm_v1/src/capm.c @@ -94,6 +94,19 @@ static BASE_StatusType CAPM_SetDeburrNum(CAPM_Handle *handle) return BASE_STATUS_OK; } +/** + * @brief Clear EAR when interrupt is CAPM_INTEARCMPMATCH or CAPM_INTEAROVF. + * @param handle: CAPM handle. + * @param intBit: Specific interrupt. + * @retval None + */ +static void CAPM_ClearEar(CAPM_Handle *handle, unsigned int intBit) +{ + if (intBit == (0x1 << CAPM_INTEARCMPMATCH) || intBit == (0x1 << CAPM_INTEAROVF)) { + handle->baseAddress->EAR.BIT.ear = 0; + } +} + /** * @brief IRQ Handler * @param handle: CAPM handle. @@ -109,8 +122,14 @@ void HAL_CAPM_IrqHandler(void *handle) unsigned int intMask = DCL_CAPM_GetInterFlag(useHandle->baseAddress); unsigned int intBit; for (unsigned int i = 0; i <= CAPM_INTDMAREQOVF; i++) { + /* 5:skip the capture interrupt overflow flag. */ + if (i == 5) { + continue; + } if (((intMask >> i) & 0x1) == 0x1) { intBit = (intMask & (0x1 << i)); + /* Clear ear when interrupt is CAPM_INTEARCMPMATCH or CAPM_INTEAROVF. */ + CAPM_ClearEar(useHandle, intBit); /* Clear interrupt. */ DCL_CAPM_ClearInter(useHandle->baseAddress, intBit); useHandle->userCallBack.EvtFinishCallback(useHandle, i); @@ -303,7 +322,7 @@ BASE_StatusType HAL_CAPM_Init(CAPM_Handle *handle) CAPM_SetDeburrNum(handle); /* Init CAPM prescale. */ DCL_CAPM_SetPreScale(handle->baseAddress, handle->preScale); - DCL_CAPM_SetDMATriggleReg(handle->baseAddress, handle->useCapNum - 1); + DCL_CAPM_SetDMATriggleReg(handle->baseAddress, handle->triggleDmaReg); CAPM_SetRegCaptureEvent(handle); CAPM_SyncInit(handle); if (CAPM_InputSel(handle) == BASE_STATUS_ERROR) { @@ -346,7 +365,7 @@ BASE_StatusType HAL_CAPM_DeInit(CAPM_Handle *handle) unsigned int HAL_CAPM_GetECRValue(CAPM_Handle *handle, CAPM_ECRNum ecrNum) { CAPM_ASSERT_PARAM(handle != NULL); - CAPM_PARAM_CHECK_WITH_RET(ecrNum > 0, BASE_STATUS_ERROR); + CAPM_PARAM_CHECK_WITH_RET(ecrNum >= 0, BASE_STATUS_ERROR); CAPM_PARAM_CHECK_WITH_RET(ecrNum < CAPM_MAX_CAP_REG_NUM, BASE_STATUS_ERROR); switch (ecrNum) { case CAPM_ECR_NUM1: @@ -411,16 +430,16 @@ unsigned int HAL_CAPM_GetSyncPhs(CAPM_Handle *handle) /** * @brief Get ECR register value by DMA. * @param handle: CAPM handle. - * @param distAddr: Distance address. + * @param saveData: Destination address. * @param dataLength: CAPM handle. * @retval BASE status type: BASE_STATUS_OK, BASE_STATUS_ERROR. */ -BASE_StatusType HAL_CAPM_GetECRValueDMA(CAPM_Handle *handle, unsigned int *distAddr, +BASE_StatusType HAL_CAPM_GetECRValueDMA(CAPM_Handle *handle, unsigned int *saveData, unsigned int dataLength) { CAPM_ASSERT_PARAM(handle != NULL); CAPM_ASSERT_PARAM(handle->dmaHandle != NULL); - CAPM_ASSERT_PARAM(distAddr != NULL); + CAPM_ASSERT_PARAM(saveData != NULL); CAPM_PARAM_CHECK_WITH_RET(dataLength > 0, BASE_STATUS_ERROR); unsigned int channel; channel = handle->dmaChannel; @@ -432,7 +451,7 @@ BASE_StatusType HAL_CAPM_GetECRValueDMA(CAPM_Handle *handle, unsigned int *distA handle->dmaHandle->userCallBack.DMA_CallbackFuns[channel].ChannelErrorCallBack = CAPM_DmaErrorIRQService; /* Get ECR value by DMA. */ if (HAL_DMA_StartIT(handle->dmaHandle, (unsigned int)(uintptr_t)(void *)&(handle->baseAddress->ECR0), - (unsigned int)(uintptr_t)(void *)distAddr, dataLength, channel) != BASE_STATUS_OK) { + (unsigned int)(uintptr_t)(void *)saveData, dataLength, channel) != BASE_STATUS_OK) { return BASE_STATUS_ERROR; } return BASE_STATUS_OK; diff --git a/src/drivers/cfd/common/inc/cfd.h b/src/drivers/cfd/common/inc/cfd.h index c697a72fd4f227c3b61a618b8bdca8627d2cbfd4..b1c23e27f596ffdde68075d1aafff11128d62beb 100644 --- a/src/drivers/cfd/common/inc/cfd.h +++ b/src/drivers/cfd/common/inc/cfd.h @@ -85,6 +85,7 @@ typedef void (*CFD_CallBackFuncType)(void *handle); */ /* Hardware abstraction layer functions -------------------------------------------------------- */ + BASE_StatusType HAL_CFD_Init(CFD_Handle *handle); BASE_StatusType HAL_CFD_DeInit(CFD_Handle *handle); BASE_StatusType CFD_RspInit(CFD_Handle *handle); diff --git a/src/drivers/cmm/cmm_v1/inc/cmm_ip.h b/src/drivers/cmm/cmm_v1/inc/cmm_ip.h index 129916eb37eeff34667f26700c1a7b5a96ae6d12..cee62e216d5f1f6aede00256b9edb33077680e5c 100644 --- a/src/drivers/cmm/cmm_v1/inc/cmm_ip.h +++ b/src/drivers/cmm/cmm_v1/inc/cmm_ip.h @@ -102,7 +102,6 @@ typedef enum { CMM_INT_COUNTER_OVERFLOW_MASK = 0x00000001U, CMM_INT_CHECK_END_MASK = 0x00000002U, CMM_INT_FREQ_ERR_MASK = 0x00000004U, - CMM_INT_CLOCK_FAIL_MASK = 0x00000008U, CMM_INT_MAX } CMM_Interrupt_Type; @@ -501,7 +500,6 @@ static inline bool IsCMMInterruptType(CMM_Interrupt_Type type) { return (type == CMM_INT_COUNTER_OVERFLOW_MASK || \ type == CMM_INT_CHECK_END_MASK || \ - type == CMM_INT_CLOCK_FAIL_MASK || \ type == CMM_INT_FREQ_ERR_MASK); } diff --git a/src/drivers/cmm/cmm_v2/inc/cmm_ip.h b/src/drivers/cmm/cmm_v2/inc/cmm_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..69c8bb64b38d9ed0495eaa2106924f8e2b9f1cd2 --- /dev/null +++ b/src/drivers/cmm/cmm_v2/inc/cmm_ip.h @@ -0,0 +1,571 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file cmm_ip.h + * @author MCU Driver Team + * @brief CMM module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the CMM. + * + Register Struct of CMM + * + CMM Register Map struct + * + Direct Configuration Layer functions of CMM + */ + +#ifndef McuMagicTag_CMM_IP_H +#define McuMagicTag_CMM_IP_H + +/* Includes ------------------------------------------------------------------ */ +#include "baseinc.h" +/* Macro definitions ------------------------------------------------------- */ +#ifdef CMM_PARAM_CHECK + #define CMM_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM + #define CMM_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET + #define CMM_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else + #define CMM_ASSERT_PARAM(para) ((void)0U) + #define CMM_PARAM_CHECK_NO_RET(para) ((void)0U) + #define CMM_PARAM_CHECK_WITH_RET(param, ret) ((void)0U) +#endif +/** + * @addtogroup CMM + * @{ + */ + +/** + * @defgroup CMM_IP: cmm_v0 + * @{ + */ + +/** + * @defgroup CMM_Param_Def CMM Parameters Definition + * @brief Description of CMM configuration parameters. + * @{ + */ + +/* Typedef definitions ------------------------------------------------------- */ +typedef enum { + CMM_TRIGGER_RISE = 0x00000000U, + CMM_TRIGGER_FALL = 0x00000001U, + CMM_TRIGGER_BOTH = 0x00000002U, + CMM_TRIGGER_NONE = 0x00000003U, + CMM_TRIGGER_MAX +} CMM_Trigger_Mode; + +typedef enum { + CMM_TARGET_FREQ_DIV_0 = 0x00000000U, + CMM_TARGET_FREQ_DIV_32 = 0x00000001U, + CMM_TARGET_FREQ_DIV_128 = 0x00000002U, + CMM_TARGET_FREQ_DIV_1024 = 0x00000003U, + CMM_TARGET_FREQ_DIV_8192 = 0x00000004U, + CMM_TARGET_FREQ_DIV_MAX +} CMM_Target_Freq_Div_Value; + +typedef enum { + CMM_REF_FREQ_DIV_0 = 0x00000000U, + CMM_REF_FREQ_DIV_4 = 0x00000001U, + CMM_REF_FREQ_DIV_8 = 0x00000002U, + CMM_REF_FREQ_DIV_32 = 0x00000003U, + CMM_REF_FREQ_DIV_MAX +} CMM_Ref_Freq_Div_Value; + +typedef enum { + CMM_TARGET_CLK_LOSC = 0x00000000U, + CMM_TARGET_CLK_HOSC = 0x00000001U, + CMM_TARGET_CLK_TCXO = 0x00000002U, + CMM_TARGET_CLK_HS_SYS = 0x00000003U, + CMM_TARGET_CLK_MAX +} CMM_Target_Clock_Source; + +typedef enum { + CMM_REF_CLK_LOSC = 0x00000000U, + CMM_REF_CLK_HOSC = 0x00000001U, + CMM_REF_CLK_TCXO = 0x00000002U, + CMM_REF_CLK_HS_SYS = 0x00000003U, + CMM_REF_CLK_MAX +} CMM_Ref_Clock_Source; + +typedef enum { + CMM_INT_COUNTER_OVERFLOW_MASK = 0x00000001U, + CMM_INT_CHECK_END_MASK = 0x00000002U, + CMM_INT_FREQ_ERR_MASK = 0x00000004U, + CMM_INT_MAX +} CMM_Interrupt_Type; + +/** + * @} + */ + +/** + * @defgroup CMM_Reg_Def CMM Register Definition + * @brief Description CMM register mapping structure. + * @{ + */ + +/** + * @brief CMM version registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 24; + unsigned int release_ver : 4; /**< Version information. */ + unsigned int reserved1 : 4; + } BIT; +} volatile CMVER_Reg; + +/** + * @brief CMM control registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cmen : 1; /**< CMM enable or disable. */ + unsigned int reserved0 : 31; + } BIT; +} volatile CMCTRL_Reg; + +/** + * @brief CMM target clock control registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int tgtsel : 3; /**< CMM target clock source. */ + unsigned int reserved0 : 1; + unsigned int tgtscale : 3; /**< CMM target clock divide factor. */ + unsigned int reserved1 : 25; + } BIT; +} volatile CMTGTCTRL_Reg; + +/** + * @brief CMM reference clock control registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int refsel : 2; /**< CMM reference clock source. */ + unsigned int reserved0 : 2; + unsigned int refdiv : 2; /**< CMM reference clock divide factor. */ + unsigned int reserved1 : 26; + } BIT; +} volatile CMREFCTRL_Reg; + +/** + * @brief CMM check window upper bound registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cmwdoh : 16; /**< CMM check window upper bound value. */ + unsigned int reserved0 : 16; + } BIT; +} volatile CMWDOH_Reg; + +/** + * @brief CMM check window low bound registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cmwdol : 16; /**< CMM check window low bound value. */ + unsigned int reserved0 : 16; + } BIT; +} volatile CMWDOL_Reg; + +/** + * @brief CMM count locked value registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cmcnt_lock : 16; /**< CMM count locked value */ + unsigned int reserved0 : 16; + } BIT; +} volatile CMCNTLOCK_Reg; + +/** + * @brief CMM interrupt enable registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cnt_ovf_en : 1; /**< CMM count overflow interrupt enable. */ + unsigned int chk_end_en : 1; /**< CMM check end interrupt enable. */ + unsigned int freq_err_en : 1; /**< CMM frequence error interrupt enable. */ + unsigned int reserved0 : 29; + } BIT; +} volatile CMINTENA_Reg; + +/** + * @brief CMM interrupt status registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cnt_ovf_int : 1; /**< CMM count overflow interrupt status. */ + unsigned int chk_end_int : 1; /**< CMM check end interrupt status. */ + unsigned int freq_err_int : 1; /**< CMM frequence error interrupt status. */ + unsigned int reserved0 : 29; + } BIT; +} volatile CMINTSTS_Reg; + +/** + * @brief CMM initial interrupt registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cnt_ovf_raw : 1; /**< CMM count overflow initial interrupt. */ + unsigned int chk_end_raw : 1; /**< CMM check end initial interrupt. */ + unsigned int freq_err_raw : 1; /**< CMM frequence error initial interrupt. */ + unsigned int reserved0 : 29; + } BIT; +} volatile CMINTRAW_Reg; + +/** + * @brief CMM interrupt injection registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cnt_ovf_inj : 1; /**< CMM frequence error interrupt injection. */ + unsigned int chk_end_inj : 1; /**< CMM check end interrupt injection. */ + unsigned int freq_err_inj : 1; /**< CMM frequence error interrupt injection. */ + unsigned int reserved0 : 29; + } BIT; +} volatile CMINTINJ_Reg; + +/** + * @brief CMM Interrupt callback functions. + * + */ +typedef struct { + void (*FreqErrorCallback)(void *handle); + /**< Clock frequency error callback function */ + void (*CheckEndCallback)(void *handle); + /**< End of each check callback function */ + void (*CountOverflowCallback)(void *handle); + /**< Count Overflow callback function */ +} CMM_UserCallBack; + +/** + * @brief CMM extend handle. + */ +typedef struct _CMM_ExtendeHandle { +} CMM_ExtendHandle; + +/** + * @brief CMM register mapping structure. + */ +typedef struct { + CMVER_Reg CMVER; /**< CMM version register, offset address: 0x0000. */ + CMCTRL_Reg CMCTRL; /**< CMM control register, offset address: 0x0004. */ + CMTGTCTRL_Reg CMTGTCTRL; /**< CMM target clock control register, offset address: 0x0008. */ + CMREFCTRL_Reg CMREFCTRL; /**< CMM reference clock control register, offset address: 0x000C. */ + CMWDOH_Reg CMWDOH; /**< CMM check window upper bound register, offset address: 0x0010. */ + CMWDOL_Reg CMWDOL; /**< CMM check window low bound register, offset address: 0x0014. */ + CMCNTLOCK_Reg CMCNTLOCK; /**< CMM count locked value register, offset address: 0x0018. */ + CMINTENA_Reg CMINTENA; /**< CMM interrupt enable register, offset address: 0x001C. */ + CMINTSTS_Reg CMINTSTS; /**< CMM interrupt status register, offset address: 0x0020. */ + CMINTRAW_Reg CMINTRAW; /**< CMM initial interrupt register, offset address: 0x0024. */ + CMINTINJ_Reg CMINTINJ; /**< CMM interrupt injection register, offset address: 0x0028. */ +} volatile CMM_RegStruct; + +/** + * @} + */ + +/** + * @brief Enable CMM module. + * @param cmmx CMM register base address. + * @retval None. + */ +static inline void DCL_CMM_Enable(CMM_RegStruct *cmmx) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + cmmx->CMCTRL.BIT.cmen = BASE_CFG_ENABLE; +} + +/** + * @brief Disable CMM module. + * @param cmmx CMM register base address. + * @retval None. + */ +static inline void DCL_CMM_Disable(CMM_RegStruct *cmmx) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + cmmx->CMCTRL.BIT.cmen = BASE_CFG_DISABLE; +} + +/** + * @brief Sets the frequency divider of the target clock. + * @param cmmx CMM register base address. + * @param value Specified frequency divider. + * @retval None. + */ +static inline void DCL_CMM_SetTargetClockFreqDivision(CMM_RegStruct *cmmx, CMM_Target_Freq_Div_Value value) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + CMM_PARAM_CHECK_NO_RET(value < CMM_TARGET_FREQ_DIV_MAX); + cmmx->CMTGTCTRL.BIT.tgtscale = value; +} + +/** + * @brief Gets the frequency divider of the target clock. + * @param cmmx CMM register base address. + * @retval unsigned int @ref CMM_Target_Freq_Div_Value. + */ +static inline unsigned int DCL_CMM_GetTargetClockFreqDivision(CMM_RegStruct *cmmx) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + return cmmx->CMTGTCTRL.BIT.tgtscale; +} + +/** + * @brief Sets the target clock source. + * @param cmmx CMM register base address. + * @param clockSource Specifies the type of the clock source. + * @retval None. + */ +static inline void DCL_CMM_SetTargetClockSource(CMM_RegStruct *cmmx, CMM_Target_Clock_Source clockSource) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + CMM_PARAM_CHECK_NO_RET(clockSource < CMM_TARGET_CLK_MAX); + cmmx->CMTGTCTRL.BIT.tgtsel = clockSource; +} + +/** + * @brief Gets the target clock source. + * @param cmmx CMM register base address. + * @retval unsigned int @ref CMM_Target_Clock_Source. + */ +static inline unsigned int DCL_CMM_GetTargetClockSource(CMM_RegStruct *cmmx) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + return cmmx->CMTGTCTRL.BIT.tgtsel; +} + +/** + * @brief Sets the frequency divider of the reference clock. + * @param cmmx CMM register base address. + * @param value Specified frequency divider. + * @retval None. + */ +static inline void DCL_CMM_SetRefClockFreqDivision(CMM_RegStruct *cmmx, CMM_Ref_Freq_Div_Value value) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + CMM_PARAM_CHECK_NO_RET(value < CMM_REF_FREQ_DIV_MAX); + cmmx->CMREFCTRL.BIT.refdiv = value; +} + +/** + * @brief Gets the frequency divider of the reference clock. + * @param cmmx CMM register base address. + * @retval unsigned int @ref CMM_Ref_Freq_Div_Value. + */ +static inline unsigned int DCL_CMM_GetRefClockFreqDivision(CMM_RegStruct *cmmx) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + return cmmx->CMREFCTRL.BIT.refdiv; +} + +/** + * @brief Sets the reference clock source. + * @param cmmx CMM register base address. + * @param clockSource Specified reference clock source. + * @retval None. + */ +static inline void DCL_CMM_SetRefClockSource(CMM_RegStruct *cmmx, CMM_Ref_Clock_Source clockSource) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + CMM_PARAM_CHECK_NO_RET(clockSource < CMM_REF_CLK_MAX); + cmmx->CMREFCTRL.BIT.refsel = clockSource; +} + +/** + * @brief Gets the reference clock source. + * @param cmmx CMM register base address. + * @retval unsigned int @ref CMM_Ref_Clock_Source. + */ +static inline unsigned int DCL_CMM_GetRefClockSource(CMM_RegStruct *cmmx) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + return cmmx->CMREFCTRL.BIT.refsel; +} + +/** + * @brief Sets the upper boundary of the detection window. + * @param cmmx CMM register base address. + * @param value The value of the upper bound. + * @retval None. + */ +static inline void DCL_CMM_SetWindowUpperBound(CMM_RegStruct *cmmx, unsigned short value) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + cmmx->CMWDOH.BIT.cmwdoh = value; +} + +/** + * @brief Gets the upper boundary of the detection window. + * @param cmmx CMM register base address. + * @retval The value of the upper bound. + */ +static inline unsigned short DCL_CMM_GetWindowUpperBound(CMM_RegStruct *cmmx) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + return cmmx->CMWDOH.BIT.cmwdoh; +} + +/** + * @brief Sets the lower boundary of the detection window. + * @param cmmx CMM register base address. + * @param value The value of the lower bound. + * @retval None. + */ +static inline void DCL_CMM_SetWindowLowerBound(CMM_RegStruct *cmmx, unsigned short value) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + cmmx->CMWDOL.BIT.cmwdol = value; +} + +/** + * @brief Gets the lower boundary of the detection window. + * @param cmmx CMM register base address. + * @retval The value of the lower bound. + */ +static inline unsigned short DCL_CMM_GetWindowLowerBound(CMM_RegStruct *cmmx) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + return cmmx->CMWDOL.BIT.cmwdol; +} + +/** + * @brief Internal counter count latch value. + * @param cmmx CMM register base address. + * @retval unsigned short. latch value. + */ +static inline unsigned short DCL_CMM_GetCntValue(CMM_RegStruct *cmmx) +{ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + return cmmx->CMCNTLOCK.BIT.cmcnt_lock; +} + +/** + * @brief Enables the specified type of interrupt. + * @param cmmx CMM register base address. + * @param type Mask of the interrupt type. + * @retval None. + */ +static inline void DCL_CMM_EnableInterrupt(CMM_RegStruct *cmmx, CMM_Interrupt_Type type) +{ + /* if define macro CMM_PARAM_CHECK, function of param check is valid */ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + CMM_PARAM_CHECK_NO_RET(type == CMM_INT_COUNTER_OVERFLOW_MASK || \ + type == CMM_INT_CHECK_END_MASK || \ + type == CMM_INT_FREQ_ERR_MASK); + cmmx->CMINTENA.reg |= type; +} + +/** + * @brief Disables the specified type of interrupt. + * @param cmmx CMM register base address. + * @param type Mask of the interrupt type. + * @retval None. + */ +static inline void DCL_CMM_DisableInterrupt(CMM_RegStruct *cmmx, CMM_Interrupt_Type type) +{ + /* if define macro CMM_PARAM_CHECK, function of param check is valid */ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + CMM_PARAM_CHECK_NO_RET(type == CMM_INT_COUNTER_OVERFLOW_MASK || \ + type == CMM_INT_CHECK_END_MASK || \ + type == CMM_INT_FREQ_ERR_MASK); + cmmx->CMINTENA.reg &= (~type); +} + +/** + * @brief Check whether the specified interrupt is triggered. + * @param cmmx CMM register base address. + * @param type Mask of the interrupt type. + * @retval bool. + */ +static inline bool DCL_CMM_GetInterruptStatus(CMM_RegStruct *cmmx, CMM_Interrupt_Type type) +{ + /* if define macro CMM_PARAM_CHECK, function of param check is valid */ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + CMM_PARAM_CHECK_WITH_RET(type == CMM_INT_COUNTER_OVERFLOW_MASK || \ + type == CMM_INT_CHECK_END_MASK || \ + type == CMM_INT_FREQ_ERR_MASK, false); + return (cmmx->CMINTSTS.reg & type) == 0 ? false : true; +} + +/** + * @brief Clears interrupts of the specified type. + * @param cmmx CMM register base address. + * @param type Mask of the interrupt type. + * @retval None. + */ +static inline void DCL_CMM_ClearInterrupt(CMM_RegStruct *cmmx, CMM_Interrupt_Type type) +{ + /* if define macro CMM_PARAM_CHECK, function of param check is valid */ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + CMM_PARAM_CHECK_NO_RET(type == CMM_INT_COUNTER_OVERFLOW_MASK || \ + type == CMM_INT_CHECK_END_MASK || \ + type == CMM_INT_FREQ_ERR_MASK); + cmmx->CMINTRAW.reg |= type; +} + +/** + * @brief Injects interrupts of the specified type. + * @param cmmx CMM register base address. + * @param type Mask of the interrupt type. + * @retval None. + */ +static inline void DCL_CMM_EnableInterruptInject(CMM_RegStruct *cmmx, CMM_Interrupt_Type type) +{ + /* if define macro CMM_PARAM_CHECK, function of param check is valid */ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + CMM_PARAM_CHECK_NO_RET(type == CMM_INT_COUNTER_OVERFLOW_MASK || \ + type == CMM_INT_CHECK_END_MASK || \ + type == CMM_INT_FREQ_ERR_MASK); + cmmx->CMINTINJ.reg |= type; +} + +/** + * @brief Stop injecting interrupts of a specified type. + * @param cmmx CMM register base address. + * @param type Mask of the interrupt type. + * @retval None. + */ +static inline void DCL_CMM_DisableInterruptInject(CMM_RegStruct *cmmx, CMM_Interrupt_Type type) +{ + /* if define macro CMM_PARAM_CHECK, function of param check is valid */ + CMM_ASSERT_PARAM(IsCMMInstance(cmmx)); + CMM_PARAM_CHECK_NO_RET(type == CMM_INT_COUNTER_OVERFLOW_MASK || \ + type == CMM_INT_CHECK_END_MASK || \ + type == CMM_INT_FREQ_ERR_MASK); + cmmx->CMINTINJ.reg &= (~type); +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* McuMagicTag_CMM_IP_H */ \ No newline at end of file diff --git a/src/drivers/cmm/cmm_v2/src/cmm.c b/src/drivers/cmm/cmm_v2/src/cmm.c new file mode 100644 index 0000000000000000000000000000000000000000..fdeeb15c796c6a3b38e5cea8eb6c04b8474c0403 --- /dev/null +++ b/src/drivers/cmm/cmm_v2/src/cmm.c @@ -0,0 +1,239 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file cmm.c + * @author MCU Driver Team + * @brief CMM module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the CMM. + * + Initialization and de-initialization functions. + * + Config the register of CMM. + * + Interrupt callback function and user registration function. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "interrupt.h" +#include "cmm.h" + +/** + * @brief Perform initial configuration based on the handle. + * @param handle CMM handle. + * @retval @ref BASE_StatusType. + */ +BASE_StatusType HAL_CMM_Init(CMM_Handle *handle) +{ + /* param check */ + CMM_ASSERT_PARAM(handle != NULL); + CMM_ASSERT_PARAM(IsCMMInstance(handle->baseAddress)); + CMM_PARAM_CHECK_WITH_RET(handle->targetClockSource < CMM_TARGET_CLK_MAX, BASE_STATUS_ERROR); + CMM_PARAM_CHECK_WITH_RET(handle->targetFreqDivision < CMM_TARGET_FREQ_DIV_MAX, BASE_STATUS_ERROR); + CMM_PARAM_CHECK_WITH_RET(handle->refClockSource < CMM_REF_CLK_MAX, BASE_STATUS_ERROR); + CMM_PARAM_CHECK_WITH_RET(handle->refFreqDivision < CMM_REF_FREQ_DIV_MAX, BASE_STATUS_ERROR); + CMM_PARAM_CHECK_WITH_RET(handle->interruptType < CMM_INT_MAX, BASE_STATUS_ERROR); + /* Init CMM target clock. */ + handle->baseAddress->CMTGTCTRL.BIT.tgtsel = handle->targetClockSource; + handle->baseAddress->CMTGTCTRL.BIT.tgtscale = handle->targetFreqDivision; + /* Init CMM reference clock. */ + handle->baseAddress->CMREFCTRL.BIT.refsel = handle->refClockSource; + handle->baseAddress->CMREFCTRL.BIT.refdiv = handle->refFreqDivision; + /* Init CMM UpperBound and LowerBound. */ + handle->baseAddress->CMWDOH.BIT.cmwdoh = handle->upperBound; + handle->baseAddress->CMWDOL.BIT.cmwdol = handle->lowerBound; + handle->baseAddress->CMINTENA.reg = handle->interruptType; + + return BASE_STATUS_OK; +} + +/** + * @brief Deinitialize configurations based on the handle. + * @param handle CMM handle. + * @retval @ref BASE_StatusType. + */ +BASE_StatusType HAL_CMM_DeInit(CMM_Handle *handle) +{ + CMM_ASSERT_PARAM(handle != NULL); + CMM_ASSERT_PARAM(IsCMMInstance(handle->baseAddress)); + /* Clear interrupt callback function. */ + handle->userCallBack.FreqErrorCallback = NULL; + handle->userCallBack.CheckEndCallback = NULL; + handle->userCallBack.CountOverflowCallback = NULL; + /* Clear register value. */ + handle->baseAddress->CMREFCTRL.reg = BASE_CFG_DISABLE; + handle->baseAddress->CMINTENA.reg = BASE_CFG_DISABLE; + return BASE_STATUS_OK; +} + + +/** + * @brief Set this parameter based on the configuration item parameters. + * @param handle CMM handle. + * @param cfgType Configurable item. @ref CMM_CFG_TYPE. + * @retval @ref BASE_StatusType. + */ +BASE_StatusType HAL_CMM_Config(CMM_Handle *handle, CMM_CFG_TYPE cfgType) +{ + /* param check */ + CMM_ASSERT_PARAM(handle != NULL); + CMM_ASSERT_PARAM(IsCMMInstance(handle->baseAddress)); + CMM_PARAM_CHECK_WITH_RET(handle->targetClockSource < CMM_TARGET_CLK_MAX, BASE_STATUS_ERROR); + CMM_PARAM_CHECK_WITH_RET(handle->mode < CMM_TRIGGER_MAX, BASE_STATUS_ERROR); + CMM_PARAM_CHECK_WITH_RET(handle->targetFreqDivision < CMM_TARGET_FREQ_DIV_MAX, BASE_STATUS_ERROR); + CMM_PARAM_CHECK_WITH_RET(handle->refClockSource < CMM_REF_CLK_MAX, BASE_STATUS_ERROR); + CMM_PARAM_CHECK_WITH_RET(handle->refFreqDivision < CMM_REF_FREQ_DIV_MAX, BASE_STATUS_ERROR); + CMM_PARAM_CHECK_WITH_RET(handle->interruptType < CMM_INT_MAX, BASE_STATUS_ERROR); + /* config register value with different type of cmm member */ + switch (cfgType) { + case CMM_CFG_UPPER_BOUND: + handle->baseAddress->CMWDOH.BIT.cmwdoh = handle->upperBound; /* upperBound value */ + break; + case CMM_CFG_LOWER_BOUND: + handle->baseAddress->CMWDOL.BIT.cmwdol = handle->lowerBound; /* lowerBound value */ + break; + case CMM_CFG_TARGET_SOURCE: + handle->baseAddress->CMTGTCTRL.BIT.tgtsel = handle->targetClockSource; /* target Clock Source */ + break; + case CMM_CFG_TARGET_FREQ_DIV: + handle->baseAddress->CMTGTCTRL.BIT.tgtscale = handle->targetFreqDivision; /* target Freq Division */ + break; + case CMM_CFG_REF_SOURCE: + handle->baseAddress->CMREFCTRL.BIT.refsel = handle->refClockSource; /* ref Clock Source */ + break; + case CMM_CFG_REF_FREQ_DIV: + handle->baseAddress->CMREFCTRL.BIT.refdiv = handle->refFreqDivision; /* ref Freq Division */ + break; + case CMM_CFG_INT_TYPE: + handle->baseAddress->CMINTENA.reg = handle->interruptType; /* interrupt Type */ + break; + default: + return BASE_STATUS_ERROR; + } + return BASE_STATUS_OK; +} + +/** + * @brief Reads the register configuration value to the handle. + * @param handle CMM handle. + * @retval None. + */ +void HAL_CMM_GetConfig(CMM_Handle *handle) +{ + /* param check */ + CMM_ASSERT_PARAM(handle != NULL); + CMM_ASSERT_PARAM(IsCMMInstance(handle->baseAddress)); + /* Get config of cmm member from register */ + handle->upperBound = handle->baseAddress->CMWDOH.BIT.cmwdoh; + handle->lowerBound = handle->baseAddress->CMWDOL.BIT.cmwdol; + handle->targetClockSource = handle->baseAddress->CMTGTCTRL.BIT.tgtsel; + handle->targetFreqDivision = handle->baseAddress->CMTGTCTRL.BIT.tgtscale; + handle->refClockSource = handle->baseAddress->CMREFCTRL.BIT.refsel; + handle->refFreqDivision = handle->baseAddress->CMREFCTRL.BIT.refdiv; +} + +/** + * @brief Start CMM Module. + * @param handle CMM handle. + * @retval None. + */ +void HAL_CMM_Start(CMM_Handle *handle) +{ + CMM_ASSERT_PARAM(handle != NULL); + CMM_ASSERT_PARAM(IsCMMInstance(handle->baseAddress)); + + handle->baseAddress->CMCTRL.BIT.cmen = BASE_CFG_ENABLE; +} + +/** + * @brief Stop CMM Module. + * @param handle CMM handle. + * @retval None. + */ +void HAL_CMM_Stop(CMM_Handle *handle) +{ + CMM_ASSERT_PARAM(handle != NULL); + CMM_ASSERT_PARAM(IsCMMInstance(handle->baseAddress)); + + handle->baseAddress->CMCTRL.BIT.cmen = BASE_CFG_DISABLE; +} + +/** + * @brief Registers the interrupt function to the specified interrupt type. + * @param handle CMM handle. + * @param type Specified interrupt type. + * @param callback Interrupt callback function. + * @retval @ref BASE_StatusType. + */ +BASE_StatusType HAL_CMM_RegisterCallback(CMM_Handle *handle, CMM_Interrupt_Type type, CMM_CallBackFuncType callback) +{ + CMM_ASSERT_PARAM(handle != NULL); + CMM_ASSERT_PARAM(callback != NULL); + CMM_ASSERT_PARAM(IsCMMInstance(handle->baseAddress)); + + switch (type) { + case CMM_INT_FREQ_ERR_MASK: /* Frequence error interrupt. */ + handle->userCallBack.FreqErrorCallback = callback; + break; + case CMM_INT_CHECK_END_MASK: /* Check end interrupt. */ + handle->userCallBack.CheckEndCallback = callback; + break; + case CMM_INT_COUNTER_OVERFLOW_MASK: /* Counter overflow interrupt. */ + handle->userCallBack.CountOverflowCallback = callback; + break; + default: + return BASE_STATUS_ERROR; + } + + return BASE_STATUS_OK; +} + +/** + * @brief Interrupt service processing function. + * @param handle CMM Handle. + * @retval None. + */ +void HAL_CMM_IrqHandler(void *handle) +{ + CMM_ASSERT_PARAM(handle != NULL); + CMM_Handle *cmmHandle = (CMM_Handle *)handle; + CMM_ASSERT_PARAM(IsCMMInstance(cmmHandle->baseAddress)); + + /**< Frequence error interrupt. */ + if (cmmHandle->baseAddress->CMINTSTS.BIT.freq_err_int == 0x01) { + cmmHandle->baseAddress->CMINTRAW.BIT.freq_err_raw = BASE_CFG_SET; + /* Disable and then enable the CMM to ensure that the CMM can still work. */ + cmmHandle->baseAddress->CMCTRL.BIT.cmen = BASE_CFG_UNSET; + cmmHandle->baseAddress->CMCTRL.BIT.cmen = BASE_CFG_SET; + if (cmmHandle->userCallBack.FreqErrorCallback) { + cmmHandle->userCallBack.FreqErrorCallback(cmmHandle); + } + } + + /**< Check end interrupt. */ + if (cmmHandle->baseAddress->CMINTSTS.BIT.chk_end_int == 0x01) { + cmmHandle->baseAddress->CMINTRAW.BIT.chk_end_raw = BASE_CFG_SET; + if (cmmHandle->userCallBack.CheckEndCallback) { + cmmHandle->userCallBack.CheckEndCallback(cmmHandle); + } + } + + /**< Counter overflow interrupt. */ + if (cmmHandle->baseAddress->CMINTSTS.BIT.cnt_ovf_int == 0x01) { + cmmHandle->baseAddress->CMINTRAW.BIT.cnt_ovf_raw = BASE_CFG_SET; + if (cmmHandle->userCallBack.CountOverflowCallback) { + cmmHandle->userCallBack.CountOverflowCallback(cmmHandle); + } + } +} \ No newline at end of file diff --git a/src/drivers/cmm/common/inc/cmm.h b/src/drivers/cmm/common/inc/cmm.h index fedc5f3680e16c738531803a24eea25efe811b87..eecf69c825cd22ac395d2be4090713869bdc31dc 100644 --- a/src/drivers/cmm/common/inc/cmm.h +++ b/src/drivers/cmm/common/inc/cmm.h @@ -97,6 +97,7 @@ typedef void (*CMM_CallBackFuncType)(void *handle); */ /* Hardware abstraction layer functions -------------------------------------------------------- */ + BASE_StatusType HAL_CMM_Init(CMM_Handle *handle); BASE_StatusType HAL_CMM_DeInit(CMM_Handle *handle); BASE_StatusType HAL_CMM_Config(CMM_Handle *handle, CMM_CFG_TYPE cfgType); diff --git a/src/drivers/crc/crc_v0/inc/crc_ip.h b/src/drivers/crc/crc_v0/inc/crc_ip.h index a8f877daa9428384959887d2763c18e5fdb7a842..ba497b8db9a6b8335e0ffa278a3a03c2e4691711 100644 --- a/src/drivers/crc/crc_v0/inc/crc_ip.h +++ b/src/drivers/crc/crc_v0/inc/crc_ip.h @@ -65,7 +65,7 @@ * +CRC16_MODBUS -- CRC-16/MODBUS algorithm, CRC16_8005, crc_mode reg value:b010 * +CRC16_CCITT_FALSE -- CRC-16/CCITT-FALSE algorithm, CRC16_1021, crc_mode reg value:b011 * +CRC16_XMODEM -- CRC-16/XMODEM algorithm, CRC16_1021, crc_mode reg value:b011 - * +CRC32 -- CRC32 algorithm, CRC32_04C11D87, crc_mode reg value:b10x + * +CRC32 -- CRC32 algorithm, CRC32_04C11DB7, crc_mode reg value:b10x * +CRC_ALG_MODE_MAX -- CRC_mode bunder */ typedef enum { @@ -86,8 +86,8 @@ typedef enum { CRC8_07_POLY_MODE_BK = 0x00000001U, CRC16_8005_POLY_MODE = 0x00000002U, CRC16_1021_POLY_MODE = 0x00000003U, - CRC32_04C11D87_POLY_MODE = 0x00000004U, - CRC32_04C11D87_POLY_MODE_BK = 0x00000005U, + CRC32_04C11DB7_POLY_MODE = 0x00000004U, + CRC32_04C11DB7_POLY_MODE_BK = 0x00000005U, CRC_POLY_MODE_MAX } CRC_PolynomialMode; @@ -543,7 +543,7 @@ static inline bool IsCrcPolynomial(CRC_PolynomialMode mode) /* Check crc polynomial mode. */ return (mode == CRC8_07_POLY_MODE || mode == CRC8_07_POLY_MODE_BK || \ mode == CRC16_8005_POLY_MODE || mode == CRC16_1021_POLY_MODE || \ - mode == CRC32_04C11D87_POLY_MODE || mode == CRC32_04C11D87_POLY_MODE_BK); + mode == CRC32_04C11DB7_POLY_MODE || mode == CRC32_04C11DB7_POLY_MODE_BK); } /** diff --git a/src/drivers/crc/crc_v0/src/crc.c b/src/drivers/crc/crc_v0/src/crc.c index 6889954a47e7e1730d250389b05cefa84fc6ed26..298118148fed0d53cbf8743763d649a1c55ead6a 100644 --- a/src/drivers/crc/crc_v0/src/crc.c +++ b/src/drivers/crc/crc_v0/src/crc.c @@ -346,7 +346,7 @@ static void CRC_SetPolynomialModeByAlgorithm(CRC_RegStruct *crcx, CRC_AlgorithmM } else if (algorithmMode == CRC16_IBM || algorithmMode == CRC16_MODBUS) { polyMode = CRC16_8005_POLY_MODE; } else if (algorithmMode == CRC32) { - polyMode = CRC32_04C11D87_POLY_MODE; + polyMode = CRC32_04C11DB7_POLY_MODE; } /* config register */ DCL_CRC_SetPolynomialMode(crcx, polyMode); diff --git a/src/drivers/crc/crc_v1/inc/crc_ip.h b/src/drivers/crc/crc_v1/inc/crc_ip.h index 3eb7502f1913cab00c87866d97d465bd95198978..53c157beb975ab979a40e35b25978ca8ba28990a 100644 --- a/src/drivers/crc/crc_v1/inc/crc_ip.h +++ b/src/drivers/crc/crc_v1/inc/crc_ip.h @@ -74,8 +74,8 @@ typedef enum { CRC8_07_POLY_MODE_BK = 0x00000001U, CRC16_8005_POLY_MODE = 0x00000002U, CRC16_1021_POLY_MODE = 0x00000003U, - CRC32_04C11D87_POLY_MODE = 0x00000004U, - CRC32_04C11D87_POLY_MODE_BK = 0x00000005U, + CRC32_04C11DB7_POLY_MODE = 0x00000004U, + CRC32_04C11DB7_POLY_MODE_BK = 0x00000005U, CRC_POLY_MODE_MAX } CRC_PolynomialMode; @@ -163,9 +163,9 @@ typedef enum { CRC16_XMODEM = ENABLE_XOR_ENABLE_LSB | REVERSE_INPUT_FALSE_OUTPUT_FALSE | TYPE_CRC_XOR_VALUE_0000 | \ TYPE_CRC_INIT_VALUE_0000 | CRC16_1021_POLY_MODE, CRC32 = ENABLE_XOR_ENABLE_LSB | REVERSE_INPUT_TURE_OUTPUT_TRUE | TYPE_CRC_XOR_VALUE_FFFFFFFF | \ - TYPE_CRC_INIT_VALUE_FFFFFFFF | CRC32_04C11D87_POLY_MODE, + TYPE_CRC_INIT_VALUE_FFFFFFFF | CRC32_04C11DB7_POLY_MODE, CRC32_MPEG2 = ENABLE_XOR_ENABLE_LSB | REVERSE_INPUT_FALSE_OUTPUT_FALSE | TYPE_CRC_XOR_VALUE_00000000 | \ - TYPE_CRC_INIT_VALUE_FFFFFFFF | CRC32_04C11D87_POLY_MODE, + TYPE_CRC_INIT_VALUE_FFFFFFFF | CRC32_04C11DB7_POLY_MODE, CRC_ALG_MODE_MAX } CRC_AlgorithmMode; @@ -520,7 +520,7 @@ static inline bool IsCrcPolynomial(unsigned int mode) /* Check crc polynomial mode. */ return (mode == CRC8_07_POLY_MODE || mode == CRC8_07_POLY_MODE_BK || \ mode == CRC16_8005_POLY_MODE || mode == CRC16_1021_POLY_MODE || \ - mode == CRC32_04C11D87_POLY_MODE || mode == CRC32_04C11D87_POLY_MODE_BK); + mode == CRC32_04C11DB7_POLY_MODE || mode == CRC32_04C11DB7_POLY_MODE_BK); } /** diff --git a/src/drivers/crg/crg_v0/inc/crg_ip.h b/src/drivers/crg/crg_v0/inc/crg_ip.h index b53d0d190db02fc3f3f9cf7ccaa0c646dbd801e1..6cd2020c408555b7c7976988dffdf514fe8adebe 100644 --- a/src/drivers/crg/crg_v0/inc/crg_ip.h +++ b/src/drivers/crg/crg_v0/inc/crg_ip.h @@ -240,16 +240,15 @@ typedef enum { * @brief CRG Test Clock Select */ typedef enum { - CRG_TEST_CLK_PLL = 0x00000000U, CRG_TEST_CLK_HOSC = 0x00000001U, CRG_TEST_CLK_LOSC = 0x00000002U, CRG_TEST_CLK_XTAL = 0x00000003U, CRG_TEST_CLK_DAC0 = 0x00000004U, CRG_TEST_CLK_DAC1 = 0x00000005U, CRG_TEST_CLK_DAC2 = 0x00000006U, - CRG_TEST_CLK_ADC0 = 0x00000007U, - CRG_TEST_CLK_ADC1 = 0x00000008U, - CRG_TEST_CLK_ADC2 = 0x00000009U, + CRG_TEST_CLK_ADC0_DIV2 = 0x00000007U, + CRG_TEST_CLK_ADC1_DIV2 = 0x00000008U, + CRG_TEST_CLK_ADC2_DIV2 = 0x00000009U, } CRG_TestClkSel; /** @@ -1246,8 +1245,8 @@ static inline void DCL_CRG_TestClkDisable(CRG_RegStruct *clk) static inline void DCL_CRG_TestClkSel(CRG_RegStruct *clk, CRG_TestClkSel clkSel) { CRG_ASSERT_PARAM(IsCRGInstance(clk)); - CRG_PARAM_CHECK_NO_RET(clkSel >= CRG_TEST_CLK_PLL); - CRG_PARAM_CHECK_NO_RET(clkSel <= CRG_TEST_CLK_ADC2); + CRG_PARAM_CHECK_NO_RET(clkSel >= CRG_TEST_CLK_HOSC); + CRG_PARAM_CHECK_NO_RET(clkSel <= CRG_TEST_CLK_ADC2_DIV2); clk->PERI_CRG47.BIT.test_clk_sel = clkSel; } /** diff --git a/src/drivers/crg/crg_v0/src/crg.c b/src/drivers/crg/crg_v0/src/crg.c index a2f12b9d7c830393db0706493b404910410ad18b..70a9be8fbae55e0bae03d4fb39d9060c52440af5 100644 --- a/src/drivers/crg/crg_v0/src/crg.c +++ b/src/drivers/crg/crg_v0/src/crg.c @@ -323,8 +323,8 @@ static inline unsigned int CRG_GetVcoFreq(void) CRG_ASSERT_PARAM(IsCRGInstance(crg)); freq = CRG_GetPllRefIni(crg->PERI_CRG0.pll_ref_cksel); - freq /= CRG_GetPreDivValue(crg->PERI_CRG1.pll_prediv); freq *= CRG_GetPllFbDivValue(crg->PERI_CRG2.pll_fbdiv); + freq /= CRG_GetPreDivValue(crg->PERI_CRG1.pll_prediv); return freq; } @@ -506,14 +506,14 @@ BASE_StatusType HAL_CRG_IpClkSelectSet(const void *baseAddress, unsigned int sel /** * @brief Get clock select of ip * @param baseAddress Ip base address - * @param clkSel Get clkSet value + * @param select Get clkSet value * @retval BASE_STATUS_OK * @retval BASE_STATUS_ERROR Match Fail or Not support */ -BASE_StatusType HAL_CRG_IpClkSelectGet(const void *baseAddress, unsigned int *clkSel) +BASE_StatusType HAL_CRG_IpClkSelectGet(const void *baseAddress, unsigned int *select) { CRG_ASSERT_PARAM(baseAddress != NULL); - CRG_ASSERT_PARAM(clkSel != NULL); + CRG_ASSERT_PARAM(select != NULL); CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); CHIP_CrgIpMatchInfo *p = GetCrgIpMatchInfo(baseAddress); @@ -527,7 +527,7 @@ BASE_StatusType HAL_CRG_IpClkSelectGet(const void *baseAddress, unsigned int *cl if (g_ipClkProc[p->type].clkSelGet == NULL) { return BASE_STATUS_ERROR; } - *clkSel = g_ipClkProc[p->type].clkSelGet(p); + *select = g_ipClkProc[p->type].clkSelGet(p); /* Obtains the module clock selection. */ return BASE_STATUS_OK; } diff --git a/src/drivers/crg/crg_v1/inc/crg_ip.h b/src/drivers/crg/crg_v1/inc/crg_ip.h index 3ee147c20c22ec13f36d00c7fa8935b46776824f..f938adca626c11703a0d1fbd60e210f90923c671 100644 --- a/src/drivers/crg/crg_v1/inc/crg_ip.h +++ b/src/drivers/crg/crg_v1/inc/crg_ip.h @@ -208,7 +208,6 @@ typedef enum { * @brief CRG Test Clock Select */ typedef enum { - CRG_TEST_CLK_PLL_PFD = 0x00000000U, CRG_TEST_CLK_HOSC = 0x00000001U, CRG_TEST_CLK_LOSC = 0x00000002U, CRG_TEST_CLK_TCXO = 0x00000003U, @@ -1716,7 +1715,7 @@ static inline void DCL_CRG_TestClkDisable(CRG_RegStruct *clk) static inline void DCL_CRG_TestClkSel(CRG_RegStruct *clk, CRG_TestClkSel clkSel) { CRG_ASSERT_PARAM(IsCRGInstance(clk)); - CRG_PARAM_CHECK_NO_RET(clkSel >= CRG_TEST_CLK_PLL_PFD); + CRG_PARAM_CHECK_NO_RET(clkSel >= CRG_TEST_CLK_HOSC); CRG_PARAM_CHECK_NO_RET(clkSel <= CRG_TEST_CLK_HOSC_DIV); clk->PERI_CRG639.BIT.test_clk_sel = clkSel; /* Set the test clock select. */ } diff --git a/src/drivers/crg/crg_v1/src/crg.c b/src/drivers/crg/crg_v1/src/crg.c index 9dd7c7af8581a282c3f21ee08b4168d57e62a66d..162f6540d5cceceea4b3512b4a87cac7793a70a6 100644 --- a/src/drivers/crg/crg_v1/src/crg.c +++ b/src/drivers/crg/crg_v1/src/crg.c @@ -291,9 +291,9 @@ static inline unsigned int CRG_GetVcoFreq(void) CRG_ASSERT_PARAM((XTRAIL_FREQ <= 30000000U)); /* The maximum of the external clock source is 30000000U. */ freq = CRG_GetPllRefIni(crg->PERI_CRG0.BIT.pll_ref_cksel); - freq /= CRG_GetPreDivValue(crg->PERI_CRG1.BIT.pll_prediv); regFbdiv = CRG_GetPllFbDivValue(crg->PERI_CRG2.BIT.pll_fbdiv); /* Get the value of the fbdiv register. */ freq *= (regFbdiv >= 0x06) ? regFbdiv : 0x06; /* 0x0-0x6: divided by 0x6 */ + freq /= CRG_GetPreDivValue(crg->PERI_CRG1.BIT.pll_prediv); return freq; } @@ -475,14 +475,14 @@ BASE_StatusType HAL_CRG_IpClkSelectSet(const void *baseAddress, unsigned int sel /** * @brief Get clock select of ip * @param baseAddress Ip base address - * @param clkSel Get clkSet value + * @param select Get clkSet value * @retval BASE_STATUS_OK * @retval BASE_STATUS_ERROR Match Fail or Not support */ -BASE_StatusType HAL_CRG_IpClkSelectGet(const void *baseAddress, unsigned int *clkSel) +BASE_StatusType HAL_CRG_IpClkSelectGet(const void *baseAddress, unsigned int *select) { CRG_ASSERT_PARAM(baseAddress != NULL); - CRG_ASSERT_PARAM(clkSel != NULL); + CRG_ASSERT_PARAM(select != NULL); CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); /* Get the CRG type of the target IP. */ CHIP_CrgIpMatchInfo *p = GetCrgIpMatchInfo(baseAddress); @@ -492,7 +492,7 @@ BASE_StatusType HAL_CRG_IpClkSelectGet(const void *baseAddress, unsigned int *cl if (g_ipClkProc[p->type].clkSelGet == NULL) { return BASE_STATUS_ERROR; } - *clkSel = g_ipClkProc[p->type].clkSelGet(p); /* Obtains the module clock selection. */ + *select = g_ipClkProc[p->type].clkSelGet(p); /* Obtains the module clock selection. */ return BASE_STATUS_OK; } diff --git a/src/drivers/crg/crg_v3/inc/crg_ip.h b/src/drivers/crg/crg_v3/inc/crg_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..26028e22f25a0c38e3dd7e1e259ceef86d25d716 --- /dev/null +++ b/src/drivers/crg/crg_v3/inc/crg_ip.h @@ -0,0 +1,1951 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file crg_ip.h + * @author MCU Driver Team + * @brief TIMER module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the TIMER. + * + CRG register mapping structure + * + Direct Configuration Layer functions of CRG + */ +#ifndef McuMagicTag_CRG_IP_H +#define McuMagicTag_CRG_IP_H + +/* Includes ------------------------------------------------------------------*/ +#include "baseinc.h" + +/** + * @addtogroup CRG + * @{ + */ + +/** + * @defgroup CRG_IP CRG_IP + * @brief CRG_IP: crg_v1 + * @{ + */ + +/** + * @defgroup CRG_Param_Def CRG Parameters Definition + * @brief Definition of CRG configuration parameters. + * @{ + */ +#ifdef CRG_PARAM_CHECK +#define CRG_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM +#define CRG_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET +#define CRG_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else +#define CRG_ASSERT_PARAM(para) ((void)0U) +#define CRG_PARAM_CHECK_NO_RET(para) ((void)0U) +#define CRG_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) +#endif + +#define IP_CLK_DISABLE 0x00000000U /**< IP Clock disable bitmask */ +#define IP_CLK_ENABLE 0x00000001U /**< IP Clock disable bitmask */ +#define HPM_CLK_ENABLE 0x00000001U /**< HPM Clock enable bitmask */ +#define HPM_1M_CLK_ENABLE 0x00000002U /**< HPM 1M Clock enable bitmask */ +#define IP_SYSCLK_ENABLE 0x00000002U /**< IP SysClock disable bitmask, Only valid for ADC */ + +#define DAC_DIV_BITLEN 4U /**< DIV bit length */ +#define DAC_DIV_MASK ((1 << DAC_DIV_BITLEN) - 1) /**< DAC div mask, base on the bit length */ + +#define ADC_DIV_FACTOR (1 << 1) /**< ADC div min factor */ +#define CRG_1MHZ_CLK_MAX_DIV 63 +#define CRG_FREQ_1MHz (1000 * 1000) +#define CRG_CLK_PFD_MIN_FREQ (4 * CRG_FREQ_1MHz) +#define CRG_CLK_PFD_MAX_FREQ (10 * CRG_FREQ_1MHz) +#define CRG_CLK_VCO_MIN_FREQ (200 * CRG_FREQ_1MHz) +#define CRG_CLK_VCO_MAX_FREQ (400 * CRG_FREQ_1MHz) +#define CRG_CLK_TARGET_MAX_FREQ (200 * CRG_FREQ_1MHz) +#define CRG_CLK_PST2_MAX_FREQ (100 * CRG_FREQ_1MHz) +/** + * @brief PLL refer clock Select + */ +typedef enum { + CRG_PLL_REF_CLK_SELECT_HOSC = 0, + CRG_PLL_REF_CLK_SELECT_XTAL = 1, +} CRG_PllRefClkSelect; + +/** + * @brief PLL previous divsion value in register + */ +typedef enum { + CRG_PLL_PREDIV_1 = 0, + CRG_PLL_PREDIV_2 = 1, + CRG_PLL_PREDIV_3 = 2, + CRG_PLL_PREDIV_4 = 3, + CRG_PLL_PREDIV_5 = 4, + CRG_PLL_PREDIV_6 = 5, + CRG_PLL_PREDIV_7 = 6, + CRG_PLL_PREDIV_8 = 7, +} CRG_PllPreDiv; + +/** + * @brief PLL previous divison value in Calc frequency + */ +typedef enum { + PLL_PREDIV_OUT_1 = 1, + PLL_PREDIV_OUT_2 = 2, + PLL_PREDIV_OUT_3 = 3, + PLL_PREDIV_OUT_4 = 4, + PLL_PREDIV_OUT_5 = 5, + PLL_PREDIV_OUT_6 = 6, + PLL_PREDIV_OUT_7 = 7, + PLL_PREDIV_OUT_8 = 8, +} PLL_PreDivOut; + +/** + * @brief PLL post division 1 value in register + */ +typedef enum { + CRG_PLL_POSTDIV_1 = 0, + CRG_PLL_POSTDIV_2 = 1, + CRG_PLL_POSTDIV_3 = 2, + CRG_PLL_POSTDIV_4 = 3, + CRG_PLL_POSTDIV_5 = 4, + CRG_PLL_POSTDIV_6 = 5, + CRG_PLL_POSTDIV_7 = 6, + CRG_PLL_POSTDIV_8 = 7, +} CRG_PllPostDiv; + +/** + * @brief PLL post division 2 value in register + */ +typedef enum { + CRG_PLL_POSTDIV2_1 = 0, + CRG_PLL_POSTDIV2_2 = 1, + CRG_PLL_POSTDIV2_3 = 2, + CRG_PLL_POSTDIV2_4 = 3, + CRG_PLL_POSTDIV2_5 = 4, + CRG_PLL_POSTDIV2_6 = 5, + CRG_PLL_POSTDIV2_7 = 6, + CRG_PLL_POSTDIV2_8 = 7, +} CRG_PllPostDiv2; + + +/** + * @brief Core clock selection + * @note default select HOSC + */ +typedef enum { + CRG_CORE_CLK_SELECT_HOSC = 0, + CRG_CORE_CLK_SELECT_TCXO = 1, + CRG_CORE_CLK_SELECT_PLL = 2, +} CRG_CoreClkSelect; + +/** + * @brief Core clock selection 2 + * @note default select HOSC + */ +typedef enum { + CRG_CORE_CLK2_SELECT_HOSC = 0, + CRG_CORE_CLK2_SELECT_TCXO = 1, + CRG_CORE_CLK2_SELECT_PLL = 2, +} CRG_CoreClkSelect2; + +/** + * @brief 1M clock selection + * @note default select HOSC + */ +typedef enum { + CRG_1M_CLK_SELECT_HOSC = 0, + CRG_1M_CLK_SELECT_TCXO = 1, +} CRG_1MClkSelect; + +/** + * @brief PLL frequency multiplication range + */ +typedef enum { + CRG_PLL_FBDIV_MIN = 6, + CRG_PLL_FBDIV_MAX = 127, +} CRG_PllFbDivRange; + +/** + * @brief PLL diagnose post div selection + */ +typedef enum { + CRG_PLL_DIG_POST_DIV_SELECT_FREF = 0, + CRG_PLL_DIG_POST_DIV_SELECT_PLL = 1, +} CRG_PllDigPostDivInSelect; + +/** + * @brief PLL diagnose loct detect lpsel + */ +typedef enum { + CRG_PLL_DIG_LOCKDET_LP_SELECT_2048 = 0, + CRG_PLL_DIG_LOCKDET_LP_SELECT_1024 = 1, + CRG_PLL_DIG_LOCKDET_LP_SELECT_512 = 2, + CRG_PLL_DIG_LOCKDET_LP_SELECT_256 = 3, +} CRG_PllDigLockDetLpSelect; + +/** + * @brief PLL Test selection + */ +typedef enum { + CRG_PLL_TEST_SELECT_FPFD = 0, + CRG_PLL_TEST_SELECT_CKFB = 1, + CRG_PLL_TEST_SELECT_LOCKDET_OUTPUT = 2, + CRG_PLL_TEST_SELECT_FOUTPOSTDIV_128 = 3, + CRG_PLL_TEST_SELECT_OUTPUT_0 = 4, +} CRG_PllDigTestSelect; + +/** + * @brief CRG Test Clock Select + */ +typedef enum { + CRG_TEST_CLK_HOSC = 0x00000001U, + CRG_TEST_CLK_LOSC = 0x00000002U, + CRG_TEST_CLK_TCXO = 0x00000003U, + CRG_TEST_CLK_BG_CHOPPER = 0x00000004U, + CRG_TEST_CLK_ADC_DIV4 = 0x00000005U, + CRG_TEST_CLK_HCLK_DIV6 = 0x00000006U, + CRG_TEST_CLK_HOSC_DIV = 0x00000007U, +} CRG_TestClkSel; + +/** + * @brief ADC source clock select + */ +typedef enum { + CRG_ADC_CLK_ASYN_HOSC = 0, + CRG_ADC_CLK_ASYN_TCXO = 1, + CRG_ADC_CLK_ASYN_PLL_DIV = 2, + CRG_ADC_CLK_SYN_CORE = 3, +} CRG_AdcClkSelect; + +/** + * @brief ADC synchronous and asynchronous clock source selection + */ +typedef enum { + CRG_ADC_CLK_ASYNCHRONOUS = 0, + CRG_ADC_CLK_SYNCHRONOUS = 1, +} CRG_AdcClkModeSelect; + +/** + * @brief ADC Div set Value + */ +typedef enum { + CRG_ADC_DIV_1 = 0, + CRG_ADC_DIV_2 = 1, + CRG_ADC_DIV_3 = 2, + CRG_ADC_DIV_4 = 3, +} CRG_AdcDiv; + +/** + * @brief CRG Extra Handle, include CRG's other config + */ +typedef struct { + CRG_PllPostDiv2 pllPostDiv2; /**< PLL post 2 ratio */ + CRG_1MClkSelect clk1MSelect; /**< 1M clock selection */ + unsigned int clk1MDiv; /**< 1M clock ratio */ +} CRG_ExtendHandle; + +/** + * @brief PLL Divison Config + */ +typedef struct { + unsigned int PreDiv; + unsigned int fbDiv; + unsigned int postDiv; +} CRG_PllDivCfg; + +/** + * @brief APB_HS_SUBSYS IP config + */ +typedef union { + unsigned int value; + struct { + unsigned int clkEnMask : 16; + unsigned int softResetReq : 16; + } BIT; +} volatile CRG_IpWoClkSelectCfg; + +/** + * @brief ADC config + * @see PERI_CRG41_Reg and PERI_CRG42_Reg and PERI_CRG43_Reg + */ +typedef union { + unsigned int value[2]; + struct { + unsigned int eflash_cken : 1; + unsigned int reserved0 : 31; + unsigned int eflash_clk_tick_cksel : 1; + unsigned int reserved1 : 31; + } BIT; +} volatile CRG_EfcIpCfg; + +typedef union { + unsigned int value[2]; + struct { + unsigned int clk_adc_div0 : 2; + unsigned int reserved0 : 6; + unsigned int clk_adc_div1 : 2; + unsigned int reserved1 : 22; + unsigned int clk_adc_cken : 1; + unsigned int reserved2 : 15; + unsigned int adc_srst_req : 1; + unsigned int reserved3 : 7; + unsigned int cfg_adc_ckmode_sel : 1; + unsigned int reserved4 : 7; + } BIT; +} volatile CRG_AdcIpCfg; + +/** + * @brief DAC config + * @see PERI_CRG45_Reg + */ +typedef union { + unsigned int value; + struct { + unsigned int clkEnMask : 3; + unsigned int reserved0 : 1; + unsigned int div : 12; + unsigned int softResetReq : 3; + unsigned int reserved1 : 13; + } BIT; +} volatile CRG_DacIpCfg; + +/** + * @brief ANA config + * @see PERI_CRG664_Reg - PERI_CRG677_Reg + */ +typedef union { + unsigned int value; + struct { + unsigned int reserved0 : 16; + unsigned int ip_srst_req : 1; + unsigned int reserved1 : 15; + } BIT; +} volatile CRG_AnaIpCfg; + +/** + * @brief IP match info for ip process + */ +typedef struct { + void *baseAddr; /**< Base address of ip */ + unsigned int offset; /**< The offset in CRG_RegStruct */ + unsigned int idx; /**< index in Reg, for example: 0 -capm0_cken 1 - capm1_cken in PERI_CRG30_Reg */ +} CRG_IpMatchInfo; + +/** + * @} + */ + +/** + * @brief CRG REG0 registers union structure definition. + */ +/* Define the union U_CRG_CKREF_CKEL */ +typedef union { + unsigned int reg; + struct { + unsigned int pll_ref_cksel : 1 ; /* [0] */ + unsigned int reserved0 : 31 ; /* [31..1] */ + } BIT; +} volatile CRG_CKREF_CKEL_REG; + +/* Define the union volatile CRG_PLL_PREDIV */ +typedef union { + unsigned int reg; + struct { + unsigned int pll_prediv : 4 ; /* [3..0] */ + unsigned int reserved0 : 28 ; /* [31..4] */ + } BIT; +} volatile CRG_PLL_PREDIV_REG; + +/* Define the union volatile CRG_PLL_FBDIV */ +typedef union { + unsigned int reg; + struct { + unsigned int pll_fbdiv : 8 ; /* [7..0] */ + unsigned int reserved0 : 24 ; /* [31..8] */ + } BIT; +} volatile CRG_PLL_FBDIV_REG; + +/* Define the union volatile CRG_PLL_PSTDIV */ +typedef union { + unsigned int reg; + struct { + unsigned int pll_postdiv1 : 4 ; /* [3..0] */ + unsigned int pll_postdiv2 : 4 ; /* [7..4] */ + unsigned int reserved0 : 24 ; /* [31..8] */ + } BIT; +} volatile CRG_PLL_PSTDIV_REG; + +/* Define the union volatile CRG_PLL_PD */ +typedef union { + unsigned int reg; + struct { + unsigned int pll_pd : 1 ; /* [0] */ + unsigned int reserved0 : 31 ; /* [31..1] */ + } BIT; +} volatile CRG_PLL_PD_REG; + +/* Define the union volatile CRG_PLL_CFG0 */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 13 ; /* [12..0] */ + unsigned int pll_dig_eb_lockdet : 1 ; /* [13] */ + unsigned int pll_dig_e_foutvco : 1 ; /* [14] */ + unsigned int pll_dig_e_test : 1 ; /* [15] */ + unsigned int pll_dig_lockdet_lpsel : 3 ; /* [18..16] */ + unsigned int reserved1 : 3 ; /* [21..19] */ + unsigned int pll_dig_postdiv_in_sel : 1 ; /* [22] */ + unsigned int reserved2 : 9 ; /* [31..23] */ + } BIT; +} volatile CRG_PLL_CFG0_REG; + +/* Define the union volatile CRG_PLL_CFG1 */ +typedef union { + unsigned int reg; + struct { + unsigned int pll_disc : 1 ; /* [0] */ + unsigned int pll_pull_h : 1 ; /* [1] */ + unsigned int pll_pull_l : 1 ; /* [2] */ + unsigned int pll_icp_sel : 4 ; /* [6..3] */ + unsigned int reserved0 : 1 ; /* [7] */ + unsigned int pll_test_dc : 5 ; /* [12..8] */ + unsigned int reserved1 : 6 ; /* [18..13] */ + unsigned int pll_dig_test_sel : 3 ; /* [21..19] */ + unsigned int reserved2 : 10 ; /* [31..22] */ + } BIT; +} volatile CRG_PLL_CFG1_REG; + +/* Define the union volatile CRG_PLL_LOCK */ +typedef union { + unsigned int reg; + struct { + unsigned int pll_lock : 1 ; /* [0] */ + unsigned int reserved0 : 31 ; /* [31..1] */ + } BIT; +} volatile CRG_PLL_LOCK_REG; + +/* Define the union volatile CRG_PLL_LOCK_DGL */ +typedef union { + unsigned int reg; + struct { + unsigned int pll_lock_deglitch : 1 ; /* [0] */ + unsigned int reserved0 : 31 ; /* [31..1] */ + } BIT; +} volatile CRG_PLL_LOCK_DGL_REG; + +/* Define the union volatile CRG_SYS_CKSEL */ +typedef union { + unsigned int reg; + struct { + unsigned int clk_pst1_sw_sel : 2 ; /* [1..0] */ + unsigned int reserved0 : 2 ; /* [3..2] */ + unsigned int clk_pst2_sw_sel : 2 ; /* [5..4] */ + unsigned int reserved1 : 2 ; /* [7..6] */ + unsigned int reserved2 : 24 ; /* [31..8] */ + } BIT; +} volatile CRG_SYS_CKSEL_REG; + +/* Define the union volatile CRG_PVD_RST_EN */ +typedef union { + unsigned int reg; + struct { + unsigned int pvd_rst_enable : 1 ; /* [0] */ + unsigned int reserved0 : 3 ; /* [3..1] */ + unsigned int reserved1 : 28 ; /* [31..4] */ + } BIT; +} volatile CRG_PVD_RST_EN_REG; + +/* Define the union volatile CRG_1M_INI_CKSEL */ +typedef union { + unsigned int reg; + struct { + unsigned int clk_1m_ini_cksel : 1 ; /* [0] */ + unsigned int reserved0 : 3 ; /* [3..1] */ + unsigned int reserved1 : 28 ; /* [31..4] */ + } BIT; +} volatile CRG_1M_INI_CKSEL_REG; + +/* Define the union volatile CRG_1M_DIV */ +typedef union { + unsigned int reg; + struct { + unsigned int clk_1m_div : 6 ; /* [5..0] */ + unsigned int reserved0 : 2 ; /* [7..6] */ + unsigned int reserved1 : 24 ; /* [31..8] */ + } BIT; +} volatile CRG_1M_DIV_REG; + +/* Define the union volatile CRG_UART0 */ +typedef union { + unsigned int reg; + struct { + unsigned int uart0_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int uart0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_UART0_REG; + +/* Define the union volatile CRG_UART1 */ +typedef union { + unsigned int reg; + struct { + unsigned int uart1_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int uart1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_UART1_REG; + +/* Define the union volatile CRG_UART2 */ +typedef union { + unsigned int reg; + struct { + unsigned int uart2_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int uart2_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_UART2_REG; + +/* Define the union volatile CRG_UART3 */ +typedef union { + unsigned int reg; + struct { + unsigned int uart3_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int uart3_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_UART3_REG; + +/* Define the union volatile CRG_UART4 */ +typedef union { + unsigned int reg; + struct { + unsigned int uart4_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int uart4_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_UART4_REG; + +/* Define the union volatile CRG_SPI0 */ +typedef union { + unsigned int reg; + struct { + unsigned int spi0_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int spi0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_SPI0_REG; + +/* Define the union volatile CRG_SPI1 */ +typedef union { + unsigned int reg; + struct { + unsigned int spi1_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int spi1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_SPI1_REG; + +/* Define the union volatile CRG_I2C */ +typedef union { + unsigned int reg; + struct { + unsigned int i2c_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int i2c_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_I2C_REG; + +/* Define the union volatile CRG_TIMER0 */ +typedef union { + unsigned int reg; + struct { + unsigned int timer0_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int timer0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_TIMER0_REG; + +/* Define the union volatile CRG_TIMER1 */ +typedef union { + unsigned int reg; + struct { + unsigned int timer1_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int timer1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_TIMER1_REG; + +/* Define the union volatile CRG_TIMER2 */ +typedef union { + unsigned int reg; + struct { + unsigned int timer2_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int timer2_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_TIMER2_REG; + +/* Define the union volatile CRG_TIMER3 */ +typedef union { + unsigned int reg; + struct { + unsigned int timer3_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int timer3_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_TIMER3_REG; + +/* Define the union volatile CRG_CAPM0 */ +typedef union { + unsigned int reg; + struct { + unsigned int capm0_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int capm0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_CAPM0_REG; + +/* Define the union volatile CRG_CAPM1 */ +typedef union { + unsigned int reg; + struct { + unsigned int capm1_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int capm1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_CAPM1_REG; + +/* Define the union volatile CRG_CAPM2 */ +typedef union { + unsigned int reg; + struct { + unsigned int capm2_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int capm2_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_CAPM2_REG; + +/* Define the union volatile CRG_CAN */ +typedef union { + unsigned int reg; + struct { + unsigned int can0_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int can0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_CAN_REG; + +/* Define the union volatile CRG_CAN1 */ +typedef union { + unsigned int reg; + struct { + unsigned int can1_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int can1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_CAN1_REG; + +/* Define the union volatile CRG_DMA */ +typedef union { + unsigned int reg; + struct { + unsigned int dma_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int dma_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_DMA_REG; + +/* Define the union volatile CRG_CMM */ +typedef union { + unsigned int reg; + struct { + unsigned int cmm_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int cmm_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_CMM_REG; + +/* Define the union volatile CRG_CFD */ +typedef union { + unsigned int reg; + struct { + unsigned int cfd_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int cfd_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_CFD_REG; + +/* Define the union volatile CRG_CRC */ +typedef union { + unsigned int reg; + struct { + unsigned int crc_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int crc_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_CRC_REG; + +/* Define the union volatile CRG_APT0 */ +typedef union { + unsigned int reg; + struct { + unsigned int apt0_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int apt0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_APT0_REG; + +/* Define the union volatile CRG_APT1 */ +typedef union { + unsigned int reg; + struct { + unsigned int apt1_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int apt1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_APT1_REG; + +/* Define the union volatile CRG_APT2 */ +typedef union { + unsigned int reg; + struct { + unsigned int apt2_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int apt2_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_APT2_REG; + +/* Define the union volatile CRG_APT3 */ +typedef union { + unsigned int reg; + struct { + unsigned int apt3_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int apt3_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_APT3_REG; + +/* Define the union volatile CRG_APT4 */ +typedef union { + unsigned int reg; + struct { + unsigned int apt4_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int apt4_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_APT4_REG; + +/* Define the union volatile CRG_APT5 */ +typedef union { + unsigned int reg; + struct { + unsigned int apt5_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int apt5_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_APT5_REG; + +/* Define the union volatile CRG_APT6 */ +typedef union { + unsigned int reg; + struct { + unsigned int apt6_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int apt6_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_APT6_REG; + +/* Define the union volatile CRG_APT7 */ +typedef union { + unsigned int reg; + struct { + unsigned int apt7_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int apt7_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_APT7_REG; + +/* Define the union volatile CRG_APT8 */ +typedef union { + unsigned int reg; + struct { + unsigned int apt8_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int apt8_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_APT8_REG; + +/* Define the union volatile CRG_GPT0 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpt0_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpt0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPT0_REG; + +/* Define the union volatile CRG_GPT1 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpt1_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpt1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPT1_REG; + +/* Define the union volatile CRG_GPIO0 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpio0_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpio0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPIO0_REG; + +/* Define the union volatile CRG_GPIO1 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpio1_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpio1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPIO1_REG; + +/* Define the union volatile CRG_GPIO2 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpio2_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpio2_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPIO2_REG; + +/* Define the union volatile CRG_GPIO3 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpio3_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpio3_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPIO3_REG; + +/* Define the union volatile CRG_GPIO4 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpio4_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpio4_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPIO4_REG; + +/* Define the union volatile CRG_GPIO5 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpio5_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpio5_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPIO5_REG; + +/* Define the union volatile CRG_GPIO6 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpio6_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpio6_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPIO6_REG; + +/* Define the union volatile CRG_GPIO7 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpio7_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpio7_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPIO7_REG; + +/* Define the union volatile CRG_GPIO8 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpio8_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpio8_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPIO8_REG; + +/* Define the union volatile CRG_GPIO9 */ +typedef union { + unsigned int reg; + struct { + unsigned int gpio9_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int gpio9_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_GPIO9_REG; + +/* Define the union volatile CRG_QDM0 */ +typedef union { + unsigned int reg; + struct { + unsigned int qdm0_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int qdm0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_QDM0_REG; + +/* Define the union volatile CRG_QDM1 */ +typedef union { + unsigned int reg; + struct { + unsigned int qdm1_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int qdm1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_QDM1_REG; + +/* Define the union volatile CRG_QDM2 */ +typedef union { + unsigned int reg; + struct { + unsigned int qdm2_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int qdm2_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_QDM2_REG; + +/* Define the union volatile CRG_QDM3 */ +typedef union { + unsigned int reg; + struct { + unsigned int qdm3_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int qdm3_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_QDM3_REG; + +/* Define the union volatile CRG_EFLASH */ +typedef union { + unsigned int reg; + struct { + unsigned int eflash_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int reserved1 : 16 ; /* [31..16] */ + } BIT; +} volatile CRG_EFLASH_REG; + +/* Define the union volatile CRG_TEST_CKSEL */ +typedef union { + unsigned int reg; + struct { + unsigned int test_clk_en : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int test_clk_sel : 3 ; /* [18..16] */ + unsigned int reserved1 : 13 ; /* [31..19] */ + } BIT; +} volatile CRG_TEST_CKSEL_REG; + +/* Define the union volatile CRG_ADC0_DIV */ +typedef union { + unsigned int reg; + struct { + unsigned int clk_adc0_div0 : 2 ; /* [1..0] */ + unsigned int reserved0 : 6 ; /* [7..2] */ + unsigned int clk_adc0_div1 : 2 ; /* [9..8] */ + unsigned int reserved1 : 6 ; /* [15..10] */ + unsigned int reserved2 : 16 ; /* [31..16] */ + } BIT; +} volatile CRG_ADC0_DIV_REG; + +/* Define the union volatile CRG_ADC0 */ +typedef union { + unsigned int reg; + struct { + unsigned int adc0_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int adc0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int adc0_clk_mode : 1 ; /* [24] */ + unsigned int reserved2 : 7 ; /* [31..25] */ + } BIT; +} volatile CRG_ADC0_REG; + +/* Define the union volatile CRG_ADC1_DIV */ +typedef union { + unsigned int reg; + struct { + unsigned int clk_adc1_div0 : 2 ; /* [1..0] */ + unsigned int reserved0 : 6 ; /* [7..2] */ + unsigned int clk_adc1_div1 : 2 ; /* [9..8] */ + unsigned int reserved1 : 6 ; /* [15..10] */ + unsigned int reserved2 : 16 ; /* [31..16] */ + } BIT; +} volatile CRG_ADC1_DIV_REG; + +/* Define the union volatile CRG_ADC1 */ +typedef union { + unsigned int reg; + struct { + unsigned int adc1_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int adc1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int adc1_clk_mode : 1 ; /* [24] */ + unsigned int reserved2 : 7 ; /* [31..25] */ + } BIT; +} volatile CRG_ADC1_REG; + +/* Define the union volatile CRG_ADC2_DIV */ +typedef union { + unsigned int reg; + struct { + unsigned int clk_adc2_div0 : 2 ; /* [1..0] */ + unsigned int reserved0 : 6 ; /* [7..2] */ + unsigned int clk_adc2_div1 : 2 ; /* [9..8] */ + unsigned int reserved1 : 6 ; /* [15..10] */ + unsigned int reserved2 : 16 ; /* [31..16] */ + } BIT; +} volatile CRG_ADC2_DIV_REG; + +/* Define the union volatile CRG_ADC2 */ +typedef union { + unsigned int reg; + struct { + unsigned int adc2_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int adc2_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int adc2_clk_mode : 1 ; /* [24] */ + unsigned int reserved2 : 7 ; /* [31..25] */ + } BIT; +} volatile CRG_ADC2_REG; + +/* Define the union volatile CRG_BG_CHOPPER */ +typedef union { + unsigned int reg; + struct { + unsigned int clk_bg_chopper_div : 6 ; /* [5..0] */ + unsigned int reserved0 : 2 ; /* [7..6] */ + unsigned int clk_bg_chopper_div_bypass : 1 ; /* [8] */ + unsigned int reserved1 : 23 ; /* [31..9] */ + } BIT; +} volatile CRG_BG_CHOPPER_REG; + +/* Define the union volatile CRG_ANA */ +typedef union { + unsigned int reg; + struct { + unsigned int clk_ana_cken : 1 ; /* [0] */ + unsigned int reserved0 : 15 ; /* [15..1] */ + unsigned int ana_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_ANA_REG; + +/* Define the union volatile CRG_VREF */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 16 ; /* [15..0] */ + unsigned int vref_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 7 ; /* [23..17] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_VREF_REG; + +/* Define the union volatile CRG_ACMP0 */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 16 ; /* [15..0] */ + unsigned int acmp0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 15 ; /* [31..17] */ + } BIT; +} volatile CRG_ACMP0_REG; + +/* Define the union volatile CRG_ACMP1 */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 16 ; /* [15..0] */ + unsigned int acmp1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 15 ; /* [31..17] */ + } BIT; +} volatile CRG_ACMP1_REG; + +/* Define the union volatile CRG_ACMP2 */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 16 ; /* [15..0] */ + unsigned int acmp2_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 15 ; /* [31..17] */ + } BIT; +} volatile CRG_ACMP2_REG; + +/* Define the union volatile CRG_DAC0 */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 16 ; /* [15..0] */ + unsigned int dac0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 15 ; /* [31..17] */ + } BIT; +} volatile CRG_DAC0_REG; + +/* Define the union volatile CRG_DAC1 */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 16 ; /* [15..0] */ + unsigned int dac1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 15 ; /* [31..17] */ + } BIT; +} volatile CRG_DAC1_REG; + +/* Define the union volatile CRG_DAC2 */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 16 ; /* [15..0] */ + unsigned int dac2_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 15 ; /* [31..17] */ + } BIT; +} volatile CRG_DAC2_REG; + +/* Define the union volatile CRG_PGA0 */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 16 ; /* [15..0] */ + unsigned int pga0_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 15 ; /* [31..17] */ + } BIT; +} volatile CRG_PGA0_REG; + +/* Define the union volatile CRG_PGA1 */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 16 ; /* [15..0] */ + unsigned int pga1_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 15 ; /* [31..17] */ + } BIT; +} volatile CRG_PGA1_REG; + +/* Define the union volatile CRG_PGA2 */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 16 ; /* [15..0] */ + unsigned int pga2_srst_req : 1 ; /* [16] */ + unsigned int reserved1 : 15 ; /* [31..17] */ + } BIT; +} volatile CRG_PGA2_REG; + +/* Define the union volatile CRG_HPM */ +typedef union { + unsigned int reg; + struct { + unsigned int hpm_cken : 1 ; /* [0] */ + unsigned int reserved0 : 3 ; /* [3..1] */ + unsigned int hpm_1m_cken : 1 ; /* [4] */ + unsigned int reserved1 : 11 ; /* [15..5] */ + unsigned int hpm_srst_req : 1 ; /* [16] */ + unsigned int reserved2 : 3 ; /* [19..17] */ + unsigned int hpm_1m_srst_req : 1 ; /* [20] */ + unsigned int reserved3 : 3 ; /* [23..21] */ + unsigned int reserved4 : 8 ; /* [31..24] */ + } BIT; +} volatile CRG_HPM_REG; + +/* Define the union volatile CRG_DEBUG */ +typedef union { + unsigned int reg; + struct { + unsigned int clk_pst1_sw_mux_sel : 2 ; /* [1..0] */ + unsigned int reserved0 : 2 ; /* [3..2] */ + unsigned int clk_pst2_sw_mux_sel : 2 ; /* [5..4] */ + unsigned int reserved1 : 2 ; /* [7..6] */ + unsigned int reserved2 : 24 ; /* [31..8] */ + } BIT; +} volatile CRG_DEBUG_REG; + +/* Define the union volatile HOSC_CTRL1 */ +typedef union { + unsigned int reg; + struct { + unsigned int hosc_ctrim_value : 10 ; /* [9..0] */ + unsigned int reserved0 : 22 ; /* [31..10] */ + } BIT; +} volatile HOSC_CTRL1_REG; + +/* Define the union volatile HOSC_CTRL2 */ +typedef union { + unsigned int reg; + struct { + unsigned int hosc_rtrim_value : 8 ; /* [7..0] */ + unsigned int hosc_itrim_value : 4 ; /* [11..8] */ + unsigned int hosc_sel_vref : 3 ; /* [14..12] */ + unsigned int reserved0 : 1 ; /* [15] */ + unsigned int hosc_kvco_sel : 2 ; /* [17..16] */ + unsigned int reserved1 : 2 ; /* [19..18] */ + unsigned int hosc_lpfr_sel : 4 ; /* [23..20] */ + unsigned int reserved2 : 8 ; /* [31..24] */ + } BIT; +} volatile HOSC_CTRL2_REG; + +/* Define the union volatile HOSC_CTRL3 */ +typedef union { + unsigned int reg; + struct { + unsigned int hosc_ate_en : 1 ; /* [0] */ + unsigned int hosc_dft_en : 1 ; /* [1] */ + unsigned int reserved0 : 2 ; /* [3..2] */ + unsigned int hosc_test : 10 ; /* [13..4] */ + unsigned int reserved1 : 2 ; /* [15..14] */ + unsigned int hosc_div_sel : 2 ; /* [17..16] */ + unsigned int reserved2 : 6 ; /* [23..18] */ + unsigned int hosc_start_up : 1 ; /* [24] */ + unsigned int reserved3 : 3 ; /* [27..25] */ + unsigned int hosc_vsel_ldo_ref : 2 ; /* [29..28] */ + unsigned int reserved4 : 2 ; /* [31..30] */ + } BIT; +} volatile HOSC_CTRL3_REG; + +/* Define the union volatile HOSC_PD */ +typedef union { + unsigned int reg; + struct { + unsigned int hosc_pd : 1 ; /* [0] */ + unsigned int reserved0 : 31 ; /* [31..1] */ + } BIT; +} volatile HOSC_PD_REG; + +/* Define the union volatile HOSC_LOCK */ +typedef union { + unsigned int reg; + struct { + unsigned int hosc_lock : 1 ; /* [0] */ + unsigned int reserved0 : 31 ; /* [31..1] */ + } BIT; +} volatile HOSC_LOCK_REG; + +typedef struct { + CRG_CKREF_CKEL_REG CRG_CKREF_CKEL; /* 0x0 */ + CRG_PLL_PREDIV_REG CRG_PLL_PREDIV; /* 0x4 */ + CRG_PLL_FBDIV_REG CRG_PLL_FBDIV; /* 0x8 */ + CRG_PLL_PSTDIV_REG CRG_PLL_PSTDIV; /* 0xc */ + CRG_PLL_PD_REG CRG_PLL_PD; /* 0x10 */ + CRG_PLL_CFG0_REG CRG_PLL_CFG0; /* 0x14 */ + CRG_PLL_CFG1_REG CRG_PLL_CFG1; /* 0x18 */ + CRG_PLL_LOCK_REG CRG_PLL_LOCK; /* 0x1c */ + CRG_PLL_LOCK_DGL_REG CRG_PLL_LOCK_DGL; /* 0x20 */ + unsigned int reserved0[55]; /* 0x24~0xfc */ + CRG_SYS_CKSEL_REG CRG_SYS_CKSEL; /* 0x100 */ + CRG_PVD_RST_EN_REG CRG_PVD_RST_EN; /* 0x104 */ + CRG_1M_INI_CKSEL_REG CRG_1M_INI_CKSEL; /* 0x108 */ + CRG_1M_DIV_REG CRG_1M_DIV; /* 0x10c */ + unsigned int reserved1[12]; /* 0x110~0x13c */ + CRG_UART0_REG CRG_UART0; /* 0x140 */ + CRG_UART1_REG CRG_UART1; /* 0x144 */ + CRG_UART2_REG CRG_UART2; /* 0x148 */ + CRG_UART3_REG CRG_UART3; /* 0x14c */ + CRG_UART4_REG CRG_UART4; /* 0x150 */ + unsigned int reserved2[11]; /* 0x154~0x17c */ + CRG_SPI0_REG CRG_SPI0; /* 0x180 */ + CRG_SPI1_REG CRG_SPI1; /* 0x184 */ + unsigned int reserved3[14]; /* 0x188~0x1bc */ + CRG_I2C_REG CRG_I2C; /* 0x1c0 */ + unsigned int reserved4[31]; /* 0x1c4~0x23c */ + CRG_TIMER0_REG CRG_TIMER0; /* 0x240 */ + CRG_TIMER1_REG CRG_TIMER1; /* 0x244 */ + CRG_TIMER2_REG CRG_TIMER2; /* 0x248 */ + CRG_TIMER3_REG CRG_TIMER3; /* 0x24c */ + unsigned int reserved5[12]; /* 0x250~0x27c */ + CRG_CAPM0_REG CRG_CAPM0; /* 0x280 */ + CRG_CAPM1_REG CRG_CAPM1; /* 0x284 */ + CRG_CAPM2_REG CRG_CAPM2; /* 0x288 */ + unsigned int reserved6[13]; /* 0x28c~0x2bc */ + CRG_CAN_REG CRG_CAN; /* 0x2c0 */ + CRG_CAN1_REG CRG_CAN1; /* 0x2c4 */ + unsigned int reserved7[14]; /* 0x2c8~0x2fc */ + CRG_DMA_REG CRG_DMA; /* 0x300 */ + unsigned int reserved8[15]; /* 0x304~0x33c */ + CRG_CMM_REG CRG_CMM; /* 0x340 */ + CRG_CFD_REG CRG_CFD; /* 0x344 */ + unsigned int reserved9[14]; /* 0x348~0x37c */ + CRG_CRC_REG CRG_CRC; /* 0x380 */ + unsigned int reserved10[31]; /* 0x384~0x3fc */ + CRG_APT0_REG CRG_APT0; /* 0x400 */ + CRG_APT1_REG CRG_APT1; /* 0x404 */ + CRG_APT2_REG CRG_APT2; /* 0x408 */ + CRG_APT3_REG CRG_APT3; /* 0x40c */ + CRG_APT4_REG CRG_APT4; /* 0x410 */ + CRG_APT5_REG CRG_APT5; /* 0x414 */ + CRG_APT6_REG CRG_APT6; /* 0x418 */ + CRG_APT7_REG CRG_APT7; /* 0x41c */ + CRG_APT8_REG CRG_APT8; /* 0x420 */ + unsigned int reserved11[7]; /* 0x424~0x43c */ + CRG_GPT0_REG CRG_GPT0; /* 0x440 */ + CRG_GPT1_REG CRG_GPT1; /* 0x444 */ + unsigned int reserved12[14]; /* 0x448~0x47c */ + CRG_GPIO0_REG CRG_GPIO0; /* 0x480 */ + CRG_GPIO1_REG CRG_GPIO1; /* 0x484 */ + CRG_GPIO2_REG CRG_GPIO2; /* 0x488 */ + CRG_GPIO3_REG CRG_GPIO3; /* 0x48c */ + CRG_GPIO4_REG CRG_GPIO4; /* 0x490 */ + CRG_GPIO5_REG CRG_GPIO5; /* 0x494 */ + CRG_GPIO6_REG CRG_GPIO6; /* 0x498 */ + CRG_GPIO7_REG CRG_GPIO7; /* 0x49c */ + CRG_GPIO8_REG CRG_GPIO8; /* 0x4a0 */ + CRG_GPIO9_REG CRG_GPIO9; /* 0x4a4 */ + unsigned int reserved13[6]; /* 0x4a8~0x4bc */ + CRG_QDM0_REG CRG_QDM0; /* 0x4c0 */ + CRG_QDM1_REG CRG_QDM1; /* 0x4c4 */ + CRG_QDM2_REG CRG_QDM2; /* 0x4c8 */ + CRG_QDM3_REG CRG_QDM3; /* 0x4cc */ + unsigned int reserved14[12]; /* 0x4d0~0x4fc */ + CRG_EFLASH_REG CRG_EFLASH; /* 0x500 */ + unsigned int reserved15[318]; /* 0x504~0x9f8 */ + CRG_TEST_CKSEL_REG CRG_TEST_CKSEL; /* 0x9fc */ + CRG_ADC0_DIV_REG CRG_ADC0_DIV; /* 0xa00 */ + CRG_ADC0_REG CRG_ADC0; /* 0xa04 */ + CRG_ADC1_DIV_REG CRG_ADC1_DIV; /* 0xa08 */ + CRG_ADC1_REG CRG_ADC1; /* 0xa0c */ + CRG_ADC2_DIV_REG CRG_ADC2_DIV; /* 0xa10 */ + CRG_ADC2_REG CRG_ADC2; /* 0xa14 */ + unsigned int reserved16[10]; /* 0xa18~0xa3c */ + CRG_BG_CHOPPER_REG CRG_BG_CHOPPER; /* 0xa40 */ + unsigned int reserved17[3]; /* 0xa44~0xa4c */ + CRG_ANA_REG CRG_ANA; /* 0xa50 */ + unsigned int reserved18[3]; /* 0xa54~0xa5c */ + CRG_VREF_REG CRG_VREF; /* 0xa60 */ + unsigned int reserved19[3]; /* 0xa64~0xa6c */ + CRG_ACMP0_REG CRG_ACMP0; /* 0xa70 */ + CRG_ACMP1_REG CRG_ACMP1; /* 0xa74 */ + CRG_ACMP2_REG CRG_ACMP2; /* 0xa78 */ + unsigned int reserved20; /* 0xa7c */ + CRG_DAC0_REG CRG_DAC0; /* 0xa80 */ + CRG_DAC1_REG CRG_DAC1; /* 0xa84 */ + CRG_DAC2_REG CRG_DAC2; /* 0xa88 */ + unsigned int reserved21; /* 0xa8c */ + CRG_PGA0_REG CRG_PGA0; /* 0xa90 */ + CRG_PGA1_REG CRG_PGA1; /* 0xa94 */ + CRG_PGA2_REG CRG_PGA2; /* 0xa98 */ + unsigned int reserved22[25]; /* 0xa9c~0xafc */ + CRG_HPM_REG CRG_HPM; /* 0xb00 */ + unsigned int reserved23[254]; /* 0xb04~0xef8 */ + CRG_DEBUG_REG CRG_DEBUG; /* 0xefc */ + HOSC_CTRL1_REG HOSC_CTRL1; /* 0xf00 */ + HOSC_CTRL2_REG HOSC_CTRL2; /* 0xf04 */ + HOSC_CTRL3_REG HOSC_CTRL3; /* 0xf08 */ + HOSC_PD_REG HOSC_PD; /* 0xf0c */ + HOSC_LOCK_REG HOSC_LOCK; /* 0xf10 */ +} volatile CRG_RegStruct; + +/** + * @} + */ + +/* Parameter Check -----------------------------------------------------------*/ +/** + * @brief Verify pll_ref_cksel configuration + * @param clkSelect pll_ref_cksel + * @retval true + * @retval false + */ +static inline bool IsCrgPllRefClkSelect(CRG_PllRefClkSelect clkSelect) +{ + return ((clkSelect == CRG_PLL_REF_CLK_SELECT_HOSC) || + (clkSelect == CRG_PLL_REF_CLK_SELECT_XTAL)); +} + +/** + * @brief Verify Crg pll_prediv configuration + * @param preDiv pll prediv value + * @retval true + * @retval false + */ +static inline bool IsCrgPllPreDiv(CRG_PllPreDiv preDiv) +{ + return ((preDiv >= CRG_PLL_PREDIV_1) && + (preDiv <= CRG_PLL_PREDIV_8)); +} + +/** + * @brief Verify Crg pll_postdiv configuration + * @param postDiv pll_postdiv value + * @retval true + * @retval false + */ +static inline bool IsCrgPllPostDiv(CRG_PllPostDiv postDiv) +{ + return ((postDiv >= CRG_PLL_POSTDIV_1) && + (postDiv <= CRG_PLL_POSTDIV_8)); +} + +/** + * @brief Verify Crg pll_postdiv2 configuration + * @param postDiv pll_postdiv2 value + * @retval true + * @retval false + */ +static inline bool IsCrgPllPostDiv2(CRG_PllPostDiv2 postDiv) +{ + return ((postDiv >= CRG_PLL_POSTDIV2_1) && + (postDiv <= CRG_PLL_POSTDIV2_8)); +} + +/** + * @brief Verify Crg pll_fbdiv configuration + * @param fbDiv pll fbdiv value + * @retval true + * @retval false + */ +static inline bool IsCrgPllFbDiv(unsigned int fbDiv) +{ + return (fbDiv <= CRG_PLL_FBDIV_MAX); +} + +/** + * @brief Verify Crg pll_digpostdiv_in_sel configuration + * @param select pll_digpostdiv_in_sel value + * @retval true + * @retval false + */ +static inline bool IsCrgPllDigPostDivInSel(CRG_PllDigPostDivInSelect select) +{ + return ((select == CRG_PLL_DIG_POST_DIV_SELECT_FREF) || + (select == CRG_PLL_DIG_POST_DIV_SELECT_PLL)); +} + +/** + * @brief Verify Crg core_cksel configuration + * @param select core_cksel value + * @retval true + * @retval false + */ +static inline bool IsCrgCoreCkSel(CRG_CoreClkSelect select) +{ + return ((select == CRG_CORE_CLK_SELECT_HOSC) || + (select == CRG_CORE_CLK_SELECT_TCXO) || + (select == CRG_CORE_CLK_SELECT_PLL)); +} + +/** + * @brief Verify Crg configuration + * @param select 1M clock selection + * @retval true + * @retval false + */ +static inline bool IsCrg1MCkSel(CRG_1MClkSelect select) +{ + return ((select == CRG_1M_CLK_SELECT_HOSC) || + (select == CRG_1M_CLK_SELECT_TCXO)); +} + +/** + * @brief Verify Crg configuration + * @param div 1M clock ratio + * @retval true + * @retval false + */ +static inline bool IsCrg1MCkDiv(unsigned int div) +{ + return (div <= CRG_1MHZ_CLK_MAX_DIV); +} + +/** + * @brief Verify Crg Ip (exclude adc) clock enable configuration + * @param enable ip clock enable value + * @retval true + * @retval false + */ +static inline bool IsCrgIpClkEnable(unsigned int enable) +{ + return ((enable == IP_CLK_DISABLE) || + (enable == IP_CLK_ENABLE)); +} + +/** + * @brief Check the PLL PreDiv is valid or not + * @param clkPllRef PLL Refer clock + * @param preDiv PLL Previous Divsion + * @retval true + * @retval false + */ +static inline bool IsCrgValidPreDiv(unsigned int pllRefFreq, unsigned int preDiv) +{ + unsigned int freq = pllRefFreq; + if (preDiv != 0) { + freq /= preDiv; + } + return (freq >= CRG_CLK_PFD_MIN_FREQ) && (freq <= CRG_CLK_PFD_MAX_FREQ); +} + +/** + * @brief Check the PLL FbDiv is valid or not + * @param clkPfdFreq PLL PFD clock + * @param fdDiv PLL FD Divsion + * @retval true + * @retval false + */ +static inline bool IsCrgValidFdDiv(unsigned int clkPfdFreq, unsigned int fdDiv) +{ + if (clkPfdFreq > 30000000U) { /* The maximum speed of the external clock source is 30000000U. */ + return false; + } else if (fdDiv > CRG_PLL_FBDIV_MAX) { + return false; + } + + unsigned int freq = (fdDiv > 0x6) ? (clkPfdFreq * fdDiv) : (clkPfdFreq * 0x6); /* 0x0-0x6: divided by 0x6 */ + return (freq >= CRG_CLK_VCO_MIN_FREQ) && (freq <= CRG_CLK_VCO_MAX_FREQ); +} + +/** + * @brief Check the PLL PostDiv is valid or not + * @param clkPllRef PLL Vco clock + * @param postDiv PLL Post Divsion + * @retval true + * @retval false + */ +static inline bool IsCrgValidPostDiv(unsigned int clkVcoFreq, unsigned int postDiv) +{ + unsigned int freq = clkVcoFreq; + if (postDiv <= CRG_PLL_POSTDIV_8) { + freq = (freq >> postDiv); + } + return (freq <= CRG_CLK_TARGET_MAX_FREQ); +} + +/** + * @brief Check the PLL PostDiv is valid or not + * @param clkPllRef PLL Vco clock + * @param postDiv2 PLL Post Divsion2 + * @retval true + * @retval false + */ +static inline bool IsCrgValidPostDiv2(unsigned int clkVcoFreq, unsigned int postDiv2) +{ + unsigned int freq = clkVcoFreq; + if (postDiv2 != 0) { + freq /= (postDiv2 + 1); + } + return (freq <= CRG_CLK_PST2_MAX_FREQ); +} + +/** + * @brief Check the adc clock select value + * @param adcClkSelect the value of adc clock select + * @retval true + * @retval false + */ +static inline bool IsCrgAdcClkModeSelect(CRG_AdcClkSelect adcClkSelect) +{ + return (adcClkSelect == CRG_ADC_CLK_ASYN_HOSC || \ + adcClkSelect == CRG_ADC_CLK_ASYN_TCXO || \ + adcClkSelect == CRG_ADC_CLK_ASYN_PLL_DIV || \ + adcClkSelect == CRG_ADC_CLK_SYN_CORE); +} + +/** + * @brief Check the adc clock div value + * @param div the value of adc clock div + * @retval true + * @retval false + */ +static inline bool IsCrgAdcClkDiv(CRG_AdcDiv div) +{ + return (div == CRG_ADC_DIV_1 || \ + div == CRG_ADC_DIV_2 || \ + div == CRG_ADC_DIV_3 || \ + div == CRG_ADC_DIV_4); +} + +/** + * @brief Set Pll Ref clock select + * @param clk Clock register base address + * @param clkSel clock source select + * @retval None + */ +static inline void DCL_CRG_SetPllRefClkSel(CRG_RegStruct *clk, CRG_PllRefClkSelect clkSel) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + CRG_PARAM_CHECK_NO_RET(IsCrgPllRefClkSelect(clkSel)); + clk->CRG_CKREF_CKEL.BIT.pll_ref_cksel = (unsigned int)clkSel; +} + +/** + * @brief Get Pll Ref clock selection + * @param clk Clock register base address + * @retval pll_ref_cksel Ref clock selection + */ +static inline CRG_PllRefClkSelect DCL_CRG_GetPllRefClkSel(const CRG_RegStruct *clk) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + return (CRG_PllRefClkSelect)clk->CRG_CKREF_CKEL.BIT.pll_ref_cksel; +} + +/** + * @brief Set prevous division ratio + * @param clk Clock register base address + * @param preDiv prevous division ratio + * @retval None + */ +static inline void DCL_CRG_SetPllPreDiv(CRG_RegStruct *clk, CRG_PllPreDiv preDiv) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + CRG_PARAM_CHECK_NO_RET(IsCrgPllPreDiv(preDiv)); + clk->CRG_PLL_PREDIV.BIT.pll_prediv = (unsigned int)preDiv; +} + +/** + * @brief Get prevous division ratio + * @param clk Clock register base address + * @retval prediv prevous division ratio + */ +static inline CRG_PllPreDiv DCL_CRG_GetPllPreDiv(const CRG_RegStruct *clk) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + return (CRG_PllPreDiv)clk->CRG_PLL_PREDIV.BIT.pll_prediv; +} + +/** + * @brief Set PLL frequency multiplication factor + * @param clk Clock register base address + * @param fbDiv Multiplication factor + * @retval None + */ +static inline void DCL_CRG_SetPllFbDiv(CRG_RegStruct *clk, unsigned int fbDiv) +{ + unsigned int div = fbDiv; + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + CRG_PARAM_CHECK_NO_RET(IsCrgPllFbDiv(fbDiv)); + clk->CRG_PLL_FBDIV.BIT.pll_fbdiv = div; +} + +/** + * @brief Get PLL frequency multiplication factor + * @param clk Clock register base address + * @retval pll_fbdiv Multiplication factor + */ +static inline unsigned int DCL_CRG_GetPllFbDiv(const CRG_RegStruct *clk) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + return clk->CRG_PLL_FBDIV.BIT.pll_fbdiv; +} + +/** + * @brief Set PLL post division ratio + * @param clk Clock register base address + * @param postDiv Post division ratio + * @retval None + */ +static inline void DCL_CRG_SetPllPostDiv1(CRG_RegStruct *clk, CRG_PllPostDiv postDiv) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + CRG_PARAM_CHECK_NO_RET(IsCrgPllPostDiv(postDiv)); + clk->CRG_PLL_PSTDIV.BIT.pll_postdiv1 = (unsigned int)postDiv; +} + +/** + * @brief Get PLL post division ratio + * @param clk Clock register base address + * @retval pll_postdiv Post division ratio + */ +static inline CRG_PllPostDiv DCL_CRG_GetPllPostDiv1(const CRG_RegStruct *clk) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + return (CRG_PllPostDiv)clk->CRG_PLL_PSTDIV.BIT.pll_postdiv1; +} + +/** + * @brief Set PLL post division ratio + * @param clk Clock register base address + * @param postDiv Post division ratio + * @retval None + */ +static inline void DCL_CRG_SetPllPostDiv2(CRG_RegStruct *clk, CRG_PllPostDiv postDiv) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + CRG_PARAM_CHECK_NO_RET(IsCrgPllPostDiv(postDiv)); + clk->CRG_PLL_PSTDIV.BIT.pll_postdiv2 = (unsigned int)postDiv; +} + +/** + * @brief Get PLL post division ratio + * @param clk Clock register base address + * @retval pll_postdiv Post division ratio + */ +static inline CRG_PllPostDiv DCL_CRG_GetPllPostDiv2(const CRG_RegStruct *clk) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + return (CRG_PllPostDiv)clk->CRG_PLL_PSTDIV.BIT.pll_postdiv2; +} + +/** + * @brief Set PLL Power + * @param clk Clock register base address + * @param pd pll power down or not + * @retval None + */ +static inline void DCL_CRG_SetPllPd(CRG_RegStruct *clk, bool pd) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + clk->CRG_PLL_PD.BIT.pll_pd = (unsigned int)pd; +} + +/** + * @brief Get PLL power status + * @param clk Clock register base address + * @retval 0: power up, 1: power down + */ +static inline bool DCL_CRG_GetPllPd(const CRG_RegStruct *clk) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + return clk->CRG_PLL_PD.BIT.pll_pd; +} + +/** + * @brief Set core clock selection + * @param clk Clock register base address + * @param select Core clock selection + * @retval None + */ +static inline void DCL_CRG_SetCoreClkSel(CRG_RegStruct *clk, CRG_CoreClkSelect select) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + CRG_PARAM_CHECK_NO_RET(IsCrgCoreCkSel(select)); + clk->CRG_SYS_CKSEL.BIT.clk_pst1_sw_sel = select; +} + +/** + * @brief Get core clock selection + * @param clk Clock register base address + * @retval Core clock selection + */ +static inline unsigned int DCL_CRG_GetCoreClkSel(const CRG_RegStruct *clk) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + return clk->CRG_SYS_CKSEL.BIT.clk_pst1_sw_sel; +} + +/** + * @brief Set core clock selection + * @param clk Clock register base address + * @param select Core clock selection + * @retval None + */ +static inline void DCL_CRG_SetAdcAsynClkSel(CRG_RegStruct *clk, CRG_CoreClkSelect select) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + CRG_PARAM_CHECK_NO_RET(IsCrgCoreCkSel(select)); + clk->CRG_SYS_CKSEL.BIT.clk_pst2_sw_sel = select; +} + +/** + * @brief Get adc core clock selection + * @param clk Clock register base address + * @retval Core clock selection + */ +static inline unsigned int DCL_CRG_GetAdcAsynClkSel(const CRG_RegStruct *clk) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + return clk->CRG_SYS_CKSEL.BIT.clk_pst2_sw_sel; +} + +/** + * @brief Set 1M clock selection + * @param clk Clock register base address + * @param select Core clock selection + * @retval None + */ +static inline void DCL_CRG_Set1MClkSel(CRG_RegStruct *clk, CRG_1MClkSelect select) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + CRG_PARAM_CHECK_NO_RET(IsCrg1MCkSel(select)); + clk->CRG_1M_INI_CKSEL.BIT.clk_1m_ini_cksel = select; +} + +/** + * @brief Get 1M clock selection + * @param clk Clock register base address + * @retval Core clock selection + */ +static inline unsigned int DCL_CRG_Get1MClkSel(const CRG_RegStruct *clk) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + return clk->CRG_1M_INI_CKSEL.BIT.clk_1m_ini_cksel; +} + +/** + * @brief Set 1M clock division ratio + * @param clk Clock register base address + * @param div Division ratio + * @retval None + */ +static inline void DCL_CRG_Set1MClkDiv(CRG_RegStruct *clk, unsigned int div) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + CRG_PARAM_CHECK_NO_RET(div <= CRG_1MHZ_CLK_MAX_DIV); + clk->CRG_1M_DIV.BIT.clk_1m_div = div; +} + +/** + * @brief Enable test clock function + * @param clk Clock register base address + * @retval None + */ +static inline void DCL_CRG_TestClkEnable(CRG_RegStruct *clk) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + clk->CRG_TEST_CKSEL.BIT.test_clk_en = BASE_CFG_ENABLE; /* Enable the test clock. */ +} + +/** + * @brief Disable test clock function + * @param clk Clock register base address + * @retval None + */ +static inline void DCL_CRG_TestClkDisable(CRG_RegStruct *clk) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + clk->CRG_TEST_CKSEL.BIT.test_clk_en = BASE_CFG_DISABLE; /* Disable the test clock. */ +} + +/** + * @brief CRG test clock select. + * @param clk Clock register base address + * @param clkSel Clock select. + * @retval None + */ +static inline void DCL_CRG_TestClkSel(CRG_RegStruct *clk, CRG_TestClkSel clkSel) +{ + CRG_ASSERT_PARAM(IsCRGInstance(clk)); + CRG_PARAM_CHECK_NO_RET(clkSel >= CRG_TEST_CLK_HOSC); + CRG_PARAM_CHECK_NO_RET(clkSel <= CRG_TEST_CLK_HOSC_DIV); + clk->CRG_TEST_CKSEL.BIT.test_clk_sel = clkSel; /* Set the test clock select. */ +} +/** + * @} + */ + +/** + * @} + */ +#endif /* McuMagicTag_CRG_IP_H */ diff --git a/src/drivers/crg/crg_v3/src/crg.c b/src/drivers/crg/crg_v3/src/crg.c new file mode 100644 index 0000000000000000000000000000000000000000..0d5b57eec5dee8419c28e257f27eb4c3a4709408 --- /dev/null +++ b/src/drivers/crg/crg_v3/src/crg.c @@ -0,0 +1,1132 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file crg.c + * @author MCU Driver Team + * @brief CRG module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the CRG. + * + Initialization and de-initialization functions + * + Config the register of CRG + * + Config the register of IP,such as Uart,Timer and so on + */ + +/* Includes ------------------------------------------------------------------*/ +#include "crg.h" +/* Macro definitions ---------------------------------------------------------*/ +#define CRG_HOSC_CTRL2_ADDR 0x10000F04 +/* Private Function -----------------------------------------------------------*/ +static unsigned int CRG_GetPllRefIni(CRG_PllRefClkSelect pllRefClkSelect); +static unsigned int CRG_GetPreDivValue(CRG_PllPreDiv pllPredDiv); +static unsigned int CRG_GetPllFbDivValue(unsigned int pllFbDiv); +static unsigned int CRG_GetPllPostDivValue(unsigned int pllPostDiv); +static inline unsigned int CRG_GetVcoFreq(void); +static BASE_StatusType CRG_IsValidPllConfig(const CRG_Handle *handle); +static void CRG_GetPllOptConfig(unsigned int targetFreq, unsigned int pllRefFreq, CRG_PllDivCfg *div); +static BASE_StatusType CRG_IsValid1MHzConfig(const CRG_Handle *handle); + +static void CRG_IpWoClkSelEnableSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int enable); +static void CRG_IpWoClkSelResetSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int reset); +static unsigned int CRG_IpWoClkSelEnableGet(const CHIP_CrgIpMatchInfo *matchInfo); +static unsigned int CRG_IpWoClkSelResetGet(const CHIP_CrgIpMatchInfo *matchInfo); + +static void CRG_AdcEnableSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int enable); +static void CRG_AdcDivSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int div); +static void CRG_AdcClkSelectSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int clkSelect); +static unsigned int CRG_AdcEnableGet(const CHIP_CrgIpMatchInfo *matchInfo); +static unsigned int CRG_AdcClkSelectGet(const CHIP_CrgIpMatchInfo *matchInfo); +static unsigned int CRG_AdcDivGet(const CHIP_CrgIpMatchInfo *matchInfo); + +static void CRG_EfcEnableSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int enable); +static unsigned int CRG_EfcEnableGet(const CHIP_CrgIpMatchInfo *matchInfo); +static void CRG_AnaEnableSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int enable); +static unsigned int CRG_AnaEnableGet(const CHIP_CrgIpMatchInfo *matchInfo); + +static unsigned int CRG_GetAdcIpFreq(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int baseClkRate, + unsigned int coreClkFreq); + +typedef CHIP_CrgIpMatchInfo *(*FindFunc)(const void *baseAddress); +typedef void (*SetFunc)(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int value); +typedef unsigned int (*GetFunc)(const CHIP_CrgIpMatchInfo *matchInfo); + +typedef struct { + CHIP_CrgIpType type; + SetFunc resetSet; + SetFunc enableSet; + SetFunc clkSelSet; + SetFunc clkDivSet; + GetFunc resetGet; + GetFunc enableGet; + GetFunc clkSelGet; + GetFunc clkDivGet; +} CRG_IpProc; + +static CRG_IpProc g_ipClkProc[CRG_IP_MAX_TYPE] = { + {CRG_IP_WWDG, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL}, + {CRG_IP_NONE_CLK_SEL, + CRG_IpWoClkSelResetSet, CRG_IpWoClkSelEnableSet, NULL, NULL, + CRG_IpWoClkSelResetGet, CRG_IpWoClkSelEnableGet, NULL, NULL}, + {CRG_IP_CAN, + CRG_IpWoClkSelResetSet, CRG_IpWoClkSelEnableSet, NULL, NULL, + CRG_IpWoClkSelResetGet, CRG_IpWoClkSelEnableGet, NULL, NULL}, + {CRG_IP_ADC, + NULL, CRG_AdcEnableSet, CRG_AdcClkSelectSet, CRG_AdcDivSet, + NULL, CRG_AdcEnableGet, CRG_AdcClkSelectGet, CRG_AdcDivGet}, + {CRG_IP_EFC, + NULL, CRG_EfcEnableSet, NULL, NULL, + NULL, CRG_EfcEnableGet, NULL, NULL}, + {CRG_IP_IWDG, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL}, + {CRG_IP_ANA, + CRG_IpWoClkSelResetSet, CRG_AnaEnableSet, NULL, NULL, + CRG_IpWoClkSelResetGet, CRG_AnaEnableGet, NULL, NULL} +}; + +static CRG_RegStruct *g_crgBaseAddr; +static unsigned char g_anaEnableFlag = 0; + +/* Public Function -----------------------------------------------------------*/ +/** + * @brief Clock Init + * @param handle CRG Handle + * @retval BASE_STATUS_ERROR Parameter Check fail + * @retval BASE_STATUS_OK Success + */ +BASE_StatusType HAL_CRG_Init(const CRG_Handle *handle) +{ + CRG_ASSERT_PARAM(handle != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(handle->baseAddress)); + /* Check the validity of PLL-related parameters. */ + CRG_PARAM_CHECK_WITH_RET(IsCrgPllRefClkSelect(handle->pllRefClkSelect), BASE_STATUS_ERROR); + CRG_PARAM_CHECK_WITH_RET(IsCrgPllPreDiv(handle->pllPreDiv), BASE_STATUS_ERROR); + CRG_PARAM_CHECK_WITH_RET(IsCrgPllFbDiv(handle->pllFbDiv), BASE_STATUS_ERROR); + CRG_PARAM_CHECK_WITH_RET(IsCrgPllPostDiv(handle->pllPostDiv), BASE_STATUS_ERROR); + CRG_PARAM_CHECK_WITH_RET(IsCrgPllPostDiv2(handle->handleEx.pllPostDiv2), BASE_STATUS_ERROR); + /* Check the Clock Source and Frequency Divider of the 1 MHz Clock. */ + CRG_PARAM_CHECK_WITH_RET(IsCrg1MCkSel(handle->handleEx.clk1MSelect), BASE_STATUS_ERROR); + CRG_PARAM_CHECK_WITH_RET(IsCrg1MCkDiv(handle->handleEx.clk1MDiv), BASE_STATUS_ERROR); + CRG_PARAM_CHECK_WITH_RET(IsCrgCoreCkSel(handle->coreClkSelect), BASE_STATUS_ERROR); + + *(unsigned int *)CRG_HOSC_CTRL2_ADDR = 0x306E; /* Optimized HOSC temperature drift performance parameter. */ + + CRG_RegStruct *reg = handle->baseAddress; + g_crgBaseAddr = (void *)reg; + /* Check the validity of the PLL parameter configuration. */ + if (CRG_IsValidPllConfig(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + /* Disable the write protection function of the CRG register. */ + DCL_SYSCTRL_CrgWriteProtectionDisable(); + + reg->CRG_CKREF_CKEL.BIT.pll_ref_cksel = handle->pllRefClkSelect; + reg->CRG_PLL_PREDIV.BIT.pll_prediv = handle->pllPreDiv; + reg->CRG_PLL_FBDIV.BIT.pll_fbdiv = handle->pllFbDiv; + reg->CRG_PLL_PSTDIV.BIT.pll_postdiv1 = handle->pllPostDiv; + reg->CRG_PLL_PSTDIV.BIT.pll_postdiv2 = handle->handleEx.pllPostDiv2; + reg->CRG_PLL_PD.BIT.pll_pd = BASE_CFG_UNSET; + + while (reg->CRG_PLL_LOCK.BIT.pll_lock != BASE_CFG_SET) { + ; /* Wait for PLL to lock */ + } + + DCL_SYSCTRL_CrgWriteProtectionEnable(); + /* Check the 1MHz clock parameter configuration. */ + if (CRG_IsValid1MHzConfig(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + while (reg->HOSC_LOCK.BIT.hosc_lock != BASE_CFG_SET) { + ; /* Wait for HOSC to lock */ + } + /* Set the Clock Source and Frequency Divider of the 1 MHz Clock. */ + reg->CRG_1M_DIV.BIT.clk_1m_div = handle->handleEx.clk1MDiv; + reg->CRG_1M_INI_CKSEL.BIT.clk_1m_ini_cksel = handle->handleEx.clk1MSelect; + return BASE_STATUS_OK; +} + +/** + * @brief Set Crg Core clock by target frequecy + * @param handle CRG handle + * @param targetFreq Target Frequency + * @retval BASE_STATUS_ERROR Parameter Check fail + * @retval BASE_STATUS_OK Success + */ +BASE_StatusType HAL_CRG_InitWithTargetFrequence(const CRG_Handle *handle, unsigned int targetFreq) +{ + CRG_ASSERT_PARAM(handle != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(handle->baseAddress)); + CRG_PARAM_CHECK_WITH_RET(IsCrgPllRefClkSelect(handle->pllRefClkSelect), BASE_STATUS_ERROR); + CRG_PARAM_CHECK_WITH_RET((targetFreq <= CRG_CLK_TARGET_MAX_FREQ), BASE_STATUS_ERROR); + + CRG_Handle crgHandle; + CRG_PllDivCfg divCfg; + unsigned int pllRefFreq; + unsigned int fbFreq; + unsigned int temp; + /* Check the validity of the external crystal oscillator frequency. */ + if ((handle->pllRefClkSelect == CRG_PLL_REF_CLK_SELECT_XTAL) && \ + (XTRAIL_FREQ > 30000000U)) { /* The maximum of the external clock source is 30000000U. */ + return BASE_STATUS_ERROR; + } + /* Obtain the clock frequency based on the clock source. */ + pllRefFreq = (handle->pllRefClkSelect == CRG_PLL_REF_CLK_SELECT_HOSC) ? HOSC_FREQ : XTRAIL_FREQ; + CRG_GetPllOptConfig(targetFreq, pllRefFreq, &divCfg); + crgHandle = *handle; + crgHandle.pllPreDiv = divCfg.PreDiv; + crgHandle.pllFbDiv = divCfg.fbDiv; + crgHandle.pllPostDiv = divCfg.postDiv; + /* Calculate the posdiv2 frequency divider. */ + fbFreq = (pllRefFreq / (divCfg.PreDiv + 1)) * (divCfg.fbDiv + 1); + for (unsigned int i = CRG_PLL_POSTDIV2_1; i <= CRG_PLL_POSTDIV2_8; i++) { + temp = fbFreq / (i + 1); + if (temp <= CRG_CLK_PST2_MAX_FREQ) { /* The maximum value is used when the configuration is valid. */ + crgHandle.handleEx.pllPostDiv2 = i; + break; + } + if (i == CRG_PLL_POSTDIV2_8) { /* No valid value. */ + return BASE_STATUS_ERROR; + } + } + return HAL_CRG_Init(&crgHandle); +} + +/** + * @brief Clock Deinit + * @param handle CRG Handle + * @retval BASE_STATUS_OK + */ +BASE_StatusType HAL_CRG_DeInit(const CRG_Handle *handle) +{ + CRG_ASSERT_PARAM(handle != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(handle->baseAddress)); + CRG_RegStruct *reg = handle->baseAddress; + DCL_SYSCTRL_CrgWriteProtectionDisable(); + + reg->CRG_CKREF_CKEL.BIT.pll_ref_cksel = 0x0; /* 0x0: default value */ + reg->CRG_PLL_PREDIV.BIT.pll_prediv = 0x02; /* 0x02: default value */ + reg->CRG_PLL_FBDIV.BIT.pll_fbdiv = 0x30; /* 0x30: default value */ + reg->CRG_PLL_PSTDIV.BIT.pll_postdiv1 = 0x1; /* 0x0: default value */ + reg->CRG_PLL_PSTDIV.BIT.pll_postdiv2 = 0x3; /* 0x0: default value */ + reg->CRG_PLL_PD.BIT.pll_pd = 0x1; /* 0x1: default value */ + + DCL_SYSCTRL_CrgWriteProtectionEnable(); + + reg->CRG_1M_DIV.BIT.clk_1m_div = 0x29; /* 0x29: default value */ + reg->CRG_1M_INI_CKSEL.BIT.clk_1m_ini_cksel = 0x0; /* 0x0: default value */ + return BASE_STATUS_OK; +} + +/** + * @brief Get Clock Config + * @param handle CRG Handle + * @retval BASE_STATUS_OK Success + */ +BASE_StatusType HAL_CRG_GetConfig(CRG_Handle *handle) +{ + CRG_ASSERT_PARAM(handle != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(handle->baseAddress)); + /* Obtains configuration parameters from registers. */ + CRG_RegStruct *reg = handle->baseAddress; + handle->pllRefClkSelect = reg->CRG_CKREF_CKEL.BIT.pll_ref_cksel; + handle->pllPreDiv = reg->CRG_PLL_PREDIV.BIT.pll_prediv; + handle->pllFbDiv = reg->CRG_PLL_FBDIV.BIT.pll_fbdiv; + handle->pllPostDiv = reg->CRG_PLL_PSTDIV.BIT.pll_postdiv1; + handle->handleEx.pllPostDiv2 = reg->CRG_PLL_PSTDIV.BIT.pll_postdiv2; + /* Enable the PLL and start the PLL output clock frequency. */ + handle->pllPd = reg->CRG_PLL_PD.BIT.pll_pd; + handle->coreClkSelect = reg->CRG_SYS_CKSEL.BIT.clk_pst1_sw_sel; + /* Get the 1MHz clock select and frequency division. */ + handle->handleEx.clk1MDiv = reg->CRG_1M_DIV.BIT.clk_1m_div; + handle->handleEx.clk1MSelect = reg->CRG_1M_INI_CKSEL.BIT.clk_1m_ini_cksel; + return BASE_STATUS_OK; +} + +/** + * @brief Set CRG Core Clock Select + * @param handle CRG Handle + * @retval BASE_STATUS_OK Success + * @retval BASE_STATUS_ERROR Paramter check fail + */ +BASE_StatusType HAL_CRG_SetCoreClockSelect(CRG_Handle *handle) +{ + CRG_ASSERT_PARAM(handle != 0); + CRG_ASSERT_PARAM(IsCRGInstance(handle->baseAddress)); + CRG_PARAM_CHECK_WITH_RET(IsCrgCoreCkSel(handle->coreClkSelect), BASE_STATUS_ERROR); + + CRG_RegStruct *reg = handle->baseAddress; + /* The write protection of the CRG register needs to be disabled. */ + DCL_SYSCTRL_CrgWriteProtectionDisable(); + DCL_CRG_SetCoreClkSel(reg, handle->coreClkSelect); + DCL_SYSCTRL_CrgWriteProtectionEnable(); + + return BASE_STATUS_OK; +} + +/** + * @brief Get PLL Clock Frequence + * @param None + * @retval unsigned int PLL clock frequency + */ +static inline unsigned int CRG_GetVcoFreq(void) +{ + unsigned int freq; + unsigned int regFbdiv; + CRG_RegStruct *crg = g_crgBaseAddr; + + CRG_ASSERT_PARAM(IsCRGInstance(crg)); + CRG_ASSERT_PARAM((XTRAIL_FREQ <= 30000000U)); /* The maximum of the external clock source is 30000000U. */ + + freq = CRG_GetPllRefIni(crg->CRG_CKREF_CKEL.BIT.pll_ref_cksel); + regFbdiv = CRG_GetPllFbDivValue(crg->CRG_PLL_FBDIV.BIT.pll_fbdiv); /* Get the value of the fbdiv register. */ + freq *= (regFbdiv >= 0x06) ? regFbdiv : 0x06; /* 0x0-0x6: divided by 0x6 */ + freq /= CRG_GetPreDivValue(crg->CRG_PLL_PREDIV.BIT.pll_prediv); + return freq; +} + +/** + * @brief Get PLL Clock Frequence + * @param None + * @retval unsigned int PLL clock frequency + */ +unsigned int HAL_CRG_GetPllFreq(void) +{ + unsigned int freq; + unsigned int pllPostDivValue; + CRG_RegStruct *crg = g_crgBaseAddr; + + CRG_ASSERT_PARAM(IsCRGInstance(crg)); + freq = CRG_GetVcoFreq(); + pllPostDivValue = CRG_GetPllPostDivValue((CRG_PllPostDiv)crg->CRG_PLL_PSTDIV.BIT.pll_postdiv1); + /* Calculate the PLL output clock frequency based on the VCO clock frequency and post-division coefficient. */ + if (pllPostDivValue != 0) { + freq /= pllPostDivValue; + } + return freq; +} + +/** + * @brief Get Core Clock Frequence + * @param None + * @retval unsigned int Core clock frequency + */ +unsigned int HAL_CRG_GetCoreClkFreq(void) +{ + unsigned int freq; + unsigned int coreClkSelect; + CRG_RegStruct *crg = g_crgBaseAddr; + + CRG_ASSERT_PARAM(IsCRGInstance(crg)); + coreClkSelect = crg->CRG_SYS_CKSEL.BIT.clk_pst1_sw_sel; + switch (coreClkSelect) { + case CRG_CORE_CLK_SELECT_HOSC: /* The clock source is an internal high-speed clock. */ + freq = HOSC_FREQ; + break; + + case CRG_CORE_CLK_SELECT_TCXO: /* The clock source is the external crystal oscillator clock. */ + freq = XTRAIL_FREQ; + break; + + case CRG_CORE_CLK_SELECT_PLL: /* The clock source is the PLL. */ + freq = HAL_CRG_GetPllFreq(); + break; + + default: + freq = LOSC_FREQ; + break; + } + return freq; +} + +/** + * @brief Get Clock Frequence + * @param handle CRG Handle + * @retval Frequece of IP + */ +unsigned int HAL_CRG_GetIpFreq(const void *baseAddress) +{ + CRG_ASSERT_PARAM(baseAddress != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); + unsigned int hclk = HAL_CRG_GetCoreClkFreq(); + unsigned int freq = LOSC_FREQ; + unsigned int coreClkFreq; + /* Get the CRG type of the target IP. */ + CHIP_CrgIpMatchInfo *p = GetCrgIpMatchInfo(baseAddress); + if (p == NULL) { + return freq; + } + switch (p->type) { + case CRG_IP_NONE_CLK_SEL: + case CRG_IP_EFC: + case CRG_IP_ANA: + case CRG_IP_WWDG: + freq = hclk; /* Returns the internal high speed clock frequency. */ + break; + + case CRG_IP_CAN: + freq = CRG_GetPllRefIni(g_crgBaseAddr->CRG_CKREF_CKEL.BIT.pll_ref_cksel); + break; + + case CRG_IP_ADC: + /* Get core clock frequence for calculating the ADC clock frequency. */ + coreClkFreq = HAL_CRG_GetCoreClkFreq(); + freq = CRG_GetAdcIpFreq(p, CRG_GetVcoFreq(), coreClkFreq); + break; + + case CRG_IP_IWDG: /* The IWDG clock frequency is an internal low-speed clock. */ + default: + break; + } + if (freq == 0) { + freq = LOSC_FREQ; + } + return freq; +} + +/** + * @brief Enable clock of ip + * @param baseAddress Ip base address + * @param enable enable mask + * @retval BASE_STATUS_ERROR Can't find the Match or operation is not support + * @retval BASE_STATUS_OK Operation Success + */ +BASE_StatusType HAL_CRG_IpEnableSet(const void *baseAddress, unsigned int enable) +{ + CRG_ASSERT_PARAM(baseAddress != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); + /* Check the validity of the input parameters. */ + CRG_PARAM_CHECK_WITH_RET((enable == IP_CLK_ENABLE || enable == IP_CLK_DISABLE), BASE_STATUS_ERROR); + /* Get the CRG type of the target IP. */ + CHIP_CrgIpMatchInfo *p = GetCrgIpMatchInfo(baseAddress); + if ((p == NULL) || (p->type >= CRG_IP_MAX_TYPE)) { + return BASE_STATUS_ERROR; + } + if (g_ipClkProc[p->type].enableSet == NULL) { + return BASE_STATUS_ERROR; + } + g_ipClkProc[p->type].enableSet(p, enable); + return BASE_STATUS_OK; +} + +/** + * @brief Get clock enable status of ip + * @param baseAddress Ip base address + * @param enable parameter out for ip enable status + * @retval BASE_STATUS_ERROR Can't find the Match or operation is not support + * @retval BASE_STATUS_OK Operation Success + */ +BASE_StatusType HAL_CRG_IpEnableGet(const void *baseAddress, unsigned int *enable) +{ + CRG_ASSERT_PARAM(baseAddress != NULL); + CRG_ASSERT_PARAM(enable != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); + /* Get the CRG type of the target IP. */ + CHIP_CrgIpMatchInfo *p = GetCrgIpMatchInfo(baseAddress); + if ((p == NULL) || (p->type < 0) || (p->type >= CRG_IP_MAX_TYPE)) { + return BASE_STATUS_ERROR; + } + if (g_ipClkProc[p->type].enableGet == NULL) { + return BASE_STATUS_ERROR; + } + *enable = g_ipClkProc[p->type].enableGet(p); /* Returns the module clock enable status. */ + return BASE_STATUS_OK; +} + +/** + * @brief Set clock select ip + * @param baseAddress Ip base address + * @param select clock select, @see CRG_APBLsClkSelect for ip in apb_ls_subsys or CRG_AdcClkSelect for adc + * @retval BASE_STATUS_OK success + * @retval BASE_STATUS_ERROR fail + */ +BASE_StatusType HAL_CRG_IpClkSelectSet(const void *baseAddress, unsigned int select) +{ + CRG_ASSERT_PARAM(baseAddress != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); + + CHIP_CrgIpMatchInfo *p = GetCrgIpMatchInfo(baseAddress); + if ((p == NULL) || (p->type >= CRG_IP_MAX_TYPE)) { + return BASE_STATUS_ERROR; + } + if (g_ipClkProc[p->type].clkSelSet == NULL) { + return BASE_STATUS_ERROR; + } + g_ipClkProc[p->type].clkSelSet(p, select); /* Clock selection of the configuration module. */ + return BASE_STATUS_OK; +} + +/** + * @brief Get clock select of ip + * @param baseAddress Ip base address + * @param select Get clkSet value + * @retval BASE_STATUS_OK + * @retval BASE_STATUS_ERROR Match Fail or Not support + */ +BASE_StatusType HAL_CRG_IpClkSelectGet(const void *baseAddress, unsigned int *select) +{ + CRG_ASSERT_PARAM(baseAddress != NULL); + CRG_ASSERT_PARAM(select != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); + /* Get the CRG type of the target IP. */ + CHIP_CrgIpMatchInfo *p = GetCrgIpMatchInfo(baseAddress); + if ((p == NULL) || (p->type >= CRG_IP_MAX_TYPE)) { + return BASE_STATUS_ERROR; + } + if (g_ipClkProc[p->type].clkSelGet == NULL) { + return BASE_STATUS_ERROR; + } + *select = g_ipClkProc[p->type].clkSelGet(p); /* Obtains the module clock selection. */ + return BASE_STATUS_OK; +} + +/** + * @brief Reset/Set clock of ip + * @param baseAddress Ip base address + * @param reset Set reset value + * @retval BASE_STATUS_OK Success + * @retval BASE_STATUS_ERROR Match Fail or Not support + */ +BASE_StatusType HAL_CRG_IpClkResetSet(const void *baseAddress, unsigned int reset) +{ + CRG_ASSERT_PARAM(baseAddress != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); + CRG_PARAM_CHECK_WITH_RET((reset == BASE_CFG_SET || reset == BASE_CFG_UNSET), BASE_STATUS_ERROR); + /* Get the CRG type of the target IP. */ + CHIP_CrgIpMatchInfo *p = GetCrgIpMatchInfo(baseAddress); + if ((p == NULL) || (p->type >= CRG_IP_MAX_TYPE)) { + return BASE_STATUS_ERROR; + } + if (g_ipClkProc[p->type].resetSet == NULL) { + return BASE_STATUS_ERROR; + } + g_ipClkProc[p->type].resetSet(p, reset); /* Configure the reset value of the module clock. */ + return BASE_STATUS_OK; +} + +/** + * @brief Get clock select of ip + * @param baseAddress Ip base address + * @param reset Get reset value + * @retval BASE_STATUS_OK Success + * @retval BASE_CFG_UNSET Match Fail or Not support + */ +BASE_StatusType HAL_CRG_IpClkResetGet(const void *baseAddress, unsigned int *reset) +{ + CRG_ASSERT_PARAM(baseAddress != NULL); + CRG_ASSERT_PARAM(reset != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); + /* Get the CRG type of the target IP. */ + CHIP_CrgIpMatchInfo *p = GetCrgIpMatchInfo(baseAddress); + if ((p == NULL) || (p->type >= CRG_IP_MAX_TYPE)) { + return BASE_STATUS_ERROR; + } + if (g_ipClkProc[p->type].resetGet == NULL) { + return BASE_STATUS_ERROR; + } + *reset = g_ipClkProc[p->type].resetGet(p); /* Query the reset status of the module clock. */ + return BASE_STATUS_OK; +} + +/** + * @brief Reset/Set clock of ip + * @param baseAddress Ip base address + * @param div set div value + * @retval BASE_STATUS_OK Success + * @retval BASE_STATUS_ERROR Match Fail or Not support + */ +BASE_StatusType HAL_CRG_IpClkDivSet(const void *baseAddress, unsigned int div) +{ + CRG_ASSERT_PARAM(baseAddress != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); + + CHIP_CrgIpMatchInfo *p = GetCrgIpMatchInfo(baseAddress); + if ((p == NULL) || (p->type >= CRG_IP_MAX_TYPE)) { + return BASE_STATUS_ERROR; + } + if (g_ipClkProc[p->type].clkDivSet == NULL) { + return BASE_STATUS_ERROR; + } + g_ipClkProc[p->type].clkDivSet(p, div); /* Configure the clock frequency divider of the module. */ + return BASE_STATUS_OK; +} + +/** + * @brief Get clock select of ip + * @param baseAddress Ip base address + * @param div get div value + * @retval BASE_STATUS_OK Success + * @retval BASE_STATUS_ERROR Match Fail or Not support + */ +BASE_StatusType HAL_CRG_IpClkDivGet(const void *baseAddress, unsigned int *div) +{ + CRG_ASSERT_PARAM(baseAddress != NULL); + CRG_ASSERT_PARAM(div != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); + /* Get the CRG type of the target IP. */ + CHIP_CrgIpMatchInfo *p = GetCrgIpMatchInfo(baseAddress); + if ((p == NULL) || (p->type >= CRG_IP_MAX_TYPE)) { + return BASE_STATUS_ERROR; + } + if (g_ipClkProc[p->type].clkDivGet == NULL) { + return BASE_STATUS_ERROR; + } + *div = g_ipClkProc[p->type].clkDivGet(p); /* Get the clock frequency division coefficient of a module. */ + return BASE_STATUS_OK; +} + +/** + * @brief PVD reset function enable switch + * @param pvd reset enable select + * @retval None + */ +void HAL_CRG_PvdResetEnable(bool enable) +{ + CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); + g_crgBaseAddr->CRG_PVD_RST_EN.BIT.pvd_rst_enable = enable; +} + +/** + * @brief Based on the target frequency, obtain the post division of the pll + * @param targetFreq Target frequency + * @param clkPfdFreq The freq of Pll after frequency multiplication + * @param divCfg Output Pll division config + * @retval None + */ +static void CRG_GetPllTargetFreqPostDiv(unsigned int targetFreq, unsigned int preDiv, unsigned int fbDiv, + unsigned int clkPfdFreq, CRG_PllDivCfg *divCfg) +{ + unsigned int clkVcoFreq; + unsigned int freq; + unsigned int delta; + unsigned int minDelta = 0xFFFFFFFF; /* Set the maximum value and initialize the default value. */ + unsigned int postDiv; + + clkVcoFreq = clkPfdFreq * fbDiv; + for (unsigned int i = CRG_PLL_POSTDIV_1; i <= CRG_PLL_POSTDIV_8; i++) { + postDiv = i; + /* Check whether the frequency after frequency division is valid. */ + if (!IsCrgValidPostDiv(clkVcoFreq, postDiv)) { + continue; + } + freq = clkVcoFreq / (postDiv + 1); + delta = (targetFreq >= freq) ? targetFreq - freq : freq - targetFreq; + if (delta < minDelta) { /* Updating Configuration Parameter Values. */ + minDelta = delta; + divCfg->PreDiv = preDiv; + divCfg->fbDiv = fbDiv; + divCfg->postDiv = i; + } + } +} + +/** + * @brief Based on the target frequency, obtain the optimal frequency division coefficient of the pll + * @param targetFreq Target frequency + * @param pllRefFreq Pll refer clock frequency + * @param divCfg Output Pll division config + * @retval None + */ +static void CRG_GetPllOptConfig(unsigned int targetFreq, unsigned int pllRefFreq, CRG_PllDivCfg *divCfg) +{ + unsigned int preDiv[] = {CRG_PLL_PREDIV_1, CRG_PLL_PREDIV_2, CRG_PLL_PREDIV_3, CRG_PLL_PREDIV_4, CRG_PLL_PREDIV_5, + CRG_PLL_PREDIV_6, CRG_PLL_PREDIV_7, CRG_PLL_PREDIV_8}; + unsigned int preDivOut; + unsigned int clkPfdFreq; + /* Configuring PLL Parameter Initialization. */ + divCfg->PreDiv = CRG_PLL_PREDIV_1; + divCfg->fbDiv = CRG_PLL_FBDIV_MIN; + divCfg->postDiv = CRG_PLL_POSTDIV_1; + + for (unsigned int i = 0; i < sizeof(preDiv) / sizeof(preDiv[0]); ++i) { + preDivOut = CRG_GetPreDivValue(preDiv[i]); + /* Check whether the frequency value after pre-division is valid. */ + if (!IsCrgValidPreDiv(pllRefFreq, preDivOut)) { + continue; + } + clkPfdFreq = pllRefFreq / preDivOut; + + for (unsigned int j = CRG_PLL_FBDIV_MIN; j <= CRG_PLL_FBDIV_MAX; ++j) { + /* Check whether the frequency value after frequency multiplication is valid. */ + if (!IsCrgValidFdDiv(clkPfdFreq, j)) { + continue; + } + /* Get the post division of the pll. */ + CRG_GetPllTargetFreqPostDiv(targetFreq, preDiv[i], j, clkPfdFreq, divCfg); + } + } +} + +/** + * @brief Get ADC Clock Frequence + * @param matchInfo match info + * @param baseClkRate clock rate + * @param coreClkFreq core clock rate + * @retval Ip Frequence + */ +static unsigned int CRG_GetAdcIpFreq(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int baseClkRate, + unsigned int coreClkFreq) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + + unsigned int clkSel; + unsigned int clkDiv; + unsigned int pst2Div; + unsigned int freq = 0; + + /* Obtains the clock source selection of the ADC. */ + const CRG_IpProc *proc = &g_ipClkProc[matchInfo->type]; + if (proc->clkSelGet == NULL) { + return 0; + } + clkSel = proc->clkSelGet(matchInfo); + /* Calculate the frequency from the ADC's clock source. */ + if (clkSel == CRG_ADC_CLK_SYN_CORE) { + freq = coreClkFreq; + } else if (clkSel == CRG_ADC_CLK_ASYN_HOSC) { + freq = HOSC_FREQ; + } else if (clkSel == CRG_ADC_CLK_ASYN_TCXO) { + /* The maximum speed of the external clock source is 30000000U. */ + freq = (XTRAIL_FREQ > 30000000U) ? 0 : XTRAIL_FREQ; + } else if (clkSel == CRG_ADC_CLK_ASYN_PLL_DIV) { + pst2Div = CRG_GetPllPostDivValue((CRG_PllPostDiv)g_crgBaseAddr->CRG_PLL_PSTDIV.BIT.pll_postdiv2); + freq = baseClkRate / pst2Div; + } + + /* Obtain the frequency divider based on the ADC clock source. */ + if (proc->clkDivGet == NULL) { + return 0; + } + clkDiv = proc->clkDivGet(matchInfo); + /* Calculate the clock frequency of the ADC. */ + return (freq / (clkDiv + 1)); +} + +/** + * @brief Check is Valid Pll Config + * @param CRG_Handle CRG handle + * @retval BASE_STATUS_OK Check Success + * @retval BASE_STATUS_ERROR Check Fail + */ +static BASE_StatusType CRG_IsValidPllConfig(const CRG_Handle *handle) +{ + unsigned int preDiv; + unsigned int freq; + + freq = CRG_GetPllRefIni(handle->pllRefClkSelect); + preDiv = CRG_GetPreDivValue(handle->pllPreDiv); + /* Check the validity of the prescaled clock frequency. */ + if (!IsCrgValidPreDiv(freq, preDiv)) { + return BASE_STATUS_ERROR; + } + freq /= preDiv; + /* Check the validity of the clock frequency after frequency multiplication. */ + if (!IsCrgValidFdDiv(freq, handle->pllFbDiv)) { + return BASE_STATUS_ERROR; + } + freq *= (handle->pllFbDiv > 0x06) ? handle->pllFbDiv : 0x06; /* 0x0-0x6: divided by 0x6 */ + /* Check whether the PLL output frequency is valid. */ + if (IsCrgValidPostDiv(freq, handle->pllPostDiv) && IsCrgValidPostDiv2(freq, handle->handleEx.pllPostDiv2)) { + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Check is Valid 1MHz Config + * @param CRG_Handle CRG handle + * @retval BASE_STATUS_OK Check Success + * @retval BASE_STATUS_ERROR Check Fail + */ +static BASE_StatusType CRG_IsValid1MHzConfig(const CRG_Handle *handle) +{ + unsigned int freq; + /* Get the ref frequency of the 1 MHz clock. */ + freq = (handle->handleEx.clk1MSelect == CRG_1M_CLK_SELECT_HOSC) ? HOSC_FREQ : XTRAIL_FREQ; + /* Check whether the 1MHz output frequency is valid. */ + if ((freq / (handle->handleEx.clk1MDiv + 1)) == CRG_FREQ_1MHz) { + return BASE_STATUS_OK; + } + return BASE_STATUS_ERROR; +} + +/** + * @brief Get clock frequence + * @param crg CRG_RegStruct + * @retval The frequence fo clock + */ +static inline unsigned int CRG_GetPllRefIni(CRG_PllRefClkSelect pllRefClkSelect) +{ + /* The maximum speed of the external clock source is 30000000U. */ + if (pllRefClkSelect == CRG_PLL_REF_CLK_SELECT_XTAL && XTRAIL_FREQ > 30000000U) { + return 0; + } + return (pllRefClkSelect == (unsigned int)CRG_PLL_REF_CLK_SELECT_HOSC) ? HOSC_FREQ : XTRAIL_FREQ; +} + +/** + * @brief Get previous division Value before PLL + * @param crg CRG_RegStruct + * @retval Previous Div value + */ +static inline unsigned int CRG_GetPreDivValue(CRG_PllPreDiv pllPredDiv) +{ + unsigned int preDiv; + if (pllPredDiv <= CRG_PLL_PREDIV_1) { /* 0 or 1 returns PLL_PREDIV_OUT_1. */ + preDiv = PLL_PREDIV_OUT_1; + } else { + preDiv = pllPredDiv + 1; + } + return preDiv; +} + +/** + * @brief Get PLL loop divider ratio + * @param crg CRG_RegStruct + * @retval PLL loop divider ratio + */ +static inline unsigned int CRG_GetPllFbDivValue(unsigned int pllFbDiv) +{ + unsigned int div = pllFbDiv; + /* Check the validity of the minimum frequency multiplication parameter. */ + if (div < CRG_PLL_FBDIV_MIN) { + div = CRG_PLL_FBDIV_MIN; + } + /* Check the validity of the maximum frequency multiplication parameter. */ + if (div > CRG_PLL_FBDIV_MAX) { + div = CRG_PLL_FBDIV_MAX; + } + return div; +} + +/** + * @brief Get post division Value after PLL + * @param crg CRG_RegStruct + * @retval Previous Div value + */ +static inline unsigned int CRG_GetPllPostDivValue(unsigned int pllPostDiv) +{ + unsigned int div = pllPostDiv; + if (div > CRG_PLL_POSTDIV_8) { + div = (CRG_PLL_POSTDIV_8 + 1); /* If the postdiv is greater than 8, set this postdiv to 8. */ + } else { + div += 1; + } + return div; +} + +/** + * @brief Enable Set of IP in APB_HS_SUBSYS + * @param matchInfo IP without Clock select match info + * @param enable BASE_CFG_SET or BASE_CFG_UNSET + * @retval None + */ +static void CRG_IpWoClkSelEnableSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int enable) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + CRG_IpWoClkSelectCfg *p = (CRG_IpWoClkSelectCfg *)(void *)(base + matchInfo->regOffset); + CRG_IpWoClkSelectCfg cfg; + cfg.value = p->value; + if (enable & IP_CLK_ENABLE) { /* Set enable of target ip. */ + cfg.BIT.clkEnMask |= 1 << matchInfo->bitOffset; + cfg.BIT.softResetReq &= ~(1 << matchInfo->bitOffset); + } else { + cfg.BIT.clkEnMask &= ~(1 << matchInfo->bitOffset); /* Disable of target ip. */ + cfg.BIT.softResetReq |= (1 << matchInfo->bitOffset); + } + p->value = cfg.value; +} + +/** + * @brief Get Enable status of IP in APB_HS_SUBSYS + * @param matchInfo IP without Clock select match info + * @retval Clock Enable status + */ +static unsigned int CRG_IpWoClkSelEnableGet(const CHIP_CrgIpMatchInfo *matchInfo) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + /* Get enable status of target ip. */ + CRG_IpWoClkSelectCfg *p = (CRG_IpWoClkSelectCfg *)(void *)(base + matchInfo->regOffset); + CRG_IpWoClkSelectCfg cfg; + + cfg.value = p->value; + return (cfg.BIT.clkEnMask & (1 << matchInfo->bitOffset)) == 0 ? false : true; +} + +/** + * @brief Reset/undo reset of IP in APB_HS_SUBSYS + * @param matchInfo IP without Clock select match info + * @param reset BASE_CFG_SET or BASE_CFG_UNSET + * @retval None + */ +static void CRG_IpWoClkSelResetSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int reset) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + CRG_IpWoClkSelectCfg *p = (CRG_IpWoClkSelectCfg *)(void *)(base + matchInfo->regOffset); + CRG_IpWoClkSelectCfg cfg; + cfg.value = p->value; + if (reset & BASE_CFG_SET) { + cfg.BIT.softResetReq |= 1 << matchInfo->bitOffset; /* reset of target ip. */ + } else { + cfg.BIT.softResetReq &= ~(1 << matchInfo->bitOffset); /* Undo reset of target ip. */ + } + p->value = cfg.value; +} + +/** + * @brief Get Reset status of IP in APB_HS_SUBSYS + * @param matchInfo IP without Clock select match info + * @retval Clock select reset status + */ +static unsigned int CRG_IpWoClkSelResetGet(const CHIP_CrgIpMatchInfo *matchInfo) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + /* Get the reset status of target ip. */ + CRG_IpWoClkSelectCfg *p = (CRG_IpWoClkSelectCfg *)(void *)(base + matchInfo->regOffset); + CRG_IpWoClkSelectCfg cfg; + cfg.value = p->value; + return (cfg.BIT.softResetReq & (1 << matchInfo->bitOffset)) ? BASE_CFG_SET : BASE_CFG_UNSET; +} + +/** + * @brief Enable/Disable ADC Clock + * @param matchInfo ADC match info + * @param enable IP_CLK_ENABLE + * @retval None + */ +static void CRG_AdcEnableSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int enable) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + CRG_AdcIpCfg *p = (CRG_AdcIpCfg *)(void *)(base + matchInfo->regOffset); + CRG_AdcIpCfg cfg; + cfg.value[1] = p->value[1]; + if (enable) { /* Enables and Deassert reset the ADC clock. */ + cfg.BIT.clk_adc_cken = BASE_CFG_SET; + cfg.BIT.adc_srst_req = BASE_CFG_UNSET; + } else { /* Disable and reset the ADC clock. */ + cfg.BIT.clk_adc_cken = BASE_CFG_UNSET; + cfg.BIT.adc_srst_req = BASE_CFG_UNSET; + } + p->value[1] = cfg.value[1]; +} + +/** + * @brief Get Enable status of ADC + * @param matchInfo ADC match info + * @retval Cken of ADC + */ +static unsigned int CRG_AdcEnableGet(const CHIP_CrgIpMatchInfo *matchInfo) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + unsigned int enable; + /* Get the enable status of the ADC clock gating. */ + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + CRG_AdcIpCfg *p = (CRG_AdcIpCfg *)(void *)(base + matchInfo->regOffset); + enable = ((p->BIT.clk_adc_cken != 0)) ? IP_CLK_ENABLE : IP_CLK_DISABLE; + return enable; +} + +/** + * @brief Set ADC Clock Select + * @param matchInfo ADC match info + * @param clkSelect @see CRG_AdcClkSelect + * @retval None + */ +static void CRG_AdcClkSelectSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int clkSelect) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + CRG_ASSERT_PARAM(IsCRGInstance(g_crgBaseAddr)); + CRG_PARAM_CHECK_NO_RET(IsCrgAdcClkModeSelect(clkSelect)); + + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + CRG_AdcIpCfg *p = (CRG_AdcIpCfg *)(void *)(base + matchInfo->regOffset); + if (clkSelect == CRG_ADC_CLK_SYN_CORE) { + p->BIT.cfg_adc_ckmode_sel = BASE_CFG_SET; /* use sync clock */ + } else { + DCL_SYSCTRL_CrgWriteProtectionDisable(); + g_crgBaseAddr->CRG_SYS_CKSEL.BIT.clk_pst2_sw_sel = clkSelect; /* write clock selection */ + DCL_SYSCTRL_CrgWriteProtectionEnable(); + p->BIT.cfg_adc_ckmode_sel = BASE_CFG_UNSET; + } +} + +/** + * @brief Get ADC Clock Select + * @param matchInfo ADC match info + * @retval Adc Clock select @see CRG_AdcClkSelect + */ +static unsigned int CRG_AdcClkSelectGet(const CHIP_CrgIpMatchInfo *matchInfo) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + CRG_AdcIpCfg *p = (CRG_AdcIpCfg *)(void *)(base + matchInfo->regOffset); + if (p->BIT.cfg_adc_ckmode_sel == BASE_CFG_SET) { + return CRG_ADC_CLK_SYN_CORE; /* Synchronous clock signal */ + } + return g_crgBaseAddr->CRG_SYS_CKSEL.BIT.clk_pst2_sw_sel; /* asynchronous clock signal */ +} + +/** + * @brief Set ADC Div + * @param matchInfo ADC match info + * @param div Adc clock division + * @retval None + */ +static void CRG_AdcDivSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int div) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + CRG_PARAM_CHECK_NO_RET(IsCrgAdcClkDiv(div)); + + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + CRG_AdcIpCfg *p = (CRG_AdcIpCfg *)(void *)(base + matchInfo->regOffset); + unsigned int clkMode = p->BIT.cfg_adc_ckmode_sel; + if (clkMode == CRG_ADC_CLK_SYNCHRONOUS) { + p->BIT.clk_adc_div1 = div; /* write div to I1 */ + } else { + p->BIT.clk_adc_div0 = div; /* write div to I0 */ + } +} + +/** + * @brief Get ADC clock division + * @param matchInfo ADC match info + * @retval Adc clock division + */ +static unsigned int CRG_AdcDivGet(const CHIP_CrgIpMatchInfo *matchInfo) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + CRG_AdcIpCfg *p = (CRG_AdcIpCfg *)(void *)(base + matchInfo->regOffset); + + unsigned int clkMode = p->BIT.cfg_adc_ckmode_sel; + + if (clkMode == CRG_ADC_CLK_SYNCHRONOUS) { + return p->BIT.clk_adc_div1; /* return div value I1 */ + } + return p->BIT.clk_adc_div0; /* return div valye I0 */ +} + +/** + * @brief Enable Clock of EFC + * @param matchInfo EFC match Info + * @param enable IP_CLK_ENABLE or IP_CRG_DISABLE + */ +static void CRG_EfcEnableSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int enable) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + /* Enables or disables EFC clock gating. */ + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + CRG_EfcIpCfg *p = (CRG_EfcIpCfg *)(void *)(base + matchInfo->regOffset); + /* Disable the write protection function of the CRG register. */ + DCL_SYSCTRL_CrgWriteProtectionDisable(); + p->BIT.eflash_cken = (enable & IP_CLK_ENABLE) ? BASE_CFG_SET : BASE_CFG_UNSET; + DCL_SYSCTRL_CrgWriteProtectionEnable(); +} + +/** + * @brief Disable Clock of EFC + * @param matchInfo EFC match Info + * @return unsigned int IP_CLK_ENABLE or IP_CRG_DISABLE + */ +static unsigned int CRG_EfcEnableGet(const CHIP_CrgIpMatchInfo *matchInfo) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + /* Get the value of the EFC register in the CRG. */ + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + /* Disable the write protection function of the CRG register. */ + DCL_SYSCTRL_CrgWriteProtectionDisable(); + CRG_EfcIpCfg *p = (CRG_EfcIpCfg *)(void *)(base + matchInfo->regOffset); + DCL_SYSCTRL_CrgWriteProtectionEnable(); + return p->BIT.eflash_cken; +} + + +/** + * @brief Enable Clock of ANA + * @param matchInfo ANA match Info + * @param enable IP_CLK_ENABLE or IP_CRG_DISABLE + */ +static void CRG_AnaEnableSet(const CHIP_CrgIpMatchInfo *matchInfo, unsigned int enable) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + CRG_PARAM_CHECK_NO_RET(enable == IP_CLK_ENABLE || enable == IP_CLK_DISABLE); + + /* Get the value of the ANA IP register in the CRG. */ + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + CRG_AnaIpCfg *p = (CRG_AnaIpCfg *)(void *)(base + matchInfo->regOffset + matchInfo->bitOffset); + + if ((enable == IP_CLK_ENABLE) && (p->BIT.ip_srst_req == BASE_CFG_SET)) { + p->BIT.ip_srst_req = BASE_CFG_UNSET; + g_anaEnableFlag++; /* count enable analog IP number */ + } else if ((enable == IP_CLK_DISABLE) && (p->BIT.ip_srst_req == BASE_CFG_UNSET)) { + p->BIT.ip_srst_req = BASE_CFG_SET; + if (g_anaEnableFlag > 0) { + g_anaEnableFlag--; /* Decreasing the count to enable the analog IP number. */ + } + } + + if ((g_anaEnableFlag == 0) && (enable == IP_CLK_DISABLE)) { /* all analog clock disable */ + CRG->CRG_ANA.BIT.clk_ana_cken = BASE_CFG_UNSET; + CRG->CRG_ANA.BIT.ana_srst_req = BASE_CFG_SET; + } else if ((g_anaEnableFlag > 0) && (enable == IP_CLK_ENABLE)) { /* all analog clock enable */ + CRG->CRG_ANA.BIT.ana_srst_req = BASE_CFG_UNSET; + CRG->CRG_ANA.BIT.clk_ana_cken = BASE_CFG_SET; + } +} + +/** + * @brief Get Clock of ANA + * @param matchInfo ANA match Info + * @return unsigned int IP_CLK_ENABLE or IP_CRG_DISABLE + */ +static unsigned int CRG_AnaEnableGet(const CHIP_CrgIpMatchInfo *matchInfo) +{ + CRG_ASSERT_PARAM(matchInfo != NULL); + CRG_ASSERT_PARAM(g_crgBaseAddr != NULL); + + /* Get the value of the ANA IP register in the CRG. */ + uintptr_t base = (uintptr_t)(void *)g_crgBaseAddr; + CRG_AnaIpCfg *p = (CRG_AnaIpCfg *)(void *)(base + matchInfo->regOffset + matchInfo->bitOffset); + /* The clock is enabled based on the IP reset status. */ + return (p->BIT.ip_srst_req) ? BASE_CFG_UNSET : BASE_CFG_SET; +} \ No newline at end of file diff --git a/src/drivers/dac/common/inc/dac.h b/src/drivers/dac/common/inc/dac.h index 4849c0926f119e9da7ff28e028190b5e3f9030ab..c1e0de5698b3b2dc8250551c9f5d2ddab7327c60 100644 --- a/src/drivers/dac/common/inc/dac.h +++ b/src/drivers/dac/common/inc/dac.h @@ -63,6 +63,7 @@ typedef struct _DAC_Handle { * @{ */ /* DAC APIs */ + BASE_StatusType HAL_DAC_Init(DAC_Handle *dacHandle); BASE_StatusType HAL_DAC_DeInit(DAC_Handle *dacHandle); void HAL_DAC_SetValue(DAC_Handle *dacHandle, unsigned int value); diff --git a/src/drivers/dac/dac_v1/inc/dac_ip.h b/src/drivers/dac/dac_v1/inc/dac_ip.h index f51391252836e3bcae9231ca514b35c496c8643b..9136bbb6419f9ed6b6ae6fc4f40faec77906abaa 100644 --- a/src/drivers/dac/dac_v1/inc/dac_ip.h +++ b/src/drivers/dac/dac_v1/inc/dac_ip.h @@ -62,6 +62,7 @@ * @brief Extent handle definition of DAC. */ typedef struct { + bool pinOutputEn; } DAC_ExtendHandle; /** @@ -110,6 +111,19 @@ typedef union { } BIT; } volatile DAC_TRIM_REG1; +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) +/** + * @brief DAC TEST register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_dac_test_enh : 1; /**< Value of DAC test output enable. */ + unsigned int reserved_1 : 31; + } BIT; +} volatile DAC_TEST_REG; +#endif /** * @brief DAC registers definition structure. */ @@ -117,6 +131,11 @@ typedef struct _DAC_RegStruct { DAC_CTRL_REG0 DAC_CTRL; /**< DAC control register. Offset address: 0x00000000U */ unsigned char space0[12]; DAC_CTRL_REG1 DAC_VALUE; /**< DAC voltage level configuration register. Offset address: 0x00000010U */ +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + unsigned char space1[116]; + DAC_TEST_REG DAC_TEST_EN; /**< DAC control register. Offset address: 0x00000088U */ +#endif } volatile DAC_RegStruct; /* Parameter Check -----------------------------------------------------------*/ @@ -166,6 +185,30 @@ static inline void DCL_DAC_SetValue(DAC_RegStruct *dacx, unsigned int value) dacx->DAC_VALUE.BIT.cfg_dac_vset = value; } +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) +/** + * @brief Set DAC test mode config, pin ouput enable or diable + * @param dacx: DAC register base address. + * @param config: DAC output enable bit value. + */ +static inline void DCL_DAC_SetPinOutputConfig(DAC_RegStruct *dacx, bool config) +{ + DAC_ASSERT_PARAM(IsDACInstance(dacx)); + dacx->DAC_TEST_EN.BIT.da_dac_test_enh = config; +} + +/** + * @brief Get DAC test mode config, pin ouput enable or diable + * @param dacx: DAC register base address. + */ +static inline bool DCL_DAC_GetPinOutputConfig(DAC_RegStruct *dacx) +{ + DAC_ASSERT_PARAM(IsDACInstance(dacx)); + return dacx->DAC_TEST_EN.BIT.da_dac_test_enh; +} +#endif + /** * @} */ diff --git a/src/drivers/dac/dac_v1/src/dac.c b/src/drivers/dac/dac_v1/src/dac.c index 7dbd89f6f90f1b5c7622971fb9793529c6aa5123..7682b12aaaa437ebf027556aec276500670fe49e 100644 --- a/src/drivers/dac/dac_v1/src/dac.c +++ b/src/drivers/dac/dac_v1/src/dac.c @@ -26,6 +26,8 @@ #include "dac.h" #include "assert.h" +#define DAC_PIN_OUTPUT_CONFIG_ADDR (0x18600008) +#define DAC_PIN_OUTPUT_CONFIG_VALUE (0x2) /** * @brief Set DAC value * @param dacHandle: DAC handle. @@ -57,6 +59,15 @@ BASE_StatusType HAL_DAC_Init(DAC_Handle *dacHandle) dacHandle->baseAddress->DAC_VALUE.BIT.cfg_dac_vset = dacHandle->dacValue; /* Turn on the DAC. */ dacHandle->baseAddress->DAC_CTRL.BIT.da_dac_enh = BASE_CFG_ENABLE; + /* Dac pin output mode config */ + if (dacHandle->handleEx.pinOutputEn) { +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + DCL_DAC_SetPinOutputConfig(dacHandle->baseAddress, BASE_CFG_ENABLE); +#else + *(unsigned int*)DAC_PIN_OUTPUT_CONFIG_ADDR = DAC_PIN_OUTPUT_CONFIG_VALUE; +#endif + } /* Wait output stable */ BASE_FUNC_DELAY_US(60); /* delay 60us */ return BASE_STATUS_OK; @@ -73,5 +84,6 @@ BASE_StatusType HAL_DAC_DeInit(DAC_Handle *dacHandle) DAC_ASSERT_PARAM(IsDACInstance(dacHandle->baseAddress)); dacHandle->baseAddress->DAC_CTRL.reg = BASE_CFG_DISABLE; /* Disable DAC, clears the count value. */ dacHandle->baseAddress->DAC_VALUE.reg = BASE_CFG_DISABLE; /* Clear DAC value. */ + *(unsigned int*)DAC_PIN_OUTPUT_CONFIG_ADDR = 0; /* disable dac pin output */ return BASE_STATUS_OK; } \ No newline at end of file diff --git a/src/drivers/debug/inc/debug.h b/src/drivers/debug/inc/debug.h index ce2a1aa5293eac2a7933168ef0a98811b74d65d8..c142d4500c7334350ec457f0b30c2152ccc8418d 100644 --- a/src/drivers/debug/inc/debug.h +++ b/src/drivers/debug/inc/debug.h @@ -66,15 +66,29 @@ static inline int DBG_dummy(const char *format, ...) #define DBG_PRINTF DBG_UartPrintf /**< Select the customized printf function */ #endif +#define DBG_SNPRINTF DBG_Snprintf /**< Select debug snprintf function */ + /** - * @defgroup DEBUG_API_Declaration DEBUG HAL API + * @defgroup DEBUG_API_Declaration + * @brief DEBUG HAL API. * @{ */ + BASE_StatusType DBG_UartPrintInit(unsigned int baudRate); BASE_StatusType DBG_UartPrintDeInit(void); -/* Format print function */ +/** + * @defgroup DEBUG_API_Declaration + * @brief Format print function. + * @{ + */ + int DBG_UartPrintf(const char *format, ...); /* Supported format: %c, %s, %d, %u, %x, %X, %p, %f */ +int DBG_Snprintf(char* destMem, unsigned int destLen, const char *format, ...); + +/** + * @} + */ /** * @} diff --git a/src/drivers/debug/log/inc/command.h b/src/drivers/debug/log/inc/command.h index 4732fafa737aef17ef85136b70f101cd08bbb122..f125b866cd26e73789aac3161b6884ef7a00ff57 100644 --- a/src/drivers/debug/log/inc/command.h +++ b/src/drivers/debug/log/inc/command.h @@ -54,10 +54,10 @@ struct CmdTable { * @brief use cmd line to find cmd * @attention None * - * @param str [IN] command character string carried in the command line + * @param cmd [IN] command character string carried in the command line * @retval struct cmdRegisterTable * */ -struct cmdRegisterTable *ExtCmdFindCmd(const char *str); +struct cmdRegisterTable *ExtCmdFindCmd(const char *cmd); /** * @brief use cmd line to match cmd read diff --git a/src/drivers/debug/log/inc/config.h b/src/drivers/debug/log/inc/config.h index 573eaa740ac7a203f9ae78031f6869fe11b32701..0d5bcc7b3ee58dc084f6040372473e97925d9f51 100644 --- a/src/drivers/debug/log/inc/config.h +++ b/src/drivers/debug/log/inc/config.h @@ -64,7 +64,7 @@ enum DataItem { * @param len [OUT] Length of the read content * @retval None */ -void ExtLoadRead(uintptr_t add, char *value, int len); +void ExtLoadRead(uintptr_t add, char *value, unsigned int len); /** * @extLoadWrite Write the content in the configuration address according to the address @@ -75,7 +75,7 @@ void ExtLoadRead(uintptr_t add, char *value, int len); * @param len [IN] Length of the content to be written * @retval None */ -void ExtLoadWrite(uintptr_t add, const char *value, int len); +void ExtLoadWrite(uintptr_t add, const char *value, unsigned int len); /** * @extConfigRead Reads content based on data items diff --git a/src/drivers/debug/log/inc/console.h b/src/drivers/debug/log/inc/console.h index d870fd981997a0e12826627eb516f78b5de0611f..b0c9b7933fb880acad601af8e8f34c0d70ebb7e0 100644 --- a/src/drivers/debug/log/inc/console.h +++ b/src/drivers/debug/log/inc/console.h @@ -52,14 +52,14 @@ int ConsoleGetc(void); * @brief Output String * @{ */ -int ConsolePuts(const char *str); +unsigned int ConsolePuts(const char *str); /** * @brief Output Characters * @{ */ void ConsolePutc(const char c); /* Format print function */ -int UartPrintf(const char *format, ...); +unsigned int UartPrintf(const char *format, ...); /* init console uart */ void ConsoleInit(UART_Handle uart); diff --git a/src/drivers/debug/log/inc/dfx_log.h b/src/drivers/debug/log/inc/dfx_log.h index bbb51567b71a6c75aceca8082aa0d3b172dce1b0..b25130542f5f358ff2a1d01d94559aec6c984794 100644 --- a/src/drivers/debug/log/inc/dfx_log.h +++ b/src/drivers/debug/log/inc/dfx_log.h @@ -59,7 +59,7 @@ struct MemoryLog { struct SysLogCtx { unsigned char init; char **modStr; - enum ExtLogLevel logLevel[EXT_MODULE_BUTT]; + enum ExtLogLevel logLevel[EXT_MODULE_BUTT + 1]; struct MemoryLog memLog; }; struct SysDebugSwitch { diff --git a/src/drivers/debug/log/inc/file_id_defs.h b/src/drivers/debug/log/inc/file_id_defs.h index b1005a51f8c2b53f5243d11420d2c639078cd2d2..5abd3c2f5e5571decb1b226f6766bc7546c87b30 100644 --- a/src/drivers/debug/log/inc/file_id_defs.h +++ b/src/drivers/debug/log/inc/file_id_defs.h @@ -44,6 +44,12 @@ extern "C" { typedef enum { FILE_ID_LOG_C = 2001, /* this is a test sample */ + FILE_ID_DFX_CRASH_C = 2002, + FILE_ID_INTERRUPT_C = 2003, + FILE_ID_SAMPLE_C = 2004, + FILE_ID_DRV_INTERRUPT_C = 2005, + FILE_ID_DRV_ASM_C = 3001, + FILE_ID_DRV_XFE_C = 3002, } file_id_enum; #ifdef __cplusplus diff --git a/src/drivers/debug/log/src/config.c b/src/drivers/debug/log/src/config.c index 2cdb30cdd5e64406c5d3dc17519b9cd37cb590e6..236913d2b58898240e9b080fb003b95aee919fb0 100644 --- a/src/drivers/debug/log/src/config.c +++ b/src/drivers/debug/log/src/config.c @@ -37,10 +37,10 @@ * @param len : length of the information to be read * @retval None. */ -void ExtLoadRead(uintptr_t add, char *value, int len) +void ExtLoadRead(uintptr_t add, char *value, unsigned int len) { /* Check whether the address is out of range */ - if (add > REGISTER_END || add < REGISTER_START) { + if (add > SRAM_END || add < SRAM_START) { EXT_PRINT("The address is out of range"); return; } @@ -50,7 +50,7 @@ void ExtLoadRead(uintptr_t add, char *value, int len) return; } /* Read information cyclically */ - for (int i = 0; i < len; i++) { + for (unsigned int i = 0; i < len; i++) { *(value + i) = *(volatile char *)(add + i); } } @@ -62,10 +62,10 @@ void ExtLoadRead(uintptr_t add, char *value, int len) * @param len : length of the information to write * @retval None. */ -void ExtLoadWrite(uintptr_t add, const char *value, int len) +void ExtLoadWrite(uintptr_t add, const char *value, unsigned int len) { /* Check whether the address is out of range */ - if (add > REGISTER_END || add < REGISTER_START) { + if (add > SRAM_END || add < SRAM_START) { EXT_PRINT("The address is out of range"); return; } @@ -75,12 +75,12 @@ void ExtLoadWrite(uintptr_t add, const char *value, int len) return; } /* Write information cyclically */ - for (int i = 0; i < len; i++) { + for (unsigned int i = 0; i < len; i++) { *(volatile char *)(add + i) = *(value + i); } } -char g_dataItem[DATA_ITEM_NUM_MAX][DATA_ITEM_MAX_LEN]; +char g_dataItem[DATA_ITEM_NUM_MAX + 1][DATA_ITEM_MAX_LEN + 1]; /** * @brief read information by config diff --git a/src/drivers/debug/log/src/console.c b/src/drivers/debug/log/src/console.c index 2c31c248893ea1eaa5063992946967db89c0c450..fcd592d59cfd5603d547c705fc960fdab9fe09be 100644 --- a/src/drivers/debug/log/src/console.c +++ b/src/drivers/debug/log/src/console.c @@ -85,9 +85,9 @@ void ConsolePutc(const char c) * @param str: string to be output. * @retval None */ -int ConsolePuts(const char *str) +unsigned int ConsolePuts(const char *str) { - int cnt = 0; + unsigned int cnt = 0; /* decompose a string into a single character output */ while (*str != '\0') { ConsolePutc(*str); @@ -340,10 +340,10 @@ static unsigned int ParseSpecifier(const char ch, va_list *paramList) * @param *paramList: Number of digits to be printed * @retval returns the number of digits of the output number */ -static unsigned int DBG_PrintIntWithField(int intNum, int fieldWidth) +static unsigned int DBG_PrintIntWithField(int intNum, unsigned int fieldWidth) { - int zeroCnt = 0; - int digitsCnt = 0; + unsigned int zeroCnt = 0; + unsigned int digitsCnt = 0; unsigned int cnt = 0; if (intNum == 0) { @@ -356,7 +356,7 @@ static unsigned int DBG_PrintIntWithField(int intNum, int fieldWidth) intNum = -intNum; digitsCnt = DBG_CountDigits(intNum, DECIMAL); /* get int value's width */ zeroCnt = fieldWidth - digitsCnt; - for (int i = 0; i < zeroCnt; i++) { + for (unsigned int i = 0; i < zeroCnt; i++) { ConsolePutc('0'); /* add '0' */ cnt++; } @@ -365,7 +365,7 @@ static unsigned int DBG_PrintIntWithField(int intNum, int fieldWidth) digitsCnt = DBG_CountDigits(intNum, DECIMAL); /* get int value's width */ cnt = digitsCnt; zeroCnt = fieldWidth - digitsCnt; - for (int i = 0; i < zeroCnt; i++) { + for (unsigned int i = 0; i < zeroCnt; i++) { ConsolePutc('0'); /* add '0' */ cnt++; } @@ -394,10 +394,10 @@ static int DBG_Atoi(const char **s) * @param *format: thing need to print * @retval returns the number of digits of the output number */ -int UartPrintf(const char *format, ...) +unsigned int UartPrintf(const char *format, ...) { /* Define Value Initialization */ - int cnt = 0; + unsigned int cnt = 0; int fieldWidth = 0; int floatPrecision = 0; float fltVal = 0; diff --git a/src/drivers/debug/log/src/dfx_log.c b/src/drivers/debug/log/src/dfx_log.c index b0cba421d07a0b8d515ba0cfccaea257eada5a7d..5385cff06ef5395a9b911e9db68770ce17259930 100644 --- a/src/drivers/debug/log/src/dfx_log.c +++ b/src/drivers/debug/log/src/dfx_log.c @@ -38,7 +38,7 @@ static struct MemoryLog g_memoryLog = {0}; #define DIVISOR 10 #define EXT_MODULE_DFX 12 /* Test Version Information Cases */ /* Address of the test case for obtaining version information */ -#define VERSION_INFO_ADDR 0x4000000 +#define VERSION_INFO_ADDR 0x2000000 /* Device Name */ char *moduleStr[EXT_MODULE_BUTT] = { "app_main", @@ -194,13 +194,13 @@ static unsigned int IsLogOutBufLegal(enum ExtLogLevel level, struct SysDebugSwit * @brief Log output and printing * @param level: Specifies the log level. * @param modId: Device ID - * @param id: device name + * @param xmlId: XML file ID * @param logBuf: Character string information to be printed * @param logBuflen: Indicates the length of the printed information. * @retval Indicates whether the printing is successful. */ -int ExtDrvLogOutBuf(enum ExtLogLevel level, enum ExtModule modId, unsigned int id, const unsigned int* logBuf, - unsigned short logBufLen) +int ExtDrvLogOutBuf(enum ExtLogLevel level, enum ExtModule modId, unsigned int xmlId, + const unsigned int* logBuf, unsigned short logBufLen) { /* Check whether the array is empty */ if (logBuf == NULL) @@ -216,7 +216,7 @@ int ExtDrvLogOutBuf(enum ExtLogLevel level, enum ExtModule modId, unsigned int i struct SysDebugSwitch *debugSwitch = GetDebugSwitch(); if (!ctx->init) { LogCtxInit(ctx); } /* Initialize the structure */ if (!(IsLogOutBufLegal(level, debugSwitch, modId, ctx))) { return EXT_SUCCESS; } - cnt = sprintf_s(buf, LOG_UINT_MAX_LEN, "%u", id); + cnt = sprintf_s(buf, LOG_UINT_MAX_LEN, "%u", xmlId); /* an error message is displayed when the return value is a negative value */ if (cnt < 0) { EXT_PRINT("sprintf err\n"); @@ -307,17 +307,17 @@ static int DealLogBuf(int len, enum ExtLogLevel level, enum ExtModule modId, con * @brief Print with no int number * @param level: Specifies the log level. * @param modId: Device ID - * @param id: custom string variable + * @param xmlId: custom string variable * @retval Indicates whether the printing is successful. */ -int ExtDrvLogOut0(enum ExtLogLevel level, enum ExtModule modId, unsigned int id) +int ExtDrvLogOut0(enum ExtLogLevel level, enum ExtModule modId, unsigned int xmlId) { /* Check whether the value is out of range */ if (level > EXT_LOG_LEVEL_BUTT || modId > EXT_MODULE_BUTT) return EXT_FAILURE; char buf[LOG_UINT_MAX_LEN] = { 0 }; int len = 0; - len = sprintf_s(buf, LOG_UINT_MAX_LEN, "%u\n", id); + len = sprintf_s(buf, LOG_UINT_MAX_LEN, "%u\n", xmlId); if (len < 0) { EXT_PRINT("sprintf err\n"); return EXT_FAILURE; @@ -330,18 +330,18 @@ int ExtDrvLogOut0(enum ExtLogLevel level, enum ExtModule modId, unsigned int id) * @brief Print with an int number * @param level: Specifies the log level. * @param modId: Device ID - * @param id: custom string variable + * @param xmlId: custom string variable * @param d0: User-defined first variable of the int type * @retval Indicates whether the printing is successful. */ -int ExtDrvLogOut1(enum ExtLogLevel level, enum ExtModule modId, unsigned int id, unsigned int d0) +int ExtDrvLogOut1(enum ExtLogLevel level, enum ExtModule modId, unsigned int xmlId, unsigned int d0) { /* Check whether the value is out of range */ if (level > EXT_LOG_LEVEL_BUTT || modId > EXT_MODULE_BUTT) return EXT_FAILURE; char buf[LOG_UINT_MAX_LEN] = { 0 }; int len = 0; - len = sprintf_s(buf, LOG_UINT_MAX_LEN, "%u %u\n", id, d0); + len = sprintf_s(buf, LOG_UINT_MAX_LEN, "%u %u\n", xmlId, d0); if (len < 0) { EXT_PRINT("sprintf err\n"); return EXT_FAILURE; @@ -354,19 +354,19 @@ int ExtDrvLogOut1(enum ExtLogLevel level, enum ExtModule modId, unsigned int id, * @brief Print with two int numbers * @param level: Specifies the log level. * @param modId: Device ID - * @param id: custom string variable + * @param xmlId: custom string variable * @param d0: User-defined first variable of the int type * @param d1: User-defined second variable of the int type * @retval Indicates whether the printing is successful. */ -int ExtDrvLogOut2(enum ExtLogLevel level, enum ExtModule modId, unsigned int id, unsigned int d0, unsigned int d1) +int ExtDrvLogOut2(enum ExtLogLevel level, enum ExtModule modId, unsigned int xmlId, unsigned int d0, unsigned int d1) { /* Check whether the value is out of range */ if (level > EXT_LOG_LEVEL_BUTT || modId > EXT_MODULE_BUTT) return EXT_FAILURE; char buf[LOG_UINT_MAX_LEN] = { 0 }; int len = 0; - len = sprintf_s(buf, LOG_UINT_MAX_LEN, "%u %u %u\n", id, d0, d1); + len = sprintf_s(buf, LOG_UINT_MAX_LEN, "%u %u %u\n", xmlId, d0, d1); if (len < 0) { EXT_PRINT("sprintf err\n"); return EXT_FAILURE; @@ -379,13 +379,13 @@ int ExtDrvLogOut2(enum ExtLogLevel level, enum ExtModule modId, unsigned int id, * @brief Print with three int numbers * @param level: Specifies the log level. * @param modId: Device ID - * @param id: custom string variable + * @param xmlId: custom string variable * @param d0: User-defined first variable of the int type * @param d1: User-defined second variable of the int type * @param d2: User-defined third variable of the int type * @retval Indicates whether the printing is successful. */ -int ExtDrvLogOut3(enum ExtLogLevel level, enum ExtModule modId, unsigned int id, unsigned int d0, unsigned int d1, +int ExtDrvLogOut3(enum ExtLogLevel level, enum ExtModule modId, unsigned int xmlId, unsigned int d0, unsigned int d1, unsigned int d2) { /* Check whether the value is out of range */ @@ -393,7 +393,7 @@ int ExtDrvLogOut3(enum ExtLogLevel level, enum ExtModule modId, unsigned int id, return EXT_FAILURE; char buf[LOG_UINT_MAX_LEN] = { 0 }; int len = 0; - len = sprintf_s(buf, LOG_UINT_MAX_LEN, "%u %u %u %u\n", id, d0, d1, d2); + len = sprintf_s(buf, LOG_UINT_MAX_LEN, "%u %u %u %u\n", xmlId, d0, d1, d2); if (len < 0) { EXT_PRINT("sprintf err\n"); return EXT_FAILURE; @@ -404,14 +404,14 @@ int ExtDrvLogOut3(enum ExtLogLevel level, enum ExtModule modId, unsigned int id, /** * @brief Setting the log level - * @param id: Indicates the device ID of the specified level + * @param modId: Indicates the device ID of the specified level * @param level: Level set for the device * @retval Indicates whether the printing is successful */ -int ExtDrvLogSetLogLevel(enum ExtModule id, enum ExtLogLevel level) +int ExtDrvLogSetLogLevel(enum ExtModule modId, enum ExtLogLevel level) { /* Exceeded the maximum value of the storage array */ - if (level >= EXT_LOG_LEVEL_BUTT || id >= EXT_MODULE_BUTT) { + if (level >= EXT_LOG_LEVEL_BUTT || modId >= EXT_MODULE_BUTT) { EXT_PRINT("module or level unsupport\n"); return EXT_FAILURE; } @@ -421,7 +421,7 @@ int ExtDrvLogSetLogLevel(enum ExtModule id, enum ExtLogLevel level) if (!ctx->init) { LogCtxInit(ctx); /* Initialize the structure */ } - ctx->logLevel[id] = level; + ctx->logLevel[modId] = level; return EXT_SUCCESS; } diff --git a/src/drivers/debug/src/debug.c b/src/drivers/debug/src/debug.c index d7cb26bc333134cac586e36d16cb174fa28c0f18..557597d29055e0b876345cd5971a88b868086d60 100644 --- a/src/drivers/debug/src/debug.c +++ b/src/drivers/debug/src/debug.c @@ -96,7 +96,7 @@ static void DBG_PrintCh(unsigned int ch) while (DBG_PRINTF_UART_PORT->UART_FR.BIT.txff == 1) { ; } - DBG_PRINTF_UART_PORT->UART_DR.BIT.data = (unsigned char)ch; + DBG_PRINTF_UART_PORT->UART_DR.reg = ch; } /** @@ -222,33 +222,41 @@ static unsigned int DBG_PrintHex(unsigned int hexNum) /** * @brief Print floating-point number through UART port. - * @param fltNum The floating-point number to be printed. + * @param fltNumber The floating-point number to be printed. * @retval unsigned int The total number of characters printed. */ -static unsigned int DBG_PrintFlt(float fltNum, unsigned int precision) +static unsigned int DBG_PrintFlt(float fltNumber, unsigned int precision) { unsigned int cnt = 0; unsigned int floatScale; - if (fltNum < 0) { + if (fltNumber < 0) { DBG_PrintCh('-'); cnt += 1; - fltNum = -fltNum; + fltNumber = -fltNumber; } - int integerVal = (int)fltNum; + int integerVal = (int)fltNumber; floatScale = DBG_Pow(10, (precision + 1)); /* 10: decimal */ - int floatVal = (long)(floatScale * (fltNum - integerVal)); + int floatVal = (long)(floatScale * (fltNumber - integerVal)); /* Half-adjust: round up or round down */ if (floatVal % DECIMAL_BASE >= HALF_ADJUST_BOUNDARY) { floatVal = floatVal / DECIMAL_BASE + 1; } else { floatVal = floatVal / DECIMAL_BASE; } + unsigned int fltCnt = DBG_CountDigits(floatVal, DECIMAL); + /* Rounding to the whole part */ + if (fltCnt > precision) { + integerVal += 1; + /* The decimal part is all 0s after the carry is carried to the integer part. */ + floatVal = 0; + /* Decimal significant bits are subtracted by 1. */ + fltCnt -= 1; + } cnt += DBG_PrintInt(integerVal); DBG_PrintCh('.'); cnt += 1; /* Pad 0 in float part */ - unsigned int fltCnt = DBG_CountDigits(floatVal, DECIMAL); if (precision > fltCnt) { for (unsigned int i = 0; i < precision - fltCnt; i++) { DBG_PrintCh('0'); /* add '0' */ @@ -413,4 +421,384 @@ int DBG_UartPrintf(const char *format, ...) VA_END(paramList); return cnt; } + +/** + * @brief Writes characters to memory of a specified length and returns the length written. + * @param chstr The int promotion of the character to be written. + * @param destMem point of memory address. + * @param destLen point of memory lenth. + * @retval unsigned int the length written. + */ +static unsigned int DBG_SnprintfChar(char chstr, char** destMem, unsigned int* destLen) +{ + DEBUG_ASSERT_PARAM(destMem != NULL); + DEBUG_ASSERT_PARAM(destLen != NULL); + if (*destLen == 0) { + return 0; + } + **destMem = chstr; /* Value assigned to the address pointed to by the memory pointer */ + *destMem = *destMem + 1; /* Memory pointer address plus 1 */ + *destLen = *destLen - 1; /* The remaining length of the buffer space is reduced by 1. */ + return 1; +} + +/** + * @brief write a string to memory of a specified length and returns the length written. + * @param str Character string to be formatted for output. + * @param destMem point of memory address. + * @param destLen point of memory lenth. + * @retval unsigned int the length written. + */ +static unsigned int DBG_SnprintfString(const char *str, char** destMem, unsigned int* destLen) +{ + DEBUG_ASSERT_PARAM(str != NULL); + DEBUG_ASSERT_PARAM(destMem != NULL); + DEBUG_ASSERT_PARAM(destLen != NULL); + int cnt = 0; + while (*str != '\0') { + if (DBG_SnprintfChar(*str, destMem, destLen) == 0) { + break; /* Store character strings based on the actual remaining space. */ + } + str++; + cnt++; /* Data and Technology Shifting Operations */ + } + return cnt; /* Returns the actual written length. */ +} + + +/** + * @brief Convert unsigned number to string and Stored in the buffer according to the basic data type. + * @param ch Characters to be formatted for output. + * @param base The number base of num. + * @param destMem point of memory address. + * @param destLen point of memory lenth. + * @retval bool Whether the writing is successful. + */ +static bool DBG_SnprintfBaseTypeNum(unsigned char ch, NumBase base, char** destMem, unsigned int* destLen) +{ + DEBUG_ASSERT_PARAM(destMem != NULL); + DEBUG_ASSERT_PARAM(destLen != NULL); + bool ret = true; + if (base == DECIMAL) { /* Decimal number */ + if (DBG_SnprintfChar((ch + '0'), destMem, destLen) == 0) { /* Number to String Conversion */ + return false; + } + } else if (base == HEXADECIMAL) { /* Hexadecimal number */ + if (ch < DECIMAL_BASE) { + if (DBG_SnprintfChar((ch + '0'), destMem, destLen) == 0) { /* Number to String Conversion */ + return false; + } + } else { + if (DBG_SnprintfChar((ch - DECIMAL_BASE + 'A'), destMem, destLen) == 0) { /* Number to String Conversion */ + return false; + } + } + } else { + return false; + } + return ret; +} + +/** + * @brief Convert unsigned number to string and write to memory of a specified length and returns the length written. + * @param num The unsigned number to be printed. + * @param base The number base of num. + * @param numLen The digits of num. + * @param destMem point of memory address. + * @param destLen point of memory lenth. + * @retval unsigned int the real length written. + */ +static unsigned int DBG_SnprintfUnsignedNum(unsigned int num, NumBase base, unsigned int numLen, \ + char** destMem, unsigned int* destLen) +{ + DEBUG_ASSERT_PARAM(destMem != NULL); + DEBUG_ASSERT_PARAM(destLen != NULL); + unsigned char ch = 0; + unsigned char realCnt = 0; + while (numLen != 0) { + ch = num / DBG_Pow(base, numLen - 1); /* Value of the most significant digit */ + num %= DBG_Pow(base, numLen - 1); + if (DBG_SnprintfBaseTypeNum(ch, base, destMem, destLen) != true) { + break; + } + numLen--; + realCnt++; + } + return realCnt; /* Returns the actual written length. */ +} + +/** + * @brief Convert signed num and write to memory of a specified length and returns the length written. + * @param intNum The decimal number to be printed. + * @param destMem point of memory address. + * @param destLen point of memory lenth. + * @retval unsigned int the real length written. + */ +static unsigned int DBG_SnprintfSignedNum(int intNum, char** destMem, unsigned int* destLen) +{ + unsigned int cnt; + unsigned int realCnt; + if (intNum == 0) { + if (DBG_SnprintfChar('0', destMem, destLen) == 0) { /* If the data is 0, store 0. */ + return 0; + } + return 1; + } + if (intNum < 0) { + if (DBG_SnprintfChar('-', destMem, destLen) == 0) { /* If the data is negative, store the minus sign. */ + return 0; + } + intNum = -intNum; + } + cnt = DBG_CountDigits(intNum, DECIMAL); /* Obtains the decimal length of data. */ + realCnt = DBG_SnprintfUnsignedNum(intNum, DECIMAL, cnt, destMem, destLen); + return realCnt; /* Returns the actual written length. */ +} + +/** + * @brief Convert hex num and write to memory of a specified length and returns the length written. + * @param hexNum The hex number to be printed. + * @param destMem point of memory address. + * @param destLen point of memory lenth. + * @retval unsigned int the real length written. + */ +static unsigned int DBG_SnprintfHex(unsigned int hexNum, char** destMem, unsigned int* destLen) +{ + unsigned int cnt = 0; + unsigned int realCnt; + if (hexNum == 0) { + if (DBG_SnprintfChar('0', destMem, destLen) == 0) { /* If the data is 0, store 0. */ + return 0; + } + return 1; + } /* Obtain and store the length of the character converted from the hexadecimal number. */ + cnt += DBG_CountDigits(hexNum, HEXADECIMAL); + realCnt = DBG_SnprintfUnsignedNum(hexNum, HEXADECIMAL, cnt, destMem, destLen); + return realCnt; /* Returns the actual written length. */ +} + +/** + * @brief Convert float number and write to memory of a specified length and returns the length written. + * @param fltNum The float number to be printed. + * @param precision Floating-point number precision. + * @param destMem point of memory address. + * @param destLen point of memory lenth. + * @retval unsigned int the real length written. + */ +static unsigned int DBG_SnprintfFlt(float fltNum, unsigned int precision, char** destMem, unsigned int* destLen) +{ + unsigned int count = 0; + unsigned int realCnt = 0; + unsigned int floatScale; + + if (fltNum < 0) { + if (DBG_SnprintfChar('-', destMem, destLen) == 0) { /* Stores the minus sign of a negative number */ + return 0; + } + count++; + fltNum = -fltNum; + } + int integerVal = (int)fltNum; + floatScale = DBG_Pow(10, (precision + 1)); /* 10: decimal */ + int floatVal = (long)(floatScale * (fltNum - integerVal)); + /* Half-adjust: round up or round down */ + if (floatVal % DECIMAL_BASE >= HALF_ADJUST_BOUNDARY) { + floatVal = floatVal / DECIMAL_BASE + 1; + } else { + floatVal = floatVal / DECIMAL_BASE; + } + unsigned int fltCnt = DBG_CountDigits(floatVal, DECIMAL); + /* Rounding to the whole part */ + if (fltCnt > precision) { + /* Decimal significant bits are subtracted by 1. */ + fltCnt -= 1; + integerVal += 1; + /* The decimal part is all 0s after the carry is carried to the integer part. */ + floatVal = 0; + } + count += DBG_SnprintfSignedNum(integerVal, destMem, destLen); /* Store Integer Part */ + if (DBG_SnprintfChar('.', destMem, destLen) == 0) { /* Stores the decimal point of a floating point number */ + return 0; + } + count++; + /* Pad 0 in float part */ + if (precision > fltCnt) { + for (unsigned int i = 0; i < precision - fltCnt; i++) { + if (DBG_SnprintfChar('0', destMem, destLen) == 0) { + return 0; /* Fill 0 when the number of decimal places is less than the number of significant digits */ + } + count++; + } + } + realCnt = DBG_SnprintfUnsignedNum(floatVal, DECIMAL, fltCnt, destMem, destLen); + realCnt += count; + return realCnt; /* Returns the actual written length. */ +} + + +/** + * @brief Parse the format specifier convert to string and write to memory of a + specified length and returns the length written. + * @param ch The format specifier. + * @param paramList The pointer of the variable parameter list. + * @param destMem point of memory address. + * @param destLen point of memory lenth. + * @retval unsigned int the real length written. + */ +static unsigned int DBG_SnprintfParseSpecifier(char** destMem, unsigned int* destLen, \ + const char ch, va_list *paramList) +{ + unsigned int countValue = 0, realCnt = 0, tmpCnt = 0, unsignedVal = 0, hexVal = 0; + char chVal = 0; + const char *strVal = NULL; + int intVal = 0; + float fltVal = 0; + switch (ch) { + case 'c': /* character type variable */ + chVal = VA_ARG(*paramList, int); /* Use type int because of byte alignment */ + if (DBG_SnprintfChar(chVal, destMem, destLen) == 0) { + return 0; + } + countValue++; + break; + case 's': /* Variable of the string type */ + strVal = VA_ARG(*paramList, const char *); + countValue += DBG_SnprintfString(strVal, destMem, destLen); + break; + case 'd': /* integer type variable */ + intVal = VA_ARG(*paramList, int); + countValue += DBG_SnprintfSignedNum(intVal, destMem, destLen); + break; + case 'u': /* unsigned integer type variable */ + unsignedVal = VA_ARG(*paramList, unsigned int); + tmpCnt = DBG_CountDigits(unsignedVal, DECIMAL); + DBG_PutUnsignedNum(unsignedVal, DECIMAL, tmpCnt); + realCnt = DBG_SnprintfUnsignedNum(unsignedVal, DECIMAL, tmpCnt, destMem, destLen); + countValue += realCnt; + break; + case 'x': + case 'X': + case 'p': /* Pointer address type variable or variable address */ + hexVal = VA_ARG(*paramList, unsigned int); + countValue += DBG_SnprintfString("0x", destMem, destLen); + countValue += DBG_SnprintfHex(hexVal, destMem, destLen); + break; + case 'f': /* Floating-point variable */ + fltVal = VA_ARG(*paramList, double); + countValue += DBG_SnprintfFlt(fltVal, 6, destMem, destLen); /* default precision: 6 */ + break; + default: + if (DBG_SnprintfChar(ch, destMem, destLen) == 0) { + return 0; + } + countValue++; + break; + } + return countValue; +} + + +/** + * @brief Convert decimal number with field width to string and write to memory of a + specified length and returns the length written. + * @param intNumber The decimal number to be printed. + * @param fieldWidth Field width. + * @param destMem point of memory address. + * @param destLen point of memory lenth. + * @retval unsigned int the real length written. + */ +static unsigned int DBG_SnprintfIntWithField(int intNumber, int fieldWidth, char** destMem, unsigned int* destLen) +{ + int zeroCnt = 0; + int digitsCnt = 0; + unsigned int realCnt = 0; + if (intNumber == 0) { + if (DBG_SnprintfChar('0', destMem, destLen) == 0) { /* If the data is 0, store 0. */ + return 0; /* When the remaining space is insufficient, 0 is returned. */ + } + return 1; + } + if (intNumber < 0) { + if (DBG_SnprintfChar('-', destMem, destLen) == 0) { /* If the data is negative, store the minus sign. */ + return 0; /* When the remaining space is insufficient, 0 is returned. */ + } + intNumber = -intNumber; + digitsCnt = DBG_CountDigits(intNumber, DECIMAL); /* get int value's width */ + zeroCnt = fieldWidth - digitsCnt; + for (int i = 0; i < zeroCnt; i++) { + if (DBG_SnprintfChar('0', destMem, destLen) == 0) { /* Fill 0 when the bit width is less than */ + return 0; /* When the remaining space is insufficient, 0 is returned. */ + } + } + } else { + digitsCnt = DBG_CountDigits(intNumber, DECIMAL); /* get int value's width */ + zeroCnt = fieldWidth - digitsCnt; + for (int i = 0; i < zeroCnt; i++) { + if (DBG_SnprintfChar('0', destMem, destLen) == 0) { /* Fill 0 when the bit width is less than */ + return 0; /* When the remaining space is insufficient, 0 is returned. */ + } + } + } + realCnt = DBG_SnprintfUnsignedNum(intNumber, DECIMAL, digitsCnt, destMem, destLen); + return realCnt; /* Returns the actual written length. */ +} + + +/** + * @brief Convert format string write to memory of a specified length, supporting %c, %s, %d, %u, %x, %X, %p, %f. + * %c To print a character. + * %s To print a string. + * %d To print a decimal value. + * %u To print an unsigned decimal value. + * %x, %X To print a hexadecimal value using upper case letters. + * %p To print a pointer as a hexadecimal value. + * %f To print a floating-point number with a fixed precision determined by FLOAT_PRECISION. + * @param format A string that contains the text to be printed and the format specifiers. + * @param ... Variable parameter list. + * @param destMem point of memory address. + * @param destLen point of memory lenth. + * @retval int the real length written. + */ +int DBG_Snprintf(char* destMem, unsigned int destLen, const char *format, ...) +{ + DEBUG_ASSERT_PARAM(destMem != NULL); + DEBUG_ASSERT_PARAM(format != NULL); + char* pDestMem = NULL; + pDestMem = destMem; /* Memory Pointer Index */ + unsigned int destMemLenth = destLen; /* Remaining space of the destination memory */ + int cntVal = 0; + int fieldWidth = 0; + int floatPrecision = 0; + float fltVal = 0; + int intVal = 0; + va_list paramList; + VA_START(paramList, format); /* The variable initialization points to the first parameter. */ + while (*format != '\0') { + if (*format != '%') { + if (DBG_SnprintfChar(*format, &pDestMem, &destMemLenth) == 0) { + return 0; + } + cntVal++; + } else { + format++; + if (*format == '0') { + format++; + fieldWidth = DBG_Atoi(&format); /* Character to Number */ + intVal = VA_ARG(paramList, int); + cntVal += DBG_SnprintfIntWithField(intVal, fieldWidth, &pDestMem, &destMemLenth); + } else if (*format == '.') { + format++; + floatPrecision = DBG_Atoi(&format); /* Character to Number */ + fltVal = VA_ARG(paramList, double); + cntVal += DBG_SnprintfFlt(fltVal, floatPrecision, &pDestMem, &destMemLenth); + } else { /* escape character parsing */ + cntVal += DBG_SnprintfParseSpecifier(&pDestMem, &destMemLenth, *format, ¶mList); + } + } + format++; + } + VA_END(paramList); + return cntVal; +} + #endif \ No newline at end of file diff --git a/src/drivers/dma/common/inc/dma.h b/src/drivers/dma/common/inc/dma.h index acd7381b38059bb360c7643c23926bcd8389479f..5f1b70dde8d2ea3cb48c59a1c93ab2d69ed07863 100644 --- a/src/drivers/dma/common/inc/dma.h +++ b/src/drivers/dma/common/inc/dma.h @@ -97,9 +97,10 @@ typedef void (* DMA_CallbackType)(void *handle); /** * @defgroup DMA_API_Declaration DMA HAL API + * @brief Hardware abstraction layer. * @{ */ -/* Hardware abstraction layer */ + BASE_StatusType HAL_DMA_Init(DMA_Handle *dmaHandle); BASE_StatusType HAL_DMA_Deinit(DMA_Handle *dmaHandle); BASE_StatusType HAL_DMA_Start(DMA_Handle *dmaHandle, unsigned int srcAddr, diff --git a/src/drivers/dma/dma_v0/src/dma.c b/src/drivers/dma/dma_v0/src/dma.c index 54f79763cc37dabc4629f3d360a7e57ffaebc4fa..57850b621d4f3cf65521b0b044608affc85f45b1 100644 --- a/src/drivers/dma/dma_v0/src/dma.c +++ b/src/drivers/dma/dma_v0/src/dma.c @@ -416,9 +416,11 @@ BASE_StatusType HAL_DMA_Start(DMA_Handle *dmaHandle, unsigned int srcAddr, dmaHandle->DMA_Channels[channel].channelAddr->DMAC_Cn_CONFIG.reg &= ~(0x0000C000); dmaHandle->DMA_Channels[channel].channelAddr->DMAC_Cn_CONFIG.BIT.ch_en = BASE_CFG_ENABLE; #ifdef BASE_DEFINE_DMA_QUICKSTART - dmaHandle->DMA_Channels[channel].srcAddr = dmaHandle->DMA_Channels[channel].channelAddr->DMAC_Cn_SRC_ADDR.reg; - dmaHandle->DMA_Channels[channel].destAddr = dmaHandle->DMA_Channels[channel].channelAddr->DMAC_Cn_DEST_ADDR.reg; - dmaHandle->DMA_Channels[channel].controlVal = dmaHandle->DMA_Channels[channel].channelAddr->DMAC_Cn_CONTROL.reg; + dmaHandle->DMA_Channels[channel].srcAddr = srcAddr; + dmaHandle->DMA_Channels[channel].destAddr = destAddr; + unsigned int val = DMA_CalControlval(dmaHandle, channel); + val |= dataLength; + dmaHandle->DMA_Channels[channel].controlVal = val; dmaHandle->DMA_Channels[channel].configVal = dmaHandle->DMA_Channels[channel].channelAddr->DMAC_Cn_CONFIG.reg; #endif return BASE_STATUS_OK; @@ -447,9 +449,11 @@ BASE_StatusType HAL_DMA_StartIT(DMA_Handle *dmaHandle, unsigned int srcAddr, /* Set tc_int_msk, err_int_msk, ch_en */ dmaHandle->DMA_Channels[channel].channelAddr->DMAC_Cn_CONFIG.reg |= 0xC001; #ifdef BASE_DEFINE_DMA_QUICKSTART - dmaHandle->DMA_Channels[channel].srcAddr = dmaHandle->DMA_Channels[channel].channelAddr->DMAC_Cn_SRC_ADDR.reg; - dmaHandle->DMA_Channels[channel].destAddr = dmaHandle->DMA_Channels[channel].channelAddr->DMAC_Cn_DEST_ADDR.reg; - dmaHandle->DMA_Channels[channel].controlVal = dmaHandle->DMA_Channels[channel].channelAddr->DMAC_Cn_CONTROL.reg; + dmaHandle->DMA_Channels[channel].srcAddr = srcAddr; + dmaHandle->DMA_Channels[channel].destAddr = destAddr; + unsigned int val = DMA_CalControlval(dmaHandle, channel); + val |= dataLength; + dmaHandle->DMA_Channels[channel].controlVal = val; dmaHandle->DMA_Channels[channel].configVal = dmaHandle->DMA_Channels[channel].channelAddr->DMAC_Cn_CONFIG.reg; #endif return BASE_STATUS_OK; diff --git a/src/drivers/dma/dma_v1/inc/dma_ip.h b/src/drivers/dma/dma_v1/inc/dma_ip.h index 156b280f51c84d94ea6415b5cd2c433bd8615005..959573b8e4e97d6a004d5d6baa5239beaaf76bf5 100644 --- a/src/drivers/dma/dma_v1/inc/dma_ip.h +++ b/src/drivers/dma/dma_v1/inc/dma_ip.h @@ -118,75 +118,83 @@ typedef enum { /** * @brief DMA request peripheral. The multiplexed transmitter requires additional * configuration of the system register. - * @details DMA request line type: - * + DMA_REQUEST_I2C0_RX -- I2C0_RX use the request line numbered 0 - * + DMA_REQUEST_I2C0_TX -- I2C0_TX use the request line numbered 1 - * + DMA_REQUEST_I2C1_RX -- I2C1_RX use the request line numbered 2 - * + DMA_REQUEST_I2C1_TX -- I2C1_RX use the request line numbered 3 - * + DMA_REQUEST_UART0_RX -- UART0_TX use the request line numbered 4 - * + DMA_REQUEST_UART0_TX -- UART0_TX use the request line numbered 5 - * + DMA_REQUEST_UART1_RX -- UART1_RX use the request line numbered 6 - * + DMA_REQUEST_UART1_TX -- UART1_TX use the request line numbered 7 - * + DMA_REQUEST_UART2_RX -- UART2_RX use the request line numbered 8 - * + DMA_REQUEST_UART2_TX -- UART2_TX use the request line numbered 9 - * + DMA_REQUEST_UART3_RX -- UART3_RX use the request line numbered 30 - * + DMA_REQUEST_UART3_TX -- UART3_TX use the request line numbered 31 - * + DMA_REQUEST_CAPM0 -- CAPM0 use the request line numbered 10 - * + DMA_REQUEST_CAPM1 -- CAPM1 use the request line numbered 11 - * + DMA_REQUEST_CAPM2 -- CAPM2 use the request line numbered 12 - * + DMA_REQUEST_ADC0 -- ADC0 use the request line numbered 13 - * + DMA_REQUEST_TIMER0 -- TIMER0 use the request line numbered 14 - * + DMA_REQUEST_TIMER1 -- TIMER1 use the request line numbered 15 - * + DMA_REQUEST_TIMER2 -- TIMER2 use the request line numbered 16 - * + DMA_REQUEST_TIMER3 -- TIMER3 use the request line numbered 17 - * + DMA_REQUEST_SPI0_RX -- SPI0_RX ause the request line numbered 18 - * + DMA_REQUEST_SPI0_TX -- SPI0_TX use the request line numbered 19 - * + DMA_REQUEST_SPI1_RX -- SPI1_RX use the request line numbered 20 - * + DMA_REQUEST_SPI1_TX -- SPI1_TX use the request line numbered 21 - * + DMA_REQUEST_APT0 -- APT0 use the request line numbered 22 - * + DMA_REQUEST_APT1 -- APT1 use the request line numbered 23 - * + DMA_REQUEST_APT2 -- APT2 use the request line numbered 24 - * + DMA_REQUEST_APT3 -- APT3 use the request line numbered 25 - * + DMA_REQUEST_GPT0 -- GPT0 use the request line numbered 26 - * + DMA_REQUEST_GPT1 -- GPT1 use the request line numbered 27 - * + DMA_REQUEST_GPT2 -- GPT2 use the request line numbered 28 - * + DMA_REQUEST_GPT3 -- GPT3 use the request line numbered 29 - * + DMA_REQUEST_MEM -- The source and destination devices are memory */ typedef enum { - DMA_REQUEST_I2C0_RX = 0x00000000U, - DMA_REQUEST_I2C0_TX = 0x00000001U, - DMA_REQUEST_I2C1_RX = 0x00000002U, - DMA_REQUEST_I2C1_TX = 0x00000003U, - DMA_REQUEST_UART0_RX = 0x00000004U, - DMA_REQUEST_UART0_TX = 0x00000005U, - DMA_REQUEST_UART1_RX = 0x00000006U, - DMA_REQUEST_UART1_TX = 0x00000007U, - DMA_REQUEST_UART2_RX = 0x00000008U, - DMA_REQUEST_UART2_TX = 0x00000009U, - DMA_REQUEST_UART3_RX = 0x0000001EU, - DMA_REQUEST_UART3_TX = 0x0000001FU, - DMA_REQUEST_CAPM0 = 0x0000000AU, - DMA_REQUEST_CAPM1 = 0x0000000BU, - DMA_REQUEST_CAPM2 = 0x0000000CU, - DMA_REQUEST_ADC0 = 0x0000000DU, - DMA_REQUEST_TIMER0 = 0x0000000EU, - DMA_REQUEST_TIMER1 = 0x0000000FU, - DMA_REQUEST_TIMER2 = 0x00000010U, - DMA_REQUEST_TIMER3 = 0x00000011U, - DMA_REQUEST_SPI0_RX = 0x00000012U, - DMA_REQUEST_SPI0_TX = 0x00000013U, - DMA_REQUEST_SPI1_RX = 0x00000014U, - DMA_REQUEST_SPI1_TX = 0x00000015U, - DMA_REQUEST_APT0 = 0x00000016U, - DMA_REQUEST_APT1 = 0x00000017U, - DMA_REQUEST_APT2 = 0x00000018U, - DMA_REQUEST_APT3 = 0x00000019U, - DMA_REQUEST_GPT0 = 0x0000001AU, - DMA_REQUEST_GPT1 = 0x0000001BU, - DMA_REQUEST_GPT2 = 0x0000001CU, - DMA_REQUEST_GPT3 = 0x0000001DU, - DMA_REQUEST_MEM = 0x00000020U, +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + DMA_REQUEST_I2C0_RX = 0x00000000U, /* I2C0_RX use the request line numbered 0 */ + DMA_REQUEST_I2C0_TX = 0x00000001U, /* I2C0_TX use the request line numbered 1 */ + DMA_REQUEST_UART0_RX = 0x00000002U, /* UART0_TX use the request line numbered 2 */ + DMA_REQUEST_UART0_TX = 0x00000003U, /* UART0_TX use the request line numbered 3 */ + DMA_REQUEST_UART1_RX = 0x00000004U, /* UART1_RX use the request line numbered 4 */ + DMA_REQUEST_UART1_TX = 0x00000005U, /* UART1_TX use the request line numbered 5 */ + DMA_REQUEST_UART2_RX = 0x00000006U, /* UART2_RX use the request line numbered 6 */ + DMA_REQUEST_UART2_TX = 0x00000007U, /* UART2_TX use the request line numbered 7 */ + DMA_REQUEST_UART3_RX = 0x00000008U, /* UART3_RX use the request line numbered 8 */ + DMA_REQUEST_UART3_TX = 0x00000009U, /* UART3_TX use the request line numbered 9 */ + DMA_REQUEST_UART4_RX = 0x0000000AU, /* UART3_RX use the request line numbered 10 */ + DMA_REQUEST_UART4_TX = 0x0000000BU, /* UART3_TX use the request line numbered 11 */ + DMA_REQUEST_SPI0_RX = 0x00000008U, /* SPI0_RX ause the request line numbered 8 */ + DMA_REQUEST_SPI0_TX = 0x00000009U, /* SPI0_TX use the request line numbered 9 */ + DMA_REQUEST_SPI1_RX = 0x0000000AU, /* SPI1_RX use the request line numbered 10 */ + DMA_REQUEST_SPI1_TX = 0x0000000BU, /* SPI1_TX use the request line numbered 11 */ + DMA_REQUEST_CAPM0 = 0x0000000CU, /* CAPM0 use the request line numbered 12 */ + DMA_REQUEST_CAPM1 = 0x0000000DU, /* CAPM1 use the request line numbered 13 */ + DMA_REQUEST_CAPM2 = 0x0000000EU, /* CAPM2 use the request line numbered 14 */ + DMA_REQUEST_TIMER0 = 0x0000000FU, /* TIMER0 use the request line numbered 15 */ + DMA_REQUEST_TIMER1 = 0x00000010U, /* TIMER1 use the request line numbered 16 */ + DMA_REQUEST_TIMER2 = 0x00000011U, /* TIMER2 use the request line numbered 17 */ + DMA_REQUEST_TIMER3 = 0x00000012U, /* TIMER3 use the request line numbered 18 */ + DMA_REQUEST_GPT0 = 0x00000013U, /* GPT0 use the request line numbered 19 */ + DMA_REQUEST_GPT1 = 0x00000014U, /* GPT1 use the request line numbered 20 */ + DMA_REQUEST_APT0 = 0x00000015U, /* APT0 use the request line numbered 21 */ + DMA_REQUEST_APT1 = 0x00000016U, /* APT1 use the request line numbered 22 */ + DMA_REQUEST_APT2 = 0x00000017U, /* APT2 use the request line numbered 23 */ + DMA_REQUEST_APT3 = 0x00000018U, /* APT3 use the request line numbered 24 */ + DMA_REQUEST_APT4 = 0x00000019U, /* APT4 use the request line numbered 25 */ + DMA_REQUEST_APT5 = 0x0000001AU, /* APT5 use the request line numbered 26 */ + DMA_REQUEST_APT6 = 0x0000001BU, /* APT6 use the request line numbered 27 */ + DMA_REQUEST_APT7 = 0x0000001CU, /* APT7 use the request line numbered 28 */ + DMA_REQUEST_APT8 = 0x0000001DU, /* APT8 use the request line numbered 29 */ + DMA_REQUEST_ADC0 = 0x0000001EU, /* ADC0 use the request line numbered 30 */ + DMA_REQUEST_ADC1 = 0x0000001FU, /* ADC1 use the request line numbered 31 */ + DMA_REQUEST_ADC2 = 0x0000000CU, /* ADC2 use the request line numbered 12 */ + DMA_REQUEST_MEM = 0x00000020U, /* The source and destination devices are memory */ +#else + DMA_REQUEST_I2C0_RX = 0x00000000U, /* I2C0_RX use the request line numbered 0 */ + DMA_REQUEST_I2C0_TX = 0x00000001U, /* I2C0_TX use the request line numbered 1 */ + DMA_REQUEST_I2C1_RX = 0x00000002U, /* I2C1_RX use the request line numbered 2 */ + DMA_REQUEST_I2C1_TX = 0x00000003U, /* I2C1_RX use the request line numbered 3 */ + DMA_REQUEST_UART0_RX = 0x00000004U, /* UART0_TX use the request line numbered 4 */ + DMA_REQUEST_UART0_TX = 0x00000005U, /* UART0_TX use the request line numbered 5 */ + DMA_REQUEST_UART1_RX = 0x00000006U, /* UART1_RX use the request line numbered 6 */ + DMA_REQUEST_UART1_TX = 0x00000007U, /* UART1_TX use the request line numbered 7 */ + DMA_REQUEST_UART2_RX = 0x00000008U, /* UART2_RX use the request line numbered 8 */ + DMA_REQUEST_UART2_TX = 0x00000009U, /* UART2_TX use the request line numbered 9 */ + DMA_REQUEST_UART3_RX = 0x0000001EU, /* UART3_RX use the request line numbered 30 */ + DMA_REQUEST_UART3_TX = 0x0000001FU, /* UART3_TX use the request line numbered 31 */ + DMA_REQUEST_CAPM0 = 0x0000000AU, /* CAPM0 use the request line numbered 10 */ + DMA_REQUEST_CAPM1 = 0x0000000BU, /* CAPM1 use the request line numbered 11 */ + DMA_REQUEST_CAPM2 = 0x0000000CU, /* CAPM2 use the request line numbered 12 */ + DMA_REQUEST_ADC0 = 0x0000000DU, /* ADC0 use the request line numbered 13 */ + DMA_REQUEST_TIMER0 = 0x0000000EU, /* TIMER0 use the request line numbered 14 */ + DMA_REQUEST_TIMER1 = 0x0000000FU, /* TIMER1 use the request line numbered 15 */ + DMA_REQUEST_TIMER2 = 0x00000010U, /* TIMER2 use the request line numbered 16 */ + DMA_REQUEST_TIMER3 = 0x00000011U, /* TIMER3 use the request line numbered 17 */ + DMA_REQUEST_SPI0_RX = 0x00000012U, /* SPI0_RX ause the request line numbered 18 */ + DMA_REQUEST_SPI0_TX = 0x00000013U, /* SPI0_TX use the request line numbered 19 */ + DMA_REQUEST_SPI1_RX = 0x00000014U, /* SPI1_RX use the request line numbered 20 */ + DMA_REQUEST_SPI1_TX = 0x00000015U, /* SPI1_TX use the request line numbered 21 */ + DMA_REQUEST_APT0 = 0x00000016U, /* APT0 use the request line numbered 22 */ + DMA_REQUEST_APT1 = 0x00000017U, /* APT1 use the request line numbered 23 */ + DMA_REQUEST_APT2 = 0x00000018U, /* APT2 use the request line numbered 24 */ + DMA_REQUEST_APT3 = 0x00000019U, /* APT3 use the request line numbered 25 */ + DMA_REQUEST_GPT0 = 0x0000001AU, /* GPT0 use the request line numbered 26 */ + DMA_REQUEST_GPT1 = 0x0000001BU, /* GPT1 use the request line numbered 27 */ + DMA_REQUEST_GPT2 = 0x0000001CU, /* GPT2 use the request line numbered 28 */ + DMA_REQUEST_GPT3 = 0x0000001DU, /* GPT3 use the request line numbered 29 */ + DMA_REQUEST_MEM = 0x00000020U, /* The source and destination devices are memory */ +#endif } DMA_RequestLineNum; /** diff --git a/src/drivers/dma/dma_v1/src/dma.c b/src/drivers/dma/dma_v1/src/dma.c index 860a9ad72cf80c38b91c26fbae21a5145b355b70..3cf8c4db47758524afcf31a360f652068c48b80a 100644 --- a/src/drivers/dma/dma_v1/src/dma.c +++ b/src/drivers/dma/dma_v1/src/dma.c @@ -150,6 +150,41 @@ BASE_StatusType HAL_DMA_InitChannel(DMA_Handle *dmaHandle, DMA_ChannelParam *cha return BASE_STATUS_OK; } +/** + * @brief Selecting the DMA request. + * @param dmaHandle DMA handle. + * @param periphNum Peripheral request ID. + * @param channel ID of the selected DMA channel @ref DMA_ChannelNum. + * @retval None. + */ +static void DMA_ReqSelect(DMA_Handle *dmaHandle, unsigned int periphNum, unsigned int channel) +{ +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + DMA_Handle *pHandle = dmaHandle->DMA_Channels[channel].pHandle; + unsigned int reqSelVal = 0; + /* Obtains the address of the peripheral that invokes the DMA. */ + unsigned int *baseAddress = (unsigned int *)pHandle->baseAddress; + + /* Obtains the configuration value of the request line source register based on the peripheral type. */ + if (baseAddress == UART3_BASE || baseAddress == UART4_BASE || baseAddress == ADC2_BASE) { + reqSelVal = 1; + } + /* Configuration request line source switching register。 */ + if (periphNum >= DMA_REQUEST_SPI0_RX && periphNum <= DMA_REQUEST_CAPM0) { + if (reqSelVal & BASE_CFG_SET) { + SYSCTRL1->DMA_REQ_SEL.reg |= 1 << periphNum; + } else { + SYSCTRL1->DMA_REQ_SEL.reg &= ~(1 << periphNum); + } + } +#else + BASE_FUNC_UNUSED(dmaHandle); + BASE_FUNC_UNUSED(periphNum); + BASE_FUNC_UNUSED(channel); +#endif +} + /** * @brief Configuring the DMA source device. * @param dmaHandle DMA handle. @@ -163,6 +198,7 @@ static void DMA_SetSrcPeriph(DMA_Handle *dmaHandle, unsigned int channel) return; } dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_CONFIG.BIT.src_periph = periphNum; + DMA_ReqSelect(dmaHandle, periphNum, channel); } /** @@ -178,6 +214,7 @@ static void DMA_SetDestPeriph(DMA_Handle *dmaHandle, unsigned int channel) return; } dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_CONFIG.BIT.dest_periph = periphNum; + DMA_ReqSelect(dmaHandle, periphNum, channel); } /** @@ -371,9 +408,11 @@ BASE_StatusType HAL_DMA_Start(DMA_Handle *dmaHandle, unsigned int srcAddr, dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_CONFIG.reg &= ~(0x0000C000); dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_CONFIG.BIT.ch_en = BASE_CFG_ENABLE; #ifdef BASE_DEFINE_DMA_QUICKSTART - dmaHandle->DMA_Channels[channel].srcAddr = dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_SRC_ADDR.reg; - dmaHandle->DMA_Channels[channel].destAddr = dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_DEST_ADDR.reg; - dmaHandle->DMA_Channels[channel].controlVal = dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_CONTROL.reg; + dmaHandle->DMA_Channels[channel].srcAddr = srcAddr; + dmaHandle->DMA_Channels[channel].destAddr = destAddr; + unsigned int val = DMA_CalControlval(dmaHandle, channel); + val |= dataLength; + dmaHandle->DMA_Channels[channel].controlVal = val; dmaHandle->DMA_Channels[channel].configVal = dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_CONFIG.reg; #endif return BASE_STATUS_OK; @@ -402,9 +441,11 @@ BASE_StatusType HAL_DMA_StartIT(DMA_Handle *dmaHandle, unsigned int srcAddr, /* Set tc_int_msk, err_int_msk, ch_en */ dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_CONFIG.reg |= 0xC001; #ifdef BASE_DEFINE_DMA_QUICKSTART - dmaHandle->DMA_Channels[channel].srcAddr = dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_SRC_ADDR.reg; - dmaHandle->DMA_Channels[channel].destAddr = dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_DEST_ADDR.reg; - dmaHandle->DMA_Channels[channel].controlVal = dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_CONTROL.reg; + dmaHandle->DMA_Channels[channel].srcAddr = srcAddr; + dmaHandle->DMA_Channels[channel].destAddr = destAddr; + unsigned int val = DMA_CalControlval(dmaHandle, channel); + val |= dataLength; + dmaHandle->DMA_Channels[channel].controlVal = val; dmaHandle->DMA_Channels[channel].configVal = dmaHandle->DMA_Channels[channel].channelAddr->DMA_Cn_CONFIG.reg; #endif return BASE_STATUS_OK; diff --git a/src/drivers/flash/flash_v1/inc/flash_ip.h b/src/drivers/flash/flash_v1/inc/flash_ip.h index 1492bacf6075e829910ff5838cad824518812d4a..a7f1f34bd983b0fcd3eaefaa6877b6aad08b7092 100644 --- a/src/drivers/flash/flash_v1/inc/flash_ip.h +++ b/src/drivers/flash/flash_v1/inc/flash_ip.h @@ -81,8 +81,9 @@ #define FLASH_SRAM_END_ADDRESS 0x04007FFF #define FLASH_MAIN_RNG_START_ADDRESS 0x03000000 -/* Only CHIP_3061MNPICA, CHIP_3061MNPIKA is supported 128K. */ -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) +/* Only this chips are supported 128K. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || \ + defined (CHIP_3061MNNIKA) #define FLASH_MAIN_RNG_END_ADDRESS 0x0301FFFF #define FLASH_MAX_SIZE 0x20000U /* Flash space size 128k bytes. */ #define FLASH_MAX_PAGE_NUM 128 @@ -182,8 +183,8 @@ typedef enum { FLASH_PAGE_61 = FLASH_BASE + 61 * FLASH_ONE_PAGE_SIZE, FLASH_PAGE_62 = FLASH_BASE + 62 * FLASH_ONE_PAGE_SIZE, FLASH_PAGE_63 = FLASH_BASE + 63 * FLASH_ONE_PAGE_SIZE, - /* Only CHIP_3061MNPICA, CHIP_3061MNPIKA is supported 128K. */ -#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) + /* Only this chips are supported 128K. */ +#if defined (CHIP_3061MNPICA) || defined (CHIP_3061MNPIKA) || defined (CHIP_3061MNNICA) || defined (CHIP_3061MNNIKA) FLASH_PAGE_64 = FLASH_BASE + 64 * FLASH_ONE_PAGE_SIZE, FLASH_PAGE_65 = FLASH_BASE + 65 * FLASH_ONE_PAGE_SIZE, FLASH_PAGE_66 = FLASH_BASE + 66 * FLASH_ONE_PAGE_SIZE, diff --git a/src/drivers/flash/flash_v3/inc/flash_ip.h b/src/drivers/flash/flash_v3/inc/flash_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..2404262d6676c96b835dc59f1fc0195be3862a50 --- /dev/null +++ b/src/drivers/flash/flash_v3/inc/flash_ip.h @@ -0,0 +1,1575 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flash_ip.h + * @author MCU Driver Team + * @brief FLASH module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the FLASH. + * + Register definition structure + * + Basic parameter configuration macro + */ + +/* Define to prevent recursive inclusion ----------------------------------------*/ +#ifndef McuMagicTag_FLASH_IP_H +#define McuMagicTag_FLASH_IP_H + +/* Includes ---------------------------------------------------------------------*/ +#include "baseinc.h" + +/* Macro definitions -----------------------------------------------------------*/ +#ifdef FLASH_PARAM_CHECK +#define FLASH_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM +#define FLASH_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET +#define FLASH_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else +#define FLASH_ASSERT_PARAM(para) ((void)0U) +#define FLASH_PARAM_CHECK_NO_RET(para) ((void)0U) +#define FLASH_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) +#endif + +/** + * @addtogroup FLASH + * @{ + */ + +/** + * @defgroup FLASH_IP FLASH_IP + * @brief FLASH_IP: flash_v3 + * @{ + */ + +#define FLASH_BASE 0x0U /* Flash PE operation base address. */ +#define FLASH_READ_BASE 0x3000000U /* Base address for the flash read operation. */ +#define FLASH_ONE_PAGE_SIZE 0x400U /* Size of a page, unit: bytes. 1K. */ +#define FLASH_ONE_PAGE_WORD_SIZE 0x100U /* Size of a page, unit: word. 1K. */ +#define FLASH_MAX_SIZE 0x80000U /* Flash space size 512k bytes. */ + +#define FLASH_KEY_REGISTER_UNLOCK_VALUE 0xFEDCBA98 +#define FLASH_KEY_REGISTER_LOCK_VALUE 0x0 + +#define FLASH_MAX_PGM_BYTE_SIZE 0x100 +#define FLASH_MAX_PGM_WORD_SIZE 0x40 +#define FLASH_MIN_PGM_BYTES_SIZE 0x10 +#define FLASH_MIN_PGM_WORDS_SIZE 4 +#define FLASH_PGM_WORDS_LEGAL_DIVISOR 4 +#define FLASH_ONE_WORD_BYTES_SIZE 4 +#define FLASH_MAX_PAGE_NUM 512 + +#define FLASH_PGM_WBUF_CNT_POS 8 +#define FLASH_PGM_WBUF_CNT_MASK (0xFF << FLASH_PGM_WBUF_CNT_POS) + +#define FLASH_MAX_CMD_PROGRAM_SIZE 0x10 /* The value is cmd program size, unit: 32bits. */ + +#define FLASH_SRAM_START_ADDRESS 0x02000000 +#define FLASH_SRAM_END_ADDRESS 0x02010000 +#define FLASH_MAIN_RNG_START_ADDRESS 0x03000000 +#define FLASH_MAIN_RNG_END_ADDRESS 0x0307FFFF + +/** + * @defgroup FLASH_Param_Def FLASH Parameters Definition + * @brief Definition of FLASH configuration parameters. + * @{ + */ +/* Typedef definitions --------------------------------------------------------*/ +/** + * @brief PE Operation Mode Enumeration Definition. + */ +typedef enum { + FLASH_PE_OP_BLOCK = 0x00000000U, + FLASH_PE_OP_IT = 0x00000001U +} FLASH_PE_OpMode; + +/** + * @brief Erase operation type enumeration definition. + */ +typedef enum { + FLASH_ERASE_MODE_PAGE = 0x00000004U, + FLASH_ERASE_MODE_CHIP = 0x00000006U +} FLASH_EraseMode; + +/** + * @brief Flash page address enumeration. + */ +typedef enum { + FLASH_PAGE_0 = FLASH_BASE, + FLASH_PAGE_1 = FLASH_BASE + FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_2 = FLASH_BASE + 2 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_3 = FLASH_BASE + 3 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_4 = FLASH_BASE + 4 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_5 = FLASH_BASE + 5 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_6 = FLASH_BASE + 6 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_7 = FLASH_BASE + 7 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_8 = FLASH_BASE + 8 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_9 = FLASH_BASE + 9 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_10 = FLASH_BASE + 10 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_11 = FLASH_BASE + 11 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_12 = FLASH_BASE + 12 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_13 = FLASH_BASE + 13 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_14 = FLASH_BASE + 14 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_15 = FLASH_BASE + 15 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_16 = FLASH_BASE + 16 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_17 = FLASH_BASE + 17 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_18 = FLASH_BASE + 18 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_19 = FLASH_BASE + 19 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_20 = FLASH_BASE + 20 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_21 = FLASH_BASE + 21 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_22 = FLASH_BASE + 22 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_23 = FLASH_BASE + 23 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_24 = FLASH_BASE + 24 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_25 = FLASH_BASE + 25 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_26 = FLASH_BASE + 26 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_27 = FLASH_BASE + 27 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_28 = FLASH_BASE + 28 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_29 = FLASH_BASE + 29 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_30 = FLASH_BASE + 30 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_31 = FLASH_BASE + 31 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_32 = FLASH_BASE + 32 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_33 = FLASH_BASE + 33 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_34 = FLASH_BASE + 34 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_35 = FLASH_BASE + 35 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_36 = FLASH_BASE + 36 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_37 = FLASH_BASE + 37 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_38 = FLASH_BASE + 38 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_39 = FLASH_BASE + 39 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_40 = FLASH_BASE + 40 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_41 = FLASH_BASE + 41 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_42 = FLASH_BASE + 42 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_43 = FLASH_BASE + 43 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_44 = FLASH_BASE + 44 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_45 = FLASH_BASE + 45 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_46 = FLASH_BASE + 46 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_47 = FLASH_BASE + 47 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_48 = FLASH_BASE + 48 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_49 = FLASH_BASE + 49 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_50 = FLASH_BASE + 50 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_51 = FLASH_BASE + 51 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_52 = FLASH_BASE + 52 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_53 = FLASH_BASE + 53 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_54 = FLASH_BASE + 54 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_55 = FLASH_BASE + 55 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_56 = FLASH_BASE + 56 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_57 = FLASH_BASE + 57 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_58 = FLASH_BASE + 58 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_59 = FLASH_BASE + 59 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_60 = FLASH_BASE + 60 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_61 = FLASH_BASE + 61 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_62 = FLASH_BASE + 62 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_63 = FLASH_BASE + 63 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_64 = FLASH_BASE + 64 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_65 = FLASH_BASE + 65 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_66 = FLASH_BASE + 66 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_67 = FLASH_BASE + 67 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_68 = FLASH_BASE + 68 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_69 = FLASH_BASE + 69 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_70 = FLASH_BASE + 70 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_71 = FLASH_BASE + 71 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_72 = FLASH_BASE + 72 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_73 = FLASH_BASE + 73 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_74 = FLASH_BASE + 74 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_75 = FLASH_BASE + 75 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_76 = FLASH_BASE + 76 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_77 = FLASH_BASE + 77 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_78 = FLASH_BASE + 78 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_79 = FLASH_BASE + 79 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_80 = FLASH_BASE + 80 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_81 = FLASH_BASE + 81 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_82 = FLASH_BASE + 82 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_83 = FLASH_BASE + 83 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_84 = FLASH_BASE + 84 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_85 = FLASH_BASE + 85 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_86 = FLASH_BASE + 86 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_87 = FLASH_BASE + 87 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_88 = FLASH_BASE + 88 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_89 = FLASH_BASE + 89 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_90 = FLASH_BASE + 90 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_91 = FLASH_BASE + 91 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_92 = FLASH_BASE + 92 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_93 = FLASH_BASE + 93 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_94 = FLASH_BASE + 94 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_95 = FLASH_BASE + 95 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_96 = FLASH_BASE + 96 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_97 = FLASH_BASE + 97 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_98 = FLASH_BASE + 98 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_99 = FLASH_BASE + 99 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_100 = FLASH_BASE + 100 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_101 = FLASH_BASE + 101 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_102 = FLASH_BASE + 102 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_103 = FLASH_BASE + 103 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_104 = FLASH_BASE + 104 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_105 = FLASH_BASE + 105 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_106 = FLASH_BASE + 106 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_107 = FLASH_BASE + 107 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_108 = FLASH_BASE + 108 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_109 = FLASH_BASE + 109 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_110 = FLASH_BASE + 110 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_111 = FLASH_BASE + 111 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_112 = FLASH_BASE + 112 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_113 = FLASH_BASE + 113 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_114 = FLASH_BASE + 114 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_115 = FLASH_BASE + 115 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_116 = FLASH_BASE + 116 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_117 = FLASH_BASE + 117 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_118 = FLASH_BASE + 118 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_119 = FLASH_BASE + 119 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_120 = FLASH_BASE + 120 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_121 = FLASH_BASE + 121 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_122 = FLASH_BASE + 122 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_123 = FLASH_BASE + 123 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_124 = FLASH_BASE + 124 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_125 = FLASH_BASE + 125 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_126 = FLASH_BASE + 126 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_127 = FLASH_BASE + 127 * FLASH_ONE_PAGE_SIZE, + + /* Only this chips are supported 256K. */ +#if defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIMH) || defined (CHIP_3065PNPIRH) || defined (CHIP_3065PNPIRE) + FLASH_PAGE_128 = FLASH_BASE + 128 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_129 = FLASH_BASE + 129 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_130 = FLASH_BASE + 130 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_131 = FLASH_BASE + 131 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_132 = FLASH_BASE + 132 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_133 = FLASH_BASE + 133 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_134 = FLASH_BASE + 134 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_135 = FLASH_BASE + 135 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_136 = FLASH_BASE + 136 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_137 = FLASH_BASE + 137 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_138 = FLASH_BASE + 138 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_139 = FLASH_BASE + 139 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_140 = FLASH_BASE + 140 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_141 = FLASH_BASE + 141 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_142 = FLASH_BASE + 142 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_143 = FLASH_BASE + 143 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_144 = FLASH_BASE + 144 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_145 = FLASH_BASE + 145 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_146 = FLASH_BASE + 146 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_147 = FLASH_BASE + 147 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_148 = FLASH_BASE + 148 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_149 = FLASH_BASE + 149 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_150 = FLASH_BASE + 150 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_151 = FLASH_BASE + 151 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_152 = FLASH_BASE + 152 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_153 = FLASH_BASE + 153 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_154 = FLASH_BASE + 154 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_155 = FLASH_BASE + 155 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_156 = FLASH_BASE + 156 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_157 = FLASH_BASE + 157 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_158 = FLASH_BASE + 158 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_159 = FLASH_BASE + 159 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_160 = FLASH_BASE + 160 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_161 = FLASH_BASE + 161 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_162 = FLASH_BASE + 162 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_163 = FLASH_BASE + 163 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_164 = FLASH_BASE + 164 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_165 = FLASH_BASE + 165 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_166 = FLASH_BASE + 166 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_167 = FLASH_BASE + 167 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_168 = FLASH_BASE + 168 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_169 = FLASH_BASE + 169 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_170 = FLASH_BASE + 170 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_171 = FLASH_BASE + 171 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_172 = FLASH_BASE + 172 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_173 = FLASH_BASE + 173 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_174 = FLASH_BASE + 174 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_175 = FLASH_BASE + 175 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_176 = FLASH_BASE + 176 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_177 = FLASH_BASE + 177 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_178 = FLASH_BASE + 178 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_179 = FLASH_BASE + 179 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_180 = FLASH_BASE + 180 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_181 = FLASH_BASE + 181 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_182 = FLASH_BASE + 182 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_183 = FLASH_BASE + 183 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_184 = FLASH_BASE + 184 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_185 = FLASH_BASE + 185 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_186 = FLASH_BASE + 186 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_187 = FLASH_BASE + 187 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_188 = FLASH_BASE + 188 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_189 = FLASH_BASE + 189 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_190 = FLASH_BASE + 190 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_191 = FLASH_BASE + 191 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_192 = FLASH_BASE + 192 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_193 = FLASH_BASE + 193 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_194 = FLASH_BASE + 194 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_195 = FLASH_BASE + 195 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_196 = FLASH_BASE + 196 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_197 = FLASH_BASE + 197 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_198 = FLASH_BASE + 198 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_199 = FLASH_BASE + 199 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_200 = FLASH_BASE + 200 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_201 = FLASH_BASE + 201 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_202 = FLASH_BASE + 202 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_203 = FLASH_BASE + 203 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_204 = FLASH_BASE + 204 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_205 = FLASH_BASE + 205 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_206 = FLASH_BASE + 206 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_207 = FLASH_BASE + 207 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_208 = FLASH_BASE + 208 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_209 = FLASH_BASE + 209 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_210 = FLASH_BASE + 210 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_211 = FLASH_BASE + 211 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_212 = FLASH_BASE + 212 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_213 = FLASH_BASE + 213 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_214 = FLASH_BASE + 214 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_215 = FLASH_BASE + 215 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_216 = FLASH_BASE + 216 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_217 = FLASH_BASE + 217 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_218 = FLASH_BASE + 218 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_219 = FLASH_BASE + 219 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_220 = FLASH_BASE + 220 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_221 = FLASH_BASE + 221 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_222 = FLASH_BASE + 222 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_223 = FLASH_BASE + 223 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_224 = FLASH_BASE + 224 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_225 = FLASH_BASE + 225 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_226 = FLASH_BASE + 226 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_227 = FLASH_BASE + 227 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_228 = FLASH_BASE + 228 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_229 = FLASH_BASE + 229 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_230 = FLASH_BASE + 230 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_231 = FLASH_BASE + 231 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_232 = FLASH_BASE + 232 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_233 = FLASH_BASE + 233 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_234 = FLASH_BASE + 234 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_235 = FLASH_BASE + 235 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_236 = FLASH_BASE + 236 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_237 = FLASH_BASE + 237 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_238 = FLASH_BASE + 238 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_239 = FLASH_BASE + 239 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_240 = FLASH_BASE + 240 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_241 = FLASH_BASE + 241 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_242 = FLASH_BASE + 242 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_243 = FLASH_BASE + 243 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_244 = FLASH_BASE + 244 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_245 = FLASH_BASE + 245 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_246 = FLASH_BASE + 246 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_247 = FLASH_BASE + 247 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_248 = FLASH_BASE + 248 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_249 = FLASH_BASE + 249 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_250 = FLASH_BASE + 250 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_251 = FLASH_BASE + 251 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_252 = FLASH_BASE + 252 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_253 = FLASH_BASE + 253 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_254 = FLASH_BASE + 254 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_255 = FLASH_BASE + 255 * FLASH_ONE_PAGE_SIZE, + + /* The chip is supported 128K. */ +#if defined (CHIP_3065PNPIRE) + FLASH_PAGE_MAX = FLASH_PAGE_255 +#endif + + /* Only this chips are supported 512K. */ +#if defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIMH) || defined (CHIP_3065PNPIRH) + FLASH_PAGE_256 = FLASH_BASE + 256 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_257 = FLASH_BASE + 257 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_258 = FLASH_BASE + 258 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_259 = FLASH_BASE + 259 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_260 = FLASH_BASE + 260 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_261 = FLASH_BASE + 261 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_262 = FLASH_BASE + 262 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_263 = FLASH_BASE + 263 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_264 = FLASH_BASE + 264 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_265 = FLASH_BASE + 265 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_266 = FLASH_BASE + 266 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_267 = FLASH_BASE + 267 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_268 = FLASH_BASE + 268 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_269 = FLASH_BASE + 269 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_270 = FLASH_BASE + 270 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_271 = FLASH_BASE + 271 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_272 = FLASH_BASE + 272 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_273 = FLASH_BASE + 273 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_274 = FLASH_BASE + 274 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_275 = FLASH_BASE + 275 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_276 = FLASH_BASE + 276 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_277 = FLASH_BASE + 277 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_278 = FLASH_BASE + 278 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_279 = FLASH_BASE + 279 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_280 = FLASH_BASE + 280 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_281 = FLASH_BASE + 281 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_282 = FLASH_BASE + 282 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_283 = FLASH_BASE + 283 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_284 = FLASH_BASE + 284 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_285 = FLASH_BASE + 285 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_286 = FLASH_BASE + 286 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_287 = FLASH_BASE + 287 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_288 = FLASH_BASE + 288 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_289 = FLASH_BASE + 289 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_290 = FLASH_BASE + 290 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_291 = FLASH_BASE + 291 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_292 = FLASH_BASE + 292 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_293 = FLASH_BASE + 293 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_294 = FLASH_BASE + 294 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_295 = FLASH_BASE + 295 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_296 = FLASH_BASE + 296 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_297 = FLASH_BASE + 297 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_298 = FLASH_BASE + 298 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_299 = FLASH_BASE + 299 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_300 = FLASH_BASE + 300 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_301 = FLASH_BASE + 301 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_302 = FLASH_BASE + 302 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_303 = FLASH_BASE + 303 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_304 = FLASH_BASE + 304 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_305 = FLASH_BASE + 305 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_306 = FLASH_BASE + 306 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_307 = FLASH_BASE + 307 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_308 = FLASH_BASE + 308 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_309 = FLASH_BASE + 309 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_310 = FLASH_BASE + 310 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_311 = FLASH_BASE + 311 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_312 = FLASH_BASE + 312 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_313 = FLASH_BASE + 313 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_314 = FLASH_BASE + 314 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_315 = FLASH_BASE + 315 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_316 = FLASH_BASE + 316 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_317 = FLASH_BASE + 317 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_318 = FLASH_BASE + 318 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_319 = FLASH_BASE + 319 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_320 = FLASH_BASE + 320 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_321 = FLASH_BASE + 321 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_322 = FLASH_BASE + 322 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_323 = FLASH_BASE + 323 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_324 = FLASH_BASE + 324 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_325 = FLASH_BASE + 325 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_326 = FLASH_BASE + 326 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_327 = FLASH_BASE + 327 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_328 = FLASH_BASE + 328 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_329 = FLASH_BASE + 329 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_330 = FLASH_BASE + 330 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_331 = FLASH_BASE + 331 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_332 = FLASH_BASE + 332 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_333 = FLASH_BASE + 333 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_334 = FLASH_BASE + 334 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_335 = FLASH_BASE + 335 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_336 = FLASH_BASE + 336 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_337 = FLASH_BASE + 337 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_338 = FLASH_BASE + 338 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_339 = FLASH_BASE + 339 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_340 = FLASH_BASE + 340 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_341 = FLASH_BASE + 341 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_342 = FLASH_BASE + 342 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_343 = FLASH_BASE + 343 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_344 = FLASH_BASE + 344 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_345 = FLASH_BASE + 345 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_346 = FLASH_BASE + 346 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_347 = FLASH_BASE + 347 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_348 = FLASH_BASE + 348 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_349 = FLASH_BASE + 349 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_350 = FLASH_BASE + 350 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_351 = FLASH_BASE + 351 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_352 = FLASH_BASE + 352 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_353 = FLASH_BASE + 353 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_354 = FLASH_BASE + 354 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_355 = FLASH_BASE + 355 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_356 = FLASH_BASE + 356 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_357 = FLASH_BASE + 357 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_358 = FLASH_BASE + 358 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_359 = FLASH_BASE + 359 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_360 = FLASH_BASE + 360 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_361 = FLASH_BASE + 361 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_362 = FLASH_BASE + 362 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_363 = FLASH_BASE + 363 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_364 = FLASH_BASE + 364 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_365 = FLASH_BASE + 365 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_366 = FLASH_BASE + 366 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_367 = FLASH_BASE + 367 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_368 = FLASH_BASE + 368 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_369 = FLASH_BASE + 369 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_370 = FLASH_BASE + 370 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_371 = FLASH_BASE + 371 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_372 = FLASH_BASE + 372 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_373 = FLASH_BASE + 373 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_374 = FLASH_BASE + 374 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_375 = FLASH_BASE + 375 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_376 = FLASH_BASE + 376 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_377 = FLASH_BASE + 377 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_378 = FLASH_BASE + 378 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_379 = FLASH_BASE + 379 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_380 = FLASH_BASE + 380 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_381 = FLASH_BASE + 381 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_382 = FLASH_BASE + 382 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_383 = FLASH_BASE + 383 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_384 = FLASH_BASE + 384 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_385 = FLASH_BASE + 385 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_386 = FLASH_BASE + 386 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_387 = FLASH_BASE + 387 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_388 = FLASH_BASE + 388 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_389 = FLASH_BASE + 389 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_390 = FLASH_BASE + 390 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_391 = FLASH_BASE + 391 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_392 = FLASH_BASE + 392 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_393 = FLASH_BASE + 393 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_394 = FLASH_BASE + 394 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_395 = FLASH_BASE + 395 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_396 = FLASH_BASE + 396 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_397 = FLASH_BASE + 397 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_398 = FLASH_BASE + 398 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_399 = FLASH_BASE + 399 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_400 = FLASH_BASE + 400 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_401 = FLASH_BASE + 401 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_402 = FLASH_BASE + 402 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_403 = FLASH_BASE + 403 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_404 = FLASH_BASE + 404 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_405 = FLASH_BASE + 405 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_406 = FLASH_BASE + 406 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_407 = FLASH_BASE + 407 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_408 = FLASH_BASE + 408 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_409 = FLASH_BASE + 409 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_410 = FLASH_BASE + 410 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_411 = FLASH_BASE + 411 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_412 = FLASH_BASE + 412 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_413 = FLASH_BASE + 413 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_414 = FLASH_BASE + 414 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_415 = FLASH_BASE + 415 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_416 = FLASH_BASE + 416 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_417 = FLASH_BASE + 417 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_418 = FLASH_BASE + 418 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_419 = FLASH_BASE + 419 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_420 = FLASH_BASE + 420 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_421 = FLASH_BASE + 421 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_422 = FLASH_BASE + 422 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_423 = FLASH_BASE + 423 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_424 = FLASH_BASE + 424 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_425 = FLASH_BASE + 425 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_426 = FLASH_BASE + 426 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_427 = FLASH_BASE + 427 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_428 = FLASH_BASE + 428 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_429 = FLASH_BASE + 429 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_430 = FLASH_BASE + 430 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_431 = FLASH_BASE + 431 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_432 = FLASH_BASE + 432 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_433 = FLASH_BASE + 433 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_434 = FLASH_BASE + 434 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_435 = FLASH_BASE + 435 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_436 = FLASH_BASE + 436 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_437 = FLASH_BASE + 437 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_438 = FLASH_BASE + 438 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_439 = FLASH_BASE + 439 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_440 = FLASH_BASE + 440 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_441 = FLASH_BASE + 441 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_442 = FLASH_BASE + 442 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_443 = FLASH_BASE + 443 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_444 = FLASH_BASE + 444 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_445 = FLASH_BASE + 445 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_446 = FLASH_BASE + 446 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_447 = FLASH_BASE + 447 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_448 = FLASH_BASE + 448 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_449 = FLASH_BASE + 449 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_450 = FLASH_BASE + 450 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_451 = FLASH_BASE + 451 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_452 = FLASH_BASE + 452 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_453 = FLASH_BASE + 453 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_454 = FLASH_BASE + 454 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_455 = FLASH_BASE + 455 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_456 = FLASH_BASE + 456 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_457 = FLASH_BASE + 457 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_458 = FLASH_BASE + 458 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_459 = FLASH_BASE + 459 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_460 = FLASH_BASE + 460 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_461 = FLASH_BASE + 461 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_462 = FLASH_BASE + 462 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_463 = FLASH_BASE + 463 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_464 = FLASH_BASE + 464 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_465 = FLASH_BASE + 465 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_466 = FLASH_BASE + 466 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_467 = FLASH_BASE + 467 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_468 = FLASH_BASE + 468 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_469 = FLASH_BASE + 469 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_470 = FLASH_BASE + 470 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_471 = FLASH_BASE + 471 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_472 = FLASH_BASE + 472 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_473 = FLASH_BASE + 473 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_474 = FLASH_BASE + 474 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_475 = FLASH_BASE + 475 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_476 = FLASH_BASE + 476 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_477 = FLASH_BASE + 477 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_478 = FLASH_BASE + 478 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_479 = FLASH_BASE + 479 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_480 = FLASH_BASE + 480 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_481 = FLASH_BASE + 481 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_482 = FLASH_BASE + 482 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_483 = FLASH_BASE + 483 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_484 = FLASH_BASE + 484 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_485 = FLASH_BASE + 485 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_486 = FLASH_BASE + 486 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_487 = FLASH_BASE + 487 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_488 = FLASH_BASE + 488 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_489 = FLASH_BASE + 489 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_490 = FLASH_BASE + 490 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_491 = FLASH_BASE + 491 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_492 = FLASH_BASE + 492 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_493 = FLASH_BASE + 493 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_494 = FLASH_BASE + 494 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_495 = FLASH_BASE + 495 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_496 = FLASH_BASE + 496 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_497 = FLASH_BASE + 497 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_498 = FLASH_BASE + 498 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_499 = FLASH_BASE + 499 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_500 = FLASH_BASE + 500 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_501 = FLASH_BASE + 501 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_502 = FLASH_BASE + 502 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_503 = FLASH_BASE + 503 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_504 = FLASH_BASE + 504 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_505 = FLASH_BASE + 505 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_506 = FLASH_BASE + 506 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_507 = FLASH_BASE + 507 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_508 = FLASH_BASE + 508 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_509 = FLASH_BASE + 509 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_510 = FLASH_BASE + 510 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_511 = FLASH_BASE + 511 * FLASH_ONE_PAGE_SIZE, + FLASH_PAGE_MAX = FLASH_PAGE_511 +#endif + +#else + /* The chip is supported 128K. */ + FLASH_PAGE_MAX = FLASH_PAGE_127 +#endif + +} FLASH_SectorAddr; + +/** + * @brief Flash operation word enumeration definition. + */ +typedef enum { + FLASH_OPERATION_READ = 0x00000001U, + FLASH_OPERATION_PROGRAM = 0x00000002U, + FLASH_OPERATION_ERASE = 0x00000004U, + FLASH_OPERATION_MASS_ERASE = 0x00000006U +} FLASH_OperationType; + +/** + * @brief Flash operation cmd code enumeration definition. + */ +typedef enum { + FLASH_CMD_READ = 0x00000001U, + FLASH_CMD_MAIN_PROGEAM = 0x00000002U, + FLASH_CMD_INFO_PROGEAM = 0x00000003U, + FLASH_CMD_MAIN_ERASE = 0x00000004U, + FLASH_CMD_INFO_ERASE = 0x00000005U, + FLASH_CMD_MASS_ERASE = 0x00000006U +} FLASH_CmdCodeType; + +/** + * @brief Callback Triggering Event Enumeration Definition + */ +typedef enum { + FLASH_WRITE_EVENT_SUCCESS, + FLASH_WRITE_EVENT_DONE, + FLASH_WRITE_EVENT_FAIL, + FLASH_ERASE_EVENT_SUCCESS, + FLASH_ERASE_EVENT_DONE, + FLASH_ERASE_EVENT_FAIL, +} FLASH_CallBackEvent; + +/** + * @brief FLASH extend handle, configuring some special parameters. + */ +typedef struct { + unsigned int onceOperateLen; /* Length of the flash memory to be operaten, write unit: byte, erase unit: page. */ +} FLASH_ExtendHandle; + +/** + * @brief User-defined callback function. + */ +typedef struct { + /** Event callback function of the flash module */ + void (*FlashCallBack)(void *handle, FLASH_CallBackEvent event, unsigned int opAddr); +} FLASH_UserCallBcak; +/** + * @} + */ + +/** + * @defgroup FLASH_Reg_Def FLASH Register Definition + * @brief register mapping structure + * @{ + */ + +/** + * @brief EFLASH command registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cmd_start : 1; /**< Write 0:no effect, 1:start cmd operation; + Read 0:cmd operation is complete, 1:cmd operation isn't complete. */ + unsigned int reserved0 : 5; + unsigned int exec_state : 2; /**< Read 0: no operation or operation completed, + 1: an operation is being performed, + 2: the operation is complete. */ + unsigned int cmd_code : 3; /**< Values represent 1: read, + 2: main_rgn Program, + 3: info_rgn Program, + 4: main_rgn Erase, + 5: info_rgn Erase, + 6: mass erase. */ + unsigned int reserved1 : 9; + unsigned int cmd_pgm_size : 6; /**< Program Size, unit:word(32bits). + 0x0:2, 0x1:4, 0x2:8,..., 0x0F:60, 0x10:64, + other values are invalid. */ + unsigned int reserved2 : 2; + unsigned int cmd_read_size : 2; /**< Read Size, unit:word(32bits). 0x0:1, 0x1:4, 0x2:8, 0x3:12. */ + unsigned int reserved3 : 2; + } BIT; +} volatile EFLASH_CMD_REG; + +/** + * @brief EFLASH address registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 2; + unsigned int cmd_addr : 22; /**< Program, erase, or read start address register. Unit:byte(8bits). + start address of Main_rgn: 0x00_0000, + start address of info_rgn: 0x80_0000, + note: the lower 2 bits cannot be written. */ + unsigned int reserved1 : 8; + } BIT; +} volatile EFLASH_ADDR_REG; + +/** + * @brief Command configuration registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 1; + unsigned int int_mode : 1; /**< Command operation mode 0:blocking mode, 1:interrupt mode. */ + unsigned int reserved1 : 30; + } BIT; +} volatile CMD_CFG_COMMON_REG; + +/** + * @brief The raw interrupt status registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 4; + unsigned int int_raw_finish : 1; /**< Operation completion status, + 0:no operation performed or operation completed, + 1:the operation completed. */ + unsigned int reserved1 : 11; + unsigned int int_raw_err_illegal : 1; /**< Invalid cmd operation errors, 0:no errors, + 1:cmd operation error. */ + unsigned int int_raw_err_erase : 1; /**< ERASE error, 0:pass, 1:failure. */ + unsigned int int_raw_err_ahb : 1; /**< AHB request error, 0:no errors, 1:AHB read address request + exceeds the range of MAIN Information Region or + AHB write request occurs. */ + unsigned int int_raw_err_ecc_corr : 1; /**< MAIN Information Region Read Data ECC Correction Error, + 0:no errors, 1:Uncorrectable ECC error occurred. */ + unsigned int int_raw_err_ecc_chk : 1; /**< MAIN Information Region read data ECC error, 0:no errors, + 1:an ECC check error occurred. */ + unsigned int reserved2 : 11; + } BIT; +} volatile INT_RAW_STATUS_REG; + +/** + * @brief The interrupt status registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 4; + unsigned int int_finish : 1; /**< Operation completion status, + 0:no operation performed or operation completed, + 1:the operation completed. */ + unsigned int reserved1 : 11; + unsigned int int_err_illegal : 1; /**< Invalid cmd operation errors, 0:no errors, + 1:cmd operation error. */ + unsigned int int_err_erase : 1; /**< ERASE error, 0:pass, 1:failure. */ + unsigned int int_err_ahb : 1; /**< AHB request error, 0:no errors, 1:AHB read address request + exceeds the range of MAIN Information Region or + AHB write request occurs. */ + unsigned int int_err_ecc_corr : 1; /**< MAIN Information Region Read Data ECC Correction Error, 0:no errors, + 1:Uncorrectable ECC error occurred. */ + unsigned int int_err_ecc_chk : 1; /**< MAIN Information Region read data ECC error, 0:no errors, + 1:an ECC check error occurred. */ + unsigned int reserved2 : 11; + } BIT; +} volatile INT_STATUS_REG; + +/** + * @brief The interrupt enable configuration registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 4; + unsigned int int_en_finish : 1; /**< Operation completion interrupt enable, 0:disable, 1:enable. */ + unsigned int reserved1 : 11; + unsigned int int_en_err_illegal : 1; /**< Invalid Cmd operation error interrupt enable, + 0:disable, 1:enable. */ + unsigned int int_en_err_erase : 1; /**< ERASE error interrupt enable, 0:disable, 1:enable. */ + unsigned int int_en_err_ahb : 1; /**< AHB request error interrupt enable, 0:disable, 1:enable. */ + unsigned int int_en_err_ecc_corr : 1; /**< Main Information region read data ECC correction error interrupt, + 0:disable, 1:enable. */ + unsigned int int_en_err_ecc_chk : 1; /**< Main Information region read data ECC check error interrupt enable, + 0:disable, 1:enable. */ + unsigned int reserved2 : 11; + } BIT; +} volatile INT_ENABLE_REG; + +/** + * @brief Interrupt clear registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 4; + unsigned int int_clr_finish : 1; /**< Operation completion interrupt clear, 0:not clear, + 1:clear raw interrupts and interrupt status. */ + unsigned int reserved1 : 11; + unsigned int int_clr_err_illegal : 1; /**< Invalid CMD operation error interrupt clear, 0:not clear, + 1:clear raw interrupts and interrupt status. */ + unsigned int int_clr_err_erase : 1; /**< erase error interrupt clear, 0:not clear, + 1:clear raw interrupts and interrupt status. */ + unsigned int int_clr_err_ahb : 1; /**< AHB request error interrupt clear, 0:not clear, + 1:clear raw interrupts and interrupt status. */ + unsigned int int_clr_err_ecc_corr : 1; /**< Main Information region read data ECC correction error + interrupt clear, 0:not clear, + 1:clear raw interrupts and interrupt status. */ + unsigned int int_clr_err_ecc_chk : 1; /**< Main Information region read data ECC error interrupt clear, + 0:not clear, 1:clear raw interrupts and interrupt status. */ + unsigned int reserved2 : 11; + } BIT; +} volatile INT_CLEAR_REG; + +/** + * @brief Prefetch control registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int prefetch_enable : 1; /**< Prefetch control enable, 0:disabled, 1:enable. */ + unsigned int reserved0 : 7; + unsigned int prefetch_invalid_req : 1; /**< Cache Data Invalid Request Control. */ + unsigned int reserved1 : 23; + } BIT; +} volatile PREFETCH_CTRL_REG; + +/** + * @brief Cache control registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cache_enable : 1; /**< Prefetch control enable, 0:disabled, 1:enable. */ + unsigned int reserved0 : 3; + unsigned int cache_replacement_sel : 1; /**< Cache replacement policy selection, 0:PLRU policy, + 1:round robin policy. */ + unsigned int reserved1 : 3; + unsigned int cache_invalid_req : 1; /**< Cache data invalid request, 0:invalidation, + 1:request cache invalid. */ + unsigned int reserved2 : 3; + unsigned int cache_policy_sel : 1; /**< Selecting a cache policy, 0:Normal Cache, + 1:Branch Cache. */ + unsigned int reserved3 : 19; + } BIT; +} volatile CACHE_CTRL_REG; + +/** + * @brief Flash ECC error detection and correction enable control registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int flash_main_ecc_check_enable : 1; /**< Flash Main region error detection enable, + 0:no ECC check, 1:ECC check. */ + unsigned int flash_main_ecc_correct_enable : 1; /**< Flash Main region error correction enable, + 0:no ECC correction, 1:ECC correction. */ + unsigned int flash_info_ecc_check_enable : 1; /**< Flash Information region ECC error detection enable, + 0:no ECC check, 1:ECC check. */ + unsigned int flash_info_ecc_correct_enable : 1; /**< Flash Information region ECC error correction function, + 0:no ECC correction, 1:ECC correction. */ + unsigned int flash_ecc_blank_filter_enable : 1; /**< Flash unprogrammed area ECC mask and filter enable, + 0:disable, 1:enable. */ + unsigned int reserved0 : 27; + } BIT; +} volatile FLASH_ECC_CTRL_REG; + +/** + * @brief Flash status registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int opcode_illegal : 3; /**< Invalid opcode value. */ + unsigned int reserved0 : 1; + unsigned int mid_illegal : 3; /**< Invalid mid value. */ + unsigned int reserved1 : 1; + unsigned int info_rgn0_illegal : 1; /**< Illegally operation info_rgn0, 0:no error, + 1:illegally access occurs. */ + unsigned int info_rgn1_illegal : 1; /**< Illegally operation info_rgn1, 0:no error, + 1:illegally access occurs. */ + unsigned int info_rgn2_illegal : 1; /**< Illegally operation info_rgn2, 0:no error, + 1:illegally access occurs. */ + unsigned int info_rgn3_illegal : 1 ; /* [11] */ + unsigned int info_rgn4_illegal : 1 ; /* [12] */ + unsigned int reserved_2 : 2 ; /* [14..13] */ + unsigned int main_rgn0_illegal : 1 ; /* [15] */ + unsigned int main_rgn1_illegal : 1 ; /* [16] */ + unsigned int main_rgn2_illegal : 1 ; /* [17] */ + unsigned int reserved_3 : 2 ; /* [19..18] */ + unsigned int parameter_illegal : 1 ; /* [20] */ + unsigned int address_unmap : 1 ; /* [21] */ + unsigned int reserved_4 : 10 ; /* [31..22] */ + } BIT; +} volatile FLASH_STATUS_REG; + +/** + * @brief Main region 0 start address registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 2; + unsigned int main_rgn0_start_addr : 17; /**< Region0 Access Start Address, Unit:Word(32bit). */ + unsigned int reserved1 : 13; + } BIT; +} volatile FLASH_REGION_0_START_ADDR_REG; + +/** + * @brief Main region 0 end address registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 2; + unsigned int main_rgn0_end_addr : 17; /**< Region0 Access End Address, Unit:Word(32bit). */ + unsigned int reserved1 : 13; + } BIT; +} volatile FLASH_REGION_0_END_ADDR_REG; + +/** + * @brief Main region0 control registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int main_rgn0_mid_r : 8; /**< Indicates the mid that allows the read operation on region0. */ + unsigned int main_rgn0_mid_p : 8; /**< Indicates the MID that allows programming operations on region0. */ + unsigned int main_rgn0_mid_e : 8; /**< Indicates the MID that allows the erase operation on region0. */ + unsigned int reserved0 : 7; + unsigned int main_rgn0_active : 1; /**< Activate Zone Access Control, 0:not activated, 1:activated. */ + } BIT; +} volatile FLASH_REGION_0_CTRL_REG; + +/** + * @brief Main region 1 start address registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 2; + unsigned int main_rgn1_start_addr : 17; /**< Region1 Access Start Address, Unit:Word(32bit). */ + unsigned int reserved1 : 13; + } BIT; +} volatile FLASH_REGION_1_START_ADDR_REG; + +/** + * @brief Main region 1 end address registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 2; + unsigned int main_rgn1_end_addr : 17; /**< Region1 Access end Address, Unit:Word(32bit). */ + unsigned int reserved1 : 13; + } BIT; +} volatile FLASH_REGION_1_END_ADDR_REG; + +/** + * @brief Main region1 control registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int main_rgn1_mid_r : 8; /**< Indicates the mid that allows the read operation on region1. */ + unsigned int main_rgn1_mid_p : 8; /**< Indicates the MID that allows programming operations on region1. */ + unsigned int main_rgn1_mid_e : 8; /**< Indicates the MID that allows the erase operation on region1. */ + unsigned int reserved0 : 7; + unsigned int main_rgn1_active : 1; /**< Activate Zone Access Control, 0:not activated, 1:activated. */ + } BIT; +} volatile FLASH_REGION_1_CTRL_REG; + +/* Define the union U_FLASH_REGION2_START_ADDR */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved_0 : 2 ; /* [1..0] */ + unsigned int main_rgn2_start_addr : 17 ; /* [18..2] */ + unsigned int reserved_1 : 13 ; /* [31..19] */ + } BIT; +} volatile FLASH_REGION_2_START_ADDR_REG; + +/* Define the union U_FLASH_REGION2_END_ADDR */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved_0 : 2 ; /* [1..0] */ + unsigned int main_rgn2_end_addr : 17 ; /* [18..2] */ + unsigned int reserved_1 : 13 ; /* [31..19] */ + } BIT; +} volatile FLASH_REGION_2_END_ADDR_REG; + +/* Define the union U_FLASH_REGION2_CTRL */ +typedef union { + unsigned int reg; + struct { + unsigned int main_rgn2_mid_r : 8 ; /* [7..0] */ + unsigned int main_rgn2_mid_p : 8 ; /* [15..8] */ + unsigned int main_rgn2_mid_e : 8 ; /* [23..16] */ + unsigned int reserved_0 : 7 ; /* [30..24] */ + unsigned int main_rgn2_active : 1 ; /* [31] */ + } BIT; +} volatile FLASH_REGION_2_CTRL_REG; + +/** + * @brief Flash Module information 1 registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int page_size : 16; /**< Info_rgn0/info_rgn1 capacity, unit:byte. */ + unsigned int information_capacity : 16; /**< Eflash page capacity, unit:byte. */ + } BIT; +} volatile EFLASH_CAPACITY_1_REG; + +/** + * @brief Flash Module information 2 registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int io_read_length : 4; /**< Read I/O size. */ + unsigned int io_write_length_information : 4; /**< Write info region I/O size. */ + unsigned int io_write_length_main : 4; /**< Write main region I/O size. */ + unsigned int min_pgm_size_information : 4; /**< Minimal programming size of information region. */ + unsigned int min_pgm_size_main : 4; /**< Minimal programming size of main region. */ + unsigned int max_pgm_size : 4; /**< Max programming size. */ + unsigned int min_erase_size : 4; /**< Minimal erase size. */ + unsigned int reserved0 : 4; + } BIT; +} volatile EFLASH_CAPACITY_2_REG; + +/** + * @brief Flash clears the programming data buffer registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int pgm_wdata_clr : 1; /**< Clear Control, 0:no effect, 1:clear current buffer. */ + unsigned int reserved0 : 7; + unsigned int pgm_wbuf_cnt : 8; /**< Obtains the size of the data in the buffer, unit:word. */ + unsigned int reserved1 : 16; + } BIT; +} volatile BUF_CLEAR_REG; + +/** + * @brief Flash clock divider registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 4; + unsigned int nread_div : 4; /**< Ratio of the system bus master clock to EFlash clock (n + 1). */ + unsigned int reserved1 : 12; + unsigned int busclk_sw_req : 1; /**< Check the cur_read_vref_cal or nread_div switchover is complete, + read 0:no finish, 1:finish. */ + unsigned int busclk_sw_protect : 1; /**< Frequency switching process protection, 0:enable, 1:disable. */ + unsigned int cur_read_vref_cal : 1; /**< Flash reference voltage calibration completion indicator. */ + unsigned int reserved2 : 1; + unsigned int data_vld_sel : 2; /**< Data_vld: one beat in advance or one beat later, + 0x0 and 0x01:no change, 0x02:take an early beat, + 0x03:delay a beat */ + unsigned int reserved3 : 6; + } BIT; +} volatile EFLASH_CLK_CFG_REG; + +/** + * @brief FLASH Register definition structure + */ +typedef struct { + EFLASH_CMD_REG EFLASH_CMD; /**< Command register, Offset Address: 0x0000. */ + EFLASH_ADDR_REG EFLASH_ADDR; /**< Address register, Offset Address: 0x0004. */ + unsigned char space0[120]; + CMD_CFG_COMMON_REG CMD_CFG_COMMON; /**< CMD configuration register, + Offset Address: 0x0080. */ + unsigned char space1[124]; + INT_RAW_STATUS_REG INT_RAW_STATUS; /**< Raw interrupt status register, + Offset Address: 0x0100. */ + INT_STATUS_REG INT_STATUS; /**< Interrupt status register, + Offset Address: 0x0104. */ + INT_ENABLE_REG INT_ENABLE; /**< Interrupt enable configuration register, + Offset Address: 0x0108. */ + INT_CLEAR_REG INT_CLEAR; /**< Interrupt clear register, + Offset Address: 0x010c. */ + unsigned char space2[16]; + PREFETCH_CTRL_REG PREFETCH_CTRL; /**< Prefetch control register, + Offset Address: 0x0120. */ + CACHE_CTRL_REG CACHE_CTRL; /**< Cache control register, Offset Address: 0x0124. */ + unsigned char space3[4]; + FLASH_ECC_CTRL_REG FLASH_ECC_CTRL; /**< Flash ECC error detection and correction enable + control register, Offset Address: 0x012c. */ + FLASH_STATUS_REG FLASH_STATUS; /**< CMD operation flash status register, + Offset Address: 0x0130. */ + unsigned char space4[4]; + unsigned int AHB_ERR_ADDR; /**< AHB error request address record register, + Offset Address: 0x0138. */ + unsigned char space5[8]; + FLASH_REGION_0_START_ADDR_REG FLASH_REGION0_START_ADDR; /**< Main region 0 start address, + Offset Address: 0x0144. */ + FLASH_REGION_0_END_ADDR_REG FLASH_REGION0_END_ADDR; /**< Main region 0 end address, + Offset Address: 0x0148. */ + FLASH_REGION_0_CTRL_REG FLASH_REGION0_CTRL; /**< Main region0 control register, + Offset Address: 0x014c. */ + FLASH_REGION_1_START_ADDR_REG FLASH_REGION1_START_ADDR; /**< Main region 1 start address, + Offset Address: 0x0150. */ + FLASH_REGION_1_END_ADDR_REG FLASH_REGION1_END_ADDR; /**< Main region 1 end address, + Offset Address: 0x0154. */ + FLASH_REGION_1_CTRL_REG FLASH_REGION1_CTRL; /**< Main region 1 control register, + Offset Address: 0x0158. */ + FLASH_REGION_2_START_ADDR_REG FLASH_REGION2_START_ADDR; + FLASH_REGION_2_END_ADDR_REG FLASH_REGION2_END_ADDR; + FLASH_REGION_2_CTRL_REG FLASH_REGION2_CTRL; + unsigned char space6[152]; + unsigned int MAGIC_LOCK; /**< CMD magic word protection register, + Offset Address: 0x0200. */ + unsigned char space7[492]; + unsigned int EFLASH_CAPACITY_0; /**< Module information register 0, + Offset Address: 0x03f0. */ + EFLASH_CAPACITY_1_REG EFLASH_CAPACITY_1; /**< Module information register 1, + Offset Address: 0x03f4. */ + EFLASH_CAPACITY_2_REG EFLASH_CAPACITY_2; /**< Module information register 2, + Offset Address: 0x03f8. */ + unsigned char space8[4]; + unsigned int PGM_WDATA; /**< Program data register, Offset Address: 0x0400. */ + unsigned char space9[508]; + unsigned int FLASH_RDATA; /**< Read data register, Offset Address: 0x0600. */ + BUF_CLEAR_REG BUF_CLEAR; /**< Programming data buffer cleanup register, + Offset Address: 0x0604. */ + unsigned int space10[206]; + EFLASH_CLK_CFG_REG EFLASH_CLK_CFG; /**< Clock divider register, Offset Address: 0x0940. */ +} volatile EFC_RegStruct; + +/** + * @} + */ + +/* Parameter check definition-------------------------------------------*/ +/** + * @brief Check Operation mode selection. + * @param opMode Flash Operation mode. + * @retval true + * @retval false + */ +static inline bool IsFlashOperationMode(FLASH_PE_OpMode opMode) +{ + return (opMode == FLASH_PE_OP_BLOCK || + opMode == FLASH_PE_OP_IT); +} + +/** + * @brief Check flash cmd code. + * @param cmdCode Flash cmd code. + * @retval true + * @retval false + */ +static inline bool IsFlashCmdCode(FLASH_CmdCodeType cmdCode) +{ + return (cmdCode == FLASH_CMD_READ || cmdCode == FLASH_CMD_MAIN_PROGEAM || \ + cmdCode == FLASH_CMD_INFO_PROGEAM || cmdCode == FLASH_CMD_MAIN_ERASE || \ + cmdCode == FLASH_CMD_INFO_ERASE || cmdCode == FLASH_CMD_MASS_ERASE); +} + +/** + * @brief Check flash cmd program size. + * @param size cmd program size, unit:Word(32bit). + * @retval true + * @retval false + */ +static inline bool IsFlashCmdProgramSize(unsigned int size) +{ + return size <= FLASH_MAX_CMD_PROGRAM_SIZE; +} + +/** + * @brief Check flash program address. + * @param addr program address, unit:Byte(8bit). + * @retval true + * @retval false + */ +static inline bool IsFlashProgramAddress(unsigned int addr) +{ + return (((addr % FLASH_MIN_PGM_BYTES_SIZE) == 0) && (addr < FLASH_MAX_SIZE)); +} + +/** + * @brief Check flash erase address. + * @param addr erase address, unit:Byte(8bit). + * @retval true + * @retval false + */ +static inline bool IsFlashEraseAddress(unsigned int addr) +{ + return ((addr % FLASH_ONE_PAGE_SIZE) == 0) && (addr <= FLASH_PAGE_MAX); +} + +/** + * @brief Check flash write source addresss. + * @param addr write source addresss. + * @retval true + * @retval false + */ +static inline bool IsFlashWriteSrcAddress(unsigned int addr) +{ + return ((addr >= FLASH_SRAM_START_ADDRESS && addr <= FLASH_SRAM_END_ADDRESS) || + (addr >= FLASH_MAIN_RNG_START_ADDRESS && addr <= FLASH_MAIN_RNG_END_ADDRESS)); +} + +/** + * @brief Check flash erase mode. + * @param mode flash erase mode. + * @retval true + * @retval false + */ +static inline bool IsFlashEraseMode(FLASH_EraseMode mode) +{ + return (mode == FLASH_ERASE_MODE_PAGE || mode == FLASH_ERASE_MODE_CHIP); +} + +/** + * @brief Enable flash command start. + * @param efc FLASH register base address. + * @retval None. + */ +static inline void DCL_FLASH_CmdStartEnable(EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + efcx->EFLASH_CMD.BIT.cmd_start = BASE_CFG_ENABLE; +} + +/** + * @brief Disable flash command start. + * @param efcx FLASH register base address. + * @retval None. + */ +static inline void DCL_FLASH_CmdStartDisable(EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + efcx->EFLASH_CMD.BIT.cmd_start = BASE_CFG_DISABLE; +} + +/** + * @brief Getting flash command start State. + * @param efcx FLASH register base address. + * @retval command start value, 1: Operation complete or no operation, 0: Operation is not complete. + */ +static inline unsigned int DCL_FLASH_GetCmdStartState(const EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + return efcx->EFLASH_CMD.BIT.cmd_start; +} + +/** + * @brief Setting FLASH cmd code. + * @param efcx FLASH register base address. + * @param cmdCode flash cmd code. + * @retval None. + */ +static inline void DCL_FLASH_SetCmdCode(EFC_RegStruct *efcx, FLASH_CmdCodeType cmdCode) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + FLASH_PARAM_CHECK_NO_RET(IsFlashCmdCode(cmdCode)); + efcx->EFLASH_CMD.BIT.cmd_code = cmdCode; +} + +/** + * @brief Getting FLASH cmd code. + * @param efcx FLASH register base address. + * @param cmdCode flash cmd code. + * @retval cmd code, 1:READ, 2:FLASH_CMD_MAIN_PROGEAM, 3:FLASH_CMD_INFO_PROGEAM, 4:FLASH_CMD_MAIN_ERASE, + 5:FLASH_CMD_INFO_ERASE, 6:FLASH_CMD_MASS_ERASE. + */ +static inline unsigned int DCL_FLASH_GetCmdCode(const EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + return efcx->EFLASH_CMD.BIT.cmd_code; +} + +/** + * @brief Setting FLASH cmd program size. + * @param efcx FLASH register base address. + * @param size flash cmd program size, unit:Word(32bit). + * @retval None. + */ +static inline void DCL_FLASH_SetCmdProgramSize(EFC_RegStruct *efcx, unsigned int size) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + FLASH_PARAM_CHECK_NO_RET(IsFlashCmdProgramSize(size)); + efcx->EFLASH_CMD.BIT.cmd_pgm_size = size; +} + +/** + * @brief Getting FLASH cmd program size. + * @param efcx FLASH register base address. + * @retval cmd program size, unit:Word(32bit). + */ +static inline unsigned int DCL_FLASH_GetCmdProgramSize(const EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + return efcx->EFLASH_CMD.BIT.cmd_pgm_size; +} + +/** + * @brief Setting FLASH program start address. + * @param efcx FLASH register base address. + * @param addr flash cmd program start address, unit:Byte(8bit). + * @retval None. + */ +static inline void DCL_FLASH_SetProgramAddress(EFC_RegStruct *efcx, unsigned int addr) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + FLASH_PARAM_CHECK_NO_RET(IsFlashProgramAddress(addr)); + efcx->EFLASH_ADDR.BIT.cmd_addr = addr; +} + +/** + * @brief Setting FLASH erase start address. + * @param efcx FLASH register base address. + * @param addr flash cmd erase start address, unit:Byte(8bit). + * @retval None. + */ +static inline void DCL_FLASH_SetEraseAddress(EFC_RegStruct *efcx, unsigned int addr) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + FLASH_PARAM_CHECK_NO_RET(IsFlashEraseAddress(addr)); + efcx->EFLASH_ADDR.BIT.cmd_addr = addr; +} + +/** + * @brief Getting FLASH cmd program, erase, read start address. + * @param efcx FLASH register base address. + * @retval cmd program, erase, read start address, unit:Byte(8bit). + */ +static inline unsigned int DCL_FLASH_GetCmdStartAddress(const EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + return efcx->EFLASH_ADDR.BIT.cmd_addr; +} + +/** + * @brief Setting FLASH operation mode. + * @param efcx FLASH register base address. + * @param mode flash operation mode. + * @retval None. + */ +static inline void DCL_FLASH_SetOptMode(EFC_RegStruct *efcx, FLASH_PE_OpMode mode) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + FLASH_PARAM_CHECK_NO_RET(IsFlashOperationMode(mode)); + efcx->CMD_CFG_COMMON.BIT.int_mode = mode; +} + +/** + * @brief Getting FLASH operation mode. + * @param efcx FLASH register base address. + * @retval operation mode, 0:FLASH_PE_OP_BLOCK, 1:FLASH_PE_OP_IT. + */ +static inline unsigned int DCL_FLASH_GetOptMode(const EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + return efcx->CMD_CFG_COMMON.BIT.int_mode; +} + +/** + * @brief Obtains the interrupt status. + * @param efcx FLASH register base address. + * @retval Interrupt Status. + */ +static inline unsigned int DCL_FLASH_GetInterrupRawtStatus(const EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + return efcx->INT_RAW_STATUS.reg; +} + +/** + * @brief Configuring Interrupt Enable. + * @param efcx FLASH register base address. + * @param intrEn Corresponding interrupt enable bit, for example, 110011. + * @retval None. + */ +static inline void DCL_FLASH_SetInterruptEn(EFC_RegStruct *efcx, unsigned int intrEn) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + efcx->INT_ENABLE.reg = intrEn; +} + +/** + * @brief Obtaining the Interrupt Enable Configuration. + * @param efcx FLASH register base address. + * @retval Interrupt enable value. + */ +static inline unsigned int DCL_FLASH_GetInterruptEnState(const EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + return efcx->INT_ENABLE.reg; +} + +/** + * @brief Clear Interrupt. + * @param efcx FLASH register base address. + * @param intrRaw Corresponding interrupt bit, for example, 110011. + * @retval None. + */ +static inline void DCL_FLASH_ClearIrq(EFC_RegStruct *efcx, unsigned int intrRaw) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + efcx->INT_CLEAR.reg = intrRaw; +} + +/** + * @brief FLASH cache invalid request enable. + * @param efcx FLASH register base address. + * @retval None. + */ +static inline void DCL_FLASH_CacheInvalidRequestEnable(EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + efcx->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_ENABLE; +} + +/** + * @brief FLASH cache invalid request disable. + * @param efcx FLASH register base address. + * @retval None. + */ +static inline void DCL_FLASH_CacheInvalidRequestDisable(EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + efcx->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_DISABLE; +} + +/** + * @brief Getting FLASH cache invalid request state. + * @param efcx FLASH register base address. + * @retval state 0:The latest invalid request has been completed, + 1:The latest invalid request is not completed. + */ +static inline unsigned int DCL_FLASH_GetCacheInvalidRequestState(const EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + return efcx->CACHE_CTRL.BIT.cache_invalid_req; +} + +/** + * @brief Getting FLASH command operation status. + * @param efcx FLASH register base address. + * @retval command operation status. + */ +static inline unsigned int DCL_FLASH_GetCommandOptStatus(const EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + return efcx->FLASH_STATUS.reg; +} + +/** + * @brief Setting FLASH magic lock. + * @param efcx FLASH register base address. + * @retval None. + */ +static inline void DCL_FLASH_MagicLock(EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + efcx->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; +} + +/** + * @brief Setting FLASH magic unlock. + * @param efcx FLASH register base address. + * @retval None. + */ +static inline void DCL_FLASH_MagicUnlock(EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + efcx->MAGIC_LOCK = FLASH_KEY_REGISTER_UNLOCK_VALUE; +} + +/** + * @brief Getting FLASH magic lock. + * @param efcx FLASH register base address. + * @retval The value of magic lock, The value 0xFEDC_BA98 indicates magic unlock, others values is magic lock. + */ +static inline unsigned int DCL_FLASH_GetMagicLock(const EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + return efcx->MAGIC_LOCK; +} + +/** + * @brief Setting FLASH program wdata value. + * @param efcx FLASH register base address. + * @param value The value of program wdata. + * @retval None. + */ +static inline void DCL_FLASH_SetProgramWdata(EFC_RegStruct *efcx, unsigned int value) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + efcx->PGM_WDATA = value; +} + +/** + * @brief FLASH program wdata celar enable. + * @param efcx FLASH register base address. + * @retval None. + */ +static inline void DCL_FLASH_ProgramWdataClearEnable(EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + efcx->BUF_CLEAR.BIT.pgm_wdata_clr = BASE_CFG_ENABLE; +} + +/** + * @brief FLASH program wdata celar disable. + * @param efcx FLASH register base address. + * @retval None. + */ +static inline void DCL_FLASH_ProgramWdataClearDisable(EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + efcx->BUF_CLEAR.BIT.pgm_wdata_clr = BASE_CFG_DISABLE; +} + +/** + * @brief Getting FLASH buf clear value. + * @param efcx FLASH register base address. + * @retval None. + */ +static inline unsigned int DCL_FLASH_GetBufClearValue(const EFC_RegStruct *efcx) +{ + FLASH_ASSERT_PARAM(IsEFCInstance(efcx)); + return efcx->BUF_CLEAR.reg; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* #ifndef McuMagicTag_FLASH_IP_H */ \ No newline at end of file diff --git a/src/drivers/flash/flash_v3/src/flash.c b/src/drivers/flash/flash_v3/src/flash.c new file mode 100644 index 0000000000000000000000000000000000000000..b6a87c5356144c00840fa0110743642343853de3 --- /dev/null +++ b/src/drivers/flash/flash_v3/src/flash.c @@ -0,0 +1,799 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file flash.c + * @author MCU Driver Team + * @brief FLASH module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the FLASH. + * + Initialization and de-initialization functions. + * + Read, write, and erase functions. + */ + +/* Includes ------------------------------------------------------------------ */ +#include "flash.h" + +#define FLASH_CRC_SAVE_BUFFER_LEN 2 +#define FLASH_ALL_INTERRUPT_ENABLE 0x001F0010 +#define FLASH_ERR_INTERRUPT_MASK 0x001F0000 +#define FLASH_CMD_INTERRUPT_MASK 0x00000010 + +#define FLASH_KEY_REGISTER_UNLOCK_VALUE 0xFEDCBA98 +#define FLASH_KEY_REGISTER_LOCK_VALUE 0x0 + +#define FLASH_INT_ERR_ECC_CHK_MASK (1 << 20) +#define FLASH_INT_ERR_ECC_CORR_MASK (1 << 19) +#define FLASH_INT_ERR_AHB_MASK (1 << 18) +#define FLASH_INT_ERR_SMWR_MASK (1 << 17) +#define FLASH_INT_ERR_ILLEGAL_MASK (1 << 16) +#define FLASH_INT_FINISH_MASK (1<< 4) + +#define FLASH_INT_CLEAR_ALL 0xFFFFFFFF + +#define FLASH_REMAP_4KB 0 +#define FLASH_REMAP_8KB 1 +#define FLASH_REMAP_128KB 2 +#define FLASH_REMAP_256KB 3 + +/** + * @brief Check whether errors occur. + * @param handle FLASH handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType CheckErrorStatus(FLASH_Handle *handle) +{ + /* Check whether errors occur. */ + if (handle->baseAddress->INT_RAW_STATUS.BIT.int_raw_err_illegal || + handle->baseAddress->INT_RAW_STATUS.BIT.int_raw_err_erase) { + return BASE_STATUS_ERROR; + } + if (handle->baseAddress->FLASH_STATUS.reg != 0) { + return BASE_STATUS_ERROR; + } + return BASE_STATUS_OK; +} + +/** + * @brief Writes to the flash memory in the unit of words. + * @param handle FLASH handle. + * @param wordNum Number of size written, unit: word. + * @retval None. + */ +static void FlashPopulateDefaults(FLASH_Handle *handle, const unsigned int wordNum) +{ + /* Complement missing data values. */ + if (wordNum % FLASH_MIN_PGM_WORDS_SIZE) { + for (unsigned int i = (wordNum % FLASH_MIN_PGM_WORDS_SIZE); i < FLASH_MIN_PGM_WORDS_SIZE; i++) { + handle->baseAddress->PGM_WDATA = 0xFFFFFFFF; /* The default value of flash is 0xFFFFFFFF. */ + } + } +} + +/** + * @brief Writes to the flash memory in the unit of words. + * @param handle FLASH handle. + * @param srcAddr Start address of the data buffer to be written. + * @param destAddr Flash destination address, which must be word-aligned. + * @param size Number of size written, unit: byte. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType FLASH_WriteWords(FLASH_Handle *handle, + const unsigned int srcAddr, + const unsigned int destAddr, + const unsigned int size) +{ + unsigned int *data = NULL; + unsigned int i; + unsigned int writeSize; + unsigned int wordNum; + /* Make sure the last operation is complete. */ + if (handle->baseAddress->EFLASH_CMD.BIT.cmd_start) { + return BASE_STATUS_BUSY; + } + + /* Get the number of last remaining data. */ + wordNum = size / FLASH_ONE_WORD_BYTES_SIZE; + wordNum += ((size % FLASH_ONE_WORD_BYTES_SIZE) == 0) ? 0 : 1; + + handle->baseAddress->MAGIC_LOCK = FLASH_KEY_REGISTER_UNLOCK_VALUE; + /* The mask of program wdata celar is 0xFF. */ + if ((handle->baseAddress->BUF_CLEAR.reg >> FLASH_PGM_WBUF_CNT_POS) & 0xFF) { + handle->baseAddress->BUF_CLEAR.BIT.pgm_wdata_clr = BASE_CFG_SET; /* program wdata celar enable. */ + } + + /* Step 1: Calculated the cmd program size, get srcAddress and get destAddress. */ + writeSize = ((wordNum % FLASH_MIN_PGM_WORDS_SIZE) != 0) ? (wordNum / FLASH_MIN_PGM_WORDS_SIZE + 1) : + wordNum / FLASH_MIN_PGM_WORDS_SIZE; + data = (unsigned int *)(uintptr_t)srcAddr; + handle->baseAddress->EFLASH_ADDR.BIT.cmd_addr = destAddr; + for (i = 0; i < wordNum; i++) { + handle->baseAddress->PGM_WDATA = *data; + data++; + } + /* Complement missing data values. */ + FlashPopulateDefaults(handle, wordNum); + + /* Step 2: Configure the parameters and start programming. */ + handle->baseAddress->EFLASH_CMD.BIT.cmd_pgm_size = writeSize; + handle->baseAddress->EFLASH_CMD.BIT.cmd_code = FLASH_OPERATION_PROGRAM; + handle->baseAddress->EFLASH_CMD.BIT.cmd_start = BASE_CFG_SET; + + /* Step 3: If the blocking mode is used, wait until the program operation is complete. */ + if (handle->peMode == FLASH_PE_OP_BLOCK) { + while (handle->baseAddress->EFLASH_CMD.BIT.cmd_start) { + ; + } + if (CheckErrorStatus(handle) != BASE_STATUS_OK) { + /* Clears data in the cache and clears the interrupt flag. */ + handle->baseAddress->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_SET; + handle->baseAddress->INT_CLEAR.reg = FLASH_INT_CLEAR_ALL; + handle->baseAddress->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; + return BASE_STATUS_ERROR; + } + handle->baseAddress->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_SET; + handle->baseAddress->INT_CLEAR.reg = FLASH_INT_CLEAR_ALL; + } + handle->baseAddress->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; + return BASE_STATUS_OK; +} + +/** + * @brief Obtains the number of words to be supplemented for write alignment to prevent cross-page write. + * @param handle FLASH handle. + * @retval Words. + */ +static unsigned int FLASH_GetWriteAlignmentWords(FLASH_Handle *handle) +{ + unsigned int numWords; + /* Step 1: Calculate the number of words occupied at the start address. */ + numWords = handle->destAddr % FLASH_MAX_PGM_WORD_SIZE; + if (numWords > 0) { + /* Step 2: Calculate the number of words in the remaining space of the ROW. */ + return FLASH_MAX_PGM_WORD_SIZE - numWords; + } + return 0; +} + +/** + * @brief Flash erase operation. + * @param handle FLASH handle. + * @param startAddr Erasing start address, which must be aligned with the minimum erasing unit. + * @param mode Erasing operation mode, supporting chip,and page. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType FLASH_EraseWithMode(FLASH_Handle *handle, unsigned int startAddr, unsigned int mode) +{ + /* Make sure the last operation is complete. */ + if (handle->baseAddress->EFLASH_CMD.BIT.cmd_start) { + return BASE_STATUS_BUSY; + } + + handle->baseAddress->MAGIC_LOCK = FLASH_KEY_REGISTER_UNLOCK_VALUE; + + /* Step 1: Configure the erase start address and erase mode, then make cmd_satrt enable. */ + handle->baseAddress->EFLASH_ADDR.BIT.cmd_addr = startAddr; + handle->baseAddress->EFLASH_CMD.BIT.cmd_code = mode; + handle->baseAddress->EFLASH_CMD.BIT.cmd_start = BASE_CFG_SET; + + /* Step 2: If the blocking mode is used, wait until the erase operation is complete. */ + if (handle->peMode == FLASH_PE_OP_BLOCK) { + while (handle->baseAddress->EFLASH_CMD.BIT.cmd_start) { + ; + } + /* Check whether errors occur. */ + if (handle->baseAddress->INT_RAW_STATUS.BIT.int_raw_err_illegal || + handle->baseAddress->INT_RAW_STATUS.BIT.int_raw_err_erase) { + handle->baseAddress->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_SET; + handle->baseAddress->INT_CLEAR.reg = FLASH_INT_CLEAR_ALL; + handle->baseAddress->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; + return BASE_STATUS_ERROR; + } + if (handle->baseAddress->FLASH_STATUS.reg != 0) { + handle->baseAddress->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_SET; + handle->baseAddress->INT_CLEAR.reg = FLASH_INT_CLEAR_ALL; + handle->baseAddress->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; + return BASE_STATUS_ERROR; + } + } + handle->baseAddress->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; + return BASE_STATUS_OK; +} + +/** + * @brief Write interrupt processing function, + * which completes the internal processing of the write operation in interrupt mode. + * @param handle FLASH handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType FLASH_WriteHandler(FLASH_Handle *handle) +{ + unsigned int dataLeft; + unsigned int tempAddr; + BASE_StatusType ret; + /* If the number of bytes to be written is greater than a Row, + data is written based on the bytes number of a row. */ + if ((handle->writeLen / FLASH_MAX_PGM_BYTE_SIZE) > 0) { + handle->handleEx.onceOperateLen = FLASH_MAX_PGM_BYTE_SIZE; + ret = FLASH_WriteWords(handle, handle->srcAddr, handle->destAddr, FLASH_MAX_PGM_BYTE_SIZE); + if (ret != BASE_STATUS_OK) { + handle->handleEx.onceOperateLen = 0; + return ret; + } + } else if (handle->writeLen > 0) { + /* If the number of bytes to be written is less than a Row, + data is written in the unit of words. In addition, if data is less than one word, complete one word. */ + dataLeft = handle->writeLen; + /* Updata the srcAddress, destAddress and write length. */ + tempAddr = (dataLeft / FLASH_ONE_WORD_BYTES_SIZE); + if (tempAddr == 0) { + tempAddr = FLASH_ONE_WORD_BYTES_SIZE; + } else { /* Get the address change value, aligned with 4words. */ + tempAddr = ((tempAddr % FLASH_ONE_WORD_BYTES_SIZE) == 0) ? tempAddr : + ((tempAddr / FLASH_ONE_WORD_BYTES_SIZE + 1) * FLASH_ONE_WORD_BYTES_SIZE); + } + handle->handleEx.onceOperateLen = tempAddr; + ret = FLASH_WriteWords(handle, handle->srcAddr, handle->destAddr, dataLeft); + if (ret != BASE_STATUS_OK) { + handle->handleEx.onceOperateLen = 0; + return ret; + } + } + return BASE_STATUS_OK; +} + +/** + * @brief Erase interrupt processing function, + * which completes the internal processing of the erase operation in interrupt mode. + * @param handle FLASH handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType FLASH_EraseHandler(FLASH_Handle *handle) +{ + /* Check whether the erasing mode is valid. */ + FLASH_PARAM_CHECK_WITH_RET((handle->destAddr <= (FLASH_PAGE_MAX / FLASH_ONE_WORD_BYTES_SIZE)), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET((handle->destAddr % (FLASH_ONE_PAGE_WORD_SIZE) == 0), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET((((FLASH_MAX_PAGE_NUM - (handle->destAddr / FLASH_ONE_PAGE_WORD_SIZE)) >=\ + handle->eraseNum) && handle->eraseNum > 0), BASE_STATUS_ERROR); + + BASE_StatusType ret; + handle->handleEx.onceOperateLen = 0x01; /* Erase 1 page at a time. */ + ret = FLASH_EraseWithMode(handle, handle->destAddr, FLASH_ERASE_MODE_PAGE); + if (ret != BASE_STATUS_OK) { + handle->handleEx.onceOperateLen = 0; + return ret; + } + /* Updata the erase destAddress and erase number. */ + return BASE_STATUS_OK; +} + +/** + * @brief Initializing the FLASH Module. + * @param handle FLASH handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_FLASH_Init(FLASH_Handle *handle) +{ + FLASH_ASSERT_PARAM(handle != NULL); + FLASH_ASSERT_PARAM(IsEFCInstance(handle->baseAddress)); + FLASH_PARAM_CHECK_WITH_RET(IsFlashOperationMode(handle->peMode), BASE_STATUS_ERROR); + + handle->baseAddress->MAGIC_LOCK = FLASH_KEY_REGISTER_UNLOCK_VALUE; /* Unlock key registers */ + if (handle->peMode == FLASH_PE_OP_IT) { + /* Enable the interrupt mode and clear the interrupt flag bit. */ + handle->baseAddress->CMD_CFG_COMMON.BIT.int_mode = BASE_CFG_SET; + handle->baseAddress->INT_ENABLE.reg = FLASH_ALL_INTERRUPT_ENABLE; + handle->baseAddress->INT_CLEAR.reg = FLASH_ALL_INTERRUPT_ENABLE; + } else { + /* If blocking mode is used, disable int_mode. */ + handle->baseAddress->CMD_CFG_COMMON.BIT.int_mode = BASE_CFG_UNSET; + } + handle->baseAddress->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; /* Lock key registers */ + handle->state = FLASH_STATE_READY; + return BASE_STATUS_OK; +} + +/** + * @brief Deinitialize the FLASH Module. + * @param handle FLASH handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_FLASH_DeInit(FLASH_Handle *handle) +{ + FLASH_ASSERT_PARAM(handle != NULL); + FLASH_ASSERT_PARAM(IsEFCInstance(handle->baseAddress)); + handle->state = FLASH_STATE_RESET; + handle->userCallBack.FlashCallBack = NULL; /* Clean interrupt callback functions. */ + handle->baseAddress->MAGIC_LOCK = FLASH_KEY_REGISTER_UNLOCK_VALUE; + /* Disable interrupt mode and interrupt enable bit. */ + handle->baseAddress->CMD_CFG_COMMON.BIT.int_mode = BASE_CFG_UNSET; + handle->baseAddress->INT_ENABLE.reg = 0x00000000; + handle->baseAddress->MAGIC_LOCK = FLASH_KEY_REGISTER_LOCK_VALUE; /* Locking Key Registers */ + return BASE_STATUS_OK; +} + +/** + * @brief Registering the Callback Function of the Flash Module. + * @param handle FLASH handle. + * @param pcallback Pointer to the callback function. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_FLASH_RegisterCallback(FLASH_Handle *handle, FLASH_CallbackFunType pcallback) +{ + FLASH_ASSERT_PARAM(handle != NULL); + FLASH_ASSERT_PARAM(IsEFCInstance(handle->baseAddress)); + handle->userCallBack.FlashCallBack = pcallback; + return BASE_STATUS_OK; +} + +/** + * @brief blocking write error handle. + * @param handle FLASH handle. + * @retval None. + */ +static void FLASH_WritteBlockingErrorHandle(FLASH_Handle *handle) +{ + handle->baseAddress->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_SET; + handle->baseAddress->INT_CLEAR.reg = FLASH_INT_CLEAR_ALL; + handle->state = FLASH_STATE_READY; +} + +/** + * @brief Write the flash memory in blocking mode. + * @param handle FLASH handle. + * @param srcAddr Start address of the data buffer to be written. + * @param destAddr Start address of the flash to be written.The address must be aligned with the minimum writable unit. + * @param srcLen Length of data to be written,unit:bytes. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_FLASH_WriteBlocking(FLASH_Handle *handle, unsigned int srcAddr, + unsigned int destAddr, const unsigned int srcLen) +{ + BASE_StatusType ret; + unsigned int i; + unsigned int currentLen; + unsigned int currentWords; + unsigned int dataLeft; + /* Check related parameters. */ + FLASH_ASSERT_PARAM(handle != NULL); + FLASH_ASSERT_PARAM(IsEFCInstance(handle->baseAddress)); + FLASH_PARAM_CHECK_WITH_RET((handle->peMode == FLASH_PE_OP_BLOCK), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET(handle->state == FLASH_STATE_READY, BASE_STATUS_ERROR); + /* Check whether the write address is valid. */ + FLASH_PARAM_CHECK_WITH_RET(IsFlashWriteSrcAddress(srcAddr), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET((destAddr < FLASH_MAX_SIZE), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET((destAddr % FLASH_MIN_PGM_BYTES_SIZE) == 0, BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET(srcLen > 0, BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET(srcLen <= (FLASH_MAX_SIZE - destAddr), BASE_STATUS_ERROR); + + handle->state = FLASH_STATE_PGM; + handle->destAddr = destAddr / FLASH_ONE_WORD_BYTES_SIZE; /* Convert the destination address unit to word. */ + handle->srcAddr = srcAddr; + + /* Get the number of words in the remaining space of the ROW. */ + currentWords = FLASH_GetWriteAlignmentWords(handle); + /* Step 1: If there is remaining space and write length greater than remaining space, + write data in the remaining space. */ + if (srcLen > (currentWords * FLASH_ONE_WORD_BYTES_SIZE) && currentWords > 0) { + ret = FLASH_WriteWords(handle, handle->srcAddr, handle->destAddr, (currentWords * FLASH_ONE_WORD_BYTES_SIZE)); + if (ret != BASE_STATUS_OK) { + FLASH_WritteBlockingErrorHandle(handle); + return ret; + } + handle->srcAddr += currentWords * FLASH_ONE_WORD_BYTES_SIZE; + handle->destAddr += currentWords; + currentLen = srcLen - currentWords * FLASH_ONE_WORD_BYTES_SIZE; + } else { + currentLen = srcLen; + } + /* Step 2: If the number of bytes to be written is greater than a Row, + data is written based on the bytes number of a row. */ + for (i = 0; i < currentLen / FLASH_MAX_PGM_BYTE_SIZE; i++) { + ret = FLASH_WriteWords(handle, handle->srcAddr, handle->destAddr, FLASH_MAX_PGM_BYTE_SIZE); + if (ret != BASE_STATUS_OK) { + FLASH_WritteBlockingErrorHandle(handle); + return ret; + } + handle->srcAddr += FLASH_MAX_PGM_WORD_SIZE * FLASH_ONE_WORD_BYTES_SIZE; + handle->destAddr += FLASH_MAX_PGM_WORD_SIZE; + } + + /* Get the number of last remaining data. */ + dataLeft = currentLen % FLASH_MAX_PGM_BYTE_SIZE; + if (dataLeft > 0) { /* This branch is executed only when the remaining data is not completely written. */ + ret = FLASH_WriteWords(handle, handle->srcAddr, handle->destAddr, dataLeft); + } + + FLASH_WritteBlockingErrorHandle(handle); + return ret; +} + +/** + * @brief WriteErase the flash memory in blocking mode. + * @param handle FLASH handle. + * @param eraseMode Erasing mode. The options are chip erasing and page erasing. + * @param startAddr Start address of the flash to be erase. The address must be aligned with the minimum erasable unit. + * @param eraseNum Number of pages to be erased. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_FLASH_EraseBlocking(FLASH_Handle *handle, FLASH_EraseMode eraseMode, + FLASH_SectorAddr startAddr, unsigned int eraseNum) +{ + /* Check related parameters. */ + FLASH_ASSERT_PARAM(handle != NULL); + FLASH_ASSERT_PARAM(IsEFCInstance(handle->baseAddress)); + FLASH_PARAM_CHECK_WITH_RET((handle->peMode == FLASH_PE_OP_BLOCK), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET(handle->state == FLASH_STATE_READY, BASE_STATUS_ERROR); + /* Check whether the erasing mode is valid. */ + FLASH_PARAM_CHECK_WITH_RET(IsFlashEraseMode(eraseMode), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET((startAddr <= FLASH_PAGE_MAX), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET((startAddr % FLASH_ONE_PAGE_SIZE == 0) || (eraseMode == FLASH_ERASE_MODE_CHIP),\ + BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET(eraseNum > 0 && eraseNum <= (FLASH_MAX_PAGE_NUM - startAddr / FLASH_ONE_PAGE_SIZE),\ + BASE_STATUS_ERROR); + + BASE_StatusType ret = BASE_STATUS_OK; + + handle->eraseNum = eraseNum; + handle->destAddr = startAddr / sizeof(unsigned int); /* Convert the destination address unit to word. */ + handle->state = FLASH_STATE_ERASE; + + if (eraseMode == FLASH_ERASE_MODE_CHIP) { + /* If the FLASH_ERASE_MODE_CHIP mode is used, all contents in the flash memory are erased. */ + ret = FLASH_EraseWithMode(handle, handle->destAddr, FLASH_ERASE_MODE_CHIP); + if (ret != BASE_STATUS_OK) { + handle->baseAddress->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_SET; + handle->state = FLASH_STATE_READY; + return ret; + } + } else if (eraseMode == FLASH_ERASE_MODE_PAGE) { + /* If the FLASH_ERASE_MODE_PAGE mode is used, erasing requires page-by-page. */ + while (handle->eraseNum) { + ret = FLASH_EraseHandler(handle); + if (ret != BASE_STATUS_OK) { + handle->baseAddress->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_SET; + handle->state = FLASH_STATE_READY; + return ret; + } + /* Updata the erase destAddress and erase number. */ + handle->destAddr += FLASH_ONE_PAGE_SIZE / sizeof(unsigned int); + handle->eraseNum--; + } + } + /* Clear the data in the cache to invalidate the data. */ + handle->baseAddress->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_SET; + handle->state = FLASH_STATE_READY; + return ret; +} + +/** + * @brief Write the flash memory in interrupt mode. + * @param handle FLASH handle. + * @param srcAddr Start address of the data buffer to be written. + * @param destAddr Start address of the flash to be written.The address must be aligned with the minimum writable unit. + * @param srcLen Length of data to be written,unit:bytes. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_FLASH_WriteIT(FLASH_Handle *handle, unsigned int srcAddr, + unsigned int destAddr, unsigned int srcLen) +{ + unsigned int currentWords; + BASE_StatusType ret; + /* Check the validity of the base address and operation mode of the flash memory. */ + FLASH_ASSERT_PARAM(handle != NULL); + FLASH_ASSERT_PARAM(IsEFCInstance(handle->baseAddress)); + FLASH_PARAM_CHECK_WITH_RET((handle->peMode == FLASH_PE_OP_IT), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET(handle->state == FLASH_STATE_READY, BASE_STATUS_ERROR); + /* Check whether the write address is valid. */ + FLASH_PARAM_CHECK_WITH_RET(IsFlashWriteSrcAddress(srcAddr), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET((destAddr < FLASH_MAX_SIZE), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET((destAddr % FLASH_MIN_PGM_BYTES_SIZE) == 0, BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET((srcLen > 0), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET(srcLen <= (FLASH_MAX_SIZE - destAddr), BASE_STATUS_ERROR); + + handle->state = FLASH_STATE_PGM; + handle->destAddr = destAddr / FLASH_ONE_WORD_BYTES_SIZE; /* Convert the destination address unit to word. */ + handle->srcAddr = srcAddr; + handle->writeLen = srcLen; + + /* Get the number of words in the remaining space of the ROW. */ + currentWords = FLASH_GetWriteAlignmentWords(handle); + /* If there is remaining space and write length greater than remaining space, + write data in the remaining space. */ + if (handle->writeLen > (currentWords * FLASH_ONE_WORD_BYTES_SIZE) && currentWords > 0) { + handle->handleEx.onceOperateLen = (currentWords * FLASH_ONE_WORD_BYTES_SIZE); + ret = FLASH_WriteWords(handle, handle->srcAddr, handle->destAddr, (currentWords * FLASH_ONE_WORD_BYTES_SIZE)); + if (ret != BASE_STATUS_OK) { + handle->handleEx.onceOperateLen = 0; + handle->state = FLASH_STATE_READY; + return ret; + } + } else { + /* Write the last remaining data. */ + ret = FLASH_WriteHandler(handle); + if (ret != BASE_STATUS_OK) { + handle->state = FLASH_STATE_READY; + return ret; + } + } + return BASE_STATUS_OK; +} + +/** + * @brief WriteErase the flash memory in interrupt mode. + * @param handle FLASH handle. + * @param eraseMode Erasing mode. The options are chip erasing and page erasing. + * @param startAddr Start address of the flash to be erase. The address must be aligned with the minimum erasable unit. + * @param eraseNum Number of pages to be erased. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_FLASH_EraseIT(FLASH_Handle *handle, FLASH_EraseMode eraseMode, + FLASH_SectorAddr startAddr, unsigned int eraseNum) +{ + BASE_StatusType ret = BASE_STATUS_OK; + FLASH_ASSERT_PARAM(handle != NULL); + FLASH_ASSERT_PARAM(IsEFCInstance(handle->baseAddress)); + FLASH_PARAM_CHECK_WITH_RET((handle->peMode == FLASH_PE_OP_IT), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET((handle->state == FLASH_STATE_READY), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET(IsFlashEraseMode(eraseMode), BASE_STATUS_ERROR); + /* Check whether the address is valid. */ + FLASH_PARAM_CHECK_WITH_RET((startAddr <= FLASH_PAGE_MAX), BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET((startAddr % FLASH_ONE_PAGE_SIZE == 0) || (eraseMode == FLASH_ERASE_MODE_CHIP),\ + BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET(eraseNum > 0 && eraseNum <= (FLASH_MAX_PAGE_NUM - startAddr / FLASH_ONE_PAGE_SIZE),\ + BASE_STATUS_ERROR); + /* Obtains the value entered by the user. */ + handle->eraseNum = eraseNum; + handle->state = FLASH_STATE_ERASE; + handle->destAddr = startAddr / sizeof(unsigned int); /* Convert the destination address unit to word. */ + + if (eraseMode == FLASH_ERASE_MODE_CHIP) { + /* If the FLASH_ERASE_MODE_CHIP mode is used, all contents in the flash memory are erased. */ + handle->handleEx.onceOperateLen = handle->eraseNum; + ret = FLASH_EraseWithMode(handle, handle->destAddr, FLASH_ERASE_MODE_CHIP); + if (ret != BASE_STATUS_OK) { + handle->handleEx.onceOperateLen = 0; + handle->state = FLASH_STATE_READY; + return ret; + } + } else if (eraseMode == FLASH_ERASE_MODE_PAGE) { + /* If the FLASH_ERASE_MODE_PAGE mode is used, erasing requires page-by-page. */ + ret = FLASH_EraseHandler(handle); + if (ret != BASE_STATUS_OK) { + handle->state = FLASH_STATE_READY; + return ret; + } + } + return BASE_STATUS_OK; +} + +/** + * @brief Get the remap range. + * @param None + * @retval the value of remap size, unit: byte. + */ +static unsigned int FlashRemapCheck(void) +{ + unsigned int remapRange = 0; + + if (SYSCTRL1->REMAP_CFG.BIT.remap_en != BASE_CFG_SET) { + return remapRange; + } + switch (SYSCTRL1->REMAP_CFG.BIT.remap_mode) { + case FLASH_REMAP_4KB: + remapRange = 0x00001000; /* 0x00001000 : 4KB reamp address range. */ + break; + case FLASH_REMAP_8KB: + remapRange = 0x00002000; /* 0x00002000 : 8KB reamp address range. */ + break; + case FLASH_REMAP_128KB: + remapRange = 0x00020000; /* 0x00020000 : 128KB reamp address range. */ + break; + case FLASH_REMAP_256KB: + remapRange = 0x00040000; /* 0x00040000 : 256KB reamp address range. */ + break; + default: + break; + } + return remapRange; +} + +/** + * @brief Interface for reading data from the flash memory. + * @param handle FLASH handle. + * @param srcAddr Flash address of the data to be read. The address must be aligned with the minimum readable unit. + * @param readLen Read Data Length,unit:bytes. + * @param dataBuff Buffer for storing read data. + * @param buffLen Buffer size for storing read data,unit:bytes. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_FLASH_Read(FLASH_Handle *handle, + unsigned int srcAddr, + unsigned int readLen, + unsigned char *dataBuff, + unsigned int buffLen) +{ + unsigned char *ptemp = NULL; + unsigned char *dtemp = NULL; + unsigned int tempLen = readLen; + unsigned int remapRange = 0; +#ifndef FLASH_PARAM_CHECK + BASE_FUNC_UNUSED(handle); /* Used to avoid code check alarm prompts. */ +#endif + FLASH_ASSERT_PARAM(handle != NULL); + FLASH_ASSERT_PARAM(IsEFCInstance(handle->baseAddress)); + FLASH_ASSERT_PARAM(dataBuff != NULL); + FLASH_PARAM_CHECK_WITH_RET(srcAddr < FLASH_MAX_SIZE, BASE_STATUS_ERROR); + FLASH_PARAM_CHECK_WITH_RET(readLen <= (FLASH_MAX_SIZE - srcAddr), BASE_STATUS_ERROR); + + dtemp = dataBuff; + /* Remap check. */ + remapRange = FlashRemapCheck(); + if (remapRange != BASE_CFG_UNSET) { + /* Refresh the readback address when the remap function is enabled. */ + if (srcAddr >= remapRange) { + /* The basic offset address needs to be added to srcAddress. */ + ptemp = (unsigned char *)(uintptr_t)srcAddr + FLASH_READ_BASE - remapRange; + } else { + /* The basic offset address needs to be added to srcAddress. */ + ptemp = (unsigned char *)(uintptr_t)srcAddr + FLASH_READ_BASE + remapRange; + } + } else { + /* The basic offset address needs to be added to srcAddress. */ + ptemp = (unsigned char *)(uintptr_t)srcAddr + FLASH_READ_BASE; + } + + if (readLen > buffLen) { + return BASE_STATUS_ERROR; + } + while (tempLen > 0) { /* Read data cyclically. */ + tempLen--; + *dtemp++ = *ptemp++; + } + return BASE_STATUS_OK; +} + +/** + * @brief Interrupt Processing Write. + * @param handle FLASH handle. + * @param status Interrupt status + * @retval None + */ +static void InterruptWriteHandle(FLASH_Handle *handle, unsigned int status) +{ + /* Check whether the parameter is valid. */ + FLASH_PARAM_CHECK_NO_RET(IsFlashWriteSrcAddress(handle->srcAddr)); + FLASH_PARAM_CHECK_NO_RET((handle->destAddr % FLASH_MIN_PGM_WORDS_SIZE) == 0); + FLASH_PARAM_CHECK_NO_RET((handle->destAddr <= (FLASH_MAX_SIZE / FLASH_ONE_WORD_BYTES_SIZE))); + FLASH_PARAM_CHECK_NO_RET(handle->writeLen <= (FLASH_MAX_SIZE - (handle->destAddr * FLASH_ONE_WORD_BYTES_SIZE))); + /* One operation complete */ + if ((status & FLASH_INT_FINISH_MASK) > 0) { + if (handle->userCallBack.FlashCallBack != NULL) { + handle->userCallBack.FlashCallBack(handle, FLASH_WRITE_EVENT_SUCCESS, handle->destAddr); + } + } + /* All operations are complete. */ + if (handle->writeLen == 0) { + if (handle->userCallBack.FlashCallBack != NULL) { + handle->userCallBack.FlashCallBack(handle, FLASH_WRITE_EVENT_DONE, handle->destAddr); + } + handle->baseAddress->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_SET; + handle->state = FLASH_STATE_READY; + } else { + FLASH_WriteHandler(handle); + } +} + +/** + * @brief Interrupt processing erase. + * @param handle FLASH handle. + * @param status Interrupt status + * @retval None + */ +static void InterruptEraseHandle(FLASH_Handle *handle, unsigned int status) +{ + /* One operation complete */ + if ((status & FLASH_INT_FINISH_MASK) > 0) { + if (handle->userCallBack.FlashCallBack != NULL) { + handle->userCallBack.FlashCallBack(handle, FLASH_ERASE_EVENT_SUCCESS, handle->destAddr); + } + } + /* All operations are complete. */ + if (handle->eraseNum == 0) { + if (handle->userCallBack.FlashCallBack != NULL) { + handle->userCallBack.FlashCallBack(handle, FLASH_ERASE_EVENT_DONE, handle->destAddr); + } + handle->baseAddress->CACHE_CTRL.BIT.cache_invalid_req = BASE_CFG_SET; + handle->state = FLASH_STATE_READY; + } else { + FLASH_EraseHandler(handle); + } +} + +/** + * @brief Interrupt Handling Function. + * @param handle Handle pointers + * @retval None + */ +void HAL_FLASH_IrqHandler(void *handle) +{ + FLASH_Handle *flashHandle = (FLASH_Handle *)handle; + unsigned int status; + FLASH_ASSERT_PARAM(flashHandle != NULL); + FLASH_ASSERT_PARAM(IsEFCInstance(flashHandle->baseAddress)); + FLASH_PARAM_CHECK_NO_RET(flashHandle->peMode == FLASH_PE_OP_IT); + + status = flashHandle->baseAddress->INT_RAW_STATUS.reg; + flashHandle->baseAddress->INT_CLEAR.reg = status & FLASH_CMD_INTERRUPT_MASK; + /* Invoke the function for programming or erasing. */ + if (flashHandle->state == FLASH_STATE_PGM) { /* If state is FLASH_STATE_PGM, call write callback function. */ + if (flashHandle->writeLen < flashHandle->handleEx.onceOperateLen) { + flashHandle->writeLen = 0; + flashHandle->destAddr += flashHandle->handleEx.onceOperateLen >> 0x02; + } else { + flashHandle->writeLen -= flashHandle->handleEx.onceOperateLen; + flashHandle->srcAddr += flashHandle->handleEx.onceOperateLen; + flashHandle->destAddr += flashHandle->handleEx.onceOperateLen >> 0x02; /* Unit conversion to word */ + } + flashHandle->handleEx.onceOperateLen = 0; + InterruptWriteHandle(flashHandle, status); + } else if (flashHandle->state == FLASH_STATE_ERASE) { + if (flashHandle->handleEx.onceOperateLen != 0x00) { /* Erase page data valid. */ + flashHandle->destAddr += + (FLASH_ONE_PAGE_SIZE * flashHandle->handleEx.onceOperateLen) / sizeof(unsigned int); + flashHandle->eraseNum -= flashHandle->handleEx.onceOperateLen; + } else { + flashHandle->eraseNum = 0; /* Illegal state generation, and the status data is cleared. */ + } + flashHandle->handleEx.onceOperateLen = 0; + + /* If state is FLASH_STATE_ERASE, call erase callback function. */ + InterruptEraseHandle(flashHandle, status); + } +} + +/** + * @brief Flash Error interrupt Handling Function. + * @param handle Handle pointers + * @retval None + */ +void HAL_FLASH_IrqHandlerError(void *handle) +{ + FLASH_Handle *flashHandle = (FLASH_Handle *)handle; + unsigned int status; + FLASH_ASSERT_PARAM(flashHandle != NULL); + FLASH_ASSERT_PARAM(IsEFCInstance(flashHandle->baseAddress)); + status = flashHandle->baseAddress->INT_RAW_STATUS.reg; + flashHandle->baseAddress->INT_CLEAR.reg = status & FLASH_ERR_INTERRUPT_MASK; + + /* If any error occurs, call the programming error or erase error callback function. */ + if ((status & (FLASH_INT_ERR_ECC_CHK_MASK | FLASH_INT_ERR_ECC_CORR_MASK | + FLASH_INT_ERR_AHB_MASK | FLASH_INT_ERR_SMWR_MASK | FLASH_INT_ERR_ILLEGAL_MASK)) > 0) { + if (flashHandle->userCallBack.FlashCallBack != NULL) { + switch (flashHandle->state) { + case FLASH_STATE_PGM : /* If state is FLASH_STATE_PGM, call write error callback function. */ + flashHandle->userCallBack.FlashCallBack(flashHandle, FLASH_WRITE_EVENT_FAIL, flashHandle->destAddr); + break; + case FLASH_STATE_ERASE : /* If state is FLASH_STATE_ERASE, call erase error callback function. */ + flashHandle->userCallBack.FlashCallBack(flashHandle, FLASH_ERASE_EVENT_FAIL, flashHandle->destAddr); + break; + default: + break; + } + } + flashHandle->state = FLASH_STATE_READY; + } +} \ No newline at end of file diff --git a/src/drivers/gpt/common_v0/inc/gpt.h b/src/drivers/gpt/common_v0/inc/gpt.h index 4db50f0ab94d47316ca9d224df6e7f25a4d98f24..ac2324f001b53ef86a1eb4a68ec665448ad493f5 100644 --- a/src/drivers/gpt/common_v0/inc/gpt.h +++ b/src/drivers/gpt/common_v0/inc/gpt.h @@ -63,11 +63,10 @@ typedef struct { /** * @defgroup GPT_API_Declaration GPT HAL API + * @brief GPT Extended Control functions. * @{ */ -/** - * GPT Extended Control functions - */ + BASE_StatusType HAL_GPT_Init(GPT_Handle *handle); void HAL_GPT_Start(GPT_Handle *handle); diff --git a/src/drivers/gpt/common_v1/inc/gpt.h b/src/drivers/gpt/common_v1/inc/gpt.h index bebbc326c512a0ee6a199246a88d2274f87a2d8f..64d57934ee1fd01998b7fd8422d2ccdf6b36fd7e 100644 --- a/src/drivers/gpt/common_v1/inc/gpt.h +++ b/src/drivers/gpt/common_v1/inc/gpt.h @@ -71,12 +71,16 @@ typedef void (* GPT_CallBackFunc)(void *handle); */ /** - * @defgroup GPT_API_Declaration GPT HAL API + * @defgroup GPT_API_Declaration + * @brief GPT HAL API. * @{ */ /** - * GPT Control functions - */ + * @defgroup GPT_API_Declaration + * @brief GPT Control functions. + * @{ + */ + BASE_StatusType HAL_GPT_Init(GPT_Handle *handle); void HAL_GPT_Start(GPT_Handle *handle); @@ -86,13 +90,29 @@ void HAL_GPT_Stop(GPT_Handle *handle); BASE_StatusType HAL_GPT_Config(GPT_Handle *handle); BASE_StatusType HAL_GPT_GetConfig(GPT_Handle *handle); +/** + * @} + */ + +/** + * @defgroup GPT_API_Declaration + * @brief Setting PWM reference points and corresponding actions. + * @{ + */ -/* Setting PWM reference points and corresponding actions */ BASE_StatusType HAL_GPT_SetReferCounterAndAction(GPT_Handle *handle, const GPT_ReferCfg *refer); void HAL_GPT_GetReferCounterAndAction(GPT_Handle *handle, GPT_ReferCfg *refer); +/** + * @} + */ + +/** + * @defgroup GPT_API_Declaration + * @brief GPT frequency divider and period. + * @{ + */ -/* GPT frequency divider and period. */ BASE_StatusType HAL_GPT_SetCountPeriod(GPT_Handle *handle, unsigned int period); unsigned int HAL_GPT_GetCountPeriod(GPT_Handle *handle); @@ -100,25 +120,60 @@ unsigned int HAL_GPT_GetCountPeriod(GPT_Handle *handle); BASE_StatusType HAL_GPT_SetDivFactor(GPT_Handle *handle, unsigned int div); unsigned int HAL_GPT_GetDivFactor(GPT_Handle *handle); +/** + * @} + */ + +/** + * @defgroup GPT_API_Declaration + * @brief GPT cache loading settings and cache status. + * @{ + */ -/* GPT cache loading settings and cache status. */ BASE_StatusType HAL_GPT_SetBufferLoad(GPT_Handle *handle, GPT_SetOption bufferLoad); unsigned int HAL_GPT_GetBufferLoadStatus(GPT_Handle *handle); +/** + * @} + */ + +/** + * @defgroup GPT_API_Declaration + * @brief Output completion interrupt configuration for the GPT channel. + * @{ + */ -/* Output completion interrupt configuration for the GPT channel. */ BASE_StatusType HAL_GPT_SetOutFinishInt(GPT_Handle *handle, GPT_SetOption outFinishInt); +/** + * @} + */ + +/** + * @defgroup GPT_API_Declaration + * @brief GPT period interrupt configuration. + * @{ + */ -/* GPT period interrupt configuration. */ BASE_StatusType HAL_GPT_SetPeriodInt(GPT_Handle *handle, GPT_SetOption periodInt); +/** + * @} + */ + +/** + * @defgroup GPT_API_Declaration + * @brief GPT interrupt service and callback registration functions. + * @{ + */ -/* GPT interrupt service and callback registration functions */ void HAL_GPT_IrqOutFinishHandler(void *handle); void HAL_GPT_IrqPeriodHandler(void *handle); BASE_StatusType HAL_GPT_RegisterCallBack(GPT_Handle *gptHandle, GPT_CallBackFunType typeID, GPT_CallBackFunc pCallback); +/** + * @} + */ /** * @} diff --git a/src/drivers/gpt/gpt_v1/src/gpt.c b/src/drivers/gpt/gpt_v1/src/gpt.c index 0ad8dad388214382a995450c9c52fe45d75d2509..65026cdd53e34dc53662c8548d41cf5fa38d2379 100644 --- a/src/drivers/gpt/gpt_v1/src/gpt.c +++ b/src/drivers/gpt/gpt_v1/src/gpt.c @@ -104,7 +104,7 @@ BASE_StatusType HAL_GPT_Config(GPT_Handle *handle) GPT_PARAM_CHECK_WITH_RET(IsGptDiv(handle->clockDiv), BASE_STATUS_ERROR); GPT_PARAM_CHECK_WITH_RET(IsGptRefDot(handle->refA0.refdot), BASE_STATUS_ERROR); GPT_PARAM_CHECK_WITH_RET(IsGptRefDot(handle->refB0.refdot), BASE_STATUS_ERROR); - GPT_PARAM_CHECK_WITH_RET(handle->refA0.refdot <= handle->refB0.refdot, BASE_STATUS_ERROR); + GPT_PARAM_CHECK_WITH_RET(handle->refA0.refdot <= handle->period, BASE_STATUS_ERROR); GPT_PARAM_CHECK_WITH_RET(handle->refB0.refdot <= handle->period, BASE_STATUS_ERROR); GPT_PARAM_CHECK_WITH_RET(IsGptAction(handle->refA0.refAction), BASE_STATUS_ERROR); GPT_PARAM_CHECK_WITH_RET(IsGptAction(handle->refB0.refAction), BASE_STATUS_ERROR); diff --git a/src/drivers/i2c/common/inc/i2c.h b/src/drivers/i2c/common/inc/i2c.h index decd4f3b3e9b8587e9c1424bf393efe0436a5c0f..14bb5073df76295ed8ff1cd41704e9e398cf4d9b 100644 --- a/src/drivers/i2c/common/inc/i2c.h +++ b/src/drivers/i2c/common/inc/i2c.h @@ -111,6 +111,7 @@ typedef struct _I2C_Handle { typedef void (*I2C_CallbackFunType)(void *handle); /* Function Interface Definition -------------------------------------------------------*/ + BASE_StatusType HAL_I2C_Init(I2C_Handle *handle); BASE_StatusType HAL_I2C_Deinit(I2C_Handle *handle); BASE_StatusType HAL_I2C_RegisterCallback(I2C_Handle *handle, I2C_CallbackId callbackID, I2C_CallbackFunType pcallback); diff --git a/src/drivers/i2c/i2c_v3/inc/i2c_ex.h b/src/drivers/i2c/i2c_v3/inc/i2c_ex.h new file mode 100644 index 0000000000000000000000000000000000000000..5cc50448655c7ca7d2db0fd4765e876f7c224217 --- /dev/null +++ b/src/drivers/i2c/i2c_v3/inc/i2c_ex.h @@ -0,0 +1,57 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file i2c_ex.h + * @author MCU Driver Team + * @brief I2C module driver + * @details The header file contains the following declaration: + * + Setting the Special Function Configuration. + */ + +#ifndef McuMagicTag_I2C_EX_H +#define McuMagicTag_I2C_EX_H + +/* Includes ------------------------------------------------------------------*/ +#include "i2c.h" +/* Macro definitions ---------------------------------------------------------*/ +/** + * @addtogroup I2C_IP + * @{ + */ + +/** + * @defgroup I2C_EX_API_Declaration I2C HAL API EX + * @{ + */ +BASE_StatusType HAL_I2C_SetDataTransferSequenceEx(I2C_Handle *handle, I2C_DataTransferSequenceType sequence); +BASE_StatusType HAL_I2C_SetSclStretchModeEx(I2C_Handle *handle, I2C_ClockStretchType clkStretch); +BASE_StatusType HAL_I2C_SetSclLowTimeoutEx(I2C_Handle *handle, unsigned int sclLowTimeout); +BASE_StatusType HAL_I2C_SetBusFreeTimeEx(I2C_Handle *handle, unsigned int busFreeTime); +BASE_StatusType HAL_I2C_Set10BitSlaveEnableEx(I2C_Handle *handle); +BASE_StatusType HAL_I2C_SetDeviceIdAddressEnableEx(I2C_Handle *handle); +BASE_StatusType HAL_I2C_SetStartByteEnableEx(I2C_Handle *handle); +BASE_StatusType HAL_I2C_SetOwnAddressMaskEx(I2C_Handle *handle, unsigned int addrMask); +BASE_StatusType HAL_I2C_SetOwnXmbAddressMaskEx(I2C_Handle *handle, unsigned int addrMask); +/** + * @} + */ + +/** + * @} + */ + +#endif /* McuMagicTag_I2C_H */ \ No newline at end of file diff --git a/src/drivers/i2c/i2c_v3/inc/i2c_ip.h b/src/drivers/i2c/i2c_v3/inc/i2c_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..33447809639c77a6a5d24ffe3f86dfba340c0258 --- /dev/null +++ b/src/drivers/i2c/i2c_v3/inc/i2c_ip.h @@ -0,0 +1,1997 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file i2c_ip.h + * @author MCU Driver Team + * @brief I2C module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the I2C. + * + Extended Configuration Parameter Struct Definition. + * + Register definition structure. + * + Timing command enumeration. + * + Direct configuration layer interface. + * + Basic parameter configuration macro. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_I2C_IP_H +#define McuMagicTag_I2C_IP_H + +/* Includes ------------------------------------------------------------------*/ +#include "baseinc.h" + +/* Macro definitions --------------------------------------------------------- */ +#ifdef I2C_PARAM_CHECK +#define I2C_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM +#define I2C_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET +#define I2C_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else +#define I2C_ASSERT_PARAM(para) ((void)0U) +#define I2C_PARAM_CHECK_NO_RET(para) ((void)0U) +#define I2C_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) +#endif + +/** + * @addtogroup I2C + * @{ + */ + +/** + * @defgroup I2C_IP I2C_IP + * @brief I2C_IP: i2c_v3 + * @{ + */ + +#define I2C_IGNORE_NAK_ENABLE BASE_CFG_ENABLE /**< Ignore acknowledgment configuration enable. */ +#define I2C_IGNORE_NAK_DISABLE BASE_CFG_DISABLE /**< Ignore acknowledgment configuration disable. */ + +#define I2C_STANDARD_FREQ_TH 100000 /**< Standard mode,the frequency band is less than or equal to 100 kHz. */ + +#define I2C_INTR_RAW_ALL_ENABLE 0x00FFFFFFU /**< 1111111111111 */ +#define I2C_INTR_RAW_ALL_DISABLE 0x00000000U /**< 0000000000000 */ + +#define I2C_INTR_EN_ALL_ENABLE 0x00FFFFFFU /**< 1111111111111 */ +#define I2C_INTR_EN_ALL_DISABLE 0x00000000U /**< 0000000000000 */ + +#define I2C_ONCE_TRANS_MAX_NUM 0x400 + +#define I2C_SCL_HIGH_TIME_POS 16 +#define I2C_SCL_HIGH_TIME_MASK (0xFFFF << I2C_SCL_HIGH_TIME_POS) +#define I2C_SCL_LOW_TIME_POS 0 +#define I2C_SCL_LOW_TIME_MASK (0xFFFF << I2C_SCL_LOW_TIME_POS) + +#define I2C_SDA_HOLD_DURATION_POS 16 +#define I2C_SDA_HOLD_DURATION_MASK (0xFFFF << I2C_SDA_HOLD_DURATION_POS) + +#define I2C_TXFIFO_WDATA_POS 0 +#define I2C_TXFIFO_WDATA_MASK 0xFF +#define I2C_TXFIFO_CMD_POS 8 +#define I2C_TXFIFO_CMD_MASK (0xF << I2C_TXFIFO_CMD_POS) +#define I2C_FIFO_SIZE 0xF + +#define XMBUS_OWN_ADDRESS_MASK 0x3FF +/** + * @defgroup I2C_Param_Def I2C Parameters Definition. + * @brief Definition of I2C configuration parameters. + * @{ + */ +/* Typedef definitions -------------------------------------------------------*/ +/** + * @brief Address Mode Selection Enumeration Definition + */ +typedef enum { + I2C_7_BITS = 0x00000000U, + I2C_10_BITS = 0x00000001U +} I2C_AddressMode; + +/** + * @brief I2C DMA operation type enumeration definition + */ +typedef enum { + I2C_DMA_OP_NONE = 0x00000000U, + I2C_DMA_OP_READ = 0x00000001U, + I2C_DMA_OP_WRITE = 0x00000002U, + I2C_DMA_OP_WRITE_READ = 0x00000003U +} I2C_DmaOperationType; + +/** + * @brief I2C mode selection enumeration definition + */ +typedef enum { + I2C_MODE_SELECT_NONE = 0x00000000U, + I2C_MODE_SELECT_MASTER_ONLY = 0x00000001U, + I2C_MODE_SELECT_SLAVE_ONLY = 0x00000002U, + I2C_MODE_SELECT_MASTER_SLAVE = 0x00000003U +} I2C_ModeSelectType; + +/** + * @brief I2C operation timing enumeration definition + */ +typedef enum { + I2C_CMD_INT1 = 0x00000000U, + I2C_CMD_S = 0x00000001U, + I2C_CMD_M_TD_RACK_S_RD_TACK = 0x00000002U, + I2C_CMD_M_TD_RNACK_S_RD_TNACK = 0x00000003U, + I2C_CMD_M_TD_S_RD = 0x00000004U, + I2C_CMD_M_RD_TACK_S_TD_RACK = 0x00000005U, + I2C_CMD_M_RD_TNACK_S_TD_RNACK = 0x00000006U, + I2C_CMD_M_RD_S_TD = 0x00000007U, + I2C_CMD_M_TPEC_RACK_S_RPEC_TACK = 0x0000000AU, + I2C_CMD_M_TPEC_RNACK_S_RPEC_TNACK = 0x0000000BU, + I2C_CMD_M_RPEC_TACK_S_TPEC_RACK = 0x0000000DU, + I2C_CMD_M_RPEC_TNACK_S_TPEC_RNACK = 0x0000000EU, + I2C_CMD_P = 0x0000000FU +} I2C_CmdType; + +/** + * @brief I2C data transfer sequence enumeration definition. + */ +typedef enum { + I2C_MOST_BIT_FIRST = 0x00000000U, + I2C_LEAST_BIT_FIRST = 0x00000001U, +} I2C_DataTransferSequenceType; + +/** + * @brief I2C clock stretching enumeration definition. + */ +typedef enum { + I2C_CLOCK_STRETCH_ENABLE = 0x00000000U, + I2C_CLOCK_STRETCH_DISABLE = 0x00000001U, +} I2C_ClockStretchType; + +/** + * @brief Callback Function ID Enumeration Definition + */ +typedef enum { + I2C_MASTER_TX_COMPLETE_CB_ID = 0x00000000U, + I2C_MASTER_RX_COMPLETE_CB_ID = 0x00000001U, + I2C_SLAVE_TX_COMPLETE_CB_ID = 0x00000002U, + I2C_SLAVE_RX_COMPLETE_CB_ID = 0x00000003U, + I2C_ERROR_CB_ID = 0x00000004U, +} I2C_CallbackId; + +/** + * @brief I2C extend handle, configuring some special parameters. + */ +typedef struct { + unsigned int spikeFilterTime; /**< The SDA and SCL Glitch Filtering Configuration. */ + unsigned int sdaDelayTime; /**< The SDA delay sampling configuration. */ + unsigned int slaveOwnXmbAddressEnable; /**< Enable the I2C second own address function. */ + unsigned int slaveOwnXmbAddress; /**< The second own address as slave. */ + + volatile unsigned int deviceAddress; + volatile unsigned char sendAddrStatus; + volatile unsigned int txReadCmdCount; + volatile unsigned int dmaTransferSize; +} I2C_ExtendHandle; + +/** + * @brief User-defined callback function. + */ +typedef struct { + void (*TxCplCallback)(void* handle); /**< Sending completion callback function. */ + void (*RxCplCallback)(void* handle); /**< Receive completion callback function. */ + void (*ErrorCallback)(void* handle); /**< Error callback function. */ +} I2C_UserCallBack; + +/** + * @} + */ + +/** + * @defgroup I2C_Reg_Def I2C Register Definition + * @brief Description I2C register mapping structure + * @{ + */ + +/** + * @brief I2C mode configuration registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int mst_slv_function : 2 ; /* [1..0] */ + unsigned int lit_end : 1 ; /* [2] */ + unsigned int xmb_pec_en : 1 ; /* [3] */ + unsigned int rack_mode : 1 ; /* [4] */ + unsigned int scl_stretch_disable : 1 ; /* [5] */ + unsigned int slv_auto_rx : 1 ; /* [6] */ + unsigned int reserved_0 : 25 ; /* [31..8] */ + } BIT; +} I2C_MODE_REG; + +/** + * @brief I2C SCL high-level and low-level duration registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int scl_low_time : 16; /**< SCL Low Level Duration. */ + unsigned int scl_high_time : 16; /**< SCL High Level Duration. */ + } BIT; +} I2C_SCL_CFG_REG; + +/** + * @brief I2C SDA timing configuration registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int sda_delay_time : 4; /**< SDA delay sampling configuration. */ + unsigned int reserved0 : 12; + unsigned int sda_hold_time : 16; /**< SDA hold time configuration. */ + } BIT; +} I2C_SDA_CFG_REG; + +/** + * @brief I2C Slave Address Configuration registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int own_address : 10; /**< Own address as slave. */ + unsigned int reserved0 : 2; + unsigned int own_address_mask : 10; /**< Slave's own address mask. */ + unsigned int reserved1 : 2; + unsigned int i2c_general_call_en : 1; /**< Enable General Call Address Receiving, 0:disable, 1:enable. */ + unsigned int i2c_device_id_en : 1; /**< Enable the function of receiving device ID addresses, + 0:disable, 1:enable. */ + unsigned int i2c_start_byte_en : 1; /**< Enable START Byte Address Receiving, 0:disable, 1:enable. */ + unsigned int i2c_10bit_slave_en : 1; /**< Enable 10bit Slave Addressing Receiving, 0:disable, 1:enable. */ + unsigned int reserved2 : 4; + } BIT; +} I2C_OWN_ADDR_REG; + +/** + * @brief I2C SMBus PMBus Device Dedicated Address Configuration registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int xmb_address : 10; /**< I2C SMBus PMBus Device Dedicated Address. */ + unsigned int reserved0 : 2; + unsigned int xmb_address_mask : 10; /**< I2C SMBus PMBus Device Private Address Mask. */ + unsigned int xmb_address_en : 1; /**< I2C SMBus PMBus Device Dedicated Address Enable, + 0:disable, 1:enable. */ + unsigned int reserved1 : 1; + unsigned int smb_host_notify_en : 1; /**< Enable receiving SMBus Host Address, 0:disable, 1:enable. */ + unsigned int smb_alert_response_en : 1; /**< Enable receiving SMBus Alert Response Address, + 0:disable, 1:enable. */ + unsigned int smb_dev_default_en : 1; /**< Enable receiving SMBus Device Default Address, + 0:disable, 1:enable. */ + unsigned int reserved2 : 1; + unsigned int pmb_zone_read_en : 1; /**< Enable RX PMBus Zone Read Address, 0:disable, 1:enable. */ + unsigned int pmb_zone_write_en : 1; /**< Enable PMBus Zone Write Address Receiving, + 0:disable, 1:enable. */ + unsigned int reserved3 : 2; + } BIT; +} XMB_DEV_ADDR_REG; + +/** + * @brief Address received by the I2C slave, R/W bit registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int rx_rw : 1; /**< The address received by the slave. */ + unsigned int rx_addr : 10; /**< R/W bit received by the slave. */ + unsigned int reserved0 : 21; + } BIT; +} I2C_RX_ADDR_REG; + +/** + * @brief I2C TX FIFO registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int tx_fifo_wdata : 8; /**< The software writes the data to be sent, write only. */ + unsigned int mst_slv_cmd : 4; /**< Master Timing Command. */ + unsigned int reserved0 : 20; + } BIT; +} I2C_TX_FIFO_REG; + +/** + * @brief I2C RX FIFO registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int rx_fifo_rdata : 8; /**< The software writes the data to be receive, read only. */ + unsigned int reserved0 : 24; + } BIT; +} I2C_RX_FIFO_REG; + +/** + * @brief I2C TX threshold registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int tx_watermark : 4 ; /* [0] */ + unsigned int reserved_0 : 28 ; /* [31..1] */ + } BIT; +} I2C_TX_WATERMARK_REG; + +/** + * @brief I2C RX threshold registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int rx_watermark : 4 ; /* [0] */ + unsigned int reserved_0 : 28 ; /* [31..1] */ + } BIT; +} I2C_RX_WATERMARK_REG; + +/** + * @brief I2C control 1 registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int mst_start : 1; /**< Master startup control, 0:disable, 1:enable. */ + unsigned int reserved0 : 1; + unsigned int rst_rx_fifo : 1; /**< Resetting the RX FIFO, 0:clearing completed, 1:clearing in progress. */ + unsigned int rst_tx_fifo : 1; /**< Resetting the TX FIFO, 0:clearing completed, 1:clearing in progress. */ + unsigned int reserved1 : 4; + unsigned int dma_operation : 2; /**< DMA operation control. */ + unsigned int dma_rx_lsreq_en : 1; /**< Flow control enable for the RX peripheral of the DMA I2C module, + 0:disable, 1:enable. */ + unsigned int reserved2 : 21; + } BIT; +} I2C_CTRL1_REG; + +/** + * @brief I2C control 2 registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int force_sda : 1; /**< Forcibly sets the value of an I2C pin, 0:set 0, 1:set 1. */ + unsigned int reserved0 : 3; + unsigned int force_scl : 1; /**< Forcibly sets the value of an I2C pin, 0:set 0, 1:set 1. */ + unsigned int reserved1 : 3; + unsigned int gpio_mode : 1; /**< The I2C pin is used as a GPIO pin. */ + unsigned int reserved2 : 3; + unsigned int smb_alert_n_oe_n : 1; /**< SMBus SMBALERT# Output Value, + 0:Low-level Open-Drain output, + 1:Open-Drain output high impedance. */ + unsigned int smb_alert_n_in : 1; /**< SMBus SMBALERT# Input value, + 0:Low level input, 1:High level input . */ + unsigned int reserved3 : 2; + unsigned int smb_suspend_n_oe_n : 1; /**< SMBus SMBSUS# is output, 0:push-pull output, + 1:no output, high impedance. */ + unsigned int smb_suspend_n_out : 1; /**< SMBus SMBSUS# Output Value, + 0:low level output, 1:high level output. */ + unsigned int smb_suspend_n_in : 1; /**< SMBus SMBSUS# Input Value, + 0:low level output, 1:high level output. */ + unsigned int reserved4 : 13; + } BIT; +} I2C_CTRL2_REG; + +/** + * @brief I2C FIFO status registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int rx_fifo_vld_num : 5; /**< Number of valid values in the RX FIFO. */ + unsigned int reserved0 : 3; + unsigned int tx_fifo_vld_num : 5; /**< Number of valid values in the TX FIFO. */ + unsigned int reserved1 : 3; + unsigned int reserved2 : 16; + } BIT; +} I2C_FIFO_STAT_REG; + +/** + * @brief I2C state machine status registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int mst_txrx_state : 3 ; /* [2..0] */ + unsigned int mst_txrx_mode : 2 ; /* [4..3] */ + unsigned int mst_txs_mode : 1 ; /* [5] */ + unsigned int mst_fsm_state : 4 ; /* [9..6] */ + unsigned int mst_cmd_exe : 4 ; /* [13..10] */ + unsigned int mst_busy : 1 ; /* [14] */ + unsigned int reserved_0 : 1 ; /* [15] */ + unsigned int slv_txrx_state : 1 ; /* [16] */ + unsigned int slv_fsm_state : 4 ; /* [20..17] */ + unsigned int slv_cmd_exe : 4 ; /* [24..21] */ + unsigned int slv_busy : 1 ; /* [25] */ + unsigned int reserved_1 : 4 ; /* [29..26] */ + unsigned int i2c_bus_free : 1 ; /* [30] */ + unsigned int reserved_2 : 1 ; /* [31] */ + } BIT; +} I2C_FSM_STAT_REG; + +/** + * @brief I2C raw interrupt registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int mst_rx_ack_unmatch_raw : 1 ; /* [0] */ + unsigned int rx_fifo_not_empty_raw : 1 ; /* [1] */ + unsigned int rx_ge_watermark_raw : 1 ; /* [2] */ + unsigned int rx_fifo_full_raw : 1 ; /* [3] */ + unsigned int tx_le_watermark_raw : 1 ; /* [4] */ + unsigned int tx_fifo_empty_raw : 1 ; /* [5] */ + unsigned int tx_fifo_not_full_raw : 1 ; /* [6] */ + unsigned int reserved_0 : 1 ; /* [7] */ + unsigned int reserved_1 : 1 ; /* [8] */ + unsigned int stop_det_raw : 1 ; /* [9] */ + unsigned int start_det_raw : 1 ; /* [10] */ + unsigned int mst_arb_lost_raw : 1 ; /* [11] */ + unsigned int mst_cmd_done_raw : 1 ; /* [12] */ + unsigned int scl_low_timeout_raw : 1 ; /* [13] */ + unsigned int smb_alert_raw : 1 ; /* [14] */ + unsigned int smb_suspend_raw : 1 ; /* [15] */ + unsigned int mst_cmd_int1_raw : 1 ; /* [16] */ + unsigned int slv_cmd_int1_raw : 1 ; /* [17] */ + unsigned int mst_pec_check_fail_raw : 1 ; /* [18] */ + unsigned int slv_pec_check_fail_raw : 1 ; /* [19] */ + unsigned int slv_rx_ack_unmatch_raw : 1 ; /* [20] */ + unsigned int slv_addr_match_raw : 1 ; /* [21] */ + unsigned int slv_arb_lost_raw : 1 ; /* [22] */ + unsigned int reserved_2 : 9 ; /* [31..24] */ + } BIT; +} I2C_INTR_RAW_REG; + +/** + * @brief I2C interrupt enable registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int mst_rx_ack_unmatch_en : 1 ; /* [0] */ + unsigned int rx_fifo_not_empty_en : 1 ; /* [1] */ + unsigned int rx_ge_watermark_en : 1 ; /* [2] */ + unsigned int rx_fifo_full_en : 1 ; /* [3] */ + unsigned int tx_le_watermark_en : 1 ; /* [4] */ + unsigned int tx_fifo_empty_en : 1 ; /* [5] */ + unsigned int tx_fifo_not_full_en : 1 ; /* [6] */ + unsigned int reserved_0 : 1 ; /* [7] */ + unsigned int reserved_1 : 1 ; /* [8] */ + unsigned int stop_det_en : 1 ; /* [9] */ + unsigned int start_det_en : 1 ; /* [10] */ + unsigned int mst_arb_lost_en : 1 ; /* [11] */ + unsigned int mst_cmd_done_en : 1 ; /* [12] */ + unsigned int scl_low_timeout_en : 1 ; /* [13] */ + unsigned int smb_alert_en : 1 ; /* [14] */ + unsigned int smb_suspend_en : 1 ; /* [15] */ + unsigned int mst_cmd_int1_en : 1 ; /* [16] */ + unsigned int slv_cmd_int1_en : 1 ; /* [17] */ + unsigned int mst_pec_check_fail_en : 1 ; /* [18] */ + unsigned int slv_pec_check_fail_en : 1 ; /* [19] */ + unsigned int slv_rx_ack_unmatch_en : 1 ; /* [20] */ + unsigned int slv_addr_match_en : 1 ; /* [21] */ + unsigned int slv_arb_lost_en : 1 ; /* [22] */ + unsigned int reserved_2 : 9 ; /* [31..24] */ + } BIT; +} I2C_INTR_EN_REG; + +/** + * @brief I2C interrupt status registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int mst_rx_ack_unmatch_int : 1 ; /* [0] */ + unsigned int rx_fifo_not_empty_int : 1 ; /* [1] */ + unsigned int rx_ge_watermark_int : 1 ; /* [2] */ + unsigned int rx_fifo_full_int : 1 ; /* [3] */ + unsigned int tx_le_watermark_int : 1 ; /* [4] */ + unsigned int tx_fifo_empty_int : 1 ; /* [5] */ + unsigned int tx_fifo_not_full_int : 1 ; /* [6] */ + unsigned int reserved_0 : 1 ; /* [7] */ + unsigned int reserved_1 : 1 ; /* [8] */ + unsigned int stop_det_int : 1 ; /* [9] */ + unsigned int start_det_int : 1 ; /* [10] */ + unsigned int mst_arb_lost_int : 1 ; /* [11] */ + unsigned int mst_cmd_done_int : 1 ; /* [12] */ + unsigned int scl_low_timeout_int : 1 ; /* [13] */ + unsigned int smb_alert_int : 1 ; /* [14] */ + unsigned int smb_suspend_int : 1 ; /* [15] */ + unsigned int mst_cmd_int1 : 1 ; /* [16] */ + unsigned int slv_cmd_int1 : 1 ; /* [17] */ + unsigned int mst_pec_check_fail_int : 1 ; /* [18] */ + unsigned int slv_pec_check_fail_int : 1 ; /* [19] */ + unsigned int slv_rx_ack_unmatch_int : 1 ; /* [20] */ + unsigned int slv_addr_match_int : 1 ; /* [21] */ + unsigned int slv_arb_lost_int : 1 ; /* [22] */ + unsigned int reserved_2 : 9 ; /* [31..24] */ + } BIT; +} I2C_INTR_STAT_REG; + +/** + * @brief I2C version number registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int version : 32; /**< I2C controller version. */ + } BIT; +} I2C_VERSION_REG; + +/** + * @brief I2C SCL timeout threshold registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int scl_low_timeout : 23; /**< SCL low-level timeout configuration. */ + unsigned int reserved0 : 9; + } BIT; +} I2C_SCL_TIMEOUT_REG; + +/** + * @brief I2C bus idle threshold registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int bus_free_time : 16; /**< Bus Idle Threshold. */ + unsigned int reserved0 : 16; + } BIT; +} I2C_BUS_FREE_REG; + +/** + * @brief I2C SDA and SCL filtering configuration registers union structure definition. + */ +typedef union { + unsigned int reg; + struct { + unsigned int spike_filter_time : 4; /**< SDA and SCL Glitch Filtering Configuration. */ + unsigned int reserved0 : 28; + } BIT; +} I2C_FILTER_REG; + +/* Define the union U_XMB_SCL_TIMEOUT */ +typedef union { + unsigned int reg; + struct { + unsigned int scl_low_mext : 12 ; /* [11..0] */ + unsigned int reserved_0 : 3 ; /* [14..12] */ + unsigned int scl_low_mext_en : 1 ; /* [15] */ + unsigned int scl_low_sext : 12 ; /* [27..16] */ + unsigned int reserved_1 : 3 ; /* [30..28] */ + unsigned int scl_low_sext_en : 1 ; /* [31] */ + } BIT; +} XMB_SCL_TIMEOUT_REG; + +/* Define the union U_I2C_CFG_ECO */ +typedef union { + unsigned int reg; + struct { + unsigned int i2c_cfg_eco : 4 ; /* [3..0] */ + unsigned int reserved_0 : 28 ; /* [31..4] */ + } BIT; +} I2C_CFG_ECO_REG; + +/** + * @brief Define the I2C register structure + */ +typedef struct { + I2C_MODE_REG I2C_MODE; /**< I2C mode configuration register, Offset address: 0x0000U. */ + I2C_SCL_CFG_REG I2C_SCL_CFG; /**< I2C SCL high/low level time register, Offset address: 0x0004U. */ + I2C_SDA_CFG_REG I2C_SDA_CFG; /**< I2C SDA timing configuration register, Offset address: 0x0008U. */ + I2C_OWN_ADDR_REG I2C_OWN_ADDR; /**< I2C slave address configuration register, + Offset address: 0x000CU. */ + XMB_DEV_ADDR_REG XMB_DEV_ADDR; /**< I2C SMBus PMBus Device Dedicated Address Configuration register, + Offset address: 0x0010U. */ + unsigned char space0[4]; + I2C_RX_ADDR_REG I2C_RX_ADDR; /**< Address received by the I2C slave, R/W bit register, + Offset address: 0x0018U. */ + unsigned char space1[4]; + I2C_TX_FIFO_REG I2C_TX_FIFO; /**< I2C TX FIFO register, Offset address: 0x0020U. */ + I2C_RX_FIFO_REG I2C_RX_FIFO; /**< I2C_RX_FIFO register, Offset address: 0x0024U. */ + unsigned char space2[160]; + I2C_TX_WATERMARK_REG I2C_TX_WATERMARK; /**< I2C TX threshold register, Offset address: 0x00C8U. */ + I2C_RX_WATERMARK_REG I2C_RX_WATERMARK; /**< I2C RX threshold register, Offset address: 0x00CCU. */ + I2C_CTRL1_REG I2C_CTRL1; /**< I2C control register 1, Offset address: 0x00D0U. */ + I2C_CTRL2_REG I2C_CTRL2; /**< I2C control register 2, Offset address: 0x00D4U. */ + I2C_FIFO_STAT_REG I2C_FIFO_STAT; /**< I2C FIFO status register, Offset address: 0x00D8U. */ + I2C_FSM_STAT_REG I2C_FSM_STAT; /**< I2C state machine status register, Offset address: 0x00DCU. */ + I2C_INTR_RAW_REG I2C_INTR_RAW; /**< I2C raw interrupt register, Offset address: 0x00E0U. */ + I2C_INTR_EN_REG I2C_INTR_EN; /**< I2C interrupt enable register, Offset address: 0x00E4U. */ + I2C_INTR_STAT_REG I2C_INTR_STAT; /**< I2C interrupt status register, Offset address: 0x00E8U. */ + unsigned char space3[20]; + I2C_VERSION_REG I2C_VERSION; /**< I2C version number register, Offset address: 0x0100U. */ + I2C_SCL_TIMEOUT_REG I2C_SCL_TIMEOUT; /**< I2C SCL timeout threshold register, Offset address: 0x0104U. */ + I2C_BUS_FREE_REG I2C_BUS_FREE; /**< I2C bus idle threshold register, Offset address: 0x0108U. */ + I2C_FILTER_REG I2C_FILTER; /**< I2C SDA and SCL filtering configuration register, + Offset address: 0x010CU. */ + XMB_SCL_TIMEOUT_REG XMB_SCL_TIMEOUT; /* 0x110 */ + unsigned int reserved_4[58]; /* 0x114~0x1f8 */ + I2C_CFG_ECO_REG I2C_CFG_ECO; /* 0x1fc */ +} volatile I2C_RegStruct; +/** + * @} + */ +/* Parameter check definition-------------------------------------------*/ +/** + * @brief Check I2C function mode selection. + * @param functionMode I2C function mode type. + * @retval true + * @retval false + */ +static inline bool IsI2cFunctionMode(I2C_ModeSelectType functionMode) +{ + return (functionMode == I2C_MODE_SELECT_NONE || + functionMode == I2C_MODE_SELECT_MASTER_ONLY || + functionMode == I2C_MODE_SELECT_SLAVE_ONLY || + functionMode == I2C_MODE_SELECT_MASTER_SLAVE); +} + +/** + * @brief Check address mode selection. + * @param addrMode I2C instance + * @retval true + * @retval false + */ +static inline bool IsI2cAddressMode(I2C_AddressMode addrMode) +{ + return (addrMode == I2C_7_BITS || + addrMode == I2C_10_BITS); +} + +/** + * @brief Check i2c sda hold time. + * @param sdaHoldTime I2C instance + * @retval true + * @retval false + */ +static inline bool IsI2cSdaHoldTime(unsigned int sdaHoldTime) +{ + return (sdaHoldTime <= 0xFFFF); /* SdaHoldTime value is 0 to 0xFFFF */ +} + +/** + * @brief Check i2c scl hold time. + * @param sclHoldTime I2C instance + * @retval true + * @retval false + */ +static inline bool IsI2cSclHoldTime(unsigned int sclHoldTime) +{ + return (sclHoldTime <= 0xFFFF); /* sclHoldTime value is 0 to 0xFFFF */ +} + +/** + * @brief Check I2C general call mode. + * @param generalCallMode I2C general call mode. + * @retval true + * @retval false + */ +static inline bool IsI2cGeneralCallMode(unsigned int generalCallMode) +{ + return (generalCallMode == BASE_CFG_ENABLE || + generalCallMode == BASE_CFG_DISABLE); +} + +/** + * @brief Check i2c own address. + * @param ownAddress I2C own address. + * @retval true + * @retval false + */ +static inline bool IsI2cOwnAddressOrMask(unsigned int ownAddress) +{ + return (ownAddress <= XMBUS_OWN_ADDRESS_MASK); /* Own address value is 0 to 0x3FF */ +} + +/** + * @brief Check XMBus address. + * @param xmbusAddress XMBus address. + * @retval true + * @retval false + */ +static inline bool IsXMBusAddressOrMask(unsigned int xmbusAddress) +{ + return (xmbusAddress <= XMBUS_OWN_ADDRESS_MASK); /* XMBus address value is 0 to 0x3FF */ +} + +/** + * @brief Check XMBus address Enable. + * @param xmbusAddress XMBus address. + * @retval true + * @retval false + */ +static inline bool IsXMBusAddressEnable(unsigned int slaveOwnXmbAddressEnable) +{ + return (slaveOwnXmbAddressEnable == BASE_CFG_ENABLE || slaveOwnXmbAddressEnable == BASE_CFG_DISABLE); +} + +/** + * @brief Check i2c SDA and SCL Glitch Filtering Time Configuration. + * @param spikeFilterTime I2C SDA and SCL Glitch Filtering Time. + * @retval true + * @retval false + */ +static inline bool IsI2cSpikeFilterTime(unsigned int spikeFilterTime) +{ + return (spikeFilterTime <= 0xF); /* The spikeFilterTime value is 0 to 0xF */ +} + + +/** + * @brief Check i2c freq. + * @param freq I2C freq + * @retval true + * @retval false + */ +static inline bool IsI2cFreq(unsigned int freq) +{ + return (freq > 0); +} + +/** + * @brief Check i2c ignore ack flag. + * @param ignoreAckFlag I2C ignore ack flag. + * @retval true + * @retval false + */ +static inline bool IsI2cIgnoreAckFlag(unsigned int ignoreAckFlag) +{ + return (ignoreAckFlag == I2C_IGNORE_NAK_ENABLE || + ignoreAckFlag == I2C_IGNORE_NAK_DISABLE); +} + +/** + * @brief Check i2c tx water mark. + * @param txWaterMark I2C tx water mark. + * @retval true + * @retval false + */ +static inline bool IsI2cTxWaterMark(unsigned int txWaterMark) +{ + return (txWaterMark <= I2C_FIFO_SIZE); /* The txWaterMark value is 0 to 0xf */ +} + +/** + * @brief Check i2c rx water mark. + * @param rxWaterMark I2C rx water mark. + * @retval true + * @retval false + */ +static inline bool IsI2cRxWaterMark(unsigned int rxWaterMark) +{ + return (rxWaterMark <= I2C_FIFO_SIZE); /* The rxWaterMark value is 0 to 0xf */ +} + +/** + * @brief Check i2c DMA Operation type. + * @param mode I2C DMA Operation type. + * @retval true + * @retval false + */ +static inline bool IsI2CDmaOperationType(I2C_DmaOperationType mode) +{ + return (mode == I2C_DMA_OP_NONE || + mode == I2C_DMA_OP_READ || + mode == I2C_DMA_OP_WRITE || + mode == I2C_DMA_OP_WRITE_READ); +} + +/** + * @brief Check i2c set one bit value. + * @param value value is set. + * @retval true + * @retval false + */ +static inline bool IsI2cSetOneBitValue(unsigned int value) +{ + return (value == BASE_CFG_UNSET || value == BASE_CFG_SET); +} + +/** + * @brief Check i2c scl timeout value. + * @param time the value of scl time out. + * @retval true + * @retval false + */ +static inline bool IsI2cSclTimoutValue(unsigned int time) +{ + return (time <= 0x7FFFFF); /* The i2c scl timeout max value is 0x7FFFFF. */ +} + +/** + * @brief Check i2c bus free time value. + * @param time the value of bus free time. + * @retval true + * @retval false + */ +static inline bool IsI2cBusFreeTimeValue(unsigned int time) +{ + return (time <= 0xFFFF); /* The i2c bus free time max value is 0xFFFF. */ +} + +/** + * @brief Check i2c data transfer sequence value. + * @param arg data transfer sequence value. + * @retval true + * @retval false + */ +static inline bool IsI2cDataTransferSequence(I2C_DataTransferSequenceType arg) +{ + return (arg == I2C_MOST_BIT_FIRST || arg == I2C_LEAST_BIT_FIRST); +} + +/** + * @brief Check i2c clock stretching enumeration value. + * @param arg clock stretching enumeration value. + * @retval true + * @retval false + */ +static inline bool IsI2cClockStretchValue(I2C_ClockStretchType arg) +{ + return (arg == I2C_CLOCK_STRETCH_ENABLE || arg == I2C_CLOCK_STRETCH_DISABLE); +} + +/** + * @brief Check i2c SCL low-level timeout value. + * @param sclLowTimeout SCL low-level timeout value. + * @retval true + * @retval false + */ +static inline bool IsI2cSclLowTimeout(unsigned int sclLowTimeout) +{ + return (sclLowTimeout <= 0x7FFFFF); /* The SCL low-level timeout upper limit is 0x7FFFFF. */ +} + +/** + * @brief Check i2c bus idle threshold value. + * @param busFreeTime bus idle threshold value. + * @retval true + * @retval false + */ +static inline bool IsI2cBusFreeTime(unsigned int busFreeTime) +{ + return (busFreeTime <= 0xFFFF); /* The SCL bus idle threshold is 0xFFFF. */ +} + +/** + * @brief Check i2c Sda delay time. + * @param busFreeTime bus idle threshold value. + * @retval true + * @retval false + */ +static inline bool IsI2cSdaDelayTime(unsigned int sdaDelayTime) +{ + return (sdaDelayTime <= 0x0F); /* The Sda delay time threshold is 0x0F. */ +} + +/** + * @brief DCL I2C mode function set. + * @param i2cx I2C register base address. + * @param function I2C mode function + * @retval None. + */ +static inline void DCL_I2C_SetFunction(I2C_RegStruct *i2cx, unsigned int function) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_ASSERT_PARAM(IsI2cFunctionMode(function)); + i2cx->I2C_MODE.BIT.mst_slv_function = function; +} + +/** + * @brief DCL I2C mode function get. + * @param i2cx I2C register base address. + * @retval I2C mode function. + */ +static inline unsigned int DCL_I2C_GetFunction(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_MODE.BIT.mst_slv_function; +} + +/** + * @brief DCL I2C endian set. + * @param i2cx I2C register base address. + * @param endian I2C data transfer sequence. + * @retval None. + */ +static inline void DCL_I2C_SetEndian(I2C_RegStruct *i2cx, I2C_DataTransferSequenceType endian) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cDataTransferSequence(endian)); + i2cx->I2C_MODE.BIT.lit_end = endian; +} + +/** + * @brief DCL I2C endian get. + * @param i2cx I2C register base address. + * @retval I2C endian. + */ +static inline unsigned int DCL_I2C_GetEndian(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_MODE.BIT.lit_end; +} + +/** + * @brief DCL I2C enable PEC. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_PECEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_ENABLE; +} + +/** + * @brief DCL I2C disable PEC. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_PECDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_DISABLE; +} + +/** + * @brief DCL I2C PEC status get. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline unsigned int DCL_I2C_GetPECStatus(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_MODE.BIT.xmb_pec_en; +} + +/** + * @brief DCL I2C enable ignore rack mode. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_IgnoreRackModeEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_MODE.BIT.rack_mode = I2C_IGNORE_NAK_ENABLE; +} + +/** + * @brief DCL I2C disable ignore rack mode. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_IgnoreRackModeDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_MODE.BIT.rack_mode = I2C_IGNORE_NAK_DISABLE; +} + +/** + * @brief DCL I2C enable scl stretch function. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SclStrechEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_MODE.BIT.scl_stretch_disable = BASE_CFG_DISABLE; +} + +/** + * @brief DCL I2C disable scl stretch function. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SclStrechDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_MODE.BIT.scl_stretch_disable = BASE_CFG_ENABLE; +} + +/** + * @brief DCL Configuring i2c SDA Hold Time. + * @param i2cx I2C register base address. + * @param sdaHoldTime Sda hold time. + * @retval None. + */ +static inline void DCL_I2C_SetSdaHoldDuration(I2C_RegStruct *i2cx, unsigned short sdaHoldTime) +{ + unsigned int glbReg; + unsigned int temp; + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + /* Read the entire register and write it back. */ + temp = ((unsigned int)sdaHoldTime) << I2C_SDA_HOLD_DURATION_POS; + glbReg = (i2cx->I2C_SDA_CFG.reg & 0xF) | temp; + i2cx->I2C_SDA_CFG.reg = glbReg; +} + +/** + * @brief Get DCL Configuring i2c SDA Hold Time. + * @param i2cx I2C register base address. + * @retval Sda hold time, 0-65535. + */ +static inline int DCL_I2C_GetSdaHoldDuration(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return ((i2cx->I2C_SDA_CFG.reg >> I2C_SDA_HOLD_DURATION_POS) & 0xFFFF); /* The mask of sda hold time is 0xFFFF. */ +} + +/** + * @brief DCL Configuring i2c SDA delay Time. + * @param i2cx I2C register base address. + * @param sdaDelayTime The value of sda delay time. + * @retval None. + */ +static inline void DCL_I2C_SetSdaDelayTime(I2C_RegStruct *i2cx, unsigned int sdaDelayTime) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cSdaDelayTime(sdaDelayTime)); + i2cx->I2C_SDA_CFG.BIT.sda_delay_time = sdaDelayTime; +} + +/** + * @brief DCL Get i2c SDA delay Time. + * @param i2cx I2C register base address. + * @retval The value of sda delay time. + */ +static inline unsigned int DCL_I2C_GetSdaDelayTime(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_SDA_CFG.BIT.sda_delay_time; +} + +/** + * @brief DCL Configuring i2c SCL High Hold Time. + * @param i2cx I2C register base address. + * @param sclHighTime Scl high hold time. + * @retval None. + */ +static inline void DCL_I2C_SetHighDuration(I2C_RegStruct *i2cx, unsigned short sclHighTime) +{ + unsigned int tempReg; + unsigned int temp; + + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + tempReg = i2cx->I2C_SCL_CFG.reg; + /* Read the entire register and write it back. */ + temp = ((unsigned int)sclHighTime) << I2C_SCL_HIGH_TIME_POS; + tempReg = (i2cx->I2C_SCL_CFG.reg & I2C_SCL_LOW_TIME_MASK) | temp; + i2cx->I2C_SCL_CFG.reg = tempReg; +} + +/** + * @brief DCL get i2c SCL High Hold Time. + * @param i2cx I2C register base address. + * @retval Scl high hold time,0-65535. + */ +static inline int DCL_I2C_GetHighDuration(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return ((i2cx->I2C_SCL_CFG.reg >> I2C_SCL_HIGH_TIME_POS) & 0xFFFF); /* The mask of scl high hold time is 0xFFFF. */ +} + +/** + * @brief DCL Configuring i2c SCL low hold Time and high hold time. + * @param i2cx I2C register base address. + * @param sclLowTime The value of SCL low hold Time. + * @param sclHighTime The value of SCL high hold Time. + * @retval None. + */ +static inline void DCL_I2C_SetSclTimeDuration(I2C_RegStruct *i2cx, unsigned short sclLowTime, + unsigned short sclHighTime) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cSclHoldTime(sclLowTime)); + I2C_PARAM_CHECK_NO_RET(IsI2cSclHoldTime(sclHighTime)); + /* Configure the I2C Communication Clock Rate. */ + i2cx->I2C_SCL_CFG.reg = ((sclLowTime & I2C_SCL_LOW_TIME_MASK) | + ((sclHighTime << I2C_SCL_HIGH_TIME_POS) & I2C_SCL_HIGH_TIME_MASK)); +} + +/** + * @brief DCL Get i2c SCL low hold Time. + * @param i2cx I2C register base address. + * @retval Scl low hold time, 0-65535. + */ +static inline int DCL_I2C_GetSclLowTime(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_SCL_CFG.BIT.scl_low_time; +} + +/** + * @brief DCL Get i2c SCL high hold Time. + * @param i2cx I2C register base address. + * @retval Scl high hold time, 0-65535. + */ +static inline int DCL_I2C_GetSclHighTime(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return ((i2cx->I2C_SCL_CFG.reg & I2C_SCL_HIGH_TIME_MASK) >> I2C_SCL_HIGH_TIME_POS); +} + +/** + * @brief DCL Set I2C owner Address. + * @param i2cx I2C register base address. + * @param ownAddr Slave address + * @retval None. + */ +static inline void DCL_I2C_SetOwnAddr(I2C_RegStruct *i2cx, unsigned int ownAddr) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_ASSERT_PARAM(IsI2cOwnAddressOrMask(ownAddr)); + i2cx->I2C_OWN_ADDR.BIT.own_address = ownAddr; +} + +/** + * @brief DCL Get I2C owner Address. + * @param i2cx I2C register base address. + * @retval I2C owner address. + */ +static inline unsigned int DCL_I2C_GetOwnAddr(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_OWN_ADDR.BIT.own_address; +} + +/** + * @brief DCL Set I2C owner address mask. + * @param i2cx I2C register base address. + * @param ownAddrMask The maske of I2C slave address. + * @retval None. + */ +static inline void DCL_I2C_SetOwnMaskAddr(I2C_RegStruct *i2cx, unsigned int ownAddrMask) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cOwnAddressOrMask(ownAddrMask)); + i2cx->I2C_OWN_ADDR.BIT.own_address_mask = ownAddrMask; +} + +/** + * @brief DCL Set I2C owner address mask. + * @param i2cx I2C register base address. + * @retval I2C owner address mask. + */ +static inline unsigned int DCL_I2C_GetOwnMaskAddr(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_OWN_ADDR.BIT.own_address_mask; +} + +/** + * @brief DCL Set I2C 10bit slave enable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_10BitSlaveEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_OWN_ADDR.BIT.i2c_10bit_slave_en = BASE_CFG_ENABLE; +} + +/** + * @brief DCL Set I2C 10bit slave disable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_10BitSlaveDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_OWN_ADDR.BIT.i2c_10bit_slave_en = BASE_CFG_DISABLE; +} + +/** + * @brief DCL Set XMBus Address. + * @param i2cx I2C register base address. + * @param xmbusAddr The address is used for I2C, SMBus and PMBus Device. + * @retval None. + */ +static inline void DCL_I2C_SetXMBusAddr(I2C_RegStruct *i2cx, unsigned int xmbusAddr) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsXMBusAddressOrMask(xmbusAddr)); + i2cx->XMB_DEV_ADDR.BIT.xmb_address = xmbusAddr; +} + +/** + * @brief DCL Get XMBus Address. + * @param i2cx I2C register base address. + * @retval The address of I2C, SMBus and PMBus Device. + */ +static inline unsigned int DCL_I2C_GetXMBusAddr(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->XMB_DEV_ADDR.BIT.xmb_address; +} + +/** + * @brief DCL Set xmbus address mask. + * @param i2cx I2C register base address. + * @param xmbusAddrMask The maske of xmbus device address. + * @retval None. + */ +static inline void DCL_I2C_SetXMBusMaskAddr(I2C_RegStruct *i2cx, unsigned int xmbusAddrMask) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_ASSERT_PARAM(IsXMBusAddressOrMask(xmbusAddrMask)); + i2cx->XMB_DEV_ADDR.BIT.xmb_address_mask = xmbusAddrMask; +} + +/** + * @brief DCL Get XMBus device address mask. + * @param i2cx I2C register base address. + * @retval XMBus device address mask. + */ +static inline unsigned int DCL_I2C_GetXMBusMaskAddr(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->XMB_DEV_ADDR.BIT.xmb_address_mask; +} + +/** + * @brief DCL Set XMBus address enable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_XMBusAddressEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.xmb_address_en = BASE_CFG_ENABLE; +} + +/** + * @brief DCL Set XMBus address disable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_XMBusAddressDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.xmb_address_en = BASE_CFG_DISABLE; +} + +/** + * @brief DCL Set SMBus host notify enable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SMBusHostNotifyEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.smb_host_notify_en = BASE_CFG_ENABLE; +} + +/** + * @brief DCL Set SMBus host notify disable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SMBusHostNotifyDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.smb_host_notify_en = BASE_CFG_DISABLE; +} + +/** + * @brief DCL Set SMBus alert response enable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SMBusAlertResponseEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.smb_alert_response_en = BASE_CFG_ENABLE; +} + +/** + * @brief DCL Set SMBus SMBus alert response disable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SMBusAlertResponseDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.smb_alert_response_en = BASE_CFG_DISABLE; +} + +/** + * @brief DCL Set Receive SMBus device default address enable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SMBusDevDefaultEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.smb_dev_default_en = BASE_CFG_ENABLE; +} + +/** + * @brief DCL Set Receive SMBus device default address disable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SMBusDevDefaultDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.smb_dev_default_en = BASE_CFG_DISABLE; +} + +/** + * @brief DCL Set Receive PMBus Zone Read Address Enable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_PMBusZoneReadEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.pmb_zone_read_en = BASE_CFG_ENABLE; +} + +/** + * @brief DCL Set Receive PMBus Zone Read Address Disable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_PMBusZoneReadDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.pmb_zone_read_en = BASE_CFG_DISABLE; +} + +/** + * @brief DCL Set Receive PMBus Zone Write Address Enable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_PMBusZoneWriteEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.pmb_zone_write_en = BASE_CFG_ENABLE; +} + +/** + * @brief DCL Set Receive PMBus Zone Write Address Disable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_PMBusZoneWriteDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->XMB_DEV_ADDR.BIT.pmb_zone_write_en = BASE_CFG_DISABLE; +} + +/** + * @brief DCL Set I2C start byte enable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_StartByteEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_OWN_ADDR.BIT.i2c_start_byte_en = BASE_CFG_ENABLE; +} + +/** + * @brief DCL Set I2C start byte disable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_StartByteDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_OWN_ADDR.BIT.i2c_start_byte_en = BASE_CFG_DISABLE; +} + +/** + * @brief DCL Set I2C device id enable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_DeviceIDEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_OWN_ADDR.BIT.i2c_device_id_en = BASE_CFG_ENABLE; +} + +/** + * @brief DCL Set I2C device id disable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_DeviceIDDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_OWN_ADDR.BIT.i2c_device_id_en = BASE_CFG_DISABLE; +} + +/** + * @brief DCL Set I2C general call enable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_GeneralCallEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_OWN_ADDR.BIT.i2c_general_call_en = BASE_CFG_ENABLE; +} + +/** + * @brief DCL Set I2C general call disable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_GeneralCallDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_OWN_ADDR.BIT.i2c_general_call_en = BASE_CFG_DISABLE; +} + +/** + * @brief Get the I2C RX received R/W Bits. + * @param i2cx I2C register base address. + * @retval The value of I2C RX received R/W Bits, 0: write, 1: read. + */ +static inline unsigned int DCL_I2C_GetRxReadOrWrite(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_RX_ADDR.BIT.rx_rw; +} + +/** + * @brief Get the I2C RX address. + * @param i2cx I2C register base address. + * @retval RX address. + */ +static inline unsigned int DCL_I2C_GetRxAddr(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_RX_ADDR.reg & 0x3FF; /* The mask of RX address is 0x3FF. */ +} + +/** + * @brief Set the I2C TX FIFO. + * @param i2cx I2C register base address. + * @param cmd I2C operation commands. + * @param data I2C operation data + * @retval None. + */ +static inline void DCL_I2C_SetTxFIFO(I2C_RegStruct *i2cx, I2C_CmdType cmd, unsigned char data) +{ + unsigned int temp; + + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + temp = (((unsigned int)cmd << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + temp |= (((unsigned int)data << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + i2cx->I2C_TX_FIFO.reg = temp; /* Set xommand and data */ +} + +/** + * @brief Get the I2C RX FIFO. + * @param i2cx I2C register base address. + * @retval RX FIFO data. + */ +static inline unsigned int DCL_I2C_GetRxFIFO(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_RX_FIFO.reg; +} + +/** + * @brief Set the I2C TX threshold. + * @param i2cx I2C register base address. + * @param waterMark I2C Tx threshold, 0-15. + * @retval None. + */ +static inline void DCL_I2C_SetTxWaterMark(I2C_RegStruct *i2cx, unsigned char waterMark) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cTxWaterMark(waterMark)); + i2cx->I2C_TX_WATERMARK.BIT.tx_watermark = waterMark; +} + +/** + * @brief Get the I2C TX threshold. + * @param i2cx I2C register base address. + * @retval I2C tx threshold. + */ +static inline unsigned int DCL_I2C_GetTxWaterMark(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_TX_WATERMARK.BIT.tx_watermark; +} + +/** + * @brief Set the I2C RX threshold. + * @param i2cx I2C register base address. + * @param waterMark I2C Rx threshold, 0-15. + * @retval None. + */ +static inline void DCL_I2C_SetRxWaterMark(I2C_RegStruct *i2cx, unsigned char waterMark) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cRxWaterMark(waterMark)); + i2cx->I2C_RX_WATERMARK.BIT.rx_watermark = waterMark; +} + +/** + * @brief Get the I2C RX threshold. + * @param i2cx I2C register base address. + * @retval I2C rx threshold. + */ +static inline int DCL_I2C_GetRxWaterMark(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_RX_WATERMARK.BIT.rx_watermark; +} + +/** + * @brief Set the I2C DMA mode. + * @param i2cx I2C register base address. + * @param mode I2C DMA operation mode. + * @retval None. + */ +static inline void DCL_I2C_SetDmaMode(I2C_RegStruct *i2cx, I2C_DmaOperationType mode) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2CDmaOperationType(mode)); + i2cx->I2C_CTRL1.BIT.dma_operation = mode; +} + +/** + * @brief DCL Set Start I2C timing execution Enable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SetMasterStartEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; +} + +/** + * @brief DCL Set Start I2C timing execution Disable. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SetMasterStartDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_CTRL1.BIT.mst_start = BASE_CFG_UNSET; +} + +/** + * @brief Get start and stop I2C timing status. + * @param i2cx I2C register base address. + * @retval start : 1, stop :0. + */ +static inline unsigned int DCL_I2C_GetStart(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_CTRL1.BIT.mst_start; +} + +/** + * @brief Rest Tx FIFO. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_ResetTxFIFO(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; +} + +/** + * @brief Rest Rx FIFO. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_ResetRxFIFO(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; +} + +/** + * @brief Set the SCL and SDA pins of the I2C to GPIO mode. + * @param i2cx I2C register base address. + * @param mode 0 disable,1 enable. + * @retval None. + */ +static inline void DCL_I2C_SetGpioMode(I2C_RegStruct *i2cx, unsigned char mode) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cSetOneBitValue(mode)); + i2cx->I2C_CTRL2.BIT.gpio_mode = mode; +} + +/** + * @brief Get the SCL and SDA pins of the I2C to GPIO mode. + * @param i2cx I2C register base address. + * @retval 0 or 1 + */ +static inline unsigned int DCL_I2C_GetGpioMode(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_CTRL2.BIT.gpio_mode; +} + +/** + * @brief Set the SDA output level. + * @param i2cx I2C register base address. + * @param level The sda output level. + * @retval 0 or 1. + */ +static inline void DCL_I2C_SetSdaLevel(I2C_RegStruct *i2cx, unsigned int level) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cSetOneBitValue(level)); + i2cx->I2C_CTRL2.BIT.force_sda = level; +} + +/** + * @brief Get the SDA output level. + * @param i2cx I2C register base address. + * @retval 0 or 1. + */ +static inline unsigned int DCL_I2C_GetSdaLevel(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_CTRL2.BIT.force_sda; +} + +/** + * @brief Set the SCL output level. + * @param i2cx I2C register base address. + * @param level The scl output level. + * @retval None. + */ +static inline void DCL_I2C_SetSclLevel(I2C_RegStruct *i2cx, unsigned int level) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cSetOneBitValue(level)); + i2cx->I2C_CTRL2.BIT.force_scl = level; +} + +/** + * @brief Get the SCL output level. + * @param i2cx I2C register base address. + * @retval 0 or 1. + */ +static inline unsigned int DCL_I2C_GetSclLevel(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_CTRL2.BIT.force_scl; +} + +/** + * @brief Get SMBus suspend_n_in level. + * @param i2cx I2C register base address. + * @retval 0 or 1. + */ +static inline unsigned int DCL_I2C_GetSMBusSuspendIn(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_CTRL2.BIT.smb_suspend_n_in; +} + +/** + * @brief Set SMBus suspend_n_out low level. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SetSMBusSuspendOutLowLevel(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_CTRL2.BIT.smb_suspend_n_out = BASE_CFG_DISABLE; +} + +/** + * @brief Set SMBus suspend_n_out high level. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SetSMBusSuspendOutHighLevel(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_CTRL2.BIT.smb_suspend_n_out = BASE_CFG_ENABLE; +} + +/** + * @brief Get SMBus suspend_n_out level. + * @param i2cx I2C register base address. + * @retval 0 or 1. + */ +static inline unsigned int DCL_I2C_GetSMBusSuspendOut(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_CTRL2.BIT.smb_suspend_n_out; +} + +/** + * @brief Set SMBus suspend_n_oe_n. + * @param i2cx I2C register base address. + * @param selcet The output value of SMBSUS#. + * @retval None. + */ +static inline void DCL_I2C_SetSMBusSuspendOe(I2C_RegStruct *i2cx, unsigned int selcet) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cSetOneBitValue(selcet)); + i2cx->I2C_CTRL2.BIT.smb_suspend_n_oe_n = selcet; +} + +/** + * @brief Get SMBus suspend_n_oe_n. + * @param i2cx I2C register base address. + * @retval 0 or 1. + */ +static inline unsigned int DCL_I2C_GetSMBusSuspendOe(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_CTRL2.BIT.smb_suspend_n_oe_n; +} + +/** + * @brief Get SMBus alert_n_in. + * @param i2cx I2C register base address. + * @retval 0 or 1. + */ +static inline unsigned int DCL_I2C_GetSMBusAlertIn(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_CTRL2.BIT.smb_alert_n_in; +} + +/** + * @brief Set SMBus alert_n_oe_n. + * @param i2cx I2C register base address. + * @param selcet The smbus alert set or unset. + * @retval None. + */ +static inline void DCL_I2C_SetSMBusAlertOe(I2C_RegStruct *i2cx, unsigned int selcet) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cSetOneBitValue(selcet)); + i2cx->I2C_CTRL2.BIT.smb_alert_n_oe_n = selcet; +} + +/** + * @brief Get SMBus alert_n_oe_n. + * @param i2cx I2C register base address. + * @retval The smbus alert value. + */ +static inline unsigned int DCL_I2C_GetSMBusAlertOe(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_CTRL2.BIT.smb_alert_n_oe_n; +} + +/** + * @brief Get the number of valid Tx FIFOs. + * @param i2cx I2C register base address. + * @retval Tx FIFO valid value. + */ +static inline unsigned int DCL_I2C_GetTxFIFOValidNum(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_FIFO_STAT.BIT.tx_fifo_vld_num; +} + +/** + * @brief Get the number of valid Rx FIFOs. + * @param i2cx I2C register base address. + * @retval Tx FIFO valid value. + */ +static inline unsigned int DCL_I2C_GetRxFIFOValidNum(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_FIFO_STAT.BIT.rx_fifo_vld_num; +} + +/** + * @brief Get the status of I2C bus. + * @param i2cx I2C register base address. + * @retval 0: bus busy, 1: bus free. + */ +static inline unsigned int DCL_I2C_GetI2cBusSatus(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_FSM_STAT.BIT.i2c_bus_free; +} + +/** + * @brief Clearing I2C raw interrupts. + * @param i2cx I2C register base address. + * @param cleanStatus The bit of interrupt raw status which need to be cleaned. + * @retval None. + */ +static inline void DCL_I2C_CleanRawINT(I2C_RegStruct *i2cx, unsigned int cleanStatus) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_INTR_RAW.reg = cleanStatus; +} + +/** + * @brief Get I2C raw interrupts status. + * @param i2cx I2C register base address. + * @retval The value of I2C raw interrupts status. + */ +static inline unsigned int DCL_I2C_GetRawINTStatus(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_INTR_RAW.reg; +} + +/** + * @brief Set enable I2C interrupts. + * @param i2cx I2C register base address. + * @param enableSelect The bit of interrupt which need to be set enable. + * @retval None. + */ +static inline void DCL_I2C_SetInterruptsEnable(I2C_RegStruct *i2cx, unsigned int enableSelect) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_INTR_EN.reg = enableSelect; +} + +/** + * @brief Get enable I2C interrupts. + * @param i2cx I2C register base address. + * @retval I2C interrupt enable value. + */ +static inline unsigned int DCL_I2C_GetInterruptsEnable(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_INTR_EN.reg; +} + +/** + * @brief Get I2C Interrupts Status. + * @param i2cx I2C register base address. + * @retval I2C interrupt status. + */ +static inline unsigned int DCL_I2C_GetInterruptsStatus(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_INTR_STAT.reg; +} + +/** + * @brief Get I2C version ID. + * @param i2cx I2C register base address. + * @retval I2C version ID. + */ +static inline unsigned int DCL_I2C_GetVersionID(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_VERSION.reg; +} + +/** + * @brief Set I2C SCL timeout. + * @param i2cx I2C register base address. + * @param timeout SCL low-level timeout configuration. + * @retval None. + */ +static inline void DCL_I2C_SetSclTimeout(I2C_RegStruct *i2cx, unsigned int timeout) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_ASSERT_PARAM(IsI2cSclTimoutValue(timeout)); + i2cx->I2C_SCL_TIMEOUT.reg = timeout; +} + +/** + * @brief Get I2C SCL timeout. + * @param i2cx I2C register base address. + * @retval I2C Scl timeout value. + */ +static inline unsigned int DCL_I2C_GetSclTimeout(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_SCL_TIMEOUT.BIT.scl_low_timeout; +} + +/** + * @brief I2C bus idle threshold configuration. + * @param i2cx I2C register base address. + * @param time The I2C bus idle threshold. + * @retval None. + */ +static inline void DCL_I2C_SetIdleThreshold(I2C_RegStruct *i2cx, unsigned int time) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cBusFreeTimeValue(time)); + i2cx->I2C_BUS_FREE.BIT.bus_free_time = time; +} + +/** + * @brief Get I2C bus idle threshold. + * @param i2cx I2C register base address. + * @retval I2C bus idle threshold. + */ +static inline unsigned int DCL_I2C_GetIdleThreshold(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_BUS_FREE.BIT.bus_free_time; +} + +/** + * @brief I2C filtering configuration. + * @param i2cx I2C register base address. + * @param time The value of SDA and SCL Glitch Filtering time. + * @retval None. + */ +static inline void DCL_I2C_SetFilter(I2C_RegStruct *i2cx, unsigned int time) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + I2C_PARAM_CHECK_NO_RET(IsI2cSpikeFilterTime(time)); + i2cx->I2C_FILTER.BIT.spike_filter_time = time; +} + +/** + * @brief Get I2C filtering configuration. + * @param i2cx I2C register base address. + * @retval I2C filtering configuration. + */ +static inline unsigned int DCL_I2C_GetFilter(const I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_FILTER.BIT.spike_filter_time; +} + +/** + * @brief Set I2C auto receive data enable as slave. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SetSlaveAutoReceiveEnable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_MODE.BIT.slv_auto_rx = BASE_CFG_ENABLE; +} + +/** + * @brief Set I2C auto receive data disable as slave. + * @param i2cx I2C register base address. + * @retval None. + */ +static inline void DCL_I2C_SetSlaveAutoReceiveDisable(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + i2cx->I2C_MODE.BIT.slv_auto_rx = BASE_CFG_DISABLE; +} + +/** + * @brief Get the state of I2C auto receive data as slave. + * @param i2cx I2C register base address. + * @retval the state of i2c auto receive data. + */ +static inline unsigned int DCL_I2C_GetSlaveAutoReceiveState(I2C_RegStruct *i2cx) +{ + I2C_ASSERT_PARAM(IsI2CInstance(i2cx)); + return i2cx->I2C_MODE.BIT.slv_auto_rx; +} +/** + * @} + */ + +/** + * @} + */ +#endif /* #ifndef McuMagicTag_I2C_IP_H */ \ No newline at end of file diff --git a/src/drivers/i2c/i2c_v3/src/i2c.c b/src/drivers/i2c/i2c_v3/src/i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..d48cd59cd982259463c13b8653c7e3991153cc71 --- /dev/null +++ b/src/drivers/i2c/i2c_v3/src/i2c.c @@ -0,0 +1,1967 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file i2c.c + * @author MCU Driver Team + * @brief I2C module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the I2C. + * + Initialization and de-initialization functions + * + Peripheral Control functions + */ + +/* Includes ------------------------------------------------------------------*/ +#include "interrupt.h" +#include "i2c.h" + +/* Macro definitions ---------------------------------------------------------*/ +#define I2C_INTERFACE_INDEX_0 0 +#define I2C_INTERFACE_INDEX_1 1 +#define I2C_MAX_INDEX_NUM 2 + +#define I2C_MASTER_STATUS 0x00 +#define I2C_SLAVE_STATUS 0x01 + +#define I2C_MAX_FIFO_SIZE 15 +#define I2C_WAIT_TIMEOUT 0x400 +#define I2C_MAX_DEV_ADDR 0x3FF + +#define I2C_OPERATION_WRITE 0 +#define I2C_OPERATION_READ 1 + +#define I2C_SEND_ADDR_STATUS_NONE 0 +#define I2C_SEND_ADDR_STATUS_WRITE 1 +#define I2C_SEND_ADDR_STATUS_READ 2 + +#define I2C_DATA_OPT_SETP_PRE 1 +#define I2C_DATA_OPT_SETP_NORMAL 2 + +/* Enable scl_low_timeout\mst_cmd_done\arb_lost\tx_fifo_not_full\rx_fifo_not_empty\mst_rx_ack_unmatch */ +#define I2C_CFG_INTERRUPT_MASTER_RX 0x3843 +/* Enable scl_low_timeout\mst_cmd_done\arb_lost\tx_fifo_not_full\mst_rx_ack_unmatch */ +#define I2C_CFG_INTERRUPT_MASTER_TX 0x3841 +/* Enable slv_addr_match_int\slv_rx_ack_unmatch_int\stop_det_int */ +#define I2C_CFG_INTERRUPT_SLAVE 0x302200 +#define I2C_TICK_MS_DIV 1000 + +#define I2C_INTR_RAW_SLAVE_ADDR_MATCH_MASK (0x1 << 21) +#define I2C_INTR_RAW_SLAVE_ACK_UNMATCH_MASK (0x1 << 20) +#define I2C_INTR_RAW_SLAVE_PEC_CHECK_FAIL_MASK (0x1 << 19) +#define I2C_INTR_RAW_MASTER_PEC_CHECK_FAIL_MASK (0x1 << 18) +#define I2C_INTR_RAW_SLAVE_CMD_INT1_MASK (0x1 << 17) +#define I2C_INTR_RAW_MASTER_CMD_INT1_MASK (0x1 << 16) +#define I2C_INTR_RAW_SMB_SUSPEND_MASK (0x1 << 15) +#define I2C_INTR_RAW_SMB_ALERT_MASK (0x1 << 14) +#define I2C_INTR_RAW_SCL_LOW_TIMEOUT_MASK (0x1 << 13) +#define I2C_INTR_RAW_ALL_CMD_DONE_MASK (0x1 << 12) +#define I2C_INTR_RAW_ARB_LOST_MASK (0x1 << 11) +#define I2C_INTR_RAW_START_DET_MASK (0x1 << 10) +#define I2C_INTR_RAW_STOP_DET_MASK (0x1 << 9) +#define I2C_INTR_RAW_TX_DATA_REQUEST_MASK (0x1 << 8) +#define I2C_INTR_RAW_RX_DATA_READY_MASK (0x1 << 7) +#define I2C_INTR_RAW_TX_FIFO_NOT_FULL_MASK (0x1 << 6) +#define I2C_INTR_RAW_TX_FIFO_EMPTY_MASK (0x1 << 5) +#define I2C_INTR_RAW_TX_LE_WATERMARK_MASK (0x1 << 4) +#define I2C_INTR_RAW_RX_FIFO_FULL_MASK (0x1 << 3) +#define I2C_INTR_RAW_RX_GE_WATERMARK_MASK (0x1 << 2) +#define I2C_INTR_RAW_RX_FIFO_NOT_EMPTY_MASK (0x1 << 1) +#define I2C_INTR_RAW_ACK_BIT_UNMATCH_MASK (0x1 << 0) + +#define I2C_10BIT_SLAVE_READ_ADDR_MASK (0xFEFF0000) +#define I2C_10BIT_SLAVE_WRITE_ADDR_MASK (0x0000FEFF) +#define I2C_10BIT_SLAVE_READ_OPT_MASK (0x01000000) + +#define I2C_7BIT_SLAVE_READ_ADDR_MASK (0x00FE0000) +#define I2C_7BIT_SLAVE_WRITE_ADDR_MASK (0x000000FE) +#define I2C_7BIT_SLAVE_READ_OPT_MASK (0x00010000) + +#define I2C_SLAVE_WRITE_ADDR_POS 8 +#define I2C_SLAVE_READ_FIX_ADDR_POS 24 +#define I2C_SLAVE_READ_DEV_ADDR_POS 16 +#define I2C_SLAVE_ADDR_MASK 0xFF +#define I2C_10BIT_SLAVE_ADDR_POS 16 + +#define HIGH_HOLD_TIME_POS 16 +#define HIGH_HOLD_TIME_MASK 0xFFFF0000 +#define LOW_HOLD_TIME_MASK 0x0000FFFF + +#define DMA_RX_CHANNEL_POS 8 +#define DMA_CHANNEL_MASK 0x00FF + +#define COMMAND_ALL_DONE 0 +#define I2C_BUS_IS_FREE 1 +#define SLAVE_ADDRESS_MATCH 2 +#define TX_FIFO_NOT_FULL 3 +#define RX_FIFO_NOT_EMPTY 4 + +#define I2C_FREQ_HIGH_PARAMTER 8 +#define I2C_FREQ_LOW_PARAMTER 9 + +/* mst_rx_ack_unmatch_raw\mst_arb_lost_raw\scl_low_timeout_raw\slv_rx_ack_unmatch_raw */ +#define I2C_ERROR_BIT_MASK 0x102801 +#define I2C_SCL_LOW_TIMEOUT_MASK 0x2000 + +static BASE_StatusType DmaMasterReadData(I2C_Handle *handle, unsigned int size); +static BASE_StatusType DmaMasterWriteData(I2C_Handle *handle, unsigned int size); +static BASE_StatusType DmaSlaveReadData(I2C_Handle *handle, unsigned int size); +static BASE_StatusType DmaSlaveWriteData(I2C_Handle *handle, unsigned int size); + +/* Some global parameters used for module internal operations */ +static volatile unsigned int g_internalTxBuffDMA[I2C_ONCE_TRANS_MAX_NUM] = {0}; +/** + * @brief Check all initial configuration parameters. + * @param handle I2C handle. + * @param clockFreq I2C work clock freq; + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType CheckAllInitParameters(I2C_Handle *handle, unsigned int clockFreq) +{ + /* Check the configuration of basic function parameters. */ + I2C_PARAM_CHECK_WITH_RET(IsI2cFunctionMode(handle->functionMode), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(IsI2cAddressMode(handle->addrMode), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(IsI2cSdaHoldTime(handle->sdaHoldTime), BASE_STATUS_ERROR); + /* Check whether the I2C freq is valid. */ + I2C_PARAM_CHECK_WITH_RET(IsI2cFreq(handle->freq), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET((clockFreq > 0), BASE_STATUS_ERROR); + if (handle->freq > clockFreq) { + return BASE_STATUS_ERROR; + } + /* Check the configuration of basic function parameters. */ + I2C_PARAM_CHECK_WITH_RET(IsI2cIgnoreAckFlag(handle->ignoreAckFlag), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(IsI2cTxWaterMark(handle->txWaterMark), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(IsI2cRxWaterMark(handle->rxWaterMark), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(IsI2cSpikeFilterTime(handle->handleEx.spikeFilterTime), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(IsI2cSdaDelayTime(handle->handleEx.sdaDelayTime), BASE_STATUS_ERROR); + /* Checking the own address and generalCall parameter enable when is used as slave. */ + if (handle->functionMode == I2C_MODE_SELECT_SLAVE_ONLY || handle->functionMode == I2C_MODE_SELECT_MASTER_SLAVE) { + I2C_PARAM_CHECK_WITH_RET(IsI2cOwnAddressOrMask(handle->slaveOwnAddress), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(IsI2cGeneralCallMode(handle->generalCallMode), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(IsXMBusAddressEnable(handle->handleEx.slaveOwnXmbAddressEnable), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(IsXMBusAddressOrMask(handle->handleEx.slaveOwnXmbAddress), BASE_STATUS_ERROR); + } + return BASE_STATUS_OK; +} + +/** + * @brief Configuring the I2C Slave Device Address. + * @param handle I2C handle. + * @param devAddr Slave device address + * @retval None. + */ +static void SetSlaveDevAddr(I2C_Handle *handle, const unsigned int devAddr) +{ + unsigned int addr; + + if (handle->addrMode == I2C_10_BITS) { + /* The upper 16 bits are the read operation address, and the lower 16 bits are the write operation address. */ + addr = (((devAddr << 16) & I2C_10BIT_SLAVE_READ_ADDR_MASK) | I2C_10BIT_SLAVE_READ_OPT_MASK) | + (devAddr & I2C_10BIT_SLAVE_WRITE_ADDR_MASK); + } else { + /* The upper 16 bits are the read operation address, and the lower 16 bits are the write operation address. */ + addr = (((devAddr << 16) & I2C_7BIT_SLAVE_READ_ADDR_MASK) | I2C_7BIT_SLAVE_READ_OPT_MASK) | + (devAddr & I2C_7BIT_SLAVE_WRITE_ADDR_MASK); + } + + handle->handleEx.deviceAddress = addr; +} + +/** + * @brief I2C Bus clear. + * @param handle I2C handle. + * @retval None. + */ +static void I2cBusClear(I2C_Handle *handle) +{ + handle->state = I2C_STATE_READY; + handle->baseAddress->I2C_MODE.BIT.mst_slv_function = I2C_STATE_RESET; + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + + /* Set the SCL and SDA pins of the I2C to GPIO mode. */ + handle->baseAddress->I2C_CTRL2.BIT.gpio_mode = BASE_CFG_ENABLE; + handle->baseAddress->I2C_CTRL2.BIT.force_scl = BASE_CFG_ENABLE; + handle->baseAddress->I2C_CTRL2.BIT.force_sda = BASE_CFG_ENABLE; + /* The device that controls the bus to be pulled down needs to release the bus within the 9 clocks. */ + for (unsigned int index = 0; index < 9; index++) { + handle->baseAddress->I2C_CTRL2.BIT.force_scl = BASE_CFG_UNSET; + BASE_FUNC_DELAY_US(5); /* The I2C timing is required. The delay is about 5 μs. */ + handle->baseAddress->I2C_CTRL2.BIT.force_scl = BASE_CFG_SET; + BASE_FUNC_DELAY_US(5); /* The I2C timing is required. The delay is about 5 μs. */ + } + handle->baseAddress->I2C_CTRL2.BIT.force_scl = BASE_CFG_ENABLE; + handle->baseAddress->I2C_CTRL2.BIT.force_sda = BASE_CFG_ENABLE; + /* I2C start */ + handle->baseAddress->I2C_CTRL2.BIT.force_sda = BASE_CFG_UNSET; + BASE_FUNC_DELAY_US(10); /* The I2C timing is required. The delay is about 10 μs. */ + /* I2C stop */ + handle->baseAddress->I2C_CTRL2.BIT.force_sda = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL2.BIT.gpio_mode = BASE_CFG_DISABLE; /* Exit the I2C GPIO mode. */ +} + +/** + * @brief Setting Error Handling. + * @param handle I2C handle. + * @retval None. + */ +static void SetErrorHandling(I2C_Handle *handle) +{ + handle->state = I2C_STATE_READY; + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + + /* If the low level times out, the I2C bus is cleared and the bus is expected to be released. */ + if (handle->baseAddress->I2C_INTR_RAW.BIT.scl_low_timeout_raw == BASE_CFG_ENABLE) { + I2cBusClear(handle); + handle->baseAddress->I2C_INTR_RAW.BIT.scl_low_timeout_raw = BASE_CFG_ENABLE; + } + + if (handle->errorCode != BASE_STATUS_OK && handle->userCallBack.ErrorCallback != NULL) { + handle->userCallBack.ErrorCallback(handle); + } +} + +/** + * @brief Item is checked for readiness. + * @param handle I2C handle. + * @param checkItem The item to be checked. + * @param opt Read or write flag. + * @retval false, item is not ready. true, item is ready. + */ +static unsigned int CheckItemStatus(I2C_Handle *handle, unsigned int checkItem, unsigned int opt) +{ + unsigned int ret = 0; + unsigned int tempStatusValue = 0; + switch (checkItem) { + case COMMAND_ALL_DONE: + /* The 0x1200 is the bit of mst_cmd_done_raw and stop_det_raw. */ + tempStatusValue = (handle->baseAddress->I2C_INTR_RAW.reg & 0x1200); /* Check the I2C is all command done. */ + ret = tempStatusValue; + break; + case I2C_BUS_IS_FREE: + /* The I2C bus is free. */ + ret = handle->baseAddress->I2C_FSM_STAT.BIT.i2c_bus_free; + break; + case SLAVE_ADDRESS_MATCH: + /* Slave servers are matched */ + tempStatusValue = (handle->baseAddress->I2C_RX_ADDR.BIT.rx_rw == opt) ? 1 : 0; + tempStatusValue |= handle->baseAddress->I2C_INTR_RAW.BIT.slv_addr_match_raw; + ret = tempStatusValue; + break; + case TX_FIFO_NOT_FULL: + /* Tx fifo is not full. */ + ret = ((handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < I2C_MAX_FIFO_SIZE)) ? 1 : 0; + break; + case RX_FIFO_NOT_EMPTY: + /* Rx fifo is not empty. */ + ret = handle->baseAddress->I2C_FIFO_STAT.BIT.rx_fifo_vld_num; + break; + default: + break; + } + return ret; +} + +/** + * @brief Wait for the item status to be ready. + * @param handle I2C handle. + * @param checkItem The item to be checked. + * @param opt Read or write flag. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType WaitStatusReady(I2C_Handle *handle, unsigned int checkItem, unsigned int opt) +{ + unsigned int preTick = DCL_SYSTICK_GetTick(); + unsigned int curTick; + unsigned long long delta = 0; + unsigned long long targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / I2C_TICK_MS_DIV * handle->timeout; + + while (true) { + if (handle->baseAddress->I2C_INTR_RAW.reg & I2C_ERROR_BIT_MASK) { + SetErrorHandling(handle); + return BASE_STATUS_ERROR; + } + + /* Check the status of the item is ready. */ + if (CheckItemStatus(handle, checkItem, opt)) { + if (checkItem == SLAVE_ADDRESS_MATCH) { + /* Clear slave address match raw interrupt */ + handle->baseAddress->I2C_INTR_RAW.BIT.slv_addr_match_raw = BASE_CFG_SET; + } + return BASE_STATUS_OK; + } + + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* Check timeout. */ + break; + } + preTick = curTick; + } + return BASE_STATUS_TIMEOUT; +} + +/** + * @brief Set the sending data and operation commands. + * @param handle I2C handle. + * @param cmd Operation commands. + * @param data Sending data. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SetTxFIFODataAndCmd(I2C_Handle *handle, I2C_CmdType cmd, unsigned char data) +{ + BASE_StatusType ret; + unsigned int temp; + + ret = WaitStatusReady(handle, TX_FIFO_NOT_FULL, I2C_OPERATION_WRITE); + if (ret != BASE_STATUS_OK) { + return ret; + } + /* The 8 to 11 bits are the Timing Commands, and the 0 to 7 bits are the write data. */ + temp = (((unsigned int)cmd << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + temp |= (((unsigned int)data << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + handle->baseAddress->I2C_TX_FIFO.reg = temp; /* Sets the data and commands to be sent. */ + return BASE_STATUS_OK; +} + +/** + * @brief Send a write command to the slave device. + * @param handle I2C handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SendSlaveAddressWriteCmd(I2C_Handle *handle) +{ + BASE_StatusType ret; + unsigned char addr; + /* Write slave address */ + if (handle->addrMode == I2C_10_BITS) { /* 10bit address Configuration */ + if (handle->transferCount == 0) { + /* The first address of a 10-bit address configuration */ + addr = (unsigned char)((handle->handleEx.deviceAddress >> I2C_SLAVE_WRITE_ADDR_POS) & + I2C_SLAVE_ADDR_MASK); + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + /* The second address of the 10-bit address configuration */ + addr = (unsigned char)(handle->handleEx.deviceAddress & I2C_SLAVE_ADDR_MASK); + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } else { + addr = (unsigned char)((handle->handleEx.deviceAddress >> I2C_SLAVE_WRITE_ADDR_POS) & + I2C_SLAVE_ADDR_MASK); + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } + } else { /* 7bit address Configuration */ + addr = (unsigned char)(handle->handleEx.deviceAddress & I2C_SLAVE_ADDR_MASK); + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } + return BASE_STATUS_OK; +} + +/** + * @brief Send a read command to the slave device. + * @param handle I2C handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SendSlaveAddressReadCmd(I2C_Handle *handle) +{ + BASE_StatusType ret; + unsigned char addr; + /* Write slave address */ + if (handle->addrMode == I2C_10_BITS) { /* 10bit address Configuration */ + if (handle->transferCount == 0) { + /* The first address of a 10-bit address configuration */ + addr = (unsigned char)((handle->handleEx.deviceAddress >> I2C_SLAVE_READ_FIX_ADDR_POS) & + I2C_SLAVE_ADDR_MASK); + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + /* The second address of the 10-bit address configuration */ + addr = (unsigned char)((handle->handleEx.deviceAddress >> I2C_SLAVE_READ_DEV_ADDR_POS) & + I2C_SLAVE_ADDR_MASK); + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } else { + addr = (unsigned char)((handle->handleEx.deviceAddress >> I2C_SLAVE_READ_FIX_ADDR_POS) & + I2C_SLAVE_ADDR_MASK); + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } + } else { /* 7bit address Configuration */ + addr = (unsigned char)((handle->handleEx.deviceAddress >> I2C_SLAVE_READ_DEV_ADDR_POS) & + I2C_SLAVE_ADDR_MASK); + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } + return BASE_STATUS_OK; +} + +/** + * @brief I2C Parameter Configuration in blocking. + * @param handle I2C handle. + * @param transferStatus The status is used to indicate read or write. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType I2C_ConfigParametersAndStartBlocking(I2C_Handle *handle, unsigned int transferStatus) +{ + BASE_StatusType ret; + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + + handle->baseAddress->I2C_CTRL1.BIT.mst_start = (transferStatus == I2C_MASTER_STATUS) ? BASE_CFG_SET : + BASE_CFG_UNSET; + if (transferStatus == I2C_SLAVE_STATUS) { + return BASE_STATUS_OK; + } + /* Send I2C start */ + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_S, 0); /* Sets the start command to be sent. */ + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return ret; + } + return ret; +} + +/** + * @brief Master send stop command in blocking. + * @param handle I2C handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType BlockingSendStopCommand(I2C_Handle *handle) +{ + BASE_StatusType ret; + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_P, 0); + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return ret; + } + /* Wait until all commands are executed. */ + ret = WaitStatusReady(handle, COMMAND_ALL_DONE, I2C_OPERATION_WRITE); + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; +} + +/** + * @brief The step of receive normal data in blocking as master. + * @param handle I2C handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType BlockingMasterRxDataOptStepNormal(I2C_Handle *handle) +{ + BASE_StatusType ret; + while (handle->transferCount < handle->transferSize) { + if (handle->transferCount == handle->transferSize - 1) { + /* Reads the last frame of data without ack. */ + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_RD_TNACK_S_TD_RNACK, 0); + } else { + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_RD_TACK_S_TD_RACK, 0); + } + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return ret; + } + /* Wait the RX FIFO is not empty. */ + ret = WaitStatusReady(handle, RX_FIFO_NOT_EMPTY, I2C_OPERATION_READ); + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return ret; + } + /* Obtains the data received from the RX FIFO. */ + *handle->transferBuff = handle->baseAddress->I2C_RX_FIFO.BIT.rx_fifo_rdata; + handle->transferBuff++; + handle->transferCount++; + } + return ret; +} + +/** + * @brief The step of transmit normal data in blocking as master. + * @param handle I2C handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType BlockingMasterTxDataOptStepNormal(I2C_Handle *handle) +{ + BASE_StatusType ret; + /* Sets data to be sent cyclically. */ + while (handle->transferCount < handle->transferSize) { + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, *handle->transferBuff); + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return ret; + } + handle->transferBuff++; + handle->transferCount++; + } + return BASE_STATUS_OK; +} + +/** + * @brief The step of receive normal data in blocking as slave. + * @param handle I2C handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType BlockingSlaveRxDataOptStepNormal(I2C_Handle *handle) +{ + while (handle->transferCount < handle->transferSize) { + /* Sets the data to be received. */ + if (SetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, 0) != BASE_STATUS_OK) { + SetErrorHandling(handle); + return BASE_STATUS_TIMEOUT; + } + if (WaitStatusReady(handle, RX_FIFO_NOT_EMPTY, I2C_OPERATION_READ) != BASE_STATUS_OK) { + SetErrorHandling(handle); + return BASE_STATUS_TIMEOUT; + } + /* Obtains the data received in the RX FIFO. */ + *handle->transferBuff = handle->baseAddress->I2C_RX_FIFO.BIT.rx_fifo_rdata; + handle->transferBuff++; + handle->transferCount++; + } + return BASE_STATUS_OK; +} + +/** + * @brief Checking Interrupts Caused by I2C Timing Errors. + * @param handle I2C handle. + * @param status Status of the I2C. + * @retval true or false + */ +static void IsInterruptErrorStatus(I2C_Handle *handle, unsigned int status) +{ + /* If the low level times out, the I2C bus is cleared and the bus is expected to be released. */ + if (status & I2C_SCL_LOW_TIMEOUT_MASK) { + I2cBusClear(handle); + } + /* Disable */ + handle->errorCode = BASE_STATUS_ERROR; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_DISABLE; + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->state = I2C_STATE_READY; + if (handle->userCallBack.ErrorCallback != NULL) { + handle->userCallBack.ErrorCallback(handle); + } +} + +/** + * @brief Interrupt handle send start command. + * @param handle I2C handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType InterruptSendStart(I2C_Handle *handle) +{ + unsigned int temp; + if (handle->handleEx.sendAddrStatus <= I2C_SEND_ADDR_STATUS_NONE) { + return BASE_STATUS_OK; + } + + if (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < I2C_MAX_FIFO_SIZE) { + /* The 8 to 11 bits are the Timing Commands, and the 0 to 7 bits are the write data. */ + temp = (((unsigned int)I2C_CMD_S << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + handle->baseAddress->I2C_TX_FIFO.reg = temp; /* Sets the data and commands to be sent. */ + } else { + return BASE_STATUS_ERROR; + } + switch (handle->handleEx.sendAddrStatus) { + case I2C_SEND_ADDR_STATUS_WRITE: + /* Send a write command to the slave. */ + if (SendSlaveAddressWriteCmd(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + break; + case I2C_SEND_ADDR_STATUS_READ: + /* Send a read command to the slave. */ + if (SendSlaveAddressReadCmd(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + break; + default: + break; + } + handle->handleEx.sendAddrStatus = I2C_SEND_ADDR_STATUS_NONE; + return BASE_STATUS_OK; +} + +/** + * @brief I2C Interrupt done Handling + * @param handle I2C handle. + * @param status I2C interrupt raw status. + * @retval None. + */ +static void InterruptAllDoneHandle(I2C_Handle *handle, unsigned int status) +{ + /* After all data transmission is complete, call the user's callback function. */ + unsigned int masterAllDone = status & I2C_INTR_RAW_ALL_CMD_DONE_MASK; + unsigned int slaveReceiveStop = status & I2C_INTR_RAW_STOP_DET_MASK; + unsigned int allDoneItFlag = (masterAllDone || slaveReceiveStop); + if ((handle->transferCount >= handle->transferSize) && allDoneItFlag) { + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_DISABLE; + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + if (handle->userCallBack.RxCplCallback != NULL && + (handle->state == I2C_STATE_BUSY_MASTER_RX || handle->state == I2C_STATE_BUSY_SLAVE_RX)) { + handle->userCallBack.RxCplCallback(handle); /* Invoke the RX callback processing function. */ + } else if (handle->userCallBack.TxCplCallback != NULL && + (handle->state == I2C_STATE_BUSY_MASTER_TX || handle->state == I2C_STATE_BUSY_SLAVE_TX)) { + handle->userCallBack.TxCplCallback(handle); /* Invoke the TX callback processing function. */ + } + handle->state = I2C_STATE_READY; + } +} + +/** + * @brief I2C interrupt TX handling + * @param handle I2C handle. + * @retval None. + */ +static void InterruptMasterTxHandle(I2C_Handle *handle) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_ASSERT_PARAM(handle->transferBuff != NULL); + unsigned int temp; + /* Send a start command to the slave. */ + if (InterruptSendStart(handle) != BASE_STATUS_OK) { + return; + } + while (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < I2C_MAX_FIFO_SIZE && + handle->transferCount < handle->transferSize) { + /* Sets the data to be sent. */ + temp = (((unsigned int)I2C_CMD_M_TD_RACK_S_RD_TACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + temp |= ((unsigned int)(*handle->transferBuff) & I2C_TXFIFO_WDATA_MASK); + handle->baseAddress->I2C_TX_FIFO.reg = temp; /* Sets the data and commands to be sent. */ + handle->transferBuff++; + handle->transferCount++; + } +} + +/** + * @brief I2C Interrupt RX Handling + * @param handle I2C handle. + * @retval None. + */ +static void InterruptMasterRxHandle(I2C_Handle *handle) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_ASSERT_PARAM(handle->transferBuff != NULL); + /* Send a start command to the slave. */ + if (InterruptSendStart(handle) != BASE_STATUS_OK) { + return; + } + /* The I2C controller fills in the receive command and starts to receive data. */ + while (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < I2C_MAX_FIFO_SIZE && + handle->handleEx.txReadCmdCount < handle->transferSize) { + if (handle->handleEx.txReadCmdCount == handle->transferSize - 1) { + handle->baseAddress->I2C_TX_FIFO.reg = + (((unsigned int)I2C_CMD_M_RD_TNACK_S_TD_RNACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } else { /* Normal data transmission. */ + handle->baseAddress->I2C_TX_FIFO.reg = + (((unsigned int)I2C_CMD_M_RD_TACK_S_TD_RACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } + handle->handleEx.txReadCmdCount++; + } + /* Obtains the data received in the RX FIFO. */ + while (handle->baseAddress->I2C_FIFO_STAT.BIT.rx_fifo_vld_num > 0 && + handle->transferCount < handle->transferSize) { + *handle->transferBuff++ = handle->baseAddress->I2C_RX_FIFO.BIT.rx_fifo_rdata; + handle->transferCount++; + } +} + +/** + * @brief I2C interrupt slave TX handling + * @param handle I2C handle. + * @retval None. + */ +static void InterruptSlaveTxHandle(I2C_Handle *handle) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_ASSERT_PARAM(handle->transferBuff != NULL); + unsigned int temp; + while (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < I2C_MAX_FIFO_SIZE && + handle->transferCount < handle->transferSize) { + if (handle->transferCount == handle->transferSize - 1) { /* no need ack. */ + temp = (((unsigned int)I2C_CMD_M_RD_TNACK_S_TD_RNACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + temp |= ((unsigned int)(*handle->transferBuff) & I2C_TXFIFO_WDATA_MASK); + handle->baseAddress->I2C_TX_FIFO.reg = temp; /* Sets the data and commands to be sent. */ + } else { /* Normal data transmission. */ + temp = (((unsigned int)I2C_CMD_M_RD_TACK_S_TD_RACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + temp |= ((unsigned int)(*handle->transferBuff) & I2C_TXFIFO_WDATA_MASK); + handle->baseAddress->I2C_TX_FIFO.reg = temp; /* Sets the data and commands to be sent. */ + } + handle->transferBuff++; + handle->transferCount++; + } +} + +/** + * @brief I2C interrupt slave RX handling + * @param handle I2C handle. + * @retval None. + */ +static void InterruptSlaveRxHandle(I2C_Handle *handle) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_ASSERT_PARAM(handle->transferBuff != NULL); + /* Set the data receiving command. */ + while (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < I2C_MAX_FIFO_SIZE && + handle->handleEx.txReadCmdCount < handle->transferSize) { + handle->baseAddress->I2C_TX_FIFO.reg = + (((unsigned int)I2C_CMD_M_TD_RACK_S_RD_TACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + handle->handleEx.txReadCmdCount++; + } + /* Obtained data from RX FIFO. */ + while (handle->baseAddress->I2C_FIFO_STAT.BIT.rx_fifo_vld_num > 0 && + handle->transferCount < handle->transferSize) { + *handle->transferBuff = handle->baseAddress->I2C_RX_FIFO.BIT.rx_fifo_rdata; + handle->transferBuff++; + handle->transferCount++; + } +} + +/** + * @brief ICallback function corresponding to the interrupt processing function. + * @param handle I2C handle. + * @param status Status of the I2C. + * @retval None. + */ +static void InterruptHandle(I2C_Handle *handle, unsigned int status) +{ + if (handle->state == I2C_STATE_BUSY_MASTER_TX) { + InterruptMasterTxHandle(handle); /* Transfer data as a host. */ + return; + } else if (handle->state == I2C_STATE_BUSY_MASTER_RX) { + InterruptMasterRxHandle(handle); /* Receive data as a host. */ + return; + } else if (handle->state == I2C_STATE_BUSY_SLAVE_TX) { + if (status & I2C_INTR_RAW_SLAVE_ADDR_MATCH_MASK) { + /* Set TX FIFO the waterline. */ + handle->baseAddress->I2C_INTR_EN.BIT.tx_fifo_not_full_en = BASE_CFG_SET; + } + if (handle->baseAddress->I2C_RX_ADDR.BIT.rx_rw == I2C_OPERATION_READ) { + InterruptSlaveTxHandle(handle); /* Transfer data as slave. */ + } + return; + } else if (handle->state == I2C_STATE_BUSY_SLAVE_RX) { + if (status & I2C_INTR_RAW_SLAVE_ADDR_MATCH_MASK) { + /* Set TX FIFO the waterline. */ + handle->baseAddress->I2C_INTR_EN.BIT.tx_fifo_not_full_en = BASE_CFG_SET; + /* Set RX FIFO the waterline. */ + handle->baseAddress->I2C_INTR_EN.BIT.rx_fifo_not_empty_en = BASE_CFG_SET; + } + if (handle->baseAddress->I2C_RX_ADDR.BIT.rx_rw == I2C_OPERATION_WRITE) { + InterruptSlaveRxHandle(handle); /* Receive data as slave. */ + } + return; + } + handle->errorCode = BASE_STATUS_ERROR; + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->state = I2C_STATE_READY; /* Changing the I2C Bus Status. */ + if (handle->userCallBack.ErrorCallback != NULL) { + handle->userCallBack.ErrorCallback(handle); + } +} + +/** + * @brief DMA Command Configuration. + * @param handle I2C handle. + * @param cmd The command type of I2C. + * @param size The number of the data to be receiving or sending. + * @retval Value of the command. + */ +static unsigned int DmaConfigCommandData(I2C_Handle *handle, I2C_CmdType cmd, unsigned int size) +{ + unsigned int temp; + /* Sets the command data. */ + if ((cmd == I2C_CMD_M_RD_TACK_S_TD_RACK) && (size == 1) && (handle->transferCount >= handle->transferSize)) { + temp = (((unsigned int)I2C_CMD_M_RD_TNACK_S_TD_RNACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } else { + temp = (((unsigned int)cmd << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } + return temp; +} + +/** + * @brief Config commands and data in dma as master. + * @param handle I2C handle. + * @param txBuff Address of the data buff to be receiving or sending. + * @param cmd The command type of I2C. + * @param size The number of the data to be receiving or sending. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType DmaMasterConfigDataAndCmd(I2C_Handle *handle, unsigned int *txBuff, I2C_CmdType cmd, + unsigned int size) +{ + unsigned int temp; + unsigned int *tempTxBuff = txBuff; + unsigned char *tempsrcTxBuff = (unsigned char*)handle->transferBuff; + unsigned int tempSize = size; + while (tempSize) { + /* Sets the command data. */ + temp = DmaConfigCommandData(handle, cmd, tempSize); + /* Sets the normal data. */ + if (cmd == I2C_CMD_M_TD_RACK_S_RD_TACK) { + temp |= (((unsigned int)*tempsrcTxBuff << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + tempsrcTxBuff++; + } else if ((cmd == I2C_CMD_M_RD_TACK_S_TD_RACK) && (tempSize > 1)) { + temp |= ((0x0 << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + } + *tempTxBuff = temp; /* Set the combined data. */ + tempTxBuff++; + tempSize--; + temp = 0; + } + return BASE_STATUS_OK; +} + +/** + * @brief Config commands and data in dma as slave. + * @param handle I2C handle. + * @param txBuff Address of the data buff to be receiving or sending. + * @param cmd The command type of I2C. + * @param size The number of the data to be receiving or sending. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType DmaSlaveConfigDataAndCmd(I2C_Handle *handle, unsigned int *txBuff, I2C_CmdType cmd, + unsigned int size) +{ + unsigned int temp; + unsigned int *tempTxBuff = txBuff; + unsigned char *tempsrcTxBuff = (unsigned char*)handle->transferBuff; + unsigned int tempSize = size; + while (tempSize) { + /* Sets the command data. */ + temp = DmaConfigCommandData(handle, cmd, tempSize); + /* Sets the normal data. */ + if (cmd == I2C_CMD_M_RD_TACK_S_TD_RACK) { + temp |= (((unsigned int)*tempsrcTxBuff << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + tempsrcTxBuff++; + } else if (cmd == I2C_CMD_M_TD_RACK_S_RD_TACK) { + temp |= ((0x0 << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + } + *tempTxBuff = temp; /* Set the combined data. */ + tempTxBuff++; + tempSize--; + temp = 0; + } + return BASE_STATUS_OK; +} + +/** + * @brief I2C DMA Error Handling. + * @param handle I2C handle. + * @retval None. + */ +static void I2C_DmaErrorHandle(I2C_Handle *handle) +{ + /* Some settings when an error occurs. */ + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_UNSET; + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + handle->errorCode = BASE_STATUS_ERROR; + if (handle->userCallBack.ErrorCallback != NULL) { + handle->userCallBack.ErrorCallback(handle); + } + handle->state = I2C_STATE_READY; +} + +/** + * @brief I2C DMA completes processing. + * @param handle I2C handle. + * @retval None. + */ +static void I2C_DmaDoneHandle(I2C_Handle *handle) +{ + /* Disable the DMA operation and configure parameters. */ + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_UNSET; + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + /* Call the corresponding callback function. */ + if (handle->state == I2C_STATE_BUSY_MASTER_RX || handle->state == I2C_STATE_BUSY_SLAVE_RX) { + if (handle->userCallBack.RxCplCallback != NULL) { + handle->userCallBack.RxCplCallback(handle); + } + } else if (handle->state == I2C_STATE_BUSY_MASTER_TX || handle->state == I2C_STATE_BUSY_SLAVE_TX) { + if (handle->userCallBack.TxCplCallback != NULL) { + handle->userCallBack.TxCplCallback(handle); + } + } + handle->state = I2C_STATE_READY; +} + +/** + * @brief Wait until all I2C timings are processed. + * @param handle I2C handle. + * @retval None. + */ +static void DmaWaitHandleFinish(I2C_Handle *handle) +{ + unsigned int intrRwa; + unsigned int preTick; + unsigned int curTick; + unsigned long long delta; + unsigned long long targetDelta; + + delta = 0; + preTick = DCL_SYSTICK_GetTick(); + /* Set the timeout threshold to 10000ms. */ + targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / I2C_TICK_MS_DIV * handle->timeout; + + while (true) { + /* Waiting for the last DMA transfer to complete. */ + intrRwa = handle->baseAddress->I2C_INTR_RAW.reg; + /* Check for errors. */ + if ((intrRwa & (I2C_INTR_RAW_ARB_LOST_MASK | I2C_INTR_RAW_ACK_BIT_UNMATCH_MASK | + I2C_INTR_RAW_SLAVE_ACK_UNMATCH_MASK)) > 0) { + I2C_DmaErrorHandle(handle); + break; + } + /* DMA transfer completed normally. */ + if ((intrRwa & (I2C_INTR_RAW_ALL_CMD_DONE_MASK | I2C_INTR_RAW_STOP_DET_MASK)) > 0) { + I2C_DmaDoneHandle(handle); + break; + } + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* Check timeout. */ + return; + } + preTick = curTick; + } +} + +/** + * @brief The I2C uses the DMA completion callback function registered by the DMA module. + * @param handle I2C handle. + * @retval None. + */ +static void DmaOptStepNormalFinishFun(void *handle) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_Handle *i2cHandle = (I2C_Handle *)(handle); + I2C_ASSERT_PARAM(IsI2CInstance(i2cHandle->baseAddress)); /* I2C baseaddress check */ + BASE_StatusType ret = BASE_STATUS_OK; + unsigned int tempOnceTransferSize; /* Used to record the amount of data transmitted this time. */ + unsigned int offset; + + offset = i2cHandle->transferCount % I2C_ONCE_TRANS_MAX_NUM; + i2cHandle->transferBuff += (offset == 0) ? I2C_ONCE_TRANS_MAX_NUM : offset; /* Update Transferred Data. */ + + if (i2cHandle->transferCount < i2cHandle->transferSize) { + /* Determine the amount of data transmitted at a time. */ + tempOnceTransferSize = (i2cHandle->handleEx.dmaTransferSize >= I2C_ONCE_TRANS_MAX_NUM) ? + I2C_ONCE_TRANS_MAX_NUM : i2cHandle->handleEx.dmaTransferSize; + i2cHandle->handleEx.dmaTransferSize -= tempOnceTransferSize; + i2cHandle->transferCount += tempOnceTransferSize; + /* Configuring the I2C Timing */ + if (i2cHandle->state == I2C_STATE_BUSY_MASTER_RX) { + ret = DmaMasterReadData(i2cHandle, tempOnceTransferSize); /* The master read data by DMA. */ + } else if (i2cHandle->state == I2C_STATE_BUSY_MASTER_TX) { + ret = DmaMasterWriteData(i2cHandle, tempOnceTransferSize); /* The master write data by DMA. */ + } else if (i2cHandle->state == I2C_STATE_BUSY_SLAVE_RX) { + ret = DmaSlaveReadData(i2cHandle, tempOnceTransferSize); /* The slave read data by DMA. */ + } else if (i2cHandle->state == I2C_STATE_BUSY_SLAVE_TX) { + ret = DmaSlaveWriteData(i2cHandle, tempOnceTransferSize); /* The slave write data by DMA. */ + } + /* Check whether errors occur. */ + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return; + } + return; + } else if (SetTxFIFODataAndCmd(i2cHandle, I2C_CMD_P, 0) != BASE_STATUS_OK) { + SetErrorHandling(i2cHandle); /* Error handle. */ + } + DmaWaitHandleFinish(i2cHandle); +} + +/** + * @brief The I2C uses the DMA error callback function registered by the DMA module. + * @param handle I2C handle. + * @retval None. + */ +static void DmaErrorHandlerFun(void *handle) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_Handle *i2cHandle = (I2C_Handle *)(handle); + I2C_ASSERT_PARAM(IsI2CInstance(i2cHandle->baseAddress)); + /* Disable the interrupt and call the error callback function. */ + i2cHandle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + i2cHandle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + i2cHandle->errorCode = BASE_STATUS_ERROR; + if (i2cHandle->userCallBack.ErrorCallback != NULL) { + i2cHandle->userCallBack.ErrorCallback(i2cHandle); + } + /* Stop DMA channel transfer. */ + HAL_DMA_StopChannel(i2cHandle->dmaHandle, i2cHandle->txDmaCh); + if (i2cHandle->state == I2C_STATE_BUSY_MASTER_RX || i2cHandle->state == I2C_STATE_BUSY_SLAVE_RX) { + HAL_DMA_StopChannel(i2cHandle->dmaHandle, i2cHandle->rxDmaCh); + } + i2cHandle->state = I2C_STATE_READY; +} + +/** + * @brief Receive data as master by the DMA module. + * @param handle I2C handle. + * @param size Number of the data to be transmitted. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType DmaMasterReadData(I2C_Handle *handle, unsigned int size) +{ + /* Combine commands and data. */ + DmaMasterConfigDataAndCmd(handle, (unsigned int *)g_internalTxBuffDMA, I2C_CMD_M_RD_TACK_S_TD_RACK, size); + + /* Configuring the DMA Callback Function. */ + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelFinishCallBack = NULL; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelErrorCallBack = DmaErrorHandlerFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->rxDmaCh].ChannelFinishCallBack = DmaOptStepNormalFinishFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->rxDmaCh].ChannelErrorCallBack = DmaErrorHandlerFun; + /* Start the DMA for data transmission. */ + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)g_internalTxBuffDMA, + (uintptr_t)&(handle->baseAddress->I2C_TX_FIFO.reg), + size, handle->txDmaCh) != BASE_STATUS_OK) { + handle->state = I2C_STATE_READY; + return BASE_STATUS_ERROR; + } + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)&(handle->baseAddress->I2C_RX_FIFO), + (uintptr_t)handle->transferBuff, size, + handle->rxDmaCh) != BASE_STATUS_OK) { + handle->state = I2C_STATE_READY; + return BASE_STATUS_ERROR; + } + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_WRITE_READ; + return BASE_STATUS_OK; +} + +/** + * @brief Transmit data as master by the DMA module. + * @param handle I2C handle. + * @param size Number of the data to be transmitted. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType DmaMasterWriteData(I2C_Handle *handle, unsigned int size) +{ + /* Combine commands and data. */ + DmaMasterConfigDataAndCmd(handle, (unsigned int *)g_internalTxBuffDMA, I2C_CMD_M_TD_RACK_S_RD_TACK, size); + + /* Configuring the DMA Callback Function. */ + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelFinishCallBack = DmaOptStepNormalFinishFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelErrorCallBack = DmaErrorHandlerFun; + /* Start the DMA for data transmission. */ + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)g_internalTxBuffDMA, + (uintptr_t)&(handle->baseAddress->I2C_TX_FIFO.reg), + size, handle->txDmaCh) != BASE_STATUS_OK) { + handle->state = I2C_STATE_READY; + return BASE_STATUS_ERROR; + } + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_WRITE; + return BASE_STATUS_OK; +} + +/** + * @brief Receive data as slave by the DMA module. + * @param handle I2C handle. + * @param size Number of the data to be transmitted. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType DmaSlaveReadData(I2C_Handle *handle, unsigned int size) +{ + /* Combine commands and data. */ + DmaSlaveConfigDataAndCmd(handle, (unsigned int *)g_internalTxBuffDMA, I2C_CMD_M_TD_RACK_S_RD_TACK, size); + + /* Configuring the DMA Callback Function. */ + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelFinishCallBack = NULL; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelErrorCallBack = DmaErrorHandlerFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->rxDmaCh].ChannelFinishCallBack = DmaOptStepNormalFinishFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->rxDmaCh].ChannelErrorCallBack = DmaErrorHandlerFun; + /* Start the DMA for data transmission. */ + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)&(handle->baseAddress->I2C_RX_FIFO), + (uintptr_t)handle->transferBuff, size, + handle->rxDmaCh) != BASE_STATUS_OK) { + handle->state = I2C_STATE_READY; + return BASE_STATUS_ERROR; + } + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)g_internalTxBuffDMA, + (uintptr_t)&(handle->baseAddress->I2C_TX_FIFO), + size, handle->txDmaCh) != BASE_STATUS_OK) { + handle->state = I2C_STATE_READY; + return BASE_STATUS_ERROR; + } + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_WRITE_READ; + return BASE_STATUS_OK; +} + +/** + * @brief Transmit data as slave by the DMA module. + * @param handle I2C handle. + * @param size Number of the data to be transmitted. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType DmaSlaveWriteData(I2C_Handle *handle, unsigned int size) +{ + /* Combine commands and data. */ + DmaSlaveConfigDataAndCmd(handle, (unsigned int *)g_internalTxBuffDMA, I2C_CMD_M_RD_TACK_S_TD_RACK, size); + /* Configure DMA Parameters */ + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelFinishCallBack = DmaOptStepNormalFinishFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelErrorCallBack = DmaErrorHandlerFun; + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)g_internalTxBuffDMA, + (uintptr_t)&(handle->baseAddress->I2C_TX_FIFO.reg), size, handle->txDmaCh) != BASE_STATUS_OK) { + handle->state = I2C_STATE_READY; + return BASE_STATUS_ERROR; + } + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_WRITE; + return BASE_STATUS_OK; +} + +/** + * @brief Transmit data by the DMA module. + * @param handle I2C handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType I2cTransferDataDma(I2C_Handle *handle) +{ + BASE_StatusType ret = BASE_STATUS_OK; + unsigned int tempOnceTransferSize; + handle->handleEx.dmaTransferSize = handle->transferSize; + + /* Determine the amount of data transmitted at a time. */ + tempOnceTransferSize = (handle->handleEx.dmaTransferSize >= I2C_ONCE_TRANS_MAX_NUM) ? I2C_ONCE_TRANS_MAX_NUM : + handle->handleEx.dmaTransferSize; + handle->handleEx.dmaTransferSize -= tempOnceTransferSize; + handle->transferCount += tempOnceTransferSize; + /* Configuring the I2C Timing */ + if (handle->state == I2C_STATE_BUSY_MASTER_RX) { + ret = DmaMasterReadData(handle, tempOnceTransferSize); + } else if (handle->state == I2C_STATE_BUSY_MASTER_TX) { + ret = DmaMasterWriteData(handle, tempOnceTransferSize); + } else if (handle->state == I2C_STATE_BUSY_SLAVE_RX) { + ret = DmaSlaveReadData(handle, tempOnceTransferSize); + } else if (handle->state == I2C_STATE_BUSY_SLAVE_TX) { + ret = DmaSlaveWriteData(handle, tempOnceTransferSize); + } + /* Check whether errors occur. */ + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return ret; + } + + return ret; +} + +/** + * @brief As Slave Multiplex Interrupt Write or Read. + * @param handle I2C handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType I2C_SlaveMultiplexIT(I2C_Handle *handle) +{ + /* Parameter Settings. */ + handle->handleEx.txReadCmdCount = 0; + handle->handleEx.sendAddrStatus = I2C_SEND_ADDR_STATUS_NONE; + /* Clean interrupt */ + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + /* Enable interrupt */ + handle->baseAddress->I2C_INTR_EN.reg = I2C_CFG_INTERRUPT_SLAVE; + return BASE_STATUS_OK; +} + +/** + * @brief Initializing the I2C Module. + * @param handle I2C handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_Init(I2C_Handle *handle) +{ + unsigned int clockFreq; + unsigned int val; + unsigned int tempReg; + unsigned int temp; + unsigned int tempSclLowTime; + unsigned int tempSclHighTime; + + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + clockFreq = HAL_CRG_GetIpFreq((void *)handle->baseAddress); + if (CheckAllInitParameters(handle, clockFreq) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + handle->state = I2C_STATE_BUSY; + /* Clears interrupts and disables interrupt reporting to facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + + /* Set SDA and SCL glitch filtering time. */ + handle->baseAddress->I2C_FILTER.BIT.spike_filter_time = handle->handleEx.spikeFilterTime; + /* Set SCL high and low duratiom time */ + tempSclLowTime = I2C_FREQ_LOW_PARAMTER + handle->handleEx.spikeFilterTime; + tempSclHighTime = I2C_FREQ_HIGH_PARAMTER + handle->handleEx.spikeFilterTime; + if (handle->freq <= I2C_STANDARD_FREQ_TH) { + /* scl_high_time = (fclk_i2c/fSCL) x 0.5 - 8 - spike_filter_time. */ + val = clockFreq / (handle->freq * 2) - tempSclHighTime; /* The clockFreq / (freq * 2) = cloclFreq/0.5/freq. */ + /* scl_low_time = (fclk_i2c/fSCL) x 0.5 - 9 - spike_filter_time. */ + val = ((val - 1) & LOW_HOLD_TIME_MASK) | ((val << HIGH_HOLD_TIME_POS) & HIGH_HOLD_TIME_MASK); + } else { + /* scl_high_time = (fclk_i2c/fSCL) x 0.36 - 8 - spike_filter_time. (n/100*36)=0.36n. */ + val = ((((clockFreq / 100) * 36) / handle->freq) - tempSclHighTime) << HIGH_HOLD_TIME_POS; + /* scl_low_time = (fclk_i2c/fSCL) x 0.64 - 9 - spike_filter_time. (n/100*64)=0.64n. */ + val |= (((((clockFreq / 100) * 64) / handle->freq) - tempSclLowTime) & LOW_HOLD_TIME_MASK); + } + handle->baseAddress->I2C_SCL_CFG.reg = val; + + /* Set sda hold duration.The value is fixed to 0xa */ + temp = ((handle->sdaHoldTime & 0x0000FFFF) << I2C_SDA_HOLD_DURATION_POS); + tempReg = (handle->handleEx.sdaDelayTime & 0x0000000F) | temp; + handle->baseAddress->I2C_SDA_CFG.reg = tempReg; + + /* Set I2C TX FIFO watermark */ + handle->baseAddress->I2C_TX_WATERMARK.BIT.tx_watermark = handle->txWaterMark; + /* Set I2C RX FIFO watermark */ + handle->baseAddress->I2C_RX_WATERMARK.BIT.rx_watermark = handle->rxWaterMark; + handle->baseAddress->I2C_MODE.BIT.mst_slv_function = handle->functionMode; + handle->baseAddress->I2C_MODE.BIT.rack_mode = handle->ignoreAckFlag; + + if (handle->functionMode == I2C_MODE_SELECT_SLAVE_ONLY || handle->functionMode == I2C_MODE_SELECT_MASTER_SLAVE) { + /* Sets the first own address of the slave. */ + handle->baseAddress->I2C_OWN_ADDR.BIT.own_address = handle->slaveOwnAddress; + handle->baseAddress->I2C_OWN_ADDR.BIT.i2c_general_call_en = handle->generalCallMode; + /* Sets the second own address of the slave. */ + if (handle->handleEx.slaveOwnXmbAddressEnable == BASE_CFG_ENABLE) { + handle->baseAddress->XMB_DEV_ADDR.BIT.xmb_address_en = BASE_CFG_ENABLE; + handle->baseAddress->XMB_DEV_ADDR.BIT.xmb_address = handle->handleEx.slaveOwnXmbAddress; + } + } + handle->state = I2C_STATE_READY; + return BASE_STATUS_OK; +} + +/** + * @brief Deinitialize the I2C module. + * @param handle I2C handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_Deinit(I2C_Handle *handle) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + + handle->state = I2C_STATE_BUSY; + /* Disable */ + handle->baseAddress->I2C_MODE.BIT.mst_slv_function = I2C_MODE_SELECT_NONE; + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + /* Clean interrupt callback functions. */ + handle->userCallBack.TxCplCallback = NULL; + handle->userCallBack.RxCplCallback = NULL; + handle->userCallBack.ErrorCallback = NULL; + handle->state = I2C_STATE_RESET; + + return BASE_STATUS_OK; +} + +/** + * @brief Callback Function Registration. + * @param handle I2C handle. + * @param callbackID Callback function ID. + * @param pcallback Pointer to the address of the registered callback function. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_RegisterCallback(I2C_Handle *handle, I2C_CallbackId callbackID, I2C_CallbackFunType pcallback) +{ + BASE_StatusType ret = BASE_STATUS_OK; + /* Check the parameter validity. */ + I2C_ASSERT_PARAM(handle != NULL && pcallback != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_ASSERT_PARAM(pcallback != NULL); + + if (handle->state == I2C_STATE_READY) { + switch (callbackID) { + case I2C_MASTER_TX_COMPLETE_CB_ID : + case I2C_SLAVE_TX_COMPLETE_CB_ID : + handle->userCallBack.TxCplCallback = pcallback; /* Invoke the transfer completion callback function. */ + break; + case I2C_MASTER_RX_COMPLETE_CB_ID : + case I2C_SLAVE_RX_COMPLETE_CB_ID : + handle->userCallBack.RxCplCallback = pcallback; /* Invoke the receive completion callback function. */ + break; + case I2C_ERROR_CB_ID: + handle->userCallBack.ErrorCallback = pcallback; + break; + default: + ret = BASE_STATUS_ERROR; + handle->errorCode = BASE_STATUS_ERROR; + break; + } + } else { /* If I2C state is not ready, don't invoke callback function. */ + ret = BASE_STATUS_ERROR; + handle->errorCode = BASE_STATUS_ERROR; + } + return ret; +} + +/** + * @brief Receiving data in blocking mode. + * @param handle I2C handle. + * @param devAddr Slave Device Address. + * @param rData Address of the data buff to be receiving. + * @param dataSize Number of the data to be receiving. + * @param timeout Timeout period,unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_MasterReadBlocking(I2C_Handle *handle, unsigned short devAddr, unsigned char *rData, + unsigned int dataSize, unsigned int timeout) +{ + I2C_ASSERT_PARAM(handle != NULL && rData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(devAddr <= I2C_MAX_DEV_ADDR, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(timeout > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); /* Status check. */ + + BASE_StatusType ret; + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + /* Waiting for the i2c bus to be idle. */ + ret = WaitStatusReady(handle, I2C_BUS_IS_FREE, I2C_SEND_ADDR_STATUS_WRITE); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + /* Configuring I2C Parameters. */ + handle->state = I2C_STATE_BUSY_MASTER_RX; + handle->transferBuff = rData; + handle->transferSize = dataSize; + handle->transferCount = 0; + handle->timeout = timeout; + SetSlaveDevAddr(handle, devAddr); + + /* step1 : Parameter Settings and startup Control. */ + ret = I2C_ConfigParametersAndStartBlocking(handle, I2C_MASTER_STATUS); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + /* step2 : Send slave address and read command. */ + ret = SendSlaveAddressReadCmd(handle); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + /* step3 : start receive data. */ + ret = BlockingMasterRxDataOptStepNormal(handle); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + /* step4 :send stop CMD. */ + ret = BlockingSendStopCommand(handle); + + return ret; +} + +/** + * @brief Send data in blocking mode. + * @param handle I2C handle. + * @param devAddr Slave Device Address. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be sent. + * @param timeout Timeout period,unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_MasterWriteBlocking(I2C_Handle *handle, unsigned short devAddr, unsigned char *wData, + unsigned int dataSize, unsigned int timeout) +{ + I2C_ASSERT_PARAM(handle != NULL && wData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(devAddr <= I2C_MAX_DEV_ADDR, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(timeout > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); /* Status check. */ + + BASE_StatusType ret = BASE_STATUS_OK; + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + /* Configuring I2C Parameters. */ + handle->state = I2C_STATE_BUSY_MASTER_TX; + handle->transferBuff = wData; + handle->transferSize = dataSize; + handle->transferCount = 0; + handle->timeout = timeout; + SetSlaveDevAddr(handle, devAddr); + + /* Waiting for the i2c bus to be idle. */ + ret = WaitStatusReady(handle, I2C_BUS_IS_FREE, I2C_SEND_ADDR_STATUS_READ); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + + /* step1 : Parameter Settings and startup Control. */ + ret = I2C_ConfigParametersAndStartBlocking(handle, I2C_MASTER_STATUS); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + /* step2 : send slave addr */ + ret = SendSlaveAddressWriteCmd(handle); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + /* step3 : Send to slave data */ + ret = BlockingMasterTxDataOptStepNormal(handle); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + /* step4 : send stop CMD */ + ret = BlockingSendStopCommand(handle); + + return ret; +} + +/** + * @brief Receiving data in blocking mode as slave. + * @param handle I2C handle. + * @param rData Address of the data buff to be receiving. + * @param dataSize Number of the data to be receiving. + * @param timeout Timeout period,unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SlaveReadBlocking(I2C_Handle *handle, unsigned char *rData, + unsigned int dataSize, unsigned int timeout) +{ + I2C_ASSERT_PARAM(handle != NULL && rData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(timeout > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); + + BASE_StatusType ret = BASE_STATUS_OK; + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + + /* Configuring I2C Parameters. */ + handle->state = I2C_STATE_BUSY_SLAVE_RX; + handle->transferBuff = rData; + handle->transferSize = dataSize; + handle->transferCount = 0; + handle->timeout = timeout; + + /* step1 : Parameter Settings. */ + I2C_ConfigParametersAndStartBlocking(handle, I2C_SLAVE_STATUS); + /* step2 : Waiting for slave address match. */ + ret = WaitStatusReady(handle, SLAVE_ADDRESS_MATCH, I2C_OPERATION_WRITE); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + /* step3 : Slave receives data from the master device. */ + ret = BlockingSlaveRxDataOptStepNormal(handle); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + /* step4 : Send stop CMD */ + ret = BlockingSendStopCommand(handle); + + return ret; +} + +/** + * @brief Send data in blocking mode as slave. + * @param handle I2C handle. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be sent. + * @param timeout Timeout period,unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SlaveWriteBlocking(I2C_Handle *handle, unsigned char *wData, + unsigned int dataSize, unsigned int timeout) +{ + I2C_ASSERT_PARAM(handle != NULL && wData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(timeout > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); + + BASE_StatusType ret = BASE_STATUS_OK; + /* Clean interrupt */ + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + + /* Configuring Transmission Parameters of I2C. */ + handle->state = I2C_STATE_BUSY_SLAVE_TX; + handle->transferBuff = wData; + handle->transferSize = dataSize; + handle->transferCount = 0; + handle->timeout = timeout; + + /* Parameter Settings. */ + I2C_ConfigParametersAndStartBlocking(handle, I2C_SLAVE_STATUS); + + /* step1 : Waiting for slave address match. */ + ret = WaitStatusReady(handle, SLAVE_ADDRESS_MATCH, I2C_OPERATION_READ); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + /* step2 : Slave send data to the master device. */ + while (handle->transferCount < (handle->transferSize - 1)) { + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_RD_TACK_S_TD_RACK, *handle->transferBuff); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + handle->transferBuff++; + handle->transferCount++; + } + /* step3 : Slave send last data without ack to the master device. */ + if (handle->transferCount == (handle->transferSize - 1)) { + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_M_RD_TNACK_S_TD_RNACK, *handle->transferBuff); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + } + /* step4 : send stop CMD */ + ret = BlockingSendStopCommand(handle); + + return ret; +} + +/** + * @brief Receiving data in interrupts mode. + * @param handle I2C handle. + * @param devAddr Slave Device Address. + * @param rData Address of the data buff to be receiving. + * @param dataSize Number of the data to be receiving. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_MasterReadIT(I2C_Handle *handle, unsigned short devAddr, + unsigned char *rData, unsigned int dataSize) +{ + I2C_ASSERT_PARAM(handle != NULL && rData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(devAddr <= I2C_MAX_DEV_ADDR, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); + + /* Configuring I2C Parameters. */ + handle->state = I2C_STATE_BUSY_MASTER_RX; + handle->transferBuff = rData; + handle->transferSize = dataSize; + handle->transferCount = 0; + SetSlaveDevAddr(handle, devAddr); + handle->handleEx.txReadCmdCount = 0; + handle->handleEx.sendAddrStatus = I2C_SEND_ADDR_STATUS_READ; + + /* Clean interrupt */ + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; + + /* Enable interrupt */ + handle->baseAddress->I2C_INTR_EN.reg = I2C_CFG_INTERRUPT_MASTER_RX; + + return BASE_STATUS_OK; +} + +/** + * @brief Send data in interrupts mode. + * @param handle I2C handle. + * @param devAddr Slave Device Address. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_MasterWriteIT(I2C_Handle *handle, unsigned short devAddr, + unsigned char *wData, unsigned int dataSize) +{ + I2C_ASSERT_PARAM(handle != NULL && wData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(devAddr <= I2C_MAX_DEV_ADDR, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); + + /* Configuring I2C Parameters. */ + handle->state = I2C_STATE_BUSY_MASTER_TX; + handle->transferBuff = wData; + handle->transferSize = dataSize; + handle->transferCount = 0; + SetSlaveDevAddr(handle, devAddr); + handle->handleEx.txReadCmdCount = 0; + handle->handleEx.sendAddrStatus = I2C_SEND_ADDR_STATUS_WRITE; + + /* Clean interrupt */ + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_RAW_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; + + /* Enable interrupt */ + handle->baseAddress->I2C_INTR_EN.reg = I2C_CFG_INTERRUPT_MASTER_TX; + + return BASE_STATUS_OK; +} + +/** + * @brief Receiving data in interrupts mode as slave. + * @param handle I2C handle. + * @param rData Address of the data buff to be receiving. + * @param dataSize Number of the data to be receiving. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SlaveReadIT(I2C_Handle *handle, unsigned char *rData, unsigned int dataSize) +{ + BASE_StatusType ret = BASE_STATUS_OK; + + I2C_ASSERT_PARAM(handle != NULL && rData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); + + /* Configuring Transmission Parameters of I2C. */ + handle->state = I2C_STATE_BUSY_SLAVE_RX; + handle->transferBuff = rData; + handle->transferSize = dataSize; + handle->transferCount = 0; + + /* Configuring the I2C Timing */ + ret = I2C_SlaveMultiplexIT(handle); + + return ret; +} + +/** + * @brief Send data in interrupts mode as slave. + * @param handle I2C handle. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SlaveWriteIT(I2C_Handle *handle, unsigned char *wData, unsigned int dataSize) +{ + BASE_StatusType ret = BASE_STATUS_OK; + + I2C_ASSERT_PARAM(handle != NULL && wData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); + + /* Configuring Transmission Parameters of I2C. */ + handle->state = I2C_STATE_BUSY_SLAVE_TX; + handle->transferBuff = wData; + handle->transferSize = dataSize; + handle->transferCount = 0; + + /* Configuring the I2C Timing */ + ret = I2C_SlaveMultiplexIT(handle); + return ret; +} + +/** + * @brief Receiving data in DMA mode. + * @param handle I2C handle. + * @param devAddr Slave Device Address. + * @param rData Address of the data buff to be receiving. + * @param dataSize Number of the data to be receiving. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_MasterReadDMA(I2C_Handle *handle, unsigned short devAddr, + unsigned char *rData, unsigned int dataSize) +{ + I2C_ASSERT_PARAM(handle != NULL && rData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /* Check the DMA transfer handle and channel. */ + I2C_ASSERT_PARAM(handle->dmaHandle != NULL); + I2C_PARAM_CHECK_WITH_RET((handle->txDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET((handle->rxDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET((handle->rxDmaCh != handle->txDmaCh), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(devAddr <= I2C_MAX_DEV_ADDR, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); + + BASE_StatusType ret = BASE_STATUS_OK; + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + + /* Configuring I2C Parameters. */ + handle->state = I2C_STATE_BUSY_MASTER_RX; + handle->transferBuff = rData; + handle->transferSize = dataSize; + handle->transferCount = 0; + SetSlaveDevAddr(handle, devAddr); + + /* Waiting for the i2c bus to be idle. */ + ret = WaitStatusReady(handle, I2C_BUS_IS_FREE, I2C_SEND_ADDR_STATUS_READ); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_S, 0); /* Sets the start command to be sent. */ + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return ret; + } + ret = SendSlaveAddressReadCmd(handle); /* Send Address to Slave. */ + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + ret = I2cTransferDataDma(handle); + return ret; +} + +/** + * @brief Send data in DMA mode. + * @param handle I2C handle. + * @param devAddr Slave Device Address. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_MasterWriteDMA(I2C_Handle *handle, unsigned short devAddr, + unsigned char *wData, unsigned int dataSize) +{ + I2C_ASSERT_PARAM(handle != NULL && wData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /* Check the DMA transfer handle and channel. */ + I2C_ASSERT_PARAM(handle->dmaHandle != NULL); + I2C_PARAM_CHECK_WITH_RET((handle->txDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(devAddr <= I2C_MAX_DEV_ADDR, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); + + BASE_StatusType ret = BASE_STATUS_OK; + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + + /* Waiting for the i2c bus to be idle. */ + ret = WaitStatusReady(handle, I2C_BUS_IS_FREE, I2C_SEND_ADDR_STATUS_READ); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SetErrorHandling(handle); + return ret; + } + /* Configuring I2C Parameters. */ + handle->state = I2C_STATE_BUSY_MASTER_TX; + handle->transferBuff = wData; + handle->transferSize = dataSize; + handle->transferCount = 0; + SetSlaveDevAddr(handle, devAddr); + + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; + /* Send I2C start */ + ret = SetTxFIFODataAndCmd(handle, I2C_CMD_S, 0); /* Sets the start command to be sent. */ + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return ret; + } + /* send slave addr */ + ret = SendSlaveAddressWriteCmd(handle); + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return ret; + } + ret = I2cTransferDataDma(handle); + + return ret; +} + +/** + * @brief Receiving data in DMA mode as slave. + * @param handle I2C handle. + * @param rData Address of the data buff to be receiving. + * @param dataSize Number of the data to be receiving. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SlaveReadDMA(I2C_Handle *handle, unsigned char *rData, unsigned int dataSize) +{ + I2C_ASSERT_PARAM(handle != NULL && rData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /* Check the DMA transfer handle and channel. */ + I2C_ASSERT_PARAM(handle->dmaHandle != NULL); + I2C_PARAM_CHECK_WITH_RET((handle->txDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET((handle->rxDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET((handle->rxDmaCh != handle->txDmaCh), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); + + BASE_StatusType ret = BASE_STATUS_OK; + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + /* Configuring Transmission Parameters of I2C. */ + handle->state = I2C_STATE_BUSY_SLAVE_RX; + handle->transferSize = dataSize; + handle->transferBuff = rData; + handle->transferCount = 0; + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_UNSET; + + /* Waiting for the address to be matched. */ + ret = WaitStatusReady(handle, SLAVE_ADDRESS_MATCH, I2C_OPERATION_WRITE); + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return ret; + } + ret = I2cTransferDataDma(handle); + return ret; +} + +/** + * @brief Send data in DMA mode as slave. + * @param handle I2C handle. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SlaveWriteDMA(I2C_Handle *handle, unsigned char *wData, unsigned int dataSize) +{ + I2C_ASSERT_PARAM(handle != NULL && wData != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /* Check the DMA transfer handle and channel. */ + I2C_ASSERT_PARAM(handle->dmaHandle != NULL); + I2C_PARAM_CHECK_WITH_RET((handle->txDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + I2C_PARAM_CHECK_WITH_RET(handle->state == I2C_STATE_READY, BASE_STATUS_ERROR); + + BASE_StatusType ret = BASE_STATUS_OK; + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + /* Configuring Transmission Parameters of I2C. */ + handle->state = I2C_STATE_BUSY_SLAVE_TX; + handle->transferSize = dataSize; + handle->transferCount = 0; + handle->transferBuff = wData; + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_UNSET; + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + /* Waiting for the address to be matched. */ + ret = WaitStatusReady(handle, SLAVE_ADDRESS_MATCH, I2C_OPERATION_WRITE); + if (ret != BASE_STATUS_OK) { + SetErrorHandling(handle); + return ret; + } + ret = I2cTransferDataDma(handle); + return ret; +} + +/** + * @brief Interrupt Handling Function. + * @param handle Handle pointers + * @retval None + */ +void HAL_I2C_IrqHandler(void *handle) +{ + I2C_Handle *i2cHandle = (I2C_Handle *)handle; + I2C_ASSERT_PARAM(i2cHandle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(i2cHandle->baseAddress)); + + unsigned int status; + /* Get the masked interrupt value. */ + status = i2cHandle->baseAddress->I2C_INTR_STAT.reg; + if (status & I2C_ERROR_BIT_MASK) { /* Error detection. */ + IsInterruptErrorStatus(i2cHandle, status); + return; + } + + /* Callback interrupt handler function. */ + InterruptHandle(i2cHandle, status); + if ((i2cHandle->transferCount >= i2cHandle->transferSize) && + (!(status & (I2C_INTR_RAW_ALL_CMD_DONE_MASK | I2C_INTR_RAW_STOP_DET_MASK)))) { + if (i2cHandle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < I2C_MAX_FIFO_SIZE) { + i2cHandle->baseAddress->I2C_TX_FIFO.reg = + (((unsigned int)I2C_CMD_P << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + i2cHandle->baseAddress->I2C_INTR_EN.BIT.tx_fifo_not_full_en = BASE_CFG_DISABLE; + i2cHandle->transferCount++; + } + } + i2cHandle->baseAddress->I2C_INTR_RAW.reg = (I2C_INTR_RAW_TX_FIFO_NOT_FULL_MASK | I2C_INTR_RAW_RX_FIFO_FULL_MASK); + /* After all data transmission is complete, call the user's callback function. */ + InterruptAllDoneHandle(i2cHandle, status); +} \ No newline at end of file diff --git a/src/drivers/i2c/i2c_v3/src/i2c_ex.c b/src/drivers/i2c/i2c_v3/src/i2c_ex.c new file mode 100644 index 0000000000000000000000000000000000000000..9a666ea3567d0fb7ed60ac1c7d227c34399e272e --- /dev/null +++ b/src/drivers/i2c/i2c_v3/src/i2c_ex.c @@ -0,0 +1,166 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file i2c_ex.c + * @author MCU Driver Team + * @brief I2C module driver + * @details The header file contains the following declaration: + * + Setting the Special Function Configuration. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "i2c_ex.h" + +/* Macro definitions ---------------------------------------------------------*/ + +/** + * @brief Set data transfer sequence. + * @param handle: I2C handle. + * @param sequence: data transfer sequence enumeration value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SetDataTransferSequenceEx(I2C_Handle *handle, I2C_DataTransferSequenceType sequence) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(IsI2cDataTransferSequence(sequence), BASE_STATUS_ERROR); + /**< Data Transfer Sequence. 0:I2C_BIG_BIT_FIRST, 1:I2C_LITTLE_BIT_FIRST. */ + handle->baseAddress->I2C_MODE.BIT.lit_end = sequence; + return BASE_STATUS_OK; +} + +/** + * @brief Set I2C clock stretching function. + * @param handle: I2C handle. + * @param clkStretch: clock stretching enumeration value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SetSclStretchModeEx(I2C_Handle *handle, I2C_ClockStretchType clkStretch) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(IsI2cClockStretchValue(clkStretch), BASE_STATUS_ERROR); + /**< Clock stretching enable. 0:enable, 1:disable. */ + handle->baseAddress->I2C_MODE.BIT.scl_stretch_disable = clkStretch; + return BASE_STATUS_OK; +} + +/** + * @brief Set I2C SCL low-level timeout. + * @param handle: I2C handle. + * @param sclLowTimeout: SCL low-level timeout value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SetSclLowTimeoutEx(I2C_Handle *handle, unsigned int sclLowTimeout) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(IsI2cSclLowTimeout(sclLowTimeout), BASE_STATUS_ERROR); + /* The unit of bus free time is I2C working clock cycle. */ + handle->baseAddress->I2C_SCL_TIMEOUT.BIT.scl_low_timeout = sclLowTimeout; + return BASE_STATUS_OK; +} + +/** + * @brief Set I2C bus idle threshold value. + * @param handle: I2C handle. + * @param busFreeTime: bus idle threshold value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SetBusFreeTimeEx(I2C_Handle *handle, unsigned int busFreeTime) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(IsI2cBusFreeTime(busFreeTime), BASE_STATUS_ERROR); + /* The unit of bus free time is I2C working clock cycle. */ + handle->baseAddress->I2C_BUS_FREE.BIT.bus_free_time = busFreeTime; + return BASE_STATUS_OK; +} + +/** + * @brief Set I2C slave receive 10-bit slave addressing. + * @param handle: I2C handle. + * @param arg: slave special function set enumeration value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_Set10BitSlaveEnableEx(I2C_Handle *handle) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /**< Enable the slave receives the 10bit addressing. */ + handle->baseAddress->I2C_OWN_ADDR.BIT.i2c_10bit_slave_en = BASE_CFG_SET; + return BASE_STATUS_OK; +} + +/** + * @brief Set I2C slave receive device ID address. + * @param handle: I2C handle. + * @param arg: slave special function set enumeration value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SetDeviceIdAddressEnableEx(I2C_Handle *handle) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /**< Enable the function of receiving device ID addresses. */ + handle->baseAddress->I2C_OWN_ADDR.BIT.i2c_device_id_en = BASE_CFG_SET; + return BASE_STATUS_OK; +} + +/** + * @brief Set I2C slave receive start byte address. + * @param handle: I2C handle. + * @param arg: slave special function set enumeration value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SetStartByteEnableEx(I2C_Handle *handle) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + handle->baseAddress->I2C_OWN_ADDR.BIT.i2c_start_byte_en = BASE_CFG_SET; /**< Enable receiving START Byte Address. */ + return BASE_STATUS_OK; +} + +/** + * @brief Set I2C slave own address mask. + * @param handle: I2C handle. + * @param addrMask: own address mask. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SetOwnAddressMaskEx(I2C_Handle *handle, unsigned int addrMask) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(IsI2cOwnAddressOrMask(addrMask), BASE_STATUS_ERROR); + handle->baseAddress->I2C_OWN_ADDR.BIT.own_address_mask = addrMask; /**< Slave's own address mask. */ + return BASE_STATUS_OK; +} + +/** + * @brief Set I2C slave XMBus address mask. + * @param handle: I2C handle. + * @param addrMask: XMBus address mask. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_I2C_SetOwnXmbAddressMaskEx(I2C_Handle *handle, unsigned int addrMask) +{ + I2C_ASSERT_PARAM(handle != NULL); + I2C_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + I2C_PARAM_CHECK_WITH_RET(IsXMBusAddressOrMask(addrMask), BASE_STATUS_ERROR); + handle->baseAddress->XMB_DEV_ADDR.BIT.xmb_address_mask = addrMask; /**< The second own address mask as slave. */ + return BASE_STATUS_OK; +} diff --git a/src/drivers/iocmg/common/iocmg.h b/src/drivers/iocmg/common/iocmg.h index 5127d7a69a2a61c651b2a0d1f21b9ad6b5a73790..cb8cc328cba5e60d46fd8de4868beda72ab7b3be 100644 --- a/src/drivers/iocmg/common/iocmg.h +++ b/src/drivers/iocmg/common/iocmg.h @@ -59,6 +59,7 @@ typedef struct { * @{ */ /* Exported global functions ------------------------------------------------- */ + IOCMG_Status HAL_IOCMG_Init(IOCMG_Handle* handle); IOCMG_Status HAL_IOCMG_SetPinAltFuncMode(unsigned int pinTypedef); IOCMG_Status HAL_IOCMG_SetPinPullMode(unsigned int pinTypedef, IOCMG_PullMode pullMode); diff --git a/src/drivers/iocmg/iocmg_v0/inc/iocmg_ip.h b/src/drivers/iocmg/iocmg_v0/inc/iocmg_ip.h index 0f6169a282c79259b2050f9e969e10139fe13ec0..d29c35792f63e44a61df0c1930efa9c7884e7433 100644 --- a/src/drivers/iocmg/iocmg_v0/inc/iocmg_ip.h +++ b/src/drivers/iocmg/iocmg_v0/inc/iocmg_ip.h @@ -136,6 +136,7 @@ typedef struct { */ static inline void DCL_IOCMG_SetRegValue(IOCMG_REG *iocmgRegx, unsigned int regValue) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); iocmgRegx->reg = regValue; } @@ -147,6 +148,7 @@ static inline void DCL_IOCMG_SetRegValue(IOCMG_REG *iocmgRegx, unsigned int regV */ static inline unsigned int DCL_IOCMG_GetRegValue(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return iocmgRegx->reg; } @@ -159,6 +161,7 @@ static inline unsigned int DCL_IOCMG_GetRegValue(IOCMG_REG *iocmgRegx) */ static inline void DCL_IOCMG_SetFuncNum(IOCMG_REG *iocmgRegx, IOCMG_FuncMode funcnum) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); IOCMG_PARAM_CHECK_NO_RET(funcnum < FUNC_MODE_MAX && funcnum >= FUNC_MODE_0); iocmgRegx->BIT.func = funcnum; @@ -171,6 +174,7 @@ static inline void DCL_IOCMG_SetFuncNum(IOCMG_REG *iocmgRegx, IOCMG_FuncMode fun */ static inline IOCMG_FuncMode DCL_IOCMG_GetFuncMode(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return iocmgRegx->BIT.func; } @@ -183,6 +187,7 @@ static inline IOCMG_FuncMode DCL_IOCMG_GetFuncMode(IOCMG_REG *iocmgRegx) */ static inline void DCL_IOCMG_SetDriveRate(IOCMG_REG *iocmgRegx, IOCMG_DriveRate driveRate) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); IOCMG_PARAM_CHECK_NO_RET(driveRate < DRIVER_RATE_MAX && driveRate >= DRIVER_RATE_4); iocmgRegx->BIT.ds = driveRate; @@ -195,6 +200,7 @@ static inline void DCL_IOCMG_SetDriveRate(IOCMG_REG *iocmgRegx, IOCMG_DriveRate */ static inline IOCMG_DriveRate DCL_IOCMG_GetDriveRate(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return iocmgRegx->BIT.ds; } @@ -207,6 +213,7 @@ static inline IOCMG_DriveRate DCL_IOCMG_GetDriveRate(IOCMG_REG *iocmgRegx) */ static inline void DCL_IOCMG_SetPullMode(IOCMG_REG *iocmgRegx, IOCMG_PullMode pullMode) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); IOCMG_PARAM_CHECK_NO_RET(pullMode < PULL_MODE_MAX && pullMode >= PULL_NONE); iocmgRegx->BIT.pu = (pullMode & 0x02) >> 1; /* 10b: pull up mode */ @@ -220,6 +227,7 @@ static inline void DCL_IOCMG_SetPullMode(IOCMG_REG *iocmgRegx, IOCMG_PullMode pu */ static inline IOCMG_PullMode DCL_IOCMG_GetPullMode(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); unsigned int pullUpMode = iocmgRegx->BIT.pu; unsigned int pullDownMode = iocmgRegx->BIT.pd; @@ -234,6 +242,7 @@ static inline IOCMG_PullMode DCL_IOCMG_GetPullMode(IOCMG_REG *iocmgRegx) */ static inline void DCL_IOCMG_SetLevelShiftRate(IOCMG_REG *iocmgRegx, IOCMG_LevelShiftRate levelShiftRate) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); IOCMG_PARAM_CHECK_NO_RET(levelShiftRate < LEVEL_SHIFT_RATE_MAX && levelShiftRate >= LEVEL_SHIFT_RATE_FAST); iocmgRegx->BIT.sr = levelShiftRate; @@ -246,6 +255,7 @@ static inline void DCL_IOCMG_SetLevelShiftRate(IOCMG_REG *iocmgRegx, IOCMG_Level */ static inline IOCMG_LevelShiftRate DCL_IOCMG_GetLevelShiftRate(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return iocmgRegx->BIT.sr; } @@ -258,6 +268,7 @@ static inline IOCMG_LevelShiftRate DCL_IOCMG_GetLevelShiftRate(IOCMG_REG *iocmgR */ static inline void DCL_IOCMG_SetSchmidtMode(IOCMG_REG *iocmgRegx, IOCMG_SchmidtMode schmidtMode) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); IOCMG_PARAM_CHECK_NO_RET(schmidtMode <= SCHMIDT_ENABLE && schmidtMode >= SCHMIDT_DISABLE); iocmgRegx->BIT.se = schmidtMode; @@ -270,6 +281,7 @@ static inline void DCL_IOCMG_SetSchmidtMode(IOCMG_REG *iocmgRegx, IOCMG_SchmidtM */ static inline IOCMG_SchmidtMode DCL_IOCMG_GetSchmidtMode(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return iocmgRegx->BIT.se; } @@ -330,9 +342,9 @@ static inline void DCL_IOCMG_SetOscClkDriveRate(IOCMG_OscClkDriveRate oscClkDriv /** * @brief Get iocmg OSC drive rate mode. * @param None. - * @retval oscClkDriveRate value of @ref IOCMG_DriveRate. + * @retval oscClkDriveRate value of @ref IOCMG_OscClkDriveRate. */ -static inline IOCMG_DriveRate DCL_IOCMG_GetOscClkDriveRate(void) +static inline IOCMG_OscClkDriveRate DCL_IOCMG_GetOscClkDriveRate(void) { return IOCMG->iocmg_6.BIT.osc_ds; } diff --git a/src/drivers/iocmg/iocmg_v0/src/iocmg.c b/src/drivers/iocmg/iocmg_v0/src/iocmg.c index c56ed8faf4ab13b058344c40833222cc80c296f6..126b0cd55ee618245d21d7c4369a44a64869fe53 100644 --- a/src/drivers/iocmg/iocmg_v0/src/iocmg.c +++ b/src/drivers/iocmg/iocmg_v0/src/iocmg.c @@ -112,9 +112,7 @@ IOCMG_FuncMode HAL_IOCMG_GetPinAltFuncMode(unsigned int pinTypedef) { /* get iocmg reg address */ IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); - if (!IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))) { - return IOCMG_REG_ADDR_ERROR; - } + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return DCL_IOCMG_GetFuncMode(iocmgRegx); } @@ -145,9 +143,7 @@ IOCMG_PullMode HAL_IOCMG_GetPinPullMode(unsigned int pinTypedef) { /* get iocmg reg address */ IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); - if (!IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))) { - return IOCMG_REG_ADDR_ERROR; - } + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return DCL_IOCMG_GetPullMode(iocmgRegx); } @@ -178,9 +174,7 @@ IOCMG_SchmidtMode HAL_IOCMG_GetPinSchmidtMode(unsigned int pinTypedef) { /* get iocmg reg address */ IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); - if (!IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))) { - return IOCMG_REG_ADDR_ERROR; - } + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return DCL_IOCMG_GetSchmidtMode(iocmgRegx); } @@ -212,9 +206,7 @@ IOCMG_LevelShiftRate HAL_IOCMG_GetPinLevelShiftRate(unsigned int pinTypedef) { /* get iocmg reg address */ IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); - if (!IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))) { - return IOCMG_REG_ADDR_ERROR; - } + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return DCL_IOCMG_GetLevelShiftRate(iocmgRegx); } @@ -245,9 +237,7 @@ IOCMG_DriveRate HAL_IOCMG_GetPinDriveRate(unsigned int pinTypedef) { /* get iocmg reg address */ IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); - if (!IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))) { - return IOCMG_REG_ADDR_ERROR; - } + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return DCL_IOCMG_GetDriveRate(iocmgRegx); } diff --git a/src/drivers/iocmg/iocmg_v1/inc/iocmg_ip.h b/src/drivers/iocmg/iocmg_v1/inc/iocmg_ip.h index 050b4cec599a076766f071bb6893b7d0edda6354..60d1f674f226c0c6d636c5fc8ca35c6e9dde1da1 100644 --- a/src/drivers/iocmg/iocmg_v1/inc/iocmg_ip.h +++ b/src/drivers/iocmg/iocmg_v1/inc/iocmg_ip.h @@ -136,6 +136,7 @@ typedef struct { */ static inline void DCL_IOCMG_SetRegValue(IOCMG_REG *iocmgRegx, unsigned int regValue) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); iocmgRegx->reg = regValue; } @@ -147,6 +148,7 @@ static inline void DCL_IOCMG_SetRegValue(IOCMG_REG *iocmgRegx, unsigned int regV */ static inline unsigned int DCL_IOCMG_GetRegValue(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return iocmgRegx->reg; } @@ -159,6 +161,7 @@ static inline unsigned int DCL_IOCMG_GetRegValue(IOCMG_REG *iocmgRegx) */ static inline void DCL_IOCMG_SetFuncNum(IOCMG_REG *iocmgRegx, IOCMG_FuncMode funcnum) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); IOCMG_PARAM_CHECK_NO_RET(funcnum < FUNC_MODE_MAX && funcnum >= FUNC_MODE_0); iocmgRegx->BIT.func = funcnum; @@ -171,6 +174,7 @@ static inline void DCL_IOCMG_SetFuncNum(IOCMG_REG *iocmgRegx, IOCMG_FuncMode fun */ static inline IOCMG_FuncMode DCL_IOCMG_GetFuncMode(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return iocmgRegx->BIT.func; } @@ -183,6 +187,7 @@ static inline IOCMG_FuncMode DCL_IOCMG_GetFuncMode(IOCMG_REG *iocmgRegx) */ static inline void DCL_IOCMG_SetDriveRate(IOCMG_REG *iocmgRegx, IOCMG_DriveRate driveRate) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); IOCMG_PARAM_CHECK_NO_RET(driveRate < DRIVER_RATE_MAX && driveRate >= DRIVER_RATE_4); iocmgRegx->BIT.ds = driveRate; @@ -195,6 +200,7 @@ static inline void DCL_IOCMG_SetDriveRate(IOCMG_REG *iocmgRegx, IOCMG_DriveRate */ static inline IOCMG_DriveRate DCL_IOCMG_GetDriveRate(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return iocmgRegx->BIT.ds; } @@ -207,6 +213,7 @@ static inline IOCMG_DriveRate DCL_IOCMG_GetDriveRate(IOCMG_REG *iocmgRegx) */ static inline void DCL_IOCMG_SetPullMode(IOCMG_REG *iocmgRegx, IOCMG_PullMode pullMode) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); IOCMG_PARAM_CHECK_NO_RET(pullMode < PULL_MODE_MAX && pullMode >= PULL_NONE); iocmgRegx->BIT.pu = (pullMode & 0x02) >> 1; /* 10b: pull up mode */ @@ -220,6 +227,7 @@ static inline void DCL_IOCMG_SetPullMode(IOCMG_REG *iocmgRegx, IOCMG_PullMode pu */ static inline IOCMG_PullMode DCL_IOCMG_GetPullMode(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); unsigned int pullUpMode = iocmgRegx->BIT.pu; unsigned int pullDownMode = iocmgRegx->BIT.pd; @@ -234,6 +242,7 @@ static inline IOCMG_PullMode DCL_IOCMG_GetPullMode(IOCMG_REG *iocmgRegx) */ static inline void DCL_IOCMG_SetLevelShiftRate(IOCMG_REG *iocmgRegx, IOCMG_LevelShiftRate levelShiftRate) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); IOCMG_PARAM_CHECK_NO_RET(levelShiftRate < LEVEL_SHIFT_RATE_MAX && levelShiftRate >= LEVEL_SHIFT_RATE_FAST); iocmgRegx->BIT.sr = levelShiftRate; @@ -246,6 +255,7 @@ static inline void DCL_IOCMG_SetLevelShiftRate(IOCMG_REG *iocmgRegx, IOCMG_Level */ static inline IOCMG_LevelShiftRate DCL_IOCMG_GetLevelShiftRate(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return iocmgRegx->BIT.sr; } @@ -258,6 +268,7 @@ static inline IOCMG_LevelShiftRate DCL_IOCMG_GetLevelShiftRate(IOCMG_REG *iocmgR */ static inline void DCL_IOCMG_SetSchmidtMode(IOCMG_REG *iocmgRegx, IOCMG_SchmidtMode schmidtMode) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); IOCMG_PARAM_CHECK_NO_RET(schmidtMode <= SCHMIDT_ENABLE && schmidtMode >= SCHMIDT_DISABLE); iocmgRegx->BIT.se = schmidtMode; @@ -270,6 +281,7 @@ static inline void DCL_IOCMG_SetSchmidtMode(IOCMG_REG *iocmgRegx, IOCMG_SchmidtM */ static inline IOCMG_SchmidtMode DCL_IOCMG_GetSchmidtMode(IOCMG_REG *iocmgRegx) { + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); return iocmgRegx->BIT.se; } @@ -330,9 +342,9 @@ static inline void DCL_IOCMG_SetOscClkDriveRate(IOCMG_OscClkDriveRate oscClkDriv /** * @brief Get iocmg OSC drive rate mode. * @param None. - * @retval oscClkDriveRate value of @ref IOCMG_DriveRate. + * @retval oscClkDriveRate value of @ref IOCMG_OscClkDriveRate. */ -static inline IOCMG_DriveRate DCL_IOCMG_GetOscClkDriveRate(void) +static inline IOCMG_OscClkDriveRate DCL_IOCMG_GetOscClkDriveRate(void) { return SYSCTRL1->XTAL_CFG.BIT.osc_ds; } diff --git a/src/drivers/iocmg/iocmg_v3/inc/iocmg_ip.h b/src/drivers/iocmg/iocmg_v3/inc/iocmg_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..57eb72eba34174e590e97eca4215add17a5e4b52 --- /dev/null +++ b/src/drivers/iocmg/iocmg_v3/inc/iocmg_ip.h @@ -0,0 +1,377 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file iocmg_ip.h + * @author MCU Driver Team + * @brief IOCMG module driver + * @details This file provides IOConfig register mapping structure. + */ + +/* Macro definitions */ +#ifndef McuMagicTag_IOCMG_IP_H +#define McuMagicTag_IOCMG_IP_H + +/* Includes ------------------------------------------------------------------ */ +#include "baseinc.h" +#include "ioconfig.h" +#include "iomap.h" +/* Macro definitions ---------------------------------------------------------*/ +#ifdef IOCMG_PARAM_CHECK + #define IOCMG_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM + #define IOCMG_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET + #define IOCMG_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else + #define IOCMG_ASSERT_PARAM(para) ((void)0U) + #define IOCMG_PARAM_CHECK_NO_RET(para) ((void)0U) + #define IOCMG_PARAM_CHECK_WITH_RET(param, ret) ((void)0U) +#endif +/** + * @addtogroup IOCMG + * @{ + */ + +/** + * @defgroup IOCMG_IP + * @{ + */ +#define IOCMG_BASE_ADDR_MASK 0xFFFF0000 +#define IOCMG_FUNC_NUM_MASK 0x0000000F +#define IOCMG_REG_VALUE_MASK 0x0000FFFF +/** + * @defgroup IOCMG_Param_Def IOCMG Parameters Definition + * @brief Description of IOCMG configuration parameters. + * @{ + */ +typedef enum { + FUNC_MODE_0 = 0u, + FUNC_MODE_1, + FUNC_MODE_2, + FUNC_MODE_3, + FUNC_MODE_4, + FUNC_MODE_5, + FUNC_MODE_6, + FUNC_MODE_7, + FUNC_MODE_8, + FUNC_MODE_9, + FUNC_MODE_10, + FUNC_MODE_11, + FUNC_MODE_12, + FUNC_MODE_13, + FUNC_MODE_14, + FUNC_MODE_15, + FUNC_MODE_MAX +} IOCMG_FuncMode; + +typedef enum { + SCHMIDT_DISABLE = 0u, + SCHMIDT_ENABLE +} IOCMG_SchmidtMode; + +typedef enum { + PULL_NONE = 0u, + PULL_DOWN, + PULL_UP, + PULL_BOTH, + PULL_MODE_MAX +} IOCMG_PullMode; + +typedef enum { + LEVEL_SHIFT_RATE_FAST = 0u, + LEVEL_SHIFT_RATE_SLOW, + LEVEL_SHIFT_RATE_MAX +} IOCMG_LevelShiftRate; + +typedef enum { + DRIVER_RATE_1 = 0u, + DRIVER_RATE_2, + DRIVER_RATE_3, + DRIVER_RATE_4, + DRIVER_RATE_MAX +} IOCMG_DriveRate; + +typedef enum { + OSC_CLK_DRIVER_RATE_1 = 0u, + OSC_CLK_DRIVER_RATE_2, + OSC_CLK_DRIVER_RATE_3, + OSC_CLK_DRIVER_RATE_4, + OSC_CLK_DRIVER_RATE_MAX +} IOCMG_OscClkDriveRate; + +typedef enum { + IOCMG_STATUS_OK, + IOCMG_BASE_ADDR_ERROR, + IOCMG_REG_ADDR_ERROR, + IOCMG_PIN_FUNC_ERROR, + IOCMG_PARAM_ERROR +} IOCMG_Status; + +/** + * @brief IOCMG extend handle, configuring some special parameters. + */ +typedef struct { +} IOCMG_ExtendHandle; +/** + * @} + */ + +/** + * @brief Get pins iocmg reg address + * @param pinTypedef the pin type defined in iomap.h + * @retval IOCMG_REG iocmg reg address. + */ +static inline IOCMG_REG* IOCMG_GetRegAddr(unsigned int pinTypedef) +{ + /* decode pin's iocmg reg offset address in base address, and conver value to point address */ + unsigned int iocmgBaseAddrValue = (uintptr_t)IOCMG_BASE; + unsigned int iocmgRegOffsetAddrValue = (pinTypedef >> 16) & 0x00000FFF; /* 16 : shift 16 bit */ + IOCMG_REG* iocmgRegxAddr = (IOCMG_REG*)(void*)(iocmgBaseAddrValue + iocmgRegOffsetAddrValue); + if (!IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegxAddr & IOCMG_BASE_ADDR_MASK))) { + return NULL; + } + return iocmgRegxAddr; +} + +/** + * @brief Set iocmg reg value. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @param regValue value of @ref IOCMG_REG. + * @retval None. + */ +static inline void DCL_IOCMG_SetRegValue(IOCMG_REG *iocmgRegx, unsigned int regValue) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + iocmgRegx->reg = regValue; +} + +/** + * @brief Get iocmg reg value. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @retval None. + */ +static inline unsigned int DCL_IOCMG_GetRegValue(IOCMG_REG *iocmgRegx) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + return iocmgRegx->reg; +} + +/** + * @brief Set iocmg function number mode. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @param funcnum value of @ref IOCMG_FuncMode. + * @retval None. + */ +static inline void DCL_IOCMG_SetFuncNum(IOCMG_REG *iocmgRegx, IOCMG_FuncMode funcnum) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + IOCMG_PARAM_CHECK_NO_RET(funcnum < FUNC_MODE_MAX && funcnum >= FUNC_MODE_0); + iocmgRegx->BIT.func = funcnum; +} + +/** + * @brief Get iocmg function number mode. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @retval Value of @ref IOCMG_FuncMode. + */ +static inline IOCMG_FuncMode DCL_IOCMG_GetFuncMode(IOCMG_REG *iocmgRegx) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + return iocmgRegx->BIT.func; +} + +/** + * @brief Set iocmg drive rate mode. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @param driveRate value of @ref IOCMG_DriveRate. + * @retval None. + */ +static inline void DCL_IOCMG_SetDriveRate(IOCMG_REG *iocmgRegx, IOCMG_DriveRate driveRate) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + IOCMG_PARAM_CHECK_NO_RET(driveRate < DRIVER_RATE_MAX && driveRate >= DRIVER_RATE_1); + iocmgRegx->BIT.ds = driveRate; +} + +/** + * @brief Get iocmg drive rate mode. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @retval Value of @ref IOCMG_DriveRate. + */ +static inline IOCMG_DriveRate DCL_IOCMG_GetDriveRate(IOCMG_REG *iocmgRegx) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + return iocmgRegx->BIT.ds; +} + +/** + * @brief Set iocmg pull up or down mode. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @param pullMode value of @ref IOCMG_PullMode. + * @retval None. + */ +static inline void DCL_IOCMG_SetPullMode(IOCMG_REG *iocmgRegx, IOCMG_PullMode pullMode) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + IOCMG_PARAM_CHECK_NO_RET(pullMode < PULL_MODE_MAX && pullMode >= PULL_NONE); + iocmgRegx->BIT.pu = (pullMode & 0x02) >> 1; /* 10b: pull up mode */ + iocmgRegx->BIT.pd = pullMode & 0x01; /* 01b: pull down mode */ +} + +/** + * @brief Get iocmg pull up or down mode. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @retval pullMode value of @ref IOCMG_PullMode. + */ +static inline IOCMG_PullMode DCL_IOCMG_GetPullMode(IOCMG_REG *iocmgRegx) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + unsigned int pullUpMode = iocmgRegx->BIT.pu; + unsigned int pullDownMode = iocmgRegx->BIT.pd; + return (pullUpMode << 1) | pullDownMode; /* 1: shift for up mode bit */ +} + +/** + * @brief Set iocmg level shift rate mode. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @param levelShiftRate value of @ref IOCMG_LevelShiftRate. + * @retval None. + */ +static inline void DCL_IOCMG_SetLevelShiftRate(IOCMG_REG *iocmgRegx, IOCMG_LevelShiftRate levelShiftRate) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + IOCMG_PARAM_CHECK_NO_RET(levelShiftRate < LEVEL_SHIFT_RATE_MAX && levelShiftRate >= LEVEL_SHIFT_RATE_FAST); + iocmgRegx->BIT.sr = levelShiftRate; +} + +/** + * @brief Get iocmg level shift rate mode. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @retval levelShiftRate value of @ref IOCMG_LevelShiftRate. + */ +static inline IOCMG_LevelShiftRate DCL_IOCMG_GetLevelShiftRate(IOCMG_REG *iocmgRegx) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + return iocmgRegx->BIT.sr; +} + +/** + * @brief Set iocmg schmidt enable mode. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @param schmidtMode value of @ref IOCMG_SchmidtMode. + * @retval None. + */ +static inline void DCL_IOCMG_SetSchmidtMode(IOCMG_REG *iocmgRegx, IOCMG_SchmidtMode schmidtMode) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + IOCMG_PARAM_CHECK_NO_RET(schmidtMode <= SCHMIDT_ENABLE && schmidtMode >= SCHMIDT_DISABLE); + iocmgRegx->BIT.se = schmidtMode; +} + +/** + * @brief Get iocmg schmidt enable mode. + * @param iocmgRegx Value of @ref IOCMG_REG. + * @retval schmidtMode value of @ref IOCMG_SchmidtMode. + */ +static inline IOCMG_SchmidtMode DCL_IOCMG_GetSchmidtMode(IOCMG_REG *iocmgRegx) +{ + IOCMG_ASSERT_PARAM(iocmgRegx != NULL); + IOCMG_ASSERT_PARAM(IsIOCMGInstance((void *)((uintptr_t)(void *)iocmgRegx & IOCMG_BASE_ADDR_MASK))); + return iocmgRegx->BIT.se; +} + +/** + * @brief set iocmg OSC clock output mode. + * @param mode function enable or not. + * @retval None. + */ +static inline void DCL_IOCMG_SetOscClkOutputMode(bool mode) +{ + IOCMG_ASSERT_PARAM(mode == BASE_CFG_ENABLE || mode == BASE_CFG_DISABLE); + SYSCTRL1->XTAL_CFG.BIT.ose_e = mode; +} + +/** + * @brief Get iocmg OSC clock output mode. + * @param None + * @retval None. + */ +static inline bool DCL_IOCMG_GetOscClkOutputMode(void) +{ + return SYSCTRL1->XTAL_CFG.BIT.ose_e; +} + +/** + * @brief set iocmg OSC clock output mode. + * @param mode function enable or not. + * @retval None. + */ +static inline void DCL_IOCMG_SetOscClkFuncMode(bool mode) +{ + IOCMG_ASSERT_PARAM(mode == BASE_CFG_ENABLE || mode == BASE_CFG_DISABLE); + SYSCTRL1->XTAL_CFG.BIT.osc_ie = mode; +} + +/** + * @brief Get iocmg OSC clock output enable mode. + * @param None. + * @retval None. + */ +static inline bool DCL_IOCMG_GetOscClkFuncMode(void) +{ + return SYSCTRL1->XTAL_CFG.BIT.osc_ie; +} + +/** + * @brief Set iocmg OSC drive rate mode. + * @param oscClkDriveRate value of @ref IOCMG_DriveRate. + * @retval None. + */ +static inline void DCL_IOCMG_SetOscClkDriveRate(IOCMG_OscClkDriveRate oscClkDriveRate) +{ + IOCMG_PARAM_CHECK_NO_RET(oscClkDriveRate < OSC_CLK_DRIVER_RATE_MAX && oscClkDriveRate >= OSC_CLK_DRIVER_RATE_1); + SYSCTRL1->XTAL_CFG.BIT.osc_ds = oscClkDriveRate; +} + +/** + * @brief Get iocmg OSC drive rate mode. + * @param None. + * @retval oscClkDriveRate value of @ref IOCMG_DriveRate. + */ +static inline IOCMG_OscClkDriveRate DCL_IOCMG_GetOscClkDriveRate(void) +{ + return SYSCTRL1->XTAL_CFG.BIT.osc_ds; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* McuMagicTag_IOCMG_IP_H */ \ No newline at end of file diff --git a/src/drivers/iocmg/iocmg_v3/src/iocmg.c b/src/drivers/iocmg/iocmg_v3/src/iocmg.c new file mode 100644 index 0000000000000000000000000000000000000000..00ebc773be9659505d435ae8410b0b87274f5875 --- /dev/null +++ b/src/drivers/iocmg/iocmg_v3/src/iocmg.c @@ -0,0 +1,266 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file iocmg.c + * @author MCU Driver Team + * @brief Provides functions about iocmg reg init and config. + */ + +/* Includes ---------------------------------------------------------------------- */ +#include "iocmg.h" +/* param definition -------------------------------------------------------------- */ +/* Function declaration----------------------------------------------------------- */ + +IOCMG_Status HAL_IOCMG_Init(IOCMG_Handle* handle); +IOCMG_Status HAL_IOCMG_SetPinAltFuncMode(unsigned int pinTypedef); +IOCMG_Status HAL_IOCMG_SetPinPullMode(unsigned int pinTypedef, IOCMG_PullMode pullMode); +IOCMG_Status HAL_IOCMG_SetPinSchmidtMode(unsigned int pinTypedef, IOCMG_SchmidtMode schmidtMode); +IOCMG_Status HAL_IOCMG_SetPinLevelShiftRate(unsigned int pinTypedef, IOCMG_LevelShiftRate levelShiftRate); +IOCMG_Status HAL_IOCMG_SetPinDriveRate(unsigned int pinTypedef, IOCMG_DriveRate driveRate); +IOCMG_Status HAL_IOCMG_SetOscClkOutputMode(bool mode); +IOCMG_Status HAL_IOCMG_SetOscClkFuncMode(bool mode); +IOCMG_Status HAL_IOCMG_SetOscClkDriveRate(IOCMG_OscClkDriveRate oscClkDriveRate); + +IOCMG_FuncMode HAL_IOCMG_GetPinAltFuncMode(unsigned int pinTypedef); +IOCMG_PullMode HAL_IOCMG_GetPinPullMode(unsigned int pinTypedef); +IOCMG_SchmidtMode HAL_IOCMG_GetPinSchmidtMode(unsigned int pinTypedef); +IOCMG_LevelShiftRate HAL_IOCMG_GetPinLevelShiftRate(unsigned int pinTypedef); +IOCMG_DriveRate HAL_IOCMG_GetPinDriveRate(unsigned int pinTypedef); +bool HAL_IOCMG_GetOscClkOutputMode(void); +bool HAL_IOCMG_GetOscClkFuncMode(void); +IOCMG_OscClkDriveRate HAL_IOCMG_GetOscClkDriveRate(void); +/* Function definiton----------------------------------------------------------- */ + +/** + * @brief Initial IOCMG reg by pin number and function mode. + * @param handle IOCMG_Handle. + * @retval status @ref IOCMG_Status. + */ +IOCMG_Status HAL_IOCMG_Init(IOCMG_Handle* handle) +{ + IOCMG_ASSERT_PARAM(handle != NULL); + IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(handle->pinTypedef); + IOCMG_REG regValue = {0}; + regValue.BIT.func = (handle->pinTypedef & IOCMG_FUNC_NUM_MASK); + regValue.BIT.ds = handle->driveRate; + regValue.BIT.pd = handle->pullMode & 0x01; /* bit0 : pd */ + regValue.BIT.pu = handle->pullMode >> 1; /* bit1 : pu */ + regValue.BIT.se = handle->schmidtMode; + regValue.BIT.sr = handle->levelShiftRate; + DCL_IOCMG_SetRegValue(iocmgRegx, regValue.reg); + return IOCMG_STATUS_OK; +} + +/** + * @brief Set pins as function mode + * @param pinTypedef the pin type defined in iomap.h + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_Status HAL_IOCMG_SetPinAltFuncMode(unsigned int pinTypedef) +{ + /* get iocmg reg address */ + IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); + /* get iocmg reg default value */ + unsigned int regValue = pinTypedef & IOCMG_REG_VALUE_MASK; + DCL_IOCMG_SetRegValue(iocmgRegx, regValue); + return IOCMG_STATUS_OK; +} + +/** + * @brief Get pins func number + * @param pinTypedef the pin type defined in iomap.h + * @retval pin func number @ref IOCMG_FuncMode. + */ +IOCMG_FuncMode HAL_IOCMG_GetPinAltFuncMode(unsigned int pinTypedef) +{ + /* get iocmg reg address */ + IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); + return DCL_IOCMG_GetFuncMode(iocmgRegx); +} + +/** + * @brief Set pins pull mode + * @param pinTypedef the pin type defined in iomap.h + * @param pullMode function define as @ref IOCMG_PullMode + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_Status HAL_IOCMG_SetPinPullMode(unsigned int pinTypedef, IOCMG_PullMode pullMode) +{ + IOCMG_PARAM_CHECK_WITH_RET(pullMode < PULL_MODE_MAX && pullMode >= PULL_NONE, IOCMG_PARAM_ERROR); + /* get iocmg reg address */ + IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); + DCL_IOCMG_SetPullMode(iocmgRegx, pullMode); + return IOCMG_STATUS_OK; +} + +/** + * @brief Get pins pull mode + * @param pinTypedef the pin type defined in iomap.h + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_PullMode HAL_IOCMG_GetPinPullMode(unsigned int pinTypedef) +{ + /* get iocmg reg address */ + IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); + return DCL_IOCMG_GetPullMode(iocmgRegx); +} + +/** + * @brief Set Pin Schmidt Mode + * @param pinTypedef the pin type defined in iomap.h + * @param schmidtMode function define as @ref IOCMG_SchmidtMode + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_Status HAL_IOCMG_SetPinSchmidtMode(unsigned int pinTypedef, IOCMG_SchmidtMode schmidtMode) +{ + IOCMG_PARAM_CHECK_WITH_RET(schmidtMode <= SCHMIDT_ENABLE && schmidtMode >= SCHMIDT_DISABLE, IOCMG_PARAM_ERROR); + /* get iocmg reg address */ + IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); + DCL_IOCMG_SetSchmidtMode(iocmgRegx, schmidtMode); + return IOCMG_STATUS_OK; +} + +/** + * @brief Get Pin Schmidt Mode + * @param pinTypedef the pin type defined in iomap.h + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_SchmidtMode HAL_IOCMG_GetPinSchmidtMode(unsigned int pinTypedef) +{ + /* get iocmg reg address */ + IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); + return DCL_IOCMG_GetSchmidtMode(iocmgRegx); +} + +/** + * @brief Set Pin level Shift Rate Mode + * @param pinTypedef the pin type defined in iomap.h + * @param schmidtMode function define as @ref IOCMG_SchmidtMode + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_Status HAL_IOCMG_SetPinLevelShiftRate(unsigned int pinTypedef, IOCMG_LevelShiftRate levelShiftRate) +{ + IOCMG_PARAM_CHECK_WITH_RET(levelShiftRate < LEVEL_SHIFT_RATE_MAX, IOCMG_PARAM_ERROR); + IOCMG_PARAM_CHECK_WITH_RET(levelShiftRate >= LEVEL_SHIFT_RATE_FAST, IOCMG_PARAM_ERROR); + /* get iocmg reg address */ + IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); + DCL_IOCMG_SetLevelShiftRate(iocmgRegx, levelShiftRate); + return IOCMG_STATUS_OK; +} + +/** + * @brief Get Pin Schmidt Mode + * @param pinTypedef the pin type defined in iomap.h + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_LevelShiftRate HAL_IOCMG_GetPinLevelShiftRate(unsigned int pinTypedef) +{ + /* get iocmg reg address */ + IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); + return DCL_IOCMG_GetLevelShiftRate(iocmgRegx); +} + +/** + * @brief Set Pin drive Rate Mode + * @param pinTypedef the pin type defined in iomap.h + * @param driveRate function define as @ref IOCMG_DriveRate + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_Status HAL_IOCMG_SetPinDriveRate(unsigned int pinTypedef, IOCMG_DriveRate driveRate) +{ + /* get iocmg reg address */ + IOCMG_PARAM_CHECK_WITH_RET(driveRate < DRIVER_RATE_MAX && driveRate >= DRIVER_RATE_1, IOCMG_PARAM_ERROR); + IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); + DCL_IOCMG_SetDriveRate(iocmgRegx, driveRate); + return IOCMG_STATUS_OK; +} + +/** + * @brief Get Pin drive Rate Mode + * @param pinTypedef the pin type defined in iomap.h + * @retval Value of @ref IOCMG_DriveRate. + */ +IOCMG_DriveRate HAL_IOCMG_GetPinDriveRate(unsigned int pinTypedef) +{ + /* get iocmg reg address */ + IOCMG_REG* iocmgRegx = IOCMG_GetRegAddr(pinTypedef); + return DCL_IOCMG_GetDriveRate(iocmgRegx); +} + +/** + * @brief Set OSC Pin clock output enable mode + * @param mode function enable or not + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_Status HAL_IOCMG_SetOscClkOutputMode(bool mode) +{ + IOCMG_ASSERT_PARAM(mode == BASE_CFG_ENABLE || mode == BASE_CFG_DISABLE); + DCL_IOCMG_SetOscClkOutputMode(mode); + return IOCMG_STATUS_OK; +} + +/** + * @brief Get OSC Pin clock output enable mode + * @retval bool enable or not + */ +bool HAL_IOCMG_GetOscClkOutputMode(void) +{ + return DCL_IOCMG_GetOscClkOutputMode(); +} + +/** + * @brief Set OSC Pin function enable mode + * @param mode function enable or not + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_Status HAL_IOCMG_SetOscClkFuncMode(bool mode) +{ + IOCMG_ASSERT_PARAM(mode == BASE_CFG_ENABLE || mode == BASE_CFG_DISABLE); + DCL_IOCMG_SetOscClkFuncMode(mode); + return IOCMG_STATUS_OK; +} + +/** + * @brief Get OSC Pin Pin function enable mode + * @retval bool enable or not + */ +bool HAL_IOCMG_GetOscClkFuncMode(void) +{ + return DCL_IOCMG_GetOscClkFuncMode(); +} + +/** + * @brief Set OSC Pin drive rate mode + * @param driveRate osc drive rate + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_Status HAL_IOCMG_SetOscClkDriveRate(IOCMG_OscClkDriveRate oscClkDriveRate) +{ + IOCMG_PARAM_CHECK_WITH_RET(oscClkDriveRate < OSC_CLK_DRIVER_RATE_MAX && \ + oscClkDriveRate >= OSC_CLK_DRIVER_RATE_1, IOCMG_PARAM_ERROR); + DCL_IOCMG_SetOscClkDriveRate(oscClkDriveRate); + return IOCMG_STATUS_OK; +} + +/** + * @brief Get OSC Pin drive rate mode + * @retval IOCMG_Status @ref IOCMG_Status. + */ +IOCMG_OscClkDriveRate HAL_IOCMG_GetOscClkDriveRate(void) +{ + return DCL_IOCMG_GetOscClkDriveRate(); +} \ No newline at end of file diff --git a/src/drivers/iwdg/common/inc/iwdg.h b/src/drivers/iwdg/common/inc/iwdg.h index 48dc1086b3c3423d2666d172bcf8bb41b6db8128..466de4b2c28bdd90f95afd2b13c46bd348b44880 100644 --- a/src/drivers/iwdg/common/inc/iwdg.h +++ b/src/drivers/iwdg/common/inc/iwdg.h @@ -71,7 +71,6 @@ typedef struct _IWDG_Handle { * @defgroup IWDG_API_Declaration IWDG HAL API * @{ */ - BASE_StatusType HAL_IWDG_Init(IWDG_Handle *handle); void HAL_IWDG_SetTimeValue(IWDG_Handle *handle, unsigned int timeValue, IWDG_TimeType timeType); unsigned int HAL_IWDG_GetLoadValue(IWDG_Handle *handle); @@ -81,7 +80,6 @@ void HAL_IWDG_Start(IWDG_Handle *handle); void HAL_IWDG_Stop(IWDG_Handle *handle); void HAL_IWDG_RegisterCallback(IWDG_Handle *handle, IWDG_CallbackType callBackFunc); void HAL_IWDG_IrqHandler(void *handle); - /** * @} */ diff --git a/src/drivers/iwdg/iwdg_v0/inc/iwdg_ip.h b/src/drivers/iwdg/iwdg_v0/inc/iwdg_ip.h index 0b92c351eaee096da1dd57a62b985c5d09d50d9f..e519bd3aba06a7932e82508895b233c93fc09b74 100644 --- a/src/drivers/iwdg/iwdg_v0/inc/iwdg_ip.h +++ b/src/drivers/iwdg/iwdg_v0/inc/iwdg_ip.h @@ -286,23 +286,6 @@ static inline bool IsIwdgTimeType(IWDG_TimeType timeType) timeType == IWDG_TIME_UNIT_MS || timeType == IWDG_TIME_UNIT_US); } - -/** - * @brief check iwdg time value parameter. - * @param baseAddress Value of @ref IWDG_RegStruct - * @param timeValue time value - * @param timeType Value of @ref IWDG_TimeType. - * @retval Bool. - */ -static inline bool IsIwdgTimeValue(IWDG_RegStruct *baseAddress, float timeValue, IWDG_TimeType timeType) -{ - float clockFreq = (float)HAL_CRG_GetIpFreq((void *)baseAddress); - float maxSecond = (float)(0xFFFFFFFF / clockFreq); /* 0xFFFFFFFF max IWDG register value */ - return ((timeType == IWDG_TIME_UNIT_TICK && timeValue <= 0xFFFFFFFF) || - (timeType == IWDG_TIME_UNIT_S && maxSecond >= timeValue) || - (timeType == IWDG_TIME_UNIT_MS && maxSecond >= timeValue / FREQ_CONVERT_MS_UNIT) || - (timeType == IWDG_TIME_UNIT_US && maxSecond >= timeValue / FREQ_CONVERT_US_UNIT)); -} /** * @} */ diff --git a/src/drivers/iwdg/iwdg_v0/src/iwdg.c b/src/drivers/iwdg/iwdg_v0/src/iwdg.c index dcc57f0c50ec0af603c14102da0730e1ea3e458d..a05dd4da7f4863265a8498fe3d570cb1fcc592a0 100644 --- a/src/drivers/iwdg/iwdg_v0/src/iwdg.c +++ b/src/drivers/iwdg/iwdg_v0/src/iwdg.c @@ -28,8 +28,34 @@ #include "interrupt.h" #include "iwdg.h" +#define IWDG_COUNT_MAX 0xFFFFFFFF +#define TIME_CHANGE_NUM 1000 static unsigned int IWDG_CalculateRegTimeout(IWDG_RegStruct *baseAddress, float timeValue, IWDG_TimeType timeType); +/** + * @brief check iwdg time value parameter. + * @param baseAddress Value of @ref IWDG_RegStruct + * @param timeValue time value + * @param timeType Value of @ref IWDG_TimeType. + * @retval Bool. + */ +static bool IsIwdgTimeValue(IWDG_RegStruct *baseAddress, float timeValue, IWDG_TimeType timeType) +{ + unsigned int clockFreq = HAL_CRG_GetIpFreq((void *)baseAddress); /* Get IWDG clock freq. */ + if (clockFreq == 0) { + return false; + } + /* Get max count. */ + double maxSecValue = ((double)(IWDG_COUNT_MAX) / (double)clockFreq); + double maxMsValue = maxSecValue * TIME_CHANGE_NUM; + double maxUsValue = maxMsValue * TIME_CHANGE_NUM; + /* Check iwdg time value parameter. */ + return ((timeType == IWDG_TIME_UNIT_TICK && timeValue <= (float)IWDG_COUNT_MAX) || + (timeType == IWDG_TIME_UNIT_S && maxSecValue >= timeValue) || + (timeType == IWDG_TIME_UNIT_MS && maxMsValue >= timeValue) || + (timeType == IWDG_TIME_UNIT_US && maxUsValue >= timeValue)); +} + /** * @brief Initializing IWDG values * @param handle Value of @ref IWDG_handle. @@ -40,8 +66,7 @@ BASE_StatusType HAL_IWDG_Init(IWDG_Handle *handle) IWDG_ASSERT_PARAM(handle != NULL); IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); IWDG_PARAM_CHECK_WITH_RET(IsIwdgTimeType(handle->timeType), BASE_STATUS_ERROR); - IWDG_PARAM_CHECK_WITH_RET(IsIwdgTimeValue(handle->baseAddress, handle->timeValue, handle->timeType), - BASE_STATUS_ERROR); + /* baseaddress = IWDG */ HAL_IWDG_SetTimeValue(handle, handle->timeValue, handle->timeType); /* Set IWDG Reset and Interrupt */ @@ -91,7 +116,10 @@ void HAL_IWDG_SetTimeValue(IWDG_Handle *handle, unsigned int timeValue, IWDG_Tim IWDG_ASSERT_PARAM(handle != NULL); IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); IWDG_PARAM_CHECK_NO_RET(IsIwdgTimeType(handle->timeType)); - IWDG_PARAM_CHECK_NO_RET(IsIwdgTimeValue(handle->baseAddress, handle->timeValue, handle->timeType)); + /* Check iwdg time value parameter. */ + if (IsIwdgTimeValue(handle->baseAddress, timeValue, timeType) == false) { + return; + } /* handle->baseAddress only could be configured IWDG */ unsigned int value = IWDG_CalculateRegTimeout(handle->baseAddress, timeValue, timeType); DCL_IWDG_SetLoadValue(handle->baseAddress, value); diff --git a/src/drivers/iwdg/iwdg_v1/inc/iwdg_ip.h b/src/drivers/iwdg/iwdg_v1/inc/iwdg_ip.h index 470629db788364cc108d65b16477b2eb0d71c585..9cb8013a624d3b043e5a5e647dc2c191a595f676 100644 --- a/src/drivers/iwdg/iwdg_v1/inc/iwdg_ip.h +++ b/src/drivers/iwdg/iwdg_v1/inc/iwdg_ip.h @@ -322,6 +322,7 @@ static inline void DCL_IWDG_SetFreqDivValue(IWDG_RegStruct *iwdgx, IWDG_FreqDivT iwdgx->IWDOG_KEY.BIT.iwdg_key = IWDG_UNLOCK_REG_CMD; iwdgx->IWDOG_PRE_DIV.BIT.iwdg_pre_div = freqDiv; /* freqDiv parameters set */ iwdgx->IWDOG_KEY.BIT.iwdg_key = IWDG_UNLOCK_REG_CMD; + BASE_FUNC_DELAY_MS(200); /* IWDG need delay 200 us */ } /** @@ -412,22 +413,6 @@ static inline bool IsIwdgTimeType(IWDG_TimeType timeType) timeType == IWDG_TIME_UNIT_US); } -/** - * @brief check iwdg time value parameter. - * @param baseAddress Value of @ref IWDG_RegStruct - * @param timeValue time value - * @param timeType Value of @ref IWDG_TimeType. - * @retval Bool. - */ -static inline bool IsIwdgTimeValue(IWDG_RegStruct *baseAddress, float timeValue, IWDG_TimeType timeType) -{ - float clockFreq = (float)HAL_CRG_GetIpFreq((void *)baseAddress); - float maxSecond = (float)(0xFFFFFFFF / clockFreq); /* 0xFFFFFFFF max input value */ - return ((timeType == IWDG_TIME_UNIT_TICK && timeValue <= 0xFFFFFFFF) || - (timeType == IWDG_TIME_UNIT_S && maxSecond >= timeValue) || - (timeType == IWDG_TIME_UNIT_MS && maxSecond >= timeValue / FREQ_CONVERT_MS_UNIT) || - (timeType == IWDG_TIME_UNIT_US && maxSecond >= timeValue / FREQ_CONVERT_US_UNIT)); -} /** * @} */ diff --git a/src/drivers/iwdg/iwdg_v1/src/iwdg.c b/src/drivers/iwdg/iwdg_v1/src/iwdg.c index ff4181089e7d2eaed0ad8d7fa854692668d1df51..0d56be4fbce1955b943e33bb3378dfdc9f83722a 100644 --- a/src/drivers/iwdg/iwdg_v1/src/iwdg.c +++ b/src/drivers/iwdg/iwdg_v1/src/iwdg.c @@ -32,6 +32,8 @@ #define IWDG_LOAD_VALUE_LIMIT 255 #define IWDG_WINDOW_VALUE_UPPER_LIMIT 255 #define IWDG_WINDOW_VALUE_LOWER_LIMIT 5 +#define IWDG_COUNT_MAX 0xFF +#define TIME_CHANGE_NUM 1000 static unsigned int IWDG_CalculateRegTimeout(IWDG_RegStruct *baseAddress, float timeValue, IWDG_TimeType timeType); /** @@ -44,8 +46,6 @@ BASE_StatusType HAL_IWDG_Init(IWDG_Handle *handle) IWDG_ASSERT_PARAM(handle != NULL); IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); IWDG_PARAM_CHECK_WITH_RET(IsIwdgTimeType(handle->timeType), BASE_STATUS_ERROR); - IWDG_PARAM_CHECK_WITH_RET(IsIwdgTimeValue(handle->baseAddress, handle->timeValue, handle->timeType), - BASE_STATUS_ERROR); BASE_FUNC_DELAY_US(200); /* IWDG need delay 200 us */ /* IWDG frequency division value less than 256 */ unsigned int freqDivVal = (handle->freqDivValue > IWDG_FREQ_DIV_256) ? IWDG_FREQ_DIV_256 : handle->freqDivValue; @@ -84,6 +84,33 @@ static unsigned int IWDG_CalculateRegTimeout(IWDG_RegStruct *baseAddress, float return timeoutValue; } +/** + * @brief check iwdg time value parameter. + * @param baseAddress Value of @ref IWDG_RegStruct + * @param timeValue time value + * @param timeType Value of @ref IWDG_TimeType. + * @retval Bool. + */ +static bool IsIwdgTimeValue(IWDG_RegStruct *baseAddress, float timeValue, IWDG_TimeType timeType) +{ + unsigned int clockFreq = HAL_CRG_GetIpFreq((void *)baseAddress); /* Get IWDG clock freq. */ + IWDG_RegStruct *iwdgx = (IWDG_RegStruct *)baseAddress; + if (clockFreq == 0) { + return false; + } + /* Get IWDG clock prediv. */ + unsigned int preDiv = iwdgx->IWDOG_PRE_DIV.BIT.iwdg_pre_div; + preDiv = IWDG_COUNT_MAX * (BASE_CFG_SET << preDiv); + float maxSecValue = ((float)(preDiv) / (float)clockFreq); + float maxMsValue = maxSecValue * TIME_CHANGE_NUM; + float maxUsValue = maxMsValue * TIME_CHANGE_NUM; + /* Check iwdg time value parameter. */ + return ((timeType == IWDG_TIME_UNIT_TICK && timeValue <= (float)IWDG_COUNT_MAX) || + (timeType == IWDG_TIME_UNIT_S && maxSecValue >= timeValue) || + (timeType == IWDG_TIME_UNIT_MS && maxMsValue >= timeValue) || + (timeType == IWDG_TIME_UNIT_US && maxUsValue >= timeValue)); +} + /** * @brief Setting the load value of the IWDG counter. * @param handle Value of @ref IWDG_handle. @@ -96,7 +123,10 @@ void HAL_IWDG_SetTimeValue(IWDG_Handle *handle, unsigned int timeValue, IWDG_Tim IWDG_ASSERT_PARAM(handle != NULL); IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); IWDG_PARAM_CHECK_NO_RET(IsIwdgTimeType(timeType)); - IWDG_PARAM_CHECK_NO_RET(IsIwdgTimeValue(handle->baseAddress, timeValue, timeType)); + /* Check iwdg time value parameter. */ + if (IsIwdgTimeValue(handle->baseAddress, timeValue, timeType) == false) { + return; + } /* handle->baseAddress only could be configed IWDG or IWDG */ unsigned int value = IWDG_CalculateRegTimeout(handle->baseAddress, timeValue, timeType); unsigned int freqDiv = DCL_IWDG_GetFreqDivValue(handle->baseAddress); diff --git a/src/drivers/iwdg/iwdg_v1/src/iwdg_ex.c b/src/drivers/iwdg/iwdg_v1/src/iwdg_ex.c index 92a11f83534ee242a9310c1881317c12c4376e0c..1843ecd6f5a95cceed5b62b8e45f0bd2e4ddddbe 100644 --- a/src/drivers/iwdg/iwdg_v1/src/iwdg_ex.c +++ b/src/drivers/iwdg/iwdg_v1/src/iwdg_ex.c @@ -29,8 +29,37 @@ /* Macro definitions ---------------------------------------------------------*/ #define IWDG_WINDOW_VALUE_UPPER_LIMIT 255 #define IWDG_WINDOW_VALUE_LOWER_LIMIT 5 - +#define IWDG_COUNT_MAXEX 0xFF +#define TIME_CHANGE_NUMEX 1000 static unsigned int IWDG_CalculateRegTimeoutEx(IWDG_RegStruct *baseAddress, float timeValue, IWDG_TimeType timeType); + +/** + * @brief check iwdg time value parameter. + * @param baseAddress Value of @ref IWDG_RegStruct + * @param timeValue time value + * @param timeType Value of @ref IWDG_TimeType. + * @retval Bool. + */ +static bool IsIwdgTimeValueEx(IWDG_RegStruct *baseAddress, float timeValue, IWDG_TimeType timeType) +{ + unsigned int clockFreq = HAL_CRG_GetIpFreq((void *)baseAddress); /* Get IWDG clock freq. */ + if (clockFreq == 0) { + return false; + } + + IWDG_RegStruct *iwdgx = (IWDG_RegStruct *)baseAddress; + /* Get IWDG clock prediv. */ + unsigned int preDiv = IWDG_COUNT_MAXEX * (BASE_CFG_SET << iwdgx->IWDOG_PRE_DIV.BIT.iwdg_pre_div); + float maxSecValue = ((float)(preDiv) / (float)clockFreq); + float maxMsValue = maxSecValue * TIME_CHANGE_NUMEX; + float maxUsValue = maxMsValue * TIME_CHANGE_NUMEX; + /* Check iwdg time value parameter. */ + return ((timeType == IWDG_TIME_UNIT_TICK && timeValue <= IWDG_COUNT_MAXEX) || + (timeType == IWDG_TIME_UNIT_S && maxSecValue >= timeValue) || + (timeType == IWDG_TIME_UNIT_MS && maxMsValue >= timeValue) || + (timeType == IWDG_TIME_UNIT_US && maxUsValue >= timeValue)); +} + /** * @brief Setting the window value of the IWDG counter. * @param handle Value of @ref IWDG_handle. @@ -43,7 +72,12 @@ void HAL_IWDG_SetWindowValueEx(IWDG_Handle *handle, unsigned int windowValue, IW IWDG_ASSERT_PARAM(handle != NULL); IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); IWDG_PARAM_CHECK_NO_RET(IsIwdgTimeType(timeType)); - /* handle->baseAddress only could be configed IWDG or IWDG */ + /* Check iwdg time value parameter. */ + if (IsIwdgTimeValueEx(handle->baseAddress, windowValue, timeType) == false) { + return; + } + + /* handle->baseAddress only could be configed IWDG */ if (handle->baseAddress->IWDOG_CONTROL.BIT.window_mode_en == BASE_CFG_SET) { handle->timeType = timeType; unsigned int value = IWDG_CalculateRegTimeoutEx(handle->baseAddress, windowValue, timeType); diff --git a/src/drivers/iwdg/iwdg_v2/inc/iwdg_ex.h b/src/drivers/iwdg/iwdg_v2/inc/iwdg_ex.h new file mode 100644 index 0000000000000000000000000000000000000000..c6ecabf1d76d43fc1716b3219540cfdff199fdd9 --- /dev/null +++ b/src/drivers/iwdg/iwdg_v2/inc/iwdg_ex.h @@ -0,0 +1,50 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file iwdg_ex.h + * @author MCU Driver Team + * @brief IWDG module driver + * @details The header file contains the following declaration: + * + IWDG Set And Get Functions. + */ + +#ifndef McuMagicTag_IWDG_EX_H +#define McuMagicTag_IWDG_EX_H + +/* Includes ------------------------------------------------------------------*/ +#include "iwdg.h" +/** + * @addtogroup IWDG_IP + * @{ + */ + +/** + * @defgroup IWDG_API_EX_Declaration IWDG HAL API EX + * @{ + */ +unsigned int HAL_IWDG_GetWindowValueEx(IWDG_Handle *handle); +void HAL_IWDG_EnableWindowModeEx(IWDG_Handle *handle); +void HAL_IWDG_DisableWindowModeEx(IWDG_Handle *handle); + +/** + * @} + */ + +/** + * @} + */ +#endif /* McuMagicTag_IWDG_H */ \ No newline at end of file diff --git a/src/drivers/iwdg/iwdg_v2/inc/iwdg_ip.h b/src/drivers/iwdg/iwdg_v2/inc/iwdg_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..9d89eb1265ef7280021e3706eca2ebff4d556efb --- /dev/null +++ b/src/drivers/iwdg/iwdg_v2/inc/iwdg_ip.h @@ -0,0 +1,610 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file iwdg_ip.h + * @author MCU Driver Team + * @brief IWDG module driver + * @details The header file contains the following declaration: + * + IWDG configuration enums. + * + IWDG register structures. + * + IWDG DCL Functions. + * + Parameters check functions. + */ + +#ifndef McuMagicTag_IWDG_IP_H +#define McuMagicTag_IWDG_IP_H + +/* Includes ------------------------------------------------------------------*/ +#include "baseinc.h" + +/* Macro definition */ +#ifdef IWDG_PARAM_CHECK + #define IWDG_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM + #define IWDG_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET + #define IWDG_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else + #define IWDG_ASSERT_PARAM(para) ((void)0U) + #define IWDG_PARAM_CHECK_NO_RET(para) ((void)0U) + #define IWDG_PARAM_CHECK_WITH_RET(param, ret) ((void)0U) +#endif + +/** + * @addtogroup IWDG + * @{ + */ + +/** + * @defgroup IWDG_IP IWDG_IP + * @brief IWDG_IP: iwdg_v1. + * @{ + */ + +/** + * @defgroup IWDG_Param_Def IWDG Parameters Definition + * @brief Description of IWDG configuration parameters. + * @{ + */ +/* MACRO definitions -------------------------------------------------------*/ +#define FREQ_CONVERT_MS_UNIT 1000 +#define FREQ_CONVERT_US_UNIT 1000000 +#define IWDG_UNLOCK_REG_CMD 0x55 /* 0x55 CMD: key equal 0x55 will unlock all reg write function */ +#define IWDG_LOCK_REG_CMD 0xFF /* 0xFF CMD: key not equal 0x55 will lock reg write function except key reg */ + +/* Typedef definitions -------------------------------------------------------*/ +typedef enum { + IWDG_TIME_UNIT_TICK = 0x00000000U, + IWDG_TIME_UNIT_S = 0x00000001U, + IWDG_TIME_UNIT_MS = 0x00000002U, + IWDG_TIME_UNIT_US = 0x00000003U +} IWDG_TimeType; + +typedef enum { + IWDG_FREQ_DIV_4 = 0x00000000U, + IWDG_FREQ_DIV_8 = 0x00000001U, + IWDG_FREQ_DIV_16 = 0x00000002U, + IWDG_FREQ_DIV_32 = 0x00000003U, + IWDG_FREQ_DIV_64 = 0x00000004U, + IWDG_FREQ_DIV_128 = 0x00000005U, + IWDG_FREQ_DIV_256 = 0x00000006U, + IWDG_FREQ_DIV_512 = 0x00000007U, + IWDG_FREQ_DIV_1024 = 0x00000008U, + IWDG_FREQ_DIV_MAX +} IWDG_FreqDivType; + +/** + * @brief IWDG extend handle. + */ +typedef struct _IWDG_ExtendHandle { + unsigned int windowValue; +} IWDG_ExtendHandle; + +/** + * @brief IWDG user callback. + */ +typedef struct { + void (* CallbackFunc)(void *handle); /**< IWDG callback Function */ +} IWDG_UserCallBack; +/** + * @} + */ + +/** + * @defgroup IWDG_Reg_Def IWDG Register Definition + * @brief Description IWDG register mapping structure. + * @{ + */ +/** + * @brief IWDG load init value. + */ +typedef union { + unsigned int reg; + struct { + unsigned int iwdg_load : 12; /**< init value. */ + unsigned int reserved0 : 20; + } BIT; +} IWDG_LOAD_REG; + +/** + * @brief IWDG get current value. + */ +typedef union { + unsigned int reg; + struct { + unsigned int iwdg_value : 12; /**< current value. */ + unsigned int reserved0 : 20; + } BIT; +} IWDG_VALUE_REG; + +/** + * @brief IWDG set window value. + */ +typedef union { + unsigned int reg; + struct { + unsigned int iwdg_window : 12; /**< window value. */ + unsigned int reserved0 : 20; + } BIT; +} IWDG_WINDOW_REG; + +/** + * @brief IWDG cmd function value. + */ +typedef union { + unsigned int reg; + struct { + unsigned int iwdg_key : 8; /**< cmd function value. */ + unsigned int reserved0 : 24; + } BIT; +} IWDG_KEY_REG; + +/** + * @brief IWDG clk pre div value. + */ +typedef union { + unsigned int reg; + struct { + unsigned int iwdg_pre_div : 4; /**< clk pre div value. */ + unsigned int reserved0 : 28; + } BIT; +} IWDG_PRE_DIV_REG; + +/** + * @brief IWDG enable interrupt and reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int inten : 1; /**< enable interrupt. */ + unsigned int resen : 1; /**< enable reset. */ + unsigned int window_mode_en : 1; /**< enable window mode. */ + unsigned int reserved0 : 29; + } BIT; +} IWDG_CONTROL_REG; + +/** + * @brief IWDG orignal interrupt signal. + */ +typedef union { + unsigned int reg; + struct { + unsigned int iwdgris : 1; /**< original interrupt status. */ + unsigned int reserved0 : 31; + } BIT; +} IWDG_RIS_REG; + +/** + * @brief mask interrupt signal. + */ +typedef union { + unsigned int reg; + struct { + unsigned int iwdgmis : 1; /**< masked interrupt status. */ + unsigned int reserved0 : 31; + } BIT; +} IWDG_MIS_REG; + +/** + * @brief IWDG status. + */ +typedef union { + unsigned int reg; + struct { + unsigned int control_update : 1; /**< Update status of the IWDG_CONTROL register. */ + unsigned int pre_div_update : 1; /**< Update status of the IWDG_PRE_DIV register. */ + unsigned int key_update : 1; /**< Update status of the IWDG_KEY register. */ + unsigned int window_update : 1; /**< Update status of the IWDG_WINDOW register. */ + unsigned int load_update : 1; /**< Update status of the IWDG_LOAD register. */ + unsigned int reserved0 : 27; + } BIT; +} IWDG_STATUS_REG; + +/** + * @brief IWDG Register Structure definition. + */ +typedef struct { + IWDG_LOAD_REG IWDG_LOAD; /**< IWDG load value register. */ + IWDG_VALUE_REG IWDG_VALUE; /**< IWDG current value register. */ + IWDG_WINDOW_REG IWDG_WINDOW; /**< IWDG Window value register. */ + IWDG_KEY_REG IWDG_KEY; /**< IWDG instruction word register. */ + IWDG_PRE_DIV_REG IWDG_PRE_DIV; /**< IWDG prescale register. */ + IWDG_CONTROL_REG IWDG_CONTROL; /**< IWDG interrupt, reset and window enable register. */ + IWDG_RIS_REG IWDG_RIS; /**< IWDG orignal interrupt register. */ + IWDG_MIS_REG IWDG_MIS; /**< IWDG mask interrupt register. */ + IWDG_STATUS_REG IWDG_STATUS; /**< IWDG status register. */ +} volatile IWDG_RegStruct; + +/** + * @} + */ +/** + * @brief Get the update status of the IWDG_LOAD register. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval unsigned int: The value 0 indicates that the update is complete. + */ +static inline unsigned int DCL_IWDG_GetLoadUpdateStatus(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_STATUS.BIT.load_update; +} + +/** + * @brief Get the update status of the IWDG_WINDOW register. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval unsigned int: The value 0 indicates that the update is complete. + */ +static inline unsigned int DCL_IWDG_GetWindowUpdateStatus(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_STATUS.BIT.window_update; +} + +/** + * @brief Get the update status of the IWDG_KEY register. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval unsigned int: The value 0 indicates that the update is complete. + */ +static inline unsigned int DCL_IWDG_GetKeyUpdateStatus(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_STATUS.BIT.key_update; +} + +/** + * @brief Get the update status of the IWDG_PRE_DIV register. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval unsigned int: The value 0 indicates that the update is complete. + */ +static inline unsigned int DCL_IWDG_GetPreDivUpdateStatus(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_STATUS.BIT.pre_div_update; +} + +/** + * @brief Get the update status of the IWDG_CONTROL register. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval unsigned int: The value 0 indicates that the update is complete. + */ +static inline unsigned int DCL_IWDG_GetControlUpdateStatus(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_STATUS.BIT.control_update; +} + +/** + * @brief Setting the load value of the IWDG counter. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @param loadValue Load value of the IWDG counter. + * @retval None. + */ +static inline void DCL_IWDG_SetLoadValue(IWDG_RegStruct *iwdgx, unsigned short loadValue) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + IWDG_PARAM_CHECK_NO_RET(loadValue <= 0xFFF); /* loadValue less than 0xFFF */ + while (DCL_IWDG_GetLoadUpdateStatus(iwdgx) != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_UNLOCK_REG_CMD; + iwdgx->IWDG_LOAD.BIT.iwdg_load = loadValue; + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_LOCK_REG_CMD; +} + +/** + * @brief Getting the load value of the IWDG load register. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval unsigned short IWDG load value. + */ +static inline unsigned short DCL_IWDG_GetLoadValue(const IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_LOAD.BIT.iwdg_load; +} + +/** + * @brief Getting the value of the IWDG counter register. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval unsigned short IWDG counter value. + */ +static inline unsigned short DCL_IWDG_GetCounterValue(const IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_VALUE.BIT.iwdg_value; +} + +/** + * @brief Setting window value. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @param windowValue window value of the IWDG counter. + * @retval None. + */ +static inline void DCL_IWDG_SetWindowValue(IWDG_RegStruct *iwdgx, unsigned short windowValue) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + IWDG_PARAM_CHECK_NO_RET(windowValue <= 0xFFF); /* windowValue less than 0xFFF */ + while (DCL_IWDG_GetWindowUpdateStatus(iwdgx) != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_UNLOCK_REG_CMD; /* Unlock Register, Enable write access */ + iwdgx->IWDG_WINDOW.BIT.iwdg_window = windowValue; + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_LOCK_REG_CMD; /* Lock Register, Enable write access */ +} + +/** + * @brief Getting window value. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @param windowValue window value of the IWDG counter. + * @retval unsigned short iwdg window value. + */ +static inline unsigned short DCL_IWDG_GetWindowValue(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_WINDOW.BIT.iwdg_window; +} + +/** + * @brief Start iwdg function. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval None. + */ +static inline void DCL_IWDG_Start(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + while (DCL_IWDG_GetKeyUpdateStatus(iwdgx) != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = 0xCC; /* 0xCC CMD: start iwdg function */ +} + +/** + * @brief Clear interrupt and reload watchdog counter value. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval None. + */ +static inline void DCL_IWDG_Refresh(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + while (DCL_IWDG_GetKeyUpdateStatus(iwdgx) != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = 0xAA; /* 0xAA CMD: clear interrupt and reload value */ +} + +/** + * @brief Disable write and read IWDG registers except IWDG_LOCK. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval None. + */ +static inline void DCL_IWDG_LockReg(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + while (DCL_IWDG_GetKeyUpdateStatus(iwdgx) != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = 0xFF; /* 0xFF CMD: key not equal 0x55 will lock reg write function except key reg */ +} + +/** + * @brief Enable write and read IWDG registers. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval None. + */ +static inline void DCL_IWDG_UnlockReg(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + while (DCL_IWDG_GetKeyUpdateStatus(iwdgx) != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = 0x55; /* 0x55 CMD: key equal 0x55 will unlock all reg write function */ +} + +/** + * @brief Get IWDG key value. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval unsigned char: 0xDD indicate the IWDG is disabled. + */ +static inline unsigned char DCL_IWDG_GetKey(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_KEY.BIT.iwdg_key; +} + +/** + * @brief Setting freq div value. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @param freqDiv freqDiv value of the IWDG counter. + * @retval None. + */ +static inline void DCL_IWDG_SetFreqDivValue(IWDG_RegStruct *iwdgx, IWDG_FreqDivType freqDiv) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + IWDG_PARAM_CHECK_NO_RET(freqDiv < IWDG_FREQ_DIV_MAX); + while (DCL_IWDG_GetPreDivUpdateStatus(iwdgx) != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_UNLOCK_REG_CMD; /* Unlock Register, Enable write access */ + iwdgx->IWDG_PRE_DIV.BIT.iwdg_pre_div = freqDiv; /* freqDiv parameters set */ + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_LOCK_REG_CMD; /* Lock Register, Enable write access */ +} + +/** + * @brief Getting freq div value. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @param freqDiv freqDiv value of the IWDG counter. + * @retval None. + */ +static inline unsigned char DCL_IWDG_GetFreqDivValue(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_PRE_DIV.BIT.iwdg_pre_div; +} + +/** + * @brief Enable reset signal. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval None. + */ +static inline void DCL_IWDG_EnableReset(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + while (iwdgx->IWDG_STATUS.BIT.control_update != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_UNLOCK_REG_CMD; /* Unlock Register, Enable write access */ + iwdgx->IWDG_CONTROL.BIT.resen = BASE_CFG_SET; + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_LOCK_REG_CMD; /* Lock Register, Enable write access */ +} + +/** + * @brief Disable reset signal. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval None. + */ +static inline void DCL_IWDG_DisableReset(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + while (iwdgx->IWDG_STATUS.BIT.control_update != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_UNLOCK_REG_CMD; /* Unlock Register, Enable write access */ + iwdgx->IWDG_CONTROL.BIT.resen = BASE_CFG_UNSET; + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_LOCK_REG_CMD; /* Lock Register, Enable write access */ +} + +/** + * @brief Start watchdog and enable interrupt signal. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval None. + */ +static inline void DCL_IWDG_EnableInterrupt(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + while (iwdgx->IWDG_STATUS.BIT.control_update != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_UNLOCK_REG_CMD; /* Unlock Register, Enable write access */ + iwdgx->IWDG_CONTROL.BIT.inten = BASE_CFG_SET; + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_LOCK_REG_CMD; /* Lock Register, Enable write access */ +} + +/** + * @brief Disable interrupt signal. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval None. + */ +static inline void DCL_IWDG_DisableInterrupt(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + while (iwdgx->IWDG_STATUS.BIT.control_update != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_UNLOCK_REG_CMD; /* Unlock Register, Enable write access */ + iwdgx->IWDG_CONTROL.BIT.inten = BASE_CFG_UNSET; + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_LOCK_REG_CMD; /* Lock Register, Enable write access */ +} + +/** + * @brief Ensable Windows mode. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval None. + */ +static inline void DCL_IWDG_EnableWindowsMode(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + while (iwdgx->IWDG_STATUS.BIT.control_update != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_UNLOCK_REG_CMD; /* Unlock Register, Enable write access */ + iwdgx->IWDG_CONTROL.BIT.window_mode_en = BASE_CFG_SET; + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_LOCK_REG_CMD; /* Lock Register, Enable write access */ +} + +/** + * @brief Disable Windows mode. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval None. + */ +static inline void DCL_IWDG_DisableWindowsMode(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + while (iwdgx->IWDG_STATUS.BIT.control_update != 0x0) { + ; + } + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_UNLOCK_REG_CMD; /* Unlock Register, Enable write access */ + iwdgx->IWDG_CONTROL.BIT.window_mode_en = BASE_CFG_UNSET; + iwdgx->IWDG_KEY.BIT.iwdg_key = IWDG_LOCK_REG_CMD; /* Lock Register, Enable write access */ +} + +/** + * @brief Get Windows mode. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval bool is enable or disable. + */ +static inline bool DCL_IWDG_GetWindowsMode(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_CONTROL.BIT.window_mode_en; +} + +/** + * @brief Getting value of IWDG RIS register. + * @param iwdgx Value of @ref IWDG_RegStruct. + * @retval unsigned int Value of IWDG RIS register. + */ +static inline unsigned int DCL_IWDG_GetRIS(IWDG_RegStruct *iwdgx) +{ + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgx)); + return iwdgx->IWDG_RIS.BIT.iwdgris; +} + +/** + * @brief check iwdg time type parameter. + * @param timeType Value of @ref IWDG_TimeType. + * @retval Bool. + */ +static inline bool IsIwdgTimeType(IWDG_TimeType timeType) +{ + return (timeType == IWDG_TIME_UNIT_TICK || + timeType == IWDG_TIME_UNIT_S || + timeType == IWDG_TIME_UNIT_MS || + timeType == IWDG_TIME_UNIT_US); +} + +/** + * @brief check iwdg time value parameter. + * @param baseAddress Value of @ref IWDG_RegStruct + * @param timeValue time value + * @param timeType Value of @ref IWDG_TimeType. + * @retval Bool. + */ +static inline bool IsIwdgTimeValue(IWDG_RegStruct *baseAddress, float timeValue, IWDG_TimeType timeType) +{ + float clockFreq = (float)HAL_CRG_GetIpFreq((void *)baseAddress); + float maxSecond = (float)((float)0xFFFFFFFF / clockFreq); /* 0xFFFFFFFF max input value */ + return ((timeType == IWDG_TIME_UNIT_TICK && timeValue <= (float)0xFFFFFFFF) || + (timeType == IWDG_TIME_UNIT_S && maxSecond >= timeValue) || + (timeType == IWDG_TIME_UNIT_MS && maxSecond >= timeValue / FREQ_CONVERT_MS_UNIT) || + (timeType == IWDG_TIME_UNIT_US && maxSecond >= timeValue / FREQ_CONVERT_US_UNIT)); +} +/** + * @} + */ + +/** + * @} + */ + +#endif /* McuMagicTag_IWDG_IP_H */ \ No newline at end of file diff --git a/src/drivers/iwdg/iwdg_v2/src/iwdg.c b/src/drivers/iwdg/iwdg_v2/src/iwdg.c new file mode 100644 index 0000000000000000000000000000000000000000..17ec3ca35c795fd0ad2eba7d92c364b3feb3642d --- /dev/null +++ b/src/drivers/iwdg/iwdg_v2/src/iwdg.c @@ -0,0 +1,255 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file iwdg.c + * @author MCU Driver Team + * @brief IWDG module driver + * @details This file provides firmware functions to manage the following functionalities of the IWDG and IWDG. + * + Initialization functions. + * + IWDG Set And Get Functions. + * + Interrupt Handler Functions. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "interrupt.h" +#include "iwdg.h" +/* Macro definitions ---------------------------------------------------------*/ +#define IWDG_LOAD_VALUE_LIMIT 4095 +#define IWDG_WINDOW_VALUE_UPPER_LIMIT 4095 +static unsigned int IWDG_CalculateRegTimeout(IWDG_RegStruct *baseAddress, float timeValue, IWDG_TimeType timeType); + +/** + * @brief Initializing IWDG or IWDG register values + * @param handle Value of @ref IWDG_handle. + * @retval BASE_StatusType: OK, ERROR + */ +BASE_StatusType HAL_IWDG_Init(IWDG_Handle *handle) +{ + IWDG_ASSERT_PARAM(handle != NULL); + IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); + IWDG_PARAM_CHECK_WITH_RET(IsIwdgTimeType(handle->timeType), BASE_STATUS_ERROR); + IWDG_PARAM_CHECK_WITH_RET(IsIwdgTimeValue(handle->baseAddress, handle->timeValue, handle->timeType), + BASE_STATUS_ERROR); + HAL_IWDG_Start(handle); /* Enable IWDG */ + + /* IWDG frequency division value less than 1024 */ + unsigned int freqDivVal = (handle->freqDivValue > IWDG_FREQ_DIV_1024) ? IWDG_FREQ_DIV_1024 : handle->freqDivValue; + DCL_IWDG_SetFreqDivValue(handle->baseAddress, freqDivVal); + + /* Set time value */ + HAL_IWDG_SetTimeValue(handle, handle->timeValue, handle->timeType); + + /* Enable IWDG interrupt */ + if (handle->enableIT) { + DCL_IWDG_EnableInterrupt(handle->baseAddress); + } else { + DCL_IWDG_DisableInterrupt(handle->baseAddress); + } + DCL_IWDG_EnableReset(handle->baseAddress); /* enable reset */ + + /* Wait for register to be updated */ + while (handle->baseAddress->IWDG_STATUS.reg != 0x00) { + ; + } + unsigned int value = IWDG_CalculateRegTimeout(handle->baseAddress, handle->handleEx.windowValue, handle->timeType); + unsigned int freqDiv = DCL_IWDG_GetFreqDivValue(handle->baseAddress); + value = (value / (1 << (freqDiv + 2))); /* 1 << (freqDiv + 2) is freq div value */ + /* The upper limit of the window value is determined. */ + value = (value <= IWDG_WINDOW_VALUE_UPPER_LIMIT) ? value : IWDG_WINDOW_VALUE_UPPER_LIMIT; + /* window value only could be set litter than load value */ + value = (value < handle->baseAddress->IWDG_LOAD.BIT.iwdg_load) ? value : + handle->baseAddress->IWDG_LOAD.BIT.iwdg_load; + + if (handle->baseAddress->IWDG_WINDOW.BIT.iwdg_window != value) { + DCL_IWDG_SetWindowValue(handle->baseAddress, value); + } else { + DCL_IWDG_Refresh(handle->baseAddress); + } + return BASE_STATUS_OK; +} + +/** + * @brief Calculate Reg Timeout. + * @param timeValue Value to be load to iwdg. + * @param timeType Value of @ref IWDG_TimeType. + * @retval unsigned int timeout Value. + */ +static unsigned int IWDG_CalculateRegTimeout(IWDG_RegStruct *baseAddress, float timeValue, IWDG_TimeType timeType) +{ + float clockFreq = (float)HAL_CRG_GetIpFreq((void *)baseAddress); + unsigned int timeoutValue = 0x00000000U; + switch (timeType) { + case IWDG_TIME_UNIT_TICK: /* If the time type is tick, calculate the timeout value. */ + timeoutValue = (unsigned int)timeValue; + break; + case IWDG_TIME_UNIT_S: /* If the time type is s, calculate the timeout value. */ + timeoutValue = (unsigned int)(timeValue * clockFreq); + break; + case IWDG_TIME_UNIT_MS: /* If the time type is ms, calculate the timeout value. */ + timeoutValue = (unsigned int)(timeValue * clockFreq / FREQ_CONVERT_MS_UNIT); + break; + case IWDG_TIME_UNIT_US: /* If the time type is us, calculate the timeout value. */ + timeoutValue = (unsigned int)(timeValue * clockFreq / FREQ_CONVERT_US_UNIT); + break; + default: + break; + } + return timeoutValue; +} + +/** + * @brief Setting the load value of the IWDG counter. + * @param handle Value of @ref IWDG_handle. + * @param timeValue time value. + * @param timeType IWDG time type. + * @retval None. + */ +void HAL_IWDG_SetTimeValue(IWDG_Handle *handle, unsigned int timeValue, IWDG_TimeType timeType) +{ + IWDG_ASSERT_PARAM(handle != NULL); + IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); + IWDG_PARAM_CHECK_NO_RET(IsIwdgTimeType(timeType)); + IWDG_PARAM_CHECK_NO_RET(IsIwdgTimeValue(handle->baseAddress, timeValue, timeType)); + unsigned int value = IWDG_CalculateRegTimeout(handle->baseAddress, timeValue, timeType); + unsigned int freqDiv = DCL_IWDG_GetFreqDivValue(handle->baseAddress); + value = (value / (1 << (freqDiv + 2))); /* 1 << (freqDiv + 2) is freq div value */ + /* The upper limit of the loaded value is determined. */ + value = (value <= IWDG_LOAD_VALUE_LIMIT) ? value : IWDG_LOAD_VALUE_LIMIT; + DCL_IWDG_SetLoadValue(handle->baseAddress, value); +} + +/** + * @brief refresh the IWDG counter. + * @param handle Value of @ref IWDG_handle. + * @retval None. + */ +void HAL_IWDG_Refresh(IWDG_Handle *handle) +{ + IWDG_ASSERT_PARAM(handle != NULL); + IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); + DCL_IWDG_Refresh(handle->baseAddress); +} + +/** + * @brief obtain the IWDG load value. + * @param handle Value of @ref IWDG_handle. + * @retval unsigned int Load value. + */ +unsigned int HAL_IWDG_GetLoadValue(IWDG_Handle *handle) +{ + IWDG_ASSERT_PARAM(handle != NULL); + IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); + return DCL_IWDG_GetLoadValue(handle->baseAddress); +} + +/** + * @brief Refresh the IWDG counter value. + * @param handle Value of @ref IWDG_handle. + * @retval unsigned int Counter value. + */ +unsigned int HAL_IWDG_GetCounterValue(IWDG_Handle *handle) +{ + IWDG_ASSERT_PARAM(handle != NULL); + IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); + + float res = (float)handle->baseAddress->IWDG_VALUE.BIT.iwdg_value; + if (res >= 4095) { /* 4095 is IWDG maximum current count */ + return handle->timeValue; + } + unsigned int freq = HAL_CRG_GetIpFreq((void *)handle->baseAddress); + /* check clockFreq not equal zero */ + if (freq == 0) { + return 0; + } + unsigned int freqDiv = DCL_IWDG_GetFreqDivValue(handle->baseAddress); + switch (handle->timeType) { + case IWDG_TIME_UNIT_TICK: /* Number of tick currently calculated */ + res = res * (1 << (freqDiv + 2)); /* 1 << (freqDiv + 2) is freq div value */ + break; + case IWDG_TIME_UNIT_S: + /* Number of seconds currently calculated */ + res = res * (1 << (freqDiv + 2)) / freq; /* 1 << (freqDiv + 2) is freq div value */ + break; + case IWDG_TIME_UNIT_MS: + /* 1 << (freqDiv + 2) is freq div value */ + res = res * (1 << (freqDiv + 2)) * FREQ_CONVERT_MS_UNIT / freq; + break; + case IWDG_TIME_UNIT_US: + /* Number of seconds currently calculated, 1 << (freqDiv + 2) is freq div value */ + res = res * (1 << (freqDiv + 2)) * FREQ_CONVERT_US_UNIT / freq; + break; + default: + break; + } + return (unsigned int)res; /* return current counter value */ +} + +/** + * @brief Start the IWDG count. + * @param handle Value of @ref IWDG_handle. + * @retval None. + */ +void HAL_IWDG_Start(IWDG_Handle *handle) +{ + IWDG_ASSERT_PARAM(handle != NULL); + IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); + DCL_IWDG_Start(handle->baseAddress); +} + +/** + * @brief Stop the IWDG count. + * @param handle Value of @ref IWDG_handle. + * @retval None. + */ +void HAL_IWDG_Stop(IWDG_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); +} + +/** + * @brief Register IWDG interrupt callback. + * @param handle Value of @ref IWDG_handle. + * @param callBackFunc Value of @ref IWDG_CallbackType. + * @retval None + */ +void HAL_IWDG_RegisterCallback(IWDG_Handle *handle, IWDG_CallbackType callBackFunc) +{ + IWDG_ASSERT_PARAM(handle != NULL); + IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); + if (callBackFunc != NULL) { + /* Invoke the callback function. */ + handle->userCallBack.CallbackFunc = callBackFunc; + } +} + +/** + * @brief Interrupt handler processing function. + * @param handle IWDG_Handle. + * @retval None. + */ +void HAL_IWDG_IrqHandler(void *handle) +{ + IWDG_Handle *iwdgHandle = (IWDG_Handle *)handle; + IWDG_ASSERT_PARAM(iwdgHandle != NULL); + IWDG_ASSERT_PARAM(IsIWDGInstance(iwdgHandle->baseAddress)); + + if (iwdgHandle->baseAddress->IWDG_MIS.BIT.iwdgmis == 0x01) { /* Interrupt flag is set, fed dog in callback */ + if (iwdgHandle->userCallBack.CallbackFunc) { + iwdgHandle->userCallBack.CallbackFunc(iwdgHandle); + } + } +} diff --git a/src/drivers/iwdg/iwdg_v2/src/iwdg_ex.c b/src/drivers/iwdg/iwdg_v2/src/iwdg_ex.c new file mode 100644 index 0000000000000000000000000000000000000000..0b85cb67c09f0e20911694c6c027f2e88b694deb --- /dev/null +++ b/src/drivers/iwdg/iwdg_v2/src/iwdg_ex.c @@ -0,0 +1,68 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file iwdg_ex.c + * @author MCU Driver Team + * @brief IWDG module driver + * @details This file provides firmware functions to manage the following functionalities of the IWDG and IWDG. + * + IWDG Set And Get Functions. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "interrupt.h" +#include "pmc.h" +#include "iwdg_ex.h" +/* Macro definitions ---------------------------------------------------------*/ +#define IWDG_WINDOW_VALUE_UPPER_LIMIT 4095 + +/** + * @brief Getting the window value of the IWDG counter. + * @param handle Value of @ref IWDG_handle. + * @retval unsigned int the value of window reg value. + */ +unsigned int HAL_IWDG_GetWindowValueEx(IWDG_Handle *handle) +{ + IWDG_ASSERT_PARAM(handle != NULL); + IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); + IWDG_ASSERT_PARAM(IsIwdgTimeType(handle->timeType)); + /* handle->baseAddress only could be configed IWDG */ + return DCL_IWDG_GetWindowValue(handle->baseAddress); +} + +/** + * @brief Enable window mode. + * @param handle Value of @ref IWDG_handle. + * @retval None. + */ +void HAL_IWDG_EnableWindowModeEx(IWDG_Handle *handle) +{ + IWDG_ASSERT_PARAM(handle != NULL); + IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); + DCL_IWDG_EnableWindowsMode(handle->baseAddress); +} + +/** + * @brief Disable window mode. + * @param handle Value of @ref IWDG_handle. + * @retval None. + */ +void HAL_IWDG_DisableWindowModeEx(IWDG_Handle *handle) +{ + IWDG_ASSERT_PARAM(handle != NULL); + IWDG_ASSERT_PARAM(IsIWDGInstance(handle->baseAddress)); + DCL_IWDG_DisableWindowsMode(handle->baseAddress); +} \ No newline at end of file diff --git a/src/drivers/pga/pga_v0/inc/pga_ip.h b/src/drivers/pga/pga_v0/inc/pga_ip.h index 1511da5f866f857916cea17042df33b8aa1ba44e..86bd4866214e9bb86a22a9a438138ab76d610b50 100644 --- a/src/drivers/pga/pga_v0/inc/pga_ip.h +++ b/src/drivers/pga/pga_v0/inc/pga_ip.h @@ -109,7 +109,7 @@ typedef union { unsigned int pga_ana_en : 1; /**< Overall enable of the PGA. */ unsigned int pga_en_ext0 : 1; /**< PGA external output enable. */ unsigned int pga_en_out : 1; /**< PGA output enable. */ - unsigned int reserved_0 : 29; + unsigned int reserved0 : 29; } BIT; } volatile PGA_CTRL0_REG; @@ -121,7 +121,7 @@ typedef union { struct { unsigned int pga_trim_ofstp : 5; /**< PGA trim PMOS offset. */ unsigned int pga_trim_ofstn : 5; /**< PGA trim NMOS offset. */ - unsigned int reserved_0 : 22; + unsigned int reserved0 : 22; } BIT; } volatile PGA_CTRL1_REG; @@ -133,7 +133,7 @@ typedef union { struct { unsigned int pga_smux : 3; /**< PGA input channel select. */ unsigned int pga_gain : 3; /**< PGA gain. */ - unsigned int reserved_0 : 26; + unsigned int reserved0 : 26; } BIT; } volatile PGA_CTRL2_REG; @@ -146,7 +146,7 @@ typedef union { unsigned int pga_sw_enlv_n : 4; /**< PGA N input SW enable, configured together with channel select. */ unsigned int pga_sw_enlv_p : 4; /**< PGA P input SW enable, configured together with channel select. */ unsigned int pga_ext_loopback : 2; /**< PGA loopback switch. */ - unsigned int reserved_0 : 22; + unsigned int reserved0 : 22; } BIT; } volatile PGA_CTRL3_REG; diff --git a/src/drivers/pga/pga_v1/inc/pga_ip.h b/src/drivers/pga/pga_v1/inc/pga_ip.h index f2fad2ee2b0855cdb3c33220e39cd7032224718c..147bd024564cd3f79963049c58398fe06fd129e9 100644 --- a/src/drivers/pga/pga_v1/inc/pga_ip.h +++ b/src/drivers/pga/pga_v1/inc/pga_ip.h @@ -38,10 +38,8 @@ #define PGA_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) #endif -#define PGA_PGA_MAX_GAIN 7 -#define PGA_MAX_GAIN_VALUE 3 -#define PGA_MAX_EXT_CAP_COMP 7 -#define PGA_EXT_VLAUE 3 +#define PGA_EXT_VALUE 3 + /** * @addtogroup PGA * @{ @@ -81,6 +79,10 @@ typedef enum { PGA_EXT_COMPENSATION_7X = 0x00000005U, PGA_EXT_COMPENSATION_8X = 0x00000006U, PGA_EXT_COMPENSATION_9X = 0x00000007U, + + PGA_EXT_COMPENSATION_10X_12X = 0x00000008U, + PGA_EXT_COMPENSATION_13X_15X = 0x00000009U, + PGA_EXT_COMPENSATION_16X_20X = 0x0000000AU, } PGA_ExtCapCompValue; /** @@ -97,7 +99,7 @@ typedef union { unsigned int reg; struct { unsigned int da_pga_enh : 1; /**< Overall enable of the PGA. */ - unsigned int reserved_0 : 31; + unsigned int reserved0 : 31; } BIT; } volatile PGA_CTRL0_REG; @@ -108,12 +110,12 @@ typedef union { unsigned int reg; struct { unsigned int da_pga_cf_ctrl : 3; /**< Feedforward capacitor compensation config in PGA external gain mode. */ - unsigned int reserved_0 : 5; + unsigned int reserved0 : 5; unsigned int da_pga_gain_ctrl : 3; /**< Gain configuration of the internal resistor of the PGA. */ - unsigned int reserved_1 : 5; + unsigned int reserved1 : 5; unsigned int da_pga_mode_ctrl : 2; /**< PGA mode configuration. 0: internal resistor gain mode; 1: external resistor gain mode; */ - unsigned int reserved_2 : 14; + unsigned int reserved2 : 14; } BIT; } volatile PGA_CTRL1_REG; @@ -124,7 +126,7 @@ typedef union { unsigned int reg; struct { unsigned int da_pga_ibias_sel : 4; /**< PGA bias current configuration level select. */ - unsigned int reserved_0 : 28; + unsigned int reserved0 : 28; } BIT; } volatile PGA_CTRL2_REG; @@ -135,7 +137,7 @@ typedef union { unsigned int reg; struct { unsigned int da_pga_vos_trim : 9; /**< Offset trim information of the PGA. */ - unsigned int reserved_0 : 23; + unsigned int reserved0 : 23; } BIT; } volatile PGA_TRIM_REG; @@ -147,7 +149,7 @@ typedef union { struct { unsigned int da_pga_test_enh : 1; /**< PGA test enable. */ unsigned int da_pga_test_sel : 2; /**< PGA test select. */ - unsigned int reserved_0 : 29; + unsigned int reserved0 : 29; } BIT; } volatile PGA_TEST_REG; @@ -158,7 +160,7 @@ typedef union { unsigned int reg; struct { unsigned int da_pga_cf_ctrl1 : 2; /**< Feedforward capacitor compensation config in external gain mode. */ - unsigned int reserved_0 : 30; + unsigned int reserved0 : 30; } BIT; } volatile PGA_RSV_REG; @@ -187,7 +189,7 @@ typedef struct _PGA_RegStruct { */ static inline bool IsPgaGain(PGA_GainValue pgaGainValue) { - return (pgaGainValue <= PGA_MAX_GAIN_VALUE); + return (pgaGainValue <= PGA_GAIN_16X); } /** @@ -198,7 +200,7 @@ static inline bool IsPgaGain(PGA_GainValue pgaGainValue) */ static inline bool IsPgaExtCapCompensation(PGA_ExtCapCompValue pgaExtCapCompValue) { - return (pgaExtCapCompValue <= PGA_MAX_EXT_CAP_COMP); + return (pgaExtCapCompValue <= PGA_EXT_COMPENSATION_16X_20X); } /* DCL layer -----------------------------------------------------------*/ @@ -233,7 +235,7 @@ static inline void DCL_PGA_DisableOut(PGA_RegStruct *pgax) static inline void DCL_PGA_SetGain(PGA_RegStruct *pgax, unsigned int value) { PGA_ASSERT_PARAM(IsPGAInstance(pgax)); - PGA_PARAM_CHECK_NO_RET(value <= PGA_PGA_MAX_GAIN); + PGA_PARAM_CHECK_NO_RET(value <= PGA_GAIN_16X); pgax->PGA_CTRL1.BIT.da_pga_gain_ctrl = value; } @@ -271,7 +273,7 @@ static inline void DCL_PGA_DisableExtGainMode(PGA_RegStruct *pgax) } /** - * @brief Fedforward capacitor compensation configuration in PGA external gain mode + * @brief Set feedforward capacitance compensation in PGA external gain mode * @param pgax: amplifier register base address. * @param extValue: Configured value of the capacitor compensation. * @retval None. @@ -279,8 +281,16 @@ static inline void DCL_PGA_DisableExtGainMode(PGA_RegStruct *pgax) static inline void DCL_PGA_SetExtCompensation(PGA_RegStruct *pgax, unsigned short extValue) { PGA_ASSERT_PARAM(IsPGAInstance(pgax)); - PGA_PARAM_CHECK_NO_RET(extValue <= PGA_PGA_MAX_GAIN); - pgax->PGA_CTRL1.BIT.da_pga_cf_ctrl = extValue; + PGA_PARAM_CHECK_NO_RET(extValue <= PGA_EXT_COMPENSATION_16X_20X); + if (extValue <= PGA_EXT_COMPENSATION_9X) { + pgax->PGA_CTRL1.BIT.da_pga_cf_ctrl = extValue; + } else { + /* If external gain is larger than PGA_EXT_COMPENSATION_9X. */ + /* da_pga_cf_ctrl of PGA_CTRL1 is set to 0x7 (111). */ + pgax->PGA_CTRL1.BIT.da_pga_cf_ctrl = 0x7; + /* da_pga_cf_ctrl1 of PGA_RSV is set to extValue - 0x7. */ + pgax->PGA_RSV.BIT.da_pga_cf_ctrl1 = extValue - 0x7; + } } /** @@ -315,7 +325,9 @@ static inline void DCL_PGA_DisableTestMode(PGA_RegStruct *pgax) static inline void DCL_PGA_SetExtCapCompValue(PGA_RegStruct *pgax, unsigned short extBigvalue) { PGA_ASSERT_PARAM(IsPGAInstance(pgax)); - PGA_PARAM_CHECK_NO_RET(extBigvalue <= PGA_EXT_VLAUE); + PGA_PARAM_CHECK_NO_RET(extBigvalue >= 0x1 && extBigvalue <= PGA_EXT_VALUE); + /* Precondition: must be set da_pga_cf_ctrl to 0x7(111). */ + pgax->PGA_CTRL1.BIT.da_pga_cf_ctrl = 0x7; pgax->PGA_RSV.BIT.da_pga_cf_ctrl1 = extBigvalue; } diff --git a/src/drivers/pga/pga_v1/src/pga.c b/src/drivers/pga/pga_v1/src/pga.c index ebc94a1f6f9541d60872a5db6f5189f1be006b2d..fdacfb1051019020439b9a72cb3943b1073e17bc 100644 --- a/src/drivers/pga/pga_v1/src/pga.c +++ b/src/drivers/pga/pga_v1/src/pga.c @@ -40,9 +40,25 @@ BASE_StatusType HAL_PGA_Init(PGA_Handle *pgaHandle) /* Initial configuration of the PGA. */ PGA_CTRL1_REG pgaControl1; pgaControl1.reg = pgaHandle->baseAddress->PGA_CTRL1.reg; - pgaControl1.BIT.da_pga_mode_ctrl = pgaHandle->externalResistorMode; /* PGA mode configuration. */ - pgaControl1.BIT.da_pga_gain_ctrl = pgaHandle->gain; /* PGA gain setting. */ - pgaControl1.BIT.da_pga_cf_ctrl = pgaHandle->handleEx.extCapCompensation; + /* PGA mode configuration. */ + pgaControl1.BIT.da_pga_mode_ctrl = pgaHandle->externalResistorMode; + if (pgaHandle->externalResistorMode) { + /* External resistance mode setting. */ + if (pgaHandle->handleEx.extCapCompensation <= PGA_EXT_COMPENSATION_9X) { + pgaControl1.BIT.da_pga_cf_ctrl = pgaHandle->handleEx.extCapCompensation; + } else { + /* If external gain is larger than PGA_EXT_COMPENSATION_9X. */ + /* da_pga_cf_ctrl of PGA_CTRL1 must be set to 0x7 (111). */ + pgaControl1.BIT.da_pga_cf_ctrl = 0x7; + /* da_pga_cf_ctrl1 of PGA_RSV is set to extValue - 0x7. */ + pgaHandle->baseAddress->PGA_RSV.BIT.da_pga_cf_ctrl1 = pgaHandle->handleEx.extCapCompensation - 0x7; + } + } else { + /* Internal resistance mode setting. */ + /* PGA gain. */ + pgaControl1.BIT.da_pga_gain_ctrl = pgaHandle->gain; + } + pgaHandle->baseAddress->PGA_CTRL1.reg = pgaControl1.reg; /* Enable PGA */ pgaHandle->baseAddress->PGA_CTRL0.BIT.da_pga_enh = BASE_CFG_ENABLE; diff --git a/src/drivers/pga/pga_v2/inc/pga_ip.h b/src/drivers/pga/pga_v2/inc/pga_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..943f4aad3ddd757e1d74ab998d99570660fea84d --- /dev/null +++ b/src/drivers/pga/pga_v2/inc/pga_ip.h @@ -0,0 +1,300 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file pga_ip.h + * @author MCU Driver Team + * @brief Programmable Gain Amplifier module driver. + * This file provides DCL functions to manage amplifier. + * + Programmable Gain Amplifier register mapping strtucture. + * + Direct configuration layer interface. + */ + +#ifndef McuMagicTag_PGA_IP_H +#define McuMagicTag_PGA_IP_H + +#include "baseinc.h" + +#ifdef PGA_PARAM_CHECK +#define PGA_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM +#define PGA_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET +#define PGA_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else +#define PGA_ASSERT_PARAM(para) ((void)0U) +#define PGA_PARAM_CHECK_NO_RET(para) ((void)0U) +#define PGA_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) +#endif + + +/** + * @addtogroup PGA + * @{ + */ + +/** + * @defgroup PGA_IP PGA_IP + * @brief PGA_IP: pga_v2. + * @{ + */ + +/** + * @defgroup PGA_REG_Definition PGA Register Structure. + * @brief PGA Register Structure Definition. + * @{ + */ + +/** + * @brief PGA input channel selection + */ +typedef enum { + PGA_CH_VIN0 = 0x00000000U, + PGA_CH_VIN1 = 0x00000001U, + PGA_CH_VIN2 = 0x00000002U, + PGA_CH_VIN3 = 0x00000003U, +} PGA_VinChannel; + + +/** + * @brief PGA gain value selection + */ +typedef enum { + PGA_GAIN_2X = 0x00000000U, + PGA_GAIN_4X = 0x00000001U, + PGA_GAIN_8X = 0x00000002U, + PGA_GAIN_16X = 0x00000003U, +} PGA_GainValue; + +/** + * @brief PGA gain value selection + */ +typedef enum { + PGA_EXT_COMPENSATION_2X = 0x00000000U, + PGA_EXT_COMPENSATION_3X = 0x00000001U, + PGA_EXT_COMPENSATION_4X = 0x00000002U, + PGA_EXT_COMPENSATION_5X = 0x00000003U, + PGA_EXT_COMPENSATION_6X = 0x00000004U, + PGA_EXT_COMPENSATION_7X = 0x00000005U, + PGA_EXT_COMPENSATION_8X = 0x00000006U, + PGA_EXT_COMPENSATION_9X = 0x00000007U, + + PGA_EXT_COMPENSATION_10X_12X = 0x0000000FU, + PGA_EXT_COMPENSATION_13X_15X = 0x000000017U, + PGA_EXT_COMPENSATION_16X_20X = 0x00000001FU, +} PGA_ExtCapCompValue; + +/** + * @brief Extent handle definition of PGA. + */ +typedef struct { + PGA_VinChannel vinChannel; /**< PGA input channel select. */ + PGA_ExtCapCompValue extCapCompensation; /**< Feedforward Capacitance Compensation in PGA External Gain Mode. */ +} PGA_ExtendHandle; + +/** + * @brief PGA control 0. + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_pga_enh : 1; /**< Overall enable of the PGA. */ + unsigned int reserved0 : 31; + } BIT; +} volatile PGA_CTRL0_REG; + +/** + * @brief PGA control 1. + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_pga_cf_ctrl : 5; /**< Feedforward capacitor compensation in PGA external gain mode. */ + unsigned int reserved0 : 3; + unsigned int da_pga_gain_ctrl : 3; /**< Gain configuration of the internal resistor of the PGA. */ + unsigned int reserved1 : 5; + unsigned int da_pga_mode_ctrl : 2; /**< PGA mode configuration. 0: internal resistor gain mode; + 1: external resistor gain mode; */ + unsigned int reserved2 : 2; + unsigned int da_pga_input_sel_p : 2; + unsigned int da_pga_input_sel_n : 2; + unsigned int reserved3 : 8; + } BIT; +} volatile PGA_CTRL1_REG; + +/** + * @brief PGA TRIM register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int da_pga_vos_trim : 9; /**< Offset trim information of the PGA. */ + unsigned int reserved0 : 23; + } BIT; +} volatile PGA_TRIM_REG; + +/** + * @brief Register mapping structure. + */ +typedef struct _PGA_RegStruct { + PGA_CTRL0_REG PGA_CTRL0; /**< PGA control 0 register. Offset address: 0x00000000U. */ + PGA_CTRL1_REG PGA_CTRL1; /**< PGA control 1 register. Offset address: 0x00000004U. */ + unsigned char space0[24]; + PGA_TRIM_REG PGA_TRIM; /**< PGA TRIM register. Offset address: 0x00000020U. */ +} volatile PGA_RegStruct; + + +/* Parameter Check -----------------------------------------------------------*/ + +/** + * @brief Verify gain value of PGA. + * @param pgaGainValue pga gain value @ref PGA_GainValue + * @retval true + * @retval false + */ +static inline bool IsPgaGain(PGA_GainValue pgaGainValue) +{ + return (pgaGainValue <= PGA_GAIN_16X); +} + +/** + * @brief Verify feedforward capacitance compensation value. + * @param pgaExtCapCompValue feedforward capacitance compensation value @ref PGA_ExtCapCompValue + * @retval true + * @retval false + */ +static inline bool IsPgaExtCapCompensation(PGA_ExtCapCompValue pgaExtCapCompValue) +{ + return (pgaExtCapCompValue <= PGA_EXT_COMPENSATION_16X_20X); +} + +/* DCL layer -----------------------------------------------------------*/ +/** + * @brief Enable amplifier's output + * @param pgax: amplifier register base address. + * @retval None. + */ +static inline void DCL_PGA_EnableOut(PGA_RegStruct *pgax) +{ + PGA_ASSERT_PARAM(IsPGAInstance(pgax)); + pgax->PGA_CTRL0.BIT.da_pga_enh = BASE_CFG_ENABLE; +} + +/** + * @brief Disable amplifier's output + * @param pgax: amplifier register base address. + * @retval None. + */ +static inline void DCL_PGA_DisableOut(PGA_RegStruct *pgax) +{ + PGA_ASSERT_PARAM(IsPGAInstance(pgax)); + pgax->PGA_CTRL0.BIT.da_pga_enh = BASE_CFG_DISABLE; +} + +/** + * @brief Set amplifier's gain + * @param pgax: amplifier register base address. + * @param value: gain value. + * @retval None. + */ +static inline void DCL_PGA_SetGain(PGA_RegStruct *pgax, unsigned int value) +{ + PGA_ASSERT_PARAM(IsPGAInstance(pgax)); + PGA_PARAM_CHECK_NO_RET(value <= PGA_GAIN_16X); + pgax->PGA_CTRL1.BIT.da_pga_gain_ctrl = value; +} + +/** + * @brief Get amplifier's gain + * @param pgax: amplifier register base address. + * @retval gain value. + */ +static inline unsigned int DCL_PGA_GetGain(PGA_RegStruct *pgax) +{ + PGA_ASSERT_PARAM(IsPGAInstance(pgax)); + return pgax->PGA_CTRL1.BIT.da_pga_gain_ctrl; +} + +/** + * @brief PGA mode configuration, enable external resistor gain mode. + * @param pgax: amplifier register base address. + * @retval None. + */ +static inline void DCL_PGA_EnableExtGainMode(PGA_RegStruct *pgax) +{ + PGA_ASSERT_PARAM(IsPGAInstance(pgax)); + pgax->PGA_CTRL1.BIT.da_pga_mode_ctrl = BASE_CFG_ENABLE; +} + +/** + * @brief PGA mode configuration, disable external resistor gain mode. + * @param pgax: amplifier register base address. + * @retval None. + */ +static inline void DCL_PGA_DisableExtGainMode(PGA_RegStruct *pgax) +{ + PGA_ASSERT_PARAM(IsPGAInstance(pgax)); + pgax->PGA_CTRL1.BIT.da_pga_mode_ctrl = BASE_CFG_DISABLE; +} + +/** + * @brief Set feedforward capacitance compensation in PGA external gain mode + * @param pgax: amplifier register base address. + * @param extValue: Configured value of the capacitor compensation. + * @retval None. + */ +static inline void DCL_PGA_SetExtCompensation(PGA_RegStruct *pgax, unsigned short extValue) +{ + PGA_ASSERT_PARAM(IsPGAInstance(pgax)); + PGA_PARAM_CHECK_NO_RET(extValue <= PGA_EXT_COMPENSATION_16X_20X); + pgax->PGA_CTRL1.BIT.da_pga_cf_ctrl = extValue; +} + +/** + * @brief Set PGA input channel + * @param pgax: amplifier register base address. + * @param channel: Input channel. + * @retval None. + */ +static inline void DCL_PGA_SetVinChannel(PGA_RegStruct *pgax, unsigned short channel) +{ + PGA_ASSERT_PARAM(IsPGAInstance(pgax)); + PGA_PARAM_CHECK_NO_RET(channel <= PGA_CH_VIN3); + pgax->PGA_CTRL1.BIT.da_pga_input_sel_p = channel; + pgax->PGA_CTRL1.BIT.da_pga_input_sel_n = channel; +} + +/** + * @brief Get PGA input channel + * @param pgax: amplifier register base address. + * @param channel: Input channel. + * @retval None. + */ +static inline unsigned int DCL_PGA_GetVinChannel(PGA_RegStruct *pgax) +{ + PGA_ASSERT_PARAM(IsPGAInstance(pgax)); + return pgax->PGA_CTRL1.BIT.da_pga_input_sel_p; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif diff --git a/src/drivers/pga/pga_v2/src/pga.c b/src/drivers/pga/pga_v2/src/pga.c new file mode 100644 index 0000000000000000000000000000000000000000..57ce7cdbead49836f0ca64d74f24eb50c7663edf --- /dev/null +++ b/src/drivers/pga/pga_v2/src/pga.c @@ -0,0 +1,109 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file pga.c + * @author MCU Driver Team. + * @brief Programmable Gain Amplifier HAL level module driver. + * This file provides firmware functions to manage the following + * functionalities of the amplifier + * + Programmable Gain Amplifier's Initialization and de-initialization functions + * + Set amplifier's gain value + */ +#include "pga.h" +#include "assert.h" + +/** + * @brief PGA HAL Init + * @param pgaHandle: PGA handle. + * @retval BASE_StatusType. BASE_STATUS_OK: success, BASE_STATUS_ERROR: fail. + */ +BASE_StatusType HAL_PGA_Init(PGA_Handle *pgaHandle) +{ + PGA_ASSERT_PARAM(pgaHandle != NULL); + PGA_ASSERT_PARAM(IsPGAInstance(pgaHandle->baseAddress)); + PGA_PARAM_CHECK_WITH_RET(IsPgaGain(pgaHandle->gain), BASE_STATUS_ERROR); + PGA_PARAM_CHECK_WITH_RET(IsPgaExtCapCompensation(pgaHandle->handleEx.extCapCompensation), BASE_STATUS_ERROR); + /* Initial configuration of the PGA. */ + PGA_CTRL1_REG pgaControl1; + pgaControl1.reg = pgaHandle->baseAddress->PGA_CTRL1.reg; + /* PGA mode configuration. */ + pgaControl1.BIT.da_pga_mode_ctrl = pgaHandle->externalResistorMode; + if (pgaHandle->externalResistorMode) { + pgaControl1.BIT.da_pga_cf_ctrl = pgaHandle->handleEx.extCapCompensation; + } else { + /* Internal resistance mode setting. */ + /* PGA gain. */ + pgaControl1.BIT.da_pga_gain_ctrl = pgaHandle->gain; + } + pgaControl1.BIT.da_pga_input_sel_p = pgaHandle->handleEx.vinChannel; + pgaControl1.BIT.da_pga_input_sel_n = pgaHandle->handleEx.vinChannel; + pgaHandle->baseAddress->PGA_CTRL1.reg = pgaControl1.reg; + /* Enable PGA */ + pgaHandle->baseAddress->PGA_CTRL0.BIT.da_pga_enh = BASE_CFG_ENABLE; + return BASE_STATUS_OK; +} + +/** + * @brief PGA HAL DeInit + * @param pgaHandle: PGA handle. + * @retval BASE_StatusType. + */ +BASE_StatusType HAL_PGA_DeInit(PGA_Handle *pgaHandle) +{ + PGA_ASSERT_PARAM(pgaHandle != NULL); + PGA_ASSERT_PARAM(IsPGAInstance(pgaHandle->baseAddress)); + pgaHandle->baseAddress->PGA_CTRL0.reg = BASE_CFG_DISABLE; /* Disable PGA. */ + pgaHandle->baseAddress->PGA_CTRL1.reg = BASE_CFG_DISABLE; /* Gain and mode deinitialization. */ + return BASE_STATUS_OK; +} + +/** + * @brief Set Gain value + * @param pgaHandle: PGA handle. + * @param gain: gain value. @ref PGA_GainValue + * @retval None. + */ +void HAL_PGA_SetGain(PGA_Handle *pgaHandle, PGA_GainValue gain) +{ + PGA_ASSERT_PARAM(pgaHandle != NULL); + PGA_ASSERT_PARAM(IsPGAInstance(pgaHandle->baseAddress)); + pgaHandle->baseAddress->PGA_CTRL1.BIT.da_pga_gain_ctrl = gain; /* Gain value setting. */ +} + +/** + * @brief Start PGA + * @param pgaHandle: PGA handle. + * @retval None + */ +void HAL_PGA_Start(PGA_Handle *pgaHandle) +{ + PGA_ASSERT_PARAM(pgaHandle != NULL); + PGA_ASSERT_PARAM(IsPGAInstance(pgaHandle->baseAddress)); + pgaHandle->baseAddress->PGA_CTRL0.BIT.da_pga_enh = BASE_CFG_ENABLE; /* Enable PGA. */ +} + +/** + * @brief Stop PGA + * @param pgaHandle: PGA handle. + * @retval None + */ +void HAL_PGA_Stop(PGA_Handle *pgaHandle) +{ + PGA_ASSERT_PARAM(pgaHandle != NULL); + PGA_ASSERT_PARAM(IsPGAInstance(pgaHandle->baseAddress)); + pgaHandle->baseAddress->PGA_CTRL0.BIT.da_pga_enh = BASE_CFG_DISABLE; /* Disable PGA. */ +} \ No newline at end of file diff --git a/src/drivers/pmc/pmc_v0/inc/pmc_ip.h b/src/drivers/pmc/pmc_v0/inc/pmc_ip.h index b137fd73b59ae18847f288777151eaac2fb0b7de..d134fdb813c149c09be68d2276d7d9470e12cfbd 100644 --- a/src/drivers/pmc/pmc_v0/inc/pmc_ip.h +++ b/src/drivers/pmc/pmc_v0/inc/pmc_ip.h @@ -286,6 +286,18 @@ static inline void DCL_PMC_EnterSleep(void) #endif } +/** + * @brief Check PMC active mode. + * @param mode value of active mode. + * @retval true + * @retval false + */ +static inline bool IsActiveMode(PMC_ActMode mode) +{ + return (mode == PMC_WAKEUP_ACT_UP_EDGE || mode == PMC_WAKEUP_ACT_DOWN_EDGE || \ + mode == PMC_WAKEUP_ACT_HIGH_LEVEL || mode == PMC_WAKEUP_ACT_LOW_LEVEL); +} + /** * @brief Enter deepsleep mode interface. * @param pmcx PMC register base address. diff --git a/src/drivers/pmc/pmc_v0/src/pmc.c b/src/drivers/pmc/pmc_v0/src/pmc.c index 6d59c73d822cf42e207db4ccdd6e53efb09e2597..f488503d6a1f5610b50e4055ac819b58472953ce 100644 --- a/src/drivers/pmc/pmc_v0/src/pmc.c +++ b/src/drivers/pmc/pmc_v0/src/pmc.c @@ -29,6 +29,7 @@ #define WAKEUP_ENABLE_OFFSET 0x8 #define WAKE_ACT_MODE_REG_WIDTH 0x2 +#define WAKEUP_CNT_OFFSET_BIT 16 /** * @brief Setting deepsleep wakeup source. @@ -39,17 +40,22 @@ static void PMC_SetDeepSleepWakeupSrc(PMC_Handle *pmcHandle) { PMC_ASSERT_PARAM(pmcHandle != NULL); PMC_ASSERT_PARAM(IsPMCInstance(pmcHandle->baseAddress)); + unsigned int wakeupConfig = 0; + if (pmcHandle->wakeupSrc == PMC_WAKEUP_NONE) { /* No wakeup source. */ return; } + if (pmcHandle->wakeupSrc == PMC_WAKEUP_CNT) { pmcHandle->baseAddress->CNT32K_WAKE_CYC = pmcHandle->wakeupTime; /* Set wakeup time */ - pmcHandle->baseAddress->WAKEUP_CTRL.BIT.cnt32k_wakeup_en = BASE_CFG_ENABLE; /* Enable wakeup from timer */ - } else { - pmcHandle->baseAddress->WAKEUP_CTRL.reg |= (pmcHandle->wakeupActMode) \ + wakeupConfig = (BASE_CFG_ENABLE << WAKEUP_CNT_OFFSET_BIT); /* Enable CNT_32K wakeup. */ + } else if (pmcHandle->wakeupSrc <= PMC_WAKEUP_3) { + PMC_PARAM_CHECK_NO_RET(IsActiveMode(pmcHandle->wakeupActMode)); + wakeupConfig = (pmcHandle->wakeupActMode) \ << (pmcHandle->wakeupSrc * WAKE_ACT_MODE_REG_WIDTH); - pmcHandle->baseAddress->WAKEUP_CTRL.reg |= ((0x1 << pmcHandle->wakeupSrc) << WAKEUP_ENABLE_OFFSET); + wakeupConfig |= ((0x1 << pmcHandle->wakeupSrc) << WAKEUP_ENABLE_OFFSET); /* Enable wakeup IO. */ } + pmcHandle->baseAddress->WAKEUP_CTRL.reg = wakeupConfig; /* Config register. */ } /** @@ -127,7 +133,11 @@ void HAL_PMC_EnterDeepSleepMode(PMC_Handle *handle) { PMC_ASSERT_PARAM(handle != NULL); PMC_ASSERT_PARAM(IsPMCInstance(handle->baseAddress)); + IRQ_Disable(); /* Disable global interrupt, prevent from being interrupted. */ handle->baseAddress->LOWPOWER_MODE.BIT.deepsleep_req = BASE_CFG_ENABLE; + while (true) { + ; /* Wait for enter deepsleep. */ + } } /** @@ -139,7 +149,11 @@ void HAL_PMC_EnterShutdownMode(PMC_Handle *handle) { PMC_ASSERT_PARAM(handle != NULL); PMC_ASSERT_PARAM(IsPMCInstance(handle->baseAddress)); + IRQ_Disable(); /* Disable global interrupt, prevent from being interrupted. */ handle->baseAddress->LOWPOWER_MODE.BIT.shutdown_req = BASE_CFG_ENABLE; + while (true) { + ; /* Wait for enter shutdown. */ + } } /** diff --git a/src/drivers/pmc/pmc_v1/src/pmc.c b/src/drivers/pmc/pmc_v1/src/pmc.c index 34ecd0747c1ab667d927ed129a91c0a8d443ccee..7a2ca1ccc85251fa6c919418272d546f1a23fb47 100644 --- a/src/drivers/pmc/pmc_v1/src/pmc.c +++ b/src/drivers/pmc/pmc_v1/src/pmc.c @@ -29,6 +29,7 @@ #define WAKEUP_ENABLE_OFFSET 0x8 #define WAKE_ACT_MODE_REG_WIDTH 0x2 +#define WAKEUP_CNT_OFFSET_BIT 16 /** * @brief Setting deepsleep wakeup source. @@ -40,19 +41,22 @@ static void PMC_SetDeepSleepWakeupSrc(PMC_Handle *pmcHandle) PMC_ASSERT_PARAM(pmcHandle != NULL); PMC_ASSERT_PARAM(IsPMCInstance(pmcHandle->baseAddress)); PMC_PARAM_CHECK_NO_RET(IsWakeupSrc(pmcHandle->wakeupSrc)); + unsigned int wakeupConfig = 0; + if (pmcHandle->wakeupSrc == PMC_WAKEUP_NONE) { /* No wakeup source. */ return; } if (pmcHandle->wakeupSrc == PMC_WAKEUP_CNT) { pmcHandle->baseAddress->CNT32K_WAKE_CYC = pmcHandle->wakeupTime; /* Set wakeup time */ - pmcHandle->baseAddress->WAKEUP_CTRL.BIT.cnt32k_wakeup_en = BASE_CFG_ENABLE; /* Enable wakeup from timer */ - } else { + wakeupConfig = (BASE_CFG_ENABLE << WAKEUP_CNT_OFFSET_BIT); /* Enable CNT_32K wakeup. */ + } else if (pmcHandle->wakeupSrc <= PMC_WAKEUP_3) { PMC_PARAM_CHECK_NO_RET(IsActiveMode(pmcHandle->wakeupActMode)); - pmcHandle->baseAddress->WAKEUP_CTRL.reg |= (pmcHandle->wakeupActMode) \ + wakeupConfig = (pmcHandle->wakeupActMode) \ << (pmcHandle->wakeupSrc * WAKE_ACT_MODE_REG_WIDTH); - pmcHandle->baseAddress->WAKEUP_CTRL.reg |= ((0x1 << pmcHandle->wakeupSrc) << WAKEUP_ENABLE_OFFSET); + wakeupConfig |= ((0x1 << pmcHandle->wakeupSrc) << WAKEUP_ENABLE_OFFSET); /* Enable wakeup IO. */ } + pmcHandle->baseAddress->WAKEUP_CTRL.reg = wakeupConfig; /* Config register. */ } /** @@ -128,7 +132,11 @@ void HAL_PMC_EnterDeepSleepMode(PMC_Handle *handle) { PMC_ASSERT_PARAM(handle != NULL); PMC_ASSERT_PARAM(IsPMCInstance(handle->baseAddress)); + IRQ_Disable(); /* Disable global interrupt, prevent from being interrupted. */ handle->baseAddress->LOWPOWER_MODE.BIT.deepsleep_req = BASE_CFG_ENABLE; + while (true) { + ; /* Wait for enter deepsleep. */ + } } /** diff --git a/src/drivers/pmc/pmc_v3/inc/pmc_ip.h b/src/drivers/pmc/pmc_v3/inc/pmc_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..91c18ef48a178f6279390f7ad9e228df9f217987 --- /dev/null +++ b/src/drivers/pmc/pmc_v3/inc/pmc_ip.h @@ -0,0 +1,703 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file pmc_ip.h + * @author MCU Driver Team + * @brief Header file containing PMC module DCL driver functions. + * This file provides functions to manage the following functionalities of PMC module. + * + Definition of PMC configuration parameters. + * + PMC registers mapping structures. + * + Direct Configutration Layer driver functions. + */ +#ifndef McuMagicTag_PMC_IP_H +#define McuMagicTag_PMC_IP_H + +#include "baseinc.h" + +#ifdef PMC_PARAM_CHECK +#define PMC_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM +#define PMC_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET +#define PMC_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else +#define PMC_ASSERT_PARAM(para) ((void)0U) +#define PMC_PARAM_CHECK_NO_RET(para) ((void)0U) +#define PMC_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) +#endif + +#define PMC_WAKEUP_SRC_MARSK 0x7F +#define PMC_WAKEUP_ACT_MODE_MARSK 0x3 + +/** + * @addtogroup PMC + * @{ + */ + +/** + * @defgroup PMC_IP PMC_IP + * @brief PMC_IP: pmc_v3. + * @{ + */ + +/** + * @defgroup PMC_Param_Def PMC Parameters Definition + * @brief Definition of PMC configuration parameters + * @{ + */ + +/** + * @brief wakeup pin level mode of PMC module. + * @details status flag: + * + PMC_WAKEUP_ACT_UP_EDGE -- Wakeup valid in up edge + * + PMC_WAKEUP_ACT_DOWN_EDGE -- Wakeup valid in down edge + * + PMC_WAKEUP_ACT_HIGH_LEVEL -- Wakeup valid in high edge + * + PMC_WAKEUP_ACT_LOW_LEVEL -- Wakeup valid in low edge + */ +typedef enum { + PMC_WAKEUP_ACT_UP_EDGE = 0x00000000U, + PMC_WAKEUP_ACT_DOWN_EDGE = 0x00000001U, + PMC_WAKEUP_ACT_HIGH_LEVEL = 0x00000002U, + PMC_WAKEUP_ACT_LOW_LEVEL = 0x00000003U, +} PMC_ActMode; + +/** + * @brief Wakeup source of deep sleep. + * @details status flag: + * + PMC_WAKEUP_0 -- Wakeup from DS_WAKEUP0. + * + PMC_WAKEUP_1 -- Wakeup from DS_WAKEUP1. + * + PMC_WAKEUP_2 -- Wakeup from DS_WAKEUP2. + * + PMC_WAKEUP_3 -- Wakeup from DS_WAKEUP3. + * + PMC_WAKEUP_IWDG -- Wakeup from IWDG. + * + PMC_WAKEUP_CNT -- Wakeup from timer. + * + PMC_WAKEUP_NONE --No Wakeup source. + */ +typedef enum { + PMC_WAKEUP_0 = 0x00000000U, + PMC_WAKEUP_1 = 0x00000001U, + PMC_WAKEUP_2 = 0x00000002U, + PMC_WAKEUP_3 = 0x00000003U, + PMC_WAKEUP_IWDG = 0x00000004U, + PMC_WAKEUP_CNT = 0x00000005U, + PMC_WAKEUP_NONE = 0x00000006U, +} PMC_LowpowerWakeupSrc; + +/** + * @brief Callback Triggering Event Enumeration Definition + */ +typedef enum { + PMC_PVD_INT_ID = 0x00, +} PMC_CallBackID; + +/** + * @brief Lowpower type. + * @details status flag: + * + PMC_LP_NONE -- Non-lowpower mode. + * + PMC_LP_DEEPSLEEP -- Deepsleep mode. + */ +typedef enum { + PMC_LP_NONE = 0x00000000U, + PMC_LP_DEEPSLEEP = 0x00000001U, +} PMC_LowpowerType; + +/** + * @brief PMC PVD threshold voltage level. + * @details PMC_PVD_THRED_LEVEL, For details, see g_pvdValueTable. + */ +typedef enum { + PMC_PVD_THRED_LEVEL0 = 0x00000000U, /* rising edge 2.18V, falling edge 2.08V. */ + PMC_PVD_THRED_LEVEL1 = 0x00000001U, /* rising edge 2.28V, falling edge 2.18V. */ + PMC_PVD_THRED_LEVEL2 = 0x00000002U, /* rising edge 2.38V, falling edge 2.28V. */ + PMC_PVD_THRED_LEVEL3 = 0x00000003U, /* rising edge 2.48V, falling edge 2.38V. */ + PMC_PVD_THRED_LEVEL4 = 0x00000004U, /* rising edge 2.58V, falling edge 2.48V. */ + PMC_PVD_THRED_LEVEL5 = 0x00000005U, /* rising edge 2.68V, falling edge 2.58V. */ + PMC_PVD_THRED_LEVEL6 = 0x00000006U, /* rising edge 2.78V, falling edge 2.68V. */ + PMC_PVD_THRED_LEVEL7 = 0x00000007U, /* rising edge 2.88V, falling edge 2.78V. */ +} PMC_PvdThreshold; + +/** + * @brief PMC extend handle, configuring some special parameters. + */ +typedef struct { +} PMC_ExtendHandle; + +/** + * @brief User-defined callback function. + */ +typedef struct { + /** Event callback function of the flash module */ + void (*PmcCallBack)(void *handle); +} PMC_UserCallBack; + +/** + * @} + */ + +/** + * @defgroup PMC_REG_Definition PMC Register Structure. + * @brief PMC Register Structure Definition. + * @{ + */ + +/* Define the union PMC_LOWPOWER_MODE */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved_0 : 4 ; + unsigned int deepsleep_req : 1 ; /**< The system enters the deepsleep mode. */ + unsigned int reserved_1 : 27 ; + } BIT; +} volatile PMC_LOWPOWER_MODE; + +/* Define the union PMC_WAKEUP_CTRL */ +typedef union { + unsigned int reg; + struct { + unsigned int wakeup0_act_mode : 2 ; /**< Valid mode select of WakeUP0. */ + unsigned int wakeup1_act_mode : 2 ; /**< Valid mode select of WakeUP1. */ + unsigned int wakeup2_act_mode : 2 ; /**< Valid mode select of WakeUP2. */ + unsigned int wakeup3_act_mode : 2 ; /**< Valid mode select of WakeUP3. */ + unsigned int wakeup0_en : 1 ; /**< Wakeup0 enable. */ + unsigned int wakeup1_en : 1 ; /**< Wakeup1 enable. */ + unsigned int wakeup2_en : 1 ; /**< Wakeup2 enable. */ + unsigned int wakeup3_en : 1 ; /**< Wakeup3 enable. */ + unsigned int iwdg_wakeup_en : 1 ; /**< IWDG enable. */ + unsigned int reserved_0 : 3 ; + unsigned int cnt32k_wakeup_en : 1 ; /**< Scheduled wakeup enable. */ + unsigned int reserved_1 : 15 ; + } BIT; +} volatile PMC_WAKEUP_CTRL; + +/* Define the union PMC_LOWPOWER_STATUS */ +typedef union { + unsigned int reg; + struct { + unsigned int wakeup_src_lock : 7 ; /**< Starts the wakeup source query. */ + unsigned int reserved_0 : 1 ; + unsigned int starup_from_shutdown : 1 ; /**< Start from the shutdown state. */ + unsigned int starup_from_deepsleep : 1 ; /**< Start from the deepsleep state. */ + unsigned int reserved_1 : 2 ; + unsigned int wakeup0_status : 1 ; /**< Wakeup0 wakeup source status. */ + unsigned int wakeup1_status : 1 ; /**< Wakeup1 wakeup source status. */ + unsigned int wakeup2_status : 1 ; /**< Wakeup2 wakeup source status. */ + unsigned int wakeup3_status : 1 ; /**< Wakeup3 wakeup source status. */ + unsigned int reserved_2 : 16 ; + } BIT; +} volatile PMC_LOWPOWER_STATUS; + +/* Define the union PMC_PVD_CTRL */ +typedef union { + unsigned int reg; + struct { + unsigned int pvd_en : 1 ; /**< PVD enable. */ + unsigned int reserved_0 : 3 ; + unsigned int pvd_rise_lv : 3 ; /**< PVD rising edge threshold. */ + unsigned int reserved_1 : 1 ; + unsigned int pvd_fall_lv : 3 ; /**< PVD falling edge threshold. */ + unsigned int reserved_2 : 21 ; + } BIT; +} volatile PMC_PVD_CTRL; + +/** + * @brief PMC registers definition structure. + */ +typedef struct { + unsigned int reserved_0[128]; + PMC_LOWPOWER_MODE LOWPOWER_MODE; /**< Low-power mode control register. Offset address: 0x200. */ + unsigned int CNT32K_WAKE_CYC; /**< Timed wakeup period config reg. Offset address: 0x204. */ + PMC_WAKEUP_CTRL WAKEUP_CTRL; /**< Wakeup control register in deepsleep mode. + Offset address: 0x208. */ + PMC_LOWPOWER_STATUS LOWPOWER_STATUS; /**< Low-power status query register. Offset address: 0x20C. */ + unsigned int reserved_1[508]; + PMC_PVD_CTRL PVD_CTRL; /**< PVD control register. Offset address: 0x20C. */ + unsigned int reserved_2[319]; + unsigned int AON_USER_REG0; /**< AON domain user register 0. Offset address: 0xF00. */ + unsigned int AON_USER_REG1; /**< AON domain user register 1. Offset address: 0xF04. */ + unsigned int AON_USER_REG2; /**< AON domain user register 2. Offset address: 0xF08. */ + unsigned int AON_USER_REG3; /**< AON domain user register 3. Offset address: 0xF0C. */ +} volatile PMC_RegStruct; + +/** + * @brief Check PVD threshold voltage level. + * @param value value of losc rtrim value. + * @retval true + * @retval false + */ +static inline bool IsPvdThreshold(PMC_PvdThreshold value) +{ + return (value == PMC_PVD_THRED_LEVEL0 || value == PMC_PVD_THRED_LEVEL1 || \ + value == PMC_PVD_THRED_LEVEL2 || value == PMC_PVD_THRED_LEVEL3 || \ + value == PMC_PVD_THRED_LEVEL4 || value == PMC_PVD_THRED_LEVEL5 || \ + value == PMC_PVD_THRED_LEVEL6 || value == PMC_PVD_THRED_LEVEL7); +} + +/** + * @brief Check PMC Wakeup source. + * @param wakeSrc value of Wakeup source. + * @retval true + * @retval false + */ +static inline bool IsWakeupSrc(PMC_LowpowerWakeupSrc wakeSrc) +{ + return (wakeSrc == PMC_WAKEUP_0 || wakeSrc == PMC_WAKEUP_1 || \ + wakeSrc == PMC_WAKEUP_2 || wakeSrc == PMC_WAKEUP_3 || \ + wakeSrc == PMC_WAKEUP_CNT); +} + +/** + * @brief Check PMC active mode. + * @param mode value of active mode. + * @retval true + * @retval false + */ +static inline bool IsActiveMode(PMC_ActMode mode) +{ + return (mode == PMC_WAKEUP_ACT_UP_EDGE || mode == PMC_WAKEUP_ACT_DOWN_EDGE || \ + mode == PMC_WAKEUP_ACT_HIGH_LEVEL || mode == PMC_WAKEUP_ACT_LOW_LEVEL); +} + +/** + * @brief Enter sleep mode interface. + * @param None. + * @retval None. + */ +static inline void DCL_PMC_EnterSleep(void) +{ +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) + /* If user mode is supported, make sure to execute WFI + commands in machine mode */ + static unsigned int priv = RISCV_U_MODE; + RISCV_PRIV_MODE_SWITCH(priv); + __asm("wfi"); + RISCV_PRIV_MODE_SWITCH(priv); +#else + /* Only machine mode, no need for mode switching */ + __asm("wfi"); +#endif +} + +/** + * @brief Enter deepsleep mode interface. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_EnterDeepSleep(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->LOWPOWER_MODE.BIT.deepsleep_req = BASE_CFG_ENABLE; +} + +/** + * @brief Setting wakeup timer cycle. + * @param pmcx PMC register base address. + * @param cycle Timer cycle value. + * @retval None. + */ +static inline void DCL_PMC_SetFixTimeWakeupTimer(PMC_RegStruct *pmcx, unsigned int cycle) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->CNT32K_WAKE_CYC = cycle; +} + +/** + * @brief Enable wakeup from timer. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_FixTimeWakeupEnable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.cnt32k_wakeup_en = BASE_CFG_ENABLE; +} + +/** + * @brief Disable wakeup from timer. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_FixTimeWakeupDisable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.cnt32k_wakeup_en = BASE_CFG_DISABLE; +} + +/** + * @brief Enable wakeup from WAKEUP0. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_Wakeup0Enable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.wakeup0_en = BASE_CFG_ENABLE; +} + +/** + * @brief Disable wakeup from WAKEUP0. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_Wakeup0Disable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.wakeup0_en = BASE_CFG_DISABLE; +} + +/** + * @brief Enable wakeup from WAKEUP1. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_Wakeup1Enable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.wakeup1_en = BASE_CFG_ENABLE; +} + +/** + * @brief Disable wakeup from WAKEUP1. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_Wakeup1Disable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.wakeup1_en = BASE_CFG_DISABLE; +} + +/** + * @brief Enable wakeup from WAKEUP2. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_Wakeup2Enable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.wakeup2_en = BASE_CFG_ENABLE; +} + +/** + * @brief Disable wakeup from WAKEUP2. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_Wakeup2Disable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.wakeup2_en = BASE_CFG_DISABLE; +} + +/** + * @brief Enable wakeup from WAKEUP3. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_Wakeup3Enable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.wakeup3_en = BASE_CFG_ENABLE; +} + +/** + * @brief Disable wakeup from WAKEUP3. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_Wakeup3Disable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.wakeup3_en = BASE_CFG_DISABLE; +} + +/** + * @brief Enable wakeup from IWDG. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_WakeupIwdgEnable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.iwdg_wakeup_en = BASE_CFG_ENABLE; +} + +/** + * @brief Disable wakeup from IWDG. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_WakeupIwdgDisable(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->WAKEUP_CTRL.BIT.iwdg_wakeup_en = BASE_CFG_DISABLE; +} + +/** + * @brief Setting WAKEUP0 active level mode. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_SetWakeup0ActiveMode(PMC_RegStruct *pmcx, PMC_ActMode mode) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + PMC_PARAM_CHECK_NO_RET(IsActiveMode(mode)); + pmcx->WAKEUP_CTRL.BIT.wakeup0_act_mode = ((unsigned int)mode & PMC_WAKEUP_ACT_MODE_MARSK); +} + +/** + * @brief Setting WAKEUP1 active level mode. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_SetWakeup1ActiveMode(PMC_RegStruct *pmcx, PMC_ActMode mode) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + PMC_PARAM_CHECK_NO_RET(IsActiveMode(mode)); + pmcx->WAKEUP_CTRL.BIT.wakeup1_act_mode = ((unsigned int)mode & PMC_WAKEUP_ACT_MODE_MARSK); +} + +/** + * @brief Setting WAKEUP2 active level mode. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_SetWakeup2ActiveMode(PMC_RegStruct *pmcx, PMC_ActMode mode) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + PMC_PARAM_CHECK_NO_RET(IsActiveMode(mode)); + pmcx->WAKEUP_CTRL.BIT.wakeup2_act_mode = ((unsigned int)mode & PMC_WAKEUP_ACT_MODE_MARSK); +} + +/** + * @brief Setting WAKEUP3 active level mode. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_SetWakeup3ActiveMode(PMC_RegStruct *pmcx, PMC_ActMode mode) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + PMC_PARAM_CHECK_NO_RET(IsActiveMode(mode)); + pmcx->WAKEUP_CTRL.BIT.wakeup3_act_mode = ((unsigned int)mode & PMC_WAKEUP_ACT_MODE_MARSK); +} + +/** + * @brief Getting WAKEUP0 status. + * @param pmcx PMC register base address. + * @retval Wakeup status. + */ +static inline bool DCL_PMC_GetWakeup0Status(const PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + return (pmcx->LOWPOWER_STATUS.BIT.wakeup0_status); +} + +/** + * @brief Getting WAKEUP1 status. + * @param pmcx PMC register base address. + * @retval Wakeup status. + */ +static inline bool DCL_PMC_GetWakeup1Status(const PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + return (pmcx->LOWPOWER_STATUS.BIT.wakeup1_status); +} + +/** + * @brief Getting WAKEUP2 status. + * @param pmcx PMC register base address. + * @retval Wakeup status. + */ +static inline bool DCL_PMC_GetWakeup2Status(const PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + return (pmcx->LOWPOWER_STATUS.BIT.wakeup2_status); +} + +/** + * @brief Getting WAKEUP3 status. + * @param pmcx PMC register base address. + * @retval Wakeup status. + */ +static inline bool DCL_PMC_GetWakeup3Status(const PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + return (pmcx->LOWPOWER_STATUS.BIT.wakeup3_status); +} + +/** + * @brief Getting flag of wakeup from deepsleep mode. + * @param pmcx PMC register base address. + * @retval flag of wakeup from deepsleep mode. + */ +static inline bool DCL_PMC_GetStartupFromDeepSleepFlag(const PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + return (pmcx->LOWPOWER_STATUS.BIT.starup_from_deepsleep); +} + +/** + * @brief Getting flag of wakeup from shutdown mode. + * @param pmcx PMC register base address. + * @retval flag of wakeup from shutdown mode. + */ +static inline bool DCL_PMC_GetStartupFromShutdownFlag(const PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + return (pmcx->LOWPOWER_STATUS.BIT.starup_from_shutdown); +} + +/** + * @brief Getting wakeup source. + * @param pmcx PMC register base address. + * @retval source of wakeup. + */ +static inline unsigned int DCL_PMC_GetWakeupSrc(const PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + return (pmcx->LOWPOWER_STATUS.BIT.wakeup_src_lock & PMC_WAKEUP_SRC_MARSK); +} + +/** + * @brief Setting always on user's regsiter 0. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_SetAlwaysOnUserReg0(PMC_RegStruct *pmcx, unsigned int value) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->AON_USER_REG0 = value; +} + +/** + * @brief Getting always on user's regsiter 0. + * @param pmcx PMC register base address. + * @retval Register0's value. + */ +static inline unsigned int DCL_PMC_GetAlwaysOnUserReg0(const PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + return (pmcx->AON_USER_REG0); +} + +/** + * @brief Setting always on user's regsiter 1. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_SetAlwaysOnUserReg1(PMC_RegStruct *pmcx, unsigned int value) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->AON_USER_REG1 = value; +} + +/** + * @brief Getting always on user's regsiter 1. + * @param pmcx PMC register base address. + * @retval Register1's value. + */ +static inline unsigned int DCL_PMC_GetAlwaysOnUserReg1(const PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + return (pmcx->AON_USER_REG1); +} + +/** + * @brief Setting always on user's regsiter 2. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_SetAlwaysOnUserReg2(PMC_RegStruct *pmcx, unsigned int value) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->AON_USER_REG2 = value; +} + +/** + * @brief Getting always on user's regsiter 2. + * @param pmcx PMC register base address. + * @retval Register2's value. + */ +static inline unsigned int DCL_PMC_GetAlwaysOnUserReg2(const PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + return (pmcx->AON_USER_REG2); +} + +/** + * @brief Setting always on user's regsiter 3. + * @param pmcx PMC register base address. + * @retval None. + */ +static inline void DCL_PMC_SetAlwaysOnUserReg3(PMC_RegStruct *pmcx, unsigned int value) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->AON_USER_REG3 = value; +} + +/** + * @brief Getting always on user's regsiter 3. + * @param pmcx PMC register base address. + * @retval Register3's value. + */ +static inline unsigned int DCL_PMC_GetAlwaysOnUserReg3(const PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + return (pmcx->AON_USER_REG3); +} + +/** + * @brief Enable PVD function. + * @retval None. + */ +static inline void DCL_PMC_EnablePvd(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->PVD_CTRL.BIT.pvd_en = BASE_CFG_SET; +} + +/** + * @brief Disable PVD function. + * @retval None. + */ +static inline void DCL_PMC_DisablePvd(PMC_RegStruct *pmcx) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + pmcx->PVD_CTRL.BIT.pvd_en = BASE_CFG_UNSET; +} + +/** + * @brief Set PVD threshold. + * @param threshold PMC PVD threshold voltage level. + * @retval None. + */ +static inline void DCL_PMC_SetPvdThreshold(PMC_RegStruct *pmcx, PMC_PvdThreshold threshold) +{ + PMC_ASSERT_PARAM(IsPMCInstance(pmcx)); + PMC_ASSERT_PARAM(IsPvdThreshold(threshold)); + pmcx->PVD_CTRL.BIT.pvd_fall_lv = threshold; + pmcx->PVD_CTRL.BIT.pvd_rise_lv = threshold; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* McuMagicTag_PMC_IP_H */ \ No newline at end of file diff --git a/src/drivers/pmc/pmc_v3/src/pmc.c b/src/drivers/pmc/pmc_v3/src/pmc.c new file mode 100644 index 0000000000000000000000000000000000000000..f4b1b0cf821c0481764c6e21f3316b3de08e0553 --- /dev/null +++ b/src/drivers/pmc/pmc_v3/src/pmc.c @@ -0,0 +1,214 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file pmc.c + * @author MCU Driver Team. + * @brief ACMP HAL level module driver. + * This file provides firmware functions to manage the following + * functionalities of the DAC and Comparator. + * + PMC's initialization and de-initialization functions. + * + Enter sleep, deepsleep mode functions. + */ + +#include "pmc_ip.h" +#include "pmc.h" + +#define WAKEUP_ENABLE_OFFSET 0x8 +#define WAKE_ACT_MODE_REG_WIDTH 0x2 +#define WAKEUP_CNT_OFFSET_BIT 16 +#define IWDG_WAKEUP_OFFSET_BIT 12 + +/** + * @brief Setting deepsleep wakeup source. + * @param pmcHandle: PMC handle. + * @retval None. + */ +static void PMC_SetDeepSleepWakeupSrc(PMC_Handle *pmcHandle) +{ + PMC_ASSERT_PARAM(pmcHandle != NULL); + PMC_ASSERT_PARAM(IsPMCInstance(pmcHandle->baseAddress)); + PMC_PARAM_CHECK_NO_RET(IsWakeupSrc(pmcHandle->wakeupSrc)); + unsigned int wakeupConfig = 0; + if (pmcHandle->wakeupSrc == PMC_WAKEUP_NONE) { /* No wakeup source. */ + return; + } + + if (pmcHandle->wakeupSrc == PMC_WAKEUP_CNT) { + pmcHandle->baseAddress->CNT32K_WAKE_CYC = pmcHandle->wakeupTime; /* Set wakeup time */ + wakeupConfig = (BASE_CFG_ENABLE << WAKEUP_CNT_OFFSET_BIT); /* Enable CNT_32K wakeup. */ + } else if (pmcHandle->wakeupSrc == PMC_WAKEUP_IWDG) { + wakeupConfig = (BASE_CFG_ENABLE << IWDG_WAKEUP_OFFSET_BIT); /* Enable wakeup from iwdg */ + } else if (pmcHandle->wakeupSrc <= PMC_WAKEUP_3) { + PMC_PARAM_CHECK_NO_RET(IsActiveMode(pmcHandle->wakeupActMode)); + wakeupConfig = (pmcHandle->wakeupActMode) << (pmcHandle->wakeupSrc * WAKE_ACT_MODE_REG_WIDTH); + wakeupConfig |= ((0x1 << pmcHandle->wakeupSrc) << WAKEUP_ENABLE_OFFSET); /* Enable wakeup IO. */ + } + pmcHandle->baseAddress->WAKEUP_CTRL.reg = wakeupConfig; /* Config register. */ +} + +/** + * @brief Init PVD function. + * @param pmcHandle: PMC handle. + * @retval None. + */ +static void PMC_PvdInit(PMC_Handle *pmcHandle) +{ + PMC_ASSERT_PARAM(pmcHandle != NULL); + PMC_ASSERT_PARAM(IsPMCInstance(pmcHandle->baseAddress)); + PMC_PARAM_CHECK_NO_RET(pmcHandle->pvdThreshold <= PMC_PVD_THRED_LEVEL7); + if (pmcHandle->pvdEnable == BASE_CFG_ENABLE) { /* if PVD function is enable */ + DCL_PMC_EnablePvd(pmcHandle->baseAddress); + DCL_PMC_SetPvdThreshold(pmcHandle->baseAddress, pmcHandle->pvdThreshold); /* set PVD threhold voltage */ + } else { + DCL_PMC_DisablePvd(pmcHandle->baseAddress); + } +} + +/** + * @brief PMC initialize interface. + * @param handle: PMC handle. + * @retval None. + */ +void HAL_PMC_Init(PMC_Handle *handle) +{ + PMC_ASSERT_PARAM(handle != NULL); + PMC_ASSERT_PARAM(IsPMCInstance(handle->baseAddress)); + PMC_PvdInit(handle); + PMC_SetDeepSleepWakeupSrc(handle); +} + +/** + * @brief PMC deinitialize interface. + * @param handle: PMC handle. + * @retval None. + */ +void HAL_PMC_DeInit(PMC_Handle *handle) +{ + PMC_ASSERT_PARAM(handle != NULL); + PMC_ASSERT_PARAM(IsPMCInstance(handle->baseAddress)); + DCL_PMC_DisablePvd(handle->baseAddress); + /* Disable all wakeup source. */ + DCL_PMC_FixTimeWakeupDisable(handle->baseAddress); + DCL_PMC_Wakeup0Disable(handle->baseAddress); + DCL_PMC_Wakeup1Disable(handle->baseAddress); + DCL_PMC_Wakeup2Disable(handle->baseAddress); + DCL_PMC_Wakeup3Disable(handle->baseAddress); + DCL_PMC_WakeupIwdgDisable(handle->baseAddress); + handle->userCallBack.PmcCallBack = NULL; /* Clean interrupt callback functions. */ +} + +/** + * @brief Enter sleep interface. + * @param None. + * @retval None. + */ +void HAL_PMC_EnterSleepMode(void) +{ +#if defined(USER_MODE_ENABLE) && (USER_MODE_ENABLE == 1) + /* If user mode is supported, make sure to execute WFI + commands in machine mode */ + static unsigned int priv = RISCV_U_MODE; + RISCV_PRIV_MODE_SWITCH(priv); + __asm("wfi"); + RISCV_PRIV_MODE_SWITCH(priv); +#else + __asm("wfi"); +#endif +} + +/** + * @brief Enter deep sleep interface. + * @param handle: PMC handle. + * @retval None. + */ +void HAL_PMC_EnterDeepSleepMode(PMC_Handle *handle) +{ + PMC_ASSERT_PARAM(handle != NULL); + PMC_ASSERT_PARAM(IsPMCInstance(handle->baseAddress)); + IRQ_Disable(); /* Disable global interrupt, prevent from being interrupted. */ + DCL_PMC_EnterDeepSleep(handle->baseAddress); + while (true) { + ; /* Wait for enter deepsleep. */ + } +} + +/** + * @brief Enter shutdown interface. + * @param handle: PMC handle. + * @retval None. + */ +void HAL_PMC_EnterShutdownMode(PMC_Handle *handle) +{ + BASE_FUNC_UNUSED(handle); + /* Not support. */ +} + +/** + * @brief Get wakeup source type. + * @param handle: PMC handle. + * @retval Lowpower type. + */ +PMC_LowpowerType HAL_PMC_GetWakeupType(PMC_Handle *handle) +{ + PMC_ASSERT_PARAM(handle != NULL); + PMC_ASSERT_PARAM(IsPMCInstance(handle->baseAddress)); + + PMC_LowpowerType wakeupMode; + bool deepsleepFlag = BASE_CFG_UNSET; /* Set as default. */ + deepsleepFlag = DCL_PMC_GetStartupFromDeepSleepFlag(handle->baseAddress); + if (deepsleepFlag == BASE_CFG_SET) { /* If deepsleep flag is set */ + wakeupMode = PMC_LP_DEEPSLEEP; + } else { + wakeupMode = PMC_LP_NONE; + } + return wakeupMode; +} + +/** + * @brief Interrupt handler function. + * @param handle PMC module handle. + * @retval None. + */ +void HAL_PMC_IrqHandler(void *handle) +{ + PMC_ASSERT_PARAM(handle != NULL); + PMC_Handle *pmcHandle = (PMC_Handle *)handle; + PMC_ASSERT_PARAM(IsPMCInstance(pmcHandle->baseAddress)); + + SYSCTRL1_RegStruct *sysCtrl1x = SYSCTRL1_BASE; + if (sysCtrl1x->PVD_STATUS.BIT.pvd_toggle == 1) { /* PVD interrupt */ + if (pmcHandle->userCallBack.PmcCallBack != NULL) { + pmcHandle->userCallBack.PmcCallBack(pmcHandle); /* execute user's callback */ + } + } +} + +/** + * @brief Interrupt callback functions registration interface. + * @param handle PMC module handle. + * @param callbackID base callback id + * @param pCallback Pointer for the user callback function. + * @retval None. + */ +void HAL_PMC_RegisterCallback(PMC_Handle *handle, PMC_CallBackID callbackID, PMC_CallbackType pCallback) +{ + PMC_ASSERT_PARAM(handle != NULL); + PMC_ASSERT_PARAM(IsPMCInstance(handle->baseAddress)); + PMC_ASSERT_PARAM(pCallback != NULL); + BASE_FUNC_UNUSED(callbackID); /* This parameter is not used to prevent compilation errors. */ + handle->userCallBack.PmcCallBack = pCallback; +} \ No newline at end of file diff --git a/src/drivers/qdm/common/inc/qdm.h b/src/drivers/qdm/common/inc/qdm.h index b890338e9219b53e8ee0127d8e9172eb89d6f367..2c647b67dd01f289c466fadcb230756480117ec5 100644 --- a/src/drivers/qdm/common/inc/qdm.h +++ b/src/drivers/qdm/common/inc/qdm.h @@ -116,7 +116,7 @@ typedef struct _QDM_handle { unsigned int qcMax; /**< TSU maximum counter number, default zero */ unsigned int period; /**< PTU period*/ unsigned int interruptEn; /**< interrupt settings by bits */ - int motorLineNum; /**< encoder line number */ + unsigned int motorLineNum; /**< encoder line number */ int speedRpm; /**< motor speed */ QDM_IndexLockMode lock_mode; /**< QDM Z index lock mode */ QDM_UserCallBack userCallBack; /**< QDM Interrupt callback functions */ @@ -129,11 +129,11 @@ typedef void (* QDM_CallbackType)(void *handle); */ /** - * @defgroup QDM_API_Declaration QDM HAL API + * @defgroup QDM_API_Declaration + * @brief QDM HAL API, Hardware abstraction layer * @{ */ -/* Hardware abstraction layer */ BASE_StatusType HAL_QDM_Init(QDM_Handle *qdmHandle); BASE_StatusType HAL_QDM_DeInit(QDM_Handle *qdmHandle); void HAL_QDM_GetPhaseErrorStatus(const QDM_Handle *qdmHandle, unsigned int *errStatus); diff --git a/src/drivers/qdm/qdm_v0/src/qdm.c b/src/drivers/qdm/qdm_v0/src/qdm.c index 5c0083d4d39d1c9dc33db16858bcb0881589cf4c..b85d6337f288caeefc31348de67f8a8733f2c0d9 100644 --- a/src/drivers/qdm/qdm_v0/src/qdm.c +++ b/src/drivers/qdm/qdm_v0/src/qdm.c @@ -289,13 +289,13 @@ static void CalculateSpeed(QDM_Handle *qdmHandle) lastPoslockValue = qdmHandle->baseAddress->QPOSLOCK; if (qdmHandle->baseAddress->QDMSTS.BIT.qdir_sts == 1) { /* forward */ tmp = deltaValue >> qdmHandle->baseAddress->QCTRL.BIT.qdu_xclk; - speed = ((tmp * SECONDS_PER_MINUTES) / qdmHandle->motorLineNum) \ - * (BASE_FUNC_GetCpuFreqHz() / qdmHandle->period); + speed = (int)(((tmp * SECONDS_PER_MINUTES) / qdmHandle->motorLineNum) \ + * (BASE_FUNC_GetCpuFreqHz() / qdmHandle->period)); qdmHandle->speedRpm = speed; } else { /* reverse */ tmp = (qdmHandle->posMax - deltaValue) >> qdmHandle->baseAddress->QCTRL.BIT.qdu_xclk; - speed = ((tmp * SECONDS_PER_MINUTES) / qdmHandle->motorLineNum) \ - * (BASE_FUNC_GetCpuFreqHz() / qdmHandle->period); + speed = (int)(((tmp * SECONDS_PER_MINUTES) / qdmHandle->motorLineNum) \ + * (BASE_FUNC_GetCpuFreqHz() / qdmHandle->period)); qdmHandle->speedRpm = -speed; } } @@ -538,7 +538,7 @@ int HAL_QDM_GetSpeedRpmMT(QDM_Handle *qdmHandle) utime = BASE_FUNC_GetCpuFreqHz() / qdmHandle->motorLineNum; tmp = utime << qdmHandle->baseAddress->QTSUCTRL.BIT.cevt_prescaler \ >> qdmHandle->baseAddress->QTSUCTRL.BIT.tsu_prescaler >> qdmHandle->baseAddress->QCTRL.BIT.qdu_xclk; - rpm = tmp * SECONDS_PER_MINUTES / qdmHandle->baseAddress->QCPRD; + rpm = (int)(tmp * SECONDS_PER_MINUTES / qdmHandle->baseAddress->QCPRD); if (qdmHandle->baseAddress->QDMSTS.BIT.qdir_sts == BASE_CFG_SET) { qdmHandle->speedRpm = rpm; diff --git a/src/drivers/smbus/common/inc/smbus.h b/src/drivers/smbus/common/inc/smbus.h new file mode 100644 index 0000000000000000000000000000000000000000..4558bad9bf8f0117edb749327bf03c9fcd191d5e --- /dev/null +++ b/src/drivers/smbus/common/inc/smbus.h @@ -0,0 +1,163 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file smbus.h + * @author MCU Driver Team, + * @brief SMBUS module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the SMBUS. + * + Initialization and de-initialization functions. + * + Peripheral transmit and receiving functions. + * + SMBUS parameter handle definition. + * + Basic Configuration Parameter Enumeration Definition. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_SMBUS_H +#define McuMagicTag_SMBUS_H + +/* Includes ------------------------------------------------------------------*/ +#include "i2c_ip.h" +#include "smbus_ip.h" +#include "dma.h" + +/** + * @defgroup SMBUS SMBUS + * @brief SMBUS module. + * @{ + */ + +/** + * @defgroup SMBUS_Common SMBUS Common + * @brief SMBUS common external module. + * @{ + */ + +/* Typedef definitions -------------------------------------------------------*/ + +/** + * @defgroup SMBUS_Handle_Definition SMBUS Handle Definition + * @{ + */ + +/** + * @brief Module Status Enumeration Definition + */ +typedef enum { + SMBUS_STATE_RESET = 0x00000000U, + SMBUS_STATE_READY = 0x00000001U, + SMBUS_STATE_BUSY = 0x00000002U, + SMBUS_STATE_BUSY_MASTER_TX = 0x00000004U, + SMBUS_STATE_BUSY_MASTER_RX = 0x00000008U, + SMBUS_STATE_BUSY_SLAVE_TX = 0x00000010U, + SMBUS_STATE_BUSY_SLAVE_RX = 0x00000020U, + SMBUS_STATE_TIMEOUT = 0x00000040U, + SMBUS_STATE_ERROR = 0x00000080U, +} SMBUS_StateType; + +/** + * @brief Module handle structure definition + */ +typedef struct _SMBUS_Handle { + I2C_RegStruct *baseAddress; /**< Register base address. */ + SMBUS_ModeSelectType functionMode; /**< Set master or slave. */ + SMBUS_AddressMode addrMode; /**< 7bit or 10bit. */ + unsigned int slaveOwnAddress; /**< Own address as slave. */ + unsigned int sdaHoldTime; /**< SDA hold time. */ + unsigned int freq; /**< Operating Frequency. */ + unsigned int ignoreAckFlag; /**< Ignore the response flag bit. */ + unsigned int generalCallMode; /**< General call mode. */ + + unsigned int rxWaterMark; /**< RX threshold configuration. */ + unsigned int txWaterMark; /**< TX threshold configuration. */ + unsigned int rxDmaCh; /**< RX DMA channel */ + unsigned int txDmaCh; /**< TX DMA channel */ + DMA_Handle *dmaHandle; /**< DMA handle */ + + volatile unsigned int deviceAddress; + volatile unsigned char *transferBuff; /**< Transmission Data buffer. */ + volatile unsigned int transferSize; /**< Transmission Data Length. */ + volatile unsigned int transferCount; /**< Transferred Data Count. */ + volatile unsigned int frameOpt; + + unsigned int timeout; /**< Timeout period. */ + volatile unsigned char sendAddrStatus; + volatile unsigned int txReadCmdCount; + volatile unsigned int dmaTransferSize; + volatile unsigned int excuteCmdFlag; + + volatile SMBUS_StateType state; /**< Running Status. */ + BASE_StatusType errorCode; /**< Error Code. */ + SMBUS_UserCallBack userCallBack; /**< User-defined callback function. */ + SMBUS_ExtendHandle handleEx; /**< Extend handle, configuring some special parameters. */ +} SMBUS_Handle; +/** + * @} + */ + +/** + * @defgroup SMBUS_API_Declaration SMBUS HAL API + * @{ + */ +/** + * @brief Callback Function Type Definition. + */ +typedef void (*SMBUS_CallbackFunType)(void *handle); + +/* Function Interface Definition -------------------------------------------------------*/ + +BASE_StatusType HAL_SMBUS_Init(SMBUS_Handle *handle); +BASE_StatusType HAL_SMBUS_Deinit(SMBUS_Handle *handle); +BASE_StatusType HAL_SMBUS_RegisterCallback(SMBUS_Handle *handle, SMBUS_CallbackId callbackID, + SMBUS_CallbackFunType pcallback); + +BASE_StatusType HAL_SMBUS_MasterReadBlocking(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int timeout, unsigned int frameOpt); +BASE_StatusType HAL_SMBUS_MasterWriteBlocking(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int timeout, unsigned int frameOpt); +BASE_StatusType HAL_SMBUS_SlaveReadBlocking(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int timeout, + unsigned int frameOpt); +BASE_StatusType HAL_SMBUS_SlaveWriteBlocking(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int timeout, + unsigned int frameOpt); + +BASE_StatusType HAL_SMBUS_MasterReadIT(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int frameOpt); +BASE_StatusType HAL_SMBUS_MasterWriteIT(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int frameOpt); +BASE_StatusType HAL_SMBUS_SlaveReadIT(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int frameOpt); +BASE_StatusType HAL_SMBUS_SlaveWriteIT(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int frameOpt); + +BASE_StatusType HAL_SMBUS_MasterReadDMA(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int frameOpt); +BASE_StatusType HAL_SMBUS_MasterWriteDMA(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int frameOpt); +BASE_StatusType HAL_SMBUS_SlaveReadDMA(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int frameOpt); +BASE_StatusType HAL_SMBUS_SlaveWriteDMA(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int frameOpt); + +void HAL_SMBUS_IrqHandler(void *handle); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* #ifndef McuMagicTag_SMBUS_H */ \ No newline at end of file diff --git a/src/drivers/smbus/smbus_v0/inc/smbus_ex.h b/src/drivers/smbus/smbus_v0/inc/smbus_ex.h new file mode 100644 index 0000000000000000000000000000000000000000..d75fb78fe6fa199cb65d7b849f3baa02c9918e79 --- /dev/null +++ b/src/drivers/smbus/smbus_v0/inc/smbus_ex.h @@ -0,0 +1,57 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file smbus_ex.h + * @author MCU Driver Team + * @brief SMBUS module driver + * @details The header file contains the following declaration: + * + Setting the Special Function Configuration. + */ + +#ifndef McuMagicTag_SMBUS_EX_H +#define McuMagicTag_SMBUS_EX_H + +/* Includes ------------------------------------------------------------------*/ +#include "smbus.h" +/* Macro definitions ---------------------------------------------------------*/ +/** + * @addtogroup SMBUS_IP + * @{ + */ + +/** + * @defgroup SMBUS_EX_API_Declaration SMBUS HAL API EX + * @{ + */ +BASE_StatusType HAL_SMBUS_SetDataTransferSequenceEx(SMBUS_Handle *handle, SMBUS_DataTransferSequenceType sequence); +BASE_StatusType HAL_SMBUS_SetSclStretchModeEx(SMBUS_Handle *handle, SMBUS_ClockStretchType clkStretch); +BASE_StatusType HAL_SMBUS_SetSclLowTimeoutEx(SMBUS_Handle *handle, unsigned int sclLowTimeout); +BASE_StatusType HAL_SMBUS_SetBusFreeTimeEx(SMBUS_Handle *handle, unsigned int busFreeTime); +BASE_StatusType HAL_SMBUS_Set10BitSlaveEnableEx(SMBUS_Handle *handle); +BASE_StatusType HAL_SMBUS_SetDeviceIdAddressEnableEx(SMBUS_Handle *handle); +BASE_StatusType HAL_SMBUS_SetStartByteEnableEx(SMBUS_Handle *handle); +BASE_StatusType HAL_SMBUS_SetOwnAddressMaskEx(SMBUS_Handle *handle, unsigned int addrMask); +BASE_StatusType HAL_SMBUS_SetOwnXmbAddressMaskEx(SMBUS_Handle *handle, unsigned int addrMask); +/** + * @} + */ + +/** + * @} + */ + +#endif /* McuMagicTag_SMBUS_H */ \ No newline at end of file diff --git a/src/drivers/smbus/smbus_v0/inc/smbus_ip.h b/src/drivers/smbus/smbus_v0/inc/smbus_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..065c45fe39a4f51365b4046e4090cac752564c6a --- /dev/null +++ b/src/drivers/smbus/smbus_v0/inc/smbus_ip.h @@ -0,0 +1,215 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file smbus_ip.h + * @author MCU Driver Team + * @brief SMBUS module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the SMBUS. + * + Extended Configuration Parameter Struct Definition. + * + Register definition structure. + * + Timing command enumeration. + * + Direct configuration layer interface. + * + Basic parameter configuration macro. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef McuMagicTag_SMBUS_IP_H +#define McuMagicTag_SMBUS_IP_H + +/* Includes ------------------------------------------------------------------*/ +#include "baseinc.h" + +/* Macro definitions --------------------------------------------------------- */ +#ifdef SMBUS_PARAM_CHECK +#define SMBUS_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM +#define SMBUS_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET +#define SMBUS_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else +#define SMBUS_ASSERT_PARAM(para) ((void)0U) +#define SMBUS_PARAM_CHECK_NO_RET(para) ((void)0U) +#define SMBUS_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) +#endif + +/** + * @addtogroup SMBUS + * @{ + */ + +/** + * @defgroup SMBUS_IP SMBUS_IP + * @brief SMBUS_IP: smbus_v0 + * @{ + */ + +#define SMBUS_IGNORE_NAK_ENABLE BASE_CFG_ENABLE /**< Ignore acknowledgment configuration enable. */ +#define SMBUS_IGNORE_NAK_DISABLE BASE_CFG_DISABLE /**< Ignore acknowledgment configuration disable. */ + +#define SMBUS_STANDARD_FREQ_TH 100000 /**< Standard mode,the frequency band is less than or equal to 100 kHz. */ + +#define SMBUS_INTR_RAW_ALL_ENABLE 0x00FFFFFFU /**< 1111111111111 */ +#define SMBUS_INTR_RAW_ALL_DISABLE 0x00000000U /**< 0000000000000 */ + +#define SMBUS_INTR_EN_ALL_ENABLE 0x00FFFFFFU /**< 1111111111111 */ +#define SMBUS_INTR_EN_ALL_DISABLE 0x00000000U /**< 0000000000000 */ + +#define SMBUS_ONCE_TRANS_MAX_NUM 0x400 + +#define XMBUS_OWN_ADDRESS_MASK 0x3FF +/** + * @defgroup SMBUS_Param_Def SMBUS Parameters Definition. + * @brief Definition of SMBUS configuration parameters. + * @{ + */ +/* Typedef definitions -------------------------------------------------------*/ +/** + * @brief Address Mode Selection Enumeration Definition + */ +typedef enum { + SMBUS_7_BITS = 0x00000000U, + SMBUS_10_BITS = 0x00000001U, +} SMBUS_AddressMode; + +/** + * @brief SMBUS mode selection enumeration definition + */ +typedef enum { + SMBUS_MODE_SELECT_NONE = 0x00000000U, + SMBUS_MODE_SELECT_MASTER_ONLY = 0x00000001U, + SMBUS_MODE_SELECT_SLAVE_ONLY = 0x00000002U, + SMBUS_MODE_SELECT_MASTER_SLAVE = 0x00000003U, +} SMBUS_ModeSelectType; + +/** + * @brief Callback Function ID Enumeration Definition + */ +typedef enum { + SMBUS_MASTER_TX_COMPLETE_CB_ID = 0x00000000U, + SMBUS_MASTER_RX_COMPLETE_CB_ID = 0x00000001U, + SMBUS_SLAVE_TX_COMPLETE_CB_ID = 0x00000002U, + SMBUS_SLAVE_RX_COMPLETE_CB_ID = 0x00000003U, + SMBUS_SLAVE_WAKEUP_COMPLETE_CB_ID = 0x00000004U, + SMBUS_ERROR_CB_ID = 0x00000005U, + SMBUS_ADDR_MATCH_COMPLETE_CB_ID = 0x00000006U, + SMBUS_MSTAER_SEND_STOP_COMPLETE_CB_ID = 0x00000007U, + SMBUS_SLAVE_DETECTED_STOP_COMPLETE_CB_ID = 0x00000008U, + SMBUS_ALERT_COMPLETE_CB_ID = 0x00000009U, +} SMBUS_CallbackId; + +/** + * @brief SMBUS data transfer sequence enumeration definition. + */ +typedef enum { + SMBUS_MOST_BIT_FIRST = 0x00000000U, + SMBUS_LEAST_BIT_FIRST = 0x00000001U, +} SMBUS_DataTransferSequenceType; + +/** + * @brief SMBUS clock stretching enumeration definition. + */ +typedef enum { + SMBUS_CLOCK_STRETCH_ENABLE = 0x00000000U, + SMBUS_CLOCK_STRETCH_DISABLE = 0x00000001U, +} SMBUS_ClockStretchType; + +/** + * @brief SMBUS transmission frame format enumeration definition. + */ +typedef enum { + SMBUS_FRAME_NONE = 0x00000000U, + SMBUS_FRAME_FIRST = 0x00000001U, + SMBUS_FRAME_START = 0x00000002U, + SMBUS_FRAME_MIDDLE = 0x00000004U, + SMBUS_FRAME_PEC = 0x00000008U, + SMBUS_FRAME_STOP = 0x00000010U, + SMBUS_FRAME_FULL = 0x00000020U, + SMBUS_FRAME_BLOCK_PROCESSING = 0x00000040U, + SMBUS_FRAME_ADDR_MATCH = 0x00000080U, + SMBUS_FRAME_EXCUTE_CMD_MATCH = 0x00000100U, +} SMBUS_FrameFormat; + +/** + * @brief XMBus alert type enumeration definition. + */ +typedef enum { + SMBUS_ALERT_DISABLE = 0x00000000U, + SMBUS_ALERT_ENABLE = 0x00000001U, +} SMBUS_AlertType; + +/** + * @brief SMBUS extend handle, configuring some special parameters. + */ +typedef struct { + unsigned char *data; + unsigned int dataSize; +} SMBUS_DataBuffer; + +/** + * @brief SMBUS extend handle, configuring some special parameters. + */ +typedef struct { + unsigned int spikeFilterTime; /**< The SDA and SCL Glitch Filtering Configuration. */ + unsigned int sdaDelayTime; /**< The SDA delay sampling configuration. */ + unsigned int slaveOwnXmbAddressEnable; /**< Enable the I2C second own address function. */ + unsigned int slaveOwnXmbAddress; /**< The second own address as slave. */ +} SMBUS_ExtendHandle; + +/** + * @brief User-defined callback function. + */ +typedef struct { + void (*MasterTxCplCallback)(void* handle); /**< Master Sending completion callback function. */ + void (*MasterRxCplCallback)(void* handle); /**< Slave Receive completion callback function. */ + void (*SlaveTxCplCallback)(void* handle); /**< Master Sending completion callback function. */ + void (*SlaveRxCplCallback)(void* handle); /**< Slave Receive completion callback function. */ + void (*ErrorCallback)(void* handle); /**< Error callback function. */ + void (*SlaveWakeupCallback)(void* handle); /**< Slave Wakeup Callback Function. */ + void (*ExecuteCmdCallback)(void *handle); /**< Callback function for executing smbus commands. */ + void (*AddrMatchCplCallback)(void *handle); /**< Address matching callback function. */ + void (*MasterSendStopCplCallback)(void *handle); /**< The master has sent a stop message callback function. */ + void (*SlaveDetectedStopCplCallback)(void *handle); /**< The slave has received a stop message callback function. */ + void (*AlertCallback)(void *handle); /**< The alert callback function. */ + void (*SclLowTimeoutCallback)(void *handle); /**< The scl low timeout callback function. */ +} SMBUS_UserCallBack; + +/** + * @} + */ + +/* Parameter check definition-------------------------------------------*/ +/** + * @brief Check SMBUS function mode selection. + * @param functionMode SMBUS function mode type. + * @retval true + * @retval false + */ +static inline bool IsSmbusFunctionMode(SMBUS_ModeSelectType functionMode) +{ + return (functionMode == SMBUS_MODE_SELECT_NONE || + functionMode == SMBUS_MODE_SELECT_MASTER_ONLY || + functionMode == SMBUS_MODE_SELECT_SLAVE_ONLY || + functionMode == SMBUS_MODE_SELECT_MASTER_SLAVE); +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* #ifndef McuMagicTag_SMBUS_IP_H */ \ No newline at end of file diff --git a/src/drivers/smbus/smbus_v0/src/smbus.c b/src/drivers/smbus/smbus_v0/src/smbus.c new file mode 100644 index 0000000000000000000000000000000000000000..b5a1b70f408439dddba99c9326e8826a11aac46c --- /dev/null +++ b/src/drivers/smbus/smbus_v0/src/smbus.c @@ -0,0 +1,2562 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file smbus.c + * @author MCU Driver Team + * @brief SMBUS module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the SMBUS. + * + Initialization and de-initialization functions + * + Peripheral Control functions + */ + +/* Includes ------------------------------------------------------------------*/ +#include "interrupt.h" +#include "smbus.h" + +/* Macro definitions ---------------------------------------------------------*/ +#define SMBUS_INTERFACE_INDEX_0 0 +#define SMBUS_INTERFACE_INDEX_1 1 +#define SMBUS_MAX_INDEX_NUM 2 + +#define SMBUS_MASTER_STATUS 0x00 +#define SMBUS_SLAVE_STATUS 0x01 + +#define SMBUS_MAX_FIFO_SIZE 15 +#define SMBUS_MAX_DEV_ADDR 0x3FF + +#define SMBUS_OPERATION_WRITE 0 +#define SMBUS_OPERATION_READ 1 + +#define SMBUS_SEND_ADDR_STATUS_NONE 0 +#define SMBUS_SEND_ADDR_STATUS_WRITE 1 +#define SMBUS_SEND_ADDR_STATUS_READ 2 + +/* Enable scl_low_timeout\mst_cmd_done\arb_lost\tx_fifo_not_full\rx_fifo_not_empty\mst_rx_ack_unmatch */ +#define SMBUS_CFG_INTERRUPT_MASTER_RX 0x3843 +/* Enable scl_low_timeout\mst_cmd_done\arb_lost\tx_fifo_not_full\mst_rx_ack_unmatch */ +#define SMBUS_CFG_INTERRUPT_MASTER_TX 0x3841 +/* Enable slv_addr_match_int\slv_rx_ack_unmatch_int\stop_det_int */ +#define SMBUS_CFG_INTERRUPT_SLAVE 0x302200 +#define SMBUS_TICK_MS_DIV 1000 + +#define SMBUS_INTR_RAW_SLAVE_ADDR_MATCH_MASK (0x1 << 21) +#define SMBUS_INTR_RAW_SLAVE_ACK_UNMATCH_MASK (0x1 << 20) +#define SMBUS_INTR_RAW_SLAVE_PEC_CHECK_FAIL_MASK (0x1 << 19) +#define SMBUS_INTR_RAW_MASTER_PEC_CHECK_FAIL_MASK (0x1 << 18) +#define SMBUS_INTR_RAW_SLAVE_CMD_INT1_MASK (0x1 << 17) +#define SMBUS_INTR_RAW_MASTER_CMD_INT1_MASK (0x1 << 16) +#define SMBUS_INTR_RAW_SMB_SUSPEND_MASK (0x1 << 15) +#define SMBUS_INTR_RAW_SMB_ALERT_MASK (0x1 << 14) +#define SMBUS_INTR_RAW_SCL_LOW_TIMEOUT_MASK (0x1 << 13) +#define SMBUS_INTR_RAW_ALL_CMD_DONE_MASK (0x1 << 12) +#define SMBUS_INTR_RAW_ARB_LOST_MASK (0x1 << 11) +#define SMBUS_INTR_RAW_START_DET_MASK (0x1 << 10) +#define SMBUS_INTR_RAW_STOP_DET_MASK (0x1 << 9) +#define SMBUS_INTR_RAW_TX_DATA_REQUEST_MASK (0x1 << 8) +#define SMBUS_INTR_RAW_RX_DATA_READY_MASK (0x1 << 7) +#define SMBUS_INTR_RAW_TX_FIFO_NOT_FULL_MASK (0x1 << 6) +#define SMBUS_INTR_RAW_TX_FIFO_EMPTY_MASK (0x1 << 5) +#define SMBUS_INTR_RAW_TX_LE_WATERMARK_MASK (0x1 << 4) +#define SMBUS_INTR_RAW_RX_FIFO_FULL_MASK (0x1 << 3) +#define SMBUS_INTR_RAW_RX_GE_WATERMARK_MASK (0x1 << 2) +#define SMBUS_INTR_RAW_RX_FIFO_NOT_EMPTY_MASK (0x1 << 1) +#define SMBUS_INTR_RAW_ACK_BIT_UNMATCH_MASK (0x1 << 0) + +#define SMBUS_10BIT_SLAVE_READ_ADDR_MASK (0xFEFF0000) +#define SMBUS_10BIT_SLAVE_WRITE_ADDR_MASK (0x0000FEFF) +#define SMBUS_10BIT_SLAVE_READ_OPT_MASK (0x01000000) + +#define SMBUS_7BIT_SLAVE_READ_ADDR_MASK (0x00FE0000) +#define SMBUS_7BIT_SLAVE_WRITE_ADDR_MASK (0x000000FE) +#define SMBUS_7BIT_SLAVE_READ_OPT_MASK (0x00010000) + +#define SMBUS_SLAVE_WRITE_ADDR_POS 8 +#define SMBUS_SLAVE_READ_FIX_ADDR_POS 24 +#define SMBUS_SLAVE_READ_DEV_ADDR_POS 16 +#define SMBUS_SLAVE_ADDR_MASK 0xFF +#define SMBUS_10BIT_SLAVE_ADDR_POS 16 + +#define HIGH_HOLD_TIME_POS 16 +#define HIGH_HOLD_TIME_MASK 0xFFFF0000 +#define LOW_HOLD_TIME_MASK 0x0000FFFF + +#define DMA_RX_CHANNEL_POS 8 +#define DMA_CHANNEL_MASK 0x00FF + +#define COMMAND_ALL_DONE 0 +#define BUS_IS_FREE 1 +#define SLAVE_ADDRESS_MATCH 2 +#define TX_FIFO_NOT_FULL 3 +#define RX_FIFO_NOT_EMPTY 4 +#define TX_FIFO_EMPTY 5 + +#define SMBUS_FREQ_HIGH_PARAMTER 8 +#define SMBUS_FREQ_LOW_PARAMTER 9 +#define SMBUS_ERROR_BIT_MASK 0x5C2801 /* slv_rx_ack_unmatch\arb_lost\mst_rx_ack_unmatch */ +#define SMBUS_SCL_LOW_TIMEOUT_MASK 0x2000 +#define SMBUS_SLAVE_WAKEUP_RAW_MASK 0x800000 +#define SMBUS_SLAVE_WAKEUP_RAW_POS 23 +#define SMBUS_ALERT_RAW_MASK 0x4000 +#define SMBUS_ALERT_RAW_POS 14 + +static BASE_StatusType SMBusDmaMasterReadData(SMBUS_Handle *handle, unsigned int size); +static BASE_StatusType SMBusDmaMasterWriteData(SMBUS_Handle *handle, unsigned int size); +static BASE_StatusType SMBusDmaSlaveReadData(SMBUS_Handle *handle, unsigned int size); +static BASE_StatusType SMBusDmaSlaveWriteData(SMBUS_Handle *handle, unsigned int size); + +/* Some global parameters used for module internal operations */ +static volatile unsigned int g_smbusInternalTxBuffDMA[I2C_ONCE_TRANS_MAX_NUM] = {0}; +/** + * @brief Check all initial configuration parameters. + * @param handle SMBUS handle. + * @param clockFreq SMBUS work clock freq; + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusCheckAllInitParameters(SMBUS_Handle *handle, unsigned int clockFreq) +{ + /* Check the configuration of basic function parameters. */ + SMBUS_PARAM_CHECK_WITH_RET(IsI2cFunctionMode(handle->functionMode), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cAddressMode(handle->addrMode), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cSdaHoldTime(handle->sdaHoldTime), BASE_STATUS_ERROR); + /* Check whether the I2C freq is valid. */ + SMBUS_PARAM_CHECK_WITH_RET(IsI2cFreq(handle->freq), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET((clockFreq > 0), BASE_STATUS_ERROR); + + if (handle->freq > clockFreq) { + return BASE_STATUS_ERROR; + } + /* Check the configuration of basic function parameters. */ + SMBUS_PARAM_CHECK_WITH_RET(IsI2cIgnoreAckFlag(handle->ignoreAckFlag), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cTxWaterMark(handle->txWaterMark), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cRxWaterMark(handle->rxWaterMark), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cSpikeFilterTime(handle->handleEx.spikeFilterTime), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cSdaDelayTime(handle->handleEx.sdaDelayTime), BASE_STATUS_ERROR); + + /* Checking the own address and generalCall parameter enable when is used as slave. */ + if (handle->functionMode == SMBUS_MODE_SELECT_SLAVE_ONLY || + handle->functionMode == SMBUS_MODE_SELECT_MASTER_SLAVE) { + SMBUS_PARAM_CHECK_WITH_RET(IsI2cOwnAddressOrMask(handle->slaveOwnAddress), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cGeneralCallMode(handle->generalCallMode), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(IsXMBusAddressEnable(handle->handleEx.slaveOwnXmbAddressEnable), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(IsXMBusAddressOrMask(handle->handleEx.slaveOwnXmbAddress), BASE_STATUS_ERROR); + } + return BASE_STATUS_OK; +} + +/** + * @brief Configuring the SMBUS Slave Device Address. + * @param handle SMBUS handle. + * @param devAddr Slave device address + * @retval None. + */ +static void SMBusSetSlaveDevAddr(SMBUS_Handle *handle, const unsigned int devAddr) +{ + unsigned int addr; + + if (handle->addrMode == SMBUS_10_BITS) { + /* The upper 16 bits are the read operation address, and the lower 16 bits are the write operation address. */ + addr = (((devAddr << 16) & SMBUS_10BIT_SLAVE_READ_ADDR_MASK) | SMBUS_10BIT_SLAVE_READ_OPT_MASK) | + (devAddr & SMBUS_10BIT_SLAVE_WRITE_ADDR_MASK); + } else { + /* The upper 16 bits are the read operation address, and the lower 16 bits are the write operation address. */ + addr = (((devAddr << 16) & SMBUS_7BIT_SLAVE_READ_ADDR_MASK) | SMBUS_7BIT_SLAVE_READ_OPT_MASK) | + (devAddr & SMBUS_7BIT_SLAVE_WRITE_ADDR_MASK); + } + + handle->deviceAddress = addr; +} + +/** + * @brief SMBUS Bus clear. + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusBusClear(SMBUS_Handle *handle) +{ + handle->state = SMBUS_STATE_READY; + handle->baseAddress->I2C_MODE.BIT.mst_slv_function = SMBUS_STATE_RESET; + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + + /* Set the SCL and SDA pins of the SMBUS to GPIO mode. */ + handle->baseAddress->I2C_CTRL2.BIT.gpio_mode = BASE_CFG_ENABLE; + handle->baseAddress->I2C_CTRL2.BIT.force_scl = BASE_CFG_ENABLE; + handle->baseAddress->I2C_CTRL2.BIT.force_sda = BASE_CFG_ENABLE; + /* The device that controls the bus to be pulled down needs to release the bus within the 9 clocks. */ + for (unsigned int index = 0; index < 9; index++) { + handle->baseAddress->I2C_CTRL2.BIT.force_scl = BASE_CFG_UNSET; + BASE_FUNC_DELAY_US(5); /* The I2C timing is required. The delay is about 5 μs. */ + handle->baseAddress->I2C_CTRL2.BIT.force_scl = BASE_CFG_SET; + BASE_FUNC_DELAY_US(5); /* The I2C timing is required. The delay is about 5 μs. */ + } + handle->baseAddress->I2C_CTRL2.BIT.force_scl = BASE_CFG_ENABLE; + handle->baseAddress->I2C_CTRL2.BIT.force_sda = BASE_CFG_ENABLE; + /* I2C start */ + handle->baseAddress->I2C_CTRL2.BIT.force_sda = BASE_CFG_UNSET; + BASE_FUNC_DELAY_US(10); /* The I2C timing is required. The delay is about 10 μs. */ + /* I2C stop */ + handle->baseAddress->I2C_CTRL2.BIT.force_sda = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL2.BIT.gpio_mode = BASE_CFG_DISABLE; /* Exit the I2C GPIO mode. */ +} + +/** + * @brief Setting Error Handling. + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusSetErrorHandling(SMBUS_Handle *handle) +{ + handle->state = SMBUS_STATE_READY; + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + + /* If the low level times out, the SMBUS bus is cleared and the bus is expected to be released. */ + if (handle->baseAddress->I2C_INTR_RAW.BIT.scl_low_timeout_raw == BASE_CFG_ENABLE) { + SMBusBusClear(handle); + handle->baseAddress->I2C_INTR_RAW.BIT.scl_low_timeout_raw = BASE_CFG_ENABLE; + } + + if (handle->errorCode != BASE_STATUS_OK && handle->userCallBack.ErrorCallback != NULL) { + handle->userCallBack.ErrorCallback(handle); + } +} + +/** + * @brief Item is checked for readiness. + * @param handle SMBUS handle. + * @param checkItem The item to be checked. + * @param opt Read or write flag. + * @retval false, item is not ready. true, item is ready. + */ +static unsigned int SMBusCheckItemStatus(SMBUS_Handle *handle, unsigned int checkItem, unsigned int opt) +{ + unsigned int ret = 0; + unsigned int tempStatusValue = 0; + switch (checkItem) { + case COMMAND_ALL_DONE: + /* The 0x1200 is the bit of mst_cmd_done_raw and stop_det_raw. */ + tempStatusValue = (handle->baseAddress->I2C_INTR_RAW.reg & 0x1200); /* Check the I2C is all command done. */ + ret = tempStatusValue; + break; + case BUS_IS_FREE: + /* The SMBUS bus is free. */ + ret = handle->baseAddress->I2C_FSM_STAT.BIT.i2c_bus_free; + break; + case SLAVE_ADDRESS_MATCH: + /* Slave servers are matched */ + tempStatusValue = (handle->baseAddress->I2C_RX_ADDR.BIT.rx_rw == opt); + tempStatusValue |= handle->baseAddress->I2C_INTR_RAW.BIT.slv_addr_match_raw; + ret = tempStatusValue; + break; + case TX_FIFO_NOT_FULL: + /* Tx fifo is not full. */ + ret = (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < SMBUS_MAX_FIFO_SIZE); + break; + case RX_FIFO_NOT_EMPTY: + /* Rx fifo is not empty. */ + ret = handle->baseAddress->I2C_FIFO_STAT.BIT.rx_fifo_vld_num; + break; + case TX_FIFO_EMPTY: + /* Tx fifo is not full. */ + ret = (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num == 0); + break; + default: + break; + } + return ret; +} + +/** + * @brief Wait for the item status to be ready. + * @param handle SMBUS handle. + * @param checkItem The item to be checked. + * @param opt Read or write flag. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusWaitStatusReady(SMBUS_Handle *handle, unsigned int checkItem, unsigned int opt) +{ + unsigned int preTick = DCL_SYSTICK_GetTick(); + unsigned int curTick; + unsigned long long delta = 0; + unsigned long long targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SMBUS_TICK_MS_DIV * handle->timeout; + + while (true) { + if (handle->baseAddress->I2C_INTR_RAW.reg & SMBUS_ERROR_BIT_MASK) { + SMBusSetErrorHandling(handle); + return BASE_STATUS_ERROR; + } + + /* Check the status of the item is ready. */ + if (SMBusCheckItemStatus(handle, checkItem, opt)) { + if (checkItem == SLAVE_ADDRESS_MATCH) { + /* Clear slave address match raw interrupt */ + handle->baseAddress->I2C_INTR_RAW.BIT.slv_addr_match_raw = BASE_CFG_SET; + } + return BASE_STATUS_OK; + } + + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* Check timeout. */ + break; + } + preTick = curTick; + } + return BASE_STATUS_TIMEOUT; +} + +/** + * @brief Set the sending data and operation commands. + * @param handle SMBUS handle. + * @param cmd Operation commands. + * @param data Sending data. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusSetTxFIFODataAndCmd(SMBUS_Handle *handle, I2C_CmdType cmd, unsigned char data) +{ + BASE_StatusType ret; + unsigned int temp; + + ret = SMBusWaitStatusReady(handle, TX_FIFO_NOT_FULL, SMBUS_OPERATION_WRITE); + if (ret != BASE_STATUS_OK) { + return ret; + } + /* The 8 to 11 bits are the Timing Commands, and the 0 to 7 bits are the write data. */ + temp = (((unsigned int)cmd << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + temp |= (((unsigned int)data << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + handle->baseAddress->I2C_TX_FIFO.reg = temp; /* Sets the data and commands to be sent. */ + return BASE_STATUS_OK; +} + +/** + * @brief Send a write command to the slave device. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusSendSlaveAddressWriteCmd(SMBUS_Handle *handle) +{ + BASE_StatusType ret; + unsigned char addr; + /* Write slave address */ + if (handle->addrMode == SMBUS_10_BITS) { /* 10bit address Configuration */ + if (handle->transferCount == 0) { + /* The first address of a 10-bit address configuration */ + addr = (unsigned char)((handle->deviceAddress >> SMBUS_SLAVE_WRITE_ADDR_POS) & + SMBUS_SLAVE_ADDR_MASK); + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + /* The second address of the 10-bit address configuration */ + addr = (unsigned char)(handle->deviceAddress & SMBUS_SLAVE_ADDR_MASK); + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } else { + addr = (unsigned char)((handle->deviceAddress >> SMBUS_SLAVE_WRITE_ADDR_POS) & + SMBUS_SLAVE_ADDR_MASK); + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } + } else { /* 7bit address Configuration */ + addr = (unsigned char)(handle->deviceAddress & SMBUS_SLAVE_ADDR_MASK); + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } + return BASE_STATUS_OK; +} + +/** + * @brief Send a read command to the slave device. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusSendSlaveAddressReadCmd(SMBUS_Handle *handle) +{ + BASE_StatusType ret; + unsigned char addr; + /* Write slave address */ + if (handle->addrMode == SMBUS_10_BITS) { /* 10bit address Configuration */ + if (handle->transferCount == 0) { + /* The first address of a 10-bit address configuration */ + addr = (unsigned char)((handle->deviceAddress >> SMBUS_SLAVE_READ_FIX_ADDR_POS) & + SMBUS_SLAVE_ADDR_MASK); + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + /* The second address of the 10-bit address configuration */ + addr = (unsigned char)((handle->deviceAddress >> SMBUS_SLAVE_READ_DEV_ADDR_POS) & + SMBUS_SLAVE_ADDR_MASK); + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } else { + addr = (unsigned char)((handle->deviceAddress >> SMBUS_SLAVE_READ_FIX_ADDR_POS) & + SMBUS_SLAVE_ADDR_MASK); + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } + } else { /* 7bit address Configuration */ + addr = (unsigned char)((handle->deviceAddress >> SMBUS_SLAVE_READ_DEV_ADDR_POS) & + SMBUS_SLAVE_ADDR_MASK); + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, addr); + if (ret != BASE_STATUS_OK) { + return ret; + } + } + return BASE_STATUS_OK; +} + +/** + * @brief Master send stop command in blocking. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusBlockingSendStopCommand(SMBUS_Handle *handle) +{ + BASE_StatusType ret; + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_P, 0); + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + /* Wait until all commands are executed. */ + ret = SMBusWaitStatusReady(handle, COMMAND_ALL_DONE, SMBUS_OPERATION_WRITE); + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_UNSET; + handle->baseAddress->I2C_INTR_EN.reg = I2C_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = I2C_INTR_RAW_ALL_ENABLE; + handle->state = SMBUS_STATE_READY; + return ret; +} + +/** + * @brief The step of receive normal data in blocking as master. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusBlockingMasterRxLastData(SMBUS_Handle *handle) +{ + BASE_StatusType ret; + /* Reads the last frame of data without ack. */ + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + /* Reads the last frame of data without ack. */ + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_RPEC_TNACK_S_TPEC_RNACK, 0); + } else { + if ((handle->frameOpt & SMBUS_FRAME_BLOCK_PROCESSING) == SMBUS_FRAME_BLOCK_PROCESSING) { + /* Reads the last frame of data with ack. */ + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_RD_TACK_S_TD_RACK, 0); + } else { + /* Reads the last frame of data without ack. */ + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_RD_TNACK_S_TD_RNACK, 0); + } + } + return ret; +} + +/** + * @brief The step of receive normal data in blocking as master. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusBlockingMasterRxDataOptStepNormal(SMBUS_Handle *handle) +{ + BASE_StatusType ret; + if (handle->transferBuff == NULL || handle->transferSize == 0) { + return BASE_STATUS_OK; + } + + while (handle->transferCount < handle->transferSize) { + if (handle->transferCount == handle->transferSize - 1) { + /* Reads the last frame of data. */ + ret = SMBusBlockingMasterRxLastData(handle); + } else { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_RD_TACK_S_TD_RACK, 0); + } + if (ret != BASE_STATUS_OK) { + return ret; + } + /* Wait the RX FIFO is not empty. */ + ret = SMBusWaitStatusReady(handle, RX_FIFO_NOT_EMPTY, SMBUS_OPERATION_READ); + if (ret != BASE_STATUS_OK) { + return ret; + } + /* Obtains the data received from the RX FIFO. */ + *handle->transferBuff = handle->baseAddress->I2C_RX_FIFO.BIT.rx_fifo_rdata; + handle->transferBuff++; + handle->transferCount++; + } + return ret; +} + +/** + * @brief The step of transmit normal data in blocking as master. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusBlockingMasterTxDataOptStepNormal(SMBUS_Handle *handle) +{ + BASE_StatusType ret; + /* In this case, the quick cmd or other input parameters are incorrect. */ + if (handle->transferBuff == NULL || handle->transferSize == 0) { + return BASE_STATUS_OK; + } + + /* Sets data to be sent cyclically. */ + while (handle->transferCount < handle->transferSize) { + if ((handle->transferCount == handle->transferSize - 1) && + (handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_TPEC_RACK_S_RPEC_TACK, 0); + } else { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, *handle->transferBuff); + } + if (ret != BASE_STATUS_OK) { + return ret; + } + handle->transferBuff++; + handle->transferCount++; + } + return BASE_STATUS_OK; +} + +/** + * @brief The step of receive normal data in blocking as slave. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusBlockingSlaveRxDataOptStepNormal(SMBUS_Handle *handle) +{ + if (handle->transferBuff == NULL || handle->transferSize == 0) { + return BASE_STATUS_OK; + } + + while (handle->transferCount < handle->transferSize) { + /* Sets the data to be received. */ + if (SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_TD_RACK_S_RD_TACK, 0) != BASE_STATUS_OK) { + return BASE_STATUS_TIMEOUT; + } + if (SMBusWaitStatusReady(handle, RX_FIFO_NOT_EMPTY, SMBUS_OPERATION_READ) != BASE_STATUS_OK) { + return BASE_STATUS_TIMEOUT; + } + /* Obtains the data received in the RX FIFO. */ + *handle->transferBuff = handle->baseAddress->I2C_RX_FIFO.BIT.rx_fifo_rdata; + handle->transferBuff++; + handle->transferCount++; + } + return BASE_STATUS_OK; +} + +/** + * @brief Checking Interrupts Caused by SMBUS Timing Errors. + * @param handle SMBUS handle. + * @param status Status of the SMBUS. + * @retval true or false + */ +static void SMBusIsInterruptErrorStatus(SMBUS_Handle *handle, unsigned int status) +{ + /* If the low level timesout, the SMBUS bus is cleared and the bus is expected to be released. */ + if (status & SMBUS_SCL_LOW_TIMEOUT_MASK) { + SMBusBusClear(handle); + } + /* Disable */ + handle->errorCode = BASE_STATUS_ERROR; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_DISABLE; + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + handle->state = SMBUS_STATE_READY; + if (handle->userCallBack.ErrorCallback != NULL) { + handle->userCallBack.ErrorCallback(handle); + } +} + +/** + * @brief Interrupt handle send start command. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusInterruptSendStart(SMBUS_Handle *handle) +{ + unsigned int temp; + if (((handle->frameOpt & SMBUS_FRAME_START) == 0) || + (handle->sendAddrStatus <= SMBUS_SEND_ADDR_STATUS_NONE)) { + return BASE_STATUS_OK; + } + + if (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < SMBUS_MAX_FIFO_SIZE) { + /* The 8 to 11 bits are the Timing Commands, and the 0 to 7 bits are the write data. */ + temp = (((unsigned int)I2C_CMD_S << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + handle->baseAddress->I2C_TX_FIFO.reg = temp; /* Sets the data and commands to be sent. */ + } else { + return BASE_STATUS_ERROR; + } + switch (handle->sendAddrStatus) { + case SMBUS_SEND_ADDR_STATUS_WRITE: + /* Send a write command to the slave. */ + if (SMBusSendSlaveAddressWriteCmd(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + break; + case SMBUS_SEND_ADDR_STATUS_READ: + /* Send a read command to the slave. */ + if (SMBusSendSlaveAddressReadCmd(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + break; + default: + break; + } + handle->sendAddrStatus = SMBUS_SEND_ADDR_STATUS_NONE; + return BASE_STATUS_OK; +} + +/** + * @brief SMBUS Interrupt done Handling without stop. + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusInterruptAllDoneHandleWithoutStop(SMBUS_Handle *handle) +{ + switch (handle->state) { + case SMBUS_STATE_BUSY_MASTER_TX: /* SMBus is at master tx state. */ + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_UNSET; + handle->state = SMBUS_STATE_READY; + if (handle->userCallBack.MasterTxCplCallback != NULL) { + handle->userCallBack.MasterTxCplCallback(handle); /* Invoke the TX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_MASTER_RX: /* SMBus is at master rx state. */ + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_UNSET; + handle->state = SMBUS_STATE_READY; + if (handle->userCallBack.MasterRxCplCallback != NULL) { + handle->userCallBack.MasterRxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_SLAVE_TX: /* SMBus is at slave tx state. */ + handle->state = SMBUS_STATE_READY; + handle->baseAddress->I2C_INTR_EN.BIT.tx_fifo_not_full_en = BASE_CFG_SET; + handle->baseAddress->I2C_INTR_EN.BIT.rx_fifo_not_empty_en = BASE_CFG_SET; + handle->baseAddress->I2C_INTR_RAW.reg = + (SMBUS_INTR_RAW_TX_FIFO_NOT_FULL_MASK | SMBUS_INTR_RAW_RX_FIFO_FULL_MASK); + if (handle->userCallBack.SlaveTxCplCallback != NULL) { + handle->userCallBack.SlaveTxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_SLAVE_RX: /* SMBus is at slave rx state. */ + handle->state = SMBUS_STATE_READY; + handle->baseAddress->I2C_INTR_EN.BIT.tx_fifo_not_full_en = BASE_CFG_SET; + handle->baseAddress->I2C_INTR_EN.BIT.rx_fifo_not_empty_en = BASE_CFG_SET; + handle->baseAddress->I2C_INTR_RAW.reg = + (SMBUS_INTR_RAW_TX_FIFO_NOT_FULL_MASK | SMBUS_INTR_RAW_RX_FIFO_FULL_MASK); + if (handle->userCallBack.SlaveRxCplCallback != NULL) { + handle->userCallBack.SlaveRxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + default: + break; + } +} + +/** + * @brief SMBUS Interrupt done Handling with stop callback. + * @param handle SMBUS handle. + * @param status SMBUS interrupt raw status. + * @retval None. + */ +static void SMBusInterruptStopCallBack(SMBUS_Handle *handle, unsigned int status) +{ + if (status & SMBUS_INTR_RAW_ALL_CMD_DONE_MASK) { + /* Invoke the RX callback processing function. */ + if (handle->userCallBack.MasterSendStopCplCallback != NULL) { + handle->userCallBack.MasterSendStopCplCallback(handle); + } + } else if (status & SMBUS_INTR_RAW_STOP_DET_MASK) { + /* Invoke the RX callback processing function. */ + if (handle->userCallBack.SlaveDetectedStopCplCallback != NULL) { + handle->userCallBack.SlaveDetectedStopCplCallback(handle); + } + } +} + +/** + * @brief SMBUS Interrupt done Handling with stop. + * @param handle SMBUS handle. + * @param status SMBUS interrupt raw status. + * @retval None. + */ +static void SMBusInterruptAllDoneHandleWithStop(SMBUS_Handle *handle, unsigned int status) +{ + switch (handle->state) { + case SMBUS_STATE_BUSY_MASTER_TX: + handle->state = SMBUS_STATE_READY; + if (handle->userCallBack.MasterTxCplCallback != NULL) { + handle->userCallBack.MasterTxCplCallback(handle); /* Invoke the TX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_MASTER_RX: + handle->state = SMBUS_STATE_READY; + if (handle->userCallBack.MasterRxCplCallback != NULL) { + handle->userCallBack.MasterRxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_SLAVE_TX: + handle->state = SMBUS_STATE_READY; + if (handle->userCallBack.SlaveTxCplCallback != NULL) { + handle->userCallBack.SlaveTxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_SLAVE_RX: + handle->state = SMBUS_STATE_READY; + if (handle->userCallBack.SlaveRxCplCallback != NULL) { + handle->userCallBack.SlaveRxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + default: + break; + } + SMBusInterruptStopCallBack(handle, status); /* SMBUS Interrupt done Handling with stop callback. */ +} + +/** + * @brief SMBUS Interrupt done Handling + * @param handle SMBUS handle. + * @param status SMBUS interrupt raw status. + * @retval None. + */ +static void SMBusInterruptAllDoneHandle(SMBUS_Handle *handle, unsigned int status) +{ + /* After all data transmission is complete, call the user's callback function. */ + unsigned int masterAllDone = status & SMBUS_INTR_RAW_ALL_CMD_DONE_MASK; + unsigned int slaveReceiveStop = status & SMBUS_INTR_RAW_STOP_DET_MASK; + unsigned int allDoneItFlag = (masterAllDone || slaveReceiveStop); + + if (handle->transferCount >= handle->transferSize && + ((handle->frameOpt & SMBUS_FRAME_STOP) != SMBUS_FRAME_STOP) && + (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num == 0)) { + /* SMBUS Interrupt done Handling without stop. */ + SMBusInterruptAllDoneHandleWithoutStop(handle); + return; + } + + if (handle->transferCount >= handle->transferSize && + ((handle->frameOpt & SMBUS_FRAME_STOP) && allDoneItFlag)) { + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_DISABLE; + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_UNSET; + /* SMBUS Interrupt done Handling with stop. */ + SMBusInterruptAllDoneHandleWithStop(handle, status); + handle->frameOpt = SMBUS_FRAME_NONE; + handle->state = SMBUS_STATE_READY; + } +} + +/** + * @brief SMBUS interrupt TX handling + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusInterruptMasterTxHandle(SMBUS_Handle *handle) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_ASSERT_PARAM(handle->transferBuff != NULL); + unsigned int temp; + /* Send a start command to the slave. */ + if (SMBusInterruptSendStart(handle) != BASE_STATUS_OK) { + return; + } + + while (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < SMBUS_MAX_FIFO_SIZE && + handle->transferCount < handle->transferSize) { + if ((handle->transferCount == handle->transferSize - 1) && + (handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + /* Sets the data to be sent. */ + temp = (((unsigned int)I2C_CMD_M_TPEC_RACK_S_RPEC_TACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } else { + /* Sets the data to be sent. */ + temp = (((unsigned int)I2C_CMD_M_TD_RACK_S_RD_TACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + temp |= ((unsigned int)(*handle->transferBuff) & I2C_TXFIFO_WDATA_MASK); + } + handle->baseAddress->I2C_TX_FIFO.reg = temp; /* Sets the data and commands to be sent. */ + handle->transferBuff++; + handle->transferCount++; + } +} + +/** + * @brief SMBUS Interrupt RX last data Handling + * @param handle SMBUS handle. + * @retval None. + */ +static unsigned int SMBusInterruptMasterRxLastDataHandle(SMBUS_Handle *handle) +{ + unsigned int temp; + if (handle->frameOpt & SMBUS_FRAME_PEC) { + /* Reads the last frame of data without ack. */ + temp = (((unsigned int)I2C_CMD_M_RPEC_TNACK_S_TPEC_RNACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } else { + if (handle->frameOpt & SMBUS_FRAME_BLOCK_PROCESSING) { + /* Reads the last frame of data without ack. */ + temp = (((unsigned int)I2C_CMD_M_RD_TACK_S_TD_RACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } else { + /* Reads the last frame of data without ack. */ + temp = (((unsigned int)I2C_CMD_M_RD_TNACK_S_TD_RNACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } + } + return temp; +} + +/** + * @brief SMBUS Interrupt RX Handling + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusInterruptMasterRxHandle(SMBUS_Handle *handle) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_ASSERT_PARAM(handle->transferBuff != NULL); + unsigned int temp; + + /* Send a start command to the slave. */ + if (SMBusInterruptSendStart(handle) != BASE_STATUS_OK) { + return; + } + + /* The SMBUS controller fills in the receive command and starts to receive data. */ + while (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < SMBUS_MAX_FIFO_SIZE && + handle->txReadCmdCount < handle->transferSize) { + if (handle->txReadCmdCount == handle->transferSize - 1) { + /* SMBUS Interrupt RX last data Handling. */ + temp = SMBusInterruptMasterRxLastDataHandle(handle); + } else { /* Normal data transmission. */ + temp = (((unsigned int)I2C_CMD_M_RD_TACK_S_TD_RACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } + handle->baseAddress->I2C_TX_FIFO.reg = temp; + handle->txReadCmdCount++; + } + + /* Obtains the data received in the RX FIFO. */ + while (handle->baseAddress->I2C_FIFO_STAT.BIT.rx_fifo_vld_num > 0 && + handle->transferCount < handle->transferSize) { + *handle->transferBuff++ = handle->baseAddress->I2C_RX_FIFO.BIT.rx_fifo_rdata; + handle->transferCount++; + } +} + +/** + * @brief SMBUS interrupt slave TX handling + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusInterruptSlaveTxHandle(SMBUS_Handle *handle) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_ASSERT_PARAM(handle->transferBuff != NULL); + unsigned int temp; + while (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < SMBUS_MAX_FIFO_SIZE && + handle->transferCount < handle->transferSize) { + if (handle->transferCount == (handle->transferSize - 1)) { /* no need ack. */ + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + temp = (((unsigned int)I2C_CMD_M_RPEC_TNACK_S_TPEC_RNACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } else { + temp = (((unsigned int)I2C_CMD_M_RD_TNACK_S_TD_RNACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + temp |= ((unsigned int)(*handle->transferBuff) & I2C_TXFIFO_WDATA_MASK); + } + } else { /* Normal data transmission. */ + temp = (((unsigned int)I2C_CMD_M_RD_TACK_S_TD_RACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + temp |= ((unsigned int)(*handle->transferBuff) & I2C_TXFIFO_WDATA_MASK); + } + handle->baseAddress->I2C_TX_FIFO.reg = temp; /* Sets the data and commands to be sent. */ + handle->transferBuff++; + handle->transferCount++; + } +} + +/** + * @brief SMBUS interrupt slave RX handling + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusInterruptSlaveRxHandle(SMBUS_Handle *handle) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_ASSERT_PARAM(handle->transferBuff != NULL); + unsigned int temp; + + /* Set the data receiving command. */ + while (handle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < SMBUS_MAX_FIFO_SIZE && + handle->txReadCmdCount < handle->transferSize) { + if (handle->txReadCmdCount == (handle->transferSize - 1)) { /* receive the last data. */ + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + /* Need to receive PEC. */ + temp = (((unsigned int)I2C_CMD_M_TPEC_RACK_S_RPEC_TACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } else { + /* Don't need to receive PEC. */ + temp = (((unsigned int)I2C_CMD_M_TD_RACK_S_RD_TACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } + } else { + temp = (((unsigned int)I2C_CMD_M_TD_RACK_S_RD_TACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } + handle->baseAddress->I2C_TX_FIFO.reg = temp; /* Write data to register. */ + handle->txReadCmdCount++; + } + /* Obtained data from RX FIFO. */ + while (handle->baseAddress->I2C_FIFO_STAT.BIT.rx_fifo_vld_num > 0 && + handle->transferCount < handle->transferSize) { + *handle->transferBuff = handle->baseAddress->I2C_RX_FIFO.BIT.rx_fifo_rdata; + handle->transferBuff++; + handle->transferCount++; + } +} + +/** + * @brief Addr match Callback function corresponding to the interrupt processing function. + * @param handle SMBUS handle. + * @param status Status of the SMBUS. + * @retval None. + */ +static void SMBusInterruptAddrMatchHandle(SMBUS_Handle *handle, unsigned int status) +{ + if (status & SMBUS_INTR_RAW_SLAVE_ADDR_MATCH_MASK) { + if ((handle->frameOpt & SMBUS_FRAME_EXCUTE_CMD_MATCH) && + handle->userCallBack.ExecuteCmdCallback != NULL) { + handle->userCallBack.ExecuteCmdCallback(handle); /* Callback execute cmd function. */ + } else if (handle->userCallBack.AddrMatchCplCallback != NULL) { + handle->userCallBack.AddrMatchCplCallback(handle); /* Callback address match function. */ + } + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_SLAVE_ADDR_MATCH_MASK; + } +} + +/** + * @brief ICallback function corresponding to the interrupt processing function. + * @param handle SMBUS handle. + * @param status Status of the SMBUS. + * @retval None. + */ +static void SMBusInterruptHandle(SMBUS_Handle *handle, unsigned int status) +{ + if (handle->state == SMBUS_STATE_BUSY_MASTER_TX) { + SMBusInterruptMasterTxHandle(handle); /* Transfer data as a host. */ + return; + } else if (handle->state == SMBUS_STATE_BUSY_MASTER_RX) { + SMBusInterruptMasterRxHandle(handle); /* Receive data as a host. */ + return; + } else if (handle->state == SMBUS_STATE_BUSY_SLAVE_TX) { + if (status & SMBUS_INTR_RAW_SLAVE_ADDR_MATCH_MASK) { + /* Set TX FIFO the waterline. */ + handle->baseAddress->I2C_INTR_EN.BIT.tx_fifo_not_full_en = BASE_CFG_SET; + } + if (handle->baseAddress->I2C_RX_ADDR.BIT.rx_rw == SMBUS_OPERATION_READ) { + SMBusInterruptSlaveTxHandle(handle); /* Transfer data as slave. */ + } + return; + } else if (handle->state == SMBUS_STATE_BUSY_SLAVE_RX) { + if (status & SMBUS_INTR_RAW_SLAVE_ADDR_MATCH_MASK) { + /* Set TX FIFO the waterline. */ + handle->baseAddress->I2C_INTR_EN.BIT.tx_fifo_not_full_en = BASE_CFG_SET; + /* Set RX FIFO the waterline. */ + handle->baseAddress->I2C_INTR_EN.BIT.rx_fifo_not_empty_en = BASE_CFG_SET; + } + + if (handle->baseAddress->I2C_RX_ADDR.BIT.rx_rw == SMBUS_OPERATION_WRITE) { + SMBusInterruptSlaveRxHandle(handle); /* Receive data as slave. */ + } + return; + } + handle->errorCode = BASE_STATUS_ERROR; + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->state = SMBUS_STATE_READY; /* Changing the SMBUS Bus Status. */ + if (handle->userCallBack.ErrorCallback != NULL) { + handle->userCallBack.ErrorCallback(handle); + } +} + +/** + * @brief Callback Function Registration in transfer mode. + * @param handle SMBUS handle. + * @param callbackID Callback function ID. + * @param pcallback Pointer to the address of the registered callback function. + * @retval None. + */ +static BASE_StatusType SMBusRegisterTransferCallback(SMBUS_Handle *handle, SMBUS_CallbackId callbackID, + SMBUS_CallbackFunType pcallback) +{ + BASE_StatusType ret = BASE_STATUS_OK; + switch (callbackID) { + case SMBUS_MASTER_TX_COMPLETE_CB_ID: + /* Invoke the transfer completion callback function. */ + handle->userCallBack.MasterTxCplCallback = pcallback; + break; + case SMBUS_MASTER_RX_COMPLETE_CB_ID: + /* Invoke the transfer completion callback function. */ + handle->userCallBack.MasterRxCplCallback = pcallback; + break; + case SMBUS_SLAVE_TX_COMPLETE_CB_ID: + /* Invoke the transfer completion callback function. */ + handle->userCallBack.SlaveTxCplCallback = pcallback; + break; + case SMBUS_SLAVE_RX_COMPLETE_CB_ID: + /* Invoke the receive completion callback function. */ + handle->userCallBack.SlaveRxCplCallback = pcallback; + break; + default: + ret = BASE_STATUS_ERROR; + break; + } + return ret; +} + +/** + * @brief DMA Command Configuration last data pec. + * @retval Value of the command. + */ +static unsigned int SMBusDmaConfigLastDataPec(SMBUS_Handle *handle) +{ + unsigned int temp = 0; + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + temp = (((unsigned int)I2C_CMD_M_RPEC_TNACK_S_TPEC_RNACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } else { + if ((handle->frameOpt & SMBUS_FRAME_BLOCK_PROCESSING) == SMBUS_FRAME_BLOCK_PROCESSING) { + /* Reads the last frame of data with ack. */ + temp = (((unsigned int)I2C_CMD_M_RD_TACK_S_TD_RACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } else { + /* Reads the last frame of data without ack. */ + temp = (((unsigned int)I2C_CMD_M_RD_TNACK_S_TD_RNACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } + } + return temp; +} + +/** + * @brief DMA Command Configuration in master. + * @param handle SMBUS handle. + * @param cmd The command type of SMBUS. + * @param size The number of the data to be receiving or sending. + * @retval Value of the command. + */ +static unsigned int SMBusMasterDmaConfigCommandData(SMBUS_Handle *handle, I2C_CmdType cmd, unsigned int size) +{ + unsigned int temp = 0; + if (handle->state == SMBUS_STATE_BUSY_MASTER_TX || handle->state == SMBUS_STATE_BUSY_SLAVE_RX) { + /* Determines whether to execute the PEC command. */ + if ((size == 1) && (handle->frameOpt & SMBUS_FRAME_PEC) && (handle->transferCount >= handle->transferSize)) { + temp = (((unsigned int)I2C_CMD_M_TPEC_RACK_S_RPEC_TACK << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } else { + temp = (((unsigned int)cmd << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } + } + return temp; +} + +/** + * @brief DMA Command Configuration. + * @param handle SMBUS handle. + * @param cmd The command type of SMBUS. + * @param size The number of the data to be receiving or sending. + * @retval Value of the command. + */ +static unsigned int SMBusDmaConfigCommandData(SMBUS_Handle *handle, I2C_CmdType cmd, unsigned int size) +{ + unsigned int temp = 0; + /* Sets the command data. */ + if (handle->state == SMBUS_STATE_BUSY_MASTER_RX || handle->state == SMBUS_STATE_BUSY_SLAVE_TX) { + if ((size == 1) && (handle->transferCount >= handle->transferSize)) { + temp = SMBusDmaConfigLastDataPec(handle); /* DMA Command Configuration last data pec. */ + } else { + /* Reads the last frame of data without ack. */ + temp = (((unsigned int)cmd << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + } + } else { + /* DMA Command Configuration in master. */ + temp = SMBusMasterDmaConfigCommandData(handle, cmd, size); + } + + return temp; +} + +/** + * @brief Config commands and data in dma as master. + * @param handle SMBUS handle. + * @param txBuff Address of the data buff to be receiving or sending. + * @param cmd The command type of SMBUS. + * @param size The number of the data to be receiving or sending. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusDmaMasterConfigDataAndCmd(SMBUS_Handle *handle, unsigned int *txBuff, I2C_CmdType cmd, + unsigned int size) +{ + unsigned int temp; + unsigned int *tempTxBuff = txBuff; + unsigned char *tempsrcTxBuff = (unsigned char*)handle->transferBuff; + unsigned int tempSize = size; + while (tempSize) { + /* Sets the command data. */ + temp = SMBusDmaConfigCommandData(handle, cmd, tempSize); + + /* Sets the normal data. */ + if (handle->state == SMBUS_STATE_BUSY_MASTER_RX) { + temp |= ((0x0 << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + } else if (handle->state == SMBUS_STATE_BUSY_MASTER_TX) { + if ((tempSize == 1) && (handle->frameOpt & SMBUS_FRAME_PEC) && + (handle->transferCount >= handle->transferSize)) { + temp |= (((unsigned int)0x0 << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + } else { + temp |= (((unsigned int)*tempsrcTxBuff << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + tempsrcTxBuff++; + } + } + *tempTxBuff = temp; /* Set the combined data. */ + tempTxBuff++; + tempSize--; + } + return BASE_STATUS_OK; +} + +/** + * @brief Config commands and data in dma as slave. + * @param handle SMBUS handle. + * @param txBuff Address of the data buff to be receiving or sending. + * @param cmd The command type of SMBUS. + * @param size The number of the data to be receiving or sending. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusDmaSlaveConfigDataAndCmd(SMBUS_Handle *handle, unsigned int *txBuff, I2C_CmdType cmd, + unsigned int size) +{ + unsigned int temp; + unsigned int *tempTxBuff = txBuff; + unsigned char *tempsrcTxBuff = (unsigned char*)handle->transferBuff; + unsigned int tempSize = size; + while (tempSize) { + /* Sets the command data. */ + temp = SMBusDmaConfigCommandData(handle, cmd, tempSize); + + /* Sets the normal data. */ + if (handle->state == SMBUS_STATE_BUSY_SLAVE_TX) { + if (tempSize == 1 && (handle->frameOpt & SMBUS_FRAME_PEC) && + (handle->transferCount >= handle->transferSize)) { + temp |= ((0x0 << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + } else { + temp |= (((unsigned int)*tempsrcTxBuff << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + tempsrcTxBuff++; + } + } else if (handle->state == SMBUS_STATE_BUSY_SLAVE_RX) { + temp |= ((0x0 << I2C_TXFIFO_WDATA_POS) & I2C_TXFIFO_WDATA_MASK); + } + *tempTxBuff = temp; /* Set the combined data. */ + tempTxBuff++; + tempSize--; + } + return BASE_STATUS_OK; +} + +/** + * @brief SMBUS DMA Error Handling. + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusDmaErrorHandle(SMBUS_Handle *handle) +{ + /* Some settings when an error occurs. */ + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_UNSET; + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + handle->errorCode = BASE_STATUS_ERROR; + if (handle->userCallBack.ErrorCallback != NULL) { + handle->userCallBack.ErrorCallback(handle); + } + handle->state = SMBUS_STATE_READY; +} + +/** + * @brief SMBUS DMA completes processing. + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusDmaDoneHandle(SMBUS_Handle *handle, unsigned int intrRwa) +{ + /* Disable the DMA operation and configure parameters. */ + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_UNSET; + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + /* Call the corresponding callback function. */ + switch (handle->state) { + case SMBUS_STATE_BUSY_MASTER_TX: + if (handle->userCallBack.MasterTxCplCallback != NULL) { + handle->userCallBack.MasterTxCplCallback(handle); /* Invoke the TX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_MASTER_RX: + if (handle->userCallBack.MasterRxCplCallback != NULL) { + handle->userCallBack.MasterRxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_SLAVE_TX: + if (handle->userCallBack.SlaveTxCplCallback != NULL) { + handle->userCallBack.SlaveTxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_SLAVE_RX: + if (handle->userCallBack.SlaveRxCplCallback != NULL) { + handle->userCallBack.SlaveRxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + default: + break; + } + SMBusInterruptStopCallBack(handle, intrRwa); /* SMBUS Interrupt done Handling with stop callback. */ + handle->state = SMBUS_STATE_READY; +} + +/** + * @brief Wait until all SMBUS timings are processed. + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusDmaWaitHandleFinish(SMBUS_Handle *handle) +{ + unsigned int intrRwa; + unsigned int preTick; + unsigned int curTick; + unsigned long long delta; + unsigned long long targetDelta; + + delta = 0; + preTick = DCL_SYSTICK_GetTick(); + /* Set the timeout threshold to 10000ms. */ + targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SMBUS_TICK_MS_DIV * handle->timeout; + + while (true) { + /* Waiting for the last DMA transfer to complete. */ + intrRwa = handle->baseAddress->I2C_INTR_RAW.reg; + /* Check for errors. */ + if ((intrRwa & (SMBUS_INTR_RAW_ARB_LOST_MASK | SMBUS_INTR_RAW_ACK_BIT_UNMATCH_MASK | + SMBUS_INTR_RAW_SLAVE_ACK_UNMATCH_MASK)) > 0) { + SMBusDmaErrorHandle(handle); + break; + } + /* DMA transfer completed normally. */ + if ((intrRwa & (SMBUS_INTR_RAW_ALL_CMD_DONE_MASK | SMBUS_INTR_RAW_STOP_DET_MASK)) > 0) { + SMBusDmaDoneHandle(handle, intrRwa); + break; + } + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* Check timeout. */ + return; + } + preTick = curTick; + } +} + +/** + * @brief SMBus stop is not sent after DMA transfer is complete. + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusDmaHandleWithoutStop(SMBUS_Handle *handle) +{ + SMBusWaitStatusReady(handle, TX_FIFO_EMPTY, SMBUS_SEND_ADDR_STATUS_WRITE); + switch (handle->state) { + case SMBUS_STATE_BUSY_SLAVE_TX: + if (handle->userCallBack.SlaveTxCplCallback != NULL) { + handle->userCallBack.SlaveTxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_MASTER_TX: + if (handle->userCallBack.MasterTxCplCallback != NULL) { + handle->userCallBack.MasterTxCplCallback(handle); /* Invoke the TX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_SLAVE_RX: + if (handle->userCallBack.SlaveRxCplCallback != NULL) { + handle->userCallBack.SlaveRxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + case SMBUS_STATE_BUSY_MASTER_RX: + if (handle->userCallBack.MasterRxCplCallback != NULL) { + handle->userCallBack.MasterRxCplCallback(handle); /* Invoke the RX callback processing function. */ + } + break; + default: + break; + } + handle->state = SMBUS_STATE_READY; +} + +/** + * @brief The SMBUS uses the DMA completion send stop. + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusDmaOptStepNormalFinishSendStop(SMBUS_Handle *handle) +{ + BASE_StatusType ret; + if (handle->transferCount >= handle->transferSize) { + if ((handle->frameOpt & SMBUS_FRAME_STOP) == SMBUS_FRAME_STOP) { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_P, 0); + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); /* Error handle. */ + return; + } + SMBusDmaWaitHandleFinish(handle); /* The frame with stop. */ + } else { + SMBusDmaHandleWithoutStop(handle); /* The frame without stop. */ + } + } +} + +/** + * @brief The SMBUS uses the DMA completion callback function registered by the DMA module. + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusDmaOptStepNormalFinishFun(void *handle) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_Handle *smbusHandle = (SMBUS_Handle *)(handle); + SMBUS_ASSERT_PARAM(IsI2CInstance(smbusHandle->baseAddress)); + BASE_StatusType ret = BASE_STATUS_OK; + unsigned int tempOnceTransferSize; /* Used to record the amount of data transmitted this time. */ + unsigned int offset; + + offset = smbusHandle->transferCount % I2C_ONCE_TRANS_MAX_NUM; + smbusHandle->transferBuff += (offset == 0) ? I2C_ONCE_TRANS_MAX_NUM : offset; /* Update Transferred Data. */ + + if (smbusHandle->transferCount < smbusHandle->transferSize) { + /* Determine the amount of data transmitted at a time. */ + tempOnceTransferSize = (smbusHandle->dmaTransferSize >= I2C_ONCE_TRANS_MAX_NUM) ? I2C_ONCE_TRANS_MAX_NUM : + smbusHandle->dmaTransferSize; + smbusHandle->dmaTransferSize -= tempOnceTransferSize; + smbusHandle->transferCount += tempOnceTransferSize; + /* Configuring the I2C Timing */ + if (smbusHandle->state == SMBUS_STATE_BUSY_MASTER_RX) { + ret = SMBusDmaMasterReadData(smbusHandle, tempOnceTransferSize); /* The master read data by DMA. */ + } else if (smbusHandle->state == SMBUS_STATE_BUSY_MASTER_TX) { + ret = SMBusDmaMasterWriteData(smbusHandle, tempOnceTransferSize); /* The master write data by DMA. */ + } else if (smbusHandle->state == SMBUS_STATE_BUSY_SLAVE_RX) { + ret = SMBusDmaSlaveReadData(smbusHandle, tempOnceTransferSize); /* The slave read data by DMA. */ + } else if (smbusHandle->state == SMBUS_STATE_BUSY_SLAVE_TX) { + ret = SMBusDmaSlaveWriteData(smbusHandle, tempOnceTransferSize); /* The slave write data by DMA. */ + } + /* Check whether errors occur. */ + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return; + } + return; + } + SMBusDmaOptStepNormalFinishSendStop(handle); /* The SMBUS uses the DMA completion send stop. */ + smbusHandle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_UNSET; + smbusHandle->frameOpt = SMBUS_FRAME_NONE; +} + +/** + * @brief The SMBUS uses the DMA error callback function registered by the DMA module. + * @param handle SMBUS handle. + * @retval None. + */ +static void SMBusDmaErrorHandlerFun(void *handle) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_Handle *smbusHandle = (SMBUS_Handle *)(handle); + SMBUS_ASSERT_PARAM(IsI2CInstance(smbusHandle->baseAddress)); + /* Disable the interrupt and call the error callback function. */ + smbusHandle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + smbusHandle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + smbusHandle->errorCode = BASE_STATUS_ERROR; + if (smbusHandle->userCallBack.ErrorCallback != NULL) { + smbusHandle->userCallBack.ErrorCallback(smbusHandle); + } + /* Stop DMA channel transfer. */ + HAL_DMA_StopChannel(smbusHandle->dmaHandle, smbusHandle->txDmaCh); + if (smbusHandle->state == SMBUS_STATE_BUSY_MASTER_RX || smbusHandle->state == SMBUS_STATE_BUSY_SLAVE_RX) { + HAL_DMA_StopChannel(smbusHandle->dmaHandle, smbusHandle->rxDmaCh); + } + smbusHandle->state = SMBUS_STATE_READY; +} + +/** + * @brief Receive data as master by the DMA module. + * @param handle SMBUS handle. + * @param size Number of the data to be transmitted. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusDmaMasterReadData(SMBUS_Handle *handle, unsigned int size) +{ + /* Combine commands and data. */ + SMBusDmaMasterConfigDataAndCmd(handle, (unsigned int *)g_smbusInternalTxBuffDMA, I2C_CMD_M_RD_TACK_S_TD_RACK, size); + + /* Configuring the DMA Callback Function. */ + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelFinishCallBack = NULL; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelErrorCallBack = SMBusDmaErrorHandlerFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->rxDmaCh].ChannelFinishCallBack = + SMBusDmaOptStepNormalFinishFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->rxDmaCh].ChannelErrorCallBack = SMBusDmaErrorHandlerFun; + /* Start the DMA for data transmission. */ + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)g_smbusInternalTxBuffDMA, + (uintptr_t)&(handle->baseAddress->I2C_TX_FIFO.reg), + size, handle->txDmaCh) != BASE_STATUS_OK) { + handle->state = SMBUS_STATE_READY; + return BASE_STATUS_ERROR; + } + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)&(handle->baseAddress->I2C_RX_FIFO), + (uintptr_t)handle->transferBuff, size, + handle->rxDmaCh) != BASE_STATUS_OK) { + handle->state = SMBUS_STATE_READY; + return BASE_STATUS_ERROR; + } + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_WRITE_READ; + return BASE_STATUS_OK; +} + +/** + * @brief Transmit data as master by the DMA module. + * @param handle SMBUS handle. + * @param size Number of the data to be transmitted. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusDmaMasterWriteData(SMBUS_Handle *handle, unsigned int size) +{ + /* Combine commands and data. */ + SMBusDmaMasterConfigDataAndCmd(handle, (unsigned int *)g_smbusInternalTxBuffDMA, I2C_CMD_M_TD_RACK_S_RD_TACK, size); + + /* Configuring the DMA Callback Function. */ + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelFinishCallBack = + SMBusDmaOptStepNormalFinishFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelErrorCallBack = SMBusDmaErrorHandlerFun; + /* Start the DMA for data transmission. */ + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)g_smbusInternalTxBuffDMA, + (uintptr_t)&(handle->baseAddress->I2C_TX_FIFO.reg), + size, handle->txDmaCh) != BASE_STATUS_OK) { + handle->state = SMBUS_STATE_READY; + return BASE_STATUS_ERROR; + } + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_WRITE; + return BASE_STATUS_OK; +} + +/** + * @brief Receive data as slave by the DMA module. + * @param handle SMBUS handle. + * @param size Number of the data to be transmitted. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusDmaSlaveReadData(SMBUS_Handle *handle, unsigned int size) +{ + /* Combine commands and data. */ + SMBusDmaSlaveConfigDataAndCmd(handle, (unsigned int *)g_smbusInternalTxBuffDMA, I2C_CMD_M_TD_RACK_S_RD_TACK, size); + + /* Configuring the DMA Callback Function. */ + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelFinishCallBack = NULL; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelErrorCallBack = SMBusDmaErrorHandlerFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->rxDmaCh].ChannelFinishCallBack = + SMBusDmaOptStepNormalFinishFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->rxDmaCh].ChannelErrorCallBack = SMBusDmaErrorHandlerFun; + /* Start the DMA for data transmission. */ + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)&(handle->baseAddress->I2C_RX_FIFO), + (uintptr_t)handle->transferBuff, size, + handle->rxDmaCh) != BASE_STATUS_OK) { + handle->state = SMBUS_STATE_READY; + return BASE_STATUS_ERROR; + } + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)g_smbusInternalTxBuffDMA, + (uintptr_t)&(handle->baseAddress->I2C_TX_FIFO), + size, handle->txDmaCh) != BASE_STATUS_OK) { + handle->state = SMBUS_STATE_READY; + return BASE_STATUS_ERROR; + } + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_WRITE_READ; + return BASE_STATUS_OK; +} + +/** + * @brief Transmit data as slave by the DMA module. + * @param handle SMBUS handle. + * @param size Number of the data to be transmitted. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusDmaSlaveWriteData(SMBUS_Handle *handle, unsigned int size) +{ + /* Combine commands and data. */ + SMBusDmaSlaveConfigDataAndCmd(handle, (unsigned int *)g_smbusInternalTxBuffDMA, I2C_CMD_M_RD_TACK_S_TD_RACK, size); + /* Configure DMA Parameters */ + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelFinishCallBack = + SMBusDmaOptStepNormalFinishFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelErrorCallBack = SMBusDmaErrorHandlerFun; + if (HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)g_smbusInternalTxBuffDMA, + (uintptr_t)&(handle->baseAddress->I2C_TX_FIFO.reg), size, handle->txDmaCh) != BASE_STATUS_OK) { + handle->state = SMBUS_STATE_READY; + return BASE_STATUS_ERROR; + } + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_WRITE; + return BASE_STATUS_OK; +} + +/** + * @brief Transmit data by the DMA module. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusTransferDataDma(SMBUS_Handle *handle) +{ + BASE_StatusType ret = BASE_STATUS_OK; + unsigned int tempOnceTransferSize; + handle->dmaTransferSize = handle->transferSize; + + /* Determine the amount of data transmitted at a time. */ + tempOnceTransferSize = (handle->dmaTransferSize >= I2C_ONCE_TRANS_MAX_NUM) ? I2C_ONCE_TRANS_MAX_NUM : + handle->dmaTransferSize; + handle->dmaTransferSize -= tempOnceTransferSize; + handle->transferCount += tempOnceTransferSize; + /* Configuring the SMBUS Timing */ + if (handle->state == SMBUS_STATE_BUSY_MASTER_RX) { + ret = SMBusDmaMasterReadData(handle, tempOnceTransferSize); + } else if (handle->state == SMBUS_STATE_BUSY_MASTER_TX) { + ret = SMBusDmaMasterWriteData(handle, tempOnceTransferSize); + } else if (handle->state == SMBUS_STATE_BUSY_SLAVE_RX) { + ret = SMBusDmaSlaveReadData(handle, tempOnceTransferSize); + } else if (handle->state == SMBUS_STATE_BUSY_SLAVE_TX) { + ret = SMBusDmaSlaveWriteData(handle, tempOnceTransferSize); + } + /* Check whether errors occur. */ + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + + return ret; +} + +/** + * @brief As Slave Multiplex Interrupt Write or Read. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusSlaveMultiplexIT(SMBUS_Handle *handle) +{ + /* Parameter Settings. */ + handle->txReadCmdCount = 0; + handle->sendAddrStatus = SMBUS_SEND_ADDR_STATUS_NONE; + /* Clean interrupt */ + if (handle->frameOpt & SMBUS_FRAME_FIRST) { + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_RAW_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + } + + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_SET; + } + + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_CFG_INTERRUPT_SLAVE; + /* Enable interrupt */ + if (((handle->frameOpt & SMBUS_FRAME_START) != SMBUS_FRAME_START)) { + if (handle->state == SMBUS_STATE_BUSY_SLAVE_TX) { + handle->baseAddress->I2C_INTR_EN.BIT.tx_fifo_not_full_en = BASE_CFG_SET; + } else { + handle->baseAddress->I2C_INTR_EN.BIT.tx_fifo_not_full_en = BASE_CFG_SET; + /* Set RX FIFO the waterline. */ + handle->baseAddress->I2C_INTR_EN.BIT.rx_fifo_not_empty_en = BASE_CFG_SET; + } + } + return BASE_STATUS_OK; +} + +/** + * @brief Confige the frame set in smbus master read blocking. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusMasterReadBlockingFrameSet(SMBUS_Handle *handle) +{ + BASE_StatusType ret; + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_SET; + } + + /* step1 : Parameter Settings and startup Control. */ + if ((handle->frameOpt & SMBUS_FRAME_START) == SMBUS_FRAME_START) { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_S, 0); /* Sets the start command to be sent. */ + if (ret != BASE_STATUS_OK) { + return ret; + } + /* Send slave address and read command. */ + ret = SMBusSendSlaveAddressReadCmd(handle); + if (ret != BASE_STATUS_OK) { + return ret; + } + } + return BASE_STATUS_OK; +} + + +/** + * @brief Confige the frame set in smbus master write blocking. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusMasterWriteBlockingFrameSet(SMBUS_Handle *handle) +{ + BASE_StatusType ret; + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_SET; + } + + /* step1 : Send I2C start and device address. */ + if ((handle->frameOpt & SMBUS_FRAME_START) == SMBUS_FRAME_START) { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_S, 0); /* Sets the start command to be sent. */ + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + /* Send slave address and write command. */ + ret = SMBusSendSlaveAddressWriteCmd(handle); + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + } + return BASE_STATUS_OK; +} + +/** + * @brief Confige the frame set in smbus slave write blocking. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static BASE_StatusType SMBusSlaveWriteBlockingFrameSet(SMBUS_Handle *handle) +{ + BASE_StatusType ret; + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_SET; + } + /* step1 : Waiting for slave address match. */ + if ((handle->frameOpt & SMBUS_FRAME_START) == SMBUS_FRAME_START) { + ret = SMBusWaitStatusReady(handle, SLAVE_ADDRESS_MATCH, SMBUS_OPERATION_READ); + if (ret != BASE_STATUS_OK) { + return ret; + } + /* Execute Cmd Callback. */ + if (((handle->frameOpt & SMBUS_FRAME_EXCUTE_CMD_MATCH) == SMBUS_FRAME_EXCUTE_CMD_MATCH) && + handle->userCallBack.ExecuteCmdCallback != NULL) { + handle->userCallBack.ExecuteCmdCallback(handle); + } + } + return BASE_STATUS_OK; +} + +/** + * @brief Initializing the SMBUS Module. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_Init(SMBUS_Handle *handle) +{ + unsigned int clockFreq; + unsigned int val; + unsigned int tempReg; + unsigned int temp; + unsigned int tempSclLowTime; + unsigned int tempSclHighTime; + + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + + clockFreq = HAL_CRG_GetIpFreq((void *)handle->baseAddress); + if (SMBusCheckAllInitParameters(handle, clockFreq) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + handle->state = SMBUS_STATE_BUSY; + /* Clears interrupts and disables interrupt reporting to facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + + /* Set SDA and SCL glitch filtering time. */ + handle->baseAddress->I2C_FILTER.BIT.spike_filter_time = handle->handleEx.spikeFilterTime; + /* Set SCL high and low duratiom time */ + tempSclLowTime = SMBUS_FREQ_LOW_PARAMTER + handle->handleEx.spikeFilterTime; + tempSclHighTime = SMBUS_FREQ_HIGH_PARAMTER + handle->handleEx.spikeFilterTime; + if (handle->freq <= SMBUS_STANDARD_FREQ_TH) { + /* scl_high_time = (fclk_i2c/fSCL) x 0.5 - 8 - spike_filter_time. */ + val = clockFreq / (handle->freq * 2) - tempSclHighTime; /* The clockFreq / (freq * 2) = cloclFreq/0.5/freq. */ + /* scl_low_time = (fclk_i2c/fSCL) x 0.5 - 9 - spike_filter_time. */ + val = ((val - 1) & LOW_HOLD_TIME_MASK) | ((val << HIGH_HOLD_TIME_POS) & HIGH_HOLD_TIME_MASK); + } else { + /* scl_high_time = (fclk_i2c/fSCL) x 0.36 - 8 - spike_filter_time. (n/100*36)=0.36n. */ + val = ((((clockFreq / 100) * 36) / handle->freq) - tempSclHighTime) << HIGH_HOLD_TIME_POS; + /* scl_low_time = (fclk_i2c/fSCL) x 0.64 - 9 - spike_filter_time. (n/100*64)=0.64n. */ + val |= (((((clockFreq / 100) * 64) / handle->freq) - tempSclLowTime) & LOW_HOLD_TIME_MASK); + } + handle->baseAddress->I2C_SCL_CFG.reg = val; + + /* Set sda hold duration.The value is fixed to 0xa */ + temp = ((handle->sdaHoldTime & 0x0000FFFF) << I2C_SDA_HOLD_DURATION_POS); + tempReg = (handle->handleEx.sdaDelayTime & 0x0000000F) | temp; + handle->baseAddress->I2C_SDA_CFG.reg = tempReg; + + /* Set SMBUS TX FIFO watermark */ + handle->baseAddress->I2C_TX_WATERMARK.BIT.tx_watermark = handle->txWaterMark; + /* Set SMBUS RX FIFO watermark */ + handle->baseAddress->I2C_RX_WATERMARK.BIT.rx_watermark = handle->rxWaterMark; + handle->baseAddress->I2C_MODE.BIT.mst_slv_function = handle->functionMode; + handle->baseAddress->I2C_MODE.BIT.rack_mode = handle->ignoreAckFlag; + + if (handle->functionMode == SMBUS_MODE_SELECT_SLAVE_ONLY || + handle->functionMode == SMBUS_MODE_SELECT_MASTER_SLAVE) { + /* Sets the first own address of the slave. */ + handle->baseAddress->I2C_OWN_ADDR.BIT.own_address = handle->slaveOwnAddress; + handle->baseAddress->I2C_OWN_ADDR.BIT.i2c_general_call_en = handle->generalCallMode; + /* Sets the second own address of the slave. */ + if (handle->handleEx.slaveOwnXmbAddressEnable == BASE_CFG_ENABLE) { + handle->baseAddress->XMB_DEV_ADDR.BIT.xmb_address_en = BASE_CFG_ENABLE; + handle->baseAddress->XMB_DEV_ADDR.BIT.xmb_address = handle->handleEx.slaveOwnXmbAddress; + } + } + handle->state = SMBUS_STATE_READY; + return BASE_STATUS_OK; +} + +/** + * @brief Deinitialize the SMBUS module. + * @param handle SMBUS handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_Deinit(SMBUS_Handle *handle) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + + handle->state = SMBUS_STATE_BUSY; + /* Disable */ + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_UNSET; + handle->baseAddress->I2C_MODE.BIT.mst_slv_function = SMBUS_MODE_SELECT_NONE; + /* Clears interrupts and disables interrupt reporting to + facilitate switching between different working modes. */ + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + /* Clean interrupt callback functions. */ + handle->userCallBack.MasterRxCplCallback = NULL; + handle->userCallBack.MasterTxCplCallback = NULL; + handle->userCallBack.SlaveRxCplCallback = NULL; + handle->userCallBack.SlaveTxCplCallback = NULL; + handle->userCallBack.SlaveWakeupCallback = NULL; + handle->userCallBack.AlertCallback = NULL; + handle->userCallBack.AddrMatchCplCallback = NULL; + handle->userCallBack.ErrorCallback = NULL; + handle->state = SMBUS_STATE_RESET; + + return BASE_STATUS_OK; +} + +/** + * @brief Callback Function Registration. + * @param handle SMBUS handle. + * @param callbackID Callback function ID. + * @param pcallback Pointer to the address of the registered callback function. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_RegisterCallback(SMBUS_Handle *handle, SMBUS_CallbackId callbackID, + SMBUS_CallbackFunType pcallback) +{ + BASE_StatusType ret = BASE_STATUS_OK; + /* Check the parameter validity. */ + SMBUS_ASSERT_PARAM(handle != NULL && pcallback != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_ASSERT_PARAM(pcallback != NULL); + + /* Callback Function Registration in transfer mode. */ + ret = SMBusRegisterTransferCallback(handle, callbackID, pcallback); + if (ret == BASE_STATUS_OK) { + return ret; + } else { + ret = BASE_STATUS_OK; + } + + switch (callbackID) { + case SMBUS_SLAVE_WAKEUP_COMPLETE_CB_ID: + /* Invoke the slave wakeup callback function. */ + handle->userCallBack.SlaveWakeupCallback = pcallback; + break; + case SMBUS_ADDR_MATCH_COMPLETE_CB_ID: + /* Invoke the address match callback function. */ + handle->userCallBack.AddrMatchCplCallback = pcallback; + break; + case SMBUS_MSTAER_SEND_STOP_COMPLETE_CB_ID: + /* Invoke the send stop callback function. */ + handle->userCallBack.MasterSendStopCplCallback = pcallback; + break; + case SMBUS_SLAVE_DETECTED_STOP_COMPLETE_CB_ID: + /* Invoke the detect send stop callback function. */ + handle->userCallBack.SlaveDetectedStopCplCallback = pcallback; + break; + case SMBUS_ALERT_COMPLETE_CB_ID: + /* Invoke the alert callback function. */ + handle->userCallBack.AlertCallback = pcallback; + break; + case SMBUS_ERROR_CB_ID: + /* Invoke the error callback function. */ + handle->userCallBack.ErrorCallback = pcallback; + break; + default: + ret = BASE_STATUS_ERROR; + handle->errorCode = BASE_STATUS_ERROR; + break; + } + + return ret; +} + +/** + * @brief I2C Parameter Configuration in blocking. + * @param handle I2C handle. + * @param transferStatus The status is used to indicate read or write. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +static void SMBusConfigParameters(SMBUS_Handle *handle) +{ + /* Clears row interrupts and disables interrupt. */ + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; +} + +/** + * @brief Receiving data in blocking mode. + * @param handle SMBUS handle. + * @param devAddr Slave Device Address. + * @param buffer: buffer.rData Address of the data buff to be receiving. + * @param buffer: buffer.dataSize Number of the data to be receiving. + * @param timeout Timeout period,unit: ms. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_MasterReadBlocking(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int timeout, unsigned int frameOpt) +{ + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(devAddr <= SMBUS_MAX_DEV_ADDR, BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(timeout > 0, BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); /* State check. */ + + BASE_StatusType ret; + /* Configuring SMBUS Parameters. */ + handle->state = SMBUS_STATE_BUSY_MASTER_RX; + handle->transferBuff = buffer.data; + handle->transferSize = buffer.dataSize; + handle->transferCount = 0; + handle->timeout = timeout; + handle->frameOpt = frameOpt; + SMBusSetSlaveDevAddr(handle, devAddr); /* Set the SMBUS Slave Device Address. */ + SMBusConfigParameters(handle); + + /* Waiting for the SMBUS bus to be idle. */ + if ((handle->frameOpt & SMBUS_FRAME_FIRST) == SMBUS_FRAME_FIRST) { + ret = SMBusWaitStatusReady(handle, BUS_IS_FREE, SMBUS_SEND_ADDR_STATUS_WRITE); + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; + } + + /* Confige the frame set in smbus master read blocking. */ + ret = SMBusMasterReadBlockingFrameSet(handle); + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + + /* step3 : start receive data. */ + ret = SMBusBlockingMasterRxDataOptStepNormal(handle); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SMBusSetErrorHandling(handle); + return ret; + } + /* step4 :send stop CMD. */ + if ((handle->frameOpt & SMBUS_FRAME_STOP) == SMBUS_FRAME_STOP) { + ret = SMBusBlockingSendStopCommand(handle); + } + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_UNSET; + handle->frameOpt = SMBUS_FRAME_NONE; + handle->state = SMBUS_STATE_READY; + return ret; +} + +/** + * @brief Send data in blocking mode. + * @param handle SMBUS handle. + * @param devAddr Slave Device Address. + * @param buffer: buffer.wData Address of the data buff to be sent. + * @param buffer: buffer.dataSize Number of the data to be sent. + * @param timeout Timeout period,unit: ms. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_MasterWriteBlocking(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int timeout, unsigned int frameOpt) +{ + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(devAddr <= SMBUS_MAX_DEV_ADDR, BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(timeout > 0, BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); /* State check. */ + + BASE_StatusType ret; + /* Configuring SMBUS Parameters. */ + handle->state = SMBUS_STATE_BUSY_MASTER_TX; + handle->transferBuff = buffer.data; + handle->transferSize = buffer.dataSize; + handle->transferCount = 0; + handle->timeout = timeout; + handle->frameOpt = frameOpt; + SMBusSetSlaveDevAddr(handle, devAddr); /* Set slave address. */ + SMBusConfigParameters(handle); + + /* Waiting for the SMBUS bus to be idle. */ + if ((handle->frameOpt & SMBUS_FRAME_FIRST) == SMBUS_FRAME_FIRST) { + ret = SMBusWaitStatusReady(handle, BUS_IS_FREE, SMBUS_SEND_ADDR_STATUS_READ); + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; + } + /* Confige the frame set in smbus master write blocking. */ + ret = SMBusMasterWriteBlockingFrameSet(handle); + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + + /* step3 : Send to slave data */ + ret = SMBusBlockingMasterTxDataOptStepNormal(handle); + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + /* step4 : send stop CMD */ + if ((handle->frameOpt & SMBUS_FRAME_STOP) == SMBUS_FRAME_STOP) { + ret = SMBusBlockingSendStopCommand(handle); + } + SMBusWaitStatusReady(handle, TX_FIFO_EMPTY, SMBUS_OPERATION_WRITE); + handle->frameOpt = SMBUS_FRAME_NONE; + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_UNSET; + handle->state = SMBUS_STATE_READY; + return ret; +} + +/** + * @brief Receiving data in blocking mode as slave. + * @param handle SMBUS handle. + * @param buffer: buffer.rData Address of the data buff to be receiving. + * @param buffer: buffer.dataSize Number of the data to be receiving. + * @param timeout Timeout period,unit: ms. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SlaveReadBlocking(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int timeout, + unsigned int frameOpt) +{ + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(timeout > 0, BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); /* State check. */ + + BASE_StatusType ret; + + /* Configuring SMBUS Parameters. */ + handle->state = SMBUS_STATE_BUSY_SLAVE_RX; + handle->transferBuff = buffer.data; + handle->transferSize = buffer.dataSize; + handle->transferCount = 0; + handle->timeout = timeout; + handle->frameOpt = frameOpt; + SMBusConfigParameters(handle); /* step1 : Parameter Settings. */ + + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_SET; + } + + if ((handle->frameOpt & SMBUS_FRAME_START) == SMBUS_FRAME_START) { + /* step2 : Waiting for slave address match. */ + ret = SMBusWaitStatusReady(handle, SLAVE_ADDRESS_MATCH, SMBUS_OPERATION_WRITE); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SMBusSetErrorHandling(handle); + return ret; + } + } + /* step3 : Slave receives data from the master device. */ + ret = SMBusBlockingSlaveRxDataOptStepNormal(handle); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SMBusSetErrorHandling(handle); + return ret; + } + + /* step3 : Wait until all commands are executed. */ + if ((handle->frameOpt & SMBUS_FRAME_STOP) == SMBUS_FRAME_STOP) { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_P, 0); + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + /* Waite command all done. */ + ret = SMBusWaitStatusReady(handle, COMMAND_ALL_DONE, SMBUS_OPERATION_WRITE); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SMBusSetErrorHandling(handle); + return ret; + } + } + + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_UNSET; + handle->frameOpt = SMBUS_FRAME_NONE; + handle->state = SMBUS_STATE_READY; + return ret; +} + +/** + * @brief Send data in blocking mode as slave. + * @param handle SMBUS handle. + * @param buffer: buffer.wData Address of the data buff to be sent. + * @param buffer: buffer.dataSize Number of the data to be sent. + * @param timeout Timeout period,unit: ms. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SlaveWriteBlocking(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int timeout, + unsigned int frameOpt) +{ + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(timeout > 0, BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); /* State check. */ + + BASE_StatusType ret; + /* Configuring Transmission Parameters of SMBUS. */ + handle->state = SMBUS_STATE_BUSY_SLAVE_TX; + handle->transferBuff = buffer.data; + handle->transferSize = buffer.dataSize; + handle->timeout = timeout; + handle->frameOpt = frameOpt; + handle->transferCount = 0; + SMBusConfigParameters(handle); /* step1 : Parameter Settings. */ + /* Confige the frame set in smbus slave write blocking. */ + ret = SMBusSlaveWriteBlockingFrameSet(handle); + if (ret != BASE_STATUS_OK) { + return ret; + } + + /* step2 : Slave send data to the master device. */ + while (handle->transferCount < handle->transferSize) { + if (handle->transferCount == handle->transferSize - 1) { + /* Deal the last frame. */ + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_RPEC_TNACK_S_TPEC_RNACK, 0); + } else { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_RD_TNACK_S_TD_RNACK, *handle->transferBuff); + } + } else { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_M_RD_TACK_S_TD_RACK, *handle->transferBuff); + } + + if (ret != BASE_STATUS_OK) { /* Error check. */ + SMBusSetErrorHandling(handle); + return ret; + } + handle->transferBuff++; + handle->transferCount++; + } + /* step4 : send stop CMD */ + if ((handle->frameOpt & SMBUS_FRAME_STOP) == SMBUS_FRAME_STOP) { + ret = SMBusBlockingSendStopCommand(handle); + } + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_UNSET; + handle->state = SMBUS_STATE_READY; + return ret; +} + +/** + * @brief Receiving data in interrupts mode. + * @param handle SMBUS handle. + * @param devAddr Slave Device Address. + * @param buffer: buffer.rData Address of the data buff to be receiving. + * @param buffer: buffer.dataSize Number of the data to be receiving. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_MasterReadIT(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int frameOpt) +{ + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(devAddr <= SMBUS_MAX_DEV_ADDR, BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); + + /* Configuring I2C Parameters. */ + handle->state = SMBUS_STATE_BUSY_MASTER_RX; + handle->transferBuff = buffer.data; + handle->transferSize = buffer.dataSize; + handle->transferCount = 0; + handle->frameOpt = frameOpt; + SMBusSetSlaveDevAddr(handle, devAddr); + handle->txReadCmdCount = 0; + handle->sendAddrStatus = SMBUS_SEND_ADDR_STATUS_READ; + + /* Clean interrupt */ + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_RAW_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_SET; + } + if ((handle->frameOpt & SMBUS_FRAME_FIRST) == SMBUS_FRAME_FIRST) { + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; + } + /* Enable interrupt */ + handle->baseAddress->I2C_INTR_EN.reg = (SMBUS_CFG_INTERRUPT_MASTER_RX | 0x4000); + return BASE_STATUS_OK; +} + +/** + * @brief Send data in interrupts mode. + * @param handle SMBUS handle. + * @param devAddr Slave Device Address. + * @param buffer: buffer.wData Address of the data buff to be sent. + * @param buffer: buffer.dataSize Number of the data to be sent. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_MasterWriteIT(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int frameOpt) +{ + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(devAddr <= SMBUS_MAX_DEV_ADDR, BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); + + /* Configuring I2C Parameters. */ + handle->state = SMBUS_STATE_BUSY_MASTER_TX; + handle->transferBuff = buffer.data; + handle->transferSize = buffer.dataSize; + handle->transferCount = 0; + handle->frameOpt = frameOpt; + SMBusSetSlaveDevAddr(handle, devAddr); + handle->txReadCmdCount = 0; + handle->sendAddrStatus = SMBUS_SEND_ADDR_STATUS_WRITE; + + /* Clean interrupt */ + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_RAW_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.dma_operation = I2C_DMA_OP_NONE; + + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_SET; + } + + if ((handle->frameOpt & SMBUS_FRAME_FIRST) == SMBUS_FRAME_FIRST) { + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; + } + /* Enable interrupt */ + handle->baseAddress->I2C_INTR_EN.reg = (SMBUS_CFG_INTERRUPT_MASTER_TX | 0x4000); + return BASE_STATUS_OK; +} + +/** + * @brief Receiving data in interrupts mode as slave. + * @param handle SMBUS handle. + * @param buffer: buffer.rData Address of the data buff to be receiving. + * @param buffer: buffer.dataSize Number of the data to be receiving. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SlaveReadIT(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int frameOpt) +{ + BASE_StatusType ret; + + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); + + /* Configuring Transmission Parameters of SMBUS. */ + handle->state = SMBUS_STATE_BUSY_SLAVE_RX; + handle->transferBuff = buffer.data; + handle->transferSize = buffer.dataSize; + handle->transferCount = 0; + handle->frameOpt = frameOpt; + /* Configuring the SMBUS Timing */ + ret = SMBusSlaveMultiplexIT(handle); + + return ret; +} + +/** + * @brief Send data in interrupts mode as slave. + * @param handle SMBUS handle. + * @param buffer: buffer.wData Address of the data buff to be sent. + * @param buffer: buffer.dataSize Number of the data to be sent. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SlaveWriteIT(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int frameOpt) +{ + BASE_StatusType ret = BASE_STATUS_OK; + + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); + + /* Configuring Transmission Parameters of SMBUS. */ + handle->state = SMBUS_STATE_BUSY_SLAVE_TX; + handle->transferBuff = buffer.data; + handle->transferSize = buffer.dataSize; + handle->transferCount = 0; + handle->frameOpt = frameOpt; + /* Configuring the SMBUS Timing */ + ret = SMBusSlaveMultiplexIT(handle); + return ret; +} + +/** + * @brief Receiving data in DMA mode. + * @param handle SMBUS handle. + * @param devAddr Slave Device Address. + * @param buffer: buffer.rData Address of the data buff to be receiving. + * @param buffer: buffer.dataSize Number of the data to be receiving. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_MasterReadDMA(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int frameOpt) +{ + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /* Check the DMA transfer handle and channel. */ + SMBUS_ASSERT_PARAM(handle->dmaHandle != NULL); + SMBUS_PARAM_CHECK_WITH_RET((handle->txDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET((handle->rxDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET((handle->rxDmaCh != handle->txDmaCh), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(devAddr <= SMBUS_MAX_DEV_ADDR, BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); + + BASE_StatusType ret = BASE_STATUS_OK; + + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + + /* Configuring I2C Parameters. */ + handle->state = SMBUS_STATE_BUSY_MASTER_RX; + handle->transferBuff = buffer.data; + handle->transferSize = buffer.dataSize; + handle->transferCount = 0; + handle->frameOpt = frameOpt; + SMBusSetSlaveDevAddr(handle, devAddr); + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_SET; + } + + /* Waiting for the SMBUS bus to be idle. */ + if ((handle->frameOpt & SMBUS_FRAME_FIRST) == SMBUS_FRAME_FIRST) { + ret = SMBusWaitStatusReady(handle, BUS_IS_FREE, SMBUS_SEND_ADDR_STATUS_READ); + if (ret != BASE_STATUS_OK) { + return ret; + } + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; + } else if (handle->baseAddress->I2C_CTRL1.BIT.mst_start != BASE_CFG_SET) { + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; + } + + /* Set the start command and address to be sent. */ + if (handle->frameOpt & SMBUS_FRAME_START) { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_S, 0); /* Sets the start command to be sent. */ + if (ret != BASE_STATUS_OK) { + return ret; + } + ret = SMBusSendSlaveAddressReadCmd(handle); /* Send Address to Slave. */ + if (ret != BASE_STATUS_OK) { + return ret; + } + } + ret = SMBusTransferDataDma(handle); + return ret; +} + +/** + * @brief Send data in DMA mode. + * @param handle SMBUS handle. + * @param devAddr Slave Device Address. + * @param buffer: buffer.wData Address of the data buff to be sent. + * @param buffer: buffer.dataSize Number of the data to be sent. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_MasterWriteDMA(SMBUS_Handle *handle, unsigned short devAddr, SMBUS_DataBuffer buffer, + unsigned int frameOpt) +{ + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /* Check the DMA transfer handle and channel. */ + SMBUS_ASSERT_PARAM(handle->dmaHandle != NULL); + SMBUS_PARAM_CHECK_WITH_RET((handle->txDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(devAddr <= SMBUS_MAX_DEV_ADDR, BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); + + BASE_StatusType ret; + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + + /* Configuring SMBUS Parameters. */ + handle->state = SMBUS_STATE_BUSY_MASTER_TX; + handle->transferBuff = buffer.data; + handle->transferSize = buffer.dataSize; + handle->transferCount = 0; + handle->frameOpt = frameOpt; + SMBusSetSlaveDevAddr(handle, devAddr); + + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_SET; + } + + /* Waiting for the SMBUS bus to be idle. */ + if ((handle->frameOpt & SMBUS_FRAME_FIRST) == SMBUS_FRAME_FIRST) { + ret = SMBusWaitStatusReady(handle, BUS_IS_FREE, SMBUS_SEND_ADDR_STATUS_READ); + if (ret != BASE_STATUS_OK) { + handle->errorCode = ret; + SMBusSetErrorHandling(handle); + return ret; + } + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_SET; + } + + /* Send SMBUS start */ + if ((handle->frameOpt & SMBUS_FRAME_START) == SMBUS_FRAME_START) { + ret = SMBusSetTxFIFODataAndCmd(handle, I2C_CMD_S, 0); /* Sets the start command to be sent. */ + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + /* send slave addr */ + ret = SMBusSendSlaveAddressWriteCmd(handle); + } + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + ret = SMBusTransferDataDma(handle); + + return ret; +} + +/** + * @brief Receiving data in DMA mode as slave. + * @param handle SMBUS handle. + * @param buffer: buffer.rData Address of the data buff to be receiving. + * @param buffer: buffer.dataSize Number of the data to be receiving. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SlaveReadDMA(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int frameOpt) +{ + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /* Check the DMA transfer handle and channel. */ + SMBUS_ASSERT_PARAM(handle->dmaHandle != NULL); + SMBUS_PARAM_CHECK_WITH_RET((handle->txDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET((handle->rxDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET((handle->rxDmaCh != handle->txDmaCh), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); /* State Check. */ + + BASE_StatusType ret = BASE_STATUS_OK; + + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + /* Configuring Transmission Parameters of SMBUS. */ + handle->state = SMBUS_STATE_BUSY_SLAVE_RX; + handle->transferSize = buffer.dataSize; + handle->transferBuff = buffer.data; + handle->transferCount = 0; + handle->frameOpt = frameOpt; + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_UNSET; + + if ((handle->frameOpt & SMBUS_FRAME_PEC) == SMBUS_FRAME_PEC) { + handle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_SET; + } + + /* Waiting for the address to be matched. */ + if ((handle->frameOpt & SMBUS_FRAME_START) == SMBUS_FRAME_START) { + ret = SMBusWaitStatusReady(handle, SLAVE_ADDRESS_MATCH, SMBUS_OPERATION_WRITE); + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + } + SMBusTransferDataDma(handle); + return ret; +} + +/** + * @brief Send data in DMA mode as slave. + * @param handle SMBUS handle. + * @param buffer: buffer.wData, Address of the data buff to be sent. + * @param buffer: buffer.dataSize Number of the data to be sent. + * @param frameOpt: frame format @ref SMBUS_FrameFormat. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SlaveWriteDMA(SMBUS_Handle *handle, SMBUS_DataBuffer buffer, unsigned int frameOpt) +{ + SMBUS_ASSERT_PARAM(handle != NULL && buffer.data != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /* Check the DMA transfer handle and channel. */ + SMBUS_ASSERT_PARAM(handle->dmaHandle != NULL); + SMBUS_PARAM_CHECK_WITH_RET((handle->txDmaCh < CHANNEL_MAX_NUM), BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(buffer.dataSize > 0, BASE_STATUS_ERROR); + SMBUS_PARAM_CHECK_WITH_RET(handle->state == SMBUS_STATE_READY, BASE_STATUS_ERROR); + + BASE_StatusType ret = BASE_STATUS_OK; + handle->baseAddress->I2C_INTR_EN.reg = SMBUS_INTR_EN_ALL_DISABLE; + handle->baseAddress->I2C_INTR_RAW.reg = SMBUS_INTR_RAW_ALL_ENABLE; + /* Configuring Transmission Parameters of SMBUS. */ + handle->state = SMBUS_STATE_BUSY_SLAVE_TX; + handle->transferSize = buffer.dataSize; + handle->transferBuff = buffer.data; + handle->transferCount = 0; + handle->frameOpt = frameOpt; + /* Startup Control */ + handle->baseAddress->I2C_CTRL1.BIT.rst_rx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.rst_tx_fifo = BASE_CFG_SET; + handle->baseAddress->I2C_CTRL1.BIT.mst_start = BASE_CFG_UNSET; + /* Waiting for the address to be matched. */ + if (handle->frameOpt & SMBUS_FRAME_START) { + ret = SMBusWaitStatusReady(handle, SLAVE_ADDRESS_MATCH, SMBUS_OPERATION_WRITE); + if (ret != BASE_STATUS_OK) { + SMBusSetErrorHandling(handle); + return ret; + } + } + SMBusTransferDataDma(handle); + return ret; +} + +/** + * @brief Interrupt Handling Function. + * @param handle Handle pointers + * @retval None + */ +void HAL_SMBUS_IrqHandler(void *handle) +{ + SMBUS_Handle *smbusHandle = (SMBUS_Handle *)handle; + SMBUS_ASSERT_PARAM(smbusHandle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(smbusHandle->baseAddress)); + + unsigned int status; + status = smbusHandle->baseAddress->I2C_INTR_STAT.reg; + + if (status & SMBUS_ERROR_BIT_MASK) { /* Check error interrupt mask. */ + SMBusIsInterruptErrorStatus(smbusHandle, status); + return; + } + + if ((status & SMBUS_ALERT_RAW_MASK) && (smbusHandle->userCallBack.AlertCallback != NULL)) { /* smbus alert */ + smbusHandle->userCallBack.AlertCallback(smbusHandle); + smbusHandle->baseAddress->I2C_INTR_RAW.reg = (1 << SMBUS_ALERT_RAW_POS); + return; + } + /* Address match handler. */ + SMBusInterruptAddrMatchHandle(handle, status); + + /* Callback interrupt handler function. */ + SMBusInterruptHandle(smbusHandle, status); + smbusHandle->baseAddress->I2C_INTR_RAW.reg = + (SMBUS_INTR_RAW_TX_FIFO_NOT_FULL_MASK | SMBUS_INTR_RAW_RX_FIFO_FULL_MASK); + if ((smbusHandle->transferCount >= smbusHandle->transferSize) && + (!(status & (SMBUS_INTR_RAW_ALL_CMD_DONE_MASK | SMBUS_INTR_RAW_STOP_DET_MASK)))) { + if (smbusHandle->baseAddress->I2C_FIFO_STAT.BIT.tx_fifo_vld_num < SMBUS_MAX_FIFO_SIZE) { + if ((smbusHandle->frameOpt & SMBUS_FRAME_STOP) == SMBUS_FRAME_STOP) { + smbusHandle->baseAddress->I2C_TX_FIFO.reg = + (((unsigned int)I2C_CMD_P << I2C_TXFIFO_CMD_POS) & I2C_TXFIFO_CMD_MASK); + smbusHandle->baseAddress->I2C_INTR_EN.BIT.tx_fifo_not_full_en = BASE_CFG_DISABLE; + smbusHandle->baseAddress->I2C_MODE.BIT.xmb_pec_en = BASE_CFG_UNSET; + } + } + } + + /* After all data transmission is complete, call the user's callback function. */ + SMBusInterruptAllDoneHandle(smbusHandle, status); +} \ No newline at end of file diff --git a/src/drivers/smbus/smbus_v0/src/smbus_ex.c b/src/drivers/smbus/smbus_v0/src/smbus_ex.c new file mode 100644 index 0000000000000000000000000000000000000000..a78933c512f0ba20397af960d63ee4fe4f04ba1f --- /dev/null +++ b/src/drivers/smbus/smbus_v0/src/smbus_ex.c @@ -0,0 +1,166 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file smbus_ex.c + * @author MCU Driver Team + * @brief SMBUS module driver + * @details The header file contains the following declaration: + * + Setting the Special Function Configuration. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "smbus_ex.h" + +/* Macro definitions ---------------------------------------------------------*/ + +/** + * @brief Set data transfer sequence. + * @param handle: SMBUS handle. + * @param sequence: data transfer sequence enumeration value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SetDataTransferSequenceEx(SMBUS_Handle *handle, SMBUS_DataTransferSequenceType sequence) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cDataTransferSequence(sequence), BASE_STATUS_ERROR); + /**< Data Transfer Sequence. 0:SMBUS_MOST_BIT_FIRST, 1:SMBUS_LEAST_BIT_FIRST. */ + handle->baseAddress->I2C_MODE.BIT.lit_end = sequence; + return BASE_STATUS_OK; +} + +/** + * @brief Set SMBUS clock stretching function. + * @param handle: SMBUS handle. + * @param clkStretch: clock stretching enumeration value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SetSclStretchModeEx(SMBUS_Handle *handle, SMBUS_ClockStretchType clkStretch) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cClockStretchValue(clkStretch), BASE_STATUS_ERROR); + /**< Clock stretching enable. 0:enable, 1:disable. */ + handle->baseAddress->I2C_MODE.BIT.scl_stretch_disable = clkStretch; + return BASE_STATUS_OK; +} + +/** + * @brief Set SMBUS SCL low-level timeout. + * @param handle: SMBUS handle. + * @param sclLowTimeout: SCL low-level timeout value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SetSclLowTimeoutEx(SMBUS_Handle *handle, unsigned int sclLowTimeout) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cSclLowTimeout(sclLowTimeout), BASE_STATUS_ERROR); + /* The unit of bus free time is SMBUS working clock cycle. */ + handle->baseAddress->I2C_SCL_TIMEOUT.BIT.scl_low_timeout = sclLowTimeout; + return BASE_STATUS_OK; +} + +/** + * @brief Set SMBUS bus idle threshold value. + * @param handle: SMBUS handle. + * @param busFreeTime: bus idle threshold value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SetBusFreeTimeEx(SMBUS_Handle *handle, unsigned int busFreeTime) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cBusFreeTime(busFreeTime), BASE_STATUS_ERROR); + /* The unit of bus free time is SMBUS working clock cycle. */ + handle->baseAddress->I2C_BUS_FREE.BIT.bus_free_time = busFreeTime; + return BASE_STATUS_OK; +} + +/** + * @brief Set SMBUS slave receive 10-bit slave addressing. + * @param handle: SMBUS handle. + * @param arg: slave special function set enumeration value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_Set10BitSlaveEnableEx(SMBUS_Handle *handle) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /**< Enable the slave receives the 10bit addressing. */ + handle->baseAddress->I2C_OWN_ADDR.BIT.i2c_10bit_slave_en = BASE_CFG_SET; + return BASE_STATUS_OK; +} + +/** + * @brief Set SMBUS slave receive device ID address. + * @param handle: SMBUS handle. + * @param arg: slave special function set enumeration value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SetDeviceIdAddressEnableEx(SMBUS_Handle *handle) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + /**< Enable the function of receiving device ID addresses. */ + handle->baseAddress->I2C_OWN_ADDR.BIT.i2c_device_id_en = BASE_CFG_SET; + return BASE_STATUS_OK; +} + +/** + * @brief Set SMBUS slave receive start byte address. + * @param handle: SMBUS handle. + * @param arg: slave special function set enumeration value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SetStartByteEnableEx(SMBUS_Handle *handle) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + handle->baseAddress->I2C_OWN_ADDR.BIT.i2c_start_byte_en = BASE_CFG_SET; /**< Enable receiving START Byte Address. */ + return BASE_STATUS_OK; +} + +/** + * @brief Set SMBUS slave own address mask. + * @param handle: SMBUS handle. + * @param addrMask: own address mask. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SetOwnAddressMaskEx(SMBUS_Handle *handle, unsigned int addrMask) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(IsI2cOwnAddressOrMask(addrMask), BASE_STATUS_ERROR); + handle->baseAddress->I2C_OWN_ADDR.BIT.own_address_mask = addrMask; /**< Slave's own address mask. */ + return BASE_STATUS_OK; +} + +/** + * @brief Set SMBUS slave XMBus address mask. + * @param handle: SMBUS handle. + * @param addrMask: XMBus address mask. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT, NOT SUPPORT. + */ +BASE_StatusType HAL_SMBUS_SetOwnXmbAddressMaskEx(SMBUS_Handle *handle, unsigned int addrMask) +{ + SMBUS_ASSERT_PARAM(handle != NULL); + SMBUS_ASSERT_PARAM(IsI2CInstance(handle->baseAddress)); + SMBUS_PARAM_CHECK_WITH_RET(IsXMBusAddressOrMask(addrMask), BASE_STATUS_ERROR); + handle->baseAddress->XMB_DEV_ADDR.BIT.xmb_address_mask = addrMask; /**< The second own address mask as slave. */ + return BASE_STATUS_OK; +} diff --git a/src/drivers/spi/spi_v0/src/spi.c b/src/drivers/spi/spi_v0/src/spi.c index f9f5e1b480a856f17196f8fa95fcd803992f3a53..15e9084c19c3d9d5d4792ea092a61726ad79dd56 100644 --- a/src/drivers/spi/spi_v0/src/spi.c +++ b/src/drivers/spi/spi_v0/src/spi.c @@ -30,10 +30,13 @@ #include "spi.h" /* Macro definitions ---------------------------------------------------------*/ #define SPI_WAIT_TIMEOUT 0x400 +#define SPI_FIFO_DEPTH 256 #define SPI_DATA_WIDTH_SHIFT_8BIT 1 #define SPI_DATA_WIDTH_SHIFT_16BIT 2 +#define SPI_DATA_SHIFT_8BIT 8 + #define SPI_INTERRUPT_SET_ALL 0xF #define SPI_DMA_FIFO_ENABLE 0x3 @@ -91,7 +94,7 @@ static BASE_StatusType ConfigThreeTransferParam(SPI_Handle *handle) if (handle->xFerMode == HAL_XFER_MODE_BLOCKING) { handle->baseAddress->SPIIMSC.reg = 0x0; } else if (handle->xFerMode == HAL_XFER_MODE_INTERRUPTS) { - handle->baseAddress->SPIIMSC.reg = SPI_INTERRUPT_SET_ALL; + handle->baseAddress->SPIIMSC.reg = 0x0; /* Setting the rx and tx interrupt transfer size */ handle->baseAddress->SPITXFIFOCR.BIT.txintsize = handle->txIntSize; handle->baseAddress->SPIRXFIFOCR.BIT.rxintsize = handle->rxIntSize; @@ -146,16 +149,45 @@ static void SpiCsControl(SPI_Handle *handle, unsigned int control) * @param handle SPI handle. * @retval None. */ -static void SpiRxTxCallack(void *handle) +static void SpiRxTxCallbackFunc(void *handle) +{ + SPI_Handle *spiHandle = (SPI_Handle *) handle; + switch (spiHandle->state) { + case HAL_SPI_STATE_BUSY_TX : + /* Invoke tx callback function. */ + if (spiHandle->txCount == spiHandle->transferSize && spiHandle->userCallBack.TxCpltCallback != NULL) { + spiHandle->userCallBack.TxCpltCallback(spiHandle); + } + break; + case HAL_SPI_STATE_BUSY_RX : + /* Invoke rx callback function. */ + if (spiHandle->userCallBack.RxCpltCallback != NULL) { + spiHandle->userCallBack.RxCpltCallback(spiHandle); + } + break; + case HAL_SPI_STATE_BUSY_TX_RX : + /* Invoke tx rx callback function. */ + if (spiHandle->userCallBack.TxRxCpltCallback != NULL) { + spiHandle->userCallBack.TxRxCpltCallback(spiHandle); + } + break; + default : + break; + } +} + +/** + * @brief Tx and Rx complete processing. + * @param handle SPI handle. + * @retval None. + */ +static void SpiRxTxCallback(void *handle) { SPI_Handle *spiHandle = (SPI_Handle *) handle; SPI_ASSERT_PARAM(spiHandle != NULL); SPI_ASSERT_PARAM(IsSPIInstance(spiHandle->baseAddress)); - if (spiHandle->txCount == spiHandle->transferSize) { - /* Invoke tx callback function. */ - if (spiHandle->userCallBack.TxCpltCallback != NULL) { - spiHandle->userCallBack.TxCpltCallback(spiHandle); - } + if (spiHandle->txCount == spiHandle->transferSize && spiHandle->baseAddress->SPIIMSC.BIT.txim != 0x0) { + /* Masks the TX interrupt. */ spiHandle->baseAddress->SPIIMSC.BIT.txim = 0x0; } @@ -168,14 +200,8 @@ static void SpiRxTxCallack(void *handle) SpiCsControl(spiHandle, SPI_CHIP_DESELECT); - /* Invoke rx callback function. */ - if (spiHandle->userCallBack.RxCpltCallback != NULL) { - spiHandle->userCallBack.RxCpltCallback(spiHandle); - } - /* Invoke tx rx callback function. */ - if (spiHandle->userCallBack.TxRxCpltCallback != NULL) { - spiHandle->userCallBack.TxRxCpltCallback(spiHandle); - } + /* RX or TX callback after cs desselect. */ + SpiRxTxCallbackFunc(spiHandle); spiHandle->state = HAL_SPI_STATE_READY; } } @@ -187,7 +213,7 @@ static void SpiRxTxCallack(void *handle) */ static void WriteData(SPI_Handle *handle) { - while (handle->baseAddress->SPISR.BIT.tnf && + while (handle->baseAddress->SPISR.BIT.tnf && (handle->txCount - handle->rxCount) < SPI_FIFO_DEPTH && (handle->transferSize > handle->txCount)) { if (handle->dataWidth > SPI_DATA_WIDTH_8BIT) { /* Only data needs to be read. Due to SPI characteristics, @@ -196,9 +222,13 @@ static void WriteData(SPI_Handle *handle) handle->baseAddress->SPIDR.reg = 0x0; handle->txCount += SPI_DATA_WIDTH_SHIFT_16BIT; } else { - handle->baseAddress->SPIDR.reg = *(unsigned short *)handle->txBuff; - handle->txCount += SPI_DATA_WIDTH_SHIFT_16BIT; /* txCount is number of bytes transferred */ - handle->txBuff += SPI_DATA_WIDTH_SHIFT_16BIT; + unsigned short txData = *handle->txBuff; + handle->txBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + unsigned short temp = *handle->txBuff; + handle->txBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + txData += (temp << SPI_DATA_SHIFT_8BIT); + handle->baseAddress->SPIDR.reg = txData; /* Write data to register. */ + handle->txCount += SPI_DATA_WIDTH_SHIFT_16BIT; /* txCount is number of bytes transferred. */ } } else { /* datawidth is 8bit */ if (handle->txBuff == NULL) { @@ -230,9 +260,12 @@ static void ReadData(SPI_Handle *handle) BASE_FUNC_UNUSED(val); handle->rxCount += SPI_DATA_WIDTH_SHIFT_16BIT; } else { - *(unsigned short *)handle->rxBuff = handle->baseAddress->SPIDR.reg; - handle->rxCount += SPI_DATA_WIDTH_SHIFT_16BIT; - handle->rxBuff += SPI_DATA_WIDTH_SHIFT_16BIT; + unsigned short rxData = handle->baseAddress->SPIDR.reg; /* Read data from register. */ + *handle->rxBuff = rxData; + handle->rxBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + *handle->rxBuff = (rxData >> SPI_DATA_SHIFT_8BIT); + handle->rxBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + handle->rxCount += SPI_DATA_WIDTH_SHIFT_16BIT; /* rxCount is number of bytes received. */ } } else { /* datawidth is 8bit */ if (handle->rxBuff == NULL) { @@ -241,7 +274,7 @@ static void ReadData(SPI_Handle *handle) handle->rxCount += SPI_DATA_WIDTH_SHIFT_8BIT; } else { *(unsigned char *)handle->rxBuff = handle->baseAddress->SPIDR.reg & 0xff; - handle->rxCount += SPI_DATA_WIDTH_SHIFT_8BIT; + handle->rxCount += SPI_DATA_WIDTH_SHIFT_8BIT; /* rxCount is number of bytes received. */ handle->rxBuff += SPI_DATA_WIDTH_SHIFT_8BIT; } } @@ -1179,5 +1212,5 @@ void HAL_SPI_IrqHandler(void *handle) } ReadData(spiHandle); } - SpiRxTxCallack(spiHandle); + SpiRxTxCallback(spiHandle); } \ No newline at end of file diff --git a/src/drivers/spi/spi_v1/inc/spi_ip.h b/src/drivers/spi/spi_v1/inc/spi_ip.h index b51a0a113b50ed717c8107f47a7459570addf51b..42cfc5afb18aae710df24284e897f6511777fce3 100644 --- a/src/drivers/spi/spi_v1/inc/spi_ip.h +++ b/src/drivers/spi/spi_v1/inc/spi_ip.h @@ -233,9 +233,7 @@ typedef enum { typedef enum { SPI_CHIP_SELECT_CHANNEL_0 = 0x00000000U, SPI_CHIP_SELECT_CHANNEL_1 = 0x00000001U, - SPI_CHIP_SELECT_CHANNEL_2 = 0x00000002U, - SPI_CHIP_SELECT_CHANNEL_3 = 0x00000003U, - SPI_CHIP_SELECT_CHANNEL_MAX = 0x00000004U + SPI_CHIP_SELECT_CHANNEL_MAX = 0x00000002U } SPI_ChipSelectChannel; /** diff --git a/src/drivers/spi/spi_v1/src/spi.c b/src/drivers/spi/spi_v1/src/spi.c index 59a37f14a4ff0a995cbc355a71eee4e299a0d0d2..1603b99cdfec662b811fb849014ce1bcd8ba8e66 100644 --- a/src/drivers/spi/spi_v1/src/spi.c +++ b/src/drivers/spi/spi_v1/src/spi.c @@ -30,11 +30,14 @@ #include "spi.h" /* Macro definitions ---------------------------------------------------------*/ #define SPI_WAIT_TIMEOUT 0x400 +#define SPI_FIFO_DEPTH 16 #define SPI_DATA_WIDTH_SHIFT_8BIT 1 #define SPI_DATA_WIDTH_SHIFT_16BIT 2 #define SPI_WRITE_FIFO_SIZE 2 +#define SPI_DATA_SHIFT_8BIT 8 + #define SPI_INTERRUPT_SET_ALL 0xF #define SPI_DMA_FIFO_ENABLE 0x3 @@ -90,7 +93,7 @@ static BASE_StatusType ConfigThreeTransferParam(SPI_Handle *handle) if (handle->xFerMode == HAL_XFER_MODE_BLOCKING) { handle->baseAddress->SPIIMSC.reg = 0x0; } else if (handle->xFerMode == HAL_XFER_MODE_INTERRUPTS) { - handle->baseAddress->SPIIMSC.reg = SPI_INTERRUPT_SET_ALL; + handle->baseAddress->SPIIMSC.reg = 0x0; /* Setting the rx and tx interrupt transfer size */ handle->baseAddress->SPITXFIFOCR.BIT.txintsize = handle->txIntSize; handle->baseAddress->SPIRXFIFOCR.BIT.rxintsize = handle->rxIntSize; @@ -145,16 +148,45 @@ static void SpiCsControl(SPI_Handle *handle, unsigned int control) * @param handle SPI handle. * @retval None. */ -static void SpiRxTxCallack(void *handle) +static void SpiRxTxCallbackFunc(void *handle) +{ + SPI_Handle *spiHandle = (SPI_Handle *) handle; + switch (spiHandle->state) { + case HAL_SPI_STATE_BUSY_TX : + /* Invoke tx callback function. */ + if (spiHandle->txCount == spiHandle->transferSize && spiHandle->userCallBack.TxCpltCallback != NULL) { + spiHandle->userCallBack.TxCpltCallback(spiHandle); + } + break; + case HAL_SPI_STATE_BUSY_RX : + /* Invoke rx callback function. */ + if (spiHandle->userCallBack.RxCpltCallback != NULL) { + spiHandle->userCallBack.RxCpltCallback(spiHandle); + } + break; + case HAL_SPI_STATE_BUSY_TX_RX : + /* Invoke tx rx callback function. */ + if (spiHandle->userCallBack.TxRxCpltCallback != NULL) { + spiHandle->userCallBack.TxRxCpltCallback(spiHandle); + } + break; + default : + break; + } +} + +/** + * @brief Tx and Rx complete processing. + * @param handle SPI handle. + * @retval None. + */ +static void SpiRxTxCallback(void *handle) { SPI_Handle *spiHandle = (SPI_Handle *) handle; SPI_ASSERT_PARAM(spiHandle != NULL); SPI_ASSERT_PARAM(IsSPIInstance(spiHandle->baseAddress)); - if (spiHandle->txCount == spiHandle->transferSize) { - /* Invoke tx callback function. */ - if (spiHandle->userCallBack.TxCpltCallback != NULL) { - spiHandle->userCallBack.TxCpltCallback(spiHandle); - } + if (spiHandle->txCount == spiHandle->transferSize && spiHandle->baseAddress->SPIIMSC.BIT.txim != 0x0) { + /* Masks the TX interrupt. */ spiHandle->baseAddress->SPIIMSC.BIT.txim = 0x0; } @@ -167,14 +199,8 @@ static void SpiRxTxCallack(void *handle) SpiCsControl(spiHandle, SPI_CHIP_DESELECT); - /* Invoke rx callback function. */ - if (spiHandle->userCallBack.RxCpltCallback != NULL) { - spiHandle->userCallBack.RxCpltCallback(spiHandle); - } - /* Invoke tx rx callback function. */ - if (spiHandle->userCallBack.TxRxCpltCallback != NULL) { - spiHandle->userCallBack.TxRxCpltCallback(spiHandle); - } + /* RX or TX callback after cs desselect. */ + SpiRxTxCallbackFunc(spiHandle); spiHandle->state = HAL_SPI_STATE_READY; } } @@ -186,8 +212,7 @@ static void SpiRxTxCallack(void *handle) */ static void WriteData(SPI_Handle *handle) { - unsigned int size = 0; - while ((size < SPI_WRITE_FIFO_SIZE) && (handle->baseAddress->SPISR.BIT.tnf) && + while (handle->baseAddress->SPISR.BIT.tnf && (handle->txCount - handle->rxCount) < SPI_FIFO_DEPTH && (handle->transferSize > handle->txCount)) { if (handle->dataWidth > SPI_DATA_WIDTH_8BIT) { /* Only data needs to be read. Due to SPI characteristics, @@ -196,9 +221,13 @@ static void WriteData(SPI_Handle *handle) handle->baseAddress->SPIDR.reg = 0x0; handle->txCount += SPI_DATA_WIDTH_SHIFT_16BIT; } else { - handle->baseAddress->SPIDR.reg = *(unsigned short *)handle->txBuff; - handle->txCount += SPI_DATA_WIDTH_SHIFT_16BIT; /* txCount is number of bytes transferred */ - handle->txBuff += SPI_DATA_WIDTH_SHIFT_16BIT; + unsigned short txData = *handle->txBuff; + handle->txBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + unsigned short temp = *handle->txBuff; + handle->txBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + txData += (temp << SPI_DATA_SHIFT_8BIT); + handle->baseAddress->SPIDR.reg = txData; /* Write data to register. */ + handle->txCount += SPI_DATA_WIDTH_SHIFT_16BIT; /* txCount is number of bytes transferred. */ } } else { /* datawidth is 8bit */ if (handle->txBuff == NULL) { @@ -210,7 +239,6 @@ static void WriteData(SPI_Handle *handle) handle->txBuff += SPI_DATA_WIDTH_SHIFT_8BIT; } } - size++; } } @@ -231,9 +259,12 @@ static void ReadData(SPI_Handle *handle) BASE_FUNC_UNUSED(val); handle->rxCount += SPI_DATA_WIDTH_SHIFT_16BIT; } else { - *(unsigned short *)handle->rxBuff = handle->baseAddress->SPIDR.reg; - handle->rxCount += SPI_DATA_WIDTH_SHIFT_16BIT; - handle->rxBuff += SPI_DATA_WIDTH_SHIFT_16BIT; + unsigned short rxData = handle->baseAddress->SPIDR.reg; /* Read data from register. */ + *handle->rxBuff = rxData; + handle->rxBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + *handle->rxBuff = (rxData >> SPI_DATA_SHIFT_8BIT); + handle->rxBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + handle->rxCount += SPI_DATA_WIDTH_SHIFT_16BIT; /* rxCount is number of bytes received. */ } } else { /* datawidth is 8bit */ if (handle->rxBuff == NULL) { @@ -242,7 +273,7 @@ static void ReadData(SPI_Handle *handle) handle->rxCount += SPI_DATA_WIDTH_SHIFT_8BIT; } else { *(unsigned char *)handle->rxBuff = handle->baseAddress->SPIDR.reg & 0xff; - handle->rxCount += SPI_DATA_WIDTH_SHIFT_8BIT; + handle->rxCount += SPI_DATA_WIDTH_SHIFT_8BIT; /* rxCount is number of bytes received. */ handle->rxBuff += SPI_DATA_WIDTH_SHIFT_8BIT; } } @@ -1167,5 +1198,5 @@ void HAL_SPI_IrqHandler(void *handle) } /* Reads and writes data based on the interrupt flag. */ ReadWriteInt(spiHandle); - SpiRxTxCallack(spiHandle); + SpiRxTxCallback(spiHandle); } \ No newline at end of file diff --git a/src/drivers/spi/spi_v3/inc/spi_ex.h b/src/drivers/spi/spi_v3/inc/spi_ex.h new file mode 100644 index 0000000000000000000000000000000000000000..22684be76f3a0fb8d1056b68b39ac08eead983de --- /dev/null +++ b/src/drivers/spi/spi_v3/inc/spi_ex.h @@ -0,0 +1,49 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file spi_ex.h + * @author MCU Driver Team + * @brief SPI module driver. + * @details This file provides firmware functions to manage the following. + * functionalities of the SPI. + * + SPI Set Functions. + */ +#ifndef McuMagicTag_SPI_EX_H +#define McuMagicTag_SPI_EX_H +/* Includes ------------------------------------------------------------------*/ +#include "spi.h" + +/* Macro definitions ---------------------------------------------------------*/ +/** + * @addtogroup SPI_IP + * @{ + */ + +/** + * @defgroup SPI_EX_API_Declaration SPI HAL API EX + * @{ + */ +BASE_StatusType HAL_SPI_SetChipConfigSelectEx(SPI_Handle *handle, HAL_SPI_CHIP_CONFIG mode); +HAL_SPI_CHIP_CONFIG HAL_SPI_GetChipConfigSelectEx(SPI_Handle *handle); +/** + * @} + */ + +/** + * @} + */ +#endif /* #ifndef McuMagicTag_SPI_EX_H */ \ No newline at end of file diff --git a/src/drivers/spi/spi_v3/inc/spi_ip.h b/src/drivers/spi/spi_v3/inc/spi_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..eaa7f8d8727fefe419ff61c8157d080a27eaadae --- /dev/null +++ b/src/drivers/spi/spi_v3/inc/spi_ip.h @@ -0,0 +1,1342 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file spi_ip.h + * @author MCU Driver Team. + * @brief SPI module driver. + * @details This file provides firmware functions to manage the following. + * functionalities of the SPI. + * + Register definition structure. + * + Direct configuration layer interface. + * + Parameter check inline function. + */ +#ifndef McuMagicTag_SPI_IP_H +#define McuMagicTag_SPI_IP_H + +/* Includes ------------------------------------------------------------------*/ +#include "baseinc.h" +#ifdef SPI_PARAM_CHECK +#define SPI_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM +#define SPI_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET +#define SPI_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else +#define SPI_ASSERT_PARAM(para) ((void)0U) +#define SPI_PARAM_CHECK_NO_RET(para) ((void)0U) +#define SPI_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) +#endif + +/** + * @addtogroup SPI + * @{ + */ + +/** + * @defgroup SPI_IP SPI_IP + * @brief SPI_IP: spi_v3. + * @{ + */ + +#define SPI_CR0_SCR_POS 8 +#define SPI_CR0_SCR_MASK (0xFF << SPI_CR0_SCR_POS) + +/** + * @defgroup SPI_Param_Def SPI Parameters Definition + * @brief Definition of SPI configuration parameters. + * @{ + */ + +/* Typedef definitions -------------------------------------------------------*/ +/** + * @brief Master and Slave Device Enumeration Definition. + */ +typedef enum { + HAL_SPI_MASTER = 0x00000000U, + HAL_SPI_SLAVE = 0x00000001U +} HAL_SPI_Mode; + +/** + * @brief Clock Polarity Enumeration Definition. + */ +typedef enum { + HAL_SPI_CLKPOL_0 = 0x00000000U, + HAL_SPI_CLKPOL_1 = 0x00000001U +} HAL_SPI_ClkPol; + +/** + * @brief Clock Phase Enumeration Definition. + */ +typedef enum { + HAL_SPI_CLKPHA_0 = 0x00000000U, + HAL_SPI_CLKPHA_1 = 0x00000001U +} HAL_SPI_ClkPha; + +/** + * @brief Enumeration definition of data endian. + */ +typedef enum { + HAL_SPI_BIG_ENDIAN = 0x00000000U, + HAL_SPI_LITTILE_ENDIAN = 0x00000001U +} HAL_SPI_Endian; + +/** + * @brief Enumerated definition of data frame mode selection. + */ +typedef enum { + HAL_SPI_MODE_MOTOROLA = 0x00000000U, + HAL_SPI_MODE_TI = 0x00000001U, + HAL_SPI_MODE_MICROWIRE = 0x00000002U +} HAL_SPI_FrameMode; + +/** + * @brief Transmission Mode Selection Enumeration Definition. + */ +typedef enum { + HAL_XFER_MODE_BLOCKING = 0x00000000U, + HAL_XFER_MODE_INTERRUPTS = 0x00000001U, + HAL_XFER_MODE_DMA = 0x00000002U +} HAL_SPI_XferMode; + +/** + * @brief SPI Chip Select Config Definition. + */ +typedef enum { + HAL_SPI_CHIP_CONFIG_AUTO = 0x00000000U, + HAL_SPI_CHIP_CONFIG_ALTASENS = 0x00000001U, + HAL_SPI_CHIP_CONFIG_SOFR_UNSET = 0x00000002U, + HAL_SPI_CHIP_CONFIG_SOFR_SET = 0x00000003U +} HAL_SPI_CHIP_CONFIG; + +/** + * @brief Data Bit Width Enumeration Definition. + */ +typedef enum { + SPI_DATA_WIDTH_4BIT = 0x00000003U, + SPI_DATA_WIDTH_5BIT = 0x00000004U, + SPI_DATA_WIDTH_6BIT = 0x00000005U, + SPI_DATA_WIDTH_7BIT = 0x00000006U, + SPI_DATA_WIDTH_8BIT = 0x00000007U, + SPI_DATA_WIDTH_9BIT = 0x00000008U, + SPI_DATA_WIDTH_10BIT = 0x00000009U, + SPI_DATA_WIDTH_11BIT = 0x0000000aU, + SPI_DATA_WIDTH_12BIT = 0x0000000bU, + SPI_DATA_WIDTH_13BIT = 0x0000000cU, + SPI_DATA_WIDTH_14BIT = 0x0000000dU, + SPI_DATA_WIDTH_15BIT = 0x0000000eU, + SPI_DATA_WIDTH_16BIT = 0x0000000fU +} HAL_SPI_DataWidth; + +/** + * @brief Definitions of available parameters for interrupt Tx thresholds. + */ +typedef enum { + SPI_TX_INTERRUPT_SIZE_0 = 0x00000000U, + SPI_TX_INTERRUPT_SIZE_1 = 0x00000001U, + SPI_TX_INTERRUPT_SIZE_2 = 0x00000002U, + SPI_TX_INTERRUPT_SIZE_3 = 0x00000003U, + SPI_TX_INTERRUPT_SIZE_4 = 0x00000004U, + SPI_TX_INTERRUPT_SIZE_5 = 0x00000005U, + SPI_TX_INTERRUPT_SIZE_6 = 0x00000006U, + SPI_TX_INTERRUPT_SIZE_7 = 0x00000007U, + SPI_TX_INTERRUPT_SIZE_8 = 0x00000008U, + SPI_TX_INTERRUPT_SIZE_9 = 0x00000009U, + SPI_TX_INTERRUPT_SIZE_10 = 0x0000000AU, + SPI_TX_INTERRUPT_SIZE_11 = 0x0000000BU, + SPI_TX_INTERRUPT_SIZE_12 = 0x0000000CU, + SPI_TX_INTERRUPT_SIZE_13 = 0x0000000DU, + SPI_TX_INTERRUPT_SIZE_14 = 0x0000000EU, + SPI_TX_INTERRUPT_SIZE_15 = 0x0000000FU +} HAL_SPI_TxInterruptSize; + +/** + * @brief Definitions of available parameters for interrupt Rx thresholds. + */ +typedef enum { + SPI_RX_INTERRUPT_SIZE_0 = 0x00000000U, + SPI_RX_INTERRUPT_SIZE_1 = 0x00000001U, + SPI_RX_INTERRUPT_SIZE_2 = 0x00000002U, + SPI_RX_INTERRUPT_SIZE_3 = 0x00000003U, + SPI_RX_INTERRUPT_SIZE_4 = 0x00000004U, + SPI_RX_INTERRUPT_SIZE_5 = 0x00000005U, + SPI_RX_INTERRUPT_SIZE_6 = 0x00000006U, + SPI_RX_INTERRUPT_SIZE_7 = 0x00000007U, + SPI_RX_INTERRUPT_SIZE_8 = 0x00000008U, + SPI_RX_INTERRUPT_SIZE_9 = 0x00000009U, + SPI_RX_INTERRUPT_SIZE_10 = 0x0000000AU, + SPI_RX_INTERRUPT_SIZE_11 = 0x0000000BU, + SPI_RX_INTERRUPT_SIZE_12 = 0x0000000CU, + SPI_RX_INTERRUPT_SIZE_13 = 0x0000000DU, + SPI_RX_INTERRUPT_SIZE_14 = 0x0000000EU, + SPI_RX_INTERRUPT_SIZE_15 = 0x0000000FU, +} HAL_SPI_RxInterruptSize; + +/** + * @brief Definitions of available parameters for DMA Tx thresholds. + */ +typedef enum { + SPI_TX_DMA_BURST_SIZE_0 = 0x00000000U, + SPI_TX_DMA_BURST_SIZE_1 = 0x00000001U, + SPI_TX_DMA_BURST_SIZE_2 = 0x00000002U, + SPI_TX_DMA_BURST_SIZE_3 = 0x00000003U, + SPI_TX_DMA_BURST_SIZE_4 = 0x00000004U, + SPI_TX_DMA_BURST_SIZE_5 = 0x00000005U, + SPI_TX_DMA_BURST_SIZE_6 = 0x00000006U, + SPI_TX_DMA_BURST_SIZE_7 = 0x00000007U, + SPI_TX_DMA_BURST_SIZE_8 = 0x00000008U, + SPI_TX_DMA_BURST_SIZE_9 = 0x00000009U, + SPI_TX_DMA_BURST_SIZE_10 = 0x0000000AU, + SPI_TX_DMA_BURST_SIZE_11 = 0x0000000BU, + SPI_TX_DMA_BURST_SIZE_12 = 0x0000000CU, + SPI_TX_DMA_BURST_SIZE_13 = 0x0000000DU, + SPI_TX_DMA_BURST_SIZE_14 = 0x0000000EU, + SPI_TX_DMA_BURST_SIZE_15 = 0x0000000FU, +} HAL_SPI_TxDmaBurstSize; + +/** + * @brief Definitions of available parameters for DMA Rx thresholds. + */ +typedef enum { + SPI_RX_DMA_BURST_SIZE_0 = 0x00000000U, + SPI_RX_DMA_BURST_SIZE_1 = 0x00000001U, + SPI_RX_DMA_BURST_SIZE_2 = 0x00000002U, + SPI_RX_DMA_BURST_SIZE_3 = 0x00000003U, + SPI_RX_DMA_BURST_SIZE_4 = 0x00000004U, + SPI_RX_DMA_BURST_SIZE_5 = 0x00000005U, + SPI_RX_DMA_BURST_SIZE_6 = 0x00000006U, + SPI_RX_DMA_BURST_SIZE_7 = 0x00000007U, + SPI_RX_DMA_BURST_SIZE_8 = 0x00000008U, + SPI_RX_DMA_BURST_SIZE_9 = 0x00000009U, + SPI_RX_DMA_BURST_SIZE_10 = 0x0000000AU, + SPI_RX_DMA_BURST_SIZE_11 = 0x0000000BU, + SPI_RX_DMA_BURST_SIZE_12 = 0x0000000CU, + SPI_RX_DMA_BURST_SIZE_13 = 0x0000000DU, + SPI_RX_DMA_BURST_SIZE_14 = 0x0000000EU, + SPI_RX_DMA_BURST_SIZE_15 = 0x0000000FU, +} HAL_SPI_RxDmaBurstSize; + +/** + * @brief Defines the SPI chip select channel. + */ +typedef enum { + SPI_CHIP_SELECT_CHANNEL_0 = 0x00000000U, + SPI_CHIP_SELECT_CHANNEL_1 = 0x00000001U, + SPI_CHIP_SELECT_CHANNEL_MAX = 0x00000002U +} SPI_ChipSelectChannel; + +/** + * @brief Defines the three-wire or four-wire mode of the SPI. + */ +typedef enum { + SPI_DATA_2LINES = 0x00000000U, + SPI_DATA_1LINE = 0x00000001U, +} SPI_DataLine; + +/** + * @brief Defines the SPI data transfer direction. + */ +typedef enum { + SPI_DATA_DIREC_RECV = 0x00000000U, + SPI_DATA_DIREC_SEND = 0x00000001U, +} SPI_DataDirec; + +/** + * @brief SPI extend handle. + */ +typedef struct _SPI_ExtendHandle { + SPI_DataLine line; +} SPI_ExtendHandle; + +/** + * @brief SPI user callback. + */ +typedef struct { + /* Sending completion callback function */ + void (* TxCpltCallback)(void *handle); + /* Receive completion callback function */ + void (* RxCpltCallback)(void *handle); + /* Receive and Sending completion callback function */ + void (* TxRxCpltCallback)(void *handle); + /* Error callback function */ + void (* ErrorCallback)(void *handle); + /* CS callback function */ + void (* CsCtrlCallback)(void *handle); +} SPI_UserCallBack; +/** + * @} + */ + +/** + * @defgroup SPI_Reg_Def SPI Register Definition + * @brief register mapping structure + * @{ + */ +/* Register Description Definition----------------------------------- */ + +/** + * @brief SPI clock, polarity, phase, frame format, data bit control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int dss : 4; /**< data width. */ + unsigned int frf : 2; /**< frame format: Motorola TI Mircowire. */ + unsigned int spo : 1; /**< motorola polarity. */ + unsigned int sph : 1; /**< motorola phase. */ + unsigned int scr : 8; /**< serial clock rate. */ + unsigned int reserved0 : 16; + } BIT; +} SPICR0_REG; + +/** + * @brief SPI parameter control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int lbm : 1; /**< loopback mode enable. */ + unsigned int sse : 1; /**< SPI enable. */ + unsigned int ms : 1; /**< Master or Salve mode. */ + unsigned int reserved0 : 1; + unsigned int bitend : 1; /**< set the endian mode. */ + unsigned int reserved1 : 1; + unsigned int triwire : 1; /**< three-wire/four-wire mode. */ + unsigned int triwiretxoe : 1; /**< Data line direction in three-wire mode. */ + unsigned int waitval : 7; /**< Microwire wait time. */ + unsigned int waiten : 1; /**< Microwire wait enable. */ + unsigned int reserved2 : 16; + } BIT; +} SPICR1_REG; + +/** + * @brief SPI data FIFO register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int data : 16; /**< send and receive FIFO. */ + unsigned int reserved0 : 16; + } BIT; +} SPIDR_REG; + +/** + * @brief SPI status register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int tfe : 1; /**< tx FIFO empty flag. */ + unsigned int tnf : 1; /**< tx FIFO not full flag. */ + unsigned int rne : 1; /**< rx FIFO not empty flag. */ + unsigned int rff : 1; /**< rx FIFO full flag. */ + unsigned int bsy : 1; /**< SPI busy flag. */ + unsigned int reserved0 : 27; + } BIT; +} SPISR_REG; + +/** + * @brief SPI clock divider register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cpsdvsr : 8; /**< clock divider value, value is even number between 2 and 254. */ + unsigned int reserved0 : 24; + } BIT; +} SPICPSR_REG; + +/** + * @brief SPI interrupt mask control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int rorim : 1; /**< rx overflow interrupt mask. */ + unsigned int rtim : 1; /**< rx timeout interrupt mask. */ + unsigned int rxim : 1; /**< rx FIFO interrupt mask. */ + unsigned int txim : 1; /**< tx FIFO interrupt mask. */ + unsigned int reserved0 : 28; + } BIT; +} SPIIMSC_REG; + +/** + * @brief SPI raw interrupt status register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int rorris : 1; /**< raw status of the rx overflow interrupt. */ + unsigned int rtris : 1; /**< raw status of the rx timeout interrupt. */ + unsigned int rxris : 1; /**< raw status of the rx FIFO interrupt. */ + unsigned int txris : 1; /**< raw status of the tx FIFO interrupt. */ + unsigned int reserved0 : 28; + } BIT; +} SPIRIS_REG; + +/** + * @brief SPI masked interrupt status register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int rormis : 1; /**< masked status of the rx overflow interrupt. */ + unsigned int rtmis : 1; /**< masked status of the rx timeout interrupt. */ + unsigned int rxmis : 1; /**< masked status of the rx FIFO interrupt. */ + unsigned int txmis : 1; /**< masked status of the tx FIFO interrupt. */ + unsigned int reserved0 : 28; + } BIT; +} SPIMIS_REG; + +/** + * @brief SPI interrupt clear register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int roric : 1; /**< clear the rx overflow interrupt. */ + unsigned int rtic : 1; /**< clear the rx timeout interrupt. */ + unsigned int reserved0 : 30; + } BIT; +} SPIICR_REG; + +/** + * @brief SPI DMA control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int rxdmae : 1; /**< DMA rx FIFO enable. */ + unsigned int txdmae : 1; /**< DMA tx FIFO enable. */ + unsigned int rxdmalsreqe : 1; /**< DMA rx FIFO SPI flow control. */ + unsigned int reserved0 : 29; + } BIT; +} SPIDMACR_REG; + +/** + * @brief SPI tx FIFO control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int txintsize : 4; /**< set the threshold of the tx FIFO request interrupt. */ + unsigned int txfiforst : 1; /**< tx fifo soft reset. */ + unsigned int reserved1 : 27; + } BIT; +} SPITXFIFOCR_REG; + +/** + * @brief SPI rx FIFO control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int rxintsize : 4; /**< set the threshold of the rx FIFO request interrupt. */ + unsigned int rxfiforst : 1; /**< rx fifo soft reset. */ + unsigned int reserved1 : 27; + } BIT; +} SPIRXFIFOCR_REG; + + +/** + * @brief SPI cs mode control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int spi_csn_sel : 2; /**< chip select. */ + unsigned int reserved0 : 2; + unsigned int spi_csn_mode : 2; /**< chip select mode. */ + unsigned int reserved1 : 26; + } BIT; +} SPICSNCR_REG; + +/** + * @brief SPI Register definition structure + */ +typedef struct { + SPICR0_REG SPICR0; /**< SPI parameter control register 0. */ + SPICR1_REG SPICR1; /**< SPI parameter control register 1. */ + SPIDR_REG SPIDR; /**< SPI data FIFO register. */ + SPISR_REG SPISR; /**< SPI status register. */ + SPICPSR_REG SPICPSR; /**< SPI clock divider register. */ + SPIIMSC_REG SPIIMSC; /**< SPI interrupt mask control register. */ + SPIRIS_REG SPIRIS; /**< SPI raw interrupt status register. */ + SPIMIS_REG SPIMIS; /**< SPI masked interrupt status register. */ + SPIICR_REG SPIICR; /**< SPI interrupt clear register. */ + SPIDMACR_REG SPIDMACR; /**< SPI DMA control register. */ + SPITXFIFOCR_REG SPITXFIFOCR; /**< SPI tx FIFO control register. */ + SPIRXFIFOCR_REG SPIRXFIFOCR; /**< SPI rx FIFO control register. */ + SPICSNCR_REG SPICSNCR; /**< SPI cs mode control register. */ +} volatile SPI_RegStruct; +/** + * @} + */ + +/** + * @brief Check whether the SPI mode is used. + * @param mode Spi mode + * @retval true + * @retval false + */ +static inline bool IsSpiMode(unsigned int mode) +{ + if (mode == HAL_SPI_MASTER || mode == HAL_SPI_SLAVE) { + return true; + } + return false; +} + +/** + * @brief Check if the transfer mode specified for the SPI. + * @param xFermode Transfer mode. + * @retval true + * @retval false + */ +static inline bool IsSpiXferMode(unsigned int xFermode) +{ + if (xFermode == HAL_XFER_MODE_BLOCKING || + xFermode == HAL_XFER_MODE_INTERRUPTS || + xFermode == HAL_XFER_MODE_DMA) { + return true; + } + return false; +} + +/** + * @brief Checking SPI Polarity Parameters. + * @param clkPolarity Polarity Parameters. + * @retval true + * @retval false + */ +static inline bool IsSpiClkPolarity(unsigned int clkPolarity) +{ + if (clkPolarity == HAL_SPI_CLKPOL_0 || + clkPolarity == HAL_SPI_CLKPOL_1) { + return true; + } + return false; +} + +/** + * @brief Checking SPI Phase Parameters. + * @param clkPhase Phase Parameters. + * @retval true + * @retval false + */ +static inline bool IsSpiClkPhase(unsigned int clkPhase) +{ + if (clkPhase == HAL_SPI_CLKPHA_0 || + clkPhase == HAL_SPI_CLKPHA_1) { + return true; + } + return false; +} + +/** + * @brief Check the SPI big-endian configuration parameters. + * @param endian Big-endian configuration parameters. + * @retval true + * @retval false + */ +static inline bool IsSpiEndian(unsigned int endian) +{ + if (endian == HAL_SPI_BIG_ENDIAN || + endian == HAL_SPI_LITTILE_ENDIAN) { + return true; + } + return false; +} + +/** + * @brief Check the SPI frame format configuration. + * @param framFormat Frame format. + * @retval true + * @retval false + */ +static inline bool IsSpiFrameFormat(unsigned int framFormat) +{ + if (framFormat == HAL_SPI_MODE_MOTOROLA || + framFormat == HAL_SPI_MODE_TI || + framFormat == HAL_SPI_MODE_MICROWIRE) { + return true; + } + return false; +} + +/** + * @brief Checking the SPI Data Bit Width Configuration. + * @param dataWidth Data Bit Width. + * @retval true + * @retval false + */ +static inline bool IsSpiDataWidth(unsigned int dataWidth) +{ + if (dataWidth >= SPI_DATA_WIDTH_4BIT && dataWidth <= SPI_DATA_WIDTH_16BIT) { + return true; + } + return false; +} + +/** + * @brief Check the configuration of the waiting time between the TX and RX in the SPI microwire frame format. + * @param waitVal Waiting time. + * @retval true + * @retval false + */ +static inline bool IsSpiWaitVal(unsigned char waitVal) +{ + /* waitval value is 0 to 0x7f */ + if (waitVal <= 0x7f) { + return true; + } + return false; +} + +/** + * @brief Check the SPI interrupt TX threshold configuration. + * @param txIntSize TX threshold configuration. + * @retval true + * @retval false + */ +static inline bool IsSpiTxIntSize(unsigned int txIntSize) +{ + if (txIntSize <= SPI_TX_INTERRUPT_SIZE_15) { + return true; + } + return false; +} + +/** + * @brief Check the SPI interrupt RX threshold configuration. + * @param rxIntSize RX threshold configuration. + * @retval true + * @retval false + */ +static inline bool IsSpiRxIntSize(unsigned int rxIntSize) +{ + if (rxIntSize <= SPI_RX_INTERRUPT_SIZE_15) { + return true; + } + return false; +} + +/** + * @brief Check the SPI DMA TX threshold configuration. + * @param txDMABurstSize TX threshold. + * @retval true + * @retval false + */ +static inline bool IsSpiTxDmaBurstSize(unsigned int txDMABurstSize) +{ + if (txDMABurstSize <= SPI_TX_DMA_BURST_SIZE_15) { + return true; + } + return false; +} + +/** + * @brief Check the SPI DMA RX threshold configuration. + * @param rxDMABurstSize RX threshold. + * @retval true + * @retval false + */ +static inline bool IsSpiRxDmaBurstSize(unsigned int rxDMABurstSize) +{ + if (rxDMABurstSize <= SPI_RX_DMA_BURST_SIZE_15) { + return true; + } + return false; +} + +/** + * @brief Checking SPI frequency divider parameters. + * @param freqCpsdvsr Frequency division parameters to be checked. + * @retval true + * @retval false + */ +static inline bool IsSpiFreqCpsdvsr(unsigned char freqCpsdvsr) +{ + /* FreqCpsdvsr value is 0 to 255 */ + if (freqCpsdvsr >= 2) { + return true; + } + return false; +} + +/** + * @brief Setting SPI Chip Config Mode + * @param mode Spi Chip Config Mode + * @retval true + * @retval false + */ +static inline bool IsSpiChipConfigMode(unsigned int mode) +{ + if (mode <= HAL_SPI_CHIP_CONFIG_SOFR_SET) { + return true; + } + return false; +} + +/** + * @brief Setting SPI Chip Select Channel + * @param csn Spi Chip Select + * @retval true + * @retval false + */ +static inline bool IsSpiChipSelectChannel(unsigned int csn) +{ + if (csn < SPI_CHIP_SELECT_CHANNEL_MAX) { + return true; + } + return false; +} + +/** + * @brief Setting SPI Chip Config Mode + * @param mode Spi Chip Config Mode + * @retval true + * @retval false + */ +static inline bool IsSpiLine(unsigned int line) +{ + if ((line == SPI_DATA_1LINE) || (line == SPI_DATA_2LINES)) { + return true; + } + return false; +} + + +/* Direct configuration layer interface----------------------------------*/ +/** + * @brief SPI module enable. + * @param spix SPI register base address. + * @param spiEnable SPI enable or disable. + * @retval None. + */ +static inline void DCL_SPI_SetSpiEnable(SPI_RegStruct *spix, bool spiEnable) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + spix->SPICR1.BIT.sse = spiEnable; +} + +/** + * @brief Get SPI enable status. + * @param spix SPI register base address. + * @retval bool SPI enable or disable. + */ +static inline bool DCL_SPI_GetSpiEnable(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR1.BIT.sse; +} + +/** + * @brief Set SPI loopback. + * @param spix SPI register base address. + * @param loop enable or disable + * @retval None. + */ +static inline void DCL_SPI_SetLoopBack(SPI_RegStruct *spix, bool loop) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + spix->SPICR1.BIT.lbm = loop; +} + +/** + * @brief Get SPI loopback. + * @param spix SPI register base address. + * @retval bool loopback is enable or disable. + */ +static inline bool DCL_SPI_GetLoopBack(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR1.BIT.lbm; +} + +/** + * @brief Configuring SPI polarity + * @param spix SPI register base address. + * @param clkPolarity SPI Polarity,the value is 0 or 1. + * @retval None. + */ +static inline void DCL_SPI_SetClkPolarity(SPI_RegStruct *spix, unsigned int clkPolarity) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiClkPolarity(clkPolarity)); + spix->SPICR0.BIT.spo = clkPolarity; +} + +/** + * @brief Get SPI polarity. + * @param spix SPI register base address. + * @retval SPI Polarity,the value is 0 or 1. + */ +static inline unsigned char DCL_SPI_GetClkPolarity(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR0.BIT.spo; +} + +/** + * @brief Configuring SPI phase. + * @param spix SPI register base address. + * @param clkPhase SPI phase,the value is 0 or 1. + * @retval None. + */ +static inline void DCL_SPI_SetClkPhase(SPI_RegStruct *spix, unsigned int clkPhase) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiClkPhase(clkPhase)); + spix->SPICR0.BIT.sph = clkPhase; +} + +/** + * @brief Get SPI phase. + * @param spix SPI register base address. + * @retval SPI phase,the value is 0 or 1. + */ +static inline unsigned char DCL_SPI_GetClkPhase(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR0.BIT.sph; +} + +/** + * @brief SPI data big endian configuration. + * @param spix SPI register base address. + * @param bitEnd Big-endian configuration parameter. The value can be 0 or 1. + * @retval None. + */ +static inline void DCL_SPI_SetBitEnd(SPI_RegStruct *spix, unsigned int bitEnd) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiEndian(bitEnd)); + spix->SPICR1.BIT.bitend = bitEnd; +} + +/** + * @brief Get SPI data big endian configuration. + * @param spix SPI register base address. + * @retval Big-endian configuration parameter. The value is 0 or 1. + */ +static inline unsigned char DCL_SPI_GetBitEnd(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR1.BIT.bitend; +} + +/** + * @brief SPI frame format configuration. + * @param spix SPI register base address. + * @param frameFormat Value: Motorola: 00, TI synchronous serial: 01, National Microwire: 10. + * @retval None. + */ +static inline void DCL_SPI_SetFrameFormat(SPI_RegStruct *spix, unsigned char frameFormat) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiFrameFormat(frameFormat)); + spix->SPICR0.BIT.frf = frameFormat; +} + +/** + * @brief Get SPI frame format configuration. + * @param spix SPI register base address. + * @retval Motorola: 00, TI synchronous serial: 01, National Microwire: 10. + */ +static inline unsigned char DCL_SPI_GetFrameFormat(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR0.BIT.frf; +} + +/** + * @brief Configuring the SPI data bit width. + * @param spix SPI register base address. + * @param dataWidth The data bit width can be set to 4 to 16 bits. + * @retval None. + */ +static inline void DCL_SPI_SetDataWidth(SPI_RegStruct *spix, unsigned int dataWidth) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiDataWidth(dataWidth)); + spix->SPICR0.BIT.dss = dataWidth; +} + +/** + * @brief Get the SPI data bit width configuring. + * @param spix SPI register base address. + * @retval SPI Data Bit Width configuring. + */ +static inline unsigned char DCL_SPI_GetDataWidth(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR0.BIT.dss; +} + +/** + * @brief SPI serial clock rate configuration. + * @param spix SPI register base address. + * @param freqScr Value range: 0 to 255. + * @retval None. + */ +static inline void DCL_SPI_SetFreqScr(SPI_RegStruct *spix, unsigned char freqScr) +{ + unsigned int cr0Reg; + unsigned int temp; + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + /* Read the entire register and write it back. */ + temp = ((unsigned int)freqScr) << SPI_CR0_SCR_POS; + cr0Reg = (spix->SPICR0.reg & (~SPI_CR0_SCR_MASK)) | temp; + spix->SPICR0.reg = cr0Reg; +} + +/** + * @brief Get SPI serial clock rate configuration. + * @param spix SPI register base address. + * @retval Value range: 0 to 255. + */ +static inline unsigned char DCL_SPI_GetFreqScr(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return ((spix->SPICR0.reg >> SPI_CR0_SCR_POS) & 0xFF); /* Minimum 8-bit mask 0xFF */ +} + +/** + * @brief SPI clock divider setting. + * @param spix SPI register base address. + * @param freqCpsdvsr The value must be an even number between 2 and 255. + * @retval None. + */ +static inline void DCL_SPI_SetFreqCpsdvsr(SPI_RegStruct *spix, unsigned char freqCpsdvsr) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiFreqCpsdvsr(freqCpsdvsr)); + spix->SPICPSR.BIT.cpsdvsr = freqCpsdvsr; +} + +/** + * @brief Get SPI clock divider setting. + * @param spix SPI register base address. + * @retval The value is an even number between 2 and 255. + */ +static inline unsigned char DCL_SPI_GetFreqCpsdvsr(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICPSR.BIT.cpsdvsr; +} + +/** + * @brief Configuring the SPI TX threshold. + * @param spix SPI register base address. + * @param txIntSize The value can be 0-15. For details, see the register manual. + * @retval None. + */ +static inline void DCL_SPI_SetTxIntSize(SPI_RegStruct *spix, unsigned int txIntSize) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiTxIntSize(txIntSize)); + spix->SPITXFIFOCR.BIT.txintsize = txIntSize; +} + +/** + * @brief Get the SPI TX threshold configuring. + * @param spix SPI register base address. + * @retval The value is 0-15. For details, see the register manual. + */ +static inline unsigned char DCL_SPI_GetTxIntSize(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPITXFIFOCR.BIT.txintsize; +} + +/** + * @brief Configuring the SPI RX threshold. + * @param spix SPI register base address. + * @param rxIntSize The value can be 0-15. For details, see the register manual. + * @retval None. + */ +static inline void DCL_SPI_SetRxIntSize(SPI_RegStruct *spix, unsigned int rxIntSize) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiRxIntSize(rxIntSize)); + spix->SPIRXFIFOCR.BIT.rxintsize = rxIntSize; +} + +/** + * @brief Get the SPI RX threshold configuring. + * @param spix SPI register base address. + * @retval The value is 0-15. For details, see the register manual. + */ +static inline unsigned char DCL_SPI_GetRxIntSize(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPIRXFIFOCR.BIT.rxintsize; +} + +/** + * @brief Configuring the CS Channel. + * @param spix SPI register base address. + * @retval None. + */ +static inline void DCL_SPI_SetChipSelect(SPI_RegStruct *spix, unsigned int channel) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiChipSelectChannel(channel)); + spix->SPICSNCR.BIT.spi_csn_sel = channel; +} + +/** + * @brief Obtains the channel of the current CS. + * @param spix SPI register base address. + * @retval SPI_ChipSelectChannel. + */ +static inline unsigned char DCL_SPI_GetChipSelect(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICSNCR.BIT.spi_csn_sel; +} + +/** + * @brief SPI CHIP CONFIG SET. + * @param spix SPI register base address. + * @param mode The value can be 0-4. For details, see the register manual. + * @retval None. + */ +static inline void DCL_SPI_SetChipConfigSelect(SPI_RegStruct *spix, HAL_SPI_CHIP_CONFIG mode) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiChipConfigMode(mode)); + spix->SPICSNCR.BIT.spi_csn_mode = mode; +} + +/** + * @brief SPI CHIP CONFIG GET. + * @param spix SPI register base address. + * @retval HAL_SPI_CHIP_CONFIG. + */ +static inline HAL_SPI_CHIP_CONFIG DCL_SPI_GetChipConfigSelect(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICSNCR.BIT.spi_csn_mode; +} + +/** + * @brief Setting the Master/Slave Mode. + * @param spix SPI register base address. + * @param mode @ref HAL_SPI_Mode. + * @retval None. + */ +static inline void DCL_SPI_SetMasterSlaveMode(SPI_RegStruct *spix, HAL_SPI_Mode mode) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiMode(mode)); + spix->SPICR1.BIT.ms = mode; +} + +/** + * @brief Getting the Master/Slave Mode. + * @param spix SPI register base address. + * @retval HAL_SPI_Mode master or slave. + */ +static inline HAL_SPI_Mode DCL_SPI_GetMasterSlaveMode(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR1.BIT.ms; +} + +/** + * @brief Set microwire waitval. + * @param spix SPI register base address. + * @param value is microwire wait beats. + * @retval None. + */ +static inline void DCL_SPI_SetMircoWaitVal(SPI_RegStruct *spix, unsigned char value) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(IsSpiWaitVal(value)); + spix->SPICR1.BIT.waitval = value; +} + +/** + * @brief Get microwire waitval. + * @param spix SPI register base address. + * @retval unsigned char, For details, see the register manual + */ +static inline unsigned char DCL_SPI_GetMircoWaitVal(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR1.BIT.waitval; +} + +/** + * @brief Set microwire wait enable or disable. + * @param spix SPI register base address. + * @param waitEn is microwire wait enable or disable. + * @retval None. + */ +static inline void DCL_SPI_SetMircoWaitEn(SPI_RegStruct *spix, bool waitEn) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + spix->SPICR1.BIT.waiten = waitEn; +} + +/** + * @brief Get microwire wait enable or disable. + * @param spix SPI register base address. + * @retval bool is microwire wait enable or disable + */ +static inline bool DCL_SPI_GetMircoWaitEn(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR1.BIT.waiten; +} + +/** + * @brief Put the data into the TX FIFO. + * @param spix SPI register base address. + * @param data is input data. + * @retval None. + */ +static inline void DCL_SPI_SetData(SPI_RegStruct *spix, unsigned short data) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + spix->SPIDR.reg = data; +} + +/** + * @brief Get data from the RX FIFO. + * @param spix SPI register base address. + * @retval unsigned short data from the RX FIFO. + */ +static inline unsigned short DCL_SPI_GetData(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPIDR.reg; +} + +/** + * @brief Get whether the TX FIFO is empty. + * @param spix SPI register base address. + * @retval bool TX FIFO is not empty or is empty. + */ +static inline bool DCL_SPI_GetTxFifoEmpty(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPISR.BIT.tfe; +} + +/** + * @brief Get whether the TX FIFO is full. + * @param spix SPI register base address. + * @retval bool TX FIFO is not full or is full. + */ +static inline bool DCL_SPI_GetTxFifoFull(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPISR.BIT.tnf; +} + +/** + * @brief Get whether the RX FIFO is empty. + * @param spix SPI register base address. + * @retval bool RX FIFO is not empty or is empty. + */ +static inline bool DCL_SPI_GetRxFifoEmpty(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPISR.BIT.rne; +} + +/** + * @brief Get whether the RX FIFO is full. + * @param spix SPI register base address. + * @retval bool RX FIFO is not full or is full. + */ +static inline bool DCL_SPI_GetRxFifoFull(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPISR.BIT.rff; +} + +/** + * @brief Get Whether the SPI is busy. + * @param spix SPI register base address. + * @retval bool SPI is busy or not busy. + */ +static inline bool DCL_SPI_GetBusyFlag(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPISR.BIT.bsy; +} + +/** + * @brief Set the interrupt mask. + * @param spix SPI register base address. + * @param intMask For details, see the register manual. + * @retval None. + */ +static inline void DCL_SPI_SetIntMask(SPI_RegStruct *spix, unsigned int intMask) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + spix->SPIIMSC.reg = intMask; +} + +/** + * @brief Get the interrupt mask. + * @param spix SPI register base address. + * @retval unsigned int interrupt mask. + */ +static inline unsigned int DCL_SPI_GetIntMask(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPIIMSC.reg; +} + +/** + * @brief Get SPIMIS register all mask interrupt status. + * @param spix SPI register base address. + * @retval unsigned short SPIMIS register interrupt mask. + */ +static inline unsigned int DCL_SPI_GetMisInt(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPIMIS.reg; +} + +/** + * @brief Clear RX timeout interrupt + * @param spix SPI register base address. + * @retval None. + */ +static inline void DCL_SPI_ClearRxTimeInt(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + spix->SPIICR.BIT.roric = BASE_CFG_SET; +} + +/** + * @brief Clear RX overflow interrupt + * @param spix SPI register base address. + * @retval None. + */ +static inline void DCL_SPI_ClearRxOverInt(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + spix->SPIICR.BIT.rtic = BASE_CFG_SET; +} + +/** + * @brief Set DMA FIFO enable register. + * @param spix SPI register base address. + * @param dmaCtl control DMA FIFO enable. + * @retval None. + */ +static inline void DCL_SPI_SetDmaTxFifo(SPI_RegStruct *spix, unsigned int dmaCtl) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + spix->SPIDMACR.reg = dmaCtl; +} + +/** + * @brief Get DMA FIFO enable register status. + * @param spix SPI register base address. + * @retval unsigned int DMA Control Register Status. + */ +static inline unsigned int DCL_SPI_GetDmaTxFifo(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPIDMACR.reg; +} + +/** + * @brief Set three-wire/four-wire mode configuration. + * @param spix SPI register base address. + * @param line SPI data line:1-data line and 2-data lines. + * @retval None. + */ +static inline void DCL_SPI_SetDataLine(SPI_RegStruct *spix, SPI_DataLine line) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(line >= SPI_DATA_2LINES && line <= SPI_DATA_1LINE); + spix->SPICR1.BIT.triwire = line; +} + +/** + * @brief Getting three-wire/four-wire mode configuration. + * @param spix SPI register base address. + * @retval SPI_DataLine:SPI_DATA_2LINES or SPI_DATA_1LINE. + */ +static inline SPI_DataLine DCL_SPI_GetDataLine(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR1.BIT.triwire; +} + +/** + * @brief Set data direction in three-wire mode . + * @param spix SPI register base address. + * @param dataDirec SPI data direction:send or recv. + * @retval None. + */ +static inline void DCL_SPI_SetDataDirec(SPI_RegStruct *spix, SPI_DataDirec direc) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + SPI_PARAM_CHECK_NO_RET(direc >= SPI_DATA_DIREC_RECV && direc <= SPI_DATA_DIREC_SEND); + spix->SPICR1.BIT.triwiretxoe = direc; +} + +/** + * @brief Get data direction in three-wire mode. + * @param spix SPI register base address. + * @retval SPI_DataDirec:recv or send. + */ +static inline SPI_DataDirec DCL_SPI_GetDataDirec(SPI_RegStruct *spix) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + return spix->SPICR1.BIT.triwiretxoe; +} + +/** + * @brief Set tx fifo reset. + * @param spix SPI register base address. + * @param txFifoRst true:tx fifo reset;false:tx fifo not reset. + * @retval None. + */ +static inline void DCL_SPI_SetTxFifoRst(SPI_RegStruct *spix, bool txFifoRst) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + spix->SPITXFIFOCR.BIT.txfiforst = (!txFifoRst); +} + +/** + * @brief Set rx fifo reset. + * @param spix SPI register base address. + * @param txFifoRst true:rx fifo reset;false:rx fifo not reset. + * @retval None. + */ +static inline void DCL_SPI_SetRxFifoRst(SPI_RegStruct *spix, bool rxFifoRst) +{ + SPI_ASSERT_PARAM(IsSPIInstance(spix)); + spix->SPIRXFIFOCR.BIT.rxfiforst = (!rxFifoRst); +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* #ifndef McuMagicTag_SPI_IP_H */ \ No newline at end of file diff --git a/src/drivers/spi/spi_v3/src/spi.c b/src/drivers/spi/spi_v3/src/spi.c new file mode 100644 index 0000000000000000000000000000000000000000..93f674f409b062a6269fd718b08a3fa70e0098a9 --- /dev/null +++ b/src/drivers/spi/spi_v3/src/spi.c @@ -0,0 +1,1226 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file spi.c + * @author MCU Driver Team + * @brief SPI module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the SPI. + * + Initialization and de-initialization functions + * + Peripheral Control functions + */ + +/* Includes ------------------------------------------------------------------*/ +#include "interrupt.h" +#include "systick.h" +#include "spi.h" +/* Macro definitions ---------------------------------------------------------*/ +#define SPI_WAIT_TIMEOUT 0x400 +#define SPI_FIFO_DEPTH 16 + +#define SPI_DATA_WIDTH_SHIFT_8BIT 1 +#define SPI_DATA_WIDTH_SHIFT_16BIT 2 + +#define SPI_DATA_SHIFT_8BIT 8 + +#define SPI_INTERRUPT_SET_ALL 0xF + +#define SPI_TICK_MS_DIV 1000 +/** + * @brief Check all initial configuration parameters. + * @param handle SPI handle. + * @retval BASE status type: OK, ERROR. + */ +static BASE_StatusType CheckAllInitParameters(SPI_Handle *handle) +{ + SPI_PARAM_CHECK_WITH_RET(IsSpiMode(handle->mode), BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(IsSpiXferMode(handle->xFerMode), BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(IsSpiEndian(handle->endian), BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(IsSpiFrameFormat(handle->frameFormat), BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(IsSpiDataWidth(handle->dataWidth), BASE_STATUS_ERROR); + /* Check spi freqCpsdvsr */ + if (handle->mode == HAL_SPI_MASTER) { + SPI_PARAM_CHECK_WITH_RET(IsSpiFreqCpsdvsr(handle->freqCpsdvsr), BASE_STATUS_ERROR); + } + /* Check motorola clkPolarity and clkPhase */ + if (handle->frameFormat == HAL_SPI_MODE_MOTOROLA) { + SPI_PARAM_CHECK_WITH_RET(IsSpiClkPolarity(handle->clkPolarity), BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(IsSpiClkPhase(handle->clkPhase), BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(IsSpiLine(handle->handleEx.line), BASE_STATUS_ERROR); + } + /* Check microwire waitVal */ + if (handle->frameFormat == HAL_SPI_MODE_MICROWIRE) { + SPI_PARAM_CHECK_WITH_RET(IsSpiWaitVal(handle->waitVal), BASE_STATUS_ERROR); + } + /* Check tx rx interrupt size */ + if (handle->xFerMode == HAL_XFER_MODE_INTERRUPTS) { + SPI_PARAM_CHECK_WITH_RET(IsSpiTxIntSize(handle->txIntSize), BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(IsSpiRxIntSize(handle->rxIntSize), BASE_STATUS_ERROR); + } + /* Check tx rx dma burst size */ + if (handle->xFerMode == HAL_XFER_MODE_DMA) { + SPI_PARAM_CHECK_WITH_RET(IsSpiTxDmaBurstSize(handle->txDMABurstSize), BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(IsSpiRxDmaBurstSize(handle->rxDMABurstSize), BASE_STATUS_ERROR); + } + return BASE_STATUS_OK; +} + +/** + * @brief Configuring the Register Parameters of the Three Transfer Modes. + * @param handle SPI handle. + * @retval BASE status type: OK, ERROR. + */ +static BASE_StatusType ConfigThreeTransferParam(SPI_Handle *handle) +{ + SPI_ASSERT_PARAM(handle != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + /* Configurations related to the three transmission modes */ + if (handle->xFerMode == HAL_XFER_MODE_BLOCKING) { + handle->baseAddress->SPIIMSC.reg = 0x0; + } else if (handle->xFerMode == HAL_XFER_MODE_INTERRUPTS) { + handle->baseAddress->SPIIMSC.reg = 0x0; + /* Setting the rx and tx interrupt transfer size */ + handle->baseAddress->SPITXFIFOCR.BIT.txintsize = handle->txIntSize; + handle->baseAddress->SPIRXFIFOCR.BIT.rxintsize = handle->rxIntSize; + } else if (handle->xFerMode == HAL_XFER_MODE_DMA) { + handle->baseAddress->SPIIMSC.reg = 0x0; + /* Setting the DMA rx and tx burst transfer size */ + handle->baseAddress->SPITXFIFOCR.BIT.txintsize = handle->txDMABurstSize; + handle->baseAddress->SPIRXFIFOCR.BIT.rxintsize = handle->rxDMABurstSize; + } else { + /* xFerMode set error */ + handle->errorCode = BASE_STATUS_ERROR; + handle->state = HAL_SPI_STATE_RESET; + return BASE_STATUS_ERROR; + } + return BASE_STATUS_OK; +} + +/** + * @brief Internal chip select control. + * @param handle SPI handle. + * @param control SPI_CHIP_DESELECT or SPI_CHIP_SELECT + * @retval None. + */ +static void InternalCsControl(SPI_Handle *handle, unsigned int control) +{ + BASE_FUNC_UNUSED(handle); + BASE_FUNC_UNUSED(control); +} + +/** + * @brief Chip select control. + * @param handle SPI handle. + * @param control SPI_CHIP_DESELECT or SPI_CHIP_SELECT + * @retval None. + */ +static void SpiCsControl(SPI_Handle *handle, unsigned int control) +{ + /* The chip select signal is determined by the chip logic. */ + if (handle->csMode == SPI_CHIP_SELECT_MODE_INTERNAL) { + InternalCsControl(handle, control); + } else { + /* The chip select signal is determined by callback */ + if (handle->userCallBack.CsCtrlCallback != NULL) { + handle->csCtrl = control; + handle->userCallBack.CsCtrlCallback(handle); + } + } +} + +/** + * @brief Invoke rx tx callback function. + * @param handle SPI handle. + * @retval None. + */ +static void SpiRxTxCallbackFunc(void *handle) +{ + SPI_Handle *spiHandle = (SPI_Handle *) handle; + switch (spiHandle->state) { + case HAL_SPI_STATE_BUSY_TX : + /* Invoke tx callback function. */ + if (spiHandle->txCount == spiHandle->transferSize && spiHandle->userCallBack.TxCpltCallback != NULL) { + spiHandle->userCallBack.TxCpltCallback(spiHandle); + } + break; + case HAL_SPI_STATE_BUSY_RX : + /* Invoke rx callback function. */ + if (spiHandle->userCallBack.RxCpltCallback != NULL) { + spiHandle->userCallBack.RxCpltCallback(spiHandle); + } + break; + case HAL_SPI_STATE_BUSY_TX_RX : + /* Invoke tx rx callback function. */ + if (spiHandle->userCallBack.TxRxCpltCallback != NULL) { + spiHandle->userCallBack.TxRxCpltCallback(spiHandle); + } + break; + default : + break; + } +} + +/** + * @brief Tx and Rx complete processing. + * @param handle SPI handle. + * @retval None. + */ +static void SpiRxTxCallback(void *handle) +{ + SPI_Handle *spiHandle = (SPI_Handle *) handle; + SPI_ASSERT_PARAM(spiHandle != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(spiHandle->baseAddress)); + if (spiHandle->txCount == spiHandle->transferSize && spiHandle->baseAddress->SPIIMSC.BIT.txim != 0x0) { + /* Masks the TX interrupt. */ + spiHandle->baseAddress->SPIIMSC.BIT.txim = 0x0; + } + + if (spiHandle->rxCount >= spiHandle->transferSize) { + /* Disable all interrupt */ + spiHandle->baseAddress->SPIIMSC.reg = 0x0; + /* Clear all interrupt */ + spiHandle->baseAddress->SPIICR.BIT.roric = BASE_CFG_SET; + spiHandle->baseAddress->SPIICR.BIT.rtic = BASE_CFG_SET; + + SpiCsControl(spiHandle, SPI_CHIP_DESELECT); + + /* RX or TX callback after cs desselect. */ + SpiRxTxCallbackFunc(spiHandle); + spiHandle->state = HAL_SPI_STATE_READY; + } +} + +/** + * @brief Writes data from the buffer to the FIFO. + * @param handle SPI handle. + * @retval None. + */ +static void WriteData(SPI_Handle *handle) +{ + while (handle->baseAddress->SPISR.BIT.tnf && (handle->txCount - handle->rxCount) < SPI_FIFO_DEPTH && + (handle->transferSize > handle->txCount)) { + if (handle->dataWidth > SPI_DATA_WIDTH_8BIT) { + /* Only data needs to be read. Due to SPI characteristics, + data must be transmitted before data can be read. Therefore, 0x0 is transmitted. */ + if (handle->txBuff == NULL) { + handle->baseAddress->SPIDR.reg = 0x0; + handle->txCount += SPI_DATA_WIDTH_SHIFT_16BIT; + } else { + unsigned short txData = *handle->txBuff; + handle->txBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + unsigned short temp = *handle->txBuff; + handle->txBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + txData += (temp << SPI_DATA_SHIFT_8BIT); + handle->baseAddress->SPIDR.reg = txData; /* Write data to register. */ + handle->txCount += SPI_DATA_WIDTH_SHIFT_16BIT; /* txCount is number of bytes transferred. */ + } + } else { /* datawidth is 8bit */ + if (handle->txBuff == NULL) { + handle->baseAddress->SPIDR.reg = 0x0; + handle->txCount += SPI_DATA_WIDTH_SHIFT_8BIT; + } else { + handle->baseAddress->SPIDR.reg = *(unsigned char *)handle->txBuff; + handle->txCount += SPI_DATA_WIDTH_SHIFT_8BIT; /* txCount is number of bytes transferred */ + handle->txBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + } + } + } +} + +/** + * @brief Reads data from the FIFO to the buffer. + * @param handle SPI handle. + * @retval None. + */ +static void ReadData(SPI_Handle *handle) +{ + unsigned short val; + + while (handle->baseAddress->SPISR.BIT.rne && (handle->transferSize > handle->rxCount)) { + if (handle->dataWidth > SPI_DATA_WIDTH_8BIT) { + /* When only data is transmitted, the data in the RX FIFO needs to be read. */ + if (handle->rxBuff == NULL) { + val = handle->baseAddress->SPIDR.reg; + BASE_FUNC_UNUSED(val); + handle->rxCount += SPI_DATA_WIDTH_SHIFT_16BIT; + } else { + unsigned short rxData = handle->baseAddress->SPIDR.reg; /* Read data from register. */ + *handle->rxBuff = rxData; + handle->rxBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + *handle->rxBuff = (rxData >> SPI_DATA_SHIFT_8BIT); + handle->rxBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + handle->rxCount += SPI_DATA_WIDTH_SHIFT_16BIT; /* rxCount is number of bytes received. */ + } + } else { /* datawidth is 8bit */ + if (handle->rxBuff == NULL) { + val = handle->baseAddress->SPIDR.reg; + BASE_FUNC_UNUSED(val); + handle->rxCount += SPI_DATA_WIDTH_SHIFT_8BIT; + } else { + *(unsigned char *)handle->rxBuff = handle->baseAddress->SPIDR.reg & 0xff; + handle->rxCount += SPI_DATA_WIDTH_SHIFT_8BIT; /* rxCount is number of bytes received. */ + handle->rxBuff += SPI_DATA_WIDTH_SHIFT_8BIT; + } + } + } +} + +/** + * @brief Read/write based on input parameters. + * The Motorola SPI/TI synchronous serial interface is full-duplex. + * Each data is received. Even if only data needs to be transmitted, + * the RX FIFO needs to be cleared. + * @param handle SPI handle. + * @retval None. + */ +static void ReadWriteData(SPI_Handle *handle) +{ + unsigned int preTick = DCL_SYSTICK_GetTick(); + unsigned int curTick = preTick; + unsigned long long delta = 0; + /* Calculate the timeout tick. */ + unsigned long long targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SPI_TICK_MS_DIV * SPI_WAIT_TIMEOUT; + WriteData(handle); + while (true) { + /* Wait for the write operation to complete */ + if (handle->baseAddress->SPISR.BIT.rne == BASE_CFG_SET) { + break; + } + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + /* Exit upon timeout */ + if (delta >= targetDelta) { + handle->errorCode = BASE_STATUS_TIMEOUT; + break; + } + preTick = curTick; + } + ReadData(handle); +} + +/** + * @brief Blocking read data processing. + * @param handle SPI handle. + * @param timeout Timeout period,unit: ms. + * @retval None. + */ +static void ReadBlocking(SPI_Handle *handle, unsigned int timeout) +{ + unsigned int preTick = DCL_SYSTICK_GetTick(); + unsigned int curTick = preTick; + unsigned long long delta = 0; + unsigned long long targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SPI_TICK_MS_DIV * timeout; + + /* Pull down the CS before transmitting data. */ + SpiCsControl(handle, SPI_CHIP_SELECT); + if (!handle->baseAddress->SPICR1.BIT.sse) { + handle->baseAddress->SPICR1.BIT.sse = BASE_CFG_SET; /* spi enable */ + } + while (handle->transferSize > handle->rxCount) { + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* The configured timeout period is exceeded. */ + handle->errorCode = BASE_STATUS_TIMEOUT; + break; + } + ReadData(handle); + preTick = curTick; + } + /* Pull up the CS after transmitting data. */ + SpiCsControl(handle, SPI_CHIP_DESELECT); + handle->state = HAL_SPI_STATE_READY; +} + +/** + * @brief Blocking read/write data processing. + * @param handle SPI handle. + * @param timeout Timeout period,unit: ms. + * @retval None. + */ +static void ReadWriteBlocking(SPI_Handle *handle, unsigned int timeout) +{ + unsigned int preTick = DCL_SYSTICK_GetTick(); + unsigned int curTick = preTick; + unsigned long long delta = 0; + unsigned long long targetDelta = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SPI_TICK_MS_DIV * timeout; + /* Pull down the CS before transmitting data. */ + SpiCsControl(handle, SPI_CHIP_SELECT); + if (!handle->baseAddress->SPICR1.BIT.sse) { + handle->baseAddress->SPICR1.BIT.sse = BASE_CFG_SET; /* spi enable */ + } + while (handle->transferSize > handle->txCount || handle->transferSize > handle->rxCount) { + curTick = DCL_SYSTICK_GetTick(); + delta += curTick > preTick ? curTick - preTick : SYSTICK_MAX_VALUE - preTick + curTick; + if (delta >= targetDelta) { /* The configured timeout period is exceeded. */ + handle->errorCode = BASE_STATUS_TIMEOUT; + break; + } + ReadWriteData(handle); + preTick = curTick; + } + /* Pull up the CS after transmitting data. */ + SpiCsControl(handle, SPI_CHIP_DESELECT); + handle->state = HAL_SPI_STATE_READY; +} + +/** + * @brief SPI read/write parameter configuration. + * @param handle SPI handle. + * @param rData Address of the data buff to be Receiving. + * @param wData Address of the data buff to be sent. + * @param dataSiz Number of the data to be Receivingd and sent. + * @retval None. + */ +static void ConfigTransmissionParameter(SPI_Handle *handle, + unsigned char *rData, + unsigned char *wData, + unsigned int dataSize) +{ + handle->errorCode = BASE_STATUS_OK; + handle->rxBuff = rData; + handle->txBuff = wData; + if (handle->dataWidth > SPI_DATA_WIDTH_8BIT && + handle->xFerMode == HAL_XFER_MODE_DMA) { + handle->transferSize = dataSize / 2; /* Processes 2 bytes at a time */ + } else { + handle->transferSize = dataSize; + } + handle->txCount = 0; + handle->rxCount = 0; +} + +/** + * @brief SPI Setting Motorola and Microwire frame format parameters. + * @param handle SPI handle. + * @retval None. + */ +static void ConfigMotorAndMicroParam(SPI_Handle *handle) +{ + if ((handle->frameFormat == HAL_SPI_MODE_MOTOROLA) && (handle->handleEx.line == SPI_DATA_1LINE)) { + handle->baseAddress->SPICR1.BIT.triwire = BASE_CFG_SET; + } else { + handle->baseAddress->SPICR1.BIT.triwire = BASE_CFG_UNSET; + } + /* Indicates whether to enable the Microwire wait period. */ + if ((handle->frameFormat == HAL_SPI_MODE_MICROWIRE) && (handle->waitEn == BASE_CFG_ENABLE)) { + handle->baseAddress->SPICR1.BIT.waitval = handle->waitVal; + handle->baseAddress->SPICR1.BIT.waiten = BASE_CFG_SET; + } else { + handle->baseAddress->SPICR1.BIT.waiten = BASE_CFG_UNSET; + } +} + +/** + * @brief Initializing the SPI Module. + * @param handle SPI handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_Init(SPI_Handle *handle) +{ + unsigned int cr0Reg; + unsigned int temp; + unsigned char frCps; + SPI_ASSERT_PARAM(handle != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + /* Check whether initialization parameters are correctly set */ + if (CheckAllInitParameters(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + handle->state = HAL_SPI_STATE_BUSY; + handle->baseAddress->SPICR1.BIT.lbm = BASE_CFG_UNSET; + handle->baseAddress->SPICR1.BIT.sse = BASE_CFG_UNSET; + handle->baseAddress->SPICR1.BIT.bitend = handle->endian; /* Setting the endian mode */ + handle->baseAddress->SPICR1.BIT.ms = handle->mode; + + temp = ((unsigned int)handle->freqScr) << SPI_CR0_SCR_POS; + cr0Reg = (handle->baseAddress->SPICR0.reg & (~SPI_CR0_SCR_MASK)) | temp; + handle->baseAddress->SPICR0.reg = cr0Reg; + /* Modulo 2 to get an even number */ + if (handle->mode == HAL_SPI_MASTER) { + frCps = handle->freqCpsdvsr; + /* Modulo 2 to get an even number */ + handle->baseAddress->SPICPSR.BIT.cpsdvsr = ((frCps % 2) == 0 ? frCps : frCps - 1); + } + + if (handle->frameFormat == HAL_SPI_MODE_MOTOROLA) { + handle->baseAddress->SPICR0.BIT.sph = handle->clkPhase; + handle->baseAddress->SPICR0.BIT.spo = handle->clkPolarity; + } + + handle->baseAddress->SPICR0.BIT.frf = handle->frameFormat; + handle->baseAddress->SPICR0.BIT.dss = handle->dataWidth; + + ConfigMotorAndMicroParam(handle); + if (ConfigThreeTransferParam(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + handle->state = HAL_SPI_STATE_READY; + return BASE_STATUS_OK; +} + +/** + * @brief Deinitialize the SPI module. + * @param handle SPI handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_Deinit(SPI_Handle *handle) +{ + SPI_ASSERT_PARAM(handle != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + + handle->state = HAL_SPI_STATE_BUSY; + + /* Disable rx and tx DMA, SPI disable */ + handle->baseAddress->SPIIMSC.reg = 0x0; + handle->baseAddress->SPIDMACR.BIT.rxdmae = BASE_CFG_UNSET; + handle->baseAddress->SPIDMACR.BIT.txdmae = BASE_CFG_UNSET; + handle->baseAddress->SPICR1.BIT.sse = BASE_CFG_UNSET; + handle->state = HAL_SPI_STATE_RESET; + /* Clean callback */ + handle->userCallBack.TxCpltCallback = NULL; + handle->userCallBack.RxCpltCallback = NULL; + handle->userCallBack.TxRxCpltCallback = NULL; + handle->userCallBack.ErrorCallback = NULL; + handle->userCallBack.CsCtrlCallback = NULL; + return BASE_STATUS_OK; +} + +/** + * @brief SPI Parameter Configuration. + * @param handle SPI handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_ConfigParameter(SPI_Handle *handle) +{ + unsigned int cr0Reg; + unsigned int temp; + unsigned char frCps; + SPI_ASSERT_PARAM(handle != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + if (CheckAllInitParameters(handle) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + + handle->baseAddress->SPICR1.BIT.sse = BASE_CFG_UNSET; + handle->baseAddress->SPICR1.BIT.ms = handle->mode; + handle->baseAddress->SPICR0.BIT.frf = handle->frameFormat; + handle->baseAddress->SPICR0.BIT.dss = handle->dataWidth; + handle->baseAddress->SPICR1.BIT.bitend = handle->endian; + /* Set freqScr */ + temp = ((unsigned int)handle->freqScr) << SPI_CR0_SCR_POS; + cr0Reg = (handle->baseAddress->SPICR0.reg & (~SPI_CR0_SCR_MASK)) | temp; + handle->baseAddress->SPICR0.reg = cr0Reg; + + /* Modulo 2 to get an even number */ + if (handle->mode == HAL_SPI_MASTER) { + frCps = handle->freqCpsdvsr; + /* Modulo 2 to get an even number */ + handle->baseAddress->SPICPSR.BIT.cpsdvsr = ((frCps % 2) == 0 ? frCps : frCps - 1); + } + + if (handle->frameFormat == HAL_SPI_MODE_MOTOROLA) { + handle->baseAddress->SPICR0.BIT.sph = handle->clkPhase; + handle->baseAddress->SPICR0.BIT.spo = handle->clkPolarity; + } + /* Setting the Interrupt Thresholds */ + if (handle->xFerMode == HAL_XFER_MODE_INTERRUPTS) { + handle->baseAddress->SPITXFIFOCR.BIT.txintsize = handle->txIntSize; + handle->baseAddress->SPIRXFIFOCR.BIT.rxintsize = handle->rxIntSize; + } else if (handle->xFerMode == HAL_XFER_MODE_DMA) { + handle->baseAddress->SPITXFIFOCR.BIT.txintsize = handle->txDMABurstSize; + handle->baseAddress->SPIRXFIFOCR.BIT.rxintsize = handle->rxDMABurstSize; + } else { + ; + } + ConfigMotorAndMicroParam(handle); + return BASE_STATUS_OK; +} + +/** + * @brief Callback Function Registration. + * @param handle SPI handle. + * @param callbackID Callback function ID.. + * @param pcallback Pointer to the address of the registered callback function. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_RegisterCallback(SPI_Handle *handle, + HAL_SPI_CallbackID callbackID, + SPI_CallbackFuncType pcallback) +{ + BASE_StatusType ret = BASE_STATUS_OK; + SPI_ASSERT_PARAM(handle != NULL && pcallback != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + + if (handle->state == HAL_SPI_STATE_READY) { + switch (callbackID) { + case SPI_TX_COMPLETE_CB_ID : + handle->userCallBack.TxCpltCallback = pcallback; + break; + case SPI_RX_COMPLETE_CB_ID : + handle->userCallBack.RxCpltCallback = pcallback; + break; + case SPI_TX_RX_COMPLETE_CB_ID : + handle->userCallBack.TxRxCpltCallback = pcallback; + break; + case SPI_ERROR_CB_ID : + handle->userCallBack.ErrorCallback = pcallback; + break; + case SPI_CS_CB_ID: + handle->userCallBack.CsCtrlCallback = pcallback; + break; + default : + handle->errorCode = BASE_STATUS_ERROR; + ret = BASE_STATUS_ERROR; + break; + } + } else { + handle->errorCode = BASE_STATUS_ERROR; + ret = BASE_STATUS_ERROR; + } + return ret; +} + +/** + * @brief Receiving data in blocking mode. + * @param handle SPI handle. + * @param rData Address of the data buff to be Receiving. + * @param dataSize Number of the data to be Receiving. + * @param timeout Timeout period,unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_ReadBlocking(SPI_Handle *handle, + unsigned char *rData, + unsigned int dataSize, + unsigned int timeout) +{ + SPI_ASSERT_PARAM(handle != NULL && rData != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + SPI_PARAM_CHECK_WITH_RET(handle->state == HAL_SPI_STATE_READY, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + + handle->state = HAL_SPI_STATE_BUSY_RX; + /* Configuring SPI transmission parameters */ + ConfigTransmissionParameter(handle, rData, NULL, dataSize); + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_SET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_SET; + + if (handle->handleEx.line == SPI_DATA_1LINE && handle->frameFormat == HAL_SPI_MODE_MOTOROLA) { + handle->baseAddress->SPICR1.BIT.triwiretxoe = BASE_CFG_UNSET; + } + if (handle->mode == HAL_SPI_MASTER) { + ReadWriteBlocking(handle, timeout); + } else { + ReadBlocking(handle, timeout); + } + + if (handle->errorCode != BASE_STATUS_OK) { + if (handle->userCallBack.ErrorCallback != NULL) { + handle->userCallBack.ErrorCallback(handle); + } + return handle->errorCode; + } + if (handle->userCallBack.RxCpltCallback != NULL) { + handle->userCallBack.RxCpltCallback(handle); + } + return BASE_STATUS_OK; +} + +/** + * @brief Send data in blocking mode. + * @param handle SPI handle. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be sent. + * @param timeout Timeout period,unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_WriteBlocking(SPI_Handle *handle, + unsigned char *wData, + unsigned int dataSize, + unsigned int timeout) +{ + SPI_ASSERT_PARAM(handle != NULL && wData != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + + SPI_PARAM_CHECK_WITH_RET(handle->state == HAL_SPI_STATE_READY, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + + handle->state = HAL_SPI_STATE_BUSY_TX; + /* Configuring SPI transmission parameters */ + ConfigTransmissionParameter(handle, NULL, wData, dataSize); + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_SET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_SET; + + if (handle->handleEx.line == SPI_DATA_1LINE && handle->frameFormat == HAL_SPI_MODE_MOTOROLA) { + handle->baseAddress->SPICR1.BIT.triwiretxoe = BASE_CFG_SET; + } + + ReadWriteBlocking(handle, timeout); + if (handle->errorCode != BASE_STATUS_OK) { + if (handle->userCallBack.ErrorCallback != NULL) { + handle->userCallBack.ErrorCallback(handle); + } + return handle->errorCode; + } + if (handle->userCallBack.TxCpltCallback != NULL) { + handle->userCallBack.TxCpltCallback(handle); + } + return BASE_STATUS_OK; +} + +/** + * @brief Receiving and send data in blocking mode. + * @param handle SPI handle. + * @param rData Address of the data buff to be Receiving. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be Receivingd and sent. + * @param timeout Timeout period,unit: ms. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_WriteReadBlocking(SPI_Handle *handle, + unsigned char *rData, + unsigned char *wData, + unsigned int dataSize, + unsigned int timeout) +{ + SPI_ASSERT_PARAM(handle != NULL && rData != NULL && wData != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + + SPI_PARAM_CHECK_WITH_RET(handle->state == HAL_SPI_STATE_READY, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + if (handle->frameFormat == HAL_SPI_MODE_MOTOROLA && handle->handleEx.line != SPI_DATA_2LINES) { + return BASE_STATUS_ERROR; + } + handle->state = HAL_SPI_STATE_BUSY_TX_RX; + /* Configuring SPI transmission parameters */ + ConfigTransmissionParameter(handle, rData, wData, dataSize); + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_SET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_SET; + ReadWriteBlocking(handle, timeout); + if (handle->errorCode != BASE_STATUS_OK) { + if (handle->userCallBack.ErrorCallback != NULL) { + handle->userCallBack.ErrorCallback(handle); + } + return handle->errorCode; + } + if (handle->userCallBack.TxRxCpltCallback != NULL) { + handle->userCallBack.TxRxCpltCallback(handle); + } + return BASE_STATUS_OK; +} + +/** + * @brief Receiving data in interrupts mode. + * @param handle SPI handle. + * @param rData Address of the data buff to be Receiving. + * @param dataSize Number of the data to be Receiving. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_ReadIT(SPI_Handle *handle, unsigned char *rData, unsigned int dataSize) +{ + SPI_ASSERT_PARAM(handle != NULL && rData != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + + SPI_PARAM_CHECK_WITH_RET(handle->state == HAL_SPI_STATE_READY, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_SET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_SET; + handle->state = HAL_SPI_STATE_BUSY_RX; + ConfigTransmissionParameter(handle, rData, NULL, dataSize); + + if (handle->handleEx.line == SPI_DATA_1LINE && handle->frameFormat == HAL_SPI_MODE_MOTOROLA) { + handle->baseAddress->SPICR1.BIT.triwiretxoe = BASE_CFG_UNSET; + } + SpiCsControl(handle, SPI_CHIP_SELECT); + if (!handle->baseAddress->SPICR1.BIT.sse) { + handle->baseAddress->SPICR1.BIT.sse = BASE_CFG_SET; + } + /* Enable related interrupts. */ + if (handle->mode == HAL_SPI_MASTER) { + handle->baseAddress->SPIIMSC.reg = 0x0F; /* 0x0F Enable read/write and overflow interrupts. */ + } else { + handle->baseAddress->SPIIMSC.reg = 0x07; /* 0x07 Enable read and overflow interrupts. */ + } + return BASE_STATUS_OK; +} + +/** + * @brief Send data in interrupts mode. + * @param handle SPI handle. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_WriteIT(SPI_Handle *handle, unsigned char *wData, unsigned int dataSize) +{ + SPI_ASSERT_PARAM(handle != NULL && wData != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + + SPI_PARAM_CHECK_WITH_RET(handle->state == HAL_SPI_STATE_READY, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_SET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_SET; + handle->state = HAL_SPI_STATE_BUSY_TX; + ConfigTransmissionParameter(handle, NULL, wData, dataSize); + + if (handle->handleEx.line == SPI_DATA_1LINE && handle->frameFormat == HAL_SPI_MODE_MOTOROLA) { + handle->baseAddress->SPICR1.BIT.triwiretxoe = BASE_CFG_SET; + } + /* interrupt enable */ + SpiCsControl(handle, SPI_CHIP_SELECT); + if (!handle->baseAddress->SPICR1.BIT.sse) { + handle->baseAddress->SPICR1.BIT.sse = BASE_CFG_SET; + } + /* 0x0F Enable read/write and overflow interrupts. */ + handle->baseAddress->SPIIMSC.reg = 0x0F; + + return BASE_STATUS_OK; +} + +/** + * @brief Receiving and send data in interrupts mode. + * @param handle SPI handle. + * @param rData Address of the data buff to be Receiving. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be Receiving and sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_WriteReadIT(SPI_Handle *handle, + unsigned char *rData, + unsigned char *wData, + unsigned int dataSize) +{ + SPI_ASSERT_PARAM(handle != NULL && rData != NULL && wData != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + + SPI_PARAM_CHECK_WITH_RET(handle->state == HAL_SPI_STATE_READY, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_SET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_SET; + if (handle->frameFormat == HAL_SPI_MODE_MOTOROLA && handle->handleEx.line != SPI_DATA_2LINES) { + return BASE_STATUS_ERROR; + } + handle->state = HAL_SPI_STATE_BUSY_TX_RX; + ConfigTransmissionParameter(handle, rData, wData, dataSize); + + SpiCsControl(handle, SPI_CHIP_SELECT); + if (!handle->baseAddress->SPICR1.BIT.sse) { + handle->baseAddress->SPICR1.BIT.sse = BASE_CFG_SET; + } + /* 0x0F Enable read/write and overflow interrupts. */ + handle->baseAddress->SPIIMSC.reg = 0x0F; + + return BASE_STATUS_OK; +} + +/** + * @brief Wait until the SPI data transmission is complete. + * @param handle SPI handle. + * @retval None. + */ +static void WaitComplete(void *handle) +{ + SPI_ASSERT_PARAM(handle != NULL); + SPI_Handle *spiHandle = (SPI_Handle *)(handle); + SPI_ASSERT_PARAM(IsSPIInstance(spiHandle->baseAddress)); + while (true) { + /* Wait for the write operation to complete */ + if (spiHandle->baseAddress->SPISR.BIT.bsy == BASE_CFG_UNSET && + spiHandle->baseAddress->SPISR.BIT.tfe == BASE_CFG_SET && + spiHandle->baseAddress->SPISR.BIT.rne == BASE_CFG_UNSET) { + break; + } + } +} + +/** + * @brief SPI DMA read completion callback function. + * @param handle SPI handle. + * @retval None + */ +static void ReadDmaFinishFun(void *handle) +{ + SPI_ASSERT_PARAM(handle != NULL); + SPI_Handle *spiHandle = (SPI_Handle *)(handle); + SPI_ASSERT_PARAM(IsSPIInstance(spiHandle->baseAddress)); + /* Waiting for SPI data transfer to complete */ + WaitComplete(spiHandle); + SpiCsControl(spiHandle, SPI_CHIP_DESELECT); + + if (spiHandle->state == HAL_SPI_STATE_BUSY_RX) { + if (spiHandle->userCallBack.RxCpltCallback != NULL) { + spiHandle->userCallBack.RxCpltCallback(spiHandle); + } + } + + if (spiHandle->state == HAL_SPI_STATE_BUSY_TX_RX) { + if (spiHandle->userCallBack.TxRxCpltCallback != NULL) { + spiHandle->userCallBack.TxRxCpltCallback(spiHandle); + } + } + + if (spiHandle->state == HAL_SPI_STATE_BUSY_TX) { + if (spiHandle->userCallBack.TxCpltCallback != NULL) { + spiHandle->userCallBack.TxCpltCallback(spiHandle); + } + } + + spiHandle->state = HAL_SPI_STATE_READY; + /* Disable rx fifo DMA */ + spiHandle->baseAddress->SPIDMACR.BIT.rxdmae = BASE_CFG_UNSET; +} + +/** + * @brief SPI DMA write completion callback function. + * @param handle SPI handle. + * @retval None + */ +static void WriteDmaFinishFun(void *handle) +{ + SPI_ASSERT_PARAM(handle != NULL); + SPI_Handle *spiHandle = (SPI_Handle *)(handle); + SPI_ASSERT_PARAM(IsSPIInstance(spiHandle->baseAddress)); + /* Waiting for SPI data transfer to complete */ + WaitComplete(spiHandle); + SpiCsControl(spiHandle, SPI_CHIP_DESELECT); + /* Disable tx fifo DMA */ + spiHandle->baseAddress->SPIDMACR.BIT.txdmae = BASE_CFG_UNSET; + if (spiHandle->userCallBack.TxCpltCallback != NULL && spiHandle->state == HAL_SPI_STATE_READY) { + spiHandle->userCallBack.TxCpltCallback(spiHandle); + } + if (spiHandle->frameFormat == HAL_SPI_MODE_MICROWIRE) { + spiHandle->state = HAL_SPI_STATE_READY; + } +} + +/** + * @brief SPI DMA error callback function. + * @param handle SPI handle. + * @retval None + */ +static void DmaErrorFun(void *handle) +{ + SPI_ASSERT_PARAM(handle != NULL); + SPI_Handle *spiHandle = (SPI_Handle *)(handle); + SPI_ASSERT_PARAM(IsSPIInstance(spiHandle->baseAddress)); + SpiCsControl(spiHandle, SPI_CHIP_DESELECT); + /* Disable rx and tx fifo DMA */ + spiHandle->baseAddress->SPIDMACR.reg = 0; + + if (spiHandle->userCallBack.ErrorCallback != NULL) { + spiHandle->userCallBack.ErrorCallback(spiHandle); + } + spiHandle->state = HAL_SPI_STATE_READY; +} + +/** + * @brief DMA enable Configuration. + * @param handle SPI handle. + * @retval None + */ +static void EnableDma(SPI_Handle *handle) +{ + handle->baseAddress->SPIIMSC.reg = 0x0; + SpiCsControl(handle, SPI_CHIP_SELECT); + if (!handle->baseAddress->SPICR1.BIT.sse) { + handle->baseAddress->SPICR1.BIT.sse = BASE_CFG_SET; + } + handle->baseAddress->SPIDMACR.BIT.txdmae = BASE_CFG_ENABLE; + handle->baseAddress->SPIDMACR.BIT.rxdmae = BASE_CFG_ENABLE; +} + +/** + * @brief SPI read and write configures the DMA for channel callback functions. + * @param handle SPI handle. + * @retval None + */ +static void SetDmaCallBack(SPI_Handle *handle) +{ + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->rxDmaCh].ChannelFinishCallBack = ReadDmaFinishFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->rxDmaCh].ChannelErrorCallBack = DmaErrorFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelFinishCallBack = WriteDmaFinishFun; + handle->dmaHandle->userCallBack.DMA_CallbackFuns[handle->txDmaCh].ChannelErrorCallBack = DmaErrorFun; +} + +/** + * @brief Receiving data in DMA mode. + * @param handle SPI handle. + * @param rData Address of the data buff to be Receiving. + * @param dataSize Number of the data to be Receiving. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_ReadDMA(SPI_Handle *handle, unsigned char *rData, unsigned int dataSize) +{ + static unsigned short writeVal = 0; + BASE_StatusType ret; + + SPI_ASSERT_PARAM(handle != NULL && rData != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + SPI_PARAM_CHECK_WITH_RET(handle->txDmaCh < CHANNEL_MAX_NUM, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(handle->rxDmaCh < CHANNEL_MAX_NUM, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(handle->state == HAL_SPI_STATE_READY, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + + handle->state = HAL_SPI_STATE_BUSY_RX; + if (handle->handleEx.line == SPI_DATA_1LINE && handle->frameFormat == HAL_SPI_MODE_MOTOROLA) { + handle->baseAddress->SPICR1.BIT.triwiretxoe = BASE_CFG_UNSET; + } + /* Configuring SPI transmission parameters */ + ConfigTransmissionParameter(handle, rData, NULL, dataSize); + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_SET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_SET; + SetDmaCallBack(handle); + /* To set the auto-increment mode of the source and destination addresses */ + handle->dmaHandle->DMA_Channels[handle->rxDmaCh].srcAddrInc = DMA_ADDR_UNALTERED; + handle->dmaHandle->DMA_Channels[handle->rxDmaCh].destAddrInc = DMA_ADDR_INCREASE; + handle->dmaHandle->DMA_Channels[handle->txDmaCh].srcAddrInc = DMA_ADDR_UNALTERED; + handle->dmaHandle->DMA_Channels[handle->txDmaCh].destAddrInc = DMA_ADDR_UNALTERED; + + /* DMA rx channel Interrupt Transfer */ + ret = HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)&(handle->baseAddress->SPIDR.reg), + (uintptr_t)handle->rxBuff, handle->transferSize, handle->rxDmaCh); + if (ret != BASE_STATUS_OK) { + handle->state = HAL_SPI_STATE_READY; + return ret; + } + /* DMA tx channel Interrupt Transfer */ + if (handle->mode == HAL_SPI_MASTER) { + ret = HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)&writeVal, (uintptr_t)&(handle->baseAddress->SPIDR.reg), + handle->transferSize, handle->txDmaCh); + if (ret != BASE_STATUS_OK) { + handle->state = HAL_SPI_STATE_READY; + return ret; + } + } + EnableDma(handle); + return ret; +} + +/** + * @brief Send data in DMA mode. + * @param handle SPI handle. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_WriteDMA(SPI_Handle *handle, unsigned char *wData, unsigned int dataSize) +{ + static unsigned short readVal; + BASE_StatusType ret; + + SPI_ASSERT_PARAM(handle != NULL && wData != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + SPI_PARAM_CHECK_WITH_RET(handle->txDmaCh < CHANNEL_MAX_NUM, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(handle->rxDmaCh < CHANNEL_MAX_NUM, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(handle->state == HAL_SPI_STATE_READY, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + + handle->state = HAL_SPI_STATE_BUSY_TX; + if (handle->handleEx.line == SPI_DATA_1LINE && handle->frameFormat == HAL_SPI_MODE_MOTOROLA) { + handle->baseAddress->SPICR1.BIT.triwiretxoe = BASE_CFG_SET; + } + /* Configuring SPI transmission parameters */ + ConfigTransmissionParameter(handle, NULL, wData, dataSize); + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_SET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_SET; + SetDmaCallBack(handle); + /* To set the auto-increment mode of the source and destination addresses */ + handle->dmaHandle->DMA_Channels[handle->rxDmaCh].srcAddrInc = DMA_ADDR_UNALTERED; + handle->dmaHandle->DMA_Channels[handle->rxDmaCh].destAddrInc = DMA_ADDR_UNALTERED; + handle->dmaHandle->DMA_Channels[handle->txDmaCh].srcAddrInc = DMA_ADDR_INCREASE; + handle->dmaHandle->DMA_Channels[handle->txDmaCh].destAddrInc = DMA_ADDR_UNALTERED; + /* DMA rx channel Interrupt Transfer */ + ret = HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)&(handle->baseAddress->SPIDR.reg), + (uintptr_t)&readVal, handle->transferSize, handle->rxDmaCh); + if (ret != BASE_STATUS_OK) { + handle->state = HAL_SPI_STATE_READY; + return ret; + } + /* DMA tx channel Interrupt Transfer */ + ret = HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)handle->txBuff, + (uintptr_t)&(handle->baseAddress->SPIDR.reg), handle->transferSize, handle->txDmaCh); + if (ret != BASE_STATUS_OK) { + handle->state = HAL_SPI_STATE_READY; + return ret; + } + EnableDma(handle); + return ret; +} + +/** + * @brief Receiving and send data in DMA mode. + * @param handle SPI handle. + * @param rData Address of the data buff to be Receiving. + * @param wData Address of the data buff to be sent. + * @param dataSize Number of the data to be Receiving and sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_WriteReadDMA(SPI_Handle *handle, + unsigned char *rData, + unsigned char *wData, + unsigned int dataSize) +{ + BASE_StatusType ret; + + SPI_ASSERT_PARAM(handle != NULL && rData != NULL && wData != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + SPI_PARAM_CHECK_WITH_RET(handle->txDmaCh < CHANNEL_MAX_NUM, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(handle->rxDmaCh < CHANNEL_MAX_NUM, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(handle->state == HAL_SPI_STATE_READY, BASE_STATUS_ERROR); + SPI_PARAM_CHECK_WITH_RET(dataSize > 0, BASE_STATUS_ERROR); + if (handle->frameFormat == HAL_SPI_MODE_MOTOROLA && handle->handleEx.line != SPI_DATA_2LINES) { + return BASE_STATUS_ERROR; + } + handle->state = HAL_SPI_STATE_BUSY_TX_RX; + /* Configuring SPI transmission parameters */ + ConfigTransmissionParameter(handle, rData, wData, dataSize); + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPITXFIFOCR.BIT.txfiforst = BASE_CFG_SET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_UNSET; + handle->baseAddress->SPIRXFIFOCR.BIT.rxfiforst = BASE_CFG_SET; + SetDmaCallBack(handle); + /* To set the auto-increment mode of the source and destination addresses */ + handle->dmaHandle->DMA_Channels[handle->rxDmaCh].srcAddrInc = DMA_ADDR_UNALTERED; + handle->dmaHandle->DMA_Channels[handle->rxDmaCh].destAddrInc = DMA_ADDR_INCREASE; + handle->dmaHandle->DMA_Channels[handle->txDmaCh].srcAddrInc = DMA_ADDR_INCREASE; + handle->dmaHandle->DMA_Channels[handle->txDmaCh].destAddrInc = DMA_ADDR_UNALTERED; + /* DMA rx channel Interrupt Transfer */ + ret = HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)&(handle->baseAddress->SPIDR.reg), + (uintptr_t)handle->rxBuff, handle->transferSize, handle->rxDmaCh); + if (ret != BASE_STATUS_OK) { + handle->state = HAL_SPI_STATE_READY; + return ret; + } + /* DMA tx channel Interrupt Transfer */ + ret = HAL_DMA_StartIT(handle->dmaHandle, (uintptr_t)handle->txBuff, + (uintptr_t)&(handle->baseAddress->SPIDR.reg), handle->transferSize, handle->txDmaCh); + if (ret != BASE_STATUS_OK) { + handle->state = HAL_SPI_STATE_READY; + return ret; + } + EnableDma(handle); + return ret; +} + +/** + * @brief Stop DMA transfer. + * @param handle SPI handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_DMAStop(SPI_Handle *handle) +{ + SPI_ASSERT_PARAM(handle != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + BASE_StatusType ret; + + ret = HAL_DMA_StopChannel(handle->dmaHandle, handle->txDmaCh); + if (ret != BASE_STATUS_OK) { + return ret; + } + ret = HAL_DMA_StopChannel(handle->dmaHandle, handle->rxDmaCh); + return ret; +} + +/** + * @brief CS Channel Configuration. + * @param handle SPI handle. + * @param channel SPI CS channel.For details, see the enumeration definition of SPI_ChipSelectChannel. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_SPI_ChipSelectChannelSet(SPI_Handle *handle, SPI_ChipSelectChannel channel) +{ + SPI_ASSERT_PARAM(handle != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + /* Check the validity of the CS parameters. */ + SPI_PARAM_CHECK_WITH_RET(channel >= SPI_CHIP_SELECT_CHANNEL_0 && channel < SPI_CHIP_SELECT_CHANNEL_MAX, + BASE_STATUS_ERROR); + handle->baseAddress->SPICSNCR.BIT.spi_csn_sel = channel; + return BASE_STATUS_OK; +} + +/** + * @brief Obtains the currently configured CS channel. + * @param handle SPI handle. + * @param channel Pointer to the address for storing the obtained CS channel value. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_SPI_ChipSelectChannelGet(SPI_Handle *handle, SPI_ChipSelectChannel *channel) +{ + SPI_ASSERT_PARAM(handle != NULL && channel != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + *channel = handle->baseAddress->SPICSNCR.BIT.spi_csn_sel; + return BASE_STATUS_OK; +} + +/** + * @brief Interrupt Handling Function. + * @param handle SPI_Handle. + * @retval None. + */ +void HAL_SPI_IrqHandler(void *handle) +{ + SPI_Handle *spiHandle = (SPI_Handle *)handle; + SPI_ASSERT_PARAM(spiHandle != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(spiHandle->baseAddress)); + /* Indicates that there is no interruption. */ + if (spiHandle->baseAddress->SPIMIS.reg == 0) { + return; + } + + /* Generating RX overflow interrupt. */ + if (spiHandle->baseAddress->SPIMIS.BIT.rormis) { + spiHandle->baseAddress->SPIIMSC.reg = 0x0; + /* Clear rx interrupt. */ + spiHandle->baseAddress->SPIICR.BIT.roric = BASE_CFG_SET; + spiHandle->baseAddress->SPIICR.BIT.rtic = BASE_CFG_SET; + + spiHandle->errorCode = BASE_STATUS_ERROR; + spiHandle->state = HAL_SPI_STATE_ERROR; + /* Invoke the error callback function. */ + if (spiHandle->userCallBack.ErrorCallback != NULL) { + spiHandle->userCallBack.ErrorCallback(spiHandle); + } + SpiCsControl(spiHandle, SPI_CHIP_DESELECT); + return; + } + /* 0x02 Receive timeout interrupt, 0x04 receive FIFO interrupt */ + if ((spiHandle->mode == HAL_SPI_SLAVE) && ((spiHandle->baseAddress->SPIMIS.reg == 0x04) || + (spiHandle->baseAddress->SPIMIS.reg == 0x02))) { + ReadData(spiHandle); + } else { /* master mode */ + WriteData(spiHandle); + ReadData(spiHandle); + } + + SpiRxTxCallback(spiHandle); +} \ No newline at end of file diff --git a/src/drivers/spi/spi_v3/src/spi_ex.c b/src/drivers/spi/spi_v3/src/spi_ex.c new file mode 100644 index 0000000000000000000000000000000000000000..c13bb3526101ef79237fdc86af8414b321e8d7ca --- /dev/null +++ b/src/drivers/spi/spi_v3/src/spi_ex.c @@ -0,0 +1,54 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file spi_ex.c + * @author MCU Driver Team + * @brief SPI module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the SPI. + * + Peripheral Control functions + */ + +/* Includes ------------------------------------------------------------------*/ +#include "spi_ex.h" + +/** + * @brief SPI SET CHIP CONGFIG SELECT. + * @param handle SPI_handle. + * @param mode SPI CS mode.For details, see the enumeration definition of HAL_SPI_CHIP_CONFIG + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_SPI_SetChipConfigSelectEx(SPI_Handle *handle, HAL_SPI_CHIP_CONFIG mode) +{ + SPI_ASSERT_PARAM(handle != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + SPI_PARAM_CHECK_WITH_RET(IsSpiChipConfigMode(mode), BASE_STATUS_ERROR); + handle->baseAddress->SPICSNCR.BIT.spi_csn_mode = mode; /* set chip mode */ + return BASE_STATUS_OK; +} + +/** + * @brief SPI GET CHIP CONGFIG SELECT. + * @param handle SPI_handle. + * @retval HAL_SPI_CHIP_CONFIG. + */ +HAL_SPI_CHIP_CONFIG HAL_SPI_GetChipConfigSelectEx(SPI_Handle *handle) +{ + SPI_ASSERT_PARAM(handle != NULL); + SPI_ASSERT_PARAM(IsSPIInstance(handle->baseAddress)); + return handle->baseAddress->SPICSNCR.BIT.spi_csn_mode; +} \ No newline at end of file diff --git a/src/drivers/timer/common/inc/timer.h b/src/drivers/timer/common/inc/timer.h index edd902cdb380ab2190d96a75a885c6b37776fd17..7a9a393e5eeb7803cc77778c824ee77fdfbeaad7 100644 --- a/src/drivers/timer/common/inc/timer.h +++ b/src/drivers/timer/common/inc/timer.h @@ -62,7 +62,7 @@ typedef struct _TIMER_Handle { volatile unsigned int bgLoad; /**< Backgroud period, set the TIMEx_BGLOAD. */ bool interruptEn; /**< Interrupt enable or disable. */ bool adcSocReqEnable; /**< Trigger ADC Enable Sampling. */ - bool dmaReqEnable; /**< Enable bit for DMA single request and DAM burst sampling. */ + bool dmaReqEnable; /**< Enable bit for DMA single request and DMA burst sampling. */ TIMER_UserCallBack userCallBack; /**< Callback function of timer. */ TIMER_ExtendHandle handleEx; /**< TIMER extend handle */ } TIMER_Handle; diff --git a/src/drivers/timer/timer_v1/src/timer_ex.c b/src/drivers/timer/timer_v1/src/timer_ex.c index b74d4bfe4d44b220a0da2fa3431cff4bb61f00bf..cb6e432f239c177382b25117590078fabdd09fca 100644 --- a/src/drivers/timer/timer_v1/src/timer_ex.c +++ b/src/drivers/timer/timer_v1/src/timer_ex.c @@ -28,14 +28,14 @@ /** * @brief Setting DMA request overflow interrupt. * @param handle Timer Handle - * @param bool enable or disable interrupt of DMA request overflow. + * @param overflow enable or disable interrupt of DMA request overflow. * @retval None */ -void HAL_TIMER_DMARequestOverFlowEx(TIMER_Handle *handle, bool overFlowSet) +void HAL_TIMER_DMARequestOverFlowEx(TIMER_Handle *handle, bool overflow) { TIMER_ASSERT_PARAM(handle != NULL); TIMER_ASSERT_PARAM(IsTIMERInstance(handle->baseAddress)); - handle->baseAddress->TIMERx_CONTROL.BIT.dmaovintenable = overFlowSet; + handle->baseAddress->TIMERx_CONTROL.BIT.dmaovintenable = (overflow == true) ? BASE_CFG_ENABLE : BASE_CFG_DISABLE; return; } diff --git a/src/drivers/tsensor/tsensor_v1/src/tsensor.c b/src/drivers/tsensor/tsensor_v1/src/tsensor.c index 65966092dcc82ca23c6d7fd6af8005ba43f2ca5c..23bd1ac2af1101ac1e3f4a31218a318c31b86bcf 100644 --- a/src/drivers/tsensor/tsensor_v1/src/tsensor.c +++ b/src/drivers/tsensor/tsensor_v1/src/tsensor.c @@ -32,6 +32,13 @@ #define NUM 16 #define TSENSOR_SOC_NUM ADC_SOC_NUM15 /* This parameter can be modified according to the actual situation */ +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) +#define TSENSOR_ADC_BASE ADC1_BASE +#else +#define TSENSOR_ADC_BASE ADC0_BASE +#endif + /** * @brief ADC for tsensor clock initialization. * @param None. @@ -40,11 +47,11 @@ static void ADC_ClkEnable(void) { unsigned int status = BASE_CFG_UNSET; - HAL_CRG_IpEnableGet(ADC0_BASE, &status); /* Check whether the ADC clock is enabled */ + HAL_CRG_IpEnableGet(TSENSOR_ADC_BASE, &status); /* Check whether the ADC clock is enabled */ if (status != IP_CLK_ENABLE) { - HAL_CRG_IpEnableSet(ADC0_BASE, IP_CLK_ENABLE); - HAL_CRG_IpClkSelectSet(ADC0_BASE, CRG_ADC_CLK_ASYN_PLL_DIV); - HAL_CRG_IpClkDivSet(ADC0_BASE, CRG_ADC_DIV_2); + HAL_CRG_IpEnableSet(TSENSOR_ADC_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(TSENSOR_ADC_BASE, CRG_ADC_CLK_ASYN_PLL_DIV); + HAL_CRG_IpClkDivSet(TSENSOR_ADC_BASE, CRG_ADC_DIV_2); } } @@ -56,9 +63,9 @@ static void ADC_ClkEnable(void) static void TSENSOR_SampleConfigure(void) { ADC_Handle adcHandle = {0}; - adcHandle.baseAddress = ADC0; + adcHandle.baseAddress = TSENSOR_ADC_BASE; adcHandle.socPriority = ADC_PRIMODE_ALL_ROUND; - HAL_ADC_Init(&adcHandle); /* ADC ADC initialization */ + HAL_ADC_Init(&adcHandle); /* ADC initialization */ SOC_Param socParam = {0}; socParam.adcInput = ADC_CH_ADCINA16; @@ -83,8 +90,14 @@ static void TSENSOR_SampleConfigure(void) static float TSENSOR_Conversion(unsigned int digital) { float curV = ((float)digital / 4096.0f) * 3.3f; /* 4096.0 and 3.3 for voltage conversion */ +#if defined (CHIP_3065PNPIMH) || defined (CHIP_3066MNPIRH) || defined (CHIP_3065PNPIRH) || \ + defined (CHIP_3065PNPIRE) || defined (CHIP_3065PNPIRA) + /* 1.3f and 25.0f are used as parameters to calculate result */ + float curTemp = (curV - 1.3f) / g_tsensorGain + 25.0f; +#else /* 1.228f and 25.0f are used as parameters to calculate result */ float curTemp = (curV - 1.228f) / g_tsensorGain + 25.0f; +#endif return curTemp; } @@ -123,14 +136,14 @@ unsigned int HAL_TSENSOR_GetResult(void) unsigned int count = 0; for (unsigned int i = 0; i < NUM; i++) { unsigned int socRet; - DCL_ADC_SOCxSoftTrigger(ADC0, TSENSOR_SOC_NUM); + DCL_ADC_SOCxSoftTrigger(TSENSOR_ADC_BASE, TSENSOR_SOC_NUM); BASE_FUNC_DELAY_MS(1); /* waite for 1ms until conversion finish */ - DCL_ADC_GetConvState(ADC0, TSENSOR_SOC_NUM); - if (DCL_ADC_GetConvState(ADC0, TSENSOR_SOC_NUM) != BASE_CFG_UNSET) { - socRet = DCL_ADC_ReadSOCxResult(ADC0, TSENSOR_SOC_NUM); + DCL_ADC_GetConvState(TSENSOR_ADC_BASE, TSENSOR_SOC_NUM); + if (DCL_ADC_GetConvState(TSENSOR_ADC_BASE, TSENSOR_SOC_NUM) != BASE_CFG_UNSET) { + socRet = DCL_ADC_ReadSOCxResult(TSENSOR_ADC_BASE, TSENSOR_SOC_NUM); ret += socRet; count++; - DCL_ADC_ResetConvState(ADC0, TSENSOR_SOC_NUM); /* Set the sampling completion flag */ + DCL_ADC_ResetConvState(TSENSOR_ADC_BASE, TSENSOR_SOC_NUM); /* Set the sampling completion flag */ } } if (count == 0) { diff --git a/src/drivers/uart/common/inc/uart.h b/src/drivers/uart/common/inc/uart.h index a80401c9f83fd517f814fac25f728e77c19e489e..17a03c5323218d6eabfc05c0eb3db83bacfbbbbd 100644 --- a/src/drivers/uart/common/inc/uart.h +++ b/src/drivers/uart/common/inc/uart.h @@ -86,17 +86,39 @@ typedef void (* UART_CallbackType)(void *handle); */ /** - * @defgroup UART_API_Declaration UART HAL API + * @defgroup UART_API_Declaration + * @brief UART HAL API. * @{ */ -/* Peripheral initialization and deinitialize functions */ +/** + * @defgroup UART_API_Declaration + * @brief Peripheral initialization and deinitialize functions. + * @{ + */ + BASE_StatusType HAL_UART_Init(UART_Handle *uartHandle); BASE_StatusType HAL_UART_DeInit(UART_Handle *uartHandle); +/** + * @} + */ + +/** + * @defgroup UART_API_Declaration + * @brief Peripheral querying the state functions. + * @{ + */ -/* Peripheral querying the state functions */ UART_State_Type HAL_UART_GetState(UART_Handle *uartHandle); +/** + * @} + */ + +/** + * @defgroup UART_API_Declaration + * @brief Peripheral transmit and abort functions. + * @{ + */ -/* Peripheral transmit and abort functions */ BASE_StatusType HAL_UART_WriteBlocking(UART_Handle *uartHandle, unsigned char *srcData, unsigned int dataLength, unsigned int blockingTime); BASE_StatusType HAL_UART_WriteIT(UART_Handle *uartHandle, unsigned char *srcData, unsigned int dataLength); @@ -109,16 +131,35 @@ BASE_StatusType HAL_UART_ReadDMA(UART_Handle *uartHandle, unsigned char *saveDat unsigned int dataLength); BASE_StatusType HAL_UART_StopRead(UART_Handle *uartHandle); BASE_StatusType HAL_UART_StopWrite(UART_Handle *uartHandle); +/** + * @} + */ + +/** + * @defgroup UART_API_Declaration + * @brief brief Peripheral interrupt service and callback registration functions. + * @{ + */ -/* brief Peripheral interrupt service and callback registration functions */ void HAL_UART_IrqHandler(void *handle); BASE_StatusType HAL_UART_RegisterCallBack(UART_Handle *uartHandle, UART_CallbackFun_Type typeID, UART_CallbackType pCallback); +/** + * @} + */ + +/** + * @defgroup UART_API_Declaration + * @brief UART read using DMA cyclically stored function. + * @{ + */ -/* UART read using DMA cyclically stored function */ BASE_StatusType HAL_UART_ReadDMAAndCyclicallyStored(UART_Handle *uartHandle, unsigned char *saveData, DMA_LinkList *tempNode, unsigned int dataLength); unsigned int HAL_UART_ReadDMAGetPos(UART_Handle *uartHandle); +/** + * @} + */ /** * @} diff --git a/src/drivers/uart/uart_v0/inc/uart_ip.h b/src/drivers/uart/uart_v0/inc/uart_ip.h index 3ed58547ca38025dff3e058868c3d53bc2143ffa..75afe97ace0bd19cbf17b5ec77491626186005a4 100644 --- a/src/drivers/uart/uart_v0/inc/uart_ip.h +++ b/src/drivers/uart/uart_v0/inc/uart_ip.h @@ -515,7 +515,7 @@ static inline bool IsUartFIFOThreshold(UART_FIFO_Threshold fifoThreshold) static inline void DCL_UART_WriteData(UART_RegStruct * const uartx, unsigned char data) { UART_ASSERT_PARAM(IsUARTInstance(uartx)); - uartx->UART_DR.BIT.data = data; /* Data to be sent. */ + uartx->UART_DR.reg = (unsigned int)data; /* Data to be sent. */ } /** @@ -526,7 +526,7 @@ static inline void DCL_UART_WriteData(UART_RegStruct * const uartx, unsigned cha static inline unsigned char DCL_UART_ReadData(const UART_RegStruct *uartx) { UART_ASSERT_PARAM(IsUARTInstance(uartx)); - return uartx->UART_DR.BIT.data; /* Data to be read. */ + return uartx->UART_DR.reg; /* Data to be read. */ } /** diff --git a/src/drivers/uart/uart_v0/src/uart.c b/src/drivers/uart/uart_v0/src/uart.c index 8bd5626c5d8d7ae302fde3e51ba88b076f3d9469..e215d6064779f300a3e2ab92b25877d17c49cbec 100644 --- a/src/drivers/uart/uart_v0/src/uart.c +++ b/src/drivers/uart/uart_v0/src/uart.c @@ -214,7 +214,7 @@ BASE_StatusType HAL_UART_WriteBlocking(UART_Handle *uartHandle, unsigned char *s continue; } /* Blocking write to DR when register is empty */ - uartHandle->baseAddress->UART_DR.BIT.data = *(src); + uartHandle->baseAddress->UART_DR.reg = *(src); src++; txCount--; } @@ -291,7 +291,7 @@ static void WriteITCallBack(UART_Handle *uartHandle) break; } uartHandle->txBuffSize -= 1; - uartHandle->baseAddress->UART_DR.BIT.data = *(uartHandle->txbuff); + uartHandle->baseAddress->UART_DR.reg = *(uartHandle->txbuff); (uartHandle->txbuff)++; } WriteItCheck(uartHandle); @@ -696,7 +696,7 @@ BASE_StatusType HAL_UART_RegisterCallBack(UART_Handle *uartHandle, UART_Callback } /** - * @brief UART DAM(rx to memory), cyclically stores data to specified memory(saveData). + * @brief UART DMA(rx to memory), cyclically stores data to specified memory(saveData). * @param uartHandle UART handle. * @param saveData Address of the data buff to be sent. * @param tempNode DMA Link List, @ref DMA_LinkList @@ -723,7 +723,7 @@ BASE_StatusType HAL_UART_ReadDMAAndCyclicallyStored(UART_Handle *uartHandle, uns uartHandle->rxbuff = saveData; uartHandle->rxBuffSize = dataLength; - /* Init DAM Channel Params */ + /* Init DMA Channel Params */ DMA_ChannelParam dmaParams; dmaParams.direction = uartHandle->dmaHandle->DMA_Channels[channel].direction; dmaParams.srcAddrInc = uartHandle->dmaHandle->DMA_Channels[channel].srcAddrInc; diff --git a/src/drivers/uart/uart_v1/inc/uart_ex.h b/src/drivers/uart/uart_v1/inc/uart_ex.h index 12219f09247bfd202a8a32923a882518c3a5cc46..e5f228fd86fa812f4f2e23a9954a77b1a765a9b3 100644 --- a/src/drivers/uart/uart_v1/inc/uart_ex.h +++ b/src/drivers/uart/uart_v1/inc/uart_ex.h @@ -49,7 +49,7 @@ BASE_StatusType HAL_UART_EnableBaudDetectionEx(UART_Handle *uartHandle); BASE_StatusType HAL_UART_DisableBaudDetectionEx(UART_Handle *uartHandle); -BASE_StatusType HAL_UART_SetRxWaiteTimeEx(UART_Handle *uartHandle, unsigned int cntOfBit); +BASE_StatusType HAL_UART_SetRxWaitTimeEx(UART_Handle *uartHandle, unsigned int cntOfBit); BASE_StatusType HAL_UART_SetOversampleMultipleEx(UART_Handle *uartHandle, UART_OversampleMultiple multiple); diff --git a/src/drivers/uart/uart_v1/inc/uart_ip.h b/src/drivers/uart/uart_v1/inc/uart_ip.h index 006cdaf3badeffe52ef7249961682999e301ab27..32751478dec8551172040cf061553e41edd70e58 100644 --- a/src/drivers/uart/uart_v1/inc/uart_ip.h +++ b/src/drivers/uart/uart_v1/inc/uart_ip.h @@ -393,15 +393,15 @@ typedef union { unsigned int reserved2 : 1; unsigned int txfeim : 1; /**< Mask status of the TX FIFO empty interrupt. */ unsigned int txfneim : 1; /**< Mask status of the TX FIFO non-empt interrupt. */ - unsigned int txtcim : 1; /**< Mask status of the TX completion interrupt. */ unsigned int reserved3 : 1; + unsigned int reserved4 : 1; unsigned int rxfeim : 1; /**< Mask status of the RX FIFO empty interrupt. */ unsigned int rxfneim : 1; /**< Mask status of the RX FIFO non-empt interrupt. */ unsigned int rxffim : 1; /**< Mask status of the RX FIFO full interrupt. */ unsigned int abdcim : 1; /**< Mask status of the auto-baud check completion interrupt. */ unsigned int abdeim : 1; /**< Mask status of auto-baud detection error interrupts. */ unsigned int cmim : 1; /**< Mask status of the character match success interrupt. */ - unsigned int reserved4 : 10; + unsigned int reserved5 : 10; } BIT; } volatile UART_IMSC_REG; @@ -692,7 +692,7 @@ static inline bool IsUartSequenceMode(UART_SequenceMode mode) static inline void DCL_UART_WriteData(UART_RegStruct * const uartx, unsigned char data) { UART_ASSERT_PARAM(IsUARTInstance(uartx)); - uartx->UART_DR.BIT.data = data; + uartx->UART_DR.reg = (unsigned int)data; } /** @@ -703,7 +703,7 @@ static inline void DCL_UART_WriteData(UART_RegStruct * const uartx, unsigned cha static inline unsigned char DCL_UART_ReadData(const UART_RegStruct *uartx) { UART_ASSERT_PARAM(IsUARTInstance(uartx)); - return uartx->UART_DR.BIT.data; + return uartx->UART_DR.reg; } /** diff --git a/src/drivers/uart/uart_v1/src/uart.c b/src/drivers/uart/uart_v1/src/uart.c index f52b870c3fd627d4c71b67cb104d12d3bc0350b5..b387a36d399abc081dffd8b1f32c197ed7f48faa 100644 --- a/src/drivers/uart/uart_v1/src/uart.c +++ b/src/drivers/uart/uart_v1/src/uart.c @@ -301,7 +301,7 @@ BASE_StatusType HAL_UART_WriteBlocking(UART_Handle *uartHandle, unsigned char *s continue; } /* Blocking write to DR when register is empty */ - uartHandle->baseAddress->UART_DR.BIT.data = *(src); + uartHandle->baseAddress->UART_DR.reg = *(src); src++; txCount--; } @@ -359,7 +359,7 @@ static void WriteITCallBack(UART_Handle *uartHandle) if (uartHandle->baseAddress->UART_FR.BIT.txff == 1) { /* True when the TX FIFO is full */ break; } - uartHandle->baseAddress->UART_DR.BIT.data = *(uartHandle->txbuff); + uartHandle->baseAddress->UART_DR.reg = *(uartHandle->txbuff); (uartHandle->txbuff)++; uartHandle->txBuffSize -= 1; } @@ -794,7 +794,7 @@ BASE_StatusType HAL_UART_RegisterCallBack(UART_Handle *uartHandle, UART_Callback } /** - * @brief UART DAM(rx to memory), cyclically stores data to specified memory(saveData). + * @brief UART DMA(rx to memory), cyclically stores data to specified memory(saveData). * @param uartHandle UART handle. * @param saveData Address of the data buff to be sent. * @param tempNode DMA Link List, @ref DMA_LinkList @@ -821,7 +821,7 @@ BASE_StatusType HAL_UART_ReadDMAAndCyclicallyStored(UART_Handle *uartHandle, uns uartHandle->rxbuff = saveData; uartHandle->rxBuffSize = dataLength; - /* Init DAM Channel Params */ + /* Init DMA Channel Params */ DMA_ChannelParam dmaParams; dmaParams.direction = uartHandle->dmaHandle->DMA_Channels[channel].direction; dmaParams.srcAddrInc = uartHandle->dmaHandle->DMA_Channels[channel].srcAddrInc; diff --git a/src/drivers/uart/uart_v1/src/uart_ex.c b/src/drivers/uart/uart_v1/src/uart_ex.c index dd93b7c2998b1504429d1381253285b3de578e39..f2a92c880caa05316758325dbb61e7fca8d15be1 100644 --- a/src/drivers/uart/uart_v1/src/uart_ex.c +++ b/src/drivers/uart/uart_v1/src/uart_ex.c @@ -102,7 +102,7 @@ BASE_StatusType HAL_UART_DisableBaudDetectionEx(UART_Handle *uartHandle) * @param cntOfBit timeout is defined as the time spent in transmitting N bits, numer of N is cntOfBit. * @retval BASE status type: OK, ERROR. */ -BASE_StatusType HAL_UART_SetRxWaiteTimeEx(UART_Handle *uartHandle, unsigned int cntOfBit) +BASE_StatusType HAL_UART_SetRxWaitTimeEx(UART_Handle *uartHandle, unsigned int cntOfBit) { UART_ASSERT_PARAM(uartHandle != NULL); UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); diff --git a/src/drivers/uart/uart_v3/inc/uart_ex.h b/src/drivers/uart/uart_v3/inc/uart_ex.h new file mode 100644 index 0000000000000000000000000000000000000000..69c5c63f3c5bd8a0565cabae0e0a7ff6d3ca2102 --- /dev/null +++ b/src/drivers/uart/uart_v3/inc/uart_ex.h @@ -0,0 +1,66 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file uart_ex.h + * @author MCU Driver Team + * @brief UART module driver. + * @details This file provides functions declaration of the UART, + * + Initialization and de-initialization functions + * + Peripheral querying the state functions. + * + Peripheral transmit and abort functions. + * + Peripheral interrupt service and callback registration functions. + * This file also provides the definition of the UART handle structure. + */ + +/* Includes ------------------------------------------------------------------*/ +#ifndef McuMagicTag_UART_EX_H +#define McuMagicTag_UART_EX_H + +#include "uart.h" + +/** + * @addtogroup UART_IP + * @{ + */ + +/** + * @defgroup UART_EX_API_Declaration UART HAL API EX + * @{ + */ +BASE_StatusType HAL_UART_OpenCharacterMatchEx(UART_Handle *uartHandle, unsigned char ch); + +BASE_StatusType HAL_UART_CloseCharacterMatchEx(UART_Handle *uartHandle); + +BASE_StatusType HAL_UART_EnableBaudDetectionEx(UART_Handle *uartHandle); + +BASE_StatusType HAL_UART_DisableBaudDetectionEx(UART_Handle *uartHandle); + +BASE_StatusType HAL_UART_SetRxWaitTimeEx(UART_Handle *uartHandle, unsigned int cntOfBit); + +BASE_StatusType HAL_UART_SetOversampleMultipleEx(UART_Handle *uartHandle, UART_OversampleMultiple multiple); + +BASE_StatusType HAL_UART_SetDataSequenceModeEx(UART_Handle *uartHandle, UART_SequenceMode mode); + +BASE_StatusType HAL_UART_SetLineModeEx(UART_Handle *uartHandle, UART_LineMode lineMode); +/** + * @} + */ + +/** + * @} + */ +#endif /* McuMagicTag_UART_EX_H */ \ No newline at end of file diff --git a/src/drivers/uart/uart_v3/inc/uart_ip.h b/src/drivers/uart/uart_v3/inc/uart_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..507136a463ba88f26dd30651d750d69d88fbfe0e --- /dev/null +++ b/src/drivers/uart/uart_v3/inc/uart_ip.h @@ -0,0 +1,1125 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file uart_ip.h + * @author MCU Driver Team + * @brief UART module driver + * @details This file provides DCL functions to manage UART and Definition of + * specific parameters. + * + Definition of UART configuration parameters. + * + UART register mapping structure. + * + Parameters check functions. + * + Direct configuration layer interface. + */ + +/* Macro definitions */ +#ifndef McuMagicTag_UART_IP_H +#define McuMagicTag_UART_IP_H + +#include "baseinc.h" + +#ifdef UART_PARAM_CHECK +#define UART_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM +#define UART_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET +#define UART_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else +#define UART_ASSERT_PARAM(para) ((void)0U) +#define UART_PARAM_CHECK_NO_RET(para) ((void)0U) +#define UART_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) +#endif + +#define UART_FIFOFULL_ONE_TWO 0x0000000FU +#define UART_FIFOFULL_ONE_EIGHT 0x00000008U + +/** + * @addtogroup UART + * @{ + */ + +/** + * @defgroup UART_IP UART_IP + * @brief UART_IP: uart_v1 + * @{ + */ + +/** + * @defgroup UART_Param_Def UART Parameters Definition + * @brief Definition of UART configuration parameters. + * @{ + */ + +/** + * @brief UART def of oversamping + */ +typedef enum { + UART_OVERSAMPLING_16X = 0x00000000U, + UART_OVERSAMPLING_15X = 0x00000001U, + UART_OVERSAMPLING_14X = 0x00000002U, + UART_OVERSAMPLING_13X = 0x00000003U, + UART_OVERSAMPLING_12X = 0x00000004U, + UART_OVERSAMPLING_11X = 0x00000005U, + UART_OVERSAMPLING_10X = 0x00000006U, + UART_OVERSAMPLING_9X = 0x00000007U, + UART_OVERSAMPLING_8X = 0x00000008U +} UART_OversampleMultiple; + +/** + * @brief Extent handle definition of UART + */ +typedef struct { + UART_OversampleMultiple overSampleMultiple; /**< Oversampling multiplier */ + bool msbFirst; /**< Configures data transmission sequence */ +} UART_ExtendHandle; + +/** + * @brief Type ID of callback function registered by the user. + */ +typedef enum { + UART_WRITE_IT_FINISH = 0x00000000U, + UART_READ_IT_FINISH = 0x00000001U, + UART_WRITE_DMA_FINISH = 0x00000002U, + UART_READ_DMA_FINISH = 0x00000003U, + UART_TRNS_IT_ERROR = 0x00000004U, + UART_TRNS_DMA_ERROR = 0x00000005U, + UART_BAUD_DETECT_FINISH = 0x00000006U, + UART_BAUD_DETECT_ERROR = 0x00000007U, + UART_CHARACTER_MATCH = 0x00000008U +} UART_CallbackFun_Type; + +/** + * @brief User Callback Function Definition + */ +typedef struct { + void (* WriteItFinishCallBack)(void *handle); /**< UART tx interrupt complete callback + function for users */ + void (* ReadItFinishCallBack)(void *handle); /**< UART rx interrupt complete callback + function for users */ + void (* WriteDmaFinishCallBack)(void *handle); /**< UART tx DMA complete callback function + for users */ + void (* ReadDmaFinishCallBack)(void *handle); /**< UART rx DMA complete callback function + for users */ + void (* TransmitItErrorCallBack)(void *handle); /**< UART interrupt mode error callback + function for users */ + void (* TransmitDmaErrorCallBack)(void *handle); /**< UART interrupt mode error callback + function for users */ + void (* BaudDetectSuccessCallBack)(void *handle); /**< Callback function for successful + UART baud rate detection */ + void (* BaudDetectErrorCallBack)(void *handle); /**< UART baud rate detection failure + callback function */ + void (* CharacterMatchCallBack)(void *handle); /**< UART character matching callback + function. */ +}UART_UserCallBack; + +/** + * @brief Type of error callback functuions. + */ +typedef enum { + UART_ERROR_FRAME = 0x00000080U, + UART_ERROR_PARITY = 0x00000100U, + UART_ERROR_BREAK = 0x00000200U, + UART_ERROR_OVERFLOW = 0x00000400U +} UART_Error_Type; + +/** + * @brief The number of data bits transmitted or received in a frame. + */ +typedef enum { + UART_DATALENGTH_5BIT = 0x00000000U, + UART_DATALENGTH_6BIT = 0x00000001U, + UART_DATALENGTH_7BIT = 0x00000002U, + UART_DATALENGTH_8BIT = 0x00000003U +} UART_DataLength; + +/** + * @brief UART parity mode. + * @details parity mode: + * + UART_PARITY_ODD -- odd check + * + UART_PARITY_EVEN -- even check + * + UART_PARITY_NONE -- none odd or even check + * + UART_PARITY_MARK -- mark check + * + UART_PARITY_SPACE -- space check + */ +typedef enum { + UART_PARITY_ODD = 0x00000000U, + UART_PARITY_EVEN = 0x00000001U, + UART_PARITY_MARK = 0x00000002U, + UART_PARITY_SPACE = 0x00000003U, + UART_PARITY_NONE = 0x00000004U +} UART_Parity_Mode; + +/** + * @brief Stop bit setting. + * @details Stop bit type: + * + UART_STOPBITS_ONE -- frame with one stop bit + * + UART_STOPBITS_TWO -- frame with two stop bits + */ +typedef enum { + UART_STOPBITS_ONE = 0x00000000U, + UART_STOPBITS_TWO = 0x00000001U +} UART_StopBits; + +/** + * @brief Three transmit mode: blocking, DMA, interrupt. + */ +typedef enum { + UART_MODE_BLOCKING = 0x00000000U, + UART_MODE_INTERRUPT = 0x00000001U, + UART_MODE_DMA = 0x00000002U, + UART_MODE_DISABLE = 0x00000003U +} UART_Transmit_Mode; + +/** + * @brief Hardware flow control mode disable/enable. + */ +typedef enum { + UART_HW_FLOWCTR_DISABLE = 0x00000000U, + UART_HW_FLOWCTR_ENABLE = 0x00000001U +} UART_HW_FlowCtr; + +/** + * @brief UART running status: deinit, ready, busy, busy(TX), busy(RX). + */ +typedef enum { + UART_STATE_NONE_INIT = 0x00000000U, + UART_STATE_READY = 0x00000001U, + UART_STATE_BUSY = 0x00000002U, + UART_STATE_BUSY_TX = 0x00000003U, + UART_STATE_BUSY_RX = 0x00000004U, +} UART_State_Type; + +/** + * @brief UART RX/TX FIFO line interrupt threshold. An interrupt is triggered when the received or discovered data + * crosses the FIFO threshold. + * @details Description: + * + UART_FIFODEPTH_SIZE0 -- rxFIFO >= 0 Bytes, txFIFO <= 0 Bytes + * + UART_FIFODEPTH_SIZE1 -- rxFIFO >= 1 Bytes, txFIFO <= 1 Bytes + * + UART_FIFODEPTH_SIZE2 -- rxFIFO >= 2 Bytes, txFIFO <= 2 Bytes + * + UART_FIFODEPTH_SIZE3 -- rxFIFO >= 3 Bytes, txFIFO <= 3 Bytes + * + UART_FIFODEPTH_SIZE4 -- rxFIFO >= 4 Bytes, txFIFO <= 4 Bytes + * + UART_FIFODEPTH_SIZE5 -- rxFIFO >= 5 Bytes, txFIFO <= 5 Bytes + * + UART_FIFODEPTH_SIZE6 -- rxFIFO >= 6 Bytes, txFIFO <= 6 Bytes + * + UART_FIFODEPTH_SIZE7 -- rxFIFO >= 7 Bytes, txFIFO <= 7 Bytes + */ +typedef enum { + UART_FIFODEPTH_SIZE0 = 0x00000000U, + UART_FIFODEPTH_SIZE1 = 0x00000001U, + UART_FIFODEPTH_SIZE2 = 0x00000002U, + UART_FIFODEPTH_SIZE3 = 0x00000003U, + UART_FIFODEPTH_SIZE4 = 0x00000004U, + UART_FIFODEPTH_SIZE5 = 0x00000005U, + UART_FIFODEPTH_SIZE6 = 0x00000006U, + UART_FIFODEPTH_SIZE7 = 0x00000007U, +} UART_FIFO_Threshold; + +/** + * @brief UART data transfer sequence. + */ +typedef enum { + UART_SEQUENCE_START_LSB = 0x00000000U, + UART_SEQUENCE_START_MSB = 0x00000001U, +} UART_SequenceMode; + +/** + * @brief UART the number of communication lines. + */ +typedef enum { + UART_2_LINE_FULL_DUPLEX = 0x00000000U, + UART_1_LINE_HALF_DUPLEX = 0x00000001U, +} UART_LineMode; + +/** + * @} + */ + +/** + * @defgroup UART_Reg_Def UART Register Definition + * @brief register mapping structure + * @{ + */ + +/** + * @brief UART data register, which stores the RX data and TX data and reads the RX status from this register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int data : 8; /**< Receives data and transmits data. */ + unsigned int fe : 1; /**< Frame error. */ + unsigned int pe : 1; /**< Verification error. */ + unsigned int be : 1; /**< Break error. */ + unsigned int oe : 1; /**< Overflow error. */ + unsigned int reserved0 : 20; + } BIT; +} UART_DR_REG; + +/** + * @brief Receive status register/error clear register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int fe : 1; /**< Frame error. */ + unsigned int pe : 1; /**< Verification error. */ + unsigned int be : 1; /**< Break error. */ + unsigned int oe : 1; /**< Overflow error. */ + unsigned int reserved0 : 28; + } BIT; +} UART_RSR_REG; + +/** + * @brief UART flag register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int cts : 1; /**< Hardware flow control status. */ + unsigned int reserved0 : 2; + unsigned int busy : 1; /**< UART busy/idle status bit. */ + unsigned int rxfe : 1; /**< RX FIFO empty flag. */ + unsigned int txff : 1; /**< TX FIFO full flag. */ + unsigned int rxff : 1; /**< RX FIFO full flag. */ + unsigned int txfe : 1; /**< TX FIFO empty flag. */ + unsigned int reserved1 : 24; + } BIT; +} UART_FR_REG; + +/** + * @brief Integer baud rate register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int bauddivint : 16; /**< Integer baud rate divider value. */ + unsigned int reserved0 : 16; + } BIT; +} UART_IBRD_REG; + +/** + * @brief Fractional baud rate register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int bauddivfrac : 6; /**< Fractional baud rate divider. */ + unsigned int reserved0 : 26; + } BIT; +} UART_FBRD_REG; + +/** + * @brief Line control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int brk : 1; /**< Send a break. */ + unsigned int pen : 1; /**< Check select bit. */ + unsigned int eps : 1; /**< Parity check selection during transmission and reception. */ + unsigned int stp2 : 1; /**< TX frame tail stop bit select. */ + unsigned int fen : 1; /**< TX and RX FIFO enable control. */ + unsigned int wlen : 2; /**< Indicates the number of transmitted and received data bits in a frame. */ + unsigned int sps : 1; /**< Select stick parity. */ + unsigned int reserved0 : 24; + } BIT; +} UART_LCR_H_REG; + +/** + * @brief UART_CR is a UART control register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int uarten : 1; /**< UART enable. */ + unsigned int reserved0 : 6; + unsigned int lbe : 1; /**< Indicates whether to enable loopback. */ + unsigned int txe : 1; /**< UART TX enable. */ + unsigned int rxe : 1; /**< UART RX enable. */ + unsigned int dtr : 1; /**< UART time run. */ + unsigned int rts : 1; /**< Request to send. */ + unsigned int reserved1 : 2; + unsigned int rtsen : 1; /**< RTS hardware flow control enable. */ + unsigned int ctsen : 1; /**< CTS hardware flow control enable. */ + unsigned int hdsel : 1; + unsigned int reserved2 : 15; + } BIT; +} UART_CR_REG; + +/** + * @brief Interrupt FIFO threshold select register. + * It is used to set the FIFO interrupt trigger threshold (UART_TXinTR or UART_RXinTR). + */ +typedef union { + unsigned int reg; + struct { + unsigned int txiflsel : 3; /**< Configure the threshold of the TX FIFO. */ + unsigned int reserved0 : 5; + unsigned int rxiflsel : 3; /**< RX FIFO threshold. */ + unsigned int reserved1 : 21; + } BIT; +} UART_IFLS_REG; + +/** + * @brief Interrupt mask register, which is used to mask interrupts. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 1; + unsigned int ctsmim : 1; /**< Mask status of the CTS interrupt. */ + unsigned int reserved1 : 2; + unsigned int rxim : 1; /**< Mask status of the RX interrupt. */ + unsigned int txim : 1; /**< Mask status of the TX interrupt. */ + unsigned int rtim : 1; /**< Mask status of the RX timeout interrupt. */ + unsigned int feim : 1; /**< Mask status of the frame error interrupt. */ + unsigned int peim : 1; /**< Mask status of the parity interrupt. */ + unsigned int beim : 1; /**< Mask status of the break error interrupt. */ + unsigned int oeim : 1; /**< Mask status of the overflow error interrupt. */ + unsigned int reserved2 : 1; + unsigned int txfeim : 1; /**< Mask status of the TX FIFO empty interrupt. */ + unsigned int txfneim : 1; /**< Mask status of the TX FIFO non-empt interrupt. */ + unsigned int reserved3 : 1; + unsigned int reserved4 : 1; + unsigned int rxfeim : 1; /**< Mask status of the RX FIFO empty interrupt. */ + unsigned int rxfneim : 1; /**< Mask status of the RX FIFO non-empt interrupt. */ + unsigned int rxffim : 1; /**< Mask status of the RX FIFO full interrupt. */ + unsigned int abdcim : 1; /**< Mask status of the auto-baud check completion interrupt. */ + unsigned int abdeim : 1; /**< Mask status of auto-baud detection error interrupts. */ + unsigned int cmim : 1; /**< Mask status of the character match success interrupt. */ + unsigned int reserved5 : 10; + } BIT; +} UART_IMSC_REG; + +/** + * @brief Raw interrupt status register. The content of this register is not affected by interrupt mask register. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 1; + unsigned int ctsmis : 1; /**< Raw CTS interrupt status. */ + unsigned int reserved1 : 2; + unsigned int rxris : 1; /**< Raw RX threshold interrupt status. */ + unsigned int txris : 1; /**< Original TX threshold interrupt status. */ + unsigned int rtris : 1; /**< Raw RX timeout interrupt status. */ + unsigned int feris : 1; /**< Raw frame error interrupt status. */ + unsigned int peris : 1; /**< Raw parity interrupt status. */ + unsigned int beris : 1; /**< Raw break error interrupt status. */ + unsigned int oeris : 1; /**< Raw overflow error interrupt status. */ + unsigned int reserved2 : 1; + unsigned int txferis : 1; /**< Original TX FIFO empty interrupt status. */ + unsigned int txfneris : 1; /**< Raw TX FIFO non-empty interrupt status. */ + unsigned int txtcris : 1; /**< Raw TX completion interrupt status. */ + unsigned int reserved3 : 1; + unsigned int rxferis : 1; /**< Raw RX FIFO empty interrupt status. */ + unsigned int rxfneris : 1; /**< Raw RX FIFO non-empty interrupt status. */ + unsigned int rxffris : 1; /**< Status of the raw RX FIFO full interrupt. */ + unsigned int abdcris : 1; /**< Raw auto-baud detection completion interrupt status. */ + unsigned int abderis : 1; /**< Raw auto-baud detection error interrupt status. */ + unsigned int cmris : 1; /**< Status of the original character matching success interrupt. */ + unsigned int reserved4 : 10; + } BIT; +} UART_RIS_REG; + +/** + * @brief Masked interrupt status register. + * It is result of AND operation between raw interrupt status and interrupt mask. + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 1; + unsigned int ctsmmis : 1; /**< Masked CTS interrupt status. */ + unsigned int reserved1 : 2; + unsigned int rxmis : 1; /**< Masked RX interrupt status. */ + unsigned int txmis : 1; /**< Masked TX interrupt status. */ + unsigned int rtmis : 1; /**< Masked RX timeout interrupt status. */ + unsigned int femis : 1; /**< Status of masked frame error interrupts. */ + unsigned int pemis : 1; /**< Masked parity interrupt status. */ + unsigned int bemis : 1; /**< Status of masked break error interrupts. */ + unsigned int oemis : 1; /**< Masked overflow error interrupt status. */ + unsigned int reserved2 : 1; + unsigned int txfeis : 1; /**< Masked TX FIFO empty interrupt status. */ + unsigned int txfneis : 1; /**< Status of the masked TX FIFO non-empty interrupt. */ + unsigned int txtcis : 1; /**< Masked TX completion interrupt status. */ + unsigned int reserved3 : 1; + unsigned int rxfeis : 1; /**< Masked RX FIFO empty interrupt status. */ + unsigned int rxfneis : 1; /**< Status of the masked RX FIFO non-empt interrupt. */ + unsigned int rxffis : 1; /**< Status of the masked RX FIFO full interrupt. */ + unsigned int abdcis : 1; /**< Status of the masked auto-baud check completion interrupt. */ + unsigned int abdeis : 1; /**< Status of masked auto-baud detection error interrupts. */ + unsigned int cmis : 1; /**< Masked character matching success interrupt status. */ + unsigned int reserved4 : 10; + } BIT; +} UART_MIS_REG; + +/** + * @brief Interrupt clear register + */ +typedef union { + unsigned int reg; + struct { + unsigned int reserved0 : 1; + unsigned int ctsmic : 1; /**< Clears the CTS interrupt. */ + unsigned int reserved1 : 2; + unsigned int rxic : 1; /**< Clears the RX interrupt. */ + unsigned int txic : 1; /**< Clears the TX interrupt. */ + unsigned int rtic : 1; /**< Receive timeout interrupt clear. */ + unsigned int feic : 1; /**< Frame error interrupt clear. */ + unsigned int peic : 1; /**< Clears the parity interrupt. */ + unsigned int beic : 1; /**< Clears the break error interrupt. */ + unsigned int oeic : 1; /**< Clears the overflow error interrupt. */ + unsigned int reserved2 : 1; + unsigned int txfeic : 1; /**< Clears the TX FIFO empty interrupt status. */ + unsigned int txfneic : 1; /**< TX FIFO non-empty interrupt clear status. */ + unsigned int txtcic : 1; /**< Transmit completion interrupt clear status. */ + unsigned int reserved3 : 1; + unsigned int rxfeic : 1; /**< RX FIFO empty interrupt clear status. */ + unsigned int rxfneic : 1; /**< RX FIFO non-empty interrupt clear status. */ + unsigned int rxffic : 1; /**< RX FIFO full interrupt clear status. */ + unsigned int abdcic : 1; /**< Auto-baud detection completion interrupt clear status. */ + unsigned int abdeic : 1; /**< Auto-baud detection error interrupt clear status. */ + unsigned int cmic : 1; /**< Clears the character matching success interrupt. */ + unsigned int reserved4 : 10; + } BIT; +} UART_ICR_REG; + +/** + * @brief DMA control register, which is used to enable DMA of TX FIFO and RX FIFO. + */ +typedef union { + unsigned int reg; + struct { + unsigned int rxdmae : 1; /** DMA enable control for the RX FIFO. */ + unsigned int txdmae : 1; /** DMA enable control for the TX FIFO. */ + unsigned int dmaonerr : 1; /** DMA enable control for RX channel when UART error interrupt occurs. */ + unsigned int rxlastsreq_en : 1; /** REQ enable for the last data stream supported by the UART RX DMA. */ + unsigned int reserved0 : 28; + } BIT; +} UART_DMACR_REG; + +/** + * @brief Data transfer sequence configuration register. It is used to configure data transfer sequence. + */ +typedef union { + unsigned int reg; + struct { + unsigned int msbfirst : 1; /**< Most significant bit before enable. */ + unsigned int reserved0 : 31; + } BIT; +} UART_DS_REG; + +/** + * @brief RX timeout duration configuration register, which is used to configure conditions for determining RX timeout. + */ +typedef union { + unsigned int reg; + struct { + unsigned int rtcfg : 24; /**< Indicates the receive timeout interval, in bits. */ + unsigned int reserved0 : 8; + } BIT; +} UART_RTCFG_REG; + +/** + * @brief Oversampling configuration register. It is used to configure the oversampling multiple. + */ +typedef union { + unsigned int reg; + struct { + unsigned int spcfg : 4; /**< Configure the oversampling multiplier. */ + unsigned int reserved0 : 28; + } BIT; +} UART_SPCFG_REG; + +/** + * @brief Auto-baud detection enable register. It is used to enable auto-baud detection function. + */ +typedef union { + unsigned int reg; + struct { + unsigned int abden : 1; /**< Auto-baud detection enable. */ + unsigned int reserved0 : 3; + unsigned int abdbusy : 1; /**< Auto-baud detection busy flag. */ + unsigned int abdenvld : 1; /**< The abden sign is already valid. */ + unsigned int reserved1 : 26; + } BIT; +} UART_ABDEN_REG; + +/** + * @brief Character match configuration register, which is used to configure characters to be matched. + */ +typedef union { + unsigned int reg; + struct { + unsigned int chamat : 8; /**< Binary character to be matched. */ + unsigned int reserved0 : 23; + unsigned int cmen : 1; /**< Character match detection enable. */ + } BIT; +} UART_CHARMATCH_REG; + +/** + * @brief Register mapping structure. + */ +typedef struct { + UART_DR_REG UART_DR; /**< Data register, offset address: 0x00000000U */ + UART_RSR_REG UART_RSR; /**< Receiving status/error clearing register, offset address: 0x00000004U */ + unsigned char space0[16]; + UART_FR_REG UART_FR; /**< Flag register, offset address: 0x00000018U */ + unsigned char space1[8]; + UART_IBRD_REG UART_IBRD; /**< Integer baud rate register, offset address: 0x00000024U */ + UART_FBRD_REG UART_FBRD; /**< Fractional baud rate register, offset address: 0x00000028U */ + UART_LCR_H_REG UART_LCR_H; /**< Wire control register, offset address: 0x0000002CU */ + UART_CR_REG UART_CR; /**< Control register, offset address: 0x00000030U */ + UART_IFLS_REG UART_IFLS; /**< Interrupt FIFO threshold register, offset address: 0x00000034U */ + UART_IMSC_REG UART_IMSC; /**< Interrupt mask status register, offset address: 0x00000038U */ + UART_RIS_REG UART_RIS; /**< Raw interrupt status register, offset address: 0x0000003CU */ + UART_MIS_REG UART_MIS; /**< Masked interrupt status register, offset address: 0x00000040U */ + UART_ICR_REG UART_ICR; /**< Interrupt clear register, offset address: 0x00000044U */ + UART_DMACR_REG UART_DMACR; /**< DMA control register register, offset address: 0x00000048U */ + unsigned char space2[4]; + UART_DS_REG UART_DS; /**< Data transfer sequence set register, offset address: 0x00000050U */ + UART_RTCFG_REG UART_RTCFG; /**< RX timeout duration configuration register, offset address: 0x00000054U */ + UART_SPCFG_REG UART_SPCFG; /**< Oversampling configuration register, offset address: 0x00000058U */ + UART_ABDEN_REG UART_ABDEN; /**< Auto-baud detection enable register, offset address: 0x0000005CU */ + UART_CHARMATCH_REG UART_CHARMATCH; /**< Character match configuration register, offset address: 0x00000060U */ +} volatile UART_RegStruct; +/** + * @} + */ + +/** + * @brief Check UART datalength parameter. + * @param datalength The number of data bits in a frame, @ref UART_DataLength + * @retval bool + */ +static inline bool IsUartDatalength(UART_DataLength datalength) +{ + return (datalength >= UART_DATALENGTH_5BIT) && (datalength <= UART_DATALENGTH_8BIT); +} + +/** + * @brief Check UART stopbits parameter. + * @param stopbits The number of stop bits in a frame, @ref UART_StopBits + * @retval bool + */ +static inline bool IsUartStopbits(UART_StopBits stopbits) +{ + return (stopbits == UART_STOPBITS_ONE) || (stopbits == UART_STOPBITS_TWO); +} + +/** + * @brief Check UART paritymode parameter. + * @param paritymode UART parity check mode, @ref UART_Parity_Mode + * @retval bool + */ +static inline bool IsUartParitymode(UART_Parity_Mode paritymode) +{ + if ((paritymode >= UART_PARITY_ODD) && (paritymode <= UART_PARITY_NONE)) { + return true; + } + return false; +} + +/** + * @brief Check UART transmode parameter. + * @param transmode Transmit mode, @ref UART_Transmit_Mode + * @retval bool + */ +static inline bool IsUartTransmode(UART_Transmit_Mode transmode) +{ + if ((transmode == UART_MODE_BLOCKING) || + (transmode == UART_MODE_INTERRUPT) || + (transmode == UART_MODE_DMA) || + (transmode == UART_MODE_DISABLE)) { + return true; + } + return false; +} + +/** + * @brief Check UART fifoThreshold parameter. + * @param fifoThreshold UART TX/RX FIFO line interrupt threshold, @ref UART_FIFO_Threshold + * @retval bool + */ +static inline bool IsUartFIFOThreshold(UART_FIFO_Threshold fifoThreshold) +{ + return (fifoThreshold >= UART_FIFODEPTH_SIZE0) && (fifoThreshold <= UART_FIFODEPTH_SIZE7); +} + + +/** + * @brief Check UART Oversampling multiple. + * @param multiple Oversampling multiple, @ref UART_OversampleMultiple + * @retval bool + */ +static inline bool IsUartOversampleMultiple(UART_OversampleMultiple multiple) +{ + return (multiple >= UART_OVERSAMPLING_16X) && (multiple <= UART_OVERSAMPLING_8X); +} + +/** + * @brief Check UART data transfer sequential mode. + * @param mode UART TX/RX sequential mode, @ref UART_SequenceMode + * @retval bool + */ +static inline bool IsUartSequenceMode(UART_SequenceMode mode) +{ + return (mode == UART_SEQUENCE_START_LSB) || (mode == UART_SEQUENCE_START_MSB); +} + +/** + * @brief Check UART data transfer sequential mode. + * @param mode UART TX/RX sequential mode, @ref UART_SequenceMode + * @retval bool + */ +static inline bool IsUartLineMode(UART_LineMode mode) +{ + return (mode == UART_1_LINE_HALF_DUPLEX) || (mode == UART_2_LINE_FULL_DUPLEX); +} + +/* Direct configuration layer */ +/** + * @brief Send a character by UART + * @param uartx UART register base address. + * @param data Character to be sent. + * @retval None. + */ +static inline void DCL_UART_WriteData(UART_RegStruct * const uartx, unsigned char data) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_DR.reg = (unsigned int)data; +} + +/** + * @brief Receive a character from UART. + * @param uartx UART register base address. + * @retval Data, read the received data from the UART data register. + */ +static inline unsigned char DCL_UART_ReadData(const UART_RegStruct *uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + return uartx->UART_DR.reg; +} + +/** + * @brief UART TX enable. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_WriteEnable(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_CR.BIT.txe = BASE_CFG_ENABLE; +} + +/** + * @brief UART TX disable. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_WriteDisable(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_CR.BIT.txe = BASE_CFG_DISABLE; +} + +/** + * @brief UART RX enable. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_ReadEnable(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_CR.BIT.rxe = BASE_CFG_ENABLE; +} + +/** + * @brief UART RX disable. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_ReadDisable(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_CR.BIT.rxe = BASE_CFG_DISABLE; +} + +/** + * @brief UART TX use DMA . + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_DMA_WriteEnable(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_DMACR.BIT.txdmae = BASE_CFG_ENABLE; +} + +/** + * @brief UART TX cannot use DMA . + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_DMA_WriteDisable(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_DMACR.BIT.txdmae = BASE_CFG_DISABLE; +} + +/** + * @brief UART RX use DMA . + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_DMA_ReadEnable(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_DMACR.BIT.rxdmae = BASE_CFG_ENABLE; +} + +/** + * @brief UART RX cannot use DMA . + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_DMA_ReadDisable(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_DMACR.BIT.rxdmae = BASE_CFG_DISABLE; +} + +/** + * @brief UART word length setting. + * @param uartx UART register base address. + * @param dataLength Word length of sending and receiving, @ref UART_DataLength + * @retval None. + */ +static inline void DCL_UART_SetDataLength(UART_RegStruct * const uartx, UART_DataLength dataLength) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + UART_PARAM_CHECK_NO_RET(IsUartDatalength(dataLength)); + uartx->UART_LCR_H.BIT.wlen = dataLength; +} + +/** + * @brief Gettintg UART word length. + * @param uartx UART register base address. + * @retval Word length. + */ +static inline unsigned int DCL_UART_GetDataLength(const UART_RegStruct * uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + return uartx->UART_LCR_H.BIT.wlen; +} + +/** + * @brief Setting UART odd parity check. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_SetParityOdd(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_LCR_H.BIT.eps = BASE_CFG_DISABLE; + uartx->UART_LCR_H.BIT.pen = BASE_CFG_ENABLE; +} + +/** + * @brief Setting UART even parity check. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_SetParityEven(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_LCR_H.BIT.eps = BASE_CFG_ENABLE; + uartx->UART_LCR_H.BIT.pen = BASE_CFG_ENABLE; +} + +/** + * @brief UART does not use parity check. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_SetParityNone(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_LCR_H.BIT.pen = BASE_CFG_DISABLE; +} + +/** + * @brief Getting UART odd/even parity check. + * @param uartx UART register base address. + * @retval Odd/even parity check, 0: odd, 1: even, 2: None. + */ +static inline unsigned int DCL_UART_GetParityCheck(const UART_RegStruct * uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + unsigned int eps = uartx->UART_LCR_H.BIT.eps; + unsigned int pen = uartx->UART_LCR_H.BIT.pen; + if (eps == 0) { + return UART_PARITY_NONE; + } else if (pen == 0) { + return UART_PARITY_ODD; + } else { + return UART_PARITY_EVEN; + } +} + +/** + * @brief Setting the stop bit. + * @param uartx UART register base address. + * @param bit One or two stop bit, @ref UART_StopBits + * @retval None. + */ +static inline void DCL_UART_SetStopBits(UART_RegStruct * const uartx, UART_StopBits bit) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + UART_PARAM_CHECK_NO_RET(IsUartStopbits(bit)); + uartx->UART_LCR_H.BIT.stp2 = bit; +} + +/** + * @brief Getting the stop bit. + * @param uartx UART register base address. + * @retval Stop bit of UART. + */ +static inline unsigned int DCL_UART_GetStopBits(const UART_RegStruct *uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + return uartx->UART_LCR_H.BIT.stp2; +} + +/** + * @brief UART uses hardware flow control. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_Enable_HwFlowCtr(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_CR.BIT.ctsen = BASE_CFG_ENABLE; + uartx->UART_CR.BIT.rtsen = BASE_CFG_ENABLE; +} + +/** + * @brief UART uses hardware flow control. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_Disable_HwFlowCtr(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_CR.BIT.ctsen = BASE_CFG_DISABLE; + uartx->UART_CR.BIT.rtsen = BASE_CFG_DISABLE; +} + +/** + * @brief UART Disable function of stick parity. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_DisableStickParity(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_LCR_H.BIT.sps = BASE_CFG_DISABLE; +} + +/** + * @brief UART enable function of stick parity 0-bit check. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_EnableStickParity_Zero(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_LCR_H.BIT.pen = BASE_CFG_ENABLE; + uartx->UART_LCR_H.BIT.eps = BASE_CFG_ENABLE; + uartx->UART_LCR_H.BIT.sps = BASE_CFG_ENABLE; +} + +/** + * @brief UART enable function of stick parity 1-bit check. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_EnableStickParity_One(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_LCR_H.BIT.pen = BASE_CFG_ENABLE; + uartx->UART_LCR_H.BIT.eps = BASE_CFG_DISABLE; + uartx->UART_LCR_H.BIT.sps = BASE_CFG_ENABLE; +} + +/** + * @brief UART enable interrupt of CTS. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_EnableCTSInt(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_LCR_H.BIT.pen = BASE_CFG_ENABLE; +} + +/** + * @brief UART clear interrupt of CTS. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_ClearCTSInt(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_ICR.BIT.ctsmic = BASE_CFG_ENABLE; + uartx->UART_IMSC.BIT.ctsmim = BASE_CFG_DISABLE; +} + +/** + * @brief UART get interrupt status of CTS. + * @param uartx UART register base address. + * @retval status, 1: Interrupt generation, 0: interrupt is not generated. + */ +static inline unsigned int DCL_UART_GetCTSIntStatus(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + return uartx->UART_MIS.BIT.ctsmmis; +} + +/** + * @brief Set the data bits. The first bit to be transmitted and received is the LSB. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_SetDataLSB(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_DS.BIT.msbfirst = 0; +} + +/** + * @brief Set the data bits. The first bit to be transmitted and received is the MSB. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_SetDataMSB(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_DS.BIT.msbfirst = 1; +} + +/** + * @brief Setting data sequences of UART. + * @param uartx UART register base address. + * @param bool 1: enable MSB 0: enable LSB. + * @retval None. + */ +static inline void DCL_UART_SetDataSequences(UART_RegStruct * const uartx, bool dataSequence) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_DS.BIT.msbfirst = dataSequence; +} + + +/** + * @brief Configuring the upper limit of receiving timeout. + * @param uartx UART register base address. + * @param timeOfBits timeout, time required to transmit a certain bit. + * @retval None. + */ +static inline void DCL_UART_SetRxTimeOut(UART_RegStruct * const uartx, unsigned int timeOfBits) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + UART_PARAM_CHECK_NO_RET(timeOfBits <= 0xFFFFFF); + uartx->UART_RTCFG.reg = timeOfBits; +} + +/** + * @brief Enable automatic baud rate detection. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_EnableBaudRateDetection(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_ABDEN.BIT.abden = BASE_CFG_ENABLE; +} + +/** + * @brief Disable automatic baud rate detection. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_DisableBaudRateDetection(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_ABDEN.BIT.abden = BASE_CFG_DISABLE; +} + +/** + * @brief Enable character adaptation. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_EnableMatchCharater(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_CHARMATCH.BIT.cmen = BASE_CFG_ENABLE; +} + +/** + * @brief Disable character adaptation. + * @param uartx UART register base address. + * @retval None. + */ +static inline void DCL_UART_DisableMatchCharater(UART_RegStruct * const uartx) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + uartx->UART_CHARMATCH.BIT.cmen = BASE_CFG_DISABLE; +} + +/** + * @brief Sets the character to be matched. + * @param uartx UART register base address. + * @param ascii ascii of character. + * @retval None. + */ +static inline void DCL_UART_SetMatchCharater(UART_RegStruct * const uartx, unsigned int ascii) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + UART_PARAM_CHECK_NO_RET(ascii <= 0xFF); + uartx->UART_CHARMATCH.BIT.chamat = ascii; +} + +/** + * @brief Sets UART oversampling multiple. + * @param uartx UART register base address. + * @param multiple Oversampling multiple, @ref UART_OversampleMultiple + * @retval None. + */ +static inline void DCL_UART_OversampleMultiple(UART_RegStruct * const uartx, UART_OversampleMultiple multiple) +{ + UART_ASSERT_PARAM(IsUARTInstance(uartx)); + UART_PARAM_CHECK_NO_RET(IsUartOversampleMultiple(multiple)); + uartx->UART_SPCFG.BIT.spcfg = multiple; +} +/** + * @} + */ + +/** + * @} + */ +#endif /* McuMagicTag_UART_IP_H */ \ No newline at end of file diff --git a/src/drivers/uart/uart_v3/src/uart.c b/src/drivers/uart/uart_v3/src/uart.c new file mode 100644 index 0000000000000000000000000000000000000000..a46ad133a6aba0f6973bcc16f457f0acc3bde5e2 --- /dev/null +++ b/src/drivers/uart/uart_v3/src/uart.c @@ -0,0 +1,884 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file uart.c + * @author MCU Driver Team + * @brief UART module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the UART. + * + Initialization and de-initialization functions. + * + Peripheral send and receive functions in blocking mode. + * + Peripheral send and receive functions in interrupt mode. + * + Peripheral send and receive functions in DMA mode. + * + Peripheral stop sending and receiving functions in interrupt/DMA mode. + * + Interrupt callback function and user registration function. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "interrupt.h" +#include "systick.h" +#include "uart.h" +/* Macro definitions ---------------------------------------------------------*/ + +#define OVERSAMPLING_PARAM 16 +#define SYSTICK_MS_DIV 1000 +#define PARITY_ODD 0x2 +#define PARITY_EVEN 0x6 +#define PARITY_MARK 0x82 +#define PARITY_SPACE 0x86 + +static unsigned int DivClosest(unsigned int x, unsigned int divisor) +{ + unsigned int ret; + if (divisor == 0) { + return 0; + } + ret = (((x) + ((divisor) / 2)) / (divisor)); /* Round up the result, add 1/2 */ + return ret; +} + +static void WriteDMAFinishFun(void *handle); +static void ReadDMAFinishFun(void *handle); +static void TransmitDMAErrorFun(void *handle); + +static void ReadITCallBack(UART_Handle *uartHandle); +static void WriteITCallBack(UART_Handle *uartHandle); +static void ErrorServiceCallback(UART_Handle *uartHandle); + +static void CharterMatchCallBack(UART_Handle *uartHandle); +static void BaudDetectCallBack(UART_Handle *uartHandle); + +static void UART_SetParityBit(UART_Handle *uartHandle); + + +/** + * @brief Baud rate detection interrupt callback function. + * @param uartHandle UART handle. + * @retval None. + */ +static void BaudDetectCallBack(UART_Handle *uartHandle) +{ + if (uartHandle->baseAddress->UART_MIS.BIT.abdcis == 0x01) { + uartHandle->baseAddress->UART_ABDEN.BIT.abden = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_IMSC.BIT.abdeim = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_IMSC.BIT.abdcim = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_ICR.BIT.abdcic = BASE_CFG_ENABLE; + /* After the baud rate automatic detection function is configured, enable UART. */ + uartHandle->baseAddress->UART_CR.BIT.txe = BASE_CFG_ENABLE; + uartHandle->baseAddress->UART_CR.BIT.rxe = BASE_CFG_ENABLE; + /* Call back user detect success function. */ + if (uartHandle->userCallBack.BaudDetectSuccessCallBack != NULL) { + uartHandle->userCallBack.BaudDetectSuccessCallBack(uartHandle); + } + } else { + /* Wait until UART is idle. */ + while (uartHandle->baseAddress->UART_ABDEN.BIT.abdbusy == 0x01) { + ; + } + uartHandle->baseAddress->UART_ICR.BIT.abdeic = BASE_CFG_ENABLE; + /* Call back user baud detect error function. */ + if (uartHandle->userCallBack.BaudDetectErrorCallBack != NULL) { + uartHandle->userCallBack.BaudDetectErrorCallBack(uartHandle); + } + } + return; +} + +/** + * @brief Character detection interrupt callback function. + * @param uartHandle UART handle. + * @retval None. + */ +static void CharterMatchCallBack(UART_Handle *uartHandle) +{ + uartHandle->baseAddress->UART_IMSC.BIT.cmim = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_ICR.BIT.cmic = BASE_CFG_ENABLE; + if (uartHandle->userCallBack.CharacterMatchCallBack != NULL) { + uartHandle->userCallBack.CharacterMatchCallBack(uartHandle); + } +} + +/** + * @brief Sets the parity bit of the UART. + * @param uartHandle UART handle. + * @retval None. + */ +static void UART_SetParityBit(UART_Handle *uartHandle) +{ + /* Sets the UART check mode. */ + switch (uartHandle->parity) { + case UART_PARITY_ODD: + uartHandle->baseAddress->UART_LCR_H.reg |= PARITY_ODD; /* Odd parity. */ + break; + case UART_PARITY_EVEN: + uartHandle->baseAddress->UART_LCR_H.reg |= PARITY_EVEN; /* Even parity. */ + break; + case UART_PARITY_MARK: + uartHandle->baseAddress->UART_LCR_H.reg |= PARITY_MARK; /* Marking parity */ + break; + case UART_PARITY_SPACE: + uartHandle->baseAddress->UART_LCR_H.reg |= PARITY_SPACE; /* space parity */ + break; + case UART_PARITY_NONE: + uartHandle->baseAddress->UART_LCR_H.BIT.pen = BASE_CFG_DISABLE; /* No parity */ + break; + default: + return; + } +} + +/** + * @brief Initialize the UART hardware configuration and configure parameters based on the specified handle. + * @param uartHandle UART handle. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_UART_Init(UART_Handle *uartHandle) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_PARAM_CHECK_WITH_RET(uartHandle->txState == UART_STATE_NONE_INIT, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(uartHandle->rxState == UART_STATE_NONE_INIT, BASE_STATUS_ERROR); + unsigned int uartClock, quot; + UART_PARAM_CHECK_WITH_RET(IsUartDatalength(uartHandle->dataLength), BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(IsUartStopbits(uartHandle->stopBits), BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(IsUartParitymode(uartHandle->parity), BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(IsUartTransmode(uartHandle->txMode), BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(IsUartTransmode(uartHandle->rxMode), BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(IsUartFIFOThreshold(uartHandle->fifoTxThr), BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(IsUartFIFOThreshold(uartHandle->fifoRxThr), BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(IsUartOversampleMultiple(uartHandle->handleEx.overSampleMultiple), BASE_STATUS_ERROR); + + uartHandle->baseAddress->UART_CR.BIT.uarten = BASE_CFG_DISABLE; + while (uartHandle->baseAddress->UART_FR.BIT.busy == 0x01) { + ; + } + + uartClock = HAL_CRG_GetIpFreq((void *)uartHandle->baseAddress); + + /* DCL OverSample Multiple check */ + uartHandle->baseAddress->UART_SPCFG.BIT.spcfg = uartHandle->handleEx.overSampleMultiple; + + /* DCL sequences setting */ + uartHandle->baseAddress->UART_DS.BIT.msbfirst = uartHandle->handleEx.msbFirst; + + /* The baud rate divider(BRD) based on the baud rate and clock frequency, calculation formula */ + unsigned int oversample = uartHandle->baseAddress->UART_SPCFG.reg; + if (uartHandle->baudRate > (uartClock / (OVERSAMPLING_PARAM - oversample))) { + return BASE_STATUS_ERROR; + } else { + unsigned int tmpClock = uartClock / (OVERSAMPLING_PARAM - oversample) * 64; /* 64 is for decimal parts */ + quot = DivClosest(tmpClock, uartHandle->baudRate); + } + /* Clear the baud rate divider register */ + uartHandle->baseAddress->UART_FBRD.reg = 0; + uartHandle->baseAddress->UART_IBRD.reg = 0; + /* The fractional baud rate divider value is stored to the lower 6 bits of the FBRD */ + uartHandle->baseAddress->UART_FBRD.reg = (quot & 0x3F); + /* Right shift 6 bits is the integer baud rate divider value, is stored to IBRD */ + uartHandle->baseAddress->UART_IBRD.reg = (quot >> 6); + uartHandle->baseAddress->UART_LCR_H.reg = 0; + uartHandle->baseAddress->UART_LCR_H.BIT.wlen = uartHandle->dataLength; /* Frame length seting */ + uartHandle->baseAddress->UART_LCR_H.BIT.stp2 = uartHandle->stopBits; /* Stop bit seting */ + UART_SetParityBit(uartHandle); + if (uartHandle->fifoMode == true) { /* FIFO threshold setting */ + uartHandle->baseAddress->UART_LCR_H.BIT.fen = BASE_CFG_ENABLE; + uartHandle->baseAddress->UART_IFLS.BIT.rxiflsel = uartHandle->fifoRxThr; + uartHandle->baseAddress->UART_IFLS.BIT.txiflsel = uartHandle->fifoTxThr; + } + if (uartHandle->hwFlowCtr == UART_HW_FLOWCTR_ENABLE) { /* Hardwarer flow control setting */ + uartHandle->baseAddress->UART_CR.reg |= 0xC000; + } + uartHandle->baseAddress->UART_CR.reg |= 0x301; /* Enable bit use 0x301 is to set txe/rxe/uarten */ + uartHandle->txState = UART_STATE_READY; + uartHandle->rxState = UART_STATE_READY; + return BASE_STATUS_OK; +} + +/** + * @brief DeInitialize the UART and restoring default parameters based on the specified handle. + * @param uartHandle UART handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_UART_DeInit(UART_Handle *uartHandle) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + uartHandle->baseAddress->UART_CR.reg = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_ICR.reg |= 0xFFFF; /* Clear all interruptions. */ + uartHandle->baseAddress->UART_IMSC.reg = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_DMACR.reg = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_LCR_H.BIT.brk = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_LCR_H.BIT.fen = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_SPCFG.BIT.spcfg = BASE_CFG_DISABLE; /* Clear Oversampling Configuration */ + uartHandle->baseAddress->UART_DS.BIT.msbfirst = BASE_CFG_DISABLE; /* Clears the data receiving sequence. */ + uartHandle->userCallBack.WriteItFinishCallBack = NULL; /* Clear all user call back function. */ + uartHandle->userCallBack.ReadItFinishCallBack = NULL; + uartHandle->userCallBack.WriteDmaFinishCallBack = NULL; /* Clear user DMA call back function. */ + uartHandle->userCallBack.ReadDmaFinishCallBack = NULL; + uartHandle->userCallBack.TransmitDmaErrorCallBack = NULL; + uartHandle->userCallBack.TransmitItErrorCallBack = NULL; + uartHandle->userCallBack.BaudDetectErrorCallBack = NULL; /* Clear user baud detection callback function */ + uartHandle->userCallBack.BaudDetectSuccessCallBack = NULL; + uartHandle->userCallBack.CharacterMatchCallBack = NULL; /* Clear user character matching callback function */ + uartHandle->rxState = UART_STATE_NONE_INIT; /* Resets the UART status to uninitialized. */ + uartHandle->txState = UART_STATE_NONE_INIT; + return BASE_STATUS_OK; +} + +/** + * @brief Return the specified UART state. + * @param uartHandle UART handle. + * @retval UART state: UART_STATE_NONE_INIT(can not use), UART_STATE_READY, UART_STATE_BUSY + * @retval UART_STATE_BUSY_TX, UART_STATE_BUSY_RX. + */ +UART_State_Type HAL_UART_GetState(UART_Handle *uartHandle) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + if (uartHandle->txState == UART_STATE_NONE_INIT) { + return UART_STATE_NONE_INIT; /* Uart Rx and Tx are not initialized */ + } + if (uartHandle->txState == UART_STATE_READY && uartHandle->rxState == UART_STATE_READY) { + return UART_STATE_READY; /* Uart Rx and Tx are ready */ + } + if (uartHandle->txState == UART_STATE_READY) { + return UART_STATE_BUSY_RX; /* Uart Rx is busy */ + } + if (uartHandle->rxState == UART_STATE_READY) { + return UART_STATE_BUSY_TX; /* Uart Tx is busy */ + } + return UART_STATE_BUSY; /* Uart Rx and Tx are busy */ +} + +/** + * @brief Send data in blocking mode. + * @param uartHandle UART handle. + * @param srcData Address of the data buff to be sent. + * @param dataLength number of the data to be sent. + * @param blockingTime Blocking time, unit: milliseconds. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_UART_WriteBlocking(UART_Handle *uartHandle, unsigned char *srcData, + unsigned int dataLength, unsigned int blockingTime) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_ASSERT_PARAM(srcData != NULL); + UART_PARAM_CHECK_WITH_RET(uartHandle->txMode == UART_MODE_BLOCKING, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(dataLength > 0, BASE_STATUS_ERROR); + unsigned long long setTick = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SYSTICK_MS_DIV * blockingTime; + UART_PARAM_CHECK_WITH_RET(setTick < SYSTICK_MAX_VALUE, BASE_STATUS_ERROR); + if (uartHandle->txState == UART_STATE_READY) { + uartHandle->txState = UART_STATE_BUSY_TX; + unsigned int txCount = dataLength; + unsigned char *src = srcData; + uartHandle->baseAddress->UART_IMSC.BIT.txim = BASE_CFG_DISABLE; /* Disable TX interrupt bit */ + uartHandle->baseAddress->UART_CR.BIT.txe = BASE_CFG_ENABLE; + unsigned long long deltaTick; + unsigned int preTick = DCL_SYSTICK_GetTick(); + unsigned int curTick = preTick; + while (txCount > 0x00) { + curTick = DCL_SYSTICK_GetTick(); + deltaTick = (curTick > preTick) ? (curTick - preTick) : (SYSTICK_MAX_VALUE - preTick + curTick); + if (deltaTick >= setTick) { + uartHandle->txState = UART_STATE_READY; + return BASE_STATUS_TIMEOUT; + } + if (uartHandle->baseAddress->UART_FR.BIT.txff == 0x01) { /* True when the TX FIFO is full */ + continue; + } + /* Blocking write to DR when register is empty */ + uartHandle->baseAddress->UART_DR.reg = *(src); + src++; + txCount--; + } + } else { + return BASE_STATUS_BUSY; + } + uartHandle->txState = UART_STATE_READY; + return BASE_STATUS_OK; +} + +/** + * @brief Send data in interrupt mode. + * @param uartHandle UART handle. + * @param srcData Address of the data buff to be sent. + * @param dataLength Number of the data to be sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_UART_WriteIT(UART_Handle *uartHandle, unsigned char *srcData, unsigned int dataLength) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_PARAM_CHECK_WITH_RET(uartHandle->txMode == UART_MODE_INTERRUPT, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(srcData != NULL, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(dataLength > 0, BASE_STATUS_ERROR); + + if (uartHandle->txState == UART_STATE_READY) { + uartHandle->txState = UART_STATE_BUSY_TX; + uartHandle->txbuff = srcData; + uartHandle->txBuffSize = dataLength; + uartHandle->baseAddress->UART_ICR.BIT.txic = BASE_CFG_ENABLE; + if (uartHandle->fifoMode == true) { + uartHandle->baseAddress->UART_IMSC.BIT.txim = BASE_CFG_ENABLE; + } else { + uartHandle->baseAddress->UART_IMSC.BIT.txfeim = BASE_CFG_ENABLE; + } + } else { + return BASE_STATUS_BUSY; + } + return BASE_STATUS_OK; +} + +/** + * @brief Interrupt sending callback function. + * The hanler function is called when Tx interruption occurs. + * @param uartHandle UART handle. + * @retval None. + */ +static void WriteITCallBack(UART_Handle *uartHandle) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_ASSERT_PARAM(uartHandle->txbuff != NULL); + if (uartHandle->txState == UART_STATE_BUSY_TX) { + while (uartHandle->txBuffSize > 0) { + if (uartHandle->baseAddress->UART_FR.BIT.txff == 1) { /* True when the TX FIFO is full */ + break; + } + uartHandle->baseAddress->UART_DR.BIT.data = *(uartHandle->txbuff); + (uartHandle->txbuff)++; + uartHandle->txBuffSize -= 1; + } + if (uartHandle->txBuffSize == 0) { + uartHandle->baseAddress->UART_IMSC.reg &= 0xFFFFEFDF; /* Disable txim and txfeim */ + uartHandle->baseAddress->UART_ICR.reg |= 0x1020; /* Clear txic and txfeic */ + uartHandle->txState = UART_STATE_READY; + /* Call user call back function */ + if (uartHandle->userCallBack.WriteItFinishCallBack != NULL) { + uartHandle->userCallBack.WriteItFinishCallBack(uartHandle); + } + } + } + return; +} + +/** + * @brief Send data in DMA mode. + * @param uartHandle UART handle. + * @param srcData Address of the data buff to be sent. + * @param dataLength Number of the data to be sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_UART_WriteDMA(UART_Handle *uartHandle, unsigned char *srcData, + unsigned int dataLength) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_PARAM_CHECK_WITH_RET(uartHandle->txMode == UART_MODE_DMA, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(srcData != NULL, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(dataLength > 0, BASE_STATUS_ERROR); + unsigned int channel = uartHandle->uartDmaTxChn; + UART_PARAM_CHECK_WITH_RET(IsDmaChannelNum(channel) == true, BASE_STATUS_ERROR); + UART_ASSERT_PARAM(uartHandle->dmaHandle != NULL); + if (uartHandle->txState == UART_STATE_READY) { + uartHandle->txState = UART_STATE_BUSY_TX; + uartHandle->baseAddress->UART_IMSC.BIT.txim = BASE_CFG_DISABLE; /* Disable TX interrupt bit */ + uartHandle->dmaHandle->userCallBack.DMA_CallbackFuns[channel].ChannelFinishCallBack = WriteDMAFinishFun; + uartHandle->dmaHandle->userCallBack.DMA_CallbackFuns[channel].ChannelErrorCallBack = TransmitDMAErrorFun; + uartHandle->txbuff = srcData; + uartHandle->txBuffSize = dataLength; + if (HAL_DMA_StartIT(uartHandle->dmaHandle, (uintptr_t)(void *)uartHandle->txbuff, + (uintptr_t)(void *)&(uartHandle->baseAddress->UART_DR), \ + dataLength, channel) != BASE_STATUS_OK) { + uartHandle->txState = UART_STATE_READY; + return BASE_STATUS_ERROR; + } + uartHandle->baseAddress->UART_DMACR.BIT.txdmae = BASE_CFG_ENABLE; /* Enable TX DMA bit */ + } else { + return BASE_STATUS_BUSY; + } + return BASE_STATUS_OK; +} + +/** + * @brief Receive data in blocking mode. + * @param uartHandle UART handle. + * @param saveData Address of the data buff to be saved. + * @param dataLength Length of the data int the storage buffer. + * @param blockingTime Blocking time, unit: milliseconds. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_UART_ReadBlocking(UART_Handle *uartHandle, unsigned char *saveData, + unsigned int dataLength, unsigned int blockingTime) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(saveData != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_PARAM_CHECK_WITH_RET(uartHandle->rxMode == UART_MODE_BLOCKING, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(dataLength > 0, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(blockingTime > 0, BASE_STATUS_ERROR); + unsigned long long setTick = HAL_CRG_GetIpFreq(SYSTICK_BASE) / SYSTICK_MS_DIV * blockingTime; + UART_PARAM_CHECK_WITH_RET(setTick < SYSTICK_MAX_VALUE, BASE_STATUS_ERROR); + if (uartHandle->rxState == UART_STATE_READY) { + uartHandle->rxState = UART_STATE_BUSY_RX; + unsigned int rxCount = dataLength; + unsigned char *save = saveData; + uartHandle->baseAddress->UART_IMSC.BIT.rxim = BASE_CFG_DISABLE; /* Disable RX interrupt bit */ + uartHandle->baseAddress->UART_ICR.reg = 0XFF; /* Clear interrupt flag */ + unsigned int tmp; + unsigned long long deltaTick; + unsigned int preTick = DCL_SYSTICK_GetTick(); + unsigned int curTick = preTick; + while (rxCount > 0) { + curTick = DCL_SYSTICK_GetTick(); + deltaTick = (curTick > preTick) ? (curTick - preTick) : (SYSTICK_MAX_VALUE - preTick + curTick); + if (deltaTick >= setTick) { + uartHandle->rxState = UART_STATE_READY; + return BASE_STATUS_TIMEOUT; + } + if (uartHandle->baseAddress->UART_FR.BIT.rxfe == 0x01) { + continue; + } + tmp = uartHandle->baseAddress->UART_DR.reg; + if (tmp & 0xF00) { /* True when receiving generated error */ + uartHandle->rxState = UART_STATE_READY; + return BASE_STATUS_ERROR; + } + *(save) = (tmp & 0xFF); /* The lower eight bits are the register data bits */ + save++; + rxCount--; + } + } else { + return BASE_STATUS_BUSY; + } + uartHandle->rxState = UART_STATE_READY; + return BASE_STATUS_OK; +} + +/** + * @brief Receive data in interrupt mode. + * @param uartHandle UART handle. + * @param saveData Address of the data buff to be saved. + * @param dataLength length of the data int the storage buffer. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_UART_ReadIT(UART_Handle *uartHandle, unsigned char *saveData, unsigned int dataLength) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_ASSERT_PARAM(saveData != NULL); + UART_PARAM_CHECK_WITH_RET(uartHandle->rxMode == UART_MODE_INTERRUPT, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(dataLength > 0, BASE_STATUS_ERROR); + if (uartHandle->rxState == UART_STATE_READY) { + uartHandle->rxState = UART_STATE_BUSY_RX; + uartHandle->rxbuff = saveData; + uartHandle->rxBuffSize = dataLength; + if (uartHandle->fifoMode == true) { + uartHandle->baseAddress->UART_IMSC.reg |= 0x7D0; /* Enable rx interrupt and rx timeout interrupt */ + } else { + uartHandle->baseAddress->UART_IMSC.reg |= 0x20780; /* Enable rx not empty interrupt */ + } + } else { + return BASE_STATUS_BUSY; + } + return BASE_STATUS_OK; +} + +/** + * @brief Interrupt receiving callback function. + * The hanler function is called when Rx interruption occurs. + * @param uartHandle UART handle. + * @retval None. + */ +static void ReadITCallBack(UART_Handle *uartHandle) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(uartHandle->rxbuff != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + if (uartHandle->rxState == UART_STATE_BUSY_RX) { + unsigned int tmp; + while (uartHandle->rxBuffSize > 0) { + if (uartHandle->baseAddress->UART_FR.BIT.rxfe == 0x01) { /* True when the RX FIFO is empty */ + break; + } + tmp = uartHandle->baseAddress->UART_DR.reg; + *(uartHandle->rxbuff) = (tmp & 0xFF); /* Read from DR when holding register/FIFO is not empty */ + uartHandle->rxbuff++; + uartHandle->rxBuffSize -= 1; + } + if (uartHandle->rxBuffSize == 0) { + uartHandle->baseAddress->UART_IMSC.reg &= 0xFFFDFFAF; /* Disable rxim ,rtim and rxfneim */ + uartHandle->rxState = UART_STATE_READY; + } + uartHandle->baseAddress->UART_ICR.reg |= 0x20050; /* Clear rxic, rtic and rxfneic */ + if (uartHandle->userCallBack.ReadItFinishCallBack != NULL && uartHandle->rxBuffSize == 0) { + uartHandle->userCallBack.ReadItFinishCallBack(uartHandle); + } + } + return; +} + +/** + * @brief Callback function of finishing receiving in DMA mode. + * The hanler function is called when Rx DMA Finish interruption occurs. + * @param handle DMA handle. + * @retval None. + */ +static void ReadDMAFinishFun(void *handle) +{ + UART_ASSERT_PARAM(handle != NULL); + UART_Handle *uartHandle = (UART_Handle *)(handle); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + uartHandle->rxState = UART_STATE_READY; + uartHandle->baseAddress->UART_DMACR.BIT.rxdmae = BASE_CFG_DISABLE; + uartHandle->rxBuffSize = 0; + if (uartHandle->userCallBack.ReadDmaFinishCallBack != NULL) { + uartHandle->userCallBack.ReadDmaFinishCallBack(uartHandle); /* User callback function */ + } + return; +} + +/** + * @brief Callback function of finishing sending in DMA mode. + * The hanler function is called when Tx DMA Finish interruption occurs. + * @param handle DMA handle. + * @retval None. + */ +static void WriteDMAFinishFun(void *handle) +{ + UART_ASSERT_PARAM(handle != NULL); + UART_Handle *uartHandle = (UART_Handle *)(handle); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + uartHandle->txState = UART_STATE_READY; + uartHandle->baseAddress->UART_DMACR.BIT.txdmae = BASE_CFG_DISABLE; + uartHandle->txBuffSize = 0; + if (uartHandle->userCallBack.WriteDmaFinishCallBack != NULL) { + uartHandle->userCallBack.WriteDmaFinishCallBack(uartHandle); /* User callback function */ + } + return; +} + +/** + * @brief Callback function of Tx/Rx error interrupt in DMA mode. + * The hanler function is called when Tx/Rx transmission error interruption occurs. + * @param handle DMA handle. + * @retval None. + */ +static void TransmitDMAErrorFun(void *handle) +{ + UART_ASSERT_PARAM(handle != NULL); + UART_Handle *uartHandle = (UART_Handle *)(handle); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + if (uartHandle->rxState == UART_STATE_BUSY_RX) { + uartHandle->baseAddress->UART_DMACR.BIT.rxdmae = BASE_CFG_DISABLE; + } + if (uartHandle->txState == UART_STATE_BUSY_TX) { + uartHandle->baseAddress->UART_DMACR.BIT.txdmae = BASE_CFG_DISABLE; + } + if (uartHandle->userCallBack.TransmitDmaErrorCallBack != NULL) { + uartHandle->userCallBack.TransmitDmaErrorCallBack(uartHandle); + } + uartHandle->txState = UART_STATE_READY; + uartHandle->rxState = UART_STATE_READY; + return; +} + +/** + * @brief Receive data in DMA mode. + * @param uartHandle UART handle. + * @param saveData Address of the data buff to be sent. + * @param dataLength number of the data to be sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_UART_ReadDMA(UART_Handle *uartHandle, unsigned char *saveData, + unsigned int dataLength) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_ASSERT_PARAM(saveData != NULL); + UART_PARAM_CHECK_WITH_RET(uartHandle->rxMode == UART_MODE_DMA, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(dataLength > 0, BASE_STATUS_ERROR); + unsigned int channel = uartHandle->uartDmaRxChn; + UART_PARAM_CHECK_WITH_RET(IsDmaChannelNum(channel) == true, BASE_STATUS_ERROR); + UART_ASSERT_PARAM(uartHandle->dmaHandle != NULL); + if (uartHandle->rxState == UART_STATE_READY) { + uartHandle->rxState = UART_STATE_BUSY_RX; + uartHandle->baseAddress->UART_IMSC.BIT.rxim = BASE_CFG_DISABLE; /* Disable RX interrupt bit */ + uartHandle->dmaHandle->userCallBack.DMA_CallbackFuns[channel].ChannelFinishCallBack = ReadDMAFinishFun; + uartHandle->dmaHandle->userCallBack.DMA_CallbackFuns[channel].ChannelErrorCallBack = TransmitDMAErrorFun; + uartHandle->rxbuff = saveData; + uartHandle->rxBuffSize = dataLength; + /* Can not masking overflow error, break error, check error, frame error interrupt */ + if (HAL_DMA_StartIT(uartHandle->dmaHandle, (uintptr_t)(void *)&(uartHandle->baseAddress->UART_DR), + (uintptr_t)(void *)uartHandle->rxbuff, dataLength, channel) != BASE_STATUS_OK) { + uartHandle->rxState = UART_STATE_READY; + return BASE_STATUS_ERROR; + } + uartHandle->baseAddress->UART_DMACR.BIT.rxdmae = BASE_CFG_ENABLE; /* Enable RX_DMA bit */ + } else { + return BASE_STATUS_BUSY; + } + return BASE_STATUS_OK; +} + +/** + * @brief Stop the process of sending data in interrupt or DMA mode. + * @param uartHandle UART handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_UART_StopWrite(UART_Handle *uartHandle) /* Only support UART_MODE_INTERRUPT and UART_MODE_DMA */ +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_ASSERT_PARAM(uartHandle->dmaHandle != NULL); + UART_PARAM_CHECK_WITH_RET(IsDmaChannelNum(uartHandle->uartDmaTxChn) == true, BASE_STATUS_ERROR); + /* Blocking send interrupt and jugdement the status of txmode. */ + uartHandle->baseAddress->UART_IMSC.BIT.txim = BASE_CFG_DISABLE; + if (uartHandle->txMode == UART_MODE_DMA) { + uartHandle->baseAddress->UART_DMACR.BIT.txdmae = BASE_CFG_DISABLE; + if (HAL_DMA_StopChannel(uartHandle->dmaHandle, uartHandle->uartDmaTxChn) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + } + uartHandle->txState = UART_STATE_READY; + return BASE_STATUS_OK; +} + +/** + * @brief Stop the process of receiving data in interrupt or DMA mode. + * @param uartHandle UART handle. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_UART_StopRead(UART_Handle *uartHandle) /* Only support UART_MODE_INTERRUPT and UART_MODE_DMA */ +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_ASSERT_PARAM(uartHandle->dmaHandle != NULL); + UART_PARAM_CHECK_WITH_RET(IsDmaChannelNum(uartHandle->uartDmaRxChn) == true, BASE_STATUS_ERROR); + unsigned int val = uartHandle->baseAddress->UART_IMSC.reg; + val &= 0xFFFDF82F; /* Disable bits: rxim, rtim, feim, peim, beim, oeim, rxfneim */ + uartHandle->baseAddress->UART_IMSC.reg = val; + if (uartHandle->rxMode == UART_MODE_DMA) { + uartHandle->baseAddress->UART_DMACR.BIT.rxdmae = BASE_CFG_DISABLE; + if (HAL_DMA_StopChannel(uartHandle->dmaHandle, uartHandle->uartDmaRxChn) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + } + uartHandle->rxState = UART_STATE_READY; + return BASE_STATUS_OK; +} + +/** + * @brief Error handler function of receiving. + * @param uartHandle UART handle. + * @retval None. + */ +static void ErrorServiceCallback(UART_Handle *uartHandle) +{ + unsigned int error = 0x00; + if (uartHandle->baseAddress->UART_MIS.BIT.oemis == BASE_CFG_ENABLE) { /* Overflow error interrupt */ + error |= uartHandle->baseAddress->UART_MIS.BIT.oemis; + uartHandle->baseAddress->UART_ICR.BIT.oeic = BASE_CFG_ENABLE; + } else if (uartHandle->baseAddress->UART_MIS.BIT.bemis == BASE_CFG_ENABLE) { /* Break error interrupt */ + error |= uartHandle->baseAddress->UART_MIS.BIT.bemis; + uartHandle->baseAddress->UART_ICR.BIT.beic = BASE_CFG_ENABLE; + } else if (uartHandle->baseAddress->UART_MIS.BIT.pemis == BASE_CFG_ENABLE) { /* Check error interrupt */ + error |= uartHandle->baseAddress->UART_MIS.BIT.pemis; + uartHandle->baseAddress->UART_ICR.BIT.peic = BASE_CFG_ENABLE; + } else if (uartHandle->baseAddress->UART_MIS.BIT.femis == BASE_CFG_ENABLE) { /* Frame error interrupt */ + error |= uartHandle->baseAddress->UART_MIS.BIT.femis; + uartHandle->baseAddress->UART_ICR.BIT.feic = BASE_CFG_ENABLE; + } + if (error != 0x00) { + uartHandle->errorType = error; + if (uartHandle->rxMode == UART_MODE_INTERRUPT && uartHandle->userCallBack.TransmitItErrorCallBack != NULL) { + uartHandle->userCallBack.TransmitItErrorCallBack(uartHandle); + } + } + return; +} + +/** + * @brief UART Interrupt service processing function. + * @param handle UART handle. + * @retval None. + */ +void HAL_UART_IrqHandler(void *handle) +{ + UART_ASSERT_PARAM(handle != NULL); + UART_Handle *uartHandle = (UART_Handle *)handle; + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + /* when tx interrupt is generated */ + if ((uartHandle->baseAddress->UART_MIS.BIT.txmis == 0x01) || + (uartHandle->baseAddress->UART_MIS.BIT.txfeis == 0x01)) { + WriteITCallBack(uartHandle); + } + /* when rx interrupt is generated */ + if ((uartHandle->baseAddress->UART_MIS.BIT.rxmis == 0x01 || uartHandle->baseAddress->UART_MIS.BIT.rtmis == 0x01) || + (uartHandle->baseAddress->UART_MIS.BIT.rxfneis == 0x1)) { + ReadITCallBack(uartHandle); + } + /* when charter match interrupt is generated */ + if (uartHandle->baseAddress->UART_MIS.BIT.cmis == 0x01) { + CharterMatchCallBack(uartHandle); + } + /* when baud detect interrupt is generated */ + if (uartHandle->baseAddress->UART_MIS.BIT.abdcis == 0x01 || uartHandle->baseAddress->UART_MIS.BIT.abdeis == 0x01) { + BaudDetectCallBack(uartHandle); + } + /* when error interrupt is generated */ + if ((uartHandle->baseAddress->UART_MIS.reg & 0x780) != 0) { + ErrorServiceCallback(uartHandle); + } + return; +} + +/** + * @brief User callback function registration interface. + * @param uartHandle UART handle. + * @param typeID Id of callback function type, @ref UART_CallbackFun_Type + * @param pCallback pointer of the specified callbcak function, @ref UART_CallbackType + * @retval BASE_StatusType: OK, ERROR. + */ +BASE_StatusType HAL_UART_RegisterCallBack(UART_Handle *uartHandle, UART_CallbackFun_Type typeID, + UART_CallbackType pCallback) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + switch (typeID) { + case UART_WRITE_IT_FINISH: + uartHandle->userCallBack.WriteItFinishCallBack = pCallback; /* Write INT finish callback register */ + break; + case UART_READ_IT_FINISH: + uartHandle->userCallBack.ReadItFinishCallBack = pCallback; /* Read INT finish callback register */ + break; + case UART_WRITE_DMA_FINISH: + uartHandle->userCallBack.WriteDmaFinishCallBack = pCallback; /* DMA write finish callback register */ + break; + case UART_READ_DMA_FINISH: + uartHandle->userCallBack.ReadDmaFinishCallBack = pCallback; /* DMA read finish callback register */ + break; + case UART_TRNS_IT_ERROR: + uartHandle->userCallBack.TransmitItErrorCallBack = pCallback; /* INT Trans error callback register */ + break; + case UART_TRNS_DMA_ERROR: + uartHandle->userCallBack.TransmitDmaErrorCallBack = pCallback; /* DMA Trans error callback register */ + break; + case UART_BAUD_DETECT_FINISH: + uartHandle->userCallBack.BaudDetectSuccessCallBack = pCallback; /* Baud detect finish callback register */ + break; + case UART_BAUD_DETECT_ERROR: + uartHandle->userCallBack.BaudDetectErrorCallBack = pCallback; /* Baud detect error callback register */ + break; + case UART_CHARACTER_MATCH: + uartHandle->userCallBack.CharacterMatchCallBack = pCallback; /* character match callback register */ + break; + default: + return BASE_STATUS_ERROR; + } + return BASE_STATUS_OK; +} + +/** + * @brief UART DMA(rx to memory), cyclically stores data to specified memory(saveData). + * @param uartHandle UART handle. + * @param saveData Address of the data buff to be sent. + * @param tempNode DMA Link List, @ref DMA_LinkList + * @param dataLength number of the data to be sent. + * @retval BASE status type: OK, ERROR, BUSY, TIMEOUT. + */ +BASE_StatusType HAL_UART_ReadDMAAndCyclicallyStored(UART_Handle *uartHandle, unsigned char *saveData, + DMA_LinkList *tempNode, unsigned int dataLength) +{ + /* Param check */ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(tempNode != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_ASSERT_PARAM(saveData != NULL); + UART_PARAM_CHECK_WITH_RET(dataLength > 0, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(uartHandle->rxMode == UART_MODE_DMA, BASE_STATUS_ERROR); + UART_PARAM_CHECK_WITH_RET(IsDmaChannelNum(uartHandle->uartDmaRxChn) == true, BASE_STATUS_ERROR); + UART_ASSERT_PARAM(uartHandle->dmaHandle != NULL); + + unsigned int channel = uartHandle->uartDmaRxChn; + if (uartHandle->rxState == UART_STATE_READY) { + uartHandle->rxState = UART_STATE_BUSY_RX; + uartHandle->baseAddress->UART_IMSC.BIT.rxim = BASE_CFG_DISABLE; /* Disable RX interrupt bit */ + uartHandle->rxbuff = saveData; + uartHandle->rxBuffSize = dataLength; + + /* Init DMA Channel Params */ + DMA_ChannelParam dmaParams; + dmaParams.direction = uartHandle->dmaHandle->DMA_Channels[channel].direction; + dmaParams.srcAddrInc = uartHandle->dmaHandle->DMA_Channels[channel].srcAddrInc; + dmaParams.destAddrInc = uartHandle->dmaHandle->DMA_Channels[channel].destAddrInc; + dmaParams.srcPeriph = uartHandle->dmaHandle->DMA_Channels[channel].srcPeriph; + dmaParams.destPeriph = uartHandle->dmaHandle->DMA_Channels[channel].destPeriph; + dmaParams.srcWidth = uartHandle->dmaHandle->DMA_Channels[channel].srcWidth; + dmaParams.destWidth = uartHandle->dmaHandle->DMA_Channels[channel].destWidth; + dmaParams.srcBurst = uartHandle->dmaHandle->DMA_Channels[channel].srcBurst; + dmaParams.destBurst = uartHandle->dmaHandle->DMA_Channels[channel].destBurst; + + /* Initialize List Node */ + if (HAL_DMA_InitNewNode(tempNode, &dmaParams, (uintptr_t)(void *)&(uartHandle->baseAddress->UART_DR), \ + (uintptr_t)(void *)uartHandle->rxbuff, dataLength) != BASE_STATUS_OK) { + uartHandle->rxState = UART_STATE_READY; + return BASE_STATUS_ERROR; + } + if (HAL_DMA_ListAddNode(tempNode, tempNode) != BASE_STATUS_OK) { + uartHandle->rxState = UART_STATE_READY; + return BASE_STATUS_ERROR; + } + + /* Can not masking overflow error, break error, check error, frame error interrupt */ + if (HAL_DMA_StartListTransfer(uartHandle->dmaHandle, tempNode, channel) != BASE_STATUS_OK) { + uartHandle->rxState = UART_STATE_READY; + return BASE_STATUS_ERROR; + } + uartHandle->baseAddress->UART_DMACR.BIT.rxdmae = BASE_CFG_ENABLE; /* Enable RX_DMA bit */ + } else { + /* Rx not ready */ + return BASE_STATUS_BUSY; + } + /* All done */ + return BASE_STATUS_OK; +} + +/** + * @brief Obtains offset address of DMA transfer address relative to specified memory (rxbuff). + * @param uartHandle UART handle. + * @retval offset address of DMA transfer address relative to specified memory (rxbuff). + */ +unsigned int HAL_UART_ReadDMAGetPos(UART_Handle *uartHandle) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(uartHandle->dmaHandle != NULL); + UART_ASSERT_PARAM(uartHandle->rxbuff != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_PARAM_CHECK_WITH_RET(IsDmaChannelNum(uartHandle->uartDmaRxChn) == true, BASE_STATUS_ERROR); + UART_ASSERT_PARAM(uartHandle->dmaHandle->DMA_Channels[uartHandle->uartDmaRxChn].channelAddr != NULL); + unsigned int writePos = 0; + /* Obtain the read destination address */ + unsigned int readAddress = uartHandle->dmaHandle->\ + DMA_Channels[uartHandle->uartDmaRxChn].channelAddr->DMA_Cn_DEST_ADDR.reg; + if (readAddress > (uintptr_t)uartHandle->rxbuff) { + writePos = readAddress - (uintptr_t)uartHandle->rxbuff; /* Number of characters currently transferred */ + } else { + writePos = 0; + } + return writePos; +} \ No newline at end of file diff --git a/src/drivers/uart/uart_v3/src/uart_ex.c b/src/drivers/uart/uart_v3/src/uart_ex.c new file mode 100644 index 0000000000000000000000000000000000000000..4dd980fc1fe621dc831978003f2363d56304ec34 --- /dev/null +++ b/src/drivers/uart/uart_v3/src/uart_ex.c @@ -0,0 +1,157 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file uart_ex.c + * @author MCU Driver Team + * @brief UART module driver. + * @details This file provides firmware functions to manage the following + * functionalities of the UART. + * + Initialization and de-initialization functions. + * + Peripheral send and receive functions in blocking mode. + * + Peripheral send and receive functions in interrupt mode. + * + Peripheral send and receive functions in DMA mode. + * + Peripheral stop sending and receiving functions in interrupt/DMA mode. + * + Interrupt callback function and user registration function. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "uart_ex.h" +/* Macro definitions ---------------------------------------------------------*/ + +/** + * @brief Open the character matching function of the UART RX and set the matching character. + * @param uartHandle UART handle. + * @param ch Characters to be matched. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_UART_OpenCharacterMatchEx(UART_Handle *uartHandle, unsigned char ch) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + uartHandle->baseAddress->UART_IMSC.BIT.cmim = BASE_CFG_ENABLE; + uartHandle->baseAddress->UART_CHARMATCH.BIT.chamat = (unsigned int)ch; /* Sets the matching character. */ + uartHandle->baseAddress->UART_CHARMATCH.BIT.cmen = BASE_CFG_ENABLE; + return BASE_STATUS_OK; +} + +/** + * @brief Close the character matching function of the UART RX. + * @param uartHandle UART handle. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_UART_CloseCharacterMatchEx(UART_Handle *uartHandle) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + uartHandle->baseAddress->UART_CHARMATCH.BIT.cmen = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_IMSC.BIT.cmim = BASE_CFG_DISABLE; /* Turn off character matching */ + return BASE_STATUS_OK; +} + +/** + * @brief Enable the UART to automatically identify the baud rate and enable the corresponding interrupt. + * @param uartHandle UART handle. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_UART_EnableBaudDetectionEx(UART_Handle *uartHandle) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + uartHandle->baseAddress->UART_CR.BIT.txe = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_CR.BIT.rxe = BASE_CFG_DISABLE; /* Disable TX and RX first */ + uartHandle->baseAddress->UART_IMSC.BIT.abdeim = BASE_CFG_ENABLE; + uartHandle->baseAddress->UART_IMSC.BIT.abdcim = BASE_CFG_ENABLE; + uartHandle->baseAddress->UART_ABDEN.BIT.abden = BASE_CFG_ENABLE; + return BASE_STATUS_OK; +} + +/** + * @brief Disable the UART to automatically identify the baud rate. + * @param uartHandle UART handle. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_UART_DisableBaudDetectionEx(UART_Handle *uartHandle) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + uartHandle->baseAddress->UART_ABDEN.BIT.abden = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_IMSC.BIT.abdeim = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_IMSC.BIT.abdcim = BASE_CFG_DISABLE; + uartHandle->baseAddress->UART_CR.BIT.txe = BASE_CFG_ENABLE; /* Enable TX */ + uartHandle->baseAddress->UART_CR.BIT.rxe = BASE_CFG_ENABLE; /* Enable RX */ + return BASE_STATUS_OK; +} + +/** + * @brief Configuring the upper limit of Rx timeout. + * @param uartHandle UART handle. + * @param cntOfBit timeout is defined as the time spent in transmitting N bits, numer of N is cntOfBit. + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_UART_SetRxWaitTimeEx(UART_Handle *uartHandle, unsigned int cntOfBit) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_PARAM_CHECK_WITH_RET(cntOfBit <= 0xFFFFFF, BASE_STATUS_ERROR); + uartHandle->baseAddress->UART_RTCFG.reg = cntOfBit; /* Set wait time */ + return BASE_STATUS_OK; +} + +/** + * @brief Sets UART oversampling multiple. + * @param uartHandle UART handle. + * @param multiple Oversampling multiple, @ref UART_OversampleMultiple + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_UART_SetOversampleMultipleEx(UART_Handle *uartHandle, UART_OversampleMultiple multiple) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_PARAM_CHECK_WITH_RET(IsUartOversampleMultiple(multiple), BASE_STATUS_ERROR); + uartHandle->baseAddress->UART_SPCFG.BIT.spcfg = multiple; /* Oversample setting */ + return BASE_STATUS_OK; +} + +/** + * @brief Sets the first bit of the character transmitted in the UART transmission. + * @param uartHandle UART handle. + * @param mode Sequence mode : LSB/MSB, @ref UART_SequenceMode + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_UART_SetDataSequenceModeEx(UART_Handle *uartHandle, UART_SequenceMode mode) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_PARAM_CHECK_WITH_RET(IsUartSequenceMode(mode), BASE_STATUS_ERROR); + uartHandle->baseAddress->UART_DS.BIT.msbfirst = mode; /* Data sequence setting */ + return BASE_STATUS_OK; +} + +/** + * @brief Set the number of lines in the UART communication. + * @param uartHandle UART handle. + * @param lineMode line mode, @ref UART_LineMode + * @retval BASE status type: OK, ERROR. + */ +BASE_StatusType HAL_UART_SetLineModeEx(UART_Handle *uartHandle, UART_LineMode lineMode) +{ + UART_ASSERT_PARAM(uartHandle != NULL); + UART_ASSERT_PARAM(IsUARTInstance(uartHandle->baseAddress)); + UART_PARAM_CHECK_WITH_RET(IsUartLineMode(lineMode), BASE_STATUS_ERROR); + uartHandle->baseAddress->UART_CR.BIT.hdsel = lineMode; /* Data sequence setting */ + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/src/drivers/wdg/wdg_v0/inc/wdg_ip.h b/src/drivers/wdg/wdg_v0/inc/wdg_ip.h index 512f579341580f7da8fff790066974af4a8625c2..9e8f6d72ee1f96a8436c9962c193b04dc512e51f 100644 --- a/src/drivers/wdg/wdg_v0/inc/wdg_ip.h +++ b/src/drivers/wdg/wdg_v0/inc/wdg_ip.h @@ -286,23 +286,6 @@ static inline bool IsWdgTimeType(WDG_TimeType timeType) timeType == WDG_TIME_UNIT_MS || timeType == WDG_TIME_UNIT_US); } - -/** - * @brief check wdg time value parameter. - * @param baseAddress Value of @ref WDG_RegStruct - * @param timeValue time value - * @param timeType Value of @ref WDG_TimeType. - * @retval Bool. - */ -static inline bool IsWdgTimeValue(WDG_RegStruct *baseAddress, float timeValue, WDG_TimeType timeType) -{ - float clockFreq = (float)HAL_CRG_GetIpFreq((void *)baseAddress); - float maxSecond = (float)(0xFFFFFFFF / clockFreq); /* 0xFFFFFFFF max WDG register value */ - return ((timeType == WDG_TIME_UNIT_TICK && timeValue <= 0xFFFFFFFF) || - (timeType == WDG_TIME_UNIT_S && maxSecond >= timeValue) || - (timeType == WDG_TIME_UNIT_MS && maxSecond >= timeValue / FREQ_CONVERT_MS_UNIT) || - (timeType == WDG_TIME_UNIT_US && maxSecond >= timeValue / FREQ_CONVERT_US_UNIT)); -} /** * @} */ diff --git a/src/drivers/wdg/wdg_v0/src/wdg.c b/src/drivers/wdg/wdg_v0/src/wdg.c index 3edca1d23972adfe12370cd20ac75875e0a20498..4131c7fbe6a4e40b1ea9f5d21842a85da22b50d7 100644 --- a/src/drivers/wdg/wdg_v0/src/wdg.c +++ b/src/drivers/wdg/wdg_v0/src/wdg.c @@ -28,8 +28,35 @@ #include "interrupt.h" #include "wdg.h" +#define WDG_COUNT_MAX 0xFFFFFFFF +#define TIME_CHANGE_NUM 1000 + static unsigned int WDG_CalculateRegTimeout(WDG_RegStruct *baseAddress, float timeValue, WDG_TimeType timeType); +/** + * @brief check wdg time value parameter. + * @param baseAddress Value of @ref WDG_RegStruct + * @param timeValue time value + * @param timeType Value of @ref WDG_TimeType. + * @retval Bool. + */ +static bool IsWdgTimeValue(WDG_RegStruct *baseAddress, float timeValue, WDG_TimeType timeType) +{ + unsigned int clockFreq = HAL_CRG_GetIpFreq((void *)baseAddress); /* Get WDG clock freq. */ + if (clockFreq == 0) { + return false; + } + + double maxSecValue = ((double)(WDG_COUNT_MAX) / (double)clockFreq); + double maxMsValue = maxSecValue * TIME_CHANGE_NUM; + double maxUsValue = maxMsValue * TIME_CHANGE_NUM; + /* Check wdg time value parameter. */ + return ((timeType == WDG_TIME_UNIT_TICK && timeValue <= (float)WDG_COUNT_MAX) || + (timeType == WDG_TIME_UNIT_S && maxSecValue >= timeValue) || + (timeType == WDG_TIME_UNIT_MS && maxMsValue >= timeValue) || + (timeType == WDG_TIME_UNIT_US && maxUsValue >= timeValue)); +} + /** * @brief Initializing WDG values * @param handle Value of @ref WDG_handle. @@ -40,8 +67,7 @@ BASE_StatusType HAL_WDG_Init(WDG_Handle *handle) WDG_ASSERT_PARAM(handle != NULL); WDG_ASSERT_PARAM(IsWDGInstance(handle->baseAddress)); WDG_PARAM_CHECK_WITH_RET(IsWdgTimeType(handle->timeType), BASE_STATUS_ERROR); - WDG_PARAM_CHECK_WITH_RET(IsWdgTimeValue(handle->baseAddress, handle->timeValue, handle->timeType), - BASE_STATUS_ERROR); + /* baseaddress = WDG */ HAL_WDG_SetTimeValue(handle, handle->timeValue, handle->timeType); /* Set Watchdog Reset and Interrupt */ @@ -91,7 +117,10 @@ void HAL_WDG_SetTimeValue(WDG_Handle *handle, unsigned int timeValue, WDG_TimeTy WDG_ASSERT_PARAM(handle != NULL); WDG_ASSERT_PARAM(IsWDGInstance(handle->baseAddress)); WDG_PARAM_CHECK_NO_RET(IsWdgTimeType(timeType)); - WDG_PARAM_CHECK_NO_RET(IsWdgTimeValue(handle->baseAddress, timeValue, timeType)); + /* Check wdg time value parameter. */ + if (IsWdgTimeValue(handle->baseAddress, timeValue, timeType) == false) { + return; + } /* handle->baseAddress only could be configured WDG */ unsigned int value = WDG_CalculateRegTimeout(handle->baseAddress, timeValue, timeType); DCL_WDG_SetLoadValue(handle->baseAddress, value); diff --git a/src/drivers/wwdg/wwdg_v1/inc/wwdg_ip.h b/src/drivers/wwdg/wwdg_v1/inc/wwdg_ip.h index 35bf7ac5b365aa381c7e745d5d9ef0ce054350bc..7b6223e3d9c3dac04114e70857b3fe298527ffa2 100644 --- a/src/drivers/wwdg/wwdg_v1/inc/wwdg_ip.h +++ b/src/drivers/wwdg/wwdg_v1/inc/wwdg_ip.h @@ -349,7 +349,7 @@ static inline void DCL_WWDG_SetFreqDivValue(WWDG_RegStruct *wwdgx, WWDG_FreqDivT WWDG_PARAM_CHECK_NO_RET(freqDiv < WWDG_FREQ_DIV_MAX); wwdgx->WWDOG_KEY.BIT.wwdg_key = WWDG_UNLOCK_REG_CMD; wwdgx->WWDOG_PRE_DIV.BIT.wwdg_pre_div = freqDiv; /* freqDiv parameters set */ - wwdgx->WWDOG_KEY.BIT.wwdg_key = WWDG_UNLOCK_REG_CMD; + wwdgx->WWDOG_KEY.BIT.wwdg_key = WWDG_LOCK_REG_CMD; } /** @@ -487,24 +487,6 @@ static inline bool IsWwdgTimeType(WWDG_TimeType timeType) timeType == WWDG_TIME_UNIT_MS || timeType == WWDG_TIME_UNIT_US); } - -/** - * @brief check wdg time value parameter. - * @param baseAddress Value of @ref WDG_RegStruct - * @param timeValue time value - * @param timeType Value of @ref WDG_TimeType. - * @retval Bool. - */ -static inline bool IsWwdgTimeValue(WWDG_RegStruct *baseAddress, float timeValue, WWDG_TimeType timeType) -{ - float clockFreq = (float)HAL_CRG_GetIpFreq((void *)baseAddress); - float maxSecond = (float)(0xFFFFFFFF / clockFreq); /* 0xFFFFFFFF max input value */ - return ((timeType == WWDG_TIME_UNIT_TICK && timeValue <= 0xFFFFFFFF) || - (timeType == WWDG_TIME_UNIT_S && maxSecond >= timeValue) || - (timeType == WWDG_TIME_UNIT_MS && maxSecond >= timeValue / FREQ_CONVERT_MS_UNIT) || - (timeType == WWDG_TIME_UNIT_US && maxSecond >= timeValue / FREQ_CONVERT_US_UNIT)); -} - /** * @} */ diff --git a/src/drivers/wwdg/wwdg_v1/src/wwdg.c b/src/drivers/wwdg/wwdg_v1/src/wwdg.c index aa00350dfa82078b7dc9b88cbdc33b622b34fef0..b90e3fd8b270756ad21f7fa895b7544c2605e3c2 100644 --- a/src/drivers/wwdg/wwdg_v1/src/wwdg.c +++ b/src/drivers/wwdg/wwdg_v1/src/wwdg.c @@ -31,8 +31,37 @@ /* Macro definitions ---------------------------------------------------------*/ #define WWDG_LOAD_VALUE_LIMIT 65535 #define WWDG_WINDOW_VALUE_LIMIT 65535 +#define WWDG_COUNT_MAX 0x0000FFFF +#define TIME_CHANGE_NUM 1000 static unsigned int WWDG_CalculateRegTimeout(WWDG_RegStruct *baseAddress, float timeValue, WWDG_TimeType timeType); +/** + * @brief check wwdg time value parameter. + * @param baseAddress Value of @ref WDG_RegStruct + * @param timeValue time value + * @param timeType Value of @ref WDG_TimeType. + * @retval Bool. + */ +static bool IsWwdgTimeValue(WWDG_RegStruct *baseAddress, float timeValue, WWDG_TimeType timeType) +{ + unsigned int clockFreq = HAL_CRG_GetIpFreq((void *)baseAddress); /* Get WDG clock freq. */ + WWDG_RegStruct *wwdgx = (WWDG_RegStruct *)baseAddress; + if (clockFreq == 0) { + return false; + } + + unsigned int preDiv = wwdgx->WWDOG_PRE_DIV.BIT.wwdg_pre_div; /* Get clock prediv. */ + preDiv = WWDG_COUNT_MAX * (BASE_CFG_SET << preDiv); + float maxSecValue = ((float)(preDiv) / (float)clockFreq); + float maxMsValue = maxSecValue * TIME_CHANGE_NUM; + float maxUsValue = maxMsValue * TIME_CHANGE_NUM; + /* Check wdg time value parameter. */ + return ((timeType == WWDG_TIME_UNIT_TICK && timeValue <= (float)WWDG_COUNT_MAX) || + (timeType == WWDG_TIME_UNIT_S && maxSecValue >= timeValue) || + (timeType == WWDG_TIME_UNIT_MS && maxMsValue >= timeValue) || + (timeType == WWDG_TIME_UNIT_US && maxUsValue >= timeValue)); +} + /** * @brief Initializing WWDG values * @param handle Value of @ref WWDG_handle. @@ -43,8 +72,7 @@ BASE_StatusType HAL_WWDG_Init(WWDG_Handle *handle) WWDG_ASSERT_PARAM(handle != NULL); WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); WWDG_PARAM_CHECK_WITH_RET(IsWwdgTimeType(handle->timeType), BASE_STATUS_ERROR); - WWDG_PARAM_CHECK_WITH_RET(IsWwdgTimeValue(handle->baseAddress, handle->timeValue, handle->timeType), - BASE_STATUS_ERROR); + /* The frequency divide value cannot exceed 8192. */ unsigned int freqDivVal = (handle->freqDivValue > WWDG_FREQ_DIV_MAX) ? WWDG_FREQ_DIV_8192 : handle->freqDivValue; DCL_WWDG_SetFreqDivValue(handle->baseAddress, freqDivVal); @@ -108,7 +136,11 @@ void HAL_WWDG_SetTimeValue(WWDG_Handle *handle, unsigned int timeValue, WWDG_Tim WWDG_ASSERT_PARAM(handle != NULL); WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); WWDG_PARAM_CHECK_NO_RET(IsWwdgTimeType(timeType)); - WWDG_PARAM_CHECK_NO_RET(IsWwdgTimeValue(handle->baseAddress, timeValue, timeType)); + + /* Check wwdg time value parameter. */ + if (IsWwdgTimeValue(handle->baseAddress, handle->timeValue, handle->timeType) == false) { + return; + } /* handle->baseAddress only could be configed WWDG */ unsigned int value = WWDG_CalculateRegTimeout(handle->baseAddress, timeValue, timeType); unsigned int freqDiv = DCL_WWDG_GetFreqDivValue(handle->baseAddress); diff --git a/src/drivers/wwdg/wwdg_v2/inc/wwdg_ex.h b/src/drivers/wwdg/wwdg_v2/inc/wwdg_ex.h new file mode 100644 index 0000000000000000000000000000000000000000..6f520c3bd6b39a21e414e39d3b87f552d4228b88 --- /dev/null +++ b/src/drivers/wwdg/wwdg_v2/inc/wwdg_ex.h @@ -0,0 +1,49 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file wwdg_ex.h + * @author MCU Driver Team + * @brief WWDG module driver + * @details The header file contains the following declaration: + * + WWDG Set And Get Functions. + */ + +#ifndef McuMagicTag_WWDG_EX_H +#define McuMagicTag_WWDG_EX_H + +/* Includes ------------------------------------------------------------------*/ +#include "wwdg.h" +/** + * @addtogroup WWDG_IP + * @{ + */ + +/** + * @defgroup WWDG_API_EX_Declaration WWDG HAL API EX + * @{ + */ +void HAL_WWDG_EnableWindowModeEx(WWDG_Handle *handle); +void HAL_WWDG_DisableWindowModeEx(WWDG_Handle *handle); + +/** + * @} + */ + +/** + * @} + */ +#endif /* McuMagicTag_WWDG_H */ \ No newline at end of file diff --git a/src/drivers/wwdg/wwdg_v2/inc/wwdg_ip.h b/src/drivers/wwdg/wwdg_v2/inc/wwdg_ip.h new file mode 100644 index 0000000000000000000000000000000000000000..0716804899930ed15534b4b78ced8dc4ffdebfb5 --- /dev/null +++ b/src/drivers/wwdg/wwdg_v2/inc/wwdg_ip.h @@ -0,0 +1,514 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file wwdg_ip.h + * @author MCU Driver Team + * @brief WWDG module driver + * @details The header file contains the following declaration: + * + WWDG configuration enums. + * + WWDG register structures. + * + WWDG DCL Functions. + * + Parameters check functions. + */ + +#ifndef McuMagicTag_WWDG_IP_H +#define McuMagicTag_WWDG_IP_H + +/* Includes ------------------------------------------------------------------*/ +#include "baseinc.h" + +/* Macro definition */ + +#ifdef WWDG_PARAM_CHECK + #define WWDG_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM + #define WWDG_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET + #define WWDG_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else + #define WWDG_ASSERT_PARAM(para) ((void)0U) + #define WWDG_PARAM_CHECK_NO_RET(para) ((void)0U) + #define WWDG_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) +#endif + +/** + * @addtogroup WWDG + * @{ + */ + +/** + * @defgroup WWDG_IP WWDG_IP + * @brief WWDG_IP: wwdg_v1. + * @{ + */ + +/** + * @defgroup WWDG_Param_Def WWDG Parameters Definition + * @brief Description of WWDG configuration parameters. + * @{ + */ +/* MACRO definitions -------------------------------------------------------*/ +#define FREQ_CONVERT_MS_UNIT 1000 +#define FREQ_CONVERT_US_UNIT 1000000 +#define WWDG_UNLOCK_REG_CMD 0x55 /* 0x55 CMD: key equal 0x55 will unlock all reg write function */ +#define WWDG_LOCK_REG_CMD 0xFF /* 0xFF CMD: key not equal 0x55 will lock reg write function except key reg */ + +/* Typedef definitions -------------------------------------------------------*/ +typedef enum { + WWDG_TIME_UNIT_TICK = 0x00000000U, + WWDG_TIME_UNIT_S = 0x00000001U, + WWDG_TIME_UNIT_MS = 0x00000002U, + WWDG_TIME_UNIT_US = 0x00000003U +} WWDG_TimeType; + +typedef enum { + WWDG_FREQ_DIV_4 = 0x00000000U, + WWDG_FREQ_DIV_8 = 0x00000001U, + WWDG_FREQ_DIV_16 = 0x00000002U, + WWDG_FREQ_DIV_32 = 0x00000003U, + WWDG_FREQ_DIV_64 = 0x00000004U, + WWDG_FREQ_DIV_128 = 0x00000005U, + WWDG_FREQ_DIV_256 = 0x00000006U, + WWDG_FREQ_DIV_512 = 0x00000007U, + WWDG_FREQ_DIV_1024 = 0x00000008U, + WWDG_FREQ_DIV_2048 = 0x00000009U, + WWDG_FREQ_DIV_4096 = 0x0000000AU, + WWDG_FREQ_DIV_8192 = 0x0000000BU, + WWDG_FREQ_DIV_MAX +} WWDG_FreqDivType; + +/** + * @brief WWDG extend handle. + */ +typedef struct _WWDG_ExtendHandle { +} WWDG_ExtendHandle; + +/** + * @brief WWDG user callback. + */ +typedef struct { + void (* CallbackFunc)(void *handle); /**< WWDG callback Function */ +} WWDG_UserCallBack; +/** + * @} + */ + +/** + * @defgroup WWDG_Reg_Def WWDG Register Definition + * @brief Description WWDG register mapping structure. + * @{ + */ +/** + * @brief WWDG load init value. + */ +typedef union { + unsigned int reg; + struct { + unsigned int wwdg_load : 16; /**< init value. */ + unsigned int reserved0 : 16; + } BIT; +} WWDG_LOAD_REG; + +/** + * @brief WWDG get current value. + */ +typedef union { + unsigned int reg; + struct { + unsigned int wwdg_value : 16; /**< current value. */ + unsigned int reserved0 : 16; + } BIT; +} WWDG_VALUE_REG; + +/** + * @brief WWDG set window value. + */ +typedef union { + unsigned int reg; + struct { + unsigned int wwdg_window : 16; /**< window value. */ + unsigned int reserved0 : 16; + } BIT; +} WWDG_WINDOW_REG; + +/** + * @brief WWDG cmd function value. + */ +typedef union { + unsigned int reg; + struct { + unsigned int wwdg_key : 8; /**< cmd function value. */ + unsigned int reserved0 : 24; + } BIT; +} WWDG_KEY_REG; + +/** + * @brief WWDG clk pre div value. + */ +typedef union { + unsigned int reg; + struct { + unsigned int wwdg_pre_div : 4; /**< clk pre div value. */ + unsigned int reserved0 : 28; + } BIT; +} WWDG_PRE_DIV_REG; + +/** + * @brief WWDG enable interrupt and reset. + */ +typedef union { + unsigned int reg; + struct { + unsigned int inten : 1; /**< enable interrupt. */ + unsigned int resen : 1; /**< enable reset. */ + unsigned int window_mode_en : 1; /**< enable window mode. */ + unsigned int reserved0 : 29; + } BIT; +} WWDG_CONTROL_REG; + +/** + * @brief WWDG orignal interrupt signal. + */ +typedef union { + unsigned int reg; + struct { + unsigned int wwdgris : 1; /**< original interrupt status. */ + unsigned int reserve : 31; + } BIT; +} WWDG_RIS_REG; + +/** + * @brief mask interrupt signal. + */ +typedef union { + unsigned int reg; + struct { + unsigned int wwdgmis : 1; /**< maske interrupt status. */ + unsigned int reserve : 31; + } BIT; +} WWDG_MIS_REG; + +/** + * @brief WWDG Register Structure definition. + */ +typedef struct { + WWDG_LOAD_REG WWDG_LOAD; /**< WWDG load value register. */ + WWDG_VALUE_REG WWDG_VALUE; /**< WWDG current value register. */ + WWDG_WINDOW_REG WWDG_WINDOW; /**< WWDG Window value register. */ + WWDG_KEY_REG WWDG_KEY; /**< WWDG instruction word register. */ + WWDG_PRE_DIV_REG WWDG_PRE_DIV; /**< WWDG prescale register. */ + WWDG_CONTROL_REG WWDG_CONTROL; /**< WWDG interrupt, reset and window enable register. */ + WWDG_RIS_REG WWDG_RIS; /**< WWDG orignal interrupt register. */ + WWDG_MIS_REG WWDG_MIS; /**< WWDG mask interrupt register. */ +} volatile WWDG_RegStruct; + +/** + * @} + */ + +/** + * @brief Setting the load value of the WWDG counter. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @param loadValue Load value of the WWDG counter. + * @retval None. + */ +static inline void DCL_WWDG_SetLoadValue(WWDG_RegStruct *wwdgx, unsigned short loadValue) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_UNLOCK_REG_CMD; + wwdgx->WWDG_LOAD.BIT.wwdg_load = loadValue; + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_LOCK_REG_CMD; +} + +/** + * @brief Getting the load value of the WWDG load register. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval unsigned short WWDG load value. + */ +static inline unsigned short DCL_WWDG_GetLoadValue(const WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + return wwdgx->WWDG_LOAD.BIT.wwdg_load; +} + +/** + * @brief Getting the value of the WWDG counter register. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval unsigned short WWDG counter value. + */ +static inline unsigned short DCL_WWDG_GetCounterValue(const WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + return wwdgx->WWDG_VALUE.BIT.wwdg_value; +} + +/** + * @brief Setting window value. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @param windowValue window value of the WWDG counter. + * @retval None. + */ +static inline void DCL_WWDG_SetWindowValue(WWDG_RegStruct *wwdgx, unsigned short windowValue) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_UNLOCK_REG_CMD; + wwdgx->WWDG_WINDOW.BIT.wwdg_window = windowValue; + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_LOCK_REG_CMD; +} + +/** + * @brief Getting window value, windowValue need bigger than 4. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @param windowValue window value of the WWDG counter. + * @retval unsigned short wwdg window value. + */ +static inline unsigned short DCL_WWDG_GetWindowValue(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + return wwdgx->WWDG_WINDOW.BIT.wwdg_window; +} + +/** + * @brief Start wwdg function. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval None. + */ +static inline void DCL_WWDG_Start(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = 0xCC; /* 0xCC CMD: start wwdg function */ +} + +/** + * @brief Stop wwdg function. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval None. + */ +static inline void DCL_WWDG_Stop(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = 0xDD; /* 0xDD CMD: stop wwdg function */ +} + +/** + * @brief Clear interrupt and reload watchdog counter value. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval None. + */ +static inline void DCL_WWDG_Refresh(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = 0xAA; /* 0xAA CMD: clear interrupt and reload value */ +} + +/** + * @brief Disable write and read WWDG registers except WWDG_LOCK. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval None. + */ +static inline void DCL_WWDG_LockReg(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = 0xFF; /* 0xFF CMD: key not equal 0x55 will lock reg write function except key reg */ +} + +/** + * @brief Enable write and read WWDG registers. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval None. + */ +static inline void DCL_WWDG_UnlockReg(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = 0x55; /* 0x55 CMD: key equal 0x55 will unlock all reg write function */ +} + +/** + * @brief Setting freq div value, value need litter than 13. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @param freqDiv freqDiv value of the WWDG counter. + * @retval None. + */ +static inline void DCL_WWDG_SetFreqDivValue(WWDG_RegStruct *wwdgx, WWDG_FreqDivType freqDiv) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + WWDG_PARAM_CHECK_NO_RET(freqDiv < WWDG_FREQ_DIV_MAX); + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_UNLOCK_REG_CMD; + wwdgx->WWDG_PRE_DIV.BIT.wwdg_pre_div = freqDiv; /* freqDiv parameters set */ + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_LOCK_REG_CMD; +} + +/** + * @brief Getting freq div value, value need litter than 13. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @param freqDiv freqDiv value of the WWDG counter. + * @retval None. + */ +static inline unsigned char DCL_WWDG_GetFreqDivValue(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + return wwdgx->WWDG_PRE_DIV.BIT.wwdg_pre_div; +} + +/** + * @brief Enable reset signal. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval None. + */ +static inline void DCL_WWDG_EnableReset(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_UNLOCK_REG_CMD; + wwdgx->WWDG_CONTROL.BIT.resen = BASE_CFG_SET; + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_LOCK_REG_CMD; +} + +/** + * @brief Disable reset signal. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval None. + */ +static inline void DCL_WWDG_DisableReset(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_UNLOCK_REG_CMD; + wwdgx->WWDG_CONTROL.BIT.resen = BASE_CFG_UNSET; + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_LOCK_REG_CMD; +} + +/** + * @brief Start watchdog and enable interrupt signal. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval None. + */ +static inline void DCL_WWDG_EnableInterrupt(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_UNLOCK_REG_CMD; + wwdgx->WWDG_CONTROL.BIT.inten = BASE_CFG_SET; + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_LOCK_REG_CMD; +} + +/** + * @brief Disable interrupt signal. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval None. + */ +static inline void DCL_WWDG_DisableInterrupt(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_UNLOCK_REG_CMD; + wwdgx->WWDG_CONTROL.BIT.inten = BASE_CFG_UNSET; + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_LOCK_REG_CMD; +} + +/** + * @brief Ensable Windows mode. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval None. + */ +static inline void DCL_WWDG_EnableWindowsMode(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_UNLOCK_REG_CMD; + wwdgx->WWDG_CONTROL.BIT.window_mode_en = BASE_CFG_SET; + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_LOCK_REG_CMD; +} + +/** + * @brief Disable Windows mode. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval None. + */ +static inline void DCL_WWDG_DisableWindowsMode(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_UNLOCK_REG_CMD; + wwdgx->WWDG_CONTROL.BIT.window_mode_en = BASE_CFG_UNSET; + wwdgx->WWDG_KEY.BIT.wwdg_key = WWDG_LOCK_REG_CMD; +} + +/** + * @brief Get Windows mode. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval bool is enable or disable. + */ +static inline bool DCL_WWDG_GetWindowsMode(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + return wwdgx->WWDG_CONTROL.BIT.window_mode_en; +} + +/** + * @brief Getting value of WWDG RIS register. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval unsigned int Value of WWDG RIS register. + */ +static inline unsigned int DCL_WWDG_GetRIS(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + return wwdgx->WWDG_RIS.BIT.wwdgris; +} + +/** + * @brief Getting value of WWDG MIS register. + * @param wwdgx Value of @ref WWDG_RegStruct. + * @retval unsigned int Value of WWDG MIS register. + */ +static inline unsigned int DCL_WWDG_GetMIS(WWDG_RegStruct *wwdgx) +{ + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgx)); + return wwdgx->WWDG_MIS.BIT.wwdgmis; +} + +/** + * @brief check wwdg time type parameter. + * @param timeType Value of @ref WWDG_TimeType. + * @retval Bool. + */ +static inline bool IsWwdgTimeType(WWDG_TimeType timeType) +{ + return (timeType == WWDG_TIME_UNIT_TICK || + timeType == WWDG_TIME_UNIT_S || + timeType == WWDG_TIME_UNIT_MS || + timeType == WWDG_TIME_UNIT_US); +} + +/** + * @brief check wdg time value parameter. + * @param baseAddress Value of @ref WDG_RegStruct + * @param timeValue time value + * @param timeType Value of @ref WDG_TimeType. + * @retval Bool. + */ +static inline bool IsWwdgTimeValue(WWDG_RegStruct *baseAddress, float timeValue, WWDG_TimeType timeType) +{ + float clockFreq = (float)HAL_CRG_GetIpFreq((void *)baseAddress); + float maxSecond = (float)((float)0xFFFFFFFF / clockFreq); /* 0xFFFFFFFF max input value */ + return ((timeType == WWDG_TIME_UNIT_TICK && timeValue <= (float)0xFFFFFFFF) || + (timeType == WWDG_TIME_UNIT_S && maxSecond >= timeValue) || + (timeType == WWDG_TIME_UNIT_MS && maxSecond >= timeValue / FREQ_CONVERT_MS_UNIT) || + (timeType == WWDG_TIME_UNIT_US && maxSecond >= timeValue / FREQ_CONVERT_US_UNIT)); +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* McuMagicTag_WWDG_IP_H */ \ No newline at end of file diff --git a/src/drivers/wwdg/wwdg_v2/src/wwdg.c b/src/drivers/wwdg/wwdg_v2/src/wwdg.c new file mode 100644 index 0000000000000000000000000000000000000000..b816d5a726153bf45f1f9f46504a49eb9917cea3 --- /dev/null +++ b/src/drivers/wwdg/wwdg_v2/src/wwdg.c @@ -0,0 +1,257 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file wwdg.c + * @author MCU Driver Team + * @brief WWDG module driver + * @details This file provides firmware functions to manage the following functionalities of the WWDG. + * + Initialization functions. + * + WWDG Set And Get Functions. + * + Interrupt Handler Functions. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "interrupt.h" +#include "wwdg.h" + +/* Macro definitions ---------------------------------------------------------*/ +#define WWDG_LOAD_VALUE_LIMIT 65535 +#define WWDG_WINDOW_VALUE_LIMIT 65535 +static unsigned int WWDG_CalculateRegTimeout(WWDG_RegStruct *baseAddress, float timeValue, WWDG_TimeType timeType); + +/** + * @brief Initializing WWDG values + * @param handle Value of @ref WWDG_handle. + * @retval BASE_StatusType: OK, ERROR + */ +BASE_StatusType HAL_WWDG_Init(WWDG_Handle *handle) +{ + WWDG_ASSERT_PARAM(handle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); + WWDG_PARAM_CHECK_WITH_RET(IsWwdgTimeType(handle->timeType), BASE_STATUS_ERROR); + WWDG_PARAM_CHECK_WITH_RET(IsWwdgTimeValue(handle->baseAddress, handle->timeValue, handle->timeType), + BASE_STATUS_ERROR); + /* The frequency divide value cannot exceed 8192. */ + unsigned int freqDivVal = (handle->freqDivValue > WWDG_FREQ_DIV_MAX) ? WWDG_FREQ_DIV_8192 : handle->freqDivValue; + DCL_WWDG_SetFreqDivValue(handle->baseAddress, freqDivVal); + HAL_WWDG_SetTimeValue(handle, handle->timeValue, handle->timeType); + /* Window mode enable */ + if (handle->baseAddress->WWDG_CONTROL.BIT.window_mode_en == BASE_CFG_ENABLE) { + unsigned int value = + WWDG_CalculateRegTimeout(handle->baseAddress, handle->windowValue, handle->timeType); + unsigned int freqDiv = DCL_WWDG_GetFreqDivValue(handle->baseAddress); + value = (value / (1 << (freqDiv + 2))); /* 1 << (freqDiv + 2) is freq div value */ + /* The upper limit of the window value is determined. */ + value = (value <= WWDG_WINDOW_VALUE_LIMIT) ? value : WWDG_WINDOW_VALUE_LIMIT; + /* window value only could be set litter than load value */ + value = (value < handle->baseAddress->WWDG_LOAD.BIT.wwdg_load) ? value : + handle->baseAddress->WWDG_LOAD.BIT.wwdg_load; + DCL_WWDG_SetWindowValue(handle->baseAddress, value); + } + DCL_WWDG_EnableInterrupt(handle->baseAddress); /* enable interrupt */ + DCL_WWDG_EnableReset(handle->baseAddress); /* enable reset */ + return BASE_STATUS_OK; +} + +/** + * @brief Calculate Reg Timeout. + * @param timeValue Value to be load to wwdg. + * @param timeType Value of @ref WWDG_TimeType. + * @retval unsigned int timeout Value. + */ +static unsigned int WWDG_CalculateRegTimeout(WWDG_RegStruct *baseAddress, float timeValue, WWDG_TimeType timeType) +{ + float clockFreq = (float)HAL_CRG_GetIpFreq((void *)baseAddress); + unsigned int timeoutValue = 0x00000000U; + switch (timeType) { + case WWDG_TIME_UNIT_TICK: /* If the time type is tick, calculate the timeout value. */ + timeoutValue = (unsigned int)timeValue; + break; + case WWDG_TIME_UNIT_S: /* If the time type is s, calculate the timeout value. */ + timeoutValue = (unsigned int)(timeValue * clockFreq); + break; + case WWDG_TIME_UNIT_MS: /* If the time type is ms, calculate the timeout value. */ + timeoutValue = (unsigned int)(timeValue * clockFreq / FREQ_CONVERT_MS_UNIT); + break; + case WWDG_TIME_UNIT_US: /* If the time type is us, calculate the timeout value. */ + timeoutValue = (unsigned int)(timeValue * clockFreq / FREQ_CONVERT_US_UNIT); + break; + default: + break; + } + return timeoutValue; +} + +/** + * @brief Setting the load value of the WWDG counter. + * @param handle Value of @ref WWDG_handle. + * @param timeValue time value of the WWDG counter. + * @param timeType WWDG time type. + * @retval None. + */ +void HAL_WWDG_SetTimeValue(WWDG_Handle *handle, unsigned int timeValue, WWDG_TimeType timeType) +{ + WWDG_ASSERT_PARAM(handle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); + WWDG_PARAM_CHECK_NO_RET(IsWwdgTimeType(timeType)); + WWDG_PARAM_CHECK_NO_RET(IsWwdgTimeValue(handle->baseAddress, timeValue, timeType)); + /* handle->baseAddress only could be configed WWDG */ + unsigned int value = WWDG_CalculateRegTimeout(handle->baseAddress, timeValue, timeType); + unsigned int freqDiv = DCL_WWDG_GetFreqDivValue(handle->baseAddress); + value = (value / (1 << (freqDiv + 2))); /* 1 << (freqDiv + 2) is freq div value */ + /* The upper limit of the loaded value is determined. */ + value = (value <= WWDG_LOAD_VALUE_LIMIT) ? value : WWDG_LOAD_VALUE_LIMIT; + DCL_WWDG_SetLoadValue(handle->baseAddress, value); +} + +/** + * @brief refresh the WWDG counter. + * @param handle Value of @ref WWDG_handle. + * @retval None. + */ +void HAL_WWDG_Refresh(WWDG_Handle *handle) +{ + WWDG_ASSERT_PARAM(handle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); + DCL_WWDG_Refresh(handle->baseAddress); +} + +/** + * @brief obtain the load value. + * @param handle Value of @ref WWDG_handle. + * @retval unsigned int time value. + */ +unsigned int HAL_WWDG_GetLoadValue(WWDG_Handle *handle) +{ + WWDG_ASSERT_PARAM(handle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); + return DCL_WWDG_GetLoadValue(handle->baseAddress); +} + +/** + * @brief Getting the window value of the WWDG counter. + * @param handle Value of @ref WWDG_handle. + * @retval unsigned int the value of window reg value. + */ +unsigned int HAL_WWDG_GetWindowValue(WWDG_Handle *handle) +{ + WWDG_ASSERT_PARAM(handle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); + /* handle->baseAddress only could be configed WWDG */ + return DCL_WWDG_GetWindowValue(handle->baseAddress); +} + +/** + * @brief Refresh the WWDG counter value. + * @param handle Value of @ref WWDG_handle. + * @retval unsigned int Counter value. + */ +unsigned int HAL_WWDG_GetCounterValue(WWDG_Handle *handle) +{ + WWDG_ASSERT_PARAM(handle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); + + float res = (float)handle->baseAddress->WWDG_VALUE.BIT.wwdg_value; + if (res >= 65535) { /* 65535 is WWDG maximum current count */ + return handle->timeValue; + } + unsigned int freq = HAL_CRG_GetIpFreq((void *)handle->baseAddress); + /* check clockFreq not equal zero */ + if (freq == 0) { + return 0; + } + unsigned int freqDiv = DCL_WWDG_GetFreqDivValue(handle->baseAddress); + switch (handle->timeType) { + case WWDG_TIME_UNIT_TICK: + /* Number of tick currently calculated */ + res = res * (1 << (freqDiv + 2)); /* 1 << (freqDiv + 2) is freq div value */ + break; + case WWDG_TIME_UNIT_S: + /* Number of seconds currently calculated */ + res = res * (1 << (freqDiv + 2)) / freq; /* 1 << (freqDiv + 2) is freq div value */ + break; + case WWDG_TIME_UNIT_MS: + /* 1 << (freqDiv + 2) is freq div value */ + res = res * (1 << (freqDiv + 2)) * FREQ_CONVERT_MS_UNIT / freq; + break; + case WWDG_TIME_UNIT_US: + /* Number of microseconds currently calculated, 1 << (freqDiv + 2) is freq div value */ + res = res * (1 << (freqDiv + 2)) * FREQ_CONVERT_US_UNIT / freq; + break; + default: + break; + } + return (unsigned int)res; +} + +/** + * @brief Start the WWDG count. + * @param handle Value of @ref WWDG_handle. + * @retval None. + */ +void HAL_WWDG_Start(WWDG_Handle *handle) +{ + WWDG_ASSERT_PARAM(handle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); + DCL_WWDG_Start(handle->baseAddress); +} + +/** + * @brief Stop the WWDG count. + * @param handle Value of @ref WWDG_handle. + * @retval None. + */ +void HAL_WWDG_Stop(WWDG_Handle *handle) +{ + WWDG_ASSERT_PARAM(handle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); + DCL_WWDG_Stop(handle->baseAddress); /* Stop WWDG Count. */ +} + +/** + * @brief Register WWDG interrupt callback. + * @param handle Value of @ref WWDG_handle. + * @param callBackFunc Value of @ref WWDG_CallbackType. + * @retval None + */ +void HAL_WWDG_RegisterCallback(WWDG_Handle *handle, WWDG_CallbackType callBackFunc) +{ + WWDG_ASSERT_PARAM(handle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); + if (callBackFunc != NULL) { + /* Invoke the callback function. */ + handle->userCallBack.CallbackFunc = callBackFunc; + } +} + +/** + * @brief Interrupt handler processing function. + * @param handle WWDG_Handle. + * @retval None. + */ +void HAL_WWDG_IrqHandler(void *handle) +{ + WWDG_Handle *wwdgHandle = (WWDG_Handle *)handle; + WWDG_ASSERT_PARAM(wwdgHandle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(wwdgHandle->baseAddress)); + + if (wwdgHandle->baseAddress->WWDG_MIS.BIT.wwdgmis == 0x01) { /* Interrupt flag is set, fed dog in callback */ + if (wwdgHandle->userCallBack.CallbackFunc) { + wwdgHandle->userCallBack.CallbackFunc(wwdgHandle); + } + } +} diff --git a/src/drivers/wwdg/wwdg_v2/src/wwdg_ex.c b/src/drivers/wwdg/wwdg_v2/src/wwdg_ex.c new file mode 100644 index 0000000000000000000000000000000000000000..36a32b1cc8b900879f4efea624930d4f615505a9 --- /dev/null +++ b/src/drivers/wwdg/wwdg_v2/src/wwdg_ex.c @@ -0,0 +1,52 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file wwdg_ex.c + * @author MCU Driver Team + * @brief WWDG module driver + * @details This file provides firmware functions to manage the following functionalities of the WWDG. + * + WWDG Set And Get Functions. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "interrupt.h" +#include "wwdg_ex.h" + +/* Macro definitions ---------------------------------------------------------*/ +/** + * @brief Enable window mode. + * @param handle Value of @ref WWDG_handle. + * @retval None. + */ +void HAL_WWDG_EnableWindowModeEx(WWDG_Handle *handle) +{ + WWDG_ASSERT_PARAM(handle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); + DCL_WWDG_EnableWindowsMode(handle->baseAddress); +} + +/** + * @brief Disable window mode. + * @param handle Value of @ref WWDG_handle. + * @retval None. + */ +void HAL_WWDG_DisableWindowModeEx(WWDG_Handle *handle) +{ + WWDG_ASSERT_PARAM(handle != NULL); + WWDG_ASSERT_PARAM(IsWWDGInstance(handle->baseAddress)); + DCL_WWDG_DisableWindowsMode(handle->baseAddress); +} \ No newline at end of file diff --git a/src/middleware/control_library/adc_calibra/mcs_adcCalibr.c b/src/middleware/control_library/adc_calibr/mcs_adcCalibr.c similarity index 100% rename from src/middleware/control_library/adc_calibra/mcs_adcCalibr.c rename to src/middleware/control_library/adc_calibr/mcs_adcCalibr.c diff --git a/src/middleware/control_library/adc_calibra/mcs_adcCalibr.h b/src/middleware/control_library/adc_calibr/mcs_adcCalibr.h similarity index 100% rename from src/middleware/control_library/adc_calibra/mcs_adcCalibr.h rename to src/middleware/control_library/adc_calibr/mcs_adcCalibr.h diff --git a/src/middleware/control_library/brake/mcs_brake.c b/src/middleware/control_library/brake/mcs_brake.c index 357cce8d27ec5db3082e6e5b4cf66f55ae3d30d1..0e04b0b90a6c07dac0551ba8407719a1fdfc12da 100644 --- a/src/middleware/control_library/brake/mcs_brake.c +++ b/src/middleware/control_library/brake/mcs_brake.c @@ -17,34 +17,51 @@ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * @file mcs_brake.c * @author MCU Algorithm Team - * @brief This file provides functions of brake module. + * @brief Math library. + * This file provides functions declaration of brake module. */ + #include "mcs_brake.h" #include "mcs_math.h" #include "mcs_assert.h" +#define PHASE_MAX_NUM 3 /** * @brief Initialize brake handle. - * @param brake: Pointer of Brake Handle. - * @param brkParam: Brake parameters. + * @param brake Pointer of brake handle. + * @param brkParam Brake parameters. + * @param ts Brake cycle. * @retval None. */ -void BRAKE_Init(BRAKE_Handle *brake, BRAKE_Param *brkParam) +void BRAKE_Init(BRAKE_Handle *brake, BRAKE_Param brkParam, float ts) { MCS_ASSERT_PARAM(brake != NULL); - MCS_ASSERT_PARAM(brkParam != NULL); - MCS_ASSERT_PARAM(brkParam->ts > 0.0f); + MCS_ASSERT_PARAM(ts > 0.0f); /* Set brake parameter. */ - brake->brkParam = brkParam; - brake->sampleShiftDuty = brkParam->sampleWinTime / brkParam->ts; + brake->ts = ts; + brake->brkFinished = 0; + + brake->brkParam.brkTime = brkParam.brkTime; + brake->brkParam.maxBrkCurr = brkParam.maxBrkCurr; + + brake->brkParam.blindDutyThr = brkParam.blindDutyThr; + brake->brkParam.blindBrkDutyStep = brkParam.blindBrkDutyStep; + + brake->brkParam.fastBrkCurrCoeff = brkParam.fastBrkCurrCoeff; + brake->brkParam.fastBrkDutyStep = brkParam.fastBrkDutyStep; + + brake->brkParam.slowBrkDutyStep = brkParam.slowBrkDutyStep; + + brake->brkParam.aptMaxCmp = brkParam.aptMaxCmp; + /* Brake count. */ - brake->tickNum = (unsigned int)(brkParam->brkTime / brkParam->ts); + brake->tickNum = (unsigned int)(brkParam.brkTime / ts); } /** * @brief Clear historical values of brake handle. - * @param brake: Pointer of Brake Handle. + * @param brake Pointer of brake handle. * @retval None. */ void BRAKE_Clear(BRAKE_Handle *brake) @@ -53,53 +70,92 @@ void BRAKE_Clear(BRAKE_Handle *brake) brake->brkDuty = 0.0f; /* brake duty */ /* counter for calculating brake time */ brake->tickCnt = 0; + brake->brkCurr = 0.0f; + brake->brkFinished = 0; /* brake status */ - brake->brkFlg = 0; + brake->status = BRAKE_CLOSED_LOOP; + brake->stage = BRAKE_INIT; +} - brake->brkFlg = BRAKE_WAIT; +/** + * @brief Set brake duty. + * @param aptAddr APT address pointer. + * @param maxCmp Maximum count of APT. + * @param brkDuty Braje duty. + * @retval None. + */ +static void BRAKE_SetPwmDuty(APT_RegStruct **aptAddr, unsigned short maxCmp, float brkDuty) +{ + /* Calc brake compare point according to the duty. */ + unsigned short comparePoint = (unsigned short)Clamp((brkDuty * maxCmp), (float)(maxCmp - 1), 1.0f); + /* Set pwm waveform according C D point. */ + for (int i = 0; i < PHASE_MAX_NUM; i++) { + APT_RegStruct *aptAddrx = aptAddr[i]; + DCL_APT_SetCounterCompare(aptAddrx, APT_COMPARE_REFERENCE_C, comparePoint); + DCL_APT_SetCounterCompare(aptAddrx, APT_COMPARE_REFERENCE_D, comparePoint); + } } /** * @brief Brake execution. - * @param brake: Pointer of Brake Handle. - * @param brkCurr: Sampling result of current during brake condition (A). + * @param BRAKE_Handle Pointer of brake handle. + * @param aptAddr APT address pointer. + * @param brkCurr Sampling result of current during brake condition (A). * @retval None. */ -void BRAKE_Exec(BRAKE_Handle *brake, float brkCurr) +void BRAKE_Exec(BRAKE_Handle *brake, APT_RegStruct **aptAddr, float brkCurr) { MCS_ASSERT_PARAM(brake != NULL); - MCS_ASSERT_PARAM(brkCurr > 0.0f); - float dutyMax = 1.0f; float curr = Abs(brkCurr); - float maxCurr = brake->brkParam->maxBrkCurr; - float sampleShiftDuty = brake->sampleShiftDuty; + float maxCurr = brake->brkParam.maxBrkCurr; + float dutyMax = 1.0f; unsigned int tickNum = brake->tickNum; - if (brake->brkFlg == BRAKE_FINISHED) { + if (brake->stage != BRAKE_EXEC) { return; } - /* Collect statistics on the total braking duration */ brake->tickCnt++; if (brake->tickCnt >= tickNum) { - /* Time to push out the brakes */ - brake->brkFlg = BRAKE_FINISHED; + /* Time to push out the brakes. */ + brake->brkFinished = 1; + return; } - if (curr < (maxCurr * brake->brkParam->fastBrkCurrCoeff)) { - brake->brkDuty += brake->brkParam->maxBrkDutyStep; - } else if (curr < maxCurr) { - brake->brkDuty += brake->brkParam->minBrkDutyStep; - } else { - brake->brkDuty -= brake->brkParam->maxBrkDutyStep; - } + /** + * Brake process: + * (1) when brake current is more than maxCurr, brake duty decrease BRAKE_DUTY_FAST every period. + * (2) when brake current is less than maxCurr, brake duty increase BRAKE_DUTY_SLOW every period. + * (3) when brake current is less than (coeff * maxCurr), brake duty increase BRAKE_DUTY_FAST every period. + * (4) when brake current is less than (maxCurr - 0.1) and brake duty is more than dutyThr, + * brake duty increase BRAKE_DUTY_BLIND every period. + * Attention: The max brake duty is 1.0. + */ + switch (brake->status) { + case BRAKE_CLOSED_LOOP: + if (curr < brake->brkParam.fastBrkCurrCoeff * maxCurr) { + brake->brkDuty += brake->brkParam.fastBrkDutyStep; /* (3) */ + } else if (curr < maxCurr) { + brake->brkDuty += brake->brkParam.slowBrkDutyStep; /* (2) */ + brake->brkDuty = Clamp(brake->brkDuty, brake->brkParam.blindDutyThr, 0.0f); + } else { + brake->brkDuty -= brake->brkParam.fastBrkDutyStep; /* (1) */ + } + + brake->status = (brake->brkDuty >= brake->brkParam.blindDutyThr && curr <= (maxCurr - 0.1f))? + BRAKE_OPEN_LOOP : BRAKE_CLOSED_LOOP; /* (4) */ + break; - /* Reserved sampling window */ - brake->brkDuty = Clamp(brake->brkDuty, dutyMax - 2.0f * sampleShiftDuty, 0.0f); - if (curr <= (maxCurr * brake->brkParam->openLoopBrkCurrCoeff) && - brake->brkDuty >= dutyMax - 3.0f * sampleShiftDuty) { - /* Because the duty cycle is too large to collect the current, the brake open loop control */ - brake->brkDuty += brake->brkParam->openLoopBrkDutyStep; - brake->brkDuty = Clamp(brake->brkDuty, dutyMax, 0.0f); + case BRAKE_OPEN_LOOP: + brake->brkDuty += brake->brkParam.blindBrkDutyStep; /* (4) */ + break; + + default: + brake->brkDuty = dutyMax; + break; } -} + + brake->brkDuty = Clamp(brake->brkDuty, dutyMax, 0.0f); + /* Set brake duty. */ + BRAKE_SetPwmDuty(aptAddr, brake->brkParam.aptMaxCmp, brake->brkDuty); +} \ No newline at end of file diff --git a/src/middleware/control_library/brake/mcs_brake.h b/src/middleware/control_library/brake/mcs_brake.h index 26a867ae29bb5173db5f00939ae246cee9a90a12..e542949b3e7d7ecfcae05f79cc06cd242c801e6c 100644 --- a/src/middleware/control_library/brake/mcs_brake.h +++ b/src/middleware/control_library/brake/mcs_brake.h @@ -15,47 +15,75 @@ * 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. - * @file mcs_brake.c + * @file mcs_brake.h * @author MCU Algorithm Team - * @brief This file provides functions of brake module. + * @brief Math library. + * This file provides functions declaration of brake module. */ #ifndef McuMagicTag_MCS_BRAKE_H #define McuMagicTag_MCS_BRAKE_H +#include "mcs_typedef.h" +#include "apt.h" /* Typedef definitions ------------------------------------------------------------------------- */ + + /** - * @brief Brake Struct. + * @brief Brake Param. */ typedef struct { - float ts; /**< control period (s). */ float brkTime; /**< brake time (s). */ - float sampleWinTime; /**< sample shift. */ float maxBrkCurr; /**< maximum brake current (A). */ - float minBrkDutyStep; /**< small brake duty step, recommend value: 0.001f. */ - float maxBrkDutyStep; /**< large brake duty step, recommend value: 0.005f. */ + + float blindDutyThr; /**< brake duty cycle when entering open-loop braking state */ + float blindBrkDutyStep; /**< large brake duty step per period. */ + float fastBrkCurrCoeff; /**< current threshold coefficient for fast braking, recommend value: 0.5f. */ - float openLoopBrkDutyStep; /**< open-loop brake duty step, recommend value: 0.0001f. */ - float openLoopBrkCurrCoeff; /**< current threshold coefficient for open-loop braking, recommend value: 0.2f. */ + float fastBrkDutyStep; /**< large brake duty step per period. */ + + float slowBrkDutyStep; /**< small brake duty step per period. */ + + unsigned short aptMaxCmp; /**< apt maximum count. */ } BRAKE_Param; +/** + * @brief Brake status enum. + */ +typedef enum { + BRAKE_CLOSED_LOOP = 0, /**< Closed loop. */ + BRAKE_OPEN_LOOP /**< Open loop. */ +} BRAKE_Status; + + +/** + * @brief Brake Stage. + */ +typedef enum { + BRAKE_INIT = 0, /**< Brake init, include APT configuration. */ + BRAKE_EXEC, /**< Brake exec, include brake current sample and brake duty adjust. */ + BRAKE_FINISHED /**< Brake finished. */ +} BRAKE_Stage; + +/** + * @brief Brake Struct. + */ typedef struct { + float ts; /**< control period (s). */ float brkDuty; /**< pwm duty ratio of lower switch during brake condition (0~1). */ - float sampleShiftDuty; /**< phase shift duty of sample point for brake current (0~1). */ + float brkCurr; /**< brake current (A). */ unsigned int tickCnt; /**< counter for calculating brake time. */ unsigned int tickNum; /**< count number corresponding to brake time. */ - unsigned char brkFlg; /**< brake status. */ - BRAKE_Param *brkParam; + unsigned int brkFinished; /**< brake finish flag. */ + BRAKE_Stage stage; /**< brake stage. */ + BRAKE_Status status; /**< brake status. */ + BRAKE_Param brkParam; /**< brake parameter. */ } BRAKE_Handle; -typedef enum { - BRAKE_WAIT = 0, - BRAKE_FINISHED -} BRAKE_Status; -void BRAKE_Init(BRAKE_Handle *brake, BRAKE_Param *brkParam); +void BRAKE_Init(BRAKE_Handle *brake, BRAKE_Param brkParam, float ts); void BRAKE_Clear(BRAKE_Handle *brake); -void BRAKE_Exec(BRAKE_Handle *brake, float brkCurr); +void BRAKE_Exec(BRAKE_Handle *brake, APT_RegStruct **aptAddr, float brkCurr); -#endif +#endif \ No newline at end of file diff --git a/src/middleware/control_library/filter/mcs_filter.c b/src/middleware/control_library/filter/mcs_filter.c index 1aadd97a00b12c4029c8b1efa5f176be0cef2359..bec4565b2631df6e235869641ec70e1b9e9aa80e 100644 --- a/src/middleware/control_library/filter/mcs_filter.c +++ b/src/middleware/control_library/filter/mcs_filter.c @@ -91,4 +91,20 @@ void FOLPF_SetTs(FOFLT_Handle *lpfHandle, float ts) float wcTs = DOUBLE_PI * lpfHandle->fc * ts; lpfHandle->a1 = 1.0f / (1.0f + wcTs); /* wcTs > 0 */ lpfHandle->b1 = 1.0f - lpfHandle->a1; +} + +/** + * @brief Set Cut-off frequency of first-order filter. + * @param lpfHandle First-order filter handle. + * @param fc Cut-off frequency (Hz). + * @retval None. + */ +void FOLPF_SetFc(FOFLT_Handle *lpfHandle, float fc) +{ + MCS_ASSERT_PARAM(lpfHandle != NULL); + MCS_ASSERT_PARAM(fc > 0.0f); + lpfHandle->fc = fc; + float wcTs = DOUBLE_PI * lpfHandle->fc * lpfHandle->ts; + lpfHandle->a1 = 1.0f / (1.0f + wcTs); /* wcTs > 0 */ + lpfHandle->b1 = 1.0f - lpfHandle->a1; } \ No newline at end of file diff --git a/src/middleware/control_library/filter/mcs_filter.h b/src/middleware/control_library/filter/mcs_filter.h index 7fee90fc94e294b1d802bd73aea34bfc45ec497d..78bfcb9d9fd22aecfdc8de6639eb57e43e9aa693 100644 --- a/src/middleware/control_library/filter/mcs_filter.h +++ b/src/middleware/control_library/filter/mcs_filter.h @@ -48,11 +48,12 @@ typedef struct { * @brief Filter function API declaration. * Transfer Func: G(s) = kw/(s+w), k = 1. */ + void FOLPF_Init(FOFLT_Handle *lpfHandle, float ts, float fc); void FOLPF_Clear(FOFLT_Handle *lpfHandle); float FOLPF_Exec(FOFLT_Handle *lpfHandle, float u); void FOLPF_SetTs(FOFLT_Handle *lpfHandle, float ts); - +void FOLPF_SetFc(FOFLT_Handle *lpfHandle, float fc); /** * @} diff --git a/src/middleware/control_library/filter/mcs_pll.c b/src/middleware/control_library/filter/mcs_pll.c index 8eba6cca05aae5031e81afbc7f24de4c447bf80a..390eb51bf5f70e5d53add980f09dc1c94ca19cd0 100644 --- a/src/middleware/control_library/filter/mcs_pll.c +++ b/src/middleware/control_library/filter/mcs_pll.c @@ -47,9 +47,8 @@ void PLL_Init(PLL_Handle *pllHandle, float ts, float bdw) pllHandle->freq = 0.0f; pllHandle->angle = 0.0f; pllHandle->ratio = DOUBLE_PI * ts; - pllHandle->pllBdw = bdw; pllHandle->pi.ts = pllHandle->ts; - PLL_ParamUpdate(pllHandle, pllHandle->pllBdw); + PLL_ParamUpdate(pllHandle, bdw); } /** diff --git a/src/middleware/control_library/filter/mcs_pll.h b/src/middleware/control_library/filter/mcs_pll.h index 7a0228b86188d164199bfa8e00d85c223f03efb1..b66eb8e05112e6be3e99d0d19a0090a7bc71138f 100644 --- a/src/middleware/control_library/filter/mcs_pll.h +++ b/src/middleware/control_library/filter/mcs_pll.h @@ -49,7 +49,6 @@ typedef struct { float ratio; /**< Conversion factor, ts * 65535 / TWO_PI. */ float freq; /**< Output estimated frequency (Hz). */ float angle; /**< Output estimated phasse angle. */ - float pllBdw; /**< pll bandWidth. */ } PLL_Handle; @@ -57,6 +56,7 @@ typedef struct { * @defgroup PLL_API PLL API * @brief The PLL module API definitions. */ + void PLL_Init(PLL_Handle *pllHandle, float ts, float bdw); void PLL_Reset(PLL_Handle *pllHandle); diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ctrl.c b/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ctrl.c index 17ecb6ee63172bb3496e662c2f2f514417fd64be..7331e48b6eed5508a3024a7806a9198221f120a4 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ctrl.c +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ctrl.c @@ -30,11 +30,11 @@ /** * @brief Initialzer of Current controller. * @param currHandle Current control handle. - * @param pidTable Motor control handle. * @param mtrParam Motor parameters. * @param idqRef idqRef. * @param idqFbk idqFbk. - * @param busVolt Bus voltage. + * @param dAxisPi PI parameter table of d axis. + * @param qAxisPi PI parameter table of q axis. * @param ts control period. * @retval None. */ @@ -89,7 +89,7 @@ void CURRCTRL_Reset(CURRCTRL_Handle *currHandle) currHandle->mtrParam = NULL; currHandle->outLimit = 0.0f; currHandle->ts = 0.0f; - /* Reset Dq axis PID current control */ + /* Reset Dq axis PID current control. */ PID_Reset(&currHandle->dAxisPi); PID_Reset(&currHandle->qAxisPi); } @@ -111,11 +111,11 @@ void CURRCTRL_Clear(CURRCTRL_Handle *currHandle) * @brief Simplified current controller PI calculation. * @param currHandle Current controller struct handle. * @param voltRef Dq-axis voltage reference which is the output of current controller. - * @param spd speed (Hz). + * @param spdRef Speed reference (Hz). * @param ffEnable Feedforward compensation enable. * @retval None. */ -void CURRCTRL_Exec(CURRCTRL_Handle *currHandle, DqAxis *vdqRef, float spd, int ffEnable) +void CURRCTRL_Exec(CURRCTRL_Handle *currHandle, DqAxis *vdqRef, float spdRef, int ffEnable) { MCS_ASSERT_PARAM(currHandle != NULL); MCS_ASSERT_PARAM(vdqRef != NULL); @@ -124,7 +124,7 @@ void CURRCTRL_Exec(CURRCTRL_Handle *currHandle, DqAxis *vdqRef, float spd, int f /* Calculate the current error of the dq axis. */ currHandle->dAxisPi.error = currHandle->idqRef->d - currHandle->idqFbk->d; currHandle->qAxisPi.error = currHandle->idqRef->q - currHandle->idqFbk->q; - CURRFF_Exec(&vdqFf, *currHandle->idqFbk, currHandle->mtrParam, spd, ffEnable); + CURRFF_Exec(&vdqFf, *currHandle->idqFbk, currHandle->mtrParam, spdRef, ffEnable); currHandle->dAxisPi.feedforward = vdqFf.d; currHandle->qAxisPi.feedforward = vdqFf.q; /* Calculation of the PI of the Dq axis current. */ diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ctrl.h b/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ctrl.h index 0fe6b555a4de5ca32d9c508d747d2fbb44f9ac5b..da384be290df5720a3abbb2f1fb99c85155fb0f4 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ctrl.h +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ctrl.h @@ -65,6 +65,7 @@ typedef struct { * @brief The current controller's API declaration. * @{ */ + void CURRCTRL_Init(CURRCTRL_Handle *currHandle, MOTOR_Param *mtrParam, DqAxis *idqRef, DqAxis *idqFbk, const PI_Param dAxisPi, const PI_Param qAxisPi, float ts); @@ -72,7 +73,7 @@ void CURRCTRL_Reset(CURRCTRL_Handle *currHandle); void CURRCTRL_Clear(CURRCTRL_Handle *currHandle); -void CURRCTRL_Exec(CURRCTRL_Handle *currHandle, DqAxis *vdqRef, float spd, int ffEnable); +void CURRCTRL_Exec(CURRCTRL_Handle *currHandle, DqAxis *vdqRef, float spdRef, int ffEnable); void CURRCTRL_SetTs(CURRCTRL_Handle *currHandle, float ts); diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ff.c b/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ff.c index 84ae2854793305ec275d155c6b3edec68793e00a..98cb7f4cd7470199828bb2fef0dbdb8565d66192 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ff.c +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ff.c @@ -29,16 +29,16 @@ * @param vdqFf DQ axis volt feedforward compensation value. * @param idqFbk DQ axis feedback current value. * @param param Motor parameters. - * @param spd Speed (Hz). + * @param spdRef Speed reference (Hz). * @param enable Whether to enable feedforward compensation. * @retval None. */ -void CURRFF_Exec(DqAxis *vdqFf, DqAxis idqFbk, MOTOR_Param *param, float spd, int enable) +void CURRFF_Exec(DqAxis *vdqFf, DqAxis idqFbk, MOTOR_Param *param, float spdRef, int enable) { MCS_ASSERT_PARAM(vdqFf != NULL); MCS_ASSERT_PARAM(param != NULL); /* The unit is converted from Hz to rad. */ - float we = spd * DOUBLE_PI; + float we = spdRef * DOUBLE_PI; if (enable) { /* Calculate the feedforward compensation value. */ vdqFf->d = -param->mtrLq * we * idqFbk.q; diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ff.h b/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ff.h index ba15e15b3c75bb1b2e5d5a170d9c9d681d2b204b..7ed2012192932d304d032c3c6a9e1d4ab2a38695 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ff.h +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_curr_ff.h @@ -26,6 +26,6 @@ #include "mcs_typedef.h" #include "mcs_mtr_param.h" -void CURRFF_Exec(DqAxis *vdqRef, DqAxis idqFbk, MOTOR_Param *param, float spd, int enable); +void CURRFF_Exec(DqAxis *vdqRef, DqAxis idqFbk, MOTOR_Param *param, float spdRef, int enable); #endif \ No newline at end of file diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_fw_ctrl.c b/src/middleware/control_library/foc_loop_ctrl/mcs_fw_ctrl.c index 3100ef65cafce9dea01ed24d8af210a2649745f5..6902ee50e19c8a16897d7df02803899e06053581 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_fw_ctrl.c +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_fw_ctrl.c @@ -28,7 +28,7 @@ * @param fw Flux-Weakening struct handle. * @retval None. */ -static void FW_Clear(FW_Handle *fw) +void FW_Clear(FW_Handle *fw) { MCS_ASSERT_PARAM(fw != NULL); fw->idRef = 0.0f; @@ -41,7 +41,7 @@ static void FW_Clear(FW_Handle *fw) * @param enable Enable flux-weakening. * @param currMax Maximum phase current (A). * @param idDemag Demagnetizing d-axis current (A). - * @param thr . + * @param thr Voltage usage at start of field weakening, recommand: 0.85f. * @retval None. */ void FW_Init(FW_Handle *fw, float ts, bool enable, float currMax, float idDemag, float thr, float slope) diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_fw_ctrl.h b/src/middleware/control_library/foc_loop_ctrl/mcs_fw_ctrl.h index 78ca1185335947d178f4c66467335e5f753cdb97..c5714bbefb48c214d75cc877a3942abe9b3e6e18 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_fw_ctrl.h +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_fw_ctrl.h @@ -26,7 +26,7 @@ typedef struct { bool enable; - float udcThreshPer; + float udcThreshPer; /* thr * ONE_DIV_SQRT3 */ float ts; float idSlope; float idRef; /* reference instruction value. */ @@ -42,4 +42,6 @@ void FW_Init(FW_Handle *fw, float ts, bool enable, float currMax, float idDemag, void FW_Exec(FW_Handle *fw, DqAxis udqRef, float udc, DqAxis *idqRefRaw); void FW_SetTs(FW_Handle *fw, float ts); + +void FW_Clear(FW_Handle *fw); #endif \ No newline at end of file diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_if_ctrl.c b/src/middleware/control_library/foc_loop_ctrl/mcs_if_ctrl.c index 7db97eb0396331a6dd88c837e402913093b17e94..80a47e3368de0afe132d79c5e854c4ec4832653a 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_if_ctrl.c +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_if_ctrl.c @@ -73,7 +73,7 @@ float IF_CurrAmpCalc(IF_Handle *ifHandle) if (ifHandle->curAmp < ifHandle->targetAmp) { ifHandle->curAmp += ifHandle->stepAmp; } else { - ifHandle->curAmp = ifHandle->targetAmp; + ifHandle->curAmp -= ifHandle->stepAmp; } return ifHandle->curAmp; diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_if_ctrl.h b/src/middleware/control_library/foc_loop_ctrl/mcs_if_ctrl.h index cd32b5c78c3db8bb81b61594d2eb30fc5db68a79..2448e832f912c1ebabdbecc19485df8b4b821e96 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_if_ctrl.h +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_if_ctrl.h @@ -55,6 +55,7 @@ typedef struct { * @brief The I/F motor control method API declaration. * @{ */ + void IF_Init(IF_Handle *ifHandle, float targetAmp, float currSlope, float stepAmpPeriod, float anglePeriod); void IF_Clear(IF_Handle *ifHandle); diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_pos_ctrl.c b/src/middleware/control_library/foc_loop_ctrl/mcs_pos_ctrl.c index 1e8922633659b6abfefd9137611836683309599a..140a72b593905a350b3858fe14cbf53bbf629331 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_pos_ctrl.c +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_pos_ctrl.c @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2022 - 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,7 +15,7 @@ * 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. - * @file mcs_posctrl.c + * @file mcs_pos_ctrl.c * @author MCU Algorithm Team * @brief This file provides function of motor position control. */ @@ -32,15 +32,21 @@ */ void POSCTRL_Clear(POSCTRL_Handle *posHandle) { + MCS_ASSERT_PARAM(posHandle != NULL); /* PID controller history values clear */ - posHandle->posPi.error = 0.0f; - posHandle->posPi.feedforward = 0.0f; - posHandle->posPi.differ = 0.0f; - posHandle->posPi.integral = 0.0f; - posHandle->posPi.saturation = 0.0f; + PID_Clear(&posHandle->posPid); - posHandle->posTarget = 0.0f; + /* trajectory mode: history values clear */ + posHandle->runTime = 0.0f; + posHandle->timeTick = 0.0f; + posHandle->deltaTime = 0.0f; + posHandle->accMax = 0.0f; /* the maximum accelerator. */ + posHandle->jerk = 0.0f; + posHandle->posTarget = 0.0f; /* Target position is 0. */ + posHandle->posIncRefPrev = 0.0f; + posHandle->posIncRef = 0.0f; posHandle->posErr = 0.0f; + posHandle->posFbkPrev = 0.0f; } /** @@ -48,23 +54,25 @@ void POSCTRL_Clear(POSCTRL_Handle *posHandle) * @param posHandle position controller struct handle. * @param ts Control period. */ -void POSCTRL_Init(POSCTRL_Handle *posHandle, const PID_Param *piCtrlTable, float ts) +void POSCTRL_Init(POSCTRL_Handle *posHandle, const PID_Param *pidCtrlTable, float ts, float posSlope) { + MCS_ASSERT_PARAM(posHandle != NULL); + MCS_ASSERT_PARAM(pidCtrlTable != NULL); POSCTRL_Clear(posHandle); posHandle->ts = ts; /* position PID controller initialization */ - posHandle->posPi.ts = posHandle->ts; - posHandle->posPi.kp = piCtrlTable->kp; - posHandle->posPi.ki = piCtrlTable->ki; - posHandle->posPi.kd = piCtrlTable->kd; - posHandle->posPi.ns = piCtrlTable->ns; - posHandle->posPi.ka = 1.0f / posHandle->posPi.kp; - posHandle->posPi.upperLimit = piCtrlTable->upperLim; - posHandle->posPi.lowerLimit = piCtrlTable->lowerLim; + posHandle->posPid.ts = posHandle->ts; + posHandle->posPid.kp = pidCtrlTable->kp; + posHandle->posPid.ki = pidCtrlTable->ki; + posHandle->posPid.kd = pidCtrlTable->kd; + posHandle->posPid.ns = pidCtrlTable->ns; + posHandle->posPid.ka = 1.0f / posHandle->posPid.kp; + posHandle->posPid.upperLimit = pidCtrlTable->upperLim; + posHandle->posPid.lowerLimit = -pidCtrlTable->upperLim; /* continuous mode: ramp controller initialization */ - RMG_Init(&posHandle->posRmg, posHandle->ts, posHandle->posRmg.slope * DOUBLE_PI); + RMG_Init(&posHandle->posRmg, posHandle->ts, posSlope); posHandle->posRmg.ts = posHandle->ts; /* position feedback history values clear */ @@ -93,8 +101,7 @@ void POSCTRL_ModeSelect(POSCTRL_Handle *posHandle, POSCTRL_Mode mode) */ void POSCTRL_SetSlope(POSCTRL_Handle *posHandle, float slope) { - posHandle->posRmg.slope = slope; - posHandle->posRmg.delta = posHandle->posRmg.ts * posHandle->posRmg.slope * DOUBLE_PI; + RMG_SetSlope(&posHandle->posRmg, slope * DOUBLE_PI); } /** @@ -118,7 +125,7 @@ float POSCTRL_AngleExpand(POSCTRL_Handle *posHandle, float angFbk) { float angFbkPrevFloat = posHandle->angFbkPrev; int loopPrev = posHandle->angFbkLoop; - int loop; + int loop; /* Number of rotation */ /* unify feedback angle to ±2*pi */ angFbk = Mod(angFbk, DOUBLE_PI); @@ -129,8 +136,10 @@ float POSCTRL_AngleExpand(POSCTRL_Handle *posHandle, float angFbk) /* check if angle rotates one cycle */ if (angFbkPrevFloat > THREE_PI_DIV_TWO && angFbkPrevFloat <= DOUBLE_PI && angFbk < HALF_PI) { + /* if theta_pre is at [270, 360), and theta is at [0, 90), that means one cycle increased. */ loop = loopPrev + 1; - } else if (angFbk > THREE_PI_DIV_TWO && THREE_PI_DIV_TWO <= DOUBLE_PI && angFbkPrevFloat < HALF_PI) { + } else if (angFbk > THREE_PI_DIV_TWO && angFbk <= DOUBLE_PI && angFbkPrevFloat < HALF_PI) { + /* if theta is at [270, 360), and theta_pre is at [0, 90), that means one cycle decreased. */ loop = loopPrev - 1; } else { loop = loopPrev; @@ -140,7 +149,7 @@ float POSCTRL_AngleExpand(POSCTRL_Handle *posHandle, float angFbk) posHandle->angFbkLoop = loop; posHandle->angFbkPrev = angFbk; - /* update output value */ + /* update output value, the absolute position is (360 * loop + theta). */ posHandle->posFbk = angFbk + loop * DOUBLE_PI; return posHandle->posFbk; @@ -150,26 +159,207 @@ float POSCTRL_AngleExpand(POSCTRL_Handle *posHandle, float angFbk) * @brief Position ring PID execution function. * @param posHandle Position controller struct handle. * @param posErr position error. - * @return float + * @return Speed reference. */ float POSCTRL_PidExec(POSCTRL_Handle *posHandle, float posErr) { float spdRef; - posHandle->posPi.error = posErr; - spdRef = PID_Exec(&posHandle->posPi); + posHandle->posPid.error = posErr; + spdRef = PID_Exec(&posHandle->posPid); return spdRef; } +/** + * @brief Trajectory planning calculation. + * @param posHandle Position controller struct handle. + * @param posFbk Position feedback. + * @param posIncRef. + */ +void POSCTRL_TrajCtrlPrepare(POSCTRL_Handle *posHandle, float posFbk, float *posIncRef) +{ + POSCTRL_Clear(posHandle); /* clear history values */ + posHandle->posTarget = posHandle->posTargetShadow; /* update position target */ + posHandle->posFbkPrev = posFbk; /* store position feedback before trajectory starts */ + posHandle->posErr = posHandle->posTarget - posHandle->posFbkPrev; /* position increment for this trajectory */ + + /* limit the maximum position change rate according to the speed limitation */ + float posSlope = posHandle->posRmg.slope; + + if (posSlope > posHandle->posPid.upperLimit * TWO_DIV_THREE) { + posSlope = posHandle->posPid.upperLimit * TWO_DIV_THREE; + } else if (posSlope < 0.0f) { + posSlope = 1.0f; + } + /* calulate whole trajectory lasts time (s) */ + posHandle->runTime = Abs(posHandle->posErr) / posSlope; + /* calulate each stage lasts time (s) */ + posHandle->deltaTime = posHandle->runTime * ONE_DIV_NINE; + /* square of deltaTime */ + posHandle->deltaTimeSq = posHandle->deltaTime * posHandle->deltaTime; + /* cube of deltaTime */ + posHandle->deltaTimeCu = posHandle->deltaTimeSq * posHandle->deltaTime; + /* jerk of the trajectory (m/s^3) */ + posHandle->jerk = posHandle->posErr * ONE_DIV_TWELVE / posHandle->deltaTimeCu; + /* maximum accelerate of the trajectory (m/s^2) */ + posHandle->accMax = posHandle->jerk * posHandle->deltaTime; + + /* trajectory time stage (s) , of the index 0, 1, 2, 3, 4, 5, 6. */ + posHandle->timeStg[TRAJ_STAGE_INDEX_0] = posHandle->deltaTime; + posHandle->timeStg[TRAJ_STAGE_INDEX_1] = 2.0f * posHandle->deltaTime; + posHandle->timeStg[TRAJ_STAGE_INDEX_2] = 3.0f * posHandle->deltaTime; + posHandle->timeStg[TRAJ_STAGE_INDEX_3] = 6.0f * posHandle->deltaTime; + posHandle->timeStg[TRAJ_STAGE_INDEX_4] = 7.0f * posHandle->deltaTime; + posHandle->timeStg[TRAJ_STAGE_INDEX_5] = 8.0f * posHandle->deltaTime; + posHandle->timeStg[TRAJ_STAGE_INDEX_6] = 9.0f * posHandle->deltaTime; + + *posIncRef = 0.0f; +} + +/** + * @brief Calculate the output position state. + * @param posHandle Position controller struct handle. + * @return stage. + */ +static POSCTRL_TRAJ_STAGE TrajPosState(POSCTRL_Handle *posHandle) +{ + POSCTRL_TRAJ_STAGE stage; + /**< trajectory control inner timer (s) */ + float timeTick = posHandle->timeTick; + /* Seven-segment trajectory time */ + float *timeStg = posHandle->timeStg; + /* Acceleration deacceleration state transition */ + if (timeTick < timeStg[TRAJ_STAGE_INDEX_0]) { + stage = TRAJ_STAGE_INDEX_0; + } else if (timeTick < timeStg[TRAJ_STAGE_INDEX_1]) { + stage = TRAJ_STAGE_INDEX_1; + } else if (timeTick < timeStg[TRAJ_STAGE_INDEX_2]) { + stage = TRAJ_STAGE_INDEX_2; + } else if (timeTick < timeStg[TRAJ_STAGE_INDEX_3]) { + stage = TRAJ_STAGE_INDEX_3; + } else if (timeTick < timeStg[TRAJ_STAGE_INDEX_4]) { + stage = TRAJ_STAGE_INDEX_4; + } else if (timeTick < timeStg[TRAJ_STAGE_INDEX_5]) { + stage = TRAJ_STAGE_INDEX_5; + } else if (timeTick < timeStg[TRAJ_STAGE_INDEX_6]) { + stage = TRAJ_STAGE_INDEX_6; + } else { + stage = TRAJ_STAGE_INDEX_7; + } + /* return trajectory state */ + return stage; +} + +/** + * @brief Calculate the output position increment reference. + * @param posHandle Position controller struct handle. + * @return postion. + */ +static float TrajPosCalc(POSCTRL_Handle *posHandle) +{ + float posIncRef; /* output position increment reference (rad) */ + /* local variables */ + float timeTick = posHandle->timeTick; + float *timeStg = posHandle->timeStg; + float jerk = posHandle->jerk; + float acc = posHandle->accMax; + float half_acc = 0.5f * acc; /* 0.5f : half */ + /* temporary variables */ + float deltaTimeSq = 0.0f; + float deltaTimeCu = 0.0f; + float deltaTime = 0.0f; + float jerkDtcu = jerk * posHandle->deltaTimeCu; + float jerkDtsq = jerk * posHandle->deltaTimeSq; + POSCTRL_TRAJ_STAGE stage = TrajPosState(posHandle); + if (TRAJ_STAGE_INDEX_1 <= stage && stage <= TRAJ_STAGE_INDEX_6) { + deltaTime = timeTick - timeStg[stage - 1]; + deltaTimeSq = deltaTime * deltaTime; + deltaTimeCu = deltaTimeSq * deltaTime; + } + switch (stage) { + case TRAJ_STAGE_INDEX_0: + /* jerk > 0, acc > 0 */ + deltaTimeCu = timeTick * timeTick * timeTick; + posIncRef = ONE_DIV_SIX * jerk * deltaTimeCu; + break; + case TRAJ_STAGE_INDEX_1: + /* jerk = 0, acc > 0 */ + posIncRef = half_acc * deltaTimeSq + 0.5f * jerkDtsq * deltaTime + ONE_DIV_SIX * jerkDtcu; + break; + case TRAJ_STAGE_INDEX_2: + /* jerk < 0, acc > 0 */ + posIncRef = - ONE_DIV_SIX * jerk * deltaTimeCu + + half_acc * deltaTimeSq + 1.5f * jerkDtsq * deltaTime + SEVEN_DIV_SIX * jerkDtcu; + break; + case TRAJ_STAGE_INDEX_3: + /* jerk = 0, acc = 0 */ + posIncRef = 3.0f * jerkDtcu + 2.0f * jerkDtsq * deltaTime; + break; + case TRAJ_STAGE_INDEX_4: + /* jerk < 0, acc < 0 */ + posIncRef = - ONE_DIV_SIX * jerk * deltaTimeCu + 2.0f * jerkDtsq * deltaTime + 9.0f * jerkDtcu; + break; + case TRAJ_STAGE_INDEX_5: + /* jerk = 0, acc < 0 */ + posIncRef = - half_acc * deltaTimeSq + 1.5f * jerkDtsq * deltaTime + SIXTY_FIVE_DIV_SIX * jerkDtcu; + break; + case TRAJ_STAGE_INDEX_6: + /* jerk > 0, acc < 0 */ + posIncRef = ONE_DIV_SIX * jerk * deltaTimeCu - half_acc * deltaTimeSq + + 0.5f * jerkDtsq * deltaTime + SEVENTY_ONE_DIV_SIX * jerkDtcu; + break; + default: + posIncRef = posHandle->posIncRefPrev; /* maintain last position */ + break; + } + + return posIncRef; +} + +/** + * @brief Executing location track planning. + * @param posHandle Position controller struct handle. + * @param posFbk Position feedback. + * @return postion. + */ +float POSCTRL_TrajCtrlExec(POSCTRL_Handle *posHandle, float posFbk) +{ + float posIncRef; /* output position increment reference (rad) */ + /* every start of a new trajectory run this function */ + /* Expanded by 10000 times and converted to an integer to avoid floating-point comparison. */ + if ((int)(posHandle->posTargetBk * 10000.0f) != (int)(posHandle->posTargetShadow * 10000.0f)) { + POSCTRL_TrajCtrlPrepare(posHandle, posFbk, &posIncRef); + posHandle->posTargetBk = posHandle->posTargetShadow; + } + + /* time accumulates */ + posHandle->timeTick += posHandle->ts; /* tick time updates */ + + posIncRef = TrajPosCalc(posHandle); + + posHandle->posIncRefPrev = posIncRef; + posHandle->posIncRef = posIncRef; + + return (posIncRef + posHandle->posFbkPrev); +} + /** * @brief position loop execution function. * @param posHandle Position controller struct handle. * @param posFbk Position feedback. * @return float, Speed reference value. */ -float POSCTRL_Exec(POSCTRL_Handle *posHandle, float posTarget, float posFbk) +float POSCTRL_Exec(POSCTRL_Handle *posHandle, float posFbk) { float posRef, spdRef; - posRef = RMG_Exec(&posHandle->posRmg, posTarget); + + if (posHandle->mode == POSCTRL_MODE_CONTINUOUS) { + posRef = RMG_Exec(&posHandle->posRmg, posHandle->posTarget); + posHandle->posTargetBk = 0.0f; + } else { + /* posHandle->mode == POSCTRL_MODE_TRAJ */ + posRef = POSCTRL_TrajCtrlExec(posHandle, posFbk); + posHandle->posRmg.yLast = posRef; + } posHandle->posRef = posRef; spdRef = POSCTRL_PidExec(posHandle, posRef - posFbk); spdRef *= ONE_DIV_DOUBLE_PI; /* transfer spdRef from rad/s to Hz */ @@ -184,7 +374,7 @@ float POSCTRL_Exec(POSCTRL_Handle *posHandle, float posTarget, float posFbk) */ void POSCTRL_SetKp(POSCTRL_Handle *posHandle, float kp) { - posHandle->posPi.kp = kp; + posHandle->posPid.kp = kp; } /** @@ -194,7 +384,7 @@ void POSCTRL_SetKp(POSCTRL_Handle *posHandle, float kp) */ void POSCTRL_SetKi(POSCTRL_Handle *posHandle, float ki) { - posHandle->posPi.ki = ki; + posHandle->posPid.ki = ki; } /** @@ -204,7 +394,7 @@ void POSCTRL_SetKi(POSCTRL_Handle *posHandle, float ki) */ void POSCTRL_SetKd(POSCTRL_Handle *posHandle, float kd) { - posHandle->posPi.kd = kd; + posHandle->posPid.kd = kd; } /** @@ -214,5 +404,5 @@ void POSCTRL_SetKd(POSCTRL_Handle *posHandle, float kd) */ void POSCTRL_SetNs(POSCTRL_Handle *posHandle, float ns) { - posHandle->posPi.ns = ns; + posHandle->posPid.ns = ns; } \ No newline at end of file diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_pos_ctrl.h b/src/middleware/control_library/foc_loop_ctrl/mcs_pos_ctrl.h index 999dd359d69ee36bf1ada15490b5c3dc2a3d975a..f285a16c27903ef73e984b26294000847b55b64f 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_pos_ctrl.h +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_pos_ctrl.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2022 - 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -41,11 +41,22 @@ typedef enum { POSCTRL_MODE_TRAJ } POSCTRL_Mode; +typedef enum { + TRAJ_STAGE_INDEX_0 = 0, + TRAJ_STAGE_INDEX_1, + TRAJ_STAGE_INDEX_2, + TRAJ_STAGE_INDEX_3, + TRAJ_STAGE_INDEX_4, + TRAJ_STAGE_INDEX_5, + TRAJ_STAGE_INDEX_6, + TRAJ_STAGE_INDEX_7, +} POSCTRL_TRAJ_STAGE; + /** * @brief Position controller struct members and parameters. */ typedef struct { - PID_Handle posPi; /**< PI controller struct in the position controller. */ + PID_Handle posPid; /**< PID controller struct in the position controller. */ float posTarget; /**< position controller input target value (rad) */ float posTargetBk; RMG_Handle posRmg; /**< position reference ramp management . */ @@ -70,10 +81,9 @@ typedef struct { float deltaTime; float accMax; float jerk; - int targetUpdateBlockFlag; /**< whether the position target can be update or not. 0: can be updated; 1: block */ float deltaTimeSq; float deltaTimeCu; - float timeStg[7]; + float timeStg[7]; /* Seven-segment trajectory time */ } POSCTRL_Handle; /** @@ -82,16 +92,18 @@ typedef struct { * @retval Speed Reference. */ void POSCTRL_Clear(POSCTRL_Handle *posHandle); -void POSCTRL_Init(POSCTRL_Handle *posHandle, const PID_Param *piCtrlTable, float ts); +void POSCTRL_Init(POSCTRL_Handle *posHandle, const PID_Param *pidCtrlTable, float ts, float posSlope); float POSCTRL_PidExec(POSCTRL_Handle *posHandle, float posErr); void POSCTRL_ModeSelect(POSCTRL_Handle *posHandle, POSCTRL_Mode mode); void POSCTRL_SetSlope(POSCTRL_Handle *posHandle, float slope); void POSCTRL_SetTarget(POSCTRL_Handle *posHandle, float posTarget); -float POSCTRL_Exec(POSCTRL_Handle *posHandle, float posTarget, float posFbk); +float POSCTRL_TrajCtrlExec(POSCTRL_Handle *posHandle, float posErr); +float POSCTRL_Exec(POSCTRL_Handle *posHandle, float posFbk); float POSCTRL_AngleExpand(POSCTRL_Handle *posHandle, float angFbk); void POSCTRL_SetKp(POSCTRL_Handle *posHandle, float kp); void POSCTRL_SetKi(POSCTRL_Handle *posHandle, float ki); void POSCTRL_SetKd(POSCTRL_Handle *posHandle, float kd); void POSCTRL_SetNs(POSCTRL_Handle *posHandle, float ns); +void POSCTRL_TrajCtrlPrepare(POSCTRL_Handle *posHandle, float posFbk, float *posIncRef); #endif /* McuMagicTag_MCS_POS_CTRL_H */ \ No newline at end of file diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_spd_ctrl.c b/src/middleware/control_library/foc_loop_ctrl/mcs_spd_ctrl.c index 5f88e833e86c0cf5db91907df949fe5dc1640d7d..4ec39351046c13a64513ffebdde235a6363f6515 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_spd_ctrl.c +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_spd_ctrl.c @@ -27,7 +27,8 @@ /** * @brief Initialzer of speed control struct handle. * @param spdHandle Speed control struct handle. - * @param PID_Param PI controller parameter table. + * @param mtrParam Motor parameter struct handle. + * @param piParam PI controller parameter table. * @param ts Speed control period. * @retval None. */ diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_startup.c b/src/middleware/control_library/foc_loop_ctrl/mcs_startup.c index 3bc2138dd7080382b3912f4a0d08ac48f23de188..fcec2a94c3dc0460a17f84dd8bd4577f564728b6 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_startup.c +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_startup.c @@ -58,16 +58,16 @@ void STARTUP_Clear(STARTUP_Handle *startHandle) /** * @brief Calculate the reference current in the startup stage. * @param startHandle The startup control handle. - * @param refHz The speed reference in the startup stage. + * @param spdRef The speed reference in the startup stage. * @return The current AMP. */ -float STARTUP_CurrCal(const STARTUP_Handle *startHandle, float refHz) +float STARTUP_CurrCal(STARTUP_Handle *startHandle, float spdRef) { MCS_ASSERT_PARAM(startHandle != NULL); float out; float tmp; /* Calculate the reference current in the startup stage */ - tmp = startHandle->spdEnd - Abs(refHz); + tmp = startHandle->spdEnd - Abs(spdRef); tmp = tmp * startHandle->regionInv; out = tmp * startHandle->initCurr; diff --git a/src/middleware/control_library/foc_loop_ctrl/mcs_startup.h b/src/middleware/control_library/foc_loop_ctrl/mcs_startup.h index 725cdd998e939f653cdde89488cd0eb9d5c918e9..e7d79d4760ef55fe0ad6996a5a6cfd9eb9896e15 100644 --- a/src/middleware/control_library/foc_loop_ctrl/mcs_startup.h +++ b/src/middleware/control_library/foc_loop_ctrl/mcs_startup.h @@ -56,8 +56,11 @@ typedef struct { * @brief The startup management API declaration. * @{ */ + void STARTUP_Init(STARTUP_Handle *startHandle, float spdBegin, float spdEnd); void STARTUP_Clear(STARTUP_Handle *startHandle); -float STARTUP_CurrCal(const STARTUP_Handle *startHandle, float refHz); - +float STARTUP_CurrCal(STARTUP_Handle *startHandle, float spdRef); +/** + * @} + */ #endif diff --git a/src/middleware/control_library/math/mcs_math.c b/src/middleware/control_library/math/mcs_math.c index d1e932f00d330b660027820e3f9f98d5d24e3403..e26b5e8374f6d424296d9c2944545e321e986fbd 100644 --- a/src/middleware/control_library/math/mcs_math.c +++ b/src/middleware/control_library/math/mcs_math.c @@ -440,9 +440,9 @@ static unsigned short BinSearch(float u, const float *table, * @param maxIndex: Max Index. * @retval Target index. */ -static unsigned short PreLookBinSearch(float u, const float *table, - unsigned short maxIndex, - float *fraction) +unsigned short PreLookBinSearch(float u, const float *table, + unsigned short maxIndex, + float *fraction) { MCS_ASSERT_PARAM(table != NULL); MCS_ASSERT_PARAM(fraction != NULL); @@ -476,13 +476,22 @@ static float ATan(float u) float y = 0.0f; if (tmp >= 0.0f && tmp < ATAN_INPUTVALUE_MIN) { index = PreLookBinSearch(tmp, atanInBottom, 49U, &frac); /* atanInBottom Max Index is 49 */ - y = atanValBottom[index] + frac * (atanValBottom[index + 1] - atanValBottom[index]); + /* Ensure that index+1 <= maxIndex, maxIndex = 49U. */ + y = index == 49U? \ + atanValBottom[index] : \ + atanValBottom[index] + frac * (atanValBottom[index + 1] - atanValBottom[index]); } else if (tmp >= ATAN_INPUTVALUE_MIN && tmp < ATAN_INPUTVALUE_MID) { index = PreLookBinSearch(tmp, atanInMid, 24U, &frac); /* atanInMid Max Index is 24 */ - y = atanValMid[index] + frac * (atanValMid[index + 1] - atanValMid[index]); + /* Ensure that index+1 <= maxIndex, atanInMid Max Index is 24 */ + y = index == 24U? \ + atanValMid[index] : \ + atanValMid[index] + frac * (atanValMid[index + 1] - atanValMid[index]); } else if (tmp >= ATAN_INPUTVALUE_MID && tmp < ATAN_INPUTVALUE_MAX) { index = PreLookBinSearch(tmp, atanInTop, 9U, &frac); /* atanInTop Max Index is 9 */ - y = atanValTop[index] + frac * (atanValTop[index + 1] - atanValTop[index]); + /* Ensure that index+1 <= maxIndex, atanInTop Max Index is 9 */ + y = index == 9U? \ + atanValTop[index] : \ + atanValTop[index] + frac * (atanValTop[index + 1] - atanValTop[index]); } else { y = HALF_PI; /* The input parameter is greater than the maximum radian, The value is PI/2. */ } @@ -554,4 +563,31 @@ float Sat(float u, float delta) } else { return (u / delta); /* all other values */ } +} + +/** + * @brief Rms calculation. + * @param Rms Rms Handle. + * @param freq signal frequency. + * @retval Rms results. + */ +float RmsCalc(RMS_Handle *rms, float realVal, float freq, float ts) +{ + float absHz = Abs(freq); + /* Limit frequency to prevent division by zero. */ + if (absHz < 1.0f) { + absHz = 1.0f; + } + /* Accumulated times of calculating the sum of squares */ + unsigned int num = (unsigned int)(1.0f / (absHz * ts)); + /* rms Sqrt((+= i * i * ts) / T) */ + rms->periodCnt++; + if (rms->periodCnt < num) { + rms->sum += realVal * realVal; + } else { + rms->periodCnt = 0; + rms->val = Sqrt(rms->sum / num); + rms->sum = 0.0f; + } + return rms->val; } \ No newline at end of file diff --git a/src/middleware/control_library/math/mcs_math.h b/src/middleware/control_library/math/mcs_math.h index 0992dc10a9c4f71f3dd9d10092bfde7b38664ad6..9dab4d01745e1655c3686b340511334eeb23fe8b 100644 --- a/src/middleware/control_library/math/mcs_math.h +++ b/src/middleware/control_library/math/mcs_math.h @@ -39,11 +39,40 @@ typedef struct { } TrigVal; +typedef struct { + float sum; + float val; + unsigned int periodCnt; +} RMS_Handle; + +/** + * @brief This function returns the sliding average filtering result. + * @param newVal Current filtered value. + * @param oldVal Historical filter value. + * @param percent Filter percentage. + * @retval Sliding average filtering result. + */ +static inline float AvgFlt(float newVal, float oldVal, float percent) +{ + return newVal * percent + oldVal * (1.0f - percent); +} + +/** + * @brief The internal round up/down function. + * @param x The input float x. + * @retval The integer value of round result. + */ +static inline int RoundInt(float x) +{ + return (int)(x + 0.5f); /* round function */ +} + /** * @defgroup MATH_API MATH API * @brief The common math API definition. * @{ */ + float GetSin(float angle); float GetCos(float angle); void TrigCalc(TrigVal *val, float angle); @@ -59,5 +88,12 @@ float AngleSub(float angle1, float angle2); float Mod(float val1, float val2); float Sat(float u, float delta); float Atan2(float x, float y); +unsigned short PreLookBinSearch(float u, const float *table, + unsigned short maxIndex, + float *fraction); +float RmsCalc(RMS_Handle *rms, float realVal, float freq, float ts); +/** + * @} + */ #endif \ No newline at end of file diff --git a/src/middleware/control_library/math/mcs_math_const.h b/src/middleware/control_library/math/mcs_math_const.h index 6a605bd9ea428da9849e99ade12a2b7659405fe6..c2c779e8f52ab9bfdc7591f799b63b5f12cac9ca 100644 --- a/src/middleware/control_library/math/mcs_math_const.h +++ b/src/middleware/control_library/math/mcs_math_const.h @@ -59,6 +59,8 @@ #define ONE_DIV_NINE (0.11111111f) /**< 1/9 */ #define ONE_DIV_TWELVE (0.08333333f) /**< 1/12 */ #define SQRT2 (1.41421356f) /**< sqrt(2) */ +#define SQRT2_DIV_TWO (0.70710678f) /**< sqrt(2)/2 */ +#define SQRT3 (1.73205081f) /**< sqrt(3) */ #define SMALL_FLOAT (0.00000001f) #define LARGE_FLOAT (10000.0f) /** diff --git a/src/middleware/control_library/modulation/mcs_r1_svpwm.h b/src/middleware/control_library/modulation/mcs_r1_svpwm.h index 3bc1990184ba15e720423f5f41f4c7037cb866a7..b8914feb0c30e2bd9f5a469a5c708991e81bc222 100644 --- a/src/middleware/control_library/modulation/mcs_r1_svpwm.h +++ b/src/middleware/control_library/modulation/mcs_r1_svpwm.h @@ -74,6 +74,7 @@ typedef struct { * @brief The SVPWM module's API declaration for R1(One Resistor) application. * @{ */ + void R1SVPWM_Init(R1SVPWM_Handle *r1svHandle, float voltPu, float samplePointShift, float sampleWindow); void R1SVPWM_Clear(R1SVPWM_Handle *r1svHandle); void R1SVPWM_Exec(R1SVPWM_Handle *r1svHandle, const AlbeAxis *uAlbe, UvwAxis *dutyUvwLeft, UvwAxis *dutyUvwRight); diff --git a/src/middleware/control_library/modulation/mcs_svpwm.c b/src/middleware/control_library/modulation/mcs_svpwm.c index 71b595ecc030ba80d4eabe48b0882bc90ff976d0..84a7d3a55958bb18761536130882f144056c24c1 100644 --- a/src/middleware/control_library/modulation/mcs_svpwm.c +++ b/src/middleware/control_library/modulation/mcs_svpwm.c @@ -71,6 +71,10 @@ void SVPWM_SectorCalc(SVPWM_CALC_Handle *svCalc) } else { svCalc->volt[SVPWM_VOLT_2] = -svCalc->volt[SVPWM_VOLT_2]; } + /* Sector empty judgment. */ + if (svCalc->sectorIndex == 0) { + svCalc->sectorIndex = SVPWM_ANGLE_0_TO_60_DEG; + } } /** diff --git a/src/middleware/control_library/modulation/mcs_svpwm.h b/src/middleware/control_library/modulation/mcs_svpwm.h index fe636fa5faa08491fc2122f32e0b32e65a4e5657..e02067affc2c0155893b1cce18ead7f6bada388c 100644 --- a/src/middleware/control_library/modulation/mcs_svpwm.h +++ b/src/middleware/control_library/modulation/mcs_svpwm.h @@ -101,6 +101,7 @@ typedef struct { * @brief The SVPWM module's API declaration. * @{ */ + void SVPWM_Init(SVPWM_Handle *svHandle, float voltPu); void SVPWM_SectorCalc(SVPWM_CALC_Handle *svCalc); void SVPWM_CompareValCalc(SVPWM_CALC_Handle *svCalc); diff --git a/src/middleware/control_library/observer/mcs_fosmo.c b/src/middleware/control_library/observer/mcs_fosmo.c index 690bbb9514d55c72407a761daa6764d01d9d7f46..18bf7a1b160b06ed0e266fa2b01873a88b68b3da 100644 --- a/src/middleware/control_library/observer/mcs_fosmo.c +++ b/src/middleware/control_library/observer/mcs_fosmo.c @@ -25,16 +25,27 @@ #include "mcs_math.h" #include "mcs_assert.h" +#define LIMIT_TIMES 10.0f -void FOSMO_Init(FOSMO_Handle *fosmo, const FOSMO_Param foSmoParam, const MOTOR_Param mtrParam, float ts) +/** + * @brief Init parameters for fosmo. + * @param fosmo The SMO handle. + * @param foSmoParam First order smo parameters. + * @param mtrParam Motor parameters. + * @param ts Control period (s). + * @retval None. + */ +void FOSMO_Init(FOSMO_Handle *fosmo, FOSMO_Param foSmoParam, MOTOR_Param *mtrParam, float ts) { MCS_ASSERT_PARAM(fosmo != NULL); MCS_ASSERT_PARAM(ts > 0.0f); /* time sample, unit: s */ fosmo->ts = ts; + /* Motor parameter */ + fosmo->mtrParam = mtrParam; /* filter coefficient */ - fosmo->a1 = 1.0f - (fosmo->ts * mtrParam.mtrRs / mtrParam.mtrLd); - fosmo->a2 = fosmo->ts / mtrParam.mtrLd; + fosmo->a1 = 1.0f - (fosmo->ts * mtrParam->mtrRs / mtrParam->mtrLd); + fosmo->a2 = fosmo->ts / mtrParam->mtrLd; fosmo->kSmo = foSmoParam.gain; fosmo->lambda = foSmoParam.lambda; /* SMO coefficient of cut-off frequency = lambda * we, unit: rad/2. */ @@ -47,7 +58,7 @@ void FOSMO_Init(FOSMO_Handle *fosmo, const FOSMO_Param foSmoParam, const MOTOR_P fosmo->emfLpfMinFreq = foSmoParam.fcEmf; /* The minimum cutoff frequency of the back EMF filter is 2.0. */ - PLL_Init(&fosmo->pll, fosmo->ts, fosmo->pllBdw); // bdw + PLL_Init(&fosmo->pll, fosmo->ts, fosmo->pllBdw); /* bdw */ /* low pass filter cutoff freqency for speed estimation is 40Hz */ FOLPF_Init(&fosmo->spdFilter, fosmo->ts, fosmo->fcLpf); @@ -120,7 +131,6 @@ void FOSMO_Exec(FOSMO_Handle *fosmo, const AlbeAxis *ialbeFbk, const AlbeAxis *v MCS_ASSERT_PARAM(fosmo != NULL); MCS_ASSERT_PARAM(ialbeFbk != NULL); MCS_ASSERT_PARAM(valbeRef != NULL); - float err; float wcTs; float fcAbs = Abs(refHz); float filCompAngle; /* Compensation angle (rad) */ @@ -128,20 +138,24 @@ void FOSMO_Exec(FOSMO_Handle *fosmo, const AlbeAxis *ialbeFbk, const AlbeAxis *v float currBeta = fosmo->ialbeEstLast.beta; float emfUnAlpha = fosmo->emfEstUnFil.alpha; float emfUnBeta = fosmo->emfEstUnFil.beta; + float iEstLimit = LIMIT_TIMES * fosmo->mtrParam->maxCurr; + float emfEstLimit = LIMIT_TIMES * fosmo->mtrParam->busVolt; /* Alpha beta current observation value */ - fosmo->ialbeEst.alpha = - (fosmo->a1 * currAlpha) + (fosmo->a2 * (valbeRef->alpha - emfUnAlpha)); - fosmo->ialbeEst.beta = - (fosmo->a1 * currBeta) + (fosmo->a2 * (valbeRef->beta - emfUnBeta)); + float ialEst = (fosmo->a1 * currAlpha) + (fosmo->a2 * (valbeRef->alpha - emfUnAlpha)); + float ibeEst = (fosmo->a1 * currBeta) + (fosmo->a2 * (valbeRef->beta - emfUnBeta)); + /* Amplitude limit */ + fosmo->ialbeEst.alpha = Clamp(ialEst, iEstLimit, -iEstLimit); + fosmo->ialbeEst.beta = Clamp(ibeEst, iEstLimit, -iEstLimit); fosmo->ialbeEstLast.alpha = fosmo->ialbeEst.alpha; fosmo->ialbeEstLast.beta = fosmo->ialbeEst.beta; /* Estmated back EMF by sign function. */ - err = fosmo->ialbeEst.alpha - ialbeFbk->alpha; - fosmo->emfEstUnFil.alpha = fosmo->kSmo * ((err > 0.0f) ? 1.0f : -1.0f); - err = fosmo->ialbeEst.beta - ialbeFbk->beta; - fosmo->emfEstUnFil.beta = fosmo->kSmo * ((err > 0.0f) ? 1.0f : -1.0f); + float emfAlEst = fosmo->kSmo * ((fosmo->ialbeEst.alpha - ialbeFbk->alpha > 0.0f) ? 1.0f : -1.0f); + float emfBeEst = fosmo->kSmo * ((fosmo->ialbeEst.beta - ialbeFbk->beta > 0.0f) ? 1.0f : -1.0f); + /* Amplitude limit */ + fosmo->emfEstUnFil.alpha = Clamp(emfAlEst, emfEstLimit, -emfEstLimit); + fosmo->emfEstUnFil.beta = Clamp(emfBeEst, emfEstLimit, -emfEstLimit); /* Estmated back EMF is filtered by first-order LPF. */ if (fcAbs <= fosmo->emfLpfMinFreq) { diff --git a/src/middleware/control_library/observer/mcs_fosmo.h b/src/middleware/control_library/observer/mcs_fosmo.h index 350842e232ae07b4e6bc40d94bfd2d06151e7768..eb4ef92914b5b6710a2a07466750bbee281a9f9c 100644 --- a/src/middleware/control_library/observer/mcs_fosmo.h +++ b/src/middleware/control_library/observer/mcs_fosmo.h @@ -58,6 +58,7 @@ typedef struct { float filCompAngle; /**< Compensation angle (atan(1/lambda)) for the back-EMF filter. */ float elecAngle; /**< SMO estimated electronic angle (rad). */ float spdEst; /**< SMO estimated electronic speed (Hz). */ + MOTOR_Param *mtrParam; AlbeAxis emfEstUnFil; /**< Estimated back-EMF in the alpha-beta coordinate by differential equation. */ AlbeAxis ialbeEst; /**< SMO estimated currents in the alpha-beta coordinate. */ AlbeAxis ialbeEstLast; /**< SMO history values of estimated currents in the alpha-beta coordinate. */ @@ -84,7 +85,7 @@ typedef struct { * @{ */ -void FOSMO_Init(FOSMO_Handle *fosmo, const FOSMO_Param foSmoParam, const MOTOR_Param mtrParam, float ts); +void FOSMO_Init(FOSMO_Handle *fosmo, FOSMO_Param foSmoParam, MOTOR_Param *mtrParam, float ts); void FOSMO_Exec(FOSMO_Handle *fosmo, const AlbeAxis *ialbeFbk, const AlbeAxis *valbeRef, float refHz); diff --git a/src/middleware/control_library/pfc/pfc_curr_ctrl.c b/src/middleware/control_library/pfc/pfc_curr_ctrl.c index 3eda2abd12bf64aa1f57a2af1fc57459cfb4d97c..9cdaddf7b89eba019e643e0aa8f95789f710284c 100644 --- a/src/middleware/control_library/pfc/pfc_curr_ctrl.c +++ b/src/middleware/control_library/pfc/pfc_curr_ctrl.c @@ -24,15 +24,35 @@ /** - * @brief Clear historical values of power factor correction(PFC) current controller. - * @param currCtrl PFC current control structure + * @brief Init PFC voltage control structure. + * @param currCtrl PFC voltage control Handle. + * @param piParam PI controller parameter table. + * @param startCurr Current threshold for starting the current loop. + * @param stopCurr Current threshold for stopping the current loop. + * @param vacAmp Amplitude of input voltage. + * @param ts Control period. * @retval None. */ -void PFC_CurrCtrlClear(PFC_CURRCTRL_Handle *currCtrl) +void PFC_CurrCtrlInit(PFC_CURRCTRL_Handle *currCtrl, PI_Param *piParam, float startCurr, \ + float stopCurr, float vacAmp, float ts) { MCS_ASSERT_PARAM(currCtrl != NULL); - currCtrl->currPiCtrl.differ = 0.0f; - currCtrl->currPiCtrl.integral = 0.0f; + MCS_ASSERT_PARAM(piParam != NULL); + MCS_ASSERT_PARAM(startCurr > 0.0f); + MCS_ASSERT_PARAM(stopCurr > 0.0f); + /* Reset pi parameters. */ + PID_Reset(&currCtrl->currPi); + /* Init pi parameters. */ + currCtrl->currPi.kp = piParam->kp; + currCtrl->currPi.ki = piParam->ki; + currCtrl->currPi.upperLimit = piParam->upperLim; + currCtrl->currPi.lowerLimit = piParam->lowerLim; + currCtrl->currPi.ts = ts; + /* Init user parameter and control parameter. */ + currCtrl->maxCurr = 0.0f; + currCtrl->startCurr = startCurr; + currCtrl->stopCurr = stopCurr; + currCtrl->unitCoeff = 1.0f / vacAmp; } /** @@ -40,11 +60,30 @@ void PFC_CurrCtrlClear(PFC_CURRCTRL_Handle *currCtrl) * @param currCtrl PFC current control structure * @retval None. */ -void PFC_CurrCtrlExec(PFC_CURRCTRL_Handle *currCtrl) +void PFC_CurrCtrlExec(PFC_CURRCTRL_Handle *currCtrl, float iacFbk) { MCS_ASSERT_PARAM(currCtrl != NULL); + + currCtrl->iacFbk = iacFbk; /* Calculate the current error of power factor correction(PFC). */ - currCtrl->currPiCtrl.error = currCtrl->currRef - currCtrl->unitCurrFdbk; - /* Calculation the output pwm duty of power factor correction(PFC) current. */ - currCtrl->pwmDuty = PI_Exec(&currCtrl->currPiCtrl); + currCtrl->currPi.error = currCtrl->iacRef - currCtrl->iacFbk; + /* Calculate the output pwm duty of power factor correction(PFC) current. */ + currCtrl->pwmDuty = PI_Exec(&currCtrl->currPi); } + +/** + * @brief Clear historical values of power factor correction(PFC) current controller. + * @param currCtrl PFC current control structure + * @retval None. + */ +void PFC_CurrCtrlClear(PFC_CURRCTRL_Handle *currCtrl) +{ + MCS_ASSERT_PARAM(currCtrl != NULL); + /* Clear history value */ + currCtrl->pwmDuty = 0.0f; + currCtrl->iacFbk = 0.0f; + currCtrl->vacFbk = 0.0f; + currCtrl->unitVacFbk = 0.0f; + /* Clear pid */ + PID_Clear(&currCtrl->currPi); +} \ No newline at end of file diff --git a/src/middleware/control_library/pfc/pfc_curr_ctrl.h b/src/middleware/control_library/pfc/pfc_curr_ctrl.h index d7ed3d9fdea33b9eb039caf628e1ffe4fc06aca0..d968b08223e563640b3e25bfd83455aacd55f199 100644 --- a/src/middleware/control_library/pfc/pfc_curr_ctrl.h +++ b/src/middleware/control_library/pfc/pfc_curr_ctrl.h @@ -43,18 +43,18 @@ * @brief current Controller Struct members and parameters. */ typedef struct { - float currRef; /* < current loop control reference current(A) */ - float currFdbk; /* < current loop control feedback current(A) */ - float unitCurrFdbk; /* < current loop control feedback unitary current */ - float maxCurrFdbk; /* < current loop control max feedback current(A) */ - float startCurrFdbk; /* < current loop control start feedback current(A) */ - float stopCurrFdbk; /* < current loop control stop feedback current(A) */ - float pwmDuty; /* < current loop control pulse width modulation(PWM) duty */ - float pwmOut; /* < current loop control PWM final output (output = cmpst + duty) */ - float rectVoltFdbk; /* < current loop control rectified feedback voltage(V) */ - float unitRectVoltFdbk; /* < current loop control rectified feedback unitary voltage */ - float compensation; - PID_Handle currPiCtrl; /* < current loop controller define */ + float iacRef; + float iacFbk; + float vacFbk; /* < current loop control rectified feedback voltage(V) */ + float unitVacFbk; + float unitCoeff; + + float maxCurr; /* < current loop control max feedback current(A) */ + float startCurr; /* < current loop control start feedback current(A) */ + float stopCurr; /* < current loop control stop feedback current(A) */ + + float pwmDuty; /* < current loop control pulse width modulation(PWM) duty */ + PID_Handle currPi; /* < current loop controller define */ } PFC_CURRCTRL_Handle; /** * @} @@ -66,9 +66,12 @@ typedef struct { * @{ */ -void PFC_CurrCtrlClear(PFC_CURRCTRL_Handle *currCtrl); +void PFC_CurrCtrlInit(PFC_CURRCTRL_Handle *currCtrl, PI_Param *piParam, float startCurr, \ + float stopCurr, float vacAmp, float ts); -void PFC_CurrCtrlExec(PFC_CURRCTRL_Handle *currCtrl); +void PFC_CurrCtrlExec(PFC_CURRCTRL_Handle *currCtrl, float iacFbk); + +void PFC_CurrCtrlClear(PFC_CURRCTRL_Handle *currCtrl); /** * @} */ diff --git a/src/middleware/control_library/pfc/pfc_volt_ctrl.c b/src/middleware/control_library/pfc/pfc_volt_ctrl.c index 1fdf5dfd345b3285d630936d4966f8fb7a3926bf..299b74d42603db15fcd0d525f52ba336ec3fd37c 100644 --- a/src/middleware/control_library/pfc/pfc_volt_ctrl.c +++ b/src/middleware/control_library/pfc/pfc_volt_ctrl.c @@ -25,27 +25,55 @@ /** - * @brief Clear historical values of power factor correction(PFC) voltage controller. - * @param voltCtrl PFC voltage control structure + * @brief Init PFC voltage control structure. + * @param voltCtrl PFC voltage control Handle. + * @param piParam PI controller parameter table. + * @param vdcRef Reference voltage. * @retval None. */ -void PFC_VoltCtrlClear(PFC_VOLTCTRL_Handle *voltCtrl) +void PFC_VoltCtrlInit(PFC_VOLTCTRL_Handle *voltCtrl, PI_Param *piParam, float vdcRef, float ts) { MCS_ASSERT_PARAM(voltCtrl != NULL); - voltCtrl->voltPiCtrl.differ = 0.0f; - voltCtrl->voltPiCtrl.integral = 0.0f; + MCS_ASSERT_PARAM(piParam != NULL); + MCS_ASSERT_PARAM(vdcRef > 0.0f); + /* Reset pi parameters. */ + PID_Reset(&voltCtrl->voltPi); + /* Init pi parameters. */ + voltCtrl->voltPi.kp = piParam->kp; + voltCtrl->voltPi.ki = piParam->ki; + voltCtrl->voltPi.upperLimit = piParam->upperLim; + voltCtrl->voltPi.lowerLimit = piParam->lowerLim; + voltCtrl->voltPi.ts = ts; + /* Init user parameter and control parameter. */ + voltCtrl->iamp = 0.0f; + voltCtrl->vdcRef = vdcRef; } + /** - * @brief Simplified power factor correction(PFC) voltage controller PI calculation. + * @brief Power factor correction(PFC) voltage controller PI calculation. * @param voltCtrl PFC voltage control structure * @retval None. */ -void PFC_VoltCtrlExec(PFC_VOLTCTRL_Handle *voltCtrl) +void PFC_VoltCtrlExec(PFC_VOLTCTRL_Handle *voltCtrl, float vdcFbk) { MCS_ASSERT_PARAM(voltCtrl != NULL); + voltCtrl->vdcFbk = vdcFbk; /* Calculate the voltage error of power factor correction(PFC). */ - voltCtrl->voltPiCtrl.error = voltCtrl->uniVoltRef - voltCtrl->unitVoltFdbk; + voltCtrl->voltPi.error = voltCtrl->vdcRef - voltCtrl->vdcFbk; /* Calculation the voltage loop control output of power factor correction(PFC). */ - voltCtrl->voltOut = PI_Exec(&voltCtrl->voltPiCtrl); + voltCtrl->iamp = PI_Exec(&voltCtrl->voltPi); } + +/** + * @brief Clear historical values of power factor correction(PFC) voltage controller. + * @param voltCtrl PFC voltage control structure + * @retval None. + */ +void PFC_VoltCtrlClear(PFC_VOLTCTRL_Handle *voltCtrl) +{ + MCS_ASSERT_PARAM(voltCtrl != NULL); + voltCtrl->iamp = 0.0f; + + PID_Clear(&voltCtrl->voltPi); +} \ No newline at end of file diff --git a/src/middleware/control_library/pfc/pfc_volt_ctrl.h b/src/middleware/control_library/pfc/pfc_volt_ctrl.h index b1f6e94d71b7f82675b413fd446f48cb8165a315..7edcb4329057bcf05e1525743078909d4686ecb8 100644 --- a/src/middleware/control_library/pfc/pfc_volt_ctrl.h +++ b/src/middleware/control_library/pfc/pfc_volt_ctrl.h @@ -43,12 +43,10 @@ * @brief Voltage controller struct. */ typedef struct { - float uniVoltRef; /* < voltage loop control unitary reference voltage(V) */ - float voltFdbk; /* < voltage loop control feedback voltage(V) */ - float unitVoltFdbk; /* < voltage loop control feedback unitary voltage */ - float startVolt; /* < voltage loop control start voltage(V) */ - float voltOut; /* < voltage loop control output */ - PID_Handle voltPiCtrl; /* < voltage loop controller define */ + float vdcRef; /* Target bus voltage */ + float vdcFbk; /* < voltage loop control feedback voltage(V) */ + float iamp; /* Voltage loop output is current amplitude */ + PID_Handle voltPi; /* < voltage loop controller define */ } PFC_VOLTCTRL_Handle; /** * @} @@ -59,9 +57,12 @@ typedef struct { * @brief The voltage controller's API declaration. * @{ */ -void PFC_VoltCtrlClear(PFC_VOLTCTRL_Handle *voltCtrl); -void PFC_VoltCtrlExec(PFC_VOLTCTRL_Handle *voltCtrl); +void PFC_VoltCtrlInit(PFC_VOLTCTRL_Handle *voltCtrl, PI_Param *piParam, float vdcRef, float ts); + +void PFC_VoltCtrlExec(PFC_VOLTCTRL_Handle *voltCtrl, float vdcFbk); + +void PFC_VoltCtrlClear(PFC_VOLTCTRL_Handle *voltCtrl); /** * @} */ @@ -69,4 +70,4 @@ void PFC_VoltCtrlExec(PFC_VOLTCTRL_Handle *voltCtrl); /** * @} */ -#endif /* McuMagicTag_PFC_VOLT_CTRL_H */ +#endif /* McuMagicTag_PFC_VOLT_CTRL_H */ \ No newline at end of file diff --git a/src/middleware/control_library/pid_controller/mcs_pid_ctrl.c b/src/middleware/control_library/pid_controller/mcs_pid_ctrl.c index f780fd62e3b0de8303393ed103f3e07ccbcfbb21..9b71e25bff7aab525c71a5813c40f42742059e3c 100644 --- a/src/middleware/control_library/pid_controller/mcs_pid_ctrl.c +++ b/src/middleware/control_library/pid_controller/mcs_pid_ctrl.c @@ -122,6 +122,46 @@ float PID_Exec(PID_Handle *pidHandle) return out; } +/** + * @brief Execute PID controller calculation. dynamic clamping, feedforward compensataion, + * differential anti-feedback disturbance + * @param pidHandle PID controller struct handle. + * @param fbError Current feedback error. + * @param fbErrorLast Last feedback error. + * @retval PID control output. + */ +float PID_ExecDiffWithFbk(PID_Handle *pidHandle) +{ + MCS_ASSERT_PARAM(pidHandle != NULL); + /* Proportional Item */ + float error = pidHandle->error; + float fbkVal = pidHandle->fbkVal; + float fbkValLast = pidHandle->fbkValLast; + float ts = pidHandle->ts; + + float p = pidHandle->kp * error; + + /* Integral Item */ + float i = pidHandle->ki * ts * (error - pidHandle->ka * pidHandle->saturation) + pidHandle->integral; + i = Clamp(i, Max(0.0f, pidHandle->upperLimit), Min(0.0f, pidHandle->lowerLimit)); + pidHandle->integral = i; + + /* Differential Item */ + float kd = pidHandle->kd; + float ns = pidHandle->ns; + float d = 1.0f / (1.0f + ts * ns) * (kd * ns * fbkVal - kd * ns * fbkValLast + pidHandle->differ); + + pidHandle->fbkValLast = pidHandle->fbkVal; + pidHandle->differ = d; + + /* Output value update and saturation value calculation */ + float val = p + i + d + pidHandle->feedforward; + float out = Clamp(val, pidHandle->upperLimit, pidHandle->lowerLimit); + pidHandle->saturation = val - out; + + return out; +} + /** * @brief Set the proportional parameter kp of PID controller. * @param pidHandle PID controller struct handle. diff --git a/src/middleware/control_library/pid_controller/mcs_pid_ctrl.h b/src/middleware/control_library/pid_controller/mcs_pid_ctrl.h index 651850972cce1aff9a836b0a79fd3bd87f1755e5..8b967a5e4160e46497529a285f0e8e12d26ab8f0 100644 --- a/src/middleware/control_library/pid_controller/mcs_pid_ctrl.h +++ b/src/middleware/control_library/pid_controller/mcs_pid_ctrl.h @@ -43,6 +43,8 @@ typedef struct { float error; /**< Error feedback. */ float errorLast; /**< Error feedback history values. */ + float fbkVal; /**< Current feedback value. */ + float fbkValLast; /**< Last feedback value. */ float feedforward; /**< Feedforward item. */ float integral; /**< Integral item. */ float saturation; /**< Saturation value of the integral item. */ @@ -83,10 +85,12 @@ typedef struct { * @brief The PID control API definitions. * @{ */ + void PID_Reset(PID_Handle *pidHandle); void PID_Clear(PID_Handle *pidHandle); float PI_Exec(PID_Handle *pidHandle); float PID_Exec(PID_Handle *pidHandle); +float PID_ExecDiffWithFbk(PID_Handle *pidHandle); void PID_SetKp(PID_Handle *pidHandle, float kp); void PID_SetKi(PID_Handle *pidHandle, float ki); diff --git a/src/middleware/control_library/power/mcs_power_mgmt.c b/src/middleware/control_library/power/mcs_power_mgmt.c index a15b3f660aadc85506a27d8e76f9f16732c227ad..8f6cae20c64d862aee089f723207055821ae9c44 100644 --- a/src/middleware/control_library/power/mcs_power_mgmt.c +++ b/src/middleware/control_library/power/mcs_power_mgmt.c @@ -27,45 +27,47 @@ /** * @brief Init motor power management. - * @param avgPower Pointer of motor power handle. + * @param powerCalc Pointer of motor power handle. * @param vdqRef Pointer of vdqRef handle. * @param idqFbk Pointer of idqFbk handle. + * @param fltCoeff Power filter coefficient. * @retval None. */ -void MotorPowerInit(POWER_Handle *avgPower, DqAxis *vdqRef, DqAxis *idqFbk) +void MotorPowerInit(POWER_Handle *powerCalc, DqAxis *vdqRef, DqAxis *idqFbk, float fltCoeff) { - MCS_ASSERT_PARAM(avgPower != NULL); + MCS_ASSERT_PARAM(powerCalc != NULL); MCS_ASSERT_PARAM(vdqRef != NULL); MCS_ASSERT_PARAM(idqFbk != NULL); /* Initialization. */ - avgPower->avgPower = 0.0f; + powerCalc->power = 0.0f; /* Initialization. */ - avgPower->vdqRef = vdqRef; - avgPower->idqFbk = idqFbk; + powerCalc->vdqRef = vdqRef; + powerCalc->idqFbk = idqFbk; + powerCalc->fltCoeff = fltCoeff; } /** * @brief Power result value. - * @param avgPower Pointer of motor power handle. + * @param powerCalc Pointer of motor power handle. * @retval Motor power value (w). */ -float MotorPowerCalc(POWER_Handle *avgPower) +float MotorPowerCalc(POWER_Handle *powerCalc) { - MCS_ASSERT_PARAM(avgPower != NULL); + MCS_ASSERT_PARAM(powerCalc != NULL); /* Calculate average power. */ - float activePower = 1.5f * (avgPower->idqFbk->d * avgPower->vdqRef->d + avgPower->idqFbk->q * avgPower->vdqRef->q); - avgPower->avgPower = activePower; - return activePower; + float actvPwr = 1.5f * (powerCalc->idqFbk->d * powerCalc->vdqRef->d + powerCalc->idqFbk->q * powerCalc->vdqRef->q); + powerCalc->power = actvPwr * powerCalc->fltCoeff + powerCalc->power * (1.0f - powerCalc->fltCoeff); + return powerCalc->power; } /** * @brief Clear motor power history value. - * @param avgPower Pointer of motor power handle. + * @param powerCalc Pointer of motor power handle. * @retval None. */ -void MotorPowerClear(POWER_Handle *avgPower) +void MotorPowerClear(POWER_Handle *powerCalc) { - MCS_ASSERT_PARAM(avgPower != NULL); + MCS_ASSERT_PARAM(powerCalc != NULL); /* Clear history value. */ - avgPower->avgPower = 0.0f; + powerCalc->power = 0.0f; } \ No newline at end of file diff --git a/src/middleware/control_library/power/mcs_power_mgmt.h b/src/middleware/control_library/power/mcs_power_mgmt.h index 1133c06b2ac14f97ba7f9dc7f7790a957eb3b034..04c4f93bab0bc5e0f5815fc81b56e52d0a00853a 100644 --- a/src/middleware/control_library/power/mcs_power_mgmt.h +++ b/src/middleware/control_library/power/mcs_power_mgmt.h @@ -29,16 +29,18 @@ /* Typedef definitions ------------------------------------------------------------------------- */ typedef struct { - float avgPower; /**< Average power. */ + float power; /**< power. */ + + float fltCoeff; /**< Power filter coefficient. */ DqAxis *idqFbk; /**< Current value of d, q axis. */ DqAxis *vdqRef; /**< Voltage value of d, q axis. */ } POWER_Handle; -void MotorPowerInit(POWER_Handle *avgPower, DqAxis *vdqRef, DqAxis *idqFbk); +void MotorPowerInit(POWER_Handle *powerCalc, DqAxis *vdqRef, DqAxis *idqFbk, float fltCoeff); -float MotorPowerCalc(POWER_Handle *avgPower); +float MotorPowerCalc(POWER_Handle *powerCalc); -void MotorPowerClear(POWER_Handle *avgPower); +void MotorPowerClear(POWER_Handle *powerCalc); #endif \ No newline at end of file diff --git a/src/middleware/control_library/protection/mcs_unbalance_det.c b/src/middleware/control_library/protection/mcs_unbalance_det.c index b7f24d89dc9dd01ab36f40de9adb55d569a85d99..94422b51134037a07d6687fbdae0a0c3ed8d73a4 100644 --- a/src/middleware/control_library/protection/mcs_unbalance_det.c +++ b/src/middleware/control_library/protection/mcs_unbalance_det.c @@ -146,7 +146,7 @@ static void UNBAL_Calc(UNBAL_Handle *unbal, UvwAxis *iuvwFbk, float unbalFltCoef /* Current cycle sampling completed */ if (unbal->startFlagLast != unbal->startFlag) { unbal->calFlag = true; - if (Abs(unbal->ia) <= 1e-6) { /* Whether there is current */ + if (Abs(unbal->ia) <= FLT_EPSILON) { /* Whether there is current */ unbal->unbalDegree = 0.0f; return; } diff --git a/src/middleware/control_library/ramp/mcs_ramp_mgmt.h b/src/middleware/control_library/ramp/mcs_ramp_mgmt.h index fecbbe48637d35752fde1c0fe94a6c2d10d2c527..5caa23f7d1c26efdd84cfec8ca35e9f1ae530ffd 100644 --- a/src/middleware/control_library/ramp/mcs_ramp_mgmt.h +++ b/src/middleware/control_library/ramp/mcs_ramp_mgmt.h @@ -41,6 +41,7 @@ typedef struct { * @brief The RAMP API definitions. * @{ */ + void RMG_Init(RMG_Handle *rmg, float ts, float slope); void RMG_Clear(RMG_Handle *rmg); float RMG_Exec(RMG_Handle *rmg, float targetVal); diff --git a/src/middleware/control_library/utilities/mcs_mtr_param.c b/src/middleware/control_library/utilities/mcs_mtr_param.c index 29eaffbf2dd2d4ec1fe946efc66c0058fcc5af98..28763e3832ed928c8d4128395b587dd43faffe18 100644 --- a/src/middleware/control_library/utilities/mcs_mtr_param.c +++ b/src/middleware/control_library/utilities/mcs_mtr_param.c @@ -44,4 +44,7 @@ handle->maxElecSpd = motorTable.maxElecSpd; /* max elec speed */ handle->maxCurr = motorTable.maxCurr; /* max current */ handle->maxTrq = motorTable.maxTrq; /* max torque */ + handle->busVolt = motorTable.busVolt; + handle->mtrPPMR = motorTable.mtrPPMR; + handle->zShift = motorTable.zShift; } \ No newline at end of file diff --git a/src/middleware/control_library/utilities/mcs_mtr_param.h b/src/middleware/control_library/utilities/mcs_mtr_param.h index 678d58a30246a979b0b1f043b24ecd36581c4053..d0b8200460eb710c5264b1853c968b744c53317a 100644 --- a/src/middleware/control_library/utilities/mcs_mtr_param.h +++ b/src/middleware/control_library/utilities/mcs_mtr_param.h @@ -45,6 +45,7 @@ typedef struct { float maxElecSpd; /**< Max elec speed, Hz. */ float maxCurr; /**< Max current, A. */ float maxTrq; /**< Max torque, Nm. */ + float busVolt; /**< Bus voltage, V. */ /* Encoder parameters */ unsigned int mtrPPMR; /**< pulse per mechanical round */ unsigned int zShift; /**< pulse Z shift */ diff --git a/src/middleware/function_safety/common/function_safety_battery.h b/src/middleware/function_safety/common/function_safety_battery.h new file mode 100644 index 0000000000000000000000000000000000000000..866d3d5b18e7eb128fb65380153fb372af3f6ae4 --- /dev/null +++ b/src/middleware/function_safety/common/function_safety_battery.h @@ -0,0 +1,31 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file stl_lib.h + * @author MCU Driver Team + * @brief This file contains the self-test head files and global module handles + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef FUNCTION_SAFETY_BATTERY_H +#define FUNCTION_SAFETY_BATTERY_H + +/* Includes ------------------------------------------------------------------*/ +#include "function_safety_common.h" + + +#endif diff --git a/src/middleware/function_safety/common/function_safety_common.h b/src/middleware/function_safety/common/function_safety_common.h new file mode 100644 index 0000000000000000000000000000000000000000..1540ddb0b44e4fcab405c1bcfcb99dc1f9a88413 --- /dev/null +++ b/src/middleware/function_safety/common/function_safety_common.h @@ -0,0 +1,247 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_battery.h + * @author MCU Driver Team + * @brief This file contains the function safety head file of battery. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef FUNCTION_SAFETYE_COMMON_H +#define FUNCTION_SAFETYE_COMMON_H + +#include "baseinc.h" +#include "sysctrl.h" +#include "crg.h" +#include "gpio.h" +/*--- Diagnose param check ----------------------------------------------------*/ +#ifdef DIAGNOSE_PARAM_CHECK +#define DIAGNOSE_PARAM_CHECK_WITH_STATE(param, state) \ + do { \ + if (!(param)) { \ + STATE_SetDiagnoseResult((FunctionSafetyState *)state, RESULT_FAIL); \ + STATE_SetDiagnoseFaultType((FunctionSafetyState *)state, FAULT_SOFTWARE_PARAM_INCORRECT); \ + return *(FunctionSafetyState *)state; \ + } \ + } while (0) +#else +#define DIAGNOSE_PARAM_CHECK_WITH_STATE(param, ret) ((void)0U) +#endif +/*--- Result definition ------------------------------------------------------*/ +#define RESULT_IS_RUNNING 0x00 +#define RESULT_WARNNING 0x01 +#define RESULT_FAIL 0x02 +#define RESULT_SUCCESS 0x03 + +/*--- Subsysterm definition --------------------------------------------------*/ +#define SUBSYS_CORE 0x01 +#define SUBSYS_CLOCK 0x02 +#define SUBSYS_COMPUTE 0x03 +#define SUBSYS_ROM 0x04 +#define SUBSYS_RAM 0x05 +#define SUBSYS_ANALOG_IO 0x06 +#define SUBSYS_DIGTAL_IO 0x07 +#define SUBSYS_TIMERS 0x08 +#define SUBSYS_CONNECT 0x09 +#define SUBSYS_MONITOR 0x0A + +/*--- Fault type definition --------------------------------------------------*/ +/* common fault type define in here, subsysterm fault type define in subsysterm file */ +#define FAULT_SOFTWARE_PARAM_INCORRECT 0x0F +#define FAULT_REPORT_TIMEOUT 0x0E +/*--- Error rate definition --------------------------------------------------*/ +#define ERROR_RATE_OVER_RANGE 0x7F +/*--- Fail safe measure definition -------------------------------------------*/ +/* common Fail safe measure define in here, subsysterm Fail safe measure define in subsysterm file */ +#define FAIL_SAFE_DEFAULT_MEASURE 0x0F + +typedef enum { + MOMENT_ALLTIME = 0U, + MOMENT_STARTUP, + MOMENT_RUNTIME, + MOMENT_IRQ, +} DiagnoseMoment; + +typedef union { + unsigned int code; + struct { + unsigned int result : 2; + unsigned int moment : 2; + unsigned int errorRate : 8; + unsigned int failSafeMeasure : 4; + unsigned int faultType : 4; + unsigned int feature : 4; + unsigned int moudule : 4; + unsigned int subsysterm : 4; + } BIT; +} FunctionSafetyState; +/** + * @brief set diagnose feature to state. + * @param state @ref FunctionSafetyState. + * @param moment moment. + * @retval None. + */ +static inline void STATE_SetDiagnoseMoment(FunctionSafetyState* state, unsigned int moment) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(moment < 4); /* 4: moment state value limit */ + state->BIT.moment = moment; +} +/** + * @brief set diagnose feature to state. + * @param state @ref FunctionSafetyState. + * @param result result. + * @retval None. + */ +static inline void STATE_SetDiagnoseResult(FunctionSafetyState* state, unsigned int result) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(result < 4); /* 4: result state value limit */ + state->BIT.result = result; +} +/** + * @brief set diagnose feature to state. + * @param state @ref FunctionSafetyState. + * @param subsysterm subsysterm. + * @retval None. + */ +static inline void STATE_SetDiagnoseSubsysterm(FunctionSafetyState* state, unsigned int subsysterm) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(subsysterm < 16); /* 16: subsysterm type value limit */ + state->BIT.subsysterm = subsysterm; +} +/** + * @brief set diagnose feature to state. + * @param state @ref FunctionSafetyState. + * @param moudule module. + * @retval None. + */ +static inline void STATE_SetDiagnoseMoudule(FunctionSafetyState* state, unsigned int moudule) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(moudule < 16); /* 16: moudule type value limit */ + state->BIT.moudule = moudule; +} +/** + * @brief set diagnose feature to state. + * @param state @ref FunctionSafetyState. + * @param feature feature. + * @retval None. + */ +static inline void STATE_SetDiagnoseFeature(FunctionSafetyState* state, unsigned int feature) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(feature < 16); /* 16: feature type value limit */ + state->BIT.feature = feature; +} +/** + * @brief set diagnose fault type to state. + * @param state @ref FunctionSafetyState. + * @param faultType fault type. + * @retval None. + */ +static inline void STATE_SetDiagnoseFaultType(FunctionSafetyState* state, unsigned int faultType) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(faultType < 16); /* 16: faultType value limit */ + state->BIT.faultType = faultType; +} +/** + * @brief set diagnose fail safe measure to state. + * @param state @ref FunctionSafetyState. + * @param failSafeMeasure fail safe measure. + * @retval None. + */ +static inline void STATE_SetDiagnoseFailSafeMeasure(FunctionSafetyState* state, unsigned int failSafeMeasure) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(failSafeMeasure < 16); /* 16: failSafeMeasure type value limit */ + state->BIT.failSafeMeasure = failSafeMeasure; +} +/** + * @brief set diagnose error rate to state. + * @param state @ref FunctionSafetyState. + * @param errorRate diagnose error rate. + * @retval None. + */ +static inline void STATE_SetDiagnoseErrorRate(FunctionSafetyState* state, unsigned int errorRate, bool unsignFlag) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(errorRate < 128); /* 128: errorRate type value limit */ + state->BIT.errorRate = unsignFlag == true ? errorRate : (0x80 | errorRate); +} +/** + * @brief store fail event state. + * @param state @ref FunctionSafetyState. + * @retval None. + */ +static inline void STATE_StoreFailEvent(FunctionSafetyState* state) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + unsigned int softIrqEventId = *(unsigned int*)(void*)state; + DCL_SYSCTRL_SetSoftInterruptEventId(softIrqEventId); /* set fail event */ +} +/** + * @brief Load fail event state. + * @param None. + * @retval state @ref FunctionSafetyState. + */ +static inline FunctionSafetyState STATE_LoadFailEvent(void) +{ + return (FunctionSafetyState)DCL_SYSCTRL_GetSoftInterruptEventId(); /* get fail event */ +} +/** + * @brief store current state. + * @param state @ref FunctionSafetyState. + * @retval None. + */ +static inline void STATE_StoreCurrentState(FunctionSafetyState* state) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + SYSCTRL0->USER_REG0.reg = *(unsigned int*)(void*)state; /* store current state into USER_REG0 */ +} +/** + * @brief Load current state. + * @param None. + * @retval state @ref FunctionSafetyState. + */ +static inline FunctionSafetyState STATE_LoadCurrentState(void) +{ + return (FunctionSafetyState)SYSCTRL0->USER_REG0.reg; /* load current state from USER_REG0 */ +} +/** + * @brief Get cpu cycle. + * @param None. + * @retval current cpu cycle. + */ +static inline unsigned int BASE_GetCpuCycle(void) +{ + /* Get the Cpu Cycle Register(CSR) */ + unsigned int cycle; + asm volatile("csrr %0, cycle" : "=r"(cycle)); + return cycle; +} + +typedef void (* ConfigFunc)(void); +typedef FunctionSafetyState (* BackupFunc)(void* handle, DiagnoseMoment moment); +typedef FunctionSafetyState (* DiagnoseFunc)(void* handle, DiagnoseMoment moment); +typedef FunctionSafetyState (* FailSafeFunc)(void* handle, DiagnoseMoment moment); +typedef FunctionSafetyState (* FaultPredictFunc)(void* handle, DiagnoseMoment moment); +typedef FunctionSafetyState (* ResumeFunc)(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/common/function_safety_mcu.h b/src/middleware/function_safety/common/function_safety_mcu.h new file mode 100644 index 0000000000000000000000000000000000000000..b0791a32b57c7fd7f09fc8e3b9c248e77f3b007b --- /dev/null +++ b/src/middleware/function_safety/common/function_safety_mcu.h @@ -0,0 +1,55 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_mcu.h + * @author MCU Driver Team + * @brief This file contains the function safety head file of mcu. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef FUNCTION_SAFETY_MCU_H +#define FUNCTION_SAFETY_MCU_H + +/* common --------------------------------------------------------------------*/ +#include "function_safety_common.h" +#include "function_safety_process.h" +/* diagnose ------------------------------------------------------------------*/ +#include "diagnose_mcu_core.h" +#include "diagnose_mcu_clock.h" +#include "diagnose_mcu_compute.h" +#include "diagnose_mcu_rom.h" +#include "diagnose_mcu_ram.h" +#include "diagnose_mcu_ana.h" +#include "diagnose_mcu_dio.h" +#include "diagnose_mcu_monitor.h" +#include "diagnose_mcu_timers.h" +#include "diagnose_mcu_connect.h" +/* fail safe -----------------------------------------------------------------*/ +#include "failsafe_mcu_ana.h" +#include "failsafe_mcu_core.h" +#include "failsafe_mcu_clock.h" +#include "failsafe_mcu_compute.h" +#include "failsafe_mcu_rom.h" +#include "failsafe_mcu_ram.h" +#include "failsafe_mcu_ana.h" +#include "failsafe_mcu_dio.h" +#include "failsafe_mcu_monitor.h" +#include "failsafe_mcu_timers.h" +#include "failsafe_mcu_connect.h" +/* fault predict -------------------------------------------------------------*/ + +#endif diff --git a/src/middleware/function_safety/common/function_safety_motor.h b/src/middleware/function_safety/common/function_safety_motor.h new file mode 100644 index 0000000000000000000000000000000000000000..da6b063498134ca98929ed26afed7166245434e3 --- /dev/null +++ b/src/middleware/function_safety/common/function_safety_motor.h @@ -0,0 +1,31 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_motor.h + * @author MCU Driver Team + * @brief This file contains the function safety head file of motor. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef FUNCTION_SAFETY_MOTOR_H +#define FUNCTION_SAFETY_MOTOR_H + +/* Includes ------------------------------------------------------------------*/ +#include "function_safety_common.h" + + +#endif diff --git a/src/middleware/function_safety/library/mcu/analog_io/inc/diagnose_mcu_ana.h b/src/middleware/function_safety/library/mcu/analog_io/inc/diagnose_mcu_ana.h new file mode 100644 index 0000000000000000000000000000000000000000..38b69fc5fd8f1883d622f8d9f0981484ef83de54 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/analog_io/inc/diagnose_mcu_ana.h @@ -0,0 +1,81 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_ana.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ana diagnose. + */ + +#ifndef DIAGNOSE_MCU_ANA_H +#define DIAGNOSE_MCU_ANA_H + +#include "function_safety_common.h" +#ifdef ADC0 /* ADC0 represent ip support adc controler, not means only adc0 */ +#include "adc.h" +#endif +#ifdef DAC0 /* DAC0 represent ip support dac controler, not means only dac0 */ +#include "dac.h" +#endif +#ifdef ACMP0 /* ACMP0 represent ip support acmp controler, not means only acmp0 */ +#include "acmp.h" +#endif +#ifdef PGA0 /* PGA0 represent ip support pga controler, not means only pga0 */ +#include "pga.h" +#endif + +#define MODULE_ADC 0x01 +#define MODULE_DAC 0x02 +#define MODULE_PGA 0x04 +#define MODULE_ACMP 0x08 + +#define FEATURE_ACCURACY 0x01 + +#define FAULT_1ST_OVER_ACCURACY 0x01 +#define FAULT_2ST_OVER_ACCURACY 0x02 +#define FAULT_3ST_OVER_ACCURACY 0x03 + +typedef struct { +#ifdef ADC0 + ADC_Handle* adcHandle; + ADC_SOCNumber socx; +#endif +#ifdef DAC0 + DAC_Handle* dacHandleRef; + DAC_Handle* dacHandleTarget; +#endif +#ifdef PGA0 + PGA_Handle* pgaHandle; +#endif +#ifdef ACMP0 + ACMP_Handle* acmpHandle; +#endif + unsigned int adcMaxRange; + unsigned int dacMaxRange; + unsigned int errRangePercent; +} ANA_DiagnoseHandle; + +#if defined(ADC0) && defined(DAC0) +FunctionSafetyState ANA_DiagnoseAdcSampleAccuracy(void* anaDiagnoseHandle, DiagnoseMoment moment); +#endif +#if defined(ADC0) && defined(DAC0) && defined(PGA0) +FunctionSafetyState ANA_DiagnosePgaInnerGainAccuracy(void* anaDiagnoseHandle, DiagnoseMoment moment); +#endif +#if defined(DAC0) && defined(ACMP0) +FunctionSafetyState ANA_DiagnoseAcmpThresholdAccuracy(void* anaDiagnoseHandle, DiagnoseMoment moment); +#endif + +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/include/nos/nos_typedef.h b/src/middleware/function_safety/library/mcu/analog_io/inc/failsafe_mcu_ana.h similarity index 71% rename from src/middleware/hisilicon/nostask/include/nos/nos_typedef.h rename to src/middleware/function_safety/library/mcu/analog_io/inc/failsafe_mcu_ana.h index 39f3cc1c76ec10bf2a9b9aa60456b40de988ed08..f671ca1d8087d30617a53228e214c11577571d5e 100644 --- a/src/middleware/hisilicon/nostask/include/nos/nos_typedef.h +++ b/src/middleware/function_safety/library/mcu/analog_io/inc/failsafe_mcu_ana.h @@ -15,40 +15,25 @@ * 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. - * @file nos_typedef.h + * @file failsafe_mcu_ana.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ana failsafe. */ -#ifndef NOS_TYPEDEF_H -#define NOS_TYPEDEF_H -#include "os_typedef.h" +#ifndef FAILSAFE_MCU_ANA_H +#define FAILSAFE_MCU_ANA_H -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ +#include "function_safety_common.h" -#define OS_NULL_BYTE ((unsigned char)0xffU) -#define OS_NULL_SHORT ((unsigned short)0xffffU) -#define OS_NULL_INT ((unsigned int)0xffffffffU) -#define NULL_DWORD ((unsigned int)0xFFFFFFFFU) +typedef struct { + ANA_DiagnoseHandle* anaDiagnoseHandle; + void* param; +} ANA_FailSafeHandle; -#ifndef UNLIKELY -#define UNLIKELY(x) __builtin_expect(!!(x), 0) +FunctionSafetyState ANA_FailSafeHandler(void* anaFailSafeHandle, DiagnoseMoment moment); +#ifdef ADC0 +FunctionSafetyState ANA_AdcFailSafeHandler(void* anaFailSafeHandle, DiagnoseMoment moment); #endif +__weak FunctionSafetyState ANA_DefaultFailSafe(void* anaFailSafeHandle, DiagnoseMoment moment); -#ifndef NOS_OK -#define NOS_OK 0 -#endif - -#ifndef NOS_FAIL -#define NOS_FAIL 1 -#endif - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* NOS_TYPEDEF_H */ +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/include/common/os_module.h b/src/middleware/function_safety/library/mcu/analog_io/inc/faultpredict_mcu_ana.h similarity index 79% rename from src/middleware/hisilicon/nostask/include/common/os_module.h rename to src/middleware/function_safety/library/mcu/analog_io/inc/faultpredict_mcu_ana.h index 4067612b58c23cdd5df3c63a8b064e2603570cf8..38eb5c23b98a3f0649608ff40eecfbb0993984f8 100644 --- a/src/middleware/hisilicon/nostask/include/common/os_module.h +++ b/src/middleware/function_safety/library/mcu/analog_io/inc/faultpredict_mcu_ana.h @@ -15,28 +15,20 @@ * 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. - * @file os_module.h + * @file faultpredict_mcu_ana.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ana faultpredict. */ -#ifndef OS_MODULE_H -#define OS_MODULE_H -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ +#ifndef FAULTPREDICT_MCU_ANA_H +#define FAULTPREDICT_MCU_ANA_H -enum OsMoudleId { - OS_MID_SYS = 0x0, /* 系统模块 */ - OS_MID_TSK = 0x8, - OS_MID_SCHED = 0x4c, - OS_MID_BUTT = 0x57 -}; +#include "function_safety_common.h" -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ +typedef struct { + void *param; +} ANA_FaultPredictHandle; -#endif /* OS_MODULE_H */ +FunctionSafetyState ANA_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/analog_io/src/diagnose_mcu_ana.c b/src/middleware/function_safety/library/mcu/analog_io/src/diagnose_mcu_ana.c new file mode 100644 index 0000000000000000000000000000000000000000..06b906f6f35eab0dd8304ee74b400438f7736970 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/analog_io/src/diagnose_mcu_ana.c @@ -0,0 +1,221 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_ana.c + * @author MCU Driver Team + * @brief This file contains the functions definition for ana diagnose. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "diagnose_mcu_ana.h" +/*----------------------------- ADC sample DAC output accuracy diagnose ------------------------------------*/ +#if defined (ADC0) && defined(DAC0) +/** + * @brief Diagnose ana subsystem's ADC sampling dac accuracy. + * @param handle Value of @ref ANA_DiagnoseHandle. + * @param state point of @ref FunctionSafetyState. + * @param testDacVal Value of dac config. + * @param refAdcVal ref adc value. + * @retval state Value of @ref FunctionSafetyState. + */ +static FunctionSafetyState AdcSampleDacAccuracyDiagnose(ANA_DiagnoseHandle* handle, FunctionSafetyState* state, \ + unsigned int testDacVal, unsigned int refAdcVal) +{ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->adcMaxRange != 0, state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(testDacVal <= handle->adcMaxRange, state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(refAdcVal <= handle->adcMaxRange, state); + HAL_DAC_SetValue(handle->dacHandleRef, testDacVal); + BASE_FUNC_DELAY_US(10); /* 10 : delay time 10us */ + HAL_ADC_SoftTrigSample(handle->adcHandle, handle->socx); + while (HAL_ADC_CheckSocFinish(handle->adcHandle, handle->socx) != BASE_STATUS_OK) { + } + unsigned int value = HAL_ADC_GetConvResult(handle->adcHandle, handle->socx); + unsigned int errRate = 0; + bool unsginFlag = 0; + if (handle->errRangePercent != 0) { + if (value > refAdcVal) { + errRate = (value - refAdcVal) * 100 / handle->adcMaxRange; /* 100: percent rate, 4096 is full range */ + unsginFlag = true; + } else { + errRate = (refAdcVal - value) * 100 / handle->adcMaxRange; /* 100: percent rate, 4096 is full range */ + unsginFlag = false; + } + STATE_SetDiagnoseErrorRate(state, errRate, unsginFlag); /* set error rate into state */ + } + if (errRate > handle->errRangePercent) { /* error judgment */ + STATE_SetDiagnoseResult(state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(state, FAULT_1ST_OVER_ACCURACY); /* set fault type and fail result into state */ + return *state; + } + return *state; +} + +/** + * @brief Diagnose ana subsystem's ADC sampling accuracy. + * @param anaDiagnoseHandle Value of @ref ANA_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState ANA_DiagnoseAdcSampleAccuracy(void* anaDiagnoseHandle, DiagnoseMoment moment) +{ + ANA_DiagnoseHandle* handle = (ANA_DiagnoseHandle*)anaDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_ANALOG_IO); + STATE_SetDiagnoseMoudule(&state, MODULE_ADC); + STATE_SetDiagnoseFeature(&state, FEATURE_ACCURACY); /* set subsysterm and module and feature */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->adcHandle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->dacHandleRef != NULL, &state); /* param check */ + /* test 1 : set DAC output 1/4 max range , adc sample dac should be about 1/4 max range */ + state = AdcSampleDacAccuracyDiagnose(handle, &state, (handle->dacMaxRange / 4), /* 1/4 dac max range */ + (handle->adcMaxRange / 4)); /* 1/4 adc max range */ + if (state.BIT.result == RESULT_FAIL) { + return state; + } + /* test 2 : set DAC output 2/4 max range , adc sample dac should be about 2/4 max range */ + state = AdcSampleDacAccuracyDiagnose(handle, &state, (handle->dacMaxRange / 2), /* 1/2 dac max range */ + (handle->adcMaxRange / 2)); /* 1/2 adc max range */ + if (state.BIT.result == RESULT_FAIL) { + return state; + } + /* test 3 : set DAC output 3/4 max range , adc sample dac should be about 3/4 max range */ + state = AdcSampleDacAccuracyDiagnose(handle, &state, ((handle->dacMaxRange * 3) / 4), /* 3/4 dac max range */ + ((handle->adcMaxRange * 3) / 4)); /* 3/4 adc max range */ + if (state.BIT.result == RESULT_FAIL) { + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set success into state */ + return state; +} +#endif +/*----------------------------- PGA Inner Gain accuracy diagnose ------------------------------------*/ +#if defined(ADC0) && defined(DAC0) && defined(PGA0) +/** + * @brief Diagnose ana subsystem's ADC sampling dac accuracy. + * @param handle Value of @ref ANA_DiagnoseHandle. + * @param state point of @ref FunctionSafetyState. + * @param testDacVal Value of dac config. + * @param refAdcVal ref adc value. + * @retval state Value of @ref FunctionSafetyState. + */ +static FunctionSafetyState PgaInnerGainAccuracyDiagnose(ANA_DiagnoseHandle* handle, FunctionSafetyState* state, \ + unsigned int refDacVal, unsigned int targetDacVal, PGA_GainValue pgaGain) +{ + DIAGNOSE_PARAM_CHECK_WITH_STATE(refDacVal <= handle->dacMaxRange, state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(targetDacVal <= handle->dacMaxRange, state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(pgaGain <= PGA_GAIN_16X, state); + HAL_DAC_SetValue(handle->dacHandleRef, refDacVal); + HAL_DAC_SetValue(handle->dacHandleTarget, targetDacVal); /* set ref and target dac value */ + HAL_PGA_SetGain(handle->pgaHandle, pgaGain); + HAL_ADC_SoftTrigSample(handle->adcHandle, handle->socx); + while (HAL_ADC_CheckSocFinish(handle->adcHandle, handle->socx) != BASE_STATUS_OK) { + } + signed int value = (signed int)HAL_ADC_GetConvResult(handle->adcHandle, handle->socx); + signed int errRate = value - (signed int)(handle->dacMaxRange / 2); /* ref adc value */ + errRate = (errRate < 0) ? -errRate : errRate; + signed int adcValErrRang = (signed int)handle->errRangePercent; + if (errRate >= adcValErrRang) { + STATE_SetDiagnoseResult(state, RESULT_FAIL); /* set fail result into state */ + STATE_SetDiagnoseFaultType(state, FAULT_1ST_OVER_ACCURACY); /* set fault type into state */ + return *state; + } + return *state; +} + +/** + * @brief Diagnose ana subsystem's PGA inner gain accuracy. + * @param anaDiagnoseHandle Value of @ref ANA_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState ANA_DiagnosePgaInnerGainAccuracy(void* anaDiagnoseHandle, DiagnoseMoment moment) +{ + ANA_DiagnoseHandle* handle = (ANA_DiagnoseHandle*)anaDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_ANALOG_IO); + STATE_SetDiagnoseMoudule(&state, MODULE_PGA); + STATE_SetDiagnoseFeature(&state, FEATURE_ACCURACY); /* set function state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->adcHandle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->pgaHandle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->dacHandleRef != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->dacHandleTarget != NULL, &state); + /* test 1 : PGA Differential 1/4 voltage, adc sample PGA out should be about 1/2 max range in gain equal 2x */ + state = PgaInnerGainAccuracyDiagnose(handle, &state, 0, (handle->dacMaxRange / 4), PGA_GAIN_2X); /* 1/4 range */ + if (state.BIT.result == RESULT_FAIL) { + return state; + } + /* test 2 : set PGA Differential 1/16 voltage, adc sample PGA out should be about 1/2 max range in gain equal 8x */ + state = PgaInnerGainAccuracyDiagnose(handle, &state, 0, (handle->dacMaxRange / 16), PGA_GAIN_8X); /* 1/16 range */ + if (state.BIT.result == RESULT_FAIL) { + return state; + } + /* test 3 : set PGA Differential 1/8 voltage, adc sample PGA out should be about 1/2 max range in gain equal 4x */ + state = PgaInnerGainAccuracyDiagnose(handle, &state, 0, (handle->dacMaxRange / 8), PGA_GAIN_4X); /* 1/8 range */ + if (state.BIT.result == RESULT_FAIL) { + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); + return state; +} +#endif +/*----------------------------- ACMP Threshold accuracy diagnose ------------------------------------*/ +#if defined(DAC0) && defined(ACMP0) +/** + * @brief Diagnose ana subsystem's ACMP compare output. + * @param anaDiagnoseHandle Value of @ref ANA_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState ANA_DiagnoseAcmpThresholdAccuracy(void* anaDiagnoseHandle, DiagnoseMoment moment) +{ + ANA_DiagnoseHandle* handle = (ANA_DiagnoseHandle*)anaDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_ANALOG_IO); + STATE_SetDiagnoseMoudule(&state, MODULE_ACMP); + STATE_SetDiagnoseFeature(&state, FEATURE_ACCURACY); /* set function state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->acmpHandle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->dacHandleRef != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->dacHandleTarget != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->errRangePercent < 100, &state); /* 100: upbound */ + unsigned int dacValErrRang = (handle->dacMaxRange / 2) * handle->errRangePercent / 100; /* 100: percent, 2: half */ + /* test 1 : set ACMP Differential voltage < 0, Not invert, ACMP out should be equal 0 */ + HAL_DAC_SetValue(handle->dacHandleRef, (handle->dacMaxRange / 2) + dacValErrRang); /* 2: half dac max range */ + HAL_DAC_SetValue(handle->dacHandleTarget, (handle->dacMaxRange / 2)); /* 2: half dac max range */ + unsigned int value = DCL_ACMP_GetCmpOutValueOriginal(handle->acmpHandle->baseAddress); + if (value == 1) { /* acmp output high level */ + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_1ST_OVER_ACCURACY); + return state; + } + /* test 2 : set ACMP Differential voltage > 0, Not invert, ACMP out should be equal 1 */ + HAL_DAC_SetValue(handle->dacHandleRef, (handle->dacMaxRange / 2) - dacValErrRang); /* N channel, 2:half dac range */ + HAL_DAC_SetValue(handle->dacHandleTarget, (handle->dacMaxRange / 2)); /* P channel, 2:half dac range */ + value = DCL_ACMP_GetCmpOutValueOriginal(handle->acmpHandle->baseAddress); + if (value == 0) { /* acmp output low level */ + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_2ST_OVER_ACCURACY); + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); + return state; +} +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/analog_io/src/failsafe_mcu_ana.c b/src/middleware/function_safety/library/mcu/analog_io/src/failsafe_mcu_ana.c new file mode 100644 index 0000000000000000000000000000000000000000..2c1b55f3a71ede5c66ab503a465cdb869bb8c756 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/analog_io/src/failsafe_mcu_ana.c @@ -0,0 +1,102 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_ana.c + * @author MCU Driver Team + * @brief This file contains the functions definition for ana failsafe. + */ + +#include "diagnose_mcu_ana.h" +#include "failsafe_mcu_ana.h" + +/** + * @brief Default failsafe of ana subsystem. + * @param anaDiagnoseHandle Value of @ref ANA_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +__weak FunctionSafetyState ANA_DefaultFailSafe(void* anaFailSafeHandle, DiagnoseMoment moment) +{ + ANA_FailSafeHandle* handle = (ANA_FailSafeHandle*)anaFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + while (1) { /* program stuck */ + } + return state; +} + +#if defined(ADC0) +/** + * @brief failsafe of ana subsystem's ADC sampling accuracy. + * @param anaDiagnoseHandle Value of @ref ANA_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState ANA_AdcFailSafeHandler(void* anaFailSafeHandle, DiagnoseMoment moment) +{ + ANA_FailSafeHandle* handle = (ANA_FailSafeHandle*)anaFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + BASE_FUNC_UNUSED(handle); + if (state.BIT.moudule != MODULE_ADC) { + return state; + } + if (moment == MOMENT_STARTUP) { + HAL_CRG_IpClkResetSet(handle->anaDiagnoseHandle->adcHandle, BASE_CFG_SET); /* adc module soft reset */ + HAL_ADC_Init(handle->anaDiagnoseHandle->adcHandle); /* adc init after adc soft reset */ + } else if (moment == MOMENT_RUNTIME) { + } else if (moment == MOMENT_IRQ) { + } + return state; +} +#endif +/** + * @brief failsafe of ana subsystem. + * @param anaDiagnoseHandle Value of @ref ANA_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState ANA_FailSafeHandler(void* anaFailSafeHandle, DiagnoseMoment moment) +{ + ANA_FailSafeHandle* handle = (ANA_FailSafeHandle*)anaFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + switch (state.BIT.moudule) { +#if defined(ADC0) + case MODULE_ADC: + state = ANA_AdcFailSafeHandler(handle, moment); /* adc fail safe handler */ + break; +#endif +#if defined(DAC0) + case MODULE_DAC: + break; +#endif +#if defined(PGA0) + case MODULE_PGA: + break; +#endif +#if defined(ACMP0) + case MODULE_ACMP: + break; +#endif + default: + state = ANA_DefaultFailSafe(handle, moment); /* default fail safe of ANA */ + break; + } + return state; +} \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/include/nos_idle_external.h b/src/middleware/function_safety/library/mcu/analog_io/src/faultpredict_mcu_ana.c similarity index 85% rename from src/middleware/hisilicon/nostask/kernel/include/nos_idle_external.h rename to src/middleware/function_safety/library/mcu/analog_io/src/faultpredict_mcu_ana.c index 494f4cb0c8feb3825b3fd8f484de786a62e46b5b..103751f3e9a8cf4195bcd10c72b723462c20cd52 100644 --- a/src/middleware/hisilicon/nostask/kernel/include/nos_idle_external.h +++ b/src/middleware/function_safety/library/mcu/analog_io/src/faultpredict_mcu_ana.c @@ -15,15 +15,9 @@ * 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. - * @file nos_idle_external.h + * @file faultpredict_mcu_ana.c + * @author MCU Driver Team + * @brief This file contains the functions definition for ana faultpredict. */ -#ifndef NOS_IDLE_EXTERNAL_H -#define NOS_IDLE_EXTERNAL_H +#include "faultpredict_mcu_ana.h" -#include "nos_sys_external.h" - -extern OsVoidFunc g_idleSwiSwitchToTask; -extern void OsIdleTaskExe(void); -extern void OsIdleThread(void); - -#endif /* NOS_IDLE_EXTERNAL_H */ diff --git a/src/middleware/function_safety/library/mcu/clock/inc/diagnose_mcu_clock.h b/src/middleware/function_safety/library/mcu/clock/inc/diagnose_mcu_clock.h new file mode 100644 index 0000000000000000000000000000000000000000..f1ca5d0bb165b90565ee56ce14bbd6096fb29d58 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/clock/inc/diagnose_mcu_clock.h @@ -0,0 +1,73 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_clock.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for clock diagnose. + */ + +#ifndef DIAGNOSE_MCU_CLOCK_H +#define DIAGNOSE_MCU_CLOCK_H + +#include "function_safety_common.h" +#ifdef CRG +#include "crg.h" +#endif +#ifdef CMM +#include "cmm.h" +#endif +#ifdef CFD +#include "cfd.h" +#endif + +#define MODULE_CMM 0x01 +#define MODULE_CFD 0x02 + +#define FEATURE_CLOCK_ACCURACY_SINGLE_CHECK 0x01 +#define FEATURE_CLOCK_ACCURACY_CONTINUE_CHECK 0x02 +#define FEATURE_PLLREF_CLOCK_STOP_CHECK 0x03 + +#define FAULT_OVER_ACCURACY 0x01 +#define FAULT_PLLREF_CLOCK_STOP 0x02 + +typedef struct { +#ifdef CMM + CMM_Handle* cmmHandle; + unsigned int cmmTargetVal; + unsigned int cmmClockCount; + bool cmmIrqFlag; +#endif +#ifdef CFD + CFD_Handle* cfdHandle; + unsigned int cfdTargetVal; + unsigned int cfdClockCount; + bool cfdIrqFlag; +#endif + unsigned int checkEndDelayTimeUs; + unsigned int errRangePercent; +} CLOCK_DiagnoseHandle; + +#ifdef CMM +FunctionSafetyState CLOCK_CmmWindowsBoundCalculate(void* clockDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState CLOCK_CmmDiagnoseAccuracy(void* clockDiagnoseHandle, DiagnoseMoment moment); +#endif +#ifdef CFD +FunctionSafetyState CLOCK_CfdWindowsBoundCalculate(void* clockDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState CLOCK_CfdDiagnosePllRefClockStop(void* clockDiagnoseHandle, DiagnoseMoment moment); +#endif + +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/include/common/os_init.h b/src/middleware/function_safety/library/mcu/clock/inc/failsafe_mcu_clock.h similarity index 72% rename from src/middleware/hisilicon/nostask/include/common/os_init.h rename to src/middleware/function_safety/library/mcu/clock/inc/failsafe_mcu_clock.h index 6ea69c16b6788067e7956bc73f29334e5dd8f4af..b1e75d3d9cf864a59964e87fba0b2742f19cef0b 100644 --- a/src/middleware/hisilicon/nostask/include/common/os_init.h +++ b/src/middleware/function_safety/library/mcu/clock/inc/failsafe_mcu_clock.h @@ -15,30 +15,22 @@ * 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. - * @file os_init.h + * @file failsafe_mcu_clock.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for clock failsafe. */ -#ifndef OS_INIT_H -#define OS_INIT_H -#include "os_task.h" +#ifndef FAILSAFE_MCU_CLOCK_H +#define FAILSAFE_MCU_CLOCK_H -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ +#include "function_safety_common.h" -/* 模块注册函数的声明 */ -extern void OsIdleReg(void); -extern unsigned int OsTskInit(void); +typedef struct { + void *param; +} CLOCK_FailSafeHandle; -/* 系统启动相关函数的声明 */ -extern unsigned int OsActivate(void); +FunctionSafetyState CLOCK_AccuracyFailSafe(void* clockFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState CLOCK_FailSafeHandler(void* clockFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState CLOCK_DefaultFailSafe(void* clockFailSafeHandle, DiagnoseMoment moment); -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* OS_INIT_H */ +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/clock/inc/faultpredict_mcu_clock.h b/src/middleware/function_safety/library/mcu/clock/inc/faultpredict_mcu_clock.h new file mode 100644 index 0000000000000000000000000000000000000000..6f1b4a96188dcf527239184c67aea115500f0f46 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/clock/inc/faultpredict_mcu_clock.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_clock.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for clock faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_CLOCK_H +#define FAULTPREDICT_MCU_CLOCK_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} CLOCK_FaultPredictHandle; + +FunctionSafetyState CLOCK_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/clock/src/diagnose_mcu_clock.c b/src/middleware/function_safety/library/mcu/clock/src/diagnose_mcu_clock.c new file mode 100644 index 0000000000000000000000000000000000000000..8893a8b79bba2894a7026b7479eef4e8cd2a6559 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/clock/src/diagnose_mcu_clock.c @@ -0,0 +1,377 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_clock.c + * @author MCU Driver Team + * @brief This file contains the functions definition for clock diagnose. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "diagnose_mcu_clock.h" + +#define FREQ_ERR_CONVERT_CNT_ERR_RANGE 0U +#define CNT_ERR_CONVERT_FREQ_ERR_RANGE 1U + +/** + * @brief clock frequency or count error swap. + * @param clockFreq Value of clock frequency. + * @param targetValue Value of target count value. + * @param percent Value of error range. + * @param convertType Value of FREQ_ERR_CONVERT_CNT_ERR_RANGE or CNT_ERR_CONVERT_FREQ_ERR_RANGE. + * @retval unsigned int frequency or count value. + */ +static unsigned int CLOCK_FreqAndCntErrSwap(unsigned int clockFreq, float targetValue, \ + unsigned int percent, bool convertType) +{ + float error = 0.0; + error = ((float)percent / 100.0f); /* 100: percent unit */ + error = (error < 0) ? (-error) : error; + if (convertType == FREQ_ERR_CONVERT_CNT_ERR_RANGE) { + return (unsigned int)(error * targetValue + 0.5f); /* 0.5: round value */ + } else { + BASE_FUNC_ASSERT_PARAM(clockFreq != 0); + return (unsigned int)(error * clockFreq + 0.5f); /* 0.5: round value */ + } +} +/* -------------------------------- CMM Diagnose Clock frequency ------------------- */ +#ifdef CMM +/** + * @brief Get the Frequency of a Clock Source. + * @param clockSource Clock source corresponding to the register. + * @param clockType zero means target clock, one means ref clock. + * @retval clock frequency. + */ +static unsigned int CLOCK_GetTargetClockSourceFreq(CMM_Target_Clock_Source clockSource) +{ + BASE_FUNC_ASSERT_PARAM(clockSource <= 4); /* 4: reg value limit */ + unsigned int clockFreq = 0; + switch (clockSource) { + case CMM_TARGET_CLK_HS_SYS: + clockFreq = HAL_CRG_GetCoreClkFreq(); /* get core clock frequency */ + break; + case CMM_TARGET_CLK_HOSC: + clockFreq = HOSC_FREQ; /* HOSC clock frequency */ + break; + case CMM_TARGET_CLK_TCXO: + clockFreq = XTRAIL_FREQ; /* XTAL clock frequency */ + break; + case CMM_TARGET_CLK_LOSC: + clockFreq = LOSC_FREQ; /* LOSC clock frequency */ + break; + case 4: /* 4: reg value means LS clock frequency */ + clockFreq = HAL_CRG_GetCoreClkFreq() / 2; /* 2: half hs clock */ + break; + default: + break; + } + return clockFreq; +} +/** + * @brief Get the Frequency of a Clock Source. + * @param clockSource Clock source corresponding to the register. + * @param clockType zero means target clock, one means ref clock. + * @retval clock frequency. + */ +static unsigned int CLOCK_GetRefClockSourceFreq(CMM_Ref_Clock_Source clockSource) +{ + BASE_FUNC_ASSERT_PARAM(clockSource <= 4); /* 4: reg value limit */ + unsigned int clockFreq = 0; + switch (clockSource) { + case CMM_REF_CLK_HS_SYS: + clockFreq = HAL_CRG_GetCoreClkFreq(); /* get core clock frequency */ + break; + case CMM_REF_CLK_HOSC: + clockFreq = HOSC_FREQ; /* HOSC clock frequency */ + break; + case CMM_REF_CLK_TCXO: + clockFreq = XTRAIL_FREQ; /* XTAL clock frequency */ + break; + case CMM_REF_CLK_LOSC: + clockFreq = LOSC_FREQ; /* LOSC clock frequency */ + break; + default: + break; + } + return clockFreq; +} + +/** + * @brief Get the Frequency division of a Clock Source. + * @param clockSourceDiv Clock division corresponding to the register. + * @param clockType zero means target clock, one means ref clock. + * @retval clock frequency division. + */ +static unsigned int CLOCK_GetTargetClockSourceDiv(CMM_Target_Freq_Div_Value clockSourceDiv) +{ + BASE_FUNC_ASSERT_PARAM(clockSourceDiv <= 4); /* 4: reg value limit */ + unsigned int clockDiv = 0; + switch (clockSourceDiv) { + case CMM_TARGET_FREQ_DIV_0: + clockDiv = 1; /* 1: div value is 1 */ + break; + case CMM_TARGET_FREQ_DIV_32: + clockDiv = 32; /* 32: div value is 32 */ + break; + case CMM_TARGET_FREQ_DIV_128: + clockDiv = 128; /* 128: div value is 128 */ + break; + case CMM_TARGET_FREQ_DIV_1024: + clockDiv = 1024; /* 1024: div value is 1024 */ + break; + case CMM_TARGET_FREQ_DIV_8192: + clockDiv = 8192; /* 8192: div value is 8192 */ + break; + default: + break; + } + return clockDiv; +} + +/** + * @brief Get the Frequency division of a Clock Source. + * @param clockSourceDiv Clock division corresponding to the register. + * @param clockType zero means target clock, one means ref clock. + * @retval clock frequency division. + */ +static unsigned int CLOCK_GetRefClockSourceDiv(CMM_Ref_Freq_Div_Value clockSourceDiv) +{ + BASE_FUNC_ASSERT_PARAM(clockSourceDiv <= 4); /* 4: reg value up bound */ + unsigned int clockDiv = 0; + switch (clockSourceDiv) { + case CMM_REF_FREQ_DIV_0: + clockDiv = 1; /* 1: div value is 1 */ + break; + case CMM_REF_FREQ_DIV_4: + clockDiv = 4; /* 4: div value is 4 */ + break; + case CMM_REF_FREQ_DIV_8: + clockDiv = 8; /* 8: div value is 8 */ + break; + case CMM_REF_FREQ_DIV_32: + clockDiv = 32; /* 32: div value is 32 */ + break; + default: + break; + } + return clockDiv; +} +/** + * @brief Get the cmm count tagert value. + * @param cmmHandle Value of @ref CMM_Handle. + * @retval unsigned int cmm count tagert value. + */ +static unsigned int CLOCK_GetCmmTargetValue(CMM_Handle* cmmHandle) +{ + BASE_FUNC_ASSERT_PARAM(cmmHandle != NULL); + unsigned int ret = 0; + /* get target clock and ref clock's frequency and division */ + unsigned int targetClockSourceFreq = CLOCK_GetTargetClockSourceFreq(cmmHandle->targetClockSource); + unsigned int refClockSourceFreq = CLOCK_GetRefClockSourceFreq(cmmHandle->refClockSource); + unsigned int targetClockDivVal = CLOCK_GetTargetClockSourceDiv(cmmHandle->targetFreqDivision); + unsigned int refClockDivVal = CLOCK_GetRefClockSourceDiv(cmmHandle->refFreqDivision); + if (targetClockSourceFreq == 0 || refClockSourceFreq == 0 || targetClockDivVal == 0 || refClockDivVal == 0) { + return ret; + } + /* prevent value is float conver to int drop data, up to unsigned int to set windows value, error control is 0.01 */ + ret = (unsigned int)(((float)targetClockDivVal / refClockDivVal) * \ + ((float)refClockSourceFreq / targetClockSourceFreq) + 0.5f); + return ret; +} + +/** + * @brief Cmm count value windows bound config. + * @param clockDiagnoseHandle Value of @ref CLOCK_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CLOCK_CmmWindowsBoundCalculate(void* clockDiagnoseHandle, DiagnoseMoment moment) +{ + CLOCK_DiagnoseHandle* handle = (CLOCK_DiagnoseHandle*)clockDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_CLOCK); + STATE_SetDiagnoseMoudule(&state, MODULE_CMM); /* set subsysterm and module */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->cmmHandle != NULL, &state); + handle->cmmTargetVal = CLOCK_GetCmmTargetValue(handle->cmmHandle); /* get target cmm count value */ + if (handle->cmmTargetVal == 0) { + STATE_SetDiagnoseFaultType(&state, FAULT_SOFTWARE_PARAM_INCORRECT); + return state; + } + unsigned int clockFreq = CLOCK_GetTargetClockSourceFreq(handle->cmmHandle->targetClockSource); + /* error unit swap from frequency and count */ + unsigned int cntError = CLOCK_FreqAndCntErrSwap(clockFreq, handle->cmmTargetVal, \ + handle->errRangePercent, FREQ_ERR_CONVERT_CNT_ERR_RANGE); + handle->cmmHandle->lowerBound = ((signed int)(handle->cmmTargetVal - cntError) < 0) ? \ + 0 : handle->cmmTargetVal - cntError; + handle->cmmHandle->upperBound = handle->cmmTargetVal + cntError; + return state; +} + +/** + * @brief Cmm diagnose clock accuracy. + * @param clockDiagnoseHandle Value of @ref CLOCK_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CLOCK_CmmDiagnoseAccuracy(void* clockDiagnoseHandle, DiagnoseMoment moment) +{ + CLOCK_DiagnoseHandle* handle = (CLOCK_DiagnoseHandle*)clockDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_CLOCK); + STATE_SetDiagnoseMoudule(&state, MODULE_CMM); + STATE_SetDiagnoseFeature(&state, FEATURE_CLOCK_ACCURACY_SINGLE_CHECK); /* set subsysterm and module and feature */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->cmmHandle != NULL, &state); + if (handle->cmmHandle->interruptType == CMM_INT_CHECK_END_MASK) { /* interrupt check end single times */ + BASE_FUNC_DELAY_US(handle->checkEndDelayTimeUs); + if (!handle->cmmIrqFlag) { + STATE_SetDiagnoseResult(&state, RESULT_IS_RUNNING); + return state; + } + handle->cmmIrqFlag = BASE_CFG_UNSET; + HAL_CMM_Stop(handle->cmmHandle); /* single check and stop */ + if (handle->cmmClockCount > handle->cmmHandle->upperBound || \ + handle->cmmClockCount < handle->cmmHandle->lowerBound) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_OVER_ACCURACY); /* set fault type */ + return state; + } + } else { + if (handle->cmmIrqFlag) { + handle->cmmIrqFlag = BASE_CFG_UNSET; + STATE_SetDiagnoseResult(&state, RESULT_FAIL); /* IN CMM CHECK ERR IRQ */ + STATE_SetDiagnoseFaultType(&state, FAULT_OVER_ACCURACY); + return state; + } + } + unsigned int errorRate = 0; + bool unsignFlag = false; + if (handle->cmmClockCount > handle->cmmTargetVal) { + errorRate = (handle->cmmClockCount - handle->cmmTargetVal); + unsignFlag = true; + } else { + errorRate = (handle->cmmTargetVal - handle->cmmClockCount); + unsignFlag = false; + } + errorRate = errorRate * 100 / (handle->cmmHandle->upperBound - handle->cmmTargetVal); /* 100 : percent */ + STATE_SetDiagnoseErrorRate(&state, errorRate, unsignFlag); /* set error rate to state */ + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +#endif +/* -------------------------------- CFD Diagnose Pll ref Clock stop ------------------- */ +#ifdef CFD +/** + * @brief Get the cfd count tagert value. + * @param cfdHandle Value of @ref CFD_Handle. + * @retval unsigned int cfd count tagert value. + */ +static unsigned int CLOCK_GetCfdTargetValue(CFD_Handle* cfdHandle) +{ + BASE_FUNC_ASSERT_PARAM(cfdHandle != NULL); + unsigned int targetClockSource = DCL_CRG_GetPllRefClkSel(CRG); + unsigned int targetClockSourceFreq = (targetClockSource == (unsigned int)CRG_PLL_REF_CLK_SELECT_HOSC) ? \ + HOSC_FREQ : XTRAIL_FREQ; + unsigned int refClockSourceFreq = LOSC_FREQ; + unsigned int targetClockDivVal = 2048; /* 2048:chip has fix the value */ + unsigned int refClockDivVal = 1; /* chip has fix the value */ + /* prevent value is float conver to int drop data, up to unsigned int to set windows value, error control is 0.01 */ + return ((unsigned int)(((float)targetClockDivVal * (float)refClockSourceFreq) / \ + ((float)refClockDivVal * (float)targetClockSourceFreq) + 0.5f)); +} + +/** + * @brief Cfd count value windows bound config. + * @param clockDiagnoseHandle Value of @ref CLOCK_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CLOCK_CfdWindowsBoundCalculate(void* clockDiagnoseHandle, DiagnoseMoment moment) +{ + CLOCK_DiagnoseHandle* handle = (CLOCK_DiagnoseHandle*)clockDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_CLOCK); + STATE_SetDiagnoseMoudule(&state, MODULE_CFD); /* set subsysterm and module */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->cfdHandle != NULL, &state); + /* target cfd count value, 0.5 for mod */ + handle->cfdTargetVal = (unsigned int)((float)CLOCK_GetCfdTargetValue(handle->cfdHandle) + 0.5f); /* 0.5 for mod */ + unsigned int clockFreq = (DCL_CRG_GetPllRefClkSel(CRG) == (unsigned int)CRG_PLL_REF_CLK_SELECT_HOSC) ? \ + HOSC_FREQ : XTRAIL_FREQ; + /* error unit swap from frequency and count */ + unsigned int cntError = CLOCK_FreqAndCntErrSwap(clockFreq, handle->cfdTargetVal, \ + handle->errRangePercent, FREQ_ERR_CONVERT_CNT_ERR_RANGE); + handle->cfdHandle->upperBound = handle->cfdTargetVal + cntError; + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); + return state; +} + +/** + * @brief Cfd diagnose pll ref clock accuracy. + * @param clockDiagnoseHandle Value of @ref CLOCK_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CLOCK_CfdDiagnosePllRefClockStop(void* clockDiagnoseHandle, DiagnoseMoment moment) +{ + CLOCK_DiagnoseHandle* handle = (CLOCK_DiagnoseHandle*)clockDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_CLOCK); + STATE_SetDiagnoseMoudule(&state, MODULE_CFD); + STATE_SetDiagnoseFeature(&state, FEATURE_PLLREF_CLOCK_STOP_CHECK); /* set subsysterm and module and feature */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->cfdHandle != NULL, &state); + if (handle->cfdHandle->interruptType == CFD_INT_CHECK_END_MASK) { /* interrupt check end single times */ + BASE_FUNC_DELAY_US(handle->checkEndDelayTimeUs); + if (!handle->cfdIrqFlag) { + STATE_SetDiagnoseResult(&state, RESULT_IS_RUNNING); + return state; + } + handle->cfdIrqFlag = BASE_CFG_UNSET; + HAL_CFD_Stop(handle->cfdHandle); /* single check and stop */ + if (handle->cfdClockCount > handle->cfdHandle->upperBound) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_PLLREF_CLOCK_STOP); /* set fault type */ + return state; + } + } else { + if (handle->cfdIrqFlag) { + handle->cfdIrqFlag = BASE_CFG_UNSET; + STATE_SetDiagnoseResult(&state, RESULT_FAIL); /* IN CMM CHECK ERR IRQ */ + STATE_SetDiagnoseFaultType(&state, FAULT_PLLREF_CLOCK_STOP); + return state; + } + } + unsigned int errorRate = 0; + bool unsignFlag = false; + if (handle->cfdClockCount > handle->cfdTargetVal) { + errorRate = (handle->cfdClockCount - handle->cfdTargetVal); + unsignFlag = true; + } else { + errorRate = (handle->cfdTargetVal - handle->cfdClockCount); + unsignFlag = false; + } + errorRate = errorRate * 100 / (handle->cmmHandle->upperBound - handle->cmmTargetVal); /* 100 : conver to percent */ + STATE_SetDiagnoseErrorRate(&state, errorRate, unsignFlag); /* set error rate to state */ + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/nos_amp_task_init.c b/src/middleware/function_safety/library/mcu/clock/src/failsafe_mcu_clock.c similarity index 38% rename from src/middleware/hisilicon/nostask/kernel/nos_amp_task_init.c rename to src/middleware/function_safety/library/mcu/clock/src/failsafe_mcu_clock.c index ccfeb832b35d1e63afac0fc99c1e7c592a35d88b..c6251583b8a3092bda7737a66a49a30f3a7b3f66 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_amp_task_init.c +++ b/src/middleware/function_safety/library/mcu/clock/src/failsafe_mcu_clock.c @@ -15,80 +15,68 @@ * 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. - * @file nos_amp_task_init.c + * @file failsafe_mcu_clock.c + * @author MCU Driver Team + * @brief This file contains the functions definition for failsafe diagnose. */ -#include "nos_task_internal.h" -/* - * 描述: AMP Task init function. - */ -unsigned int OsTskAMPInit(void); -unsigned int OsTskAMPInit(void) +#include "diagnose_mcu_clock.h" +#include "failsafe_mcu_clock.h" +/** + * @brief default failsafe measure of clock . + * @param clockDiagnoseHandle Value of @ref CLOCK_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +__weak FunctionSafetyState CLOCK_DefaultFailSafe(void* clockFailSafeHandle, DiagnoseMoment moment) { - unsigned int idx; - - // 1为Idle任务 - g_threadNum += (g_tskMaxNum + 1); - - if (g_tskCBArray == NULL) { - return OS_ERRNO_TSK_NO_MEMORY; - } - - OS_LIST_INIT(&g_tskCBFreeList); - for (idx = 0; idx < OS_MAX_TCB_NUM - 1; idx++) { - g_tskCBArray[idx].taskStatus = OS_TSK_UNUSED; - g_tskCBArray[idx].taskPid = idx; - ListTailAdd(&g_tskCBArray[idx].pendList, &g_tskCBFreeList); + CLOCK_FailSafeHandle* handle = (CLOCK_FailSafeHandle*)clockFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + while (1) { /* program stuck for doing something */ } - - /* 在初始化时给RUNNING_TASK的PID赋一个合法的无效值,放置在Trace使用时出现异常 */ - RUNNING_TASK = OS_PST_ZOMBIE_TASK; - - /* 在初始化时给RUNNING_TASK的PID赋一个合法的无效值,放置在Trace使用时出现异常 */ - RUNNING_TASK->taskPid = idx; - - /* Init empty ready list for each priority. */ - for (idx = 0; idx < OS_TSK_NUM_OF_PRIORITIES; idx++) { - OS_LIST_INIT(&g_runQueue.readyList[idx]); - } - - OS_LIST_INIT(&g_tskSortedDelay.tskList); - OS_LIST_INIT(&g_tskRecyleList); - - /* 增加OS_TSK_INUSE状态,使得在Trace记录的第一条信息状态为OS_TSK_INUSE(创建状态) */ - RUNNING_TASK->taskStatus = (OS_TSK_INUSE | OS_TSK_RUNNING); - RUNNING_TASK->priority = OS_TSK_PRIORITY_LOWEST + 1; - - return NOS_OK; + return state; } - -unsigned char __attribute__((aligned(16))) g_idleTaskStackSpace[OS_TSK_IDLE_STACK_SIZE]; - -/* - * 描述: ilde Task create. - */ -unsigned int OsIdleTskAMPCreate(void) +/** + * @brief failsafe measure of clock accuracy. + * @param clockDiagnoseHandle Value of @ref CLOCK_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CLOCK_AccuracyFailSafe(void* clockFailSafeHandle, DiagnoseMoment moment) { - unsigned int ret; - unsigned int taskHdl; - struct TskInitParam taskInitParam; - const char *tskName = "IdleCore000"; - /* Create background task. */ - taskInitParam.taskEntry = (TskEntryFunc)g_idleEntry; - taskInitParam.stackSize = (unsigned int)sizeof(g_idleTaskStackSpace); - taskInitParam.name = tskName; - /* Lowest Priority */ - taskInitParam.taskPrio = OS_TSK_PRIORITY_LOWEST; - taskInitParam.stackAddr = (uintptr_t)g_idleTaskStackSpace; - taskInitParam.privateData = 0; - - /* 任务调度的必要条件就是有背景任务,此时背景任务还没有创建,因此不会发生任务切换 */ - ret = NOS_TaskCreateInner(&taskHdl, &taskInitParam); - if (ret != NOS_OK) { - return ret; + CLOCK_FailSafeHandle* handle = (CLOCK_FailSafeHandle*)clockFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + BASE_FUNC_UNUSED(handle); + if (moment == MOMENT_STARTUP) { /* at moment startup */ + } else if (moment == MOMENT_RUNTIME) { /* at moment runtime */ + } else if (moment == MOMENT_IRQ) { /* at moment irq */ } - - IDLE_TASK_ID = taskHdl; - - return ret; + return state; } +/** + * @brief failsafe measure handler of clock. + * @param clockDiagnoseHandle Value of @ref CLOCK_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CLOCK_FailSafeHandler(void* clockFailSafeHandle, DiagnoseMoment moment) +{ + CLOCK_FailSafeHandle* handle = (CLOCK_FailSafeHandle*)clockFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + switch (state.BIT.faultType) { + case FAULT_OVER_ACCURACY: + state = CLOCK_AccuracyFailSafe(handle, moment); /* clock accuracy fail safe handler */ + break; + case FAULT_PLLREF_CLOCK_STOP: + break; + default: + state = CLOCK_DefaultFailSafe(handle, moment); /* clock default fail safe handler */ + break; + } + return state; +} \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/clock/src/faultpredict_mcu_clock.c b/src/middleware/function_safety/library/mcu/clock/src/faultpredict_mcu_clock.c new file mode 100644 index 0000000000000000000000000000000000000000..30b8692b3d13c3c2bbfff30ab70d90a0f3b179b3 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/clock/src/faultpredict_mcu_clock.c @@ -0,0 +1,23 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_clock.c + * @author MCU Driver Team + * @brief This file contains the functions definition for failsafe faultpredict. + */ +#include "faultpredict_mcu_ana.h" + diff --git a/src/middleware/function_safety/library/mcu/compute/inc/diagnose_mcu_compute.h b/src/middleware/function_safety/library/mcu/compute/inc/diagnose_mcu_compute.h new file mode 100644 index 0000000000000000000000000000000000000000..d2740506f11f479c2d75bda1d54da355c69e370e --- /dev/null +++ b/src/middleware/function_safety/library/mcu/compute/inc/diagnose_mcu_compute.h @@ -0,0 +1,50 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_compute.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for compute diagnose. + */ + +#ifndef DIAGNOSE_MCU_COMPUTE_H +#define DIAGNOSE_MCU_COMPUTE_H + +#include "function_safety_common.h" +#ifdef CRC +#include "crc.h" +#endif + +#define MODULE_CRC 0x01 + +#define FEATURE_COMPUTE_CORRECT 0x01 + +#define FAULT_CRC32_ALGORITHM_COMPUTE_UNCORRECT 0x01 + +typedef struct { +#ifdef CRC + CRC_Handle* crcHandle; +#endif + unsigned int inputTestData; + unsigned int inputDataSize; + unsigned int outputRefData; +} COMPUTE_DiagnoseHandle; + +#ifdef CRC +FunctionSafetyState COMPUTE_DiagnoseCrcAlgorithmCorrect(void* computeDiagnoseHandle, DiagnoseMoment moment); +#endif + +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/include/common/os_buildef_common.h b/src/middleware/function_safety/library/mcu/compute/inc/failsafe_mcu_compute.h similarity index 72% rename from src/middleware/hisilicon/nostask/include/common/os_buildef_common.h rename to src/middleware/function_safety/library/mcu/compute/inc/failsafe_mcu_compute.h index 851bd8b36e82e5937c883eb6e256c86d299ffcd1..04f1dcbf8f0ccdec28a077b439b376707a8a0bee 100644 --- a/src/middleware/hisilicon/nostask/include/common/os_buildef_common.h +++ b/src/middleware/function_safety/library/mcu/compute/inc/failsafe_mcu_compute.h @@ -15,29 +15,22 @@ * 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. - * @file os_buildef_common.h + * @file failsafe_mcu_compute.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for compute failsafe. */ -#ifndef OS_BUILDEF_COMMON_H -#define OS_BUILDEF_COMMON_H -/* To define OS_HARDWARE_PLATFORM */ -/* 编译器有个bug, 未定义的宏的数值默认是0,所以不用使用'0' */ -#define OS_RISCV 0x19 -#define OS_PLATFORM_INVALID 0x1a +#ifndef FAILSAFE_MCU_COMPUTE_H +#define FAILSAFE_MCU_COMPUTE_H -/* To define OS_CPU_TYPE */ -/* 编译器有个bug, 未定义的宏的数值默认是0,所以不用使用'0' */ -#define OS_HIMIDEER 0x22 +#include "function_safety_common.h" -/* 必须方案nos_buildef的头文件中,否则会出现宏开关不生效的问题 */ -#ifdef YES -#undef YES -#endif -#define YES 1 +typedef struct { + void *param; +} COMPUTE_FailSafeHandle; -#ifdef NO -#undef NO -#endif -#define NO 0 +FunctionSafetyState COMPUTE_DefaultFailSafe(void* computeFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState COMPUTE_FailSafeHandler(void* computeFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState COMPUTE_Crc32FailSafe(void* computeFailSafeHandle, DiagnoseMoment moment); -#endif /* OS_BUILDEF_COMMON_H */ +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/nos_taskself_id.c b/src/middleware/function_safety/library/mcu/compute/inc/faultpredict_mcu_compute.h similarity index 78% rename from src/middleware/hisilicon/nostask/kernel/nos_taskself_id.c rename to src/middleware/function_safety/library/mcu/compute/inc/faultpredict_mcu_compute.h index 253080a03e759d6adc66cec9ae20a86812e0f4ea..f223b380e770a48f739b9677156a5a6acf83bcbc 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_taskself_id.c +++ b/src/middleware/function_safety/library/mcu/compute/inc/faultpredict_mcu_compute.h @@ -15,26 +15,20 @@ * 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. - * @file nos_taskself_id.c + * @file faultpredict_mcu_compute.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for compute faultpredict. */ -#include "nos_task_external.h" -/* - * 描述: 获取当前任务ID - */ -unsigned int NOS_TaskSelf(unsigned int *taskPid) -{ - struct TagTskCB *tskCB = RUNNING_TASK; +#ifndef FAULTPREDICT_MCU_COMPUTE_H +#define FAULTPREDICT_MCU_COMPUTE_H - if (taskPid == NULL) { - return OS_ERRNO_TSK_PTR_NULL; - } +#include "function_safety_common.h" - /* 任务的 PID 非法 */ - if (tskCB == NULL) { - return OS_ERRNO_TSK_ID_INVALID; - } +typedef struct { + void *param; +} COMPUTE_FaultPredictHandle; - *taskPid = tskCB->taskPid; - return NOS_OK; -} +FunctionSafetyState COMPUTE_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/include/nos_amp_task_internal.h b/src/middleware/function_safety/library/mcu/compute/src/diagnose_mcu_compute.c similarity index 48% rename from src/middleware/hisilicon/nostask/kernel/include/nos_amp_task_internal.h rename to src/middleware/function_safety/library/mcu/compute/src/diagnose_mcu_compute.c index a912f6ae1e5dc5f9683c1ab2f0efd5b8f11f6c9a..618ee62803f3cf1900f75ff1aca598d2367b7a14 100644 --- a/src/middleware/hisilicon/nostask/kernel/include/nos_amp_task_internal.h +++ b/src/middleware/function_safety/library/mcu/compute/src/diagnose_mcu_compute.c @@ -15,61 +15,39 @@ * 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. - * @file nos_amp_task_internal.h + * @file diagnose_mcu_compute.c + * @author MCU Driver Team + * @brief This file contains the functions definition for compute diagnose. */ -#ifndef NOS_AMP_TASK_INTERNAL_H -#define NOS_AMP_TASK_INTERNAL_H -#include "nos_task_external.h" - -#define OS_TSK_PRIO_BIT_MAP_POW 5 -#define OS_TSK_PRIO_RDY_BIT 0x80000000U - -extern unsigned int OsTskAMPInit(void); - -/* 加入队列尾部 */ -INLINE void OsEnqueueTaskAmp(struct TagOsRunQue *runQue, struct TagTskCB *tsk) -{ - unsigned int priority = tsk->priority; - - ListTailAdd(&tsk->pendList, &runQue->readyList[priority]); - runQue->taskReadyListBitMap |= (OS_TSK_PRIO_RDY_BIT >> priority); -} - -/* 加入队列头部 */ -INLINE void OsEnqueueTaskHeadAmp(struct TagOsRunQue *runQue, struct TagTskCB *tsk) -{ - unsigned int priority = tsk->priority; - - ListAdd(&tsk->pendList, &runQue->readyList[priority]); - runQue->taskReadyListBitMap |= (OS_TSK_PRIO_RDY_BIT >> priority); -} - -/* 出队 */ -INLINE void OsDequeueTaskAmp(struct TagOsRunQue *runQue, struct TagTskCB *tsk) +/* Includes ------------------------------------------------------------------*/ +#include "diagnose_mcu_compute.h" +#ifdef CRC +/** + * @brief diagnose the Correctness of the CRC32 algorithm. + * @param computeDiagnoseHandle Value of @ref COMPUTE_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState COMPUTE_DiagnoseCrcAlgorithmCorrect(void* computeDiagnoseHandle, DiagnoseMoment moment) { - unsigned int priority = tsk->priority; - struct TagListObject *readyList = &runQue->readyList[priority]; - - /* 从链表中删除 */ - ListDelete(&tsk->pendList); - if (ListEmpty(readyList)) { - runQue->taskReadyListBitMap &= ~(OS_TSK_PRIO_RDY_BIT >> priority); + COMPUTE_DiagnoseHandle* handle = (COMPUTE_DiagnoseHandle*)computeDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_COMPUTE); + STATE_SetDiagnoseMoudule(&state, MODULE_CRC); + STATE_SetDiagnoseFeature(&state, FEATURE_COMPUTE_CORRECT); /* set diagnose subsys, module and feature to state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->crcHandle != NULL, &state); /* param check point not null */ + /* compara crc out value with ref crc value */ + bool result = HAL_CRC_CheckInputData(handle->crcHandle, &handle->inputTestData, \ + handle->inputDataSize, handle->outputRefData); + if (result == false) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_CRC32_ALGORITHM_COMPUTE_UNCORRECT); /* set fault type */ + return state; } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result */ + return state; } - -/* 将运行队列的任务计数++ */ -INLINE void OsIncNrRunning(struct TagOsRunQue *runQue) -{ - (void)runQue; - return; -} - -/* 将运行队列的任务计数-- */ -INLINE void OsDecNrRunning(struct TagOsRunQue *runQue) -{ - (void)runQue; - return; -} - -#endif /* NOS_AMP_TASK_INTERNAL_H */ +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/compute/src/failsafe_mcu_compute.c b/src/middleware/function_safety/library/mcu/compute/src/failsafe_mcu_compute.c new file mode 100644 index 0000000000000000000000000000000000000000..9b8fd14671b3e90cbb0e4449857d56d4d5bd34ee --- /dev/null +++ b/src/middleware/function_safety/library/mcu/compute/src/failsafe_mcu_compute.c @@ -0,0 +1,78 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_compute.c + * @author MCU Driver Team + * @brief This file contains the functions definition for compute failsafe. + */ + +#include "diagnose_mcu_compute.h" +#include "failsafe_mcu_compute.h" + +/** + * @brief default failsafe measure of compute . + * @param computeFailSafeHandle Value of @ref COMPUTE_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +__weak FunctionSafetyState COMPUTE_DefaultFailSafe(void* computeFailSafeHandle, DiagnoseMoment moment) +{ + COMPUTE_FailSafeHandle* handle = (COMPUTE_FailSafeHandle*)computeFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check */ + while (1) { + } + return state; +} +/** + * @brief failsafe measure of crc32 algorythm correctness. + * @param computeFailSafeHandle Value of @ref COMPUTE_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState COMPUTE_Crc32FailSafe(void* computeFailSafeHandle, DiagnoseMoment moment) +{ + COMPUTE_FailSafeHandle* handle = (COMPUTE_FailSafeHandle*)computeFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure handler of ccompute. + * @param computeFailSafeHandle Value of @ref COMPUTE_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState COMPUTE_FailSafeHandler(void* computeFailSafeHandle, DiagnoseMoment moment) +{ + COMPUTE_FailSafeHandle* handle = (COMPUTE_FailSafeHandle*)computeFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + switch (state.BIT.faultType) { + case FAULT_CRC32_ALGORITHM_COMPUTE_UNCORRECT: + state = COMPUTE_Crc32FailSafe(handle, moment); /* crc32 calculate fail safe */ + break; + default: + state = COMPUTE_DefaultFailSafe(handle, moment); /* cpmpute default fail safe */ + break; + } + return state; +} \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/compute/src/faultpredict_mcu_compute.c b/src/middleware/function_safety/library/mcu/compute/src/faultpredict_mcu_compute.c new file mode 100644 index 0000000000000000000000000000000000000000..9fc53733e8264cd37c738838b203a4541b78e732 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/compute/src/faultpredict_mcu_compute.c @@ -0,0 +1,23 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_compute.c + * @author MCU Driver Team + * @brief This file contains the functions definition for compute faultpredict. + */ +#include "faultpredict_mcu_ana.h" + diff --git a/src/middleware/function_safety/library/mcu/connect/inc/diagnose_mcu_connect.h b/src/middleware/function_safety/library/mcu/connect/inc/diagnose_mcu_connect.h new file mode 100644 index 0000000000000000000000000000000000000000..290c3e018856206d2032a4a6d251e06a1a232f1a --- /dev/null +++ b/src/middleware/function_safety/library/mcu/connect/inc/diagnose_mcu_connect.h @@ -0,0 +1,65 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_connect.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for connect diagnose. + */ + +#ifndef DIAGNOSE_MCU_CONNECT_H +#define DIAGNOSE_MCU_CONNECT_H + +#include "function_safety_common.h" +#ifdef I2C +#include "i2c.h" +#endif +#ifdef UART0 +#include "uart.h" +#endif +#ifdef SPI +#include "spi.h" +#endif +#ifdef CAN +#include "can.h" +#endif + +#define MODULE_I2C 0x01 +#define MODULE_UART 0x02 +#define MODULE_SPI 0x03 +#define MODULE_CAN 0x04 + +#define FEATURE_CONNECT_DATA_CORRECT 0x01 + +#define FAULT_CONNECT_DATA_UNCORRECT 0x01 + +typedef struct { +#ifdef I2C + I2C_Handle* i2cHandle; +#endif +#ifdef UART0 + UART_Handle* uartHandle; +#endif +#ifdef SPI + SPI_Handle* spiHandle; +#endif +#ifdef CAN + CAN_Handle* canHandle; +#endif +} CONNECT_DiagnoseHandle; + + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/connect/inc/failsafe_mcu_connect.h b/src/middleware/function_safety/library/mcu/connect/inc/failsafe_mcu_connect.h new file mode 100644 index 0000000000000000000000000000000000000000..4fb000f5b057fef97f5119b37d6bdc11bd889fbb --- /dev/null +++ b/src/middleware/function_safety/library/mcu/connect/inc/failsafe_mcu_connect.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_connect.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for connect failsafe. + */ + +#ifndef FAILSAFE_MCU_CONNECT_H +#define FAILSAFE_MCU_CONNECT_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} CONNECT_FailSafeHandle; + +FunctionSafetyState CONNECT_FailSafeHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/connect/inc/faultpredict_mcu_connect.h b/src/middleware/function_safety/library/mcu/connect/inc/faultpredict_mcu_connect.h new file mode 100644 index 0000000000000000000000000000000000000000..fe6ca4c9b00c32b0e75ed4b84a510e827807084b --- /dev/null +++ b/src/middleware/function_safety/library/mcu/connect/inc/faultpredict_mcu_connect.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_connect.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for connect faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_CONNECT_H +#define FAULTPREDICT_MCU_CONNECT_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} CONNECT_FaultPredictHandle; + +FunctionSafetyState CONNECT_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/connect/src/diagnose_mcu_connect.c b/src/middleware/function_safety/library/mcu/connect/src/diagnose_mcu_connect.c new file mode 100644 index 0000000000000000000000000000000000000000..bf653168328ff6cb8e55a108e8b39d3e12a3cc2f --- /dev/null +++ b/src/middleware/function_safety/library/mcu/connect/src/diagnose_mcu_connect.c @@ -0,0 +1,24 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_connect.c + * @author MCU Driver Team + * @brief This file contains the functions definition for connect diagnose. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "diagnose_mcu_compute.h" diff --git a/src/middleware/function_safety/library/mcu/connect/src/failsafe_mcu_connect.c b/src/middleware/function_safety/library/mcu/connect/src/failsafe_mcu_connect.c new file mode 100644 index 0000000000000000000000000000000000000000..7958e508e4394253b8fc140ffbaaef77d576eb0b --- /dev/null +++ b/src/middleware/function_safety/library/mcu/connect/src/failsafe_mcu_connect.c @@ -0,0 +1,23 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_connect.c + * @author MCU Driver Team + * @brief This file contains the functions definition for connect failsafe. + */ + +#include "failsafe_mcu_connect.h" \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/connect/src/faultpredict_mcu_connect.c b/src/middleware/function_safety/library/mcu/connect/src/faultpredict_mcu_connect.c new file mode 100644 index 0000000000000000000000000000000000000000..8d32b5860811005021b05b6af58e79f30c7b063a --- /dev/null +++ b/src/middleware/function_safety/library/mcu/connect/src/faultpredict_mcu_connect.c @@ -0,0 +1,23 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_connect.c + * @author MCU Driver Team + * @brief This file contains the functions definition for connect faultpredict. + */ +#include "faultpredict_mcu_ana.h" + diff --git a/src/middleware/function_safety/library/mcu/core/inc/diagnose_mcu_core.h b/src/middleware/function_safety/library/mcu/core/inc/diagnose_mcu_core.h new file mode 100644 index 0000000000000000000000000000000000000000..0bfb299888179c103b6a34fea1f100720e1fedf0 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/core/inc/diagnose_mcu_core.h @@ -0,0 +1,55 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_core.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for core diagnose. + */ + +#ifndef DIAGNOSE_MCU_CORE_H +#define DIAGNOSE_MCU_CORE_H + +#include "function_safety_common.h" + +#define MODULE_CPU_REGISTER 0x01 +#define MODULE_PC_REGISTER 0x02 +#define MODULE_CPU_SOFT_INTTERRUPT 0x03 + +#define FEATURE_REG_WRITE_READ 0x01 +#define FEATURE_REG_PC_JUMP 0x02 +#define FEATURE_SYSCTRL_CPU_STATUS 0x03 +#define FEATURE_SOFT_INTERRUPT 0x04 + +#define FAULT_REG_SAF 0x01 +#define FAULT_REG_AF 0x02 +#define FAULT_REG_TF 0x03 +#define FAULT_REG_CF 0x04 +#define FAULT_PC_JUMP 0x05 +#define FAULT_PC_INVALID 0x06 +#define FAULT_SYSCTRL_CPU_STATUS 0x07 +#define FAULT_CPU_SOFT_INTTERRUPT 0x08 + +typedef struct { + void* param; +} CORE_DiagnoseHandle; + +FunctionSafetyState CORE_DiagnoseCpuSoftwareIrq(void* coreDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_DiagnoseCpuStatus(void* coreDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_DiagnoseCpuGeneralRegister(void* coreDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_DiagnosePcRegister(void* coreDiagnoseHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/core/inc/failsafe_mcu_core.h b/src/middleware/function_safety/library/mcu/core/inc/failsafe_mcu_core.h new file mode 100644 index 0000000000000000000000000000000000000000..6d002a21caad5e5ec80b221e2ab16760555d8f09 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/core/inc/failsafe_mcu_core.h @@ -0,0 +1,37 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_core.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for core failsafe. + */ + +#ifndef FAILSAFE_MCU_CORE_H +#define FAILSAFE_MCU_CORE_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} CORE_FailSafeHandle; + +FunctionSafetyState CORE_FailSafeHandler(void* coreHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_DefaultFailSafe(void* coreHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_RegSafFailSafe(void* coreHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_FailSafeHandler(void* coreHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/core/inc/faultpredict_mcu_core.h b/src/middleware/function_safety/library/mcu/core/inc/faultpredict_mcu_core.h new file mode 100644 index 0000000000000000000000000000000000000000..eb41a076bf301364dc6764b408b51067c1a2502a --- /dev/null +++ b/src/middleware/function_safety/library/mcu/core/inc/faultpredict_mcu_core.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_core.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for core faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_CORE_H +#define FAULTPREDICT_MCU_CORE_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} CORE_FaultPredictHandle; + +FunctionSafetyState CORE_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/core/src/diagnose_cpu_runtime.S b/src/middleware/function_safety/library/mcu/core/src/diagnose_cpu_runtime.S new file mode 100644 index 0000000000000000000000000000000000000000..8bbe9f5f66683cf6894adda633316c4dccd520e4 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/core/src/diagnose_cpu_runtime.S @@ -0,0 +1,132 @@ +# File Name : diagnose_cpu_runtime.S +# Description : Full RISC-V CPU test during run-time +# Input : None. +# Output : None. +# Return : SUCCESS (=0) if test is ok + +.section .text +.align 2 + +.global CPU_DiagnoseRuntime +.type CPU_DiagnoseRuntime,@function + +#ifdef __riscv64 +#define LREG ld +#define SREG sd +#define REGBYTES 8 +#else +#define LREG lw +#define SREG sw +#define REGBYTES 4 +#endif + +#define TOTAL_INT_SIZE_ON_STACK (20 * REGBYTES) + +.macro push_reg + addi sp, sp, -(TOTAL_INT_SIZE_ON_STACK) + stmia {ra, t0-t2, a0-a7, t3-t6}, (sp) + addi sp, sp, -(TOTAL_INT_SIZE_ON_STACK) +.endm + +.macro pop_reg + addi sp, sp, TOTAL_INT_SIZE_ON_STACK + ldmia {ra, t0-t2, a0-a7, t3-t6}, (sp) + addi sp, sp, TOTAL_INT_SIZE_ON_STACK +.endm + +CPU_DiagnoseRuntime: + push_reg + + # Register a0, a1 (holds value returned by the function) + li a0, 0xAAAAAAAA + li a1, 0xAAAAAAAA + bne a0, a1, FailReturnLabel + li a0, 0x55555555 + li a1, 0x55555555 + bne a0, a1, FailReturnLabel + + # Register a2 + li a0, 0xAAAAAAAA + li a2, 0xAAAAAAAA + bne a0, a2, FailReturnLabel + li a0, 0x55555555 + li a2, 0x55555555 + bne a0, a2, FailReturnLabel + + # Register a3 + li a0, 0xAAAAAAAA + li a3, 0xAAAAAAAA + bne a0, a3, FailReturnLabel + li a0, 0x55555555 + li a3, 0x55555555 + bne a0, a3, FailReturnLabel + + # Register a4 + li a0, 0xAAAAAAAA + li a4, 0xAAAAAAAA + bne a0, a4, FailReturnLabel + li a0, 0x55555555 + li a4, 0x55555555 + bne a0, a4, FailReturnLabel + + # Register a5 + li a0, 0xAAAAAAAA + li a5, 0xAAAAAAAA + bne a0, a5, FailReturnLabel + li a0, 0x55555555 + li a5, 0x55555555 + bne a0, a5, FailReturnLabel + + # Register a6 + li a0, 0xAAAAAAAA + li a6, 0xAAAAAAAA + bne a0, a6, FailReturnLabel + li a0, 0x55555555 + li a6, 0x55555555 + bne a0, a6, FailReturnLabel + + # Register a7 + li a0, 0xAAAAAAAA + li a7, 0xAAAAAAAA + bne a0, a7, FailReturnLabel + li a0, 0x55555555 + li a7, 0x55555555 + bne a0, a7, FailReturnLabel + + # Ramp pattern verification + li a0, 0x00000000 + li a1, 0x00000001 + li a2, 0x00000002 + li a3, 0x00000003 + li a4, 0x00000004 + li a5, 0x00000005 + li a6, 0x00000006 + li a7, 0x00000007 + xori a0, a0, 0x00000000 + bnez a0, FailReturnLabel + xori a1, a1, 0x00000001 + bnez a1, FailReturnLabel + xori a2, a2, 0x00000002 + bnez a2, FailReturnLabel + xori a3, a3, 0x00000003 + bnez a3, FailReturnLabel + xori a4, a4, 0x00000004 + bnez a4, FailReturnLabel + xori a5, a5, 0x00000005 + bnez a5, FailReturnLabel + xori a6, a6, 0x00000006 + bnez a6, FailReturnLabel + xori a7, a7, 0x00000007 + bnez a7, FailReturnLabel + +SuccessReturnLabel: + pop_reg + # CPU test success + li a0, 0x0 + ret + +FailReturnLabel: + pop_reg + # CPU test fail + li a0, 0x1 + ret \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/core/src/diagnose_cpu_startup.S b/src/middleware/function_safety/library/mcu/core/src/diagnose_cpu_startup.S new file mode 100644 index 0000000000000000000000000000000000000000..af41e0be35808f7acaf639ea81d4bcc0a591234b --- /dev/null +++ b/src/middleware/function_safety/library/mcu/core/src/diagnose_cpu_startup.S @@ -0,0 +1,248 @@ +# File Name : diagnose_cpu_startup.S +# Description : Full RISC-V CPU test at start-up +# Input : None. +# Output : None. +# Return : SUCCESS (=0) +# WARNING : all registers content destroyed when exiting this function + +# Externally declare fail-safe routines to prevent unrecoverable failures + + +.section .text +.align 2 + +.global CPU_DiagnoseStartup +.type CPU_DiagnoseStartup,@function + +#ifdef __riscv64 +#define LREG ld +#define SREG sd +#define REGBYTES 8 +#else +#define LREG lw +#define SREG sw +#define REGBYTES 4 +#endif + +#define TOTAL_INT_SIZE_ON_STACK (30 * REGBYTES) + +.macro push_reg + addi sp, sp, -(TOTAL_INT_SIZE_ON_STACK) + stmia {ra, t0-t2, a0-a7, t3-t6}, (sp) + addi sp, sp, -(TOTAL_INT_SIZE_ON_STACK) +.endm + +.macro pop_reg + addi sp, sp, TOTAL_INT_SIZE_ON_STACK + ldmia {ra, t0-t2, a0-a7, t3-t6}, (sp) + addi sp, sp, TOTAL_INT_SIZE_ON_STACK +.endm + +CPU_DiagnoseStartup: + push_reg + + # Function test of a0, a1 + li a0, 0xAAAAAAAA + li a1, 0xAAAAAAAA + bne a0, a1, FailReturnLabel + li a0, 0x55555555 + li a1, 0x55555555 + bne a0, a1, FailReturnLabel + + # Register a2 + li a2, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, a2, FailReturnLabel + li a2, 0x55555555 + li a0, 0x55555555 + bne a0, a2, FailReturnLabel + + # Register a3 + li a3, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, a3, FailReturnLabel + li a3, 0x55555555 + li a0, 0x55555555 + bne a0, a3, FailReturnLabel + + # Register a4 + li a4, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, a4, FailReturnLabel + li a4, 0x55555555 + li a0, 0x55555555 + bne a0, a4, FailReturnLabel + + # Register a5 + li a5, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, a5, FailReturnLabel + li a5, 0x55555555 + li a0, 0x55555555 + bne a0, a5, FailReturnLabel + + # Register a6 + li a6, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, a6, FailReturnLabel + li a6, 0x55555555 + li a0, 0x55555555 + bne a0, a6, FailReturnLabel + + # Register a7 + li a7, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, a7, FailReturnLabel + li a7, 0x55555555 + li a0, 0x55555555 + bne a0, a7, FailReturnLabel + + # Register t0 + li t0, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, t0, FailReturnLabel + li t0, 0x55555555 + li a0, 0x55555555 + bne a0, t0, FailReturnLabel + + # Register t1 + li t1, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, t1, FailReturnLabel + li t1, 0x55555555 + li a0, 0x55555555 + bne a0, t1, FailReturnLabel + + # Register t2 + li t2, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, t2, FailReturnLabel + li t2, 0x55555555 + li a0, 0x55555555 + bne a0, t2, FailReturnLabel + + # Register t3 + li t3, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, t3, FailReturnLabel + li t3, 0x55555555 + li a0, 0x55555555 + bne a0, t3, FailReturnLabel + + # Register t4 + li t4, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, t4, FailReturnLabel + li t4, 0x55555555 + li a0, 0x55555555 + bne a0, t4, FailReturnLabel + + # Register t5 + li t5, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, t5, FailReturnLabel + li t5, 0x55555555 + li a0, 0x55555555 + bne a0, t5, FailReturnLabel + + # Register t6 + li t6, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, t6, FailReturnLabel + li t6, 0x55555555 + li a0, 0x55555555 + bne a0, t6, FailReturnLabel + + # Ramp pattern verification + li a0, 0x00000000 + li a1, 0x00000001 + li a2, 0x00000002 + li a3, 0x00000003 + li a4, 0x00000004 + li a5, 0x00000005 + li a6, 0x00000006 + li a7, 0x00000007 + li t0, 0x00000008 + li t1, 0x00000009 + li t2, 0x0000000A + li t3, 0x0000000B + li t4, 0x0000000C + li t5, 0x0000000D + li t6, 0x0000000E + + xori a0, a0, 0x00000000 + bnez a0, FailReturnLabel + xori a1, a1, 0x00000001 + bnez a1, FailReturnLabel + xori a2, a2, 0x00000002 + bnez a2, FailReturnLabel + xori a3, a3, 0x00000003 + bnez a3, FailReturnLabel + xori a4, a4, 0x00000004 + bnez a4, FailReturnLabel + xori a5, a5, 0x00000005 + bnez a5, FailReturnLabel + xori a6, a6, 0x00000006 + bnez a6, FailReturnLabel + xori a7, a7, 0x00000007 + bnez a7, FailReturnLabel + xori t0, t0, 0x00000008 + bnez t0, FailReturnLabel + xori t1, t1, 0x00000009 + bnez t1, FailReturnLabel + xori t2, t2, 0x0000000A + bnez t2, FailReturnLabel + xori t3, t3, 0x0000000B + bnez t3, FailReturnLabel + xori t4, t4, 0x0000000C + bnez t4, FailReturnLabel + xori t5, t5, 0x0000000D + bnez t5, FailReturnLabel + xori t6, t6, 0x0000000E + bnez t6, FailReturnLabel + + # Process return address register (ra) + mv a1, ra # The return address must be saved + li ra, 0xAAAAAAAA + li a0, 0xAAAAAAAA + bne a0, ra, FailReturnLabel + li ra, 0x55555555 + li a0, 0x55555555 + bne a0, ra, FailReturnLabel + mv ra, a1 + + # Process thread pointer (tp) + mv a0, tp # Save process stack value. + li a1, 0xAAAAAAA8 + mv a1, tp + mv a2, tp + bne a1, a2, FailReturnLabel + li a1, 0x55555554 + mv a1, tp + mv a2, tp + bne a1, a2, FailReturnLabel + mv tp, a0 # Restore process stack value + + # Process global pointer (gp). + mv a0, gp # Save process stack value. + li a1, 0xAAAAAAA8 + mv a1, gp + mv a2, gp + bne a1, a2, FailReturnLabel + li a1, 0x55555554 + mv a1, gp + mv a2, gp + bne a1, a2, FailReturnLabel + mv gp, a0 # Restore process stack value + +SuccessReturnLabel: + pop_reg + # CPU test success + li a0, 0x0 + ret + +FailReturnLabel: + pop_reg + # CPU test fail + li a0, 0x1 + ret \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/core/src/diagnose_mcu_core.c b/src/middleware/function_safety/library/mcu/core/src/diagnose_mcu_core.c new file mode 100644 index 0000000000000000000000000000000000000000..dfa952de0903bda0046e05b385833333f934bec3 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/core/src/diagnose_mcu_core.c @@ -0,0 +1,169 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_core.c + * @author MCU Driver Team + * @brief This file contains the functions definition for core diagnose. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "diagnose_mcu_core.h" + +BASE_StatusType CPU_DiagnoseStartup(void); +BASE_StatusType CPU_DiagnoseRuntime(void); +/** + * @brief diagnose the cpu status. + * @param coreDiagnoseHandle Value of @ref CORE_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CORE_DiagnoseCpuStatus(void* coreDiagnoseHandle, DiagnoseMoment moment) +{ + CORE_DiagnoseHandle* handle = (CORE_DiagnoseHandle*)coreDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_CORE); + STATE_SetDiagnoseMoudule(&state, MODULE_CPU_REGISTER); + STATE_SetDiagnoseFeature(&state, FEATURE_SYSCTRL_CPU_STATUS); /* set diagnose subsys, module and feature to state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + if (DCL_SYSCTRL_CheckCpuStatus(SYSCTRL_LOCKUP_BIT) != 0 || + DCL_SYSCTRL_CheckCpuStatus(SYSCTRL_HARD_FAULT_BIT) != 0) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_SYSCTRL_CPU_STATUS); /* set fault type to state */ + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set success to state */ + return state; +} +/** + * @brief diagnose soft interrupt in irq handler. + * @param handle Value of @ref CORE_DiagnoseHandle. + * @retval None. + */ +static void DiagnoseSoftwareInterrupt(void* handle) +{ + FunctionSafetyState* stateHandle = (FunctionSafetyState *)handle; + stateHandle->BIT.result = RESULT_SUCCESS; /* set result success to state */ + DCL_SYSCTRL_ClearSoftInterrupt(); /* clear soft irq */ +} +/** + * @brief diagnose soft interrupt of cpu. + * @param coreDiagnoseHandle Value of @ref CORE_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CORE_DiagnoseCpuSoftwareIrq(void* coreDiagnoseHandle, DiagnoseMoment moment) +{ + CORE_DiagnoseHandle* handle = (CORE_DiagnoseHandle*)coreDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_CORE); + STATE_SetDiagnoseMoudule(&state, MODULE_CPU_SOFT_INTTERRUPT); + STATE_SetDiagnoseFeature(&state, FEATURE_SOFT_INTERRUPT); /* set diagnose subsys, module and feature to state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + IRQ_DisableN(IRQ_SOFTWARE); + IRQ_Unregister(IRQ_SOFTWARE); + IRQ_Register(IRQ_SOFTWARE, DiagnoseSoftwareInterrupt, &state); + IRQ_SetPriority(IRQ_SOFTWARE, 7); /* 7: interrupt priority */ + IRQ_EnableN(IRQ_SOFTWARE); + DCL_SYSCTRL_GenerateSoftInterrupt(); + BASE_FUNC_DELAY_US(100); /* 100: delay 100us */ + /* wait soft irq return and check */ + if (state.BIT.result != RESULT_SUCCESS) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_CPU_SOFT_INTTERRUPT); + return state; + } + IRQ_DisableN(IRQ_SOFTWARE); + IRQ_Unregister(IRQ_SOFTWARE); + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); + return state; +} +/** + * @brief diagnose general register of cpu. + * @param coreDiagnoseHandle Value of @ref CORE_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CORE_DiagnoseCpuGeneralRegister(void* coreDiagnoseHandle, DiagnoseMoment moment) +{ + CORE_DiagnoseHandle* handle = (CORE_DiagnoseHandle*)coreDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_CORE); + STATE_SetDiagnoseMoudule(&state, MODULE_CPU_REGISTER); + STATE_SetDiagnoseFeature(&state, FEATURE_REG_WRITE_READ); /* set diagnose subsys, module and feature to state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + if (moment == MOMENT_STARTUP) { + if (CPU_DiagnoseStartup() != BASE_STATUS_OK) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_REG_SAF); /* set fail result and fault type to state */ + return state; + } + } else if (moment == MOMENT_RUNTIME) { + if (CPU_DiagnoseRuntime() != BASE_STATUS_OK) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_REG_SAF); /* set fail result and fault type to state */ + return state; + } + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set success resul to state */ + return state; +} +/** + * @brief diagnose pc jump function of cpu. + * @param testValue Value of test pc fucntion. + * @retval revert value of testValue. + */ +static unsigned int DiagnosePcJump(unsigned int testValue) +{ + testValue = (~testValue); /* change pc jump address */ + return testValue; +} +/** + * @brief diagnose pc register of cpu. + * @param coreDiagnoseHandle Value of @ref CORE_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CORE_DiagnosePcRegister(void* coreDiagnoseHandle, DiagnoseMoment moment) +{ + CORE_DiagnoseHandle* handle = (CORE_DiagnoseHandle*)coreDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_CORE); + STATE_SetDiagnoseMoudule(&state, MODULE_PC_REGISTER); + STATE_SetDiagnoseFeature(&state, FEATURE_REG_PC_JUMP); /* set diagnose subsys, module and feature to state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + if (DCL_SYSCTRL_CheckCpuStatus(SYSCTRL_PC_VALID_BIT) != BASE_CFG_SET) { /* check pc state */ + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_PC_INVALID); /* set fail result and fault type to state */ + return state; + } + unsigned int testValue = 0xAAAAAAAAU; /* test pattern */ + if (~testValue != DiagnosePcJump(testValue)) { /* change pc jump address and return to origin address */ + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_PC_JUMP); /* set fail result and fault type to state */ + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); + return state; +} \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/core/src/failsafe_mcu_core.c b/src/middleware/function_safety/library/mcu/core/src/failsafe_mcu_core.c new file mode 100644 index 0000000000000000000000000000000000000000..6bcad48fad3b45e28a36cf23a80c6fb266cd57f3 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/core/src/failsafe_mcu_core.c @@ -0,0 +1,86 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_core.c + * @author MCU Driver Team + * @brief This file contains the functions definition for core failsafe. + */ +#include "diagnose_mcu_core.h" +#include "failsafe_mcu_core.h" +/** + * @brief default failsafe measure of core. + * @param coreHandle Value of @ref CORE_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CORE_DefaultFailSafe(void* coreHandle, DiagnoseMoment moment) +{ + CORE_FailSafeHandle* handle = (CORE_FailSafeHandle*)coreHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + while (1) { + } + return state; +} +/** + * @brief failsafe measure of core reg saf. + * @param coreHandle Value of @ref CORE_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CORE_RegSafFailSafe(void* coreHandle, DiagnoseMoment moment) +{ + CORE_FailSafeHandle* handle = (CORE_FailSafeHandle*)coreHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure handler of core. + * @param coreHandle Value of @ref CORE_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState CORE_FailSafeHandler(void* coreHandle, DiagnoseMoment moment) +{ + CORE_FailSafeHandle* handle = (CORE_FailSafeHandle*)coreHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + switch (state.BIT.faultType) { + case FAULT_REG_SAF: + state = CORE_RegSafFailSafe(handle, moment); /* core reg saf fail safe */ + break; + case FAULT_REG_AF: + break; + case FAULT_REG_TF: + break; + case FAULT_REG_CF: + break; + case FAULT_PC_JUMP: + break; + case FAULT_PC_INVALID: + break; + default: + state = CORE_DefaultFailSafe(handle, moment); /* core default fail safe */ + break; + } + return state; +} \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/core/src/faultpredict_mcu_core.c b/src/middleware/function_safety/library/mcu/core/src/faultpredict_mcu_core.c new file mode 100644 index 0000000000000000000000000000000000000000..cd252e4c60c7e316807a3bcfe3c872eaf6882ff2 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/core/src/faultpredict_mcu_core.c @@ -0,0 +1,23 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_core.c + * @author MCU Driver Team + * @brief This file contains the functions definition for core faultpredict. + */ +#include "faultpredict_mcu_ana.h" + diff --git a/src/middleware/function_safety/library/mcu/digtal_io/inc/diagnose_mcu_dio.h b/src/middleware/function_safety/library/mcu/digtal_io/inc/diagnose_mcu_dio.h new file mode 100644 index 0000000000000000000000000000000000000000..d8c676e687b0b036e6825b1c4381e032eabc0e0b --- /dev/null +++ b/src/middleware/function_safety/library/mcu/digtal_io/inc/diagnose_mcu_dio.h @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_dio.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for dio diagnose. + */ + +#ifndef DIAGNOSE_MCU_DIO_H +#define DIAGNOSE_MCU_DIO_H + +#include "function_safety_common.h" +#ifdef GPIO0 +#include "gpio.h" +#endif +#define MODULE_GPIO 0x01 + +#define FEATURE_GPIO_BASIC 0x01 +#define FEATURE_GPIO_INTERRUPT 0x02 + +#define FAULT_GPIO_DIR_INPUT 0x01 +#define FAULT_GPIO_DIR_OUTPUT 0x02 +#define FAULT_GPIO_LEVEL_HIGH 0x03 +#define FAULT_GPIO_LEVEL_LOW 0x04 +#define FAULT_GPIO_INT_RISE_NACK 0x05 +#define FAULT_GPIO_INT_FALL_NACK 0x06 +#define FAULT_GPIO_INT_LOW_LEVEL_NACK 0x07 +#define FAULT_GPIO_INT_HIGH_LEVEL_NACK 0x08 +#define FAULT_GPIO_INT_BOTH_NACK 0x09 +#define FAULT_GPIO_INT_PINS_UNMATCH 0x0A + +typedef struct { +#ifdef GPIO0 + GPIO_Handle* gpioHandleRef; + GPIO_Handle* gpioHandleTarget; +#endif + bool irqFlag; +} DIO_DiagnoseHandle; + +#ifdef GPIO0 +FunctionSafetyState DIO_DiagnoseGpioDirectionAndLevel(void* dioDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState DIO_DiagnoseGpioInterrupt(void* dioDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState DIO_GpioIrqCheckCallback(void* dioDiagnoseHandle, DiagnoseMoment moment); +#endif + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/digtal_io/inc/failsafe_mcu_dio.h b/src/middleware/function_safety/library/mcu/digtal_io/inc/failsafe_mcu_dio.h new file mode 100644 index 0000000000000000000000000000000000000000..deb2f5e96b46387bd851fddb830a07b481ba9185 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/digtal_io/inc/failsafe_mcu_dio.h @@ -0,0 +1,37 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_dio.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for dio failsafe. + */ + +#ifndef FAILSAFE_MCU_DIO_H +#define FAILSAFE_MCU_DIO_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} DIO_FailSafeHandle; + +FunctionSafetyState DIO_FailSafeHandler(void* dioFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState DIO_InterruptFailSafe(void* dioFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState DIO_DirectionLevelFailSafe(void* dioFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState DIO_DefaultFailSafe(void* dioFailSafeHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/digtal_io/inc/faultpredict_mcu_dio.h b/src/middleware/function_safety/library/mcu/digtal_io/inc/faultpredict_mcu_dio.h new file mode 100644 index 0000000000000000000000000000000000000000..cac625c90b89f358c9f316f68ce669c8e2cfdf2b --- /dev/null +++ b/src/middleware/function_safety/library/mcu/digtal_io/inc/faultpredict_mcu_dio.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_dio.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for dio faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_DIO_H +#define FAULTPREDICT_MCU_DIO_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} DIO_FaultPredictHandle; + +FunctionSafetyState DIO_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/digtal_io/src/diagnose_mcu_dio.c b/src/middleware/function_safety/library/mcu/digtal_io/src/diagnose_mcu_dio.c new file mode 100644 index 0000000000000000000000000000000000000000..d8c6a76e0fc4b8f0e75f82f8706f0094e8756d98 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/digtal_io/src/diagnose_mcu_dio.c @@ -0,0 +1,183 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_dio.c + * @author MCU Driver Team + * @brief This file contains the functions definition for dio diagnose. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "diagnose_mcu_dio.h" + +#define GPIO_LEVEL_HOLD_TIME_US 20 + +#ifdef GPIO0 +/** + * @brief diagnose gpio's direction and level. + * @param dioDiagnoseHandle Value of @ref DIO_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState DIO_DiagnoseGpioDirectionAndLevel(void* dioDiagnoseHandle, DiagnoseMoment moment) +{ + DIO_DiagnoseHandle* handle = (DIO_DiagnoseHandle*)dioDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_DIGTAL_IO); + STATE_SetDiagnoseMoudule(&state, MODULE_GPIO); + STATE_SetDiagnoseFeature(&state, FEATURE_GPIO_BASIC); /* set diagnose subsys, module and feature to state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->gpioHandleRef != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->gpioHandleTarget != NULL, &state); + HAL_GPIO_SetDirection(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_OUTPUT_MODE); + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_HIGH_LEVEL); + HAL_GPIO_SetDirection(handle->gpioHandleTarget, handle->gpioHandleTarget->pins, GPIO_INPUT_MODE); + BASE_FUNC_DELAY_US(10); /* 10: delay time 10us */ + unsigned int pinsValue = HAL_GPIO_GetAllValue(handle->gpioHandleTarget); + if (pinsValue != handle->gpioHandleRef->pins) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_GPIO_DIR_INPUT); /* set fail result and fault type to state */ + return state; + } + HAL_GPIO_SetDirection(handle->gpioHandleTarget, handle->gpioHandleTarget->pins, GPIO_OUTPUT_MODE); + HAL_GPIO_SetValue(handle->gpioHandleTarget, handle->gpioHandleTarget->pins, GPIO_HIGH_LEVEL); + HAL_GPIO_SetDirection(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_INPUT_MODE); + BASE_FUNC_DELAY_US(10); /* 10: delay time 10us */ + pinsValue = HAL_GPIO_GetAllValue(handle->gpioHandleRef); + if (pinsValue != handle->gpioHandleTarget->pins) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_GPIO_DIR_OUTPUT); /* set fail result and fault type to state */ + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +/** + * @brief check gpio's interrupt source. + * @param dioDiagnoseHandle Value of @ref DIO_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState DIO_GpioIrqCheckCallback(void* dioDiagnoseHandle, DiagnoseMoment moment) +{ + DIO_DiagnoseHandle* handle = (DIO_DiagnoseHandle*)dioDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check */ + handle->irqFlag = true; + /* Queries the masked GPIO interrupt status. */ + unsigned int mis = DCL_GPIO_GetMIS(handle->gpioHandleTarget->baseAddress); + if (mis != handle->gpioHandleTarget->pins) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_GPIO_INT_PINS_UNMATCH); /* set fail result and fault type to state */ + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +/** + * @brief gpio's interrupt triger config. + * @param dioDiagnoseHandle Value of @ref DIO_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +static void DIO_GpioIrqTrigerConfig(DIO_DiagnoseHandle* handle, GPIO_InterruptMode mode) +{ + HAL_GPIO_SetIrqType(handle->gpioHandleTarget, handle->gpioHandleRef->pins, mode); /* set gpio interrupt type */ + if (mode == GPIO_INT_TYPE_FALL_EDGE) { /* fall edge interrupt type testcase config */ + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_HIGH_LEVEL); + BASE_FUNC_DELAY_US(GPIO_LEVEL_HOLD_TIME_US); + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_LOW_LEVEL); + } else if (mode == GPIO_INT_TYPE_RISE_EDGE) { /* rise edge interrupt type testcase config */ + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_LOW_LEVEL); + BASE_FUNC_DELAY_US(GPIO_LEVEL_HOLD_TIME_US); + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_HIGH_LEVEL); + } else if (mode == GPIO_INT_TYPE_LOW_LEVEL) { /* low level interrupt type testcase config */ + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_HIGH_LEVEL); + BASE_FUNC_DELAY_US(GPIO_LEVEL_HOLD_TIME_US); + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_LOW_LEVEL); + BASE_FUNC_DELAY_US(GPIO_LEVEL_HOLD_TIME_US); + } else if (mode == GPIO_INT_TYPE_HIGH_LEVEL) { /* high level interrupt type testcase config */ + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_LOW_LEVEL); + BASE_FUNC_DELAY_US(GPIO_LEVEL_HOLD_TIME_US); + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_HIGH_LEVEL); + BASE_FUNC_DELAY_US(GPIO_LEVEL_HOLD_TIME_US); + } else if (mode == GPIO_INT_TYPE_BOTH_EDGE) { /* both edge interrupt type testcase config */ + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_LOW_LEVEL); + BASE_FUNC_DELAY_US(GPIO_LEVEL_HOLD_TIME_US); + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_HIGH_LEVEL); + BASE_FUNC_DELAY_US(GPIO_LEVEL_HOLD_TIME_US); + HAL_GPIO_SetValue(handle->gpioHandleRef, handle->gpioHandleRef->pins, GPIO_LOW_LEVEL); + BASE_FUNC_DELAY_US(GPIO_LEVEL_HOLD_TIME_US); + } + DCL_GPIO_DisableIrq(handle->gpioHandleTarget->baseAddress, handle->gpioHandleTarget->pins); /* disable gpio irq */ +} +/** + * @brief diagnose gpio's interrupt. + * @param dioDiagnoseHandle Value of @ref DIO_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState DIO_DiagnoseGpioInterrupt(void* dioDiagnoseHandle, DiagnoseMoment moment) +{ + DIO_DiagnoseHandle* handle = (DIO_DiagnoseHandle*)dioDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_DIGTAL_IO); + STATE_SetDiagnoseMoudule(&state, MODULE_GPIO); + STATE_SetDiagnoseFeature(&state, FEATURE_GPIO_INTERRUPT); /* set diagnose subsys, module and feature to state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->gpioHandleRef != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->gpioHandleTarget != NULL, &state); /* param check */ + DIO_GpioIrqTrigerConfig(handle, GPIO_INT_TYPE_FALL_EDGE); /* triggle fall edge interrupt */ + if (handle->irqFlag != true) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_GPIO_INT_FALL_NACK); + return state; + } + handle->irqFlag = false; + DIO_GpioIrqTrigerConfig(handle, GPIO_INT_TYPE_RISE_EDGE); /* triggle rise edge interrupt */ + if (handle->irqFlag != true) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_GPIO_INT_RISE_NACK); + return state; + } + handle->irqFlag = false; + DIO_GpioIrqTrigerConfig(handle, GPIO_INT_TYPE_LOW_LEVEL); /* triggle low level interrupt */ + if (handle->irqFlag != true) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_GPIO_INT_LOW_LEVEL_NACK); + return state; + } + handle->irqFlag = false; + DIO_GpioIrqTrigerConfig(handle, GPIO_INT_TYPE_HIGH_LEVEL); /* triggle high level interrupt */ + if (handle->irqFlag != true) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_GPIO_INT_HIGH_LEVEL_NACK); + return state; + } + handle->irqFlag = false; + DIO_GpioIrqTrigerConfig(handle, GPIO_INT_TYPE_BOTH_EDGE); /* triggle both edge interrupt */ + if (handle->irqFlag != true) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_GPIO_INT_BOTH_NACK); + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/nos_amp_task.c b/src/middleware/function_safety/library/mcu/digtal_io/src/failsafe_mcu_dio.c similarity index 31% rename from src/middleware/hisilicon/nostask/kernel/nos_amp_task.c rename to src/middleware/function_safety/library/mcu/digtal_io/src/failsafe_mcu_dio.c index bd91f5d52aad1be25145fe808058a5fa644f0e93..a3bb88107bf3a4a433461ec3f66f1f094decba0f 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_amp_task.c +++ b/src/middleware/function_safety/library/mcu/digtal_io/src/failsafe_mcu_dio.c @@ -15,107 +15,89 @@ * 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. - * @file nos_amp_task.c + * @file failsafe_mcu_dio.c + * @author MCU Driver Team + * @brief This file contains the functions definition for dio failsafe. */ -#include "nos_task_external.h" +#include "diagnose_mcu_dio.h" +#include "failsafe_mcu_dio.h" -struct TagOsTskSortedDelayList g_tskSortedDelay; -struct TagOsRunQue g_runQueue; // 核的局部运行队列 - -/* - * 描述: Task schedule, switch to the highest task. - */ -void OsTskSchedule(void) +/** + * @brief default failsafe measure of gpio. + * @param dioFailSafeHandle Value of @ref DIO_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +__weak FunctionSafetyState DIO_DefaultFailSafe(void* dioFailSafeHandle, DiagnoseMoment moment) { - /* HIDSP平台为关中断下调度,外层已经关中断 */ - /* Find the highest task */ - OsTskHighestSet(); - - /* In case that running is not highest then reschedule */ - if ((g_highestTask != RUNNING_TASK) && (g_uniTaskLock == 0)) { - UNI_FLAG |= OS_FLG_TSK_REQ; - - /* only if there is not HWI or SWI or TICK the trap */ - if (OS_INT_INACTIVE) { - OsTaskTrap(); - return; - } + DIO_FailSafeHandle* handle = (DIO_FailSafeHandle*)dioFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + while (1) { } - - return; + return state; } - -static void OsReAddToTimerList(struct TagListObject *taskList, struct TagTskCB *taskCB) +/** + * @brief failsafe measure of gpio direction and level. + * @param dioFailSafeHandle Value of @ref DIO_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState DIO_DirectionLevelFailSafe(void* dioFailSafeHandle, DiagnoseMoment moment) { - struct TagTskCB *tskDelay = NULL; - if (ListEmpty(taskList)) { - ListTailAdd(&taskCB->timerList, taskList); - } else { - /* Put the task to right location */ - LIST_FOR_EACH(tskDelay, taskList, struct TagTskCB, timerList) { - if (tskDelay->expirationTick > taskCB->expirationTick) { - break; - } - } - /* Put the task to right location */ - ListTailAdd(&taskCB->timerList, &tskDelay->timerList); - } + DIO_FailSafeHandle* handle = (DIO_FailSafeHandle*)dioFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; } - -/* 任务扫描 */ -unsigned long long NOS_GetCycle(void); -void OsTaskScan(void) +/** + * @brief failsafe measure of gpio interrupt. + * @param dioFailSafeHandle Value of @ref DIO_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState DIO_InterruptFailSafe(void* dioFailSafeHandle, DiagnoseMoment moment) { - struct TagTskCB *taskCB = NULL; - bool needSchedule = FALSE; - /* 获取延时链表 */ - struct TagListObject *tskSortedDelayList = &g_tskSortedDelay.tskList; - unsigned long long curTick = (unsigned long long)(NOS_GetCycle()); - - LIST_FOR_EACH(taskCB, tskSortedDelayList, struct TagTskCB, timerList) { - if ((unsigned long long)taskCB->expirationTick > curTick) { + DIO_FailSafeHandle* handle = (DIO_FailSafeHandle*)dioFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure handler of gpio. + * @param dioFailSafeHandle Value of @ref DIO_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState DIO_FailSafeHandler(void* dioFailSafeHandle, DiagnoseMoment moment) +{ + DIO_FailSafeHandle* handle = (DIO_FailSafeHandle*)dioFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + switch (state.BIT.faultType) { + case FAULT_GPIO_DIR_INPUT: + case FAULT_GPIO_DIR_OUTPUT: + case FAULT_GPIO_LEVEL_HIGH: + case FAULT_GPIO_LEVEL_LOW: + state = DIO_DirectionLevelFailSafe(handle, moment); /* gpio direction and level fail safe */ + break; + case FAULT_GPIO_INT_RISE_NACK: + case FAULT_GPIO_INT_FALL_NACK: + case FAULT_GPIO_INT_LOW_LEVEL_NACK: + case FAULT_GPIO_INT_HIGH_LEVEL_NACK: + case FAULT_GPIO_INT_BOTH_NACK: + case FAULT_GPIO_INT_PINS_UNMATCH: + state = DIO_InterruptFailSafe(handle, moment); /* gpio interrupt fail safe */ + break; + default: + state = DIO_DefaultFailSafe(handle, moment); /* gpio default fail safe */ break; - } - /* 从链表中删除 */ - ListDelete(&taskCB->timerList); -#if defined(OS_OPTION_306X) - /* 任务是否被延时 */ - if ((OS_TSK_PERIOD & taskCB->taskStatus) != 0) { - taskCB->expirationTick = (unsigned long long)taskCB->expirationTick + - (unsigned long long)(taskCB->privateData); - TSK_StatusClear(taskCB, OS_TSK_SUSPEND); - OsReAddToTimerList(tskSortedDelayList, taskCB); - } -#endif - /* 任务是否被阻塞 */ - if ((OS_TSK_PEND & taskCB->taskStatus) != 0) { - TSK_StatusClear(taskCB, OS_TSK_PEND); - ListDelete(&taskCB->pendList); - } else if (((OS_TSK_MSG_PEND | OS_TSK_VOS_PEND) & taskCB->taskStatus) != 0) { - TSK_StatusClear(taskCB, (OS_TSK_MSG_PEND | OS_TSK_VOS_PEND)); - } else if (((OS_TSK_EVENT_PEND | OS_TSK_VOS_PEND) & taskCB->taskStatus) != 0) { - TSK_StatusClear(taskCB, (OS_TSK_EVENT_PEND | OS_TSK_VOS_PEND)); - } else if ((OS_TSK_QUEUE_PEND & taskCB->taskStatus) != 0) { - ListDelete(&taskCB->pendList); - TSK_StatusClear(taskCB, OS_TSK_QUEUE_PEND); - } else { - /* 清除任务状态 */ - TSK_StatusClear(taskCB, OS_TSK_DELAY); - } - - /* timer锁只要锁到链表删除位置,下面的ready添加为tcb与rq的操作,锁rq */ - if ((OS_TSK_SUSPEND_READY_BLOCK & taskCB->taskStatus) == 0) { - OsTskReadyAddBGD(taskCB); - needSchedule = TRUE; - } else { - taskCB->expirationCnt++; - } - - taskCB = LIST_COMPONENT(tskSortedDelayList, struct TagTskCB, timerList); - } - - if (needSchedule) { - /* 发生调度 */ - OsTskScheduleFast(); } -} + return state; +} \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/digtal_io/src/faultpredict_mcu_dio.c b/src/middleware/function_safety/library/mcu/digtal_io/src/faultpredict_mcu_dio.c new file mode 100644 index 0000000000000000000000000000000000000000..bef034da400c5e114d28e1275d75ccdb278f151a --- /dev/null +++ b/src/middleware/function_safety/library/mcu/digtal_io/src/faultpredict_mcu_dio.c @@ -0,0 +1,23 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_dio.c + * @author MCU Driver Team + * @brief This file contains the functions definition for dio faultpredict. + */ +#include "faultpredict_mcu_ana.h" + diff --git a/src/middleware/hisilicon/nostask/arch/nos_port.c b/src/middleware/function_safety/library/mcu/monitor/inc/diagnose_mcu_monitor.h similarity index 42% rename from src/middleware/hisilicon/nostask/arch/nos_port.c rename to src/middleware/function_safety/library/mcu/monitor/inc/diagnose_mcu_monitor.h index cf617c67956dacef248083025bebbc1e3cef91a8..5b58dbe282778eaf7a9dfb6201c8b0fa9c7e2eac 100644 --- a/src/middleware/hisilicon/nostask/arch/nos_port.c +++ b/src/middleware/function_safety/library/mcu/monitor/inc/diagnose_mcu_monitor.h @@ -15,72 +15,85 @@ * 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. - * @file nos_port.c + * @file diagnose_mcu_monitor.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for monitor diagnose. */ -#include "nos_sys_external.h" -#define INDEX_STEP 8 -#define HIGH_8BIT_U32_OFFSET 24 -#define HIGH_4BIT_U32_OFFSET 28 -#define LEADING_ZERO_NUM_OF_ZERO 32 -#define OS_MAX_U8 0xFFU -#define OS_GET_8BIT_HIGH_4BIT(num) ((num) >> 4) -#define OS_GET_8BIT_LOW_4BIT(num) ((num) & 0xFU) +#ifndef DIAGNOSE_MCU_MONITOR_H +#define DIAGNOSE_MCU_MONITOR_H -void OsTskContextGet(uintptr_t saveAddr, struct TskContext *context) -{ - if (OS_INT_ACTIVE) { - /* 中断上下文中,callee-save寄存器是未压栈且不准确的 */ - *context = *(struct TskContext *)(saveAddr - CALLER_REG_SIZE); - } else { - *context = *(struct TskContext *)saveAddr; - } -} -#ifdef OS_OPTION_306X -#include "nos_306x_adapter.h" +#include "function_safety_common.h" +#ifdef CRG +#include "crg.h" #endif -/* 任务上下文初始化 */ -void *OsTskContextInit(unsigned int taskId, unsigned int stackSize, uintptr_t *topStack, uintptr_t funcTskEntry) -{ - struct TskContext *context = (struct TskContext *)((uintptr_t)topStack + stackSize - sizeof(struct TskContext)); - - /* 传参 */ - context->ra = 0; - context->a0 = taskId; - context->mepc = funcTskEntry; - context->mstatus = MSTATUS_DEF_RESTORE; - context->prithd = 0; - context->fcsr = 0; -#ifdef OS_OPTION_306X - context->tickIntNum = TICK_IRQ_EN_NUM; +#ifdef WDG +#include "wdg.h" +#endif +#ifdef WWDG +#include "wwdg.h" +#endif +#ifdef IWDG +#include "iwdg.h" +#endif +#ifdef PMC +#include "pmc.h" +#endif +#ifdef TSENSOR +#include "tsensor.h" +#endif +#ifdef SYSCTRL0 +#include "sysctrl.h" #endif - return (void *)context; -} -/* 32表示无效,3、2、1、0表示在4bit位中前导零的个数 */ -unsigned short g_lmb1Idx[16] = { 32, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; +#define MODULE_WDG 0x01 +#define MODULE_IWDG 0x02 +#define MODULE_WWDG 0x03 +#define MODULE_PMC 0x04 +#define MODULE_TSENSOR 0x05 -/* getLMB1 */ -unsigned int OsGetLMB1(unsigned int value) -{ - signed int idx; - unsigned int check1; - unsigned int check2; +#define FEATURE_MONITOR_PROGRAM_STUCK 0x01 +#define FEATURE_MONITOR_WDG_RESET 0x02 +#define FEATURE_MONITOR_POWER_LOW_LEVEL 0x03 +#define FEATURE_MONITOR_CHIP_OVER_TEMPERATUR 0x04 - for (idx = HIGH_8BIT_U32_OFFSET; idx >= 0; idx -= INDEX_STEP) { - check1 = (value >> (unsigned int)idx) & OS_MAX_U8; +#define FAULT_WDG_PROGRAM_STUCK_RESET 0x01 +#define FAULT_WDG_UNRESET 0x02 +#define FAULT_PMC_POWER_LOW_LEVEL 0x03 +#define FAULT_TSENSOR_CHIP_OVER_TEMPERATUR 0x04 - if (check1 != 0) { - /* get high bit */ - check2 = OS_GET_8BIT_HIGH_4BIT(check1); - if (check2 != 0) { - return ((unsigned int)g_lmb1Idx[check2] + (unsigned int)(HIGH_8BIT_U32_OFFSET - idx)); - } +typedef struct { +#ifdef WDG + WDG_Handle* wdgHandle; +#endif +#ifdef WWDG + WWDG_Handle* wwdgHandle; +#endif +#ifdef IWDG + IWDG_Handle* iwdgHandle; +#endif +#ifdef PMC + PMC_Handle* pmcHandle; +#endif + unsigned int startupResetTimeUs; + unsigned int runTimeResetTimeUs; + unsigned int overTemperatureValue; + bool pmcIrqFlag; +} MONITOR_DiagnoseHandle; - /* get low bit */ - return ((unsigned int)g_lmb1Idx[OS_GET_8BIT_LOW_4BIT(check1)] + (unsigned int)(HIGH_4BIT_U32_OFFSET - idx)); - } - } +#if defined(WDG) || defined(WWDG) +FunctionSafetyState MONITOR_DiagnoseProgramStuckByWdg(void* monitorDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_DiagnoseWdgResetFunction(void* monitorDiagnoseHandle, DiagnoseMoment moment); +#endif +#if defined(IWDG) +FunctionSafetyState MONITOR_DiagnoseProgramStuckByIwdg(void* monitorDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_DiagnoseIwdgResetFunction(void* monitorDiagnoseHandle, DiagnoseMoment moment); +#endif +#if defined(PMC) +FunctionSafetyState MONITOR_DiagnosePowerLowLevelByPmc(void* monitorDiagnoseHandle, DiagnoseMoment moment); +#endif +#if defined(TSENSOR) +FunctionSafetyState MONITOR_DiagnoseOverTemperatureByTsensor(void* monitorDiagnoseHandle, DiagnoseMoment moment); +#endif - return LEADING_ZERO_NUM_OF_ZERO; -} +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/config/nos_config.c b/src/middleware/function_safety/library/mcu/monitor/inc/failsafe_mcu_monitor.h similarity index 66% rename from src/middleware/hisilicon/nostask/config/nos_config.c rename to src/middleware/function_safety/library/mcu/monitor/inc/failsafe_mcu_monitor.h index 65d80a037988b50d7fcae537b3c1b76ab8842026..7fcb096481b255fc0f34b16143b00cf7c15e0403 100644 --- a/src/middleware/hisilicon/nostask/config/nos_config.c +++ b/src/middleware/function_safety/library/mcu/monitor/inc/failsafe_mcu_monitor.h @@ -15,45 +15,24 @@ * 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. - * @file nos_config.c + * @file failsafe_mcu_monitor.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for monitor failsafe. */ -#include "nos_config_internal.h" -#include "nos_sys_external.h" -#include "os_sys.h" -/* 任务初始化 */ -static unsigned int OsTskConfigInit(void) -{ - unsigned int ret; - ret = OsTskInit(); - return ret; -} +#ifndef FAILSAFE_MCU_MONITOR_H +#define FAILSAFE_MCU_MONITOR_H -static unsigned int OsSysConfigReg(void) -{ - /* idle注册 */ - OsIdleReg(); - UNI_FLAG = 0; +#include "function_safety_common.h" - return 0; -} +typedef struct { + void *param; +} MONITOR_FailSafeHandle; -/* OsStart阶段对相应的运行模块不进行OS_INIT_TRACE_END TRACE记录 */ -unsigned int OsStart(void) -{ - unsigned int ret; +FunctionSafetyState MONITOR_FailSafeHandler(void* monitorFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_tsensorFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_pmcFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_wdgFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_DefaultFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment); - /* 表示系统在进行启动阶段,匹配MOUDLE_ID之后,标记进入任务模块的启动 */ - ret = OsActivate(); - - return ret; -} - -int NOS_MoudleInit(void) -{ - OsSysConfigReg(); - OsTskConfigInit(); - - /* Execution should not reach this point */ - return (signed int)OS_OK; -} +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/monitor/inc/faultpredict_mcu_monitor.h b/src/middleware/function_safety/library/mcu/monitor/inc/faultpredict_mcu_monitor.h new file mode 100644 index 0000000000000000000000000000000000000000..9391ea28ce7ef5450135b1d830c5f45a1256d424 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/monitor/inc/faultpredict_mcu_monitor.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_monitor.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for monitor faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_MONITOR_H +#define FAULTPREDICT_MCU_MONITOR_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} MONITOR_FaultPredictHandle; + +FunctionSafetyState MONITOR_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/monitor/src/diagnose_mcu_monitor.c b/src/middleware/function_safety/library/mcu/monitor/src/diagnose_mcu_monitor.c new file mode 100644 index 0000000000000000000000000000000000000000..d761a4578d0044c950f7751d368b501dd1952af3 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/monitor/src/diagnose_mcu_monitor.c @@ -0,0 +1,223 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_monitor.c + * @author MCU Driver Team + * @brief This file contains the functions definition for monitor diagnose. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "diagnose_mcu_monitor.h" +/*------------------------------- WDG or WWDG monitor program stuck -----------------------------------*/ +#if defined(WDG) || defined(WWDG) +/** + * @brief diagnose program stuck by wdg. + * @param monitorDiagnoseHandle Value of @ref MONITOR_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState MONITOR_DiagnoseProgramStuckByWdg(void* monitorDiagnoseHandle, DiagnoseMoment moment) +{ + MONITOR_DiagnoseHandle* handle = (MONITOR_DiagnoseHandle*)monitorDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_MONITOR); + STATE_SetDiagnoseMoudule(&state, MODULE_WDG); /* set diagnose subsys, module and feature to state */ + STATE_SetDiagnoseFeature(&state, FEATURE_MONITOR_PROGRAM_STUCK); + if (DCL_SYSCTRL_GetWdgResetConut() > 1) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); /* set fail result and fault type to state */ + STATE_SetDiagnoseFaultType(&state, FAULT_WDG_PROGRAM_STUCK_RESET); + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +/** + * @brief diagnose wdg's reset function. + * @param monitorDiagnoseHandle Value of @ref MONITOR_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState MONITOR_DiagnoseWdgResetFunction(void* monitorDiagnoseHandle, DiagnoseMoment moment) +{ + MONITOR_DiagnoseHandle* handle = (MONITOR_DiagnoseHandle*)monitorDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); +#ifdef WDG + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->wdgHandle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->wdgHandle->baseAddress != NULL, &state); /* param check not NULL */ +#elif defined(WWDG) + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->wwdgHandle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->wwdgHandle->baseAddress != NULL, &state); /* param check not NULL */ +#endif + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_MONITOR); + STATE_SetDiagnoseMoudule(&state, MODULE_WDG); + STATE_SetDiagnoseFeature(&state, FEATURE_MONITOR_WDG_RESET); /* set diagnose subsys, module and feature to state */ + if (DCL_SYSCTRL_GetWdgResetConut() == 0) { +#ifdef WDG + DCL_WDG_EnableReset(handle->wdgHandle->baseAddress); + HAL_WDG_Start(handle->wdgHandle); +#elif defined(WWDG) + DCL_WWDG_EnableReset(handle->wwdgHandle->baseAddress); + HAL_WWDG_Start(handle->wwdgHandle); +#endif + } + unsigned int preTime = BASE_FUNC_GetTick(); + while (DCL_SYSCTRL_GetWdgResetConut() == 0) { + unsigned int currentTime = BASE_FUNC_GetTick(); + unsigned int durationTick = (currentTime > preTime) ? (currentTime - preTime) : \ + preTime + SYSTICK_MAX_VALUE -currentTime + 1; + unsigned int durationTimeUs = durationTick / HAL_CRG_GetCoreClkFreq() / CRG_FREQ_1MHz; + if (durationTimeUs > handle->startupResetTimeUs + 2000) { /* 2000: over 2000us wait for reset */ + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_WDG_UNRESET); /* set fail result and fault type to state */ + return state; + } + } +#ifdef WDG + HAL_WDG_Stop(handle->wdgHandle); +#elif defined(WWDG) + HAL_WWDG_Stop(handle->wwdgHandle); +#endif + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +#endif +/*------------------------------- IWDG monitor program stuck -----------------------------------*/ +#ifdef IWDG +/** + * @brief diagnose program stuck by iwdg. + * @param monitorDiagnoseHandle Value of @ref MONITOR_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState MONITOR_DiagnoseProgramStuckByIwdg(void* monitorDiagnoseHandle, DiagnoseMoment moment) +{ + MONITOR_DiagnoseHandle* handle = (MONITOR_DiagnoseHandle*)monitorDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_MONITOR); + STATE_SetDiagnoseMoudule(&state, MODULE_IWDG); + STATE_SetDiagnoseFeature(&state, FEATURE_MONITOR_PROGRAM_STUCK); + if (DCL_SYSCTRL_GetIWdgResetConut() > 1) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); /* set fail result and fault type to state */ + STATE_SetDiagnoseFaultType(&state, FAULT_WDG_PROGRAM_STUCK_RESET); + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} + +/** + * @brief diagnose iwdg's reset function. + * @param monitorDiagnoseHandle Value of @ref MONITOR_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState MONITOR_DiagnoseIwdgResetFunction(void* monitorDiagnoseHandle, DiagnoseMoment moment) +{ + MONITOR_DiagnoseHandle* handle = (MONITOR_DiagnoseHandle*)monitorDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->iwdgHandle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->iwdgHandle->baseAddress != NULL, &state); /* param check not NULL */ + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_MONITOR); + STATE_SetDiagnoseMoudule(&state, MODULE_IWDG); + STATE_SetDiagnoseFeature(&state, FEATURE_MONITOR_WDG_RESET); /* set diagnose subsys, module and feature to state */ + if (DCL_SYSCTRL_GetIWdgResetConut() == 0) { + DCL_IWDG_EnableReset(handle->iwdgHandle->baseAddress); + HAL_IWDG_Start(handle->iwdgHandle); + } + unsigned int preTime = BASE_FUNC_GetTick(); + while (DCL_SYSCTRL_GetIWdgResetConut() == 0) { + unsigned int currentTime = BASE_FUNC_GetTick(); + unsigned int durationTick = (currentTime > preTime) ? (currentTime - preTime) : \ + preTime + SYSTICK_MAX_VALUE -currentTime + 1; + unsigned int durationTimeUs = durationTick / HAL_CRG_GetCoreClkFreq() / CRG_FREQ_1MHz; + if (durationTimeUs > handle->startupResetTimeUs + 2000) { /* 2000: over 2000us wait for reset */ + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_WDG_UNRESET); /* set fail result and fault type to state */ + return state; + } + } + HAL_IWDG_Stop(handle->iwdgHandle); + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +#endif +/*------------------------------- PMC monitor low voltage UVP -----------------------------------*/ +#ifdef PMC +/** + * @brief diagnose power low level by pmc. + * @param monitorDiagnoseHandle Value of @ref MONITOR_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState MONITOR_DiagnosePowerLowLevelByPmc(void* monitorDiagnoseHandle, DiagnoseMoment moment) +{ + MONITOR_DiagnoseHandle* handle = (MONITOR_DiagnoseHandle*)monitorDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->pmcHandle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->pmcHandle->baseAddress != NULL, &state); /* param check not NULL */ + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_MONITOR); + STATE_SetDiagnoseMoudule(&state, MODULE_PMC); /* set diagnose subsys, module and feature to state */ + STATE_SetDiagnoseFeature(&state, FEATURE_MONITOR_POWER_LOW_LEVEL); + if (handle->pmcIrqFlag == BASE_CFG_SET) { + handle->pmcIrqFlag = BASE_CFG_UNSET; + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_PMC_POWER_LOW_LEVEL); /* set fail result and fault type to state */ + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +#endif +/*------------------------------- TSENSOR monitor over heat -----------------------------------*/ +#ifdef TSENSOR +/** + * @brief diagnose temperature over heat by tsensor. + * @param monitorDiagnoseHandle Value of @ref MONITOR_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState MONITOR_DiagnoseOverTemperatureByTsensor(void* monitorDiagnoseHandle, DiagnoseMoment moment) +{ + MONITOR_DiagnoseHandle* handle = (MONITOR_DiagnoseHandle*)monitorDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_MONITOR); + STATE_SetDiagnoseMoudule(&state, MODULE_TSENSOR); /* set diagnose subsys, module and feature to state */ + STATE_SetDiagnoseFeature(&state, FEATURE_MONITOR_CHIP_OVER_TEMPERATUR); + unsigned int temperature = (unsigned int)HAL_TSENSOR_GetTemperature(); + if (temperature >= handle->overTemperatureValue) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); /* set fail result and fault type to state */ + STATE_SetDiagnoseFaultType(&state, FAULT_TSENSOR_CHIP_OVER_TEMPERATUR); + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/monitor/src/failsafe_mcu_monitor.c b/src/middleware/function_safety/library/mcu/monitor/src/failsafe_mcu_monitor.c new file mode 100644 index 0000000000000000000000000000000000000000..682044c132f7eb62770d46a1682fe1e2d19297e1 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/monitor/src/failsafe_mcu_monitor.c @@ -0,0 +1,114 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_monitor.c + * @author MCU Driver Team + * @brief This file contains the functions definition for monitor failsafe. + */ +#include "diagnose_mcu_monitor.h" +#include "failsafe_mcu_monitor.h" + +/** + * @brief default failsafe measure of monitor. + * @param monitorFailSafeHandle Value of @ref MONITOR_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +__weak FunctionSafetyState MONITOR_DefaultFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment) +{ + MONITOR_FailSafeHandle* handle = (MONITOR_FailSafeHandle*)monitorFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + while (1) { + } + return state; +} +/** + * @brief failsafe measure of program stuck. + * @param monitorFailSafeHandle Value of @ref MONITOR_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState MONITOR_wdgFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment) +{ + MONITOR_FailSafeHandle* handle = (MONITOR_FailSafeHandle*)monitorFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure of power low level. + * @param monitorFailSafeHandle Value of @ref MONITOR_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState MONITOR_pmcFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment) +{ + MONITOR_FailSafeHandle* handle = (MONITOR_FailSafeHandle*)monitorFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure of temperature over heat. + * @param monitorFailSafeHandle Value of @ref MONITOR_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState MONITOR_tsensorFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment) +{ + MONITOR_FailSafeHandle* handle = (MONITOR_FailSafeHandle*)monitorFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure handler of monitor. + * @param monitorFailSafeHandle Value of @ref MONITOR_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState MONITOR_FailSafeHandler(void* monitorFailSafeHandle, DiagnoseMoment moment) +{ + MONITOR_FailSafeHandle* handle = (MONITOR_FailSafeHandle*)monitorFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + switch (state.BIT.faultType) { + case FAULT_WDG_PROGRAM_STUCK_RESET: + case FAULT_WDG_UNRESET: + state = MONITOR_wdgFailSafe(handle, moment); /* monitor's wdg fail safe */ + break; + case FAULT_PMC_POWER_LOW_LEVEL: + state = MONITOR_pmcFailSafe(handle, moment); /* monitor's pmc fail safe */ + break; + case FAULT_TSENSOR_CHIP_OVER_TEMPERATUR: + state = MONITOR_tsensorFailSafe(handle, moment); /* monitor's tsensor fail safe */ + break; + default: + state = MONITOR_DefaultFailSafe(handle, moment); /* monitor's default fail safe */ + break; + } + return state; +} \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/monitor/src/faultpredict_mcu_monitor.c b/src/middleware/function_safety/library/mcu/monitor/src/faultpredict_mcu_monitor.c new file mode 100644 index 0000000000000000000000000000000000000000..712235f5d247c01ccb96188e9a0b23dbdd36e84a --- /dev/null +++ b/src/middleware/function_safety/library/mcu/monitor/src/faultpredict_mcu_monitor.c @@ -0,0 +1,23 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_monitor.c + * @author MCU Driver Team + * @brief This file contains the functions definition for monitor faultpredict. + */ +#include "faultpredict_mcu_monitor.h" + diff --git a/src/middleware/function_safety/library/mcu/ram/inc/diagnose_mcu_ram.h b/src/middleware/function_safety/library/mcu/ram/inc/diagnose_mcu_ram.h new file mode 100644 index 0000000000000000000000000000000000000000..a227f5c50903b217286a9d888f420d802c20dc7b --- /dev/null +++ b/src/middleware/function_safety/library/mcu/ram/inc/diagnose_mcu_ram.h @@ -0,0 +1,53 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_ram.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ram diagnose. + */ + +#ifndef DIAGNOSE_MCU_RAM_H +#define DIAGNOSE_MCU_RAM_H + +#include "function_safety_common.h" + +#define MODULE_RAM_SRAM 0x01 +#define MODULE_RAM_STACK 0x02 + +#define FEATURE_SRAM_MARCH 0x01 +#define FEATURE_SRAM_PARITY 0x02 +#define FEATURE_STACK_OVERFLOW_CHECK 0x03 + +#define FAULT_DATA_NOT_INTEGRITY 0x01 +#define FAULT_SRAM_STEP_RANGE 0x02 +#define FAULT_SRAM_FULL_RANGE 0x03 +#define FAULT_SRAM_PARITY_ERROR 0x04 +#define FAULT_STACK_OVERFLOW 0x05 + +typedef struct { + unsigned int* sramStartAddr; + unsigned int* sramCurrentAddr; + unsigned int* sramCurrentAddrInv; + unsigned int* sramEndAddr; + unsigned int sramPattern; +} RAM_DiagnoseHandle; + +FunctionSafetyState RAM_DiagnoseSramByMarchAlgorithm(void* ramDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_DiagnoseSramByParityCheck(void* ramDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_DiagnoseStackOverflow(void* ramDiagnoseHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/ram/inc/failsafe_mcu_ram.h b/src/middleware/function_safety/library/mcu/ram/inc/failsafe_mcu_ram.h new file mode 100644 index 0000000000000000000000000000000000000000..a3cfc0456a230fa0c500b5759bc85c3e8eeb7e4f --- /dev/null +++ b/src/middleware/function_safety/library/mcu/ram/inc/failsafe_mcu_ram.h @@ -0,0 +1,39 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_ram.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ram failsafe. + */ + +#ifndef FAILSAFE_MCU_RAM_H +#define FAILSAFE_MCU_RAM_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} RAM_FailSafeHandle; + +FunctionSafetyState RAM_FailSafeHandler(void* ramFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_OverflowFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_ParityFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_FullRangeFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_StepRangeFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_DefaultFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/ram/inc/faultpredict_mcu_ram.h b/src/middleware/function_safety/library/mcu/ram/inc/faultpredict_mcu_ram.h new file mode 100644 index 0000000000000000000000000000000000000000..fa52a8a0ca58a6c460b76cd16609e05043fc7b94 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/ram/inc/faultpredict_mcu_ram.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_ram.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ram faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_RAM_H +#define FAULTPREDICT_MCU_RAM_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} RAM_FaultPredictHandle; + +FunctionSafetyState RAM_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/ram/src/diagnose_mcu_ram.c b/src/middleware/function_safety/library/mcu/ram/src/diagnose_mcu_ram.c new file mode 100644 index 0000000000000000000000000000000000000000..3a2b384e4cbbeabd49ea4f4fb38196ae42ce5c2a --- /dev/null +++ b/src/middleware/function_safety/library/mcu/ram/src/diagnose_mcu_ram.c @@ -0,0 +1,175 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_ram.c + * @author MCU Driver Team + * @brief This file contains the functions definition for ram diagnose. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "diagnose_mcu_ram.h" + +/* Reserved area for RAM buffer, include overlap for test purposes */ +/* Don't change this parameter as it is related to physical technology used! */ +#define RT_RAM_BLOCKSIZE 0x00000006U +/* Min overlap to cover coupling fault from one tested row to the other */ +#define RT_RAM_BLOCK_OVERLAP 0x00000001U + +BASE_StatusType RAM_DiagnoseStepRange(unsigned int *start, unsigned int *buffer, unsigned int pattern); +BASE_StatusType RAM_DiagnoseFullRange(unsigned int *start, unsigned int *end, unsigned int pattern); + +#ifdef DIAGNOSE_RAM_SCRAMBLER +const unsigned int g_scrambleRamOrder[9] = {-8, 0, 4, 12, 8, 16, 20, 28, 24}; /* use in match c test */ +#else +const unsigned int g_standRamOrder[9] = {-4, 0, 4, 8, 12, 16, 20, 24, 28}; /* use in match c test */ +#endif +/* Pattern for stack overflow test in this array */ +unsigned int g_ramStepCheckBufferAddr[RT_RAM_BLOCKSIZE + 2U] __attribute__((section("RAM_DIAGNOSE_BUF"))); +unsigned int g_stackChkPattern[4] __attribute__((section("STACK_SRAM_BOUND"))) \ + = {0xEEEEEEEE, 0xCCCCCCCCU, 0xBBBBBBBBU, 0xDDDDDDDDU}; + +/** + * @brief diagnose slice sram by march algorithm. + * @param ramDiagnoseHandle Value of @ref RAM_DiagnoseHandle. + * @param state Value of @ref FunctionSafetyState. + * @retval None. + */ +static void RAM_DiagnoseSliceSramAndRecovery(RAM_DiagnoseHandle* handle, FunctionSafetyState* state) +{ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, state); /* param check not NULL */ + bool status = BASE_STATUS_OK; + if ((((unsigned int)(uintptr_t)(void *)handle->sramCurrentAddr) ^ \ + ((unsigned int)(uintptr_t)(void *)handle->sramCurrentAddrInv)) != 0xFFFFFFFFU) { + STATE_SetDiagnoseResult(state, RESULT_FAIL); /* set fail result and fault type to state */ + STATE_SetDiagnoseFaultType(state, FAULT_DATA_NOT_INTEGRITY); + return; + } + if (handle->sramCurrentAddr > handle->sramEndAddr) { + status = RAM_DiagnoseStepRange(g_ramStepCheckBufferAddr, g_ramStepCheckBufferAddr, handle->sramPattern); + if (status != BASE_STATUS_OK) { + STATE_SetDiagnoseResult(state, RESULT_FAIL); /* set fail result and fault type to state */ + STATE_SetDiagnoseFaultType(state, FAULT_SRAM_STEP_RANGE); + return; + } + STATE_SetDiagnoseResult(state, RESULT_SUCCESS); /* set result success to state */ + handle->sramCurrentAddr = handle->sramStartAddr; + handle->sramCurrentAddrInv = (unsigned int*)(void*)(~(unsigned int)(uintptr_t)(void*)handle->sramCurrentAddr); + } else { + status = RAM_DiagnoseStepRange(handle->sramCurrentAddr, g_ramStepCheckBufferAddr, handle->sramPattern); + if (status != BASE_STATUS_OK) { + STATE_SetDiagnoseResult(state, RESULT_FAIL); /* set fail result and fault type to state */ + STATE_SetDiagnoseFaultType(state, FAULT_SRAM_STEP_RANGE); + return; + } + if (handle->sramCurrentAddr == handle->sramStartAddr) { + handle->sramCurrentAddr += 2 * (RT_RAM_BLOCKSIZE - (2 * RT_RAM_BLOCK_OVERLAP)); /* 2:skip bufferSize 0x20 */ + } else { + handle->sramCurrentAddr += RT_RAM_BLOCKSIZE - (2 * RT_RAM_BLOCK_OVERLAP); /* 2: front and tail */ + } + handle->sramCurrentAddrInv = (unsigned int*)(void*)(~(unsigned int)(uintptr_t)(void*)handle->sramCurrentAddr); + } + STATE_SetDiagnoseResult(state, RESULT_SUCCESS); /* set result success to state */ + return; +} + +/** + * @brief diagnose sram by march algorithm. + * @param ramDiagnoseHandle Value of @ref RAM_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState RAM_DiagnoseSramByMarchAlgorithm(void* ramDiagnoseHandle, DiagnoseMoment moment) +{ + RAM_DiagnoseHandle* handle = (RAM_DiagnoseHandle*)ramDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_RAM); + STATE_SetDiagnoseMoudule(&state, MODULE_RAM_SRAM); + STATE_SetDiagnoseFeature(&state, FEATURE_SRAM_MARCH); /* set diagnose subsys, module and feature to state */ + if (moment == MOMENT_STARTUP) { /* startup diagnose */ + while (handle->sramCurrentAddr <= handle->sramEndAddr - 16) { /* 16 : once diagnose lenth */ + IRQ_Disable(); + RAM_DiagnoseSliceSramAndRecovery(handle, &state); + IRQ_Enable(); + if (state.BIT.result == RESULT_FAIL) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); /* set fail result and fault type to state */ + STATE_SetDiagnoseFaultType(&state, FAULT_SRAM_FULL_RANGE); + return state; + } + } + handle->sramCurrentAddr = handle->sramStartAddr; + handle->sramCurrentAddrInv = (unsigned int*)(void*)(~(unsigned int)(uintptr_t)(void*)handle->sramCurrentAddr); + } else if (moment == MOMENT_RUNTIME) { /* runtime diagnose */ + IRQ_Disable(); + RAM_DiagnoseSliceSramAndRecovery(handle, &state); + IRQ_Enable(); + } + return state; +} +/** + * @brief diagnose sram by parity check. + * @param ramDiagnoseHandle Value of @ref RAM_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState RAM_DiagnoseSramByParityCheck(void* ramDiagnoseHandle, DiagnoseMoment moment) +{ + RAM_DiagnoseHandle* handle = (RAM_DiagnoseHandle*)ramDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_RAM); + STATE_SetDiagnoseMoudule(&state, MODULE_RAM_SRAM); + STATE_SetDiagnoseFeature(&state, FEATURE_SRAM_PARITY); /* set diagnose subsys, module and feature to state */ + unsigned int status = DCL_SYSCTRL_GetSysramParityErrorStatus(); + if (status & 0x01) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_SRAM_PARITY_ERROR); /* set fail result and fault type to state */ + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +/** + * @brief diagnose stack overflow. + * @param ramDiagnoseHandle Value of @ref RAM_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState RAM_DiagnoseStackOverflow(void* ramDiagnoseHandle, DiagnoseMoment moment) +{ + RAM_DiagnoseHandle* handle = (RAM_DiagnoseHandle*)ramDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_RAM); + STATE_SetDiagnoseMoudule(&state, MODULE_RAM_STACK); /* set diagnose subsys, module and feature to state */ + STATE_SetDiagnoseFeature(&state, FEATURE_STACK_OVERFLOW_CHECK); + if (g_stackChkPattern[0] != 0xEEEEEEEE || /* test pattern 0 */ + g_stackChkPattern[1] != 0xCCCCCCCC || /* test pattern 1 */ + g_stackChkPattern[2] != 0xBBBBBBBB || /* test pattern 2 */ + g_stackChkPattern[3] != 0xDDDDDDDD) { /* test pattern 3 */ + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_STACK_OVERFLOW); /* set fail result and fault type to state */ + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/ram/src/diagnose_ram_march.S b/src/middleware/function_safety/library/mcu/ram/src/diagnose_ram_march.S new file mode 100644 index 0000000000000000000000000000000000000000..f2282a2765af3fb75232b64f9466db22eb1e5fcc --- /dev/null +++ b/src/middleware/function_safety/library/mcu/ram/src/diagnose_ram_march.S @@ -0,0 +1,385 @@ +# File Name : diagnose_ram_march.S +# Description : Full RISC-V CPU test full ram at start-up or +# test ram for classB parameters during run-time +# Input : None. +# Output : None. +# Return : SUCCESS (=0) if test is ok + +.section .text +.align 2 + +.global RAM_DiagnoseFullRange +.type RAM_DiagnoseFullRange,@function +.global RAM_DiagnoseStepRange +.type RAM_DiagnoseStepRange,@function + +# tables with offsets of physical order of address in RAM +.extern g_standRamOrder +.extern g_scrambleRamOrder + +# RAM Test Control +# #define USE_MARCHX_TEST + +#ifdef __riscv64 + #define LREG ld + #define SREG sd + #define REGBYTES 8 +#else + #define LREG lw + #define SREG sw + #define REGBYTES 4 +#endif + +/* ------------------------------------RAM_DiagnoseFullRange--------------------------------- */ +# Function Name : RAM_DiagnoseFullRange +# Description : Full RAM MarchC test for start-up +# Input : a0 .. RAM begin (first address to check), +# a1 .. RAM end (last address to check) +# a2 .. Background pattern +# Return : SUCCESS (=1) +# WARNING : All the RAM area including stack is destroyed during this test +RAM_DiagnoseFullRange: + not a3, a2 +#ifdef DIAGNOSE_RAM_SCRAMBLER + la a4, g_scrambleRamOrder # setup pointer to physical order of the addresses (a4) +#else + la a4, g_standRamOrder +#endif + +/* Save ram address register value */ + mv t0, a0 + mv t1, a1 + add t2, a4, 4 + +# *** Step 1 *** +# Write background pattern with addresses increasing +__FULL1_LOOP: + SREG a2, (a0) + addi a0, a0, 4 + blt a0, a1, __FULL1_LOOP + +# *** Step 2 *** +# Verify background and write inverted background with addresses increasing + mv a0, t0 + mv a4, t2 + add t3, t2, 16 +__FULL2_LOOP: + __CHECK2_LOOP: + LREG t4, (a4) + addi a4, a4, 4 + add t5, a0, t4 + LREG t6, (t5) + bne t6, a2, __FULL_ERR + SREG a3, (t5) + blt a4, t3, __CHECK2_LOOP + # restore register + addi a0, a0, 16 + mv a4, t2 + blt a0, a1, __FULL2_LOOP + +# *** Step 3 *** +# Verify inverted background and write background with addresses increasing + mv a0, t0 + mv a4, t2 + add t3, t2, 16 +__FULL3_LOOP: + __CHECK3_LOOP: + LREG t4, (a4) + addi a4, a4, 4 + add t5, a0, t4 + LREG t6, (t5) + bne t6, a3, __FULL_ERR + SREG a2, (t5) + blt a4, t3, __CHECK3_LOOP + # restore register + addi a0, a0, 16 + mv a4, t2 + blt a0, a1, __FULL3_LOOP + +# *** Step 4 *** +# Verify background and write inverted background with addresses decreasing + mv a0, t0 + add a1, t1, -16 # Include ram end address + mv a4, t2 + add t3, t2, 16 +__FULL4_LOOP: + __CHECK4_LOOP: + LREG t4, (a4) + addi a4, a4, 4 + add t5, a1, t4 + LREG t6, (t5) + bne t6, a2, __FULL_ERR + SREG a3, (t5) + blt a4, t3, __CHECK4_LOOP + # restore register + addi a1, a1, -16 + mv a4, t2 + bge a1, a0, __FULL4_LOOP + +# *** Step 5 *** +# Verify inverted background and write background with addresses decreasing + mv a0, t0 + add a1, t1, -16 # Include ram end address + mv a4, t2 + add t3, t2, 16 +__FULL5_LOOP: + __CHECK5_LOOP: + LREG t4, (a4) + addi a4, a4, 4 + add t5, a1, t4 + LREG t6, (t5) + bne t6, a3, __FULL_ERR + SREG a2, (t5) + blt a4, t3, __CHECK5_LOOP + # restore register + addi a1, a1, -16 + mv a4, t2 + bge a1, a0, __FULL5_LOOP + +# *** Step 6 *** +# Verify background with addresses increasing + mv a0, t0 + mv a1, t1 +__FULL6_LOOP: + LREG t3, (a0) + addi a0, a0, 4 + bne t3, a2, __FULL_ERR + blt a0, a1, __FULL6_LOOP + +__FULL_MARCH_RET: + li a0, 0 # Correct return + jal __FULL_RET + +__FULL_ERR: + li a0, 1 # error result + +__FULL_RET: + ret # return to the caller + + + +/* ------------------------------------RAM_DiagnoseStepRange--------------------------------- */ +# Function Name : RAM_DiagnoseStepRange +# Description : Transparent RAM MarchC-/March X test for run time +# Input : a0 .. RAM begin (first address to test), +# a1 .. Buffer begin (First address of backup buffer) +# a2 .. Background pattern +# Return : SUCCESS (=1) +# WARNING - The RAM area under test is out of original content during this test! +# Neighbour addresses (first-1 or -2 and last+1) are tested, too. +# Compilation parameters : ARTISAN - changes order of the sequence of tested +# addresses to respect their physical order +# USE_MARCHX_TEST - Skip step 3 and 4 of March C- to make the test +# shorter and faster overall +RAM_DiagnoseStepRange: +#ifdef ARTISAN + la a4, g_scrambleRamOrder # setup pointer to physical order of the addresses (a4) +#else + la a4, g_standRamOrder +#endif + + not a3, a2 # setup inverted background pattern (a3) + + # Save address register value + mv t0, a1 # save buffer start address + mv t1, a4 # save offset start address + + # Runtime RAM buffer test + beq a0, a1, __BUFF_TEST # a0 == a1 is buffer test + +# ***************** test of the RAM slice ********************* + mv a1, t0 + addi t2, t0, 20 # save 6 word + __SAVE_LOOP: + LREG t3, (a4) # load data offset + addi a4, a4, 4 + add t4, a0, t3 + LREG t5, (t4) + SREG t5, (a1) + addi a1, a1, 4 + ble a1, t2, __SAVE_LOOP + +# *** Step 1 *** +# Write background pattern with addresses increasing + mv a4, t1 # restore offset start address + addi t2, t1, 20 +__STEP1_LOOP: + LREG t3, (a4) # load data offset + addi a4, a4, 4 + add t4, a0, t3 + SREG a2, (t4) # store background pattern + ble a4, t2, __STEP1_LOOP + +# *** Step 2 *** +# Verify background and write inverted background with addresses increasing + mv a4, t1 + addi t2, t1, 20 +__STEP2_LOOP: + LREG t3, (a4) + addi a4, a4, 4 + add t4, a0, t3 + LREG t5, (t4) + bne t5, a2, __STEP_ERR # verify background pattern + SREG a3, (t4) # store inverted background pattern + ble a4, t2, __STEP2_LOOP + +#ifdef USE_MARCHX_TEST +#else +# *** Step 3 *** (not used at March-X test) +# Verify inverted background and write background with addresses increasing + mv a4, t1 + addi t2, t1, 20 +__STEP3_LOOP: + LREG t3, (a4) + addi a4, a4, 4 + add t4, a0, t3 + LREG t5, (t4) + bne t5, a3, __STEP_ERR + SREG a2, (t4) + ble a4, t2, __STEP3_LOOP + +# *** Step 4 *** (not used at March-X test) +# Verify background and write inverted background with addresses decreasing + add a4, t1, 20 + mv t2, t1 +__STEP4_LOOP: + LREG t3, (a4) + addi a4, a4, -4 + add t4, a0, t3 + LREG t5, (t4) + bne t5, a2, __STEP_ERR # verify background pattern + SREG a3, (t4) # store inverted background pattrern + bge a4, t2, __STEP4_LOOP +#endif + +# *** Step 5 *** +# Verify inverted background and write background with addresses decreasing + add a4, t1, 20 + mv t2, t1 +__STEP5_LOOP: + LREG t3, (a4) + addi a4, a4, -4 + add t4, a0, t3 + LREG t5, (t4) + bne t5, a3, __STEP_ERR + SREG a2, (t4) + bge a4, t2, __STEP5_LOOP + +# *** Step 6 *** +# Verify background with addresses increasing + mv a4, t1 + add t2, t1, 20 +__STEP6_LOOP: + LREG t3, (a4) + add a4, a4, 4 + add t4, a0, t3 + LREG t5, (t4) + bne t5, a2, __STEP_ERR # verify background pattern + ble a4, t2, __STEP6_LOOP + +/* --------------------------- Recovery ram data ----------------------- */ + mv a4, t1 + mv a1, t0 + add t2, t0, 20 +__RESTORE_LOOP: + LREG t3, (a4) # load data offset + add a4, a4, 4 + add t4, a0, t3 + LREG t5, (a1) + addi a1, a1, 4 + SREG t5, (t4) # load data from RAM buffer + ble a1, t2, __RESTORE_LOOP + j __MARCH_RET + +/* --------------------------- BUFFER Test ----------------------- */ +# ************** test of the buffer itself ******************** +__BUFF_TEST: +# *** Step 1 *** +# Write background pattern with addresses increasing + add a4, t1, 4 + add t2, t1, 32 +__BUFF1_LOOP: + LREG t3, (a4) # load data offset The test starts from 0 and the array index is 1. + addi a4, a4, 4 + add t4, a1, t3 + SREG a2, (t4) # store background pattern + ble a4, t2, __BUFF1_LOOP + +# *** Step 2 *** +# Verify background and write inverted background with addresses increasing + add a4, t1, 4 + add t2, t1, 32 +__BUFF2_LOOP: + LREG t3, (a4) + addi a4, a4, 4 + add t4, a1, t3 + LREG t5, (t4) + bne t5, a2, __STEP_ERR + SREG a3, (t4) + ble a4, t2, __BUFF2_LOOP + +#ifdef USE_MARCHX_TEST +#else +# *** Step 3 *** (not used at March-X test) +# Verify inverted background and write background with addresses increasing + add a4, t1, 4 + add t2, t1, 32 +__BUFF3_LOOP: + LREG t3, (a4) + addi a4, a4, 4 + add t4, a1, t3 + LREG t5, (t4) + bne t5, a3, __STEP_ERR + SREG a2, (t4) + ble a4, t2, __BUFF3_LOOP + +# *** Step 4 *** (not used at March-X test) +# Verify background and write inverted background with addresses decreasing + add a4, t1, 32 + add t2, t1, 4 +__BUFF4_LOOP: + LREG t3, (a4) + add a4, a4, -4 + add t4, a1, t3 + LREG t5, (t4) + bne t5, a2, __STEP_ERR + SREG a3, (t4) + bge a4, t2, __BUFF4_LOOP +#endif + +# *** Step 5 *** +# Verify inverted background and write background with addresses decreasing + add a4, t1, 32 + add t2, t1, 4 +__BUFF5_LOOP: + LREG t3, (a4) + add a4, a4, -4 + add t4, a1, t3 + LREG t5, (t4) + bne t5, a3, __STEP_ERR + SREG a2, (t4) + bge a4, t2, __BUFF5_LOOP + +# *** Step 6 *** +# Verify background with addresses increasing + add a4, t1, 4 + add t2, t1, 32 +__BUFF6_LOOP: + LREG t3, (a4) + addi a4, a4, 4 + add t4, a1, t3 + LREG t5, (t4) + bne t5, a2, __STEP_ERR + ble a4, t2, __BUFF6_LOOP + +__MARCH_RET: + li a0, 0 # Correct return + j __STEP_RET + +__STEP_ERR: + li a0, 1 + ret +# li a0, 1 # error result + +__STEP_RET: + ret # return to the caller \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/ram/src/failsafe_mcu_ram.c b/src/middleware/function_safety/library/mcu/ram/src/failsafe_mcu_ram.c new file mode 100644 index 0000000000000000000000000000000000000000..54b7df31a38ff1b529ddb402064de681fec2cc6c --- /dev/null +++ b/src/middleware/function_safety/library/mcu/ram/src/failsafe_mcu_ram.c @@ -0,0 +1,132 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_ram.c + * @author MCU Driver Team + * @brief This file contains the functions definition for ram failsafe. + */ +#include "diagnose_mcu_ram.h" +#include "failsafe_mcu_ram.h" + +/** + * @brief default failsafe measure of ram. + * @param ramFailSafeHandle Value of @ref RAM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +__weak FunctionSafetyState RAM_DefaultFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment) +{ + RAM_FailSafeHandle* handle = (RAM_FailSafeHandle*)ramFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + while (1) { + } + return state; +} +/** + * @brief failsafe measure of ram step range diagnose. + * @param ramFailSafeHandle Value of @ref RAM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState RAM_StepRangeFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment) +{ + RAM_FailSafeHandle* handle = (RAM_FailSafeHandle*)ramFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure of ram full range diagnose. + * @param ramFailSafeHandle Value of @ref RAM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState RAM_FullRangeFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment) +{ + RAM_FailSafeHandle* handle = (RAM_FailSafeHandle*)ramFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure of ram stack overflow. + * @param ramFailSafeHandle Value of @ref RAM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState RAM_OverflowFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment) +{ + RAM_FailSafeHandle* handle = (RAM_FailSafeHandle*)ramFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure of ram parity check. + * @param ramFailSafeHandle Value of @ref RAM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState RAM_ParityFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment) +{ + RAM_FailSafeHandle* handle = (RAM_FailSafeHandle*)ramFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure handler of ram. + * @param dioFailSafeHandle Value of @ref DIO_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState RAM_FailSafeHandler(void* ramFailSafeHandle, DiagnoseMoment moment) +{ + RAM_FailSafeHandle* handle = (RAM_FailSafeHandle*)ramFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + switch (state.BIT.faultType) { + case FAULT_DATA_NOT_INTEGRITY: + case FAULT_SRAM_STEP_RANGE: + state = RAM_StepRangeFailSafe(handle, moment); /* ram step range fail safe */ + break; + case FAULT_SRAM_FULL_RANGE: + state = RAM_FullRangeFailSafe(handle, moment); /* ram full range fail safe */ + break; + case FAULT_SRAM_PARITY_ERROR: + state = RAM_ParityFailSafe(handle, moment); /* ram parity check fail safe */ + break; + case FAULT_STACK_OVERFLOW: + state = RAM_OverflowFailSafe(handle, moment); /* ram step range fail safe */ + break; + default: + state = RAM_DefaultFailSafe(handle, moment); /* ram default fail safe */ + break; + } + return state; +} \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/ram/src/faultpredict_mcu_ram.c b/src/middleware/function_safety/library/mcu/ram/src/faultpredict_mcu_ram.c new file mode 100644 index 0000000000000000000000000000000000000000..6467b9418160a10b790d1d97b370465134afb701 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/ram/src/faultpredict_mcu_ram.c @@ -0,0 +1,23 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_ram.c + * @author MCU Driver Team + * @brief This file contains the functions definition for ram faultpredict. + */ +#include "faultpredict_mcu_ram.h" + diff --git a/src/middleware/hisilicon/nostask/include/common/os_typedef.h b/src/middleware/function_safety/library/mcu/rom/inc/diagnose_mcu_rom.h similarity index 58% rename from src/middleware/hisilicon/nostask/include/common/os_typedef.h rename to src/middleware/function_safety/library/mcu/rom/inc/diagnose_mcu_rom.h index 4c0b755f14fb757f8a8b41591ff4cd6a1dff8990..9e6ce375fd4fb4f40f13338906e1a4b31a1da48b 100644 --- a/src/middleware/hisilicon/nostask/include/common/os_typedef.h +++ b/src/middleware/function_safety/library/mcu/rom/inc/diagnose_mcu_rom.h @@ -15,74 +15,52 @@ * 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. - * @file os_typedef.h + * @file diagnose_mcu_rom.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for rom diagnose. */ -#ifndef OS_TYPEDEF_H -#define OS_TYPEDEF_H -#include -#include +#ifndef DIAGNOSE_MCU_ROM_H +#define DIAGNOSE_MCU_ROM_H -#ifndef INLINE -#define INLINE static __inline __attribute__((always_inline)) +#include "function_safety_common.h" +#ifdef CRC +#include "crc.h" #endif - -#ifndef OS_EMBED_ASM -#define OS_EMBED_ASM __asm__ __volatile__ +#ifdef EFC +#include "flash.h" #endif -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -typedef void (*OsVoidFunc)(void); +#define MODULE_ROM_RANGE 0x01 +#define MODULE_ROM_EFLASH 0x02 -#ifndef FALSE -#define FALSE ((bool)0) -#endif +#define FEATURE_ROM_INTEGRITY 0x01 +#define FEATURE_EFLASH_ECC 0x02 -#ifndef TRUE -#define TRUE ((bool)1) -#endif +#define FAULT_DATA_NOT_INTEGRITY 0x01 +#define FAULT_ROM_STEP_RANGE 0x02 +#define FAULT_ROM_FULL_RANGE 0x03 +#define FAULT_EFLASH_ECC_ERROR 0x04 -#ifndef NULL -#define NULL ((void *)0) +typedef struct { +#ifdef CRC + CRC_Handle* crcHandle; #endif - -#define OS_FAIL 1 -#define OS_ERROR (unsigned int)(-1) -#define OS_INVALID (-1) - -#ifndef OS_OK -#define OS_OK 0 +#ifdef EFC + EFC_RegStruct* flashBase; + unsigned int eccIntRegVal; #endif - -#ifndef U8_INVALID -#define U8_INVALID 0xffU + unsigned int* startAddr; + unsigned int* indexPointer; + unsigned int* indexPointerInv; + unsigned int flashBlockSizeInWords; +} ROM_DiagnoseHandle; + +#ifdef CRC +FunctionSafetyState ROM_DiagnoseIntegrity(void* romDiagnoseHandle, DiagnoseMoment moment); #endif - -#ifndef U12_INVALID -#define U12_INVALID 0xfffU +#ifdef EFC +FunctionSafetyState ROM_DiagnoseFlashEcc(void* romDiagnoseHandle, DiagnoseMoment moment); #endif -#ifndef U16_INVALID -#define U16_INVALID 0xffffU -#endif - -#ifndef U32_INVALID -#define U32_INVALID 0xffffffffU -#endif - -#ifndef U64_INVALID -#define U64_INVALID 0xffffffffffffffffUL -#endif - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* OS_TYPEDEF_H */ +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/rom/inc/failsafe_mcu_rom.h b/src/middleware/function_safety/library/mcu/rom/inc/failsafe_mcu_rom.h new file mode 100644 index 0000000000000000000000000000000000000000..bc43174f89873999d45de14354cbd07879a64841 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/rom/inc/failsafe_mcu_rom.h @@ -0,0 +1,38 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_rom.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for rom failsafe. + */ + +#ifndef FAILSAFE_MCU_ROM_H +#define FAILSAFE_MCU_ROM_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} ROM_FailSafeHandle; + +FunctionSafetyState ROM_FailSafeHandler(void* romFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState ROM_IntegrityFailSafe(void* romFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState ROM_FullRangeFailSafe(void* romFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState ROM_StepRangeFailSafe(void* romFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState ROM_DefaultFailSafe(void* romFailSafeHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/rom/inc/faultpredict_mcu_rom.h b/src/middleware/function_safety/library/mcu/rom/inc/faultpredict_mcu_rom.h new file mode 100644 index 0000000000000000000000000000000000000000..4e3fe6c278d21a3302c57c8e4a90b50cae809baf --- /dev/null +++ b/src/middleware/function_safety/library/mcu/rom/inc/faultpredict_mcu_rom.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_rom.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for rom faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_ROM_H +#define FAULTPREDICT_MCU_ROM_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} ANA_FaultPredictHandle; + +FunctionSafetyState ANA_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/rom/src/diagnose_mcu_rom.c b/src/middleware/function_safety/library/mcu/rom/src/diagnose_mcu_rom.c new file mode 100644 index 0000000000000000000000000000000000000000..e2f4ec546a581848a5a6354ba9b5588043391296 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/rom/src/diagnose_mcu_rom.c @@ -0,0 +1,162 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_rom.c + * @author MCU Driver Team + * @brief This file contains the functions for rom diagnose. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "diagnose_mcu_rom.h" + +unsigned int g_refCrcSum __attribute__((section("CHECKSUM"))); +#define REF_VALUE_CRC32 (*((unsigned int *)&g_refCrcSum + 1)) +#define ROM_END ((unsigned int *)&g_refCrcSum + 1) +/** + * @brief endian swap function. + * @param inputDate Value of input. + * @retval unsigned int Value of inputDate endiam swap. + */ +static unsigned int EndianSwap(unsigned int inputDate) +{ + unsigned int outputData; + /* big little endian swap */ + outputData = (unsigned int)(((unsigned int)(inputDate & 0xff000000) >> 24) | /* 24: right shift 24 bit */ + ((unsigned int)(inputDate & 0x00ff0000) >> 8) | /* 8: right shift 8 bit */ + ((unsigned int)(inputDate & 0x0000ff00) << 8) | /* 8: left shift 24 bit */ + ((unsigned int)(inputDate & 0x000000ff) << 24)) ; /* 24: left shift 24 bit */ + return outputData; +} + +/*-------------------------------- CRC diagnose rom intgrity ------------------------------------------*/ +#ifdef CRC +/** + * @brief ROM diagnose integrity at startup. + * @param handle @ref ROM_DiagnoseHandle. + * @param state @ref FunctionSafetyState. + * @retval state @ref FunctionSafetyState. + */ +static FunctionSafetyState ROM_DiagnoseIntegrityStartup(ROM_DiagnoseHandle* handle, FunctionSafetyState* state) +{ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + unsigned int romFullSize = (ROM_END - handle->startAddr) * 4 / (handle->crcHandle->inputDataFormat + 1); + bool result = HAL_CRC_CheckInputData(handle->crcHandle, handle->startAddr, \ + romFullSize, EndianSwap(REF_VALUE_CRC32)); + if (result == false) { + STATE_SetDiagnoseResult(state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(state, FAULT_ROM_FULL_RANGE); /* set fail result and fault type to state */ + return *state; + } else { + STATE_SetDiagnoseResult(state, RESULT_SUCCESS); /* set result success to state */ + } + return *state; +} + +/** + * @brief ROM diagnose integrity at run time. + * @param handle @ref ROM_DiagnoseHandle. + * @param state @ref FunctionSafetyState. + * @retval state @ref FunctionSafetyState. + */ +static FunctionSafetyState ROM_DiagnoseIntegrityRuntime(ROM_DiagnoseHandle* handle, FunctionSafetyState* state) +{ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + if ((((unsigned int)(uintptr_t)(void *)handle->indexPointer) ^ \ + ((unsigned int)(uintptr_t)(void *)handle->indexPointerInv)) != 0xFFFFFFFFU) { + STATE_SetDiagnoseResult(state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(state, FAULT_DATA_NOT_INTEGRITY); /* set fail result and fault type to state */ + return *state; + } + if (handle->indexPointer <= ROM_END) { + for (unsigned int index = 0; index < handle->flashBlockSizeInWords; ++index) { + /* Avoid out of ROM test range */ + if ((handle->indexPointer + index) > ROM_END) { + break; + } + unsigned int hostData = *((unsigned int *)handle->indexPointer + index); + HAL_CRC_SetInputDataGetCheck(handle->crcHandle, EndianSwap(hostData)); + } + handle->indexPointer += handle->flashBlockSizeInWords; /* Increment pointer to next block */ + handle->indexPointerInv = ((unsigned int *)(~((unsigned int)(uintptr_t)(void *)handle->indexPointer))); + STATE_SetDiagnoseResult(state, RESULT_IS_RUNNING); + } else { + unsigned int crcValue = EndianSwap(DCL_CRC_GetOutputData(handle->crcHandle->baseAddress)); + if (crcValue != REF_VALUE_CRC32) { + STATE_SetDiagnoseResult(state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(state, FAULT_ROM_STEP_RANGE); /* set fail result and fault type to state */ + return *state; + } else { + STATE_SetDiagnoseResult(state, RESULT_SUCCESS); /* set result success to state */ + } + handle->indexPointer = handle->startAddr; + handle->indexPointerInv = ((unsigned int *)(~((unsigned int)(uintptr_t)(void *)handle->startAddr))); + HAL_CRC_DeInit(handle->crcHandle); + } + return *state; +} + +/** + * @brief diagnose rom integrith by crc32. + * @param romDiagnoseHandle Value of @ref ROM_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState ROM_DiagnoseIntegrity(void* romDiagnoseHandle, DiagnoseMoment moment) +{ + ROM_DiagnoseHandle* handle = (ROM_DiagnoseHandle*)romDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_ROM); + STATE_SetDiagnoseMoudule(&state, MODULE_ROM_RANGE); + STATE_SetDiagnoseFeature(&state, FEATURE_ROM_INTEGRITY); /* set diagnose subsys, module and feature to state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle->crcHandle != NULL, &state); /* param check not NULL */ + if (moment == MOMENT_STARTUP) { + state = ROM_DiagnoseIntegrityStartup(handle, &state); + } else if (moment == MOMENT_RUNTIME) { + state = ROM_DiagnoseIntegrityRuntime(handle, &state); + } + return state; +} +#endif +/*-------------------------------- CRC diagnose rom intgrity ------------------------------------------*/ +#ifdef EFC +/** + * @brief diagnose rom integrith by flash ecc. + * @param romDiagnoseHandle Value of @ref ROM_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState ROM_DiagnoseFlashEcc(void* romDiagnoseHandle, DiagnoseMoment moment) +{ + ROM_DiagnoseHandle* handle = (ROM_DiagnoseHandle*)romDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_ROM); + STATE_SetDiagnoseMoudule(&state, MODULE_ROM_EFLASH); + STATE_SetDiagnoseFeature(&state, FEATURE_EFLASH_ECC); /* set diagnose subsys, module and feature to state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + unsigned int status = DCL_FLASH_GetInterrupRawtStatus(handle->flashBase); + if ((status & handle->eccIntRegVal) != 0) { + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_EFLASH_ECC_ERROR); /* set fail result and fault type to state */ + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + return state; +} +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/rom/src/failsafe_mcu_rom.c b/src/middleware/function_safety/library/mcu/rom/src/failsafe_mcu_rom.c new file mode 100644 index 0000000000000000000000000000000000000000..be6694daba0c528ba67042c3bc05b866de47872a --- /dev/null +++ b/src/middleware/function_safety/library/mcu/rom/src/failsafe_mcu_rom.c @@ -0,0 +1,115 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_rom.c + * @author MCU Driver Team + * @brief This file contains the functions for rom failsafe. + */ + +#include "diagnose_mcu_rom.h" +#include "failsafe_mcu_rom.h" +/** + * @brief default failsafe measure of rom. + * @param romFailSafeHandle Value of @ref ROM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +__weak FunctionSafetyState ROM_DefaultFailSafe(void* romFailSafeHandle, DiagnoseMoment moment) +{ + ROM_FailSafeHandle* handle = (ROM_FailSafeHandle*)romFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + while (1) { + } + return state; +} +/** + * @brief failsafe measure of rom step range diagnose. + * @param romFailSafeHandle Value of @ref ROM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState ROM_StepRangeFailSafe(void* romFailSafeHandle, DiagnoseMoment moment) +{ + ROM_FailSafeHandle* handle = (ROM_FailSafeHandle*)romFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure of rom full range diagnose. + * @param romFailSafeHandle Value of @ref ROM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState ROM_FullRangeFailSafe(void* romFailSafeHandle, DiagnoseMoment moment) +{ + ROM_FailSafeHandle* handle = (ROM_FailSafeHandle*)romFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure of rom integrity. + * @param romFailSafeHandle Value of @ref ROM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState ROM_IntegrityFailSafe(void* romFailSafeHandle, DiagnoseMoment moment) +{ + ROM_FailSafeHandle* handle = (ROM_FailSafeHandle*)romFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure handler of rom. + * @param romFailSafeHandle Value of @ref ROM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState ROM_FailSafeHandler(void* romFailSafeHandle, DiagnoseMoment moment) +{ + ROM_FailSafeHandle* handle = (ROM_FailSafeHandle*)romFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not NULL */ + switch (state.BIT.faultType) { + case FAULT_DATA_NOT_INTEGRITY: + state = ROM_IntegrityFailSafe(handle, moment); /* rom integrity fail safe */ + break; + case FAULT_ROM_STEP_RANGE: + state = ROM_StepRangeFailSafe(handle, moment); /* rom step range fail safe */ + break; + case FAULT_ROM_FULL_RANGE: + state = ROM_FullRangeFailSafe(handle, moment); /* rom full range fail safe */ + break; + case FAULT_EFLASH_ECC_ERROR: + break; + default: + state = ROM_DefaultFailSafe(handle, moment); /* rom default fail safe */ + break; + } + return state; +} \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/rom/src/faultpredict_mcu_rom.c b/src/middleware/function_safety/library/mcu/rom/src/faultpredict_mcu_rom.c new file mode 100644 index 0000000000000000000000000000000000000000..c46663b8fe33227c2c17d5de971953e476e62587 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/rom/src/faultpredict_mcu_rom.c @@ -0,0 +1,23 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_rom.c + * @author MCU Driver Team + * @brief This file contains the functions for rom faultpredict. + */ +#include "faultpredict_mcu_rom.h" + diff --git a/src/middleware/hisilicon/nostask/kernel/include/nos_task_internal.h b/src/middleware/function_safety/library/mcu/timers/inc/diagnose_mcu_timers.h similarity index 49% rename from src/middleware/hisilicon/nostask/kernel/include/nos_task_internal.h rename to src/middleware/function_safety/library/mcu/timers/inc/diagnose_mcu_timers.h index 86be5d4df56059771a98f3e9bc5f7d844555df79..d0824d52f3dcf512f238d9bc2fa16156e10c567f 100644 --- a/src/middleware/hisilicon/nostask/kernel/include/nos_task_internal.h +++ b/src/middleware/function_safety/library/mcu/timers/inc/diagnose_mcu_timers.h @@ -15,76 +15,74 @@ * 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. - * @file nos_task_internal.h + * @file diagnose_mcu_timers.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for timers diagnose. */ -#ifndef NOS_TASK_INTERNAL_H -#define NOS_TASK_INTERNAL_H -#include "nos_task_external.h" -#include "nos_task_sched_external.h" +#ifndef DIAGNOSE_MCU_TIMERS_H +#define DIAGNOSE_MCU_TIMERS_H -/* - * 模块内宏定义 - */ -#define OS_TSK_STACK_MAGIC OS_TSK_STACK_MAGIC_WORD - -/* 锁 */ -INLINE unsigned int NOS_TaskIntLock(void) -{ -#ifdef OS_OPTION_306X - return NOS_SystickLock(); -#else - return (unsigned int)NOS_IntLock(); +#include "function_safety_common.h" +#ifdef CRG +#include "crg.h" #endif -} - -/* 锁恢复 */ -INLINE void NOS_TaskIntRestore(unsigned int intSave) -{ -#ifdef OS_OPTION_306X - NOS_SystickRestore(intSave); -#else - NOS_IntRestore(intSave); +#ifdef TIMER0 +#include "timer.h" +#endif +#ifdef APT0 +#include "apt.h" +#endif +#ifdef QDM0 +#include "qdm.h" +#endif +#ifdef CAPM0 +#include "capm.h" +#endif +#ifdef GPT0 +#include "gpt.h" #endif -} - -/* - * 模块内全局变量声明 - */ -extern struct TagListObject g_tskCBFreeList; -extern struct TagListObject g_tskRecyleList; -/* - * 模块内函数声明 - */ -extern unsigned int OsTaskDelStatusCheck(struct TagTskCB *taskCB); -extern void OsTskRecycle(void); -extern unsigned long NOS_TaskUpdateExpirCnt(unsigned int taskPid); +#define MODULE_TIMER 0x01 +#define MODULE_APT 0x02 +#define MODULE_QDM 0x03 +#define MODULE_CAPM 0x04 +#define MODULE_GPT 0x05 -INLINE void OsMoveTaskToReady(struct TagTskCB *taskCB) -{ - /* If task is not blocked then move it to ready list */ - if ((taskCB->taskStatus & OS_TSK_BLOCK) == 0) { - OsTskReadyAdd(taskCB); +#define FEATURE_TIMER_INTERRUPT_ACCURACY 0x01 +#define FEATURE_APT_INTERRUPT_ACCURACY 0x02 +#define FEATURE_QDM_INTERRUPT_ACCURACY 0x03 +#define FEATURE_CAPM_INTERRUPT_ACCURACY 0x04 +#define FEATURE_GPT_INTERRUPT_ACCURACY 0x05 - if ((OS_FLG_BGD_ACTIVE & UNI_FLAG) != 0) { - OsSpinUnlockTaskRq(taskCB); - /* task Schedule */ - OsTskSchedule(); - return; - } - } +#define FAULT_INTERRUPT_ACCURACY 0x01 - OsSpinUnlockTaskRq(taskCB); -} +typedef struct { +#ifdef TIMER0 + TIMER_Handle* timerHandle; +#endif +#ifdef APT0 + APT_Handle* aptHandle; +#endif +#ifdef QDM0 + QDM_Handle* qdmHandle; +#endif +#ifdef CAPM0 + CAPM_Handle* capmHandle; +#endif +#ifdef GPT0 + GPT_Handle* gptHandle; +#endif + unsigned int setTimeUs; + unsigned int pretimeCycle; + unsigned int currenttimeCycle; + unsigned int durationUs; + unsigned int errRangeUs; + bool timerIrqFlag; +} TIMERS_DiagnoseHandle; -INLINE unsigned int OsTaskCreateUsrStkCfgInit(struct TskInitParam *initParam, - unsigned int *curStackSize, struct TagTskCB *taskCB) -{ - (void)taskCB; - /* Obtains the stack size. */ - *curStackSize = initParam->stackSize; - return NOS_OK; -} +#ifdef TIMER0 +FunctionSafetyState TIMERS_DiagnoseInterruptIntervalAccuracy(void* timersDiagnoseHandle, DiagnoseMoment moment); +#endif -#endif /* NOS_TASK_INTERNAL_H */ +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/timers/inc/failsafe_mcu_timers.h b/src/middleware/function_safety/library/mcu/timers/inc/failsafe_mcu_timers.h new file mode 100644 index 0000000000000000000000000000000000000000..46ae7138c8fc1e4a63f1224c01ad54d6fa1ac5b2 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/timers/inc/failsafe_mcu_timers.h @@ -0,0 +1,36 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_timers.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for timers failsafe. + */ + +#ifndef FAILSAFE_MCU_TIMERS_H +#define FAILSAFE_MCU_TIMERS_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} TIMERS_FailSafeHandle; + +FunctionSafetyState TIMERS_FailSafeHandler(void* timersFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState TIMERS_InterruptFailSafe(void* timersFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState TIMERS_DefaultFailSafe(void* timersFailSafeHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/timers/inc/faultpredict_mcu_timers.h b/src/middleware/function_safety/library/mcu/timers/inc/faultpredict_mcu_timers.h new file mode 100644 index 0000000000000000000000000000000000000000..87ea327e45fd63666d4d668d82636cd4a5d18ee4 --- /dev/null +++ b/src/middleware/function_safety/library/mcu/timers/inc/faultpredict_mcu_timers.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_timers.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for timers faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_TIMERS_H +#define FAULTPREDICT_MCU_TIMERS_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} ANA_FaultPredictHandle; + +FunctionSafetyState ANA_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/timers/src/diagnose_mcu_timers.c b/src/middleware/function_safety/library/mcu/timers/src/diagnose_mcu_timers.c new file mode 100644 index 0000000000000000000000000000000000000000..4b1842b8673ec1e7b8d2bdf6ea5843498d2efe6a --- /dev/null +++ b/src/middleware/function_safety/library/mcu/timers/src/diagnose_mcu_timers.c @@ -0,0 +1,55 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_timers.c + * @author MCU Driver Team + * @brief This file contains the functions for timers diagnose. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "diagnose_mcu_timers.h" +#ifdef TIMER0 +/** + * @brief calculate interrupt interval of timer. + * @param timersDiagnoseHandle Value of @ref TIMERS_DiagnoseHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState TIMERS_DiagnoseInterruptIntervalAccuracy(void* timersDiagnoseHandle, DiagnoseMoment moment) +{ + TIMERS_DiagnoseHandle* handle = (TIMERS_DiagnoseHandle*)timersDiagnoseHandle; + FunctionSafetyState state = {0}; + BASE_FUNC_UNUSED(moment); + STATE_SetDiagnoseSubsysterm(&state, SUBSYS_TIMERS); /* run in timer irq handler */ + STATE_SetDiagnoseMoudule(&state, MODULE_TIMER); /* set diagnose subsys, module and feature to state */ + STATE_SetDiagnoseFeature(&state, FEATURE_TIMER_INTERRUPT_ACCURACY); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + if (!handle->timerIrqFlag) { + STATE_SetDiagnoseResult(&state, RESULT_IS_RUNNING); /* set result ongoing to state */ + return state; + } + handle->timerIrqFlag = BASE_CFG_UNSET; + if (handle->durationUs > (handle->setTimeUs + handle->errRangeUs)) { /* interrupt interval judgement */ + STATE_SetDiagnoseResult(&state, RESULT_FAIL); + STATE_SetDiagnoseFaultType(&state, FAULT_INTERRUPT_ACCURACY); /* set fail result and fault type to state */ + return state; + } + STATE_SetDiagnoseResult(&state, RESULT_SUCCESS); /* set result success to state */ + HAL_TIMER_Stop(handle->timerHandle); + return state; +} +#endif \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/timers/src/failsafe_mcu_timers.c b/src/middleware/function_safety/library/mcu/timers/src/failsafe_mcu_timers.c new file mode 100644 index 0000000000000000000000000000000000000000..ebec828c343b3e2c1c4c3ce84f8575e0e255879b --- /dev/null +++ b/src/middleware/function_safety/library/mcu/timers/src/failsafe_mcu_timers.c @@ -0,0 +1,76 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_timers.c + * @author MCU Driver Team + * @brief This file contains the functions for timers failsafe. + */ +#include "diagnose_mcu_timers.h" +#include "failsafe_mcu_timers.h" +/** + * @brief default failsafe measure of timers. + * @param romFailSafeHandle Value of @ref ROM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +__weak FunctionSafetyState TIMERS_DefaultFailSafe(void* timersFailSafeHandle, DiagnoseMoment moment) +{ + TIMERS_FailSafeHandle* handle = (TIMERS_FailSafeHandle*)timersFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not null */ + while (1) { + } + return state; +} +/** + * @brief failsafe measure of timer interrupt. + * @param romFailSafeHandle Value of @ref ROM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState TIMERS_InterruptFailSafe(void* timersFailSafeHandle, DiagnoseMoment moment) +{ + TIMERS_FailSafeHandle* handle = (TIMERS_FailSafeHandle*)timersFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not null */ + BASE_FUNC_UNUSED(moment); + BASE_FUNC_UNUSED(handle); + return state; +} +/** + * @brief failsafe measure handler of timer. + * @param romFailSafeHandle Value of @ref ROM_FailSafeHandle. + * @param moment Value of @ref DiagnoseMoment. + * @retval state Value of @ref FunctionSafetyState. + */ +FunctionSafetyState TIMERS_FailSafeHandler(void* timersFailSafeHandle, DiagnoseMoment moment) +{ + TIMERS_FailSafeHandle* handle = (TIMERS_FailSafeHandle*)timersFailSafeHandle; + FunctionSafetyState state = STATE_LoadFailEvent(); /* load fail event */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); /* param check not null */ + switch (state.BIT.faultType) { + case FAULT_INTERRUPT_ACCURACY: + state = TIMERS_InterruptFailSafe(handle, moment); /* timer interrupt interval fail safe */ + break; + default: + state = TIMERS_DefaultFailSafe(handle, moment); /* timer default fail safe */ + break; + } + return state; +} \ No newline at end of file diff --git a/src/middleware/function_safety/library/mcu/timers/src/faultpredict_mcu_timers.c b/src/middleware/function_safety/library/mcu/timers/src/faultpredict_mcu_timers.c new file mode 100644 index 0000000000000000000000000000000000000000..7325be88a1a20da5ef76b5ecb41eb64d38377d4c --- /dev/null +++ b/src/middleware/function_safety/library/mcu/timers/src/faultpredict_mcu_timers.c @@ -0,0 +1,23 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_timers.c + * @author MCU Driver Team + * @brief This file contains the functions for timers fault predict. + */ +#include "faultpredict_mcu_timers.h" + diff --git a/src/middleware/function_safety/process/function_safety_process.c b/src/middleware/function_safety/process/function_safety_process.c new file mode 100644 index 0000000000000000000000000000000000000000..ae083f4cf36231619375cbad3bddeec914939d33 --- /dev/null +++ b/src/middleware/function_safety/process/function_safety_process.c @@ -0,0 +1,127 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_process.c + * @author MCU Driver Team + * @brief function safety general process module. + * @details function safety general process implement. + */ +#include "function_safety_process.h" + +/** + * @brief Excute function safety diagnose process and return state. + * @param processHandle @ref FunctionSafetyProcessHandle. + * @param *state @ref FunctionSafetyState. + * @param processTime @ref ProcessTimeCycle. + * @retval None. + */ +static void DiagnoseProcess(FunctionSafetyProcessHandle* handle, FunctionSafetyState* state, \ + ProcessTimeCycle* processTime) +{ + if (handle->diagnoseFunc == NULL || handle->diagnoseHandle == NULL) { + return; + } + if (processTime != NULL && processTime->timeCycleRecordSwitch) { + unsigned int startCycle = BASE_FUNC_GetTick(); /* diagnose start cycle */ + *state = handle->diagnoseFunc(handle->diagnoseHandle, handle->moment); /* diagnose function */ + unsigned int endCycle = BASE_FUNC_GetTick(); /* diagnose end cycle */ + processTime->diagnoseTimeCycle = (endCycle > startCycle) ? (endCycle - startCycle) : \ + (startCycle + UINT_MAX - endCycle + 1); + } else { + *state = handle->diagnoseFunc(handle->diagnoseHandle, handle->moment); /* diagnose function */ + } + STATE_StoreCurrentState(state); /* store current state */ + if (state->BIT.result == RESULT_FAIL) { /* result fail judgement */ + STATE_StoreFailEvent(state); + } +} + +/** + * @brief Excute function safety failsafe process and return state. + * @param processHandle @ref FunctionSafetyProcessHandle. + * @param *state @ref FunctionSafetyState. + * @param processTime @ref ProcessTimeCycle. + * @retval None. + */ +static void FailSafeProcess(FunctionSafetyProcessHandle* handle, FunctionSafetyState* state, \ + ProcessTimeCycle* processTime) +{ + if ((state->BIT.result != RESULT_FAIL) || handle->failSafeFunc == NULL || handle->failSafeHandle == NULL) { + return; + } + if (processTime != NULL && processTime->timeCycleRecordSwitch) { + unsigned int startCycle = BASE_FUNC_GetTick(); /* get start cycle */ + *state = handle->failSafeFunc(handle->failSafeHandle, handle->moment); /* fail safe function */ + unsigned int endCycle = BASE_FUNC_GetTick(); /* get end cycle */ + /* calculate fail safe duration cycle */ + processTime->failSafeTimeCycle = (endCycle > startCycle) ? (endCycle - startCycle) : \ + (startCycle + UINT_MAX - endCycle + 1); + } else { + *state = handle->failSafeFunc(handle->failSafeHandle, handle->moment); /* fail safe function */ + } +} + +/** + * @brief Excute function safety fault predict process and return state. + * @param processHandle @ref FunctionSafetyProcessHandle. + * @param *state @ref FunctionSafetyState. + * @param processTime @ref ProcessTimeCycle. + * @retval None. + */ +static void FaultPredictProcess(FunctionSafetyProcessHandle* handle, FunctionSafetyState* state, \ + ProcessTimeCycle* processTime) +{ + if ((state->BIT.result == RESULT_FAIL) || handle->faultPredictFunc == NULL || handle->faultPredictHandle == NULL) { + return; + } + if (processTime != NULL && processTime->timeCycleRecordSwitch) { + unsigned int startCycle = BASE_FUNC_GetTick(); /* get start cycle */ + *state = handle->faultPredictFunc(handle->faultPredictHandle, handle->moment); /* fault predict function */ + unsigned int endCycle = BASE_FUNC_GetTick(); /* get end cycle */ + processTime->faultPredictTimeCycle = (endCycle > startCycle) ? (endCycle - startCycle) : \ + (startCycle + UINT_MAX - endCycle + 1); + } else { + *state = handle->faultPredictFunc(handle->faultPredictHandle, handle->moment); /* fault predict function */ + } +} + +/** + * @brief Excute function safety process and return state. + * @param processHandle @ref FunctionSafetyProcessHandle. + * @param processTime @ref ProcessTimeCycle. + * @retval state @ref FunctionSafetyState. + */ +FunctionSafetyState FunctionSafetyProcess(void* processHandle, ProcessTimeCycle* processTime) +{ + FunctionSafetyProcessHandle* handle = (FunctionSafetyProcessHandle*)processHandle; + FunctionSafetyState state = {0}; /* init state */ + DIAGNOSE_PARAM_CHECK_WITH_STATE(handle != NULL, &state); + DIAGNOSE_PARAM_CHECK_WITH_STATE(processTime != NULL, &state); + if (handle->contexBackupFunc && handle->contexHandle) { + state = handle->contexBackupFunc(handle->contexHandle, handle->moment); /* contex backup */ + } + if (handle->handleConfigFunc) { + handle->handleConfigFunc(); /* handle config */ + } + DiagnoseProcess(handle, &state, processTime); + FailSafeProcess(handle, &state, processTime); + FaultPredictProcess(handle, &state, processTime); + if (handle->contexResumeFunc && handle->contexHandle) { + handle->contexResumeFunc(handle->contexHandle, handle->moment); /* contex resume */ + } + return state; +} \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/include/nos_sys_external.h b/src/middleware/function_safety/process/function_safety_process.h similarity index 58% rename from src/middleware/hisilicon/nostask/kernel/include/nos_sys_external.h rename to src/middleware/function_safety/process/function_safety_process.h index c660ba9943b36165ab224ae821fc4525d97ed2a7..5f8754bfacb3107531d9ddcafe1e23dc10f61659 100644 --- a/src/middleware/hisilicon/nostask/kernel/include/nos_sys_external.h +++ b/src/middleware/function_safety/process/function_safety_process.h @@ -15,45 +15,39 @@ * 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. - * @file nos_sys_external.h + * @file function_safety_process.h + * @author MCU Driver Team + * @brief function safety process module. + * @details function safety process handle and interfece. */ -#ifndef NOS_SYS_EXTERNAL_H -#define NOS_SYS_EXTERNAL_H -#include "nos_base_task.h" -#include "nos_list_external.h" -#include "nos_cpu_external.h" +#ifndef FUNCTION_SAFETY_PROCESS_H +#define FUNCTION_SAFETY_PROCESS_H -#define OS_INT_ACTIVE_MASK \ - (OS_FLG_HWI_ACTIVE | OS_FLG_SWI_ACTIVE | OS_FLG_TICK_ACTIVE | \ - OS_FLG_SYS_ACTIVE | OS_FLG_EXC_ACTIVE | OS_FLG_FIBER_ACTIVE) +#include "function_safety_common.h" -#define OS_INT_ACTIVE ((UNI_FLAG & OS_INT_ACTIVE_MASK) != 0) -#define OS_INT_INACTIVE (!(OS_INT_ACTIVE)) -#define OS_THREAD_FLAG_MASK (OS_FLG_BGD_ACTIVE | OS_INT_ACTIVE_MASK) +typedef struct { + BackupFunc contexBackupFunc; + ConfigFunc handleConfigFunc; + DiagnoseFunc diagnoseFunc; + FailSafeFunc failSafeFunc; + FaultPredictFunc faultPredictFunc; + ResumeFunc contexResumeFunc; + void* contexHandle; + void* diagnoseHandle; + void* failSafeHandle; + void* faultPredictHandle; + DiagnoseMoment moment; +} FunctionSafetyProcessHandle; -/* 有TICK情况下CPU占用率触发函数类型定义。 */ -typedef void (*TickEntryFunc)(void); -typedef void (*TaskScanFunc)(void); +typedef struct { + bool timeCycleRecordSwitch; + unsigned int diagnoseTimeCycle; + unsigned int failSafeTimeCycle; + unsigned int faultPredictTimeCycle; +} ProcessTimeCycle; -/* - * 模块间全局变量声明 - */ -extern unsigned int g_threadNum; -extern unsigned int g_tickNoRespondCnt; -#define TICK_NO_RESPOND_CNT g_tickNoRespondCnt +FunctionSafetyState FunctionSafetyProcess(void* processHandle, ProcessTimeCycle* processTime); -extern unsigned long long g_uniTicks; -/* Tick计数补偿值 */ -extern TaskScanFunc g_taskScanHook; -extern OsVoidFunc g_idleEntry; -extern unsigned int g_uniFlag; -#define UNI_FLAG g_uniFlag - -typedef unsigned long long (*GetTickFunc)(void); - -void NOS_SetNosParam(GetTickFunc func); -unsigned long long NOS_GetCurTick(void); - -#endif /* NOS_SYS_EXTERNAL_H */ +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/loaderboot/loader_3061m.bin b/src/middleware/hisilicon/loaderboot/loader_3061m.bin deleted file mode 100644 index 938ebc856ef4e1fa243b35e575a8696df1d90f3f..0000000000000000000000000000000000000000 Binary files a/src/middleware/hisilicon/loaderboot/loader_3061m.bin and /dev/null differ diff --git a/src/middleware/hisilicon/loaderboot/loader_3065h.bin b/src/middleware/hisilicon/loaderboot/loader_3065h.bin index 48314a7a20ccb468fbcfe52b943847785e90e128..964da2449f60e01311fcc87055c06743a82f8486 100644 Binary files a/src/middleware/hisilicon/loaderboot/loader_3065h.bin and b/src/middleware/hisilicon/loaderboot/loader_3065h.bin differ diff --git a/src/middleware/hisilicon/nostask/arch/include/os_asm_cpu_riscv_external.h b/src/middleware/hisilicon/nostask/arch/include/os_asm_cpu_riscv_external.h deleted file mode 100644 index d2de50f11df824749362e34f661156d4af548f1d..0000000000000000000000000000000000000000 --- a/src/middleware/hisilicon/nostask/arch/include/os_asm_cpu_riscv_external.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder 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 HOLDER 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. - * @file os_asm_cpu_riscv_external.h - */ -#ifndef OS_ASM_CPU_RISCV_EXTERNAL_H -#define OS_ASM_CPU_RISCV_EXTERNAL_H - -#define OS_FLG_TSK_REQ 0x1000U -#define OS_FLG_BGD_ACTIVE 0x0002U -#define OS_FLG_HWI_ACTIVE 0x0001U -#define OS_FLG_SWI_ACTIVE 0x0004U -#define OS_FLG_TICK_ACTIVE 0x0008U -#define OS_FLG_SYS_ACTIVE 0x0010U -#define OS_FLG_EXC_ACTIVE 0x0020U -#define OS_FLG_FIBER_ACTIVE 0x40000U /* 纤程激活 */ - -#define REG_OFF_RA 0 -#define REG_OFF_GP (REG_OFF_RA + 4) // 4 -#define REG_OFF_TP (REG_OFF_GP + 4) // 8 -#define REG_OFF_T0 (REG_OFF_TP + 4) // 12 -#define REG_OFF_T1 (REG_OFF_T0 + 4) // 16 -#define REG_OFF_T2 (REG_OFF_T1 + 4) // 20 -#define REG_OFF_T3 (REG_OFF_T2 + 4) // 24 -#define REG_OFF_T4 (REG_OFF_T3 + 4) // 28 -#define REG_OFF_T5 (REG_OFF_T4 + 4) // 32 -#define REG_OFF_T6 (REG_OFF_T5 + 4) // 36 -#define REG_OFF_A0 (REG_OFF_T6 + 4) // 40 -#define REG_OFF_A1 (REG_OFF_A0 + 4) // 44 -#define REG_OFF_A2 (REG_OFF_A1 + 4) // 48 -#define REG_OFF_A3 (REG_OFF_A2 + 4) // 52 -#define REG_OFF_A4 (REG_OFF_A3 + 4) // 56 -#define REG_OFF_A5 (REG_OFF_A4 + 4) // 60 -#define REG_OFF_A6 (REG_OFF_A5 + 4) // 64 -#define REG_OFF_A7 (REG_OFF_A6 + 4) // 68 -#define REG_OFF_MEPC (REG_OFF_A7 + 4) // 72 -#define REG_OFF_MSTATUS (REG_OFF_MEPC + 4) // 76 - -#define CALLER_REG_SIZE (REG_OFF_MSTATUS + 4) // 80 - -#define REG_OFF_S0 0 -#define REG_OFF_S1 (REG_OFF_S0 + 4) // 4 -#define REG_OFF_S2 (REG_OFF_S1 + 4) // 8 -#define REG_OFF_S3 (REG_OFF_S2 + 4) // 12 -#define REG_OFF_S4 (REG_OFF_S3 + 4) // 16 -#define REG_OFF_S5 (REG_OFF_S4 + 4) // 20 -#define REG_OFF_S6 (REG_OFF_S5 + 4) // 24 -#define REG_OFF_S7 (REG_OFF_S6 + 4) // 28 -#define REG_OFF_S8 (REG_OFF_S7 + 4) // 32 -#define REG_OFF_S9 (REG_OFF_S8 + 4) // 36 -#define REG_OFF_S10 (REG_OFF_S9 + 4) // 40 -#define REG_OFF_S11 (REG_OFF_S10 + 4) // 44 - -#define CALLEE_REG_SIZE (REG_OFF_S11 + 4) // 48 - -#define MCAUSE_ECALL 11 -#define MCAUSE_EXC_MASK 0x7fffffffU - -#endif /* OS_ASM_CPU_RISCV_EXTERNAL_H */ diff --git a/src/middleware/hisilicon/nostask/arch/nos_dispatch.S b/src/middleware/hisilicon/nostask/arch/nos_dispatch.S deleted file mode 100644 index 01d2e0173e0dfef50932607177fa63b6502d6820..0000000000000000000000000000000000000000 --- a/src/middleware/hisilicon/nostask/arch/nos_dispatch.S +++ /dev/null @@ -1,319 +0,0 @@ -/** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder 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 HOLDER 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. - * @file nos_dispatch.S - */ - -#include "os_asm_cpu_riscv_external.h" -#include "nos_buildef.h" -#include "nos_306x_adapter.h" - -#ifdef __riscv64 -#define LREG ld -#define SREG sd -#define FLREG fld -#define FSREG fsd -#define REGBYTES 8 -#else -#define LREG lw -#define SREG sw -#define FLREG flw -#define FSREG fsw -#define REGBYTES 4 -#endif - -#define MSTATUS_MIE 0x00000008 -#define MSTATUS_MPIE 0x00000080 -#define MSTATUS_MPP_M_MODE (3U << 11) -#ifdef OS_OPTION_FPU -#define TOTAL_INT_SIZE_ON_STACK (44 * REGBYTES) -#else -#define TOTAL_INT_SIZE_ON_STACK (24 * REGBYTES) -#endif - - .global OsTskContextLoad - .global OsTaskSwitch - .global NOS_IntUnLock - .global NOS_IntLock - .global NOS_IntRestore - .global OsTaskTrueSwitch - .global OsHwiPostHandle - .global NOS_SystickLock - .global NOS_SystickRestore - - .type OsTskContextLoad, function - .type OsTaskSwitch, function - .type NOS_IntUnLock, function - .type NOS_IntLock, function - .type NOS_IntRestore, function - .type OsTaskTrueSwitch, function - .type OsHwiPostHandle,function - .type NOS_SystickLock, function - .type NOS_SystickRestore, function - - .align 2 - -OsHwiPostHandle: - lw a0, g_uniFlag - li a1, OS_FLG_TSK_REQ - and a0, a0, a1 - beqz a0, OsTskNaroContextLoad - - addi sp, sp, -CALLEE_REG_SIZE - /* Need reschedule, save callee-save registers */ - sw s0, REG_OFF_S0(sp) - sw s1, REG_OFF_S1(sp) - sw s2, REG_OFF_S2(sp) - sw s3, REG_OFF_S3(sp) - sw s4, REG_OFF_S4(sp) - sw s5, REG_OFF_S5(sp) - sw s6, REG_OFF_S6(sp) - sw s7, REG_OFF_S7(sp) - sw s8, REG_OFF_S8(sp) - sw s9, REG_OFF_S9(sp) - sw s10, REG_OFF_S10(sp) - sw s11, REG_OFF_S11(sp) -#ifdef OS_OPTION_FPU - addi sp, sp, -CALLEE_REG_SIZE - FSREG fs0, REG_OFF_S0(sp) - FSREG fs1, REG_OFF_S1(sp) - FSREG fs2, REG_OFF_S2(sp) - FSREG fs3, REG_OFF_S3(sp) - FSREG fs4, REG_OFF_S4(sp) - FSREG fs5, REG_OFF_S5(sp) - FSREG fs6, REG_OFF_S6(sp) - FSREG fs7, REG_OFF_S7(sp) - FSREG fs8, REG_OFF_S8(sp) - FSREG fs9, REG_OFF_S9(sp) - FSREG fs10, REG_OFF_S10(sp) - FSREG fs11, REG_OFF_S11(sp) -#endif - lw a0, g_runningTask - sw sp, 0(a0) - - tail OsMainSchedule - - -OsTaskTrueSwitch: - addi sp, sp, -(TOTAL_INT_SIZE_ON_STACK) - SREG a0, 3 * REGBYTES(sp) - SREG a1, 4 * REGBYTES(sp) - csrr a0, CIPRI - csrr a1, PRITHD - csrw PRITHD, a0 /* read prithd */ - SREG a1, 6 * REGBYTES(sp) /* save prithd */ - csrr a1, mstatus /* read mstatus */ - SREG a1, 7 * REGBYTES(sp) /* save mstatus */ - csrr a1, mepc /* read mepc */ - addi a1, a1, 4 - SREG a1, 8 * REGBYTES(sp) /* save mepc */ - li a1, MSTATUS_MPP_M_MODE - csrs mstatus, a1 - -OsTaskTrueSwitchPhase2: - SREG t0, 0 * REGBYTES(sp) - SREG t1, 1 * REGBYTES(sp) - SREG t2, 2 * REGBYTES(sp) - SREG a2, 5 * REGBYTES(sp) - SREG ra, 9 * REGBYTES(sp) - SREG a3, 10 * REGBYTES(sp) - SREG a4, 11 * REGBYTES(sp) - SREG a5, 12 * REGBYTES(sp) - SREG a6, 13 * REGBYTES(sp) - SREG a7, 14 * REGBYTES(sp) - SREG t3, 15 * REGBYTES(sp) - SREG t4, 16 * REGBYTES(sp) - SREG t5, 17 * REGBYTES(sp) - SREG t6, 18 * REGBYTES(sp) - csrr a0, TICK_IRQ_EN_BASE - andi a0, a0, TICK_IRQ_EN_NUM - SREG a0, 19 * REGBYTES(sp) - -#ifdef OS_OPTION_FPU - FSREG f0, 23 * REGBYTES(sp) - FSREG f1, 24 * REGBYTES(sp) - FSREG f2, 25 * REGBYTES(sp) - FSREG f3, 26 * REGBYTES(sp) - FSREG f4, 27 * REGBYTES(sp) - FSREG f5, 28 * REGBYTES(sp) - FSREG f6, 29 * REGBYTES(sp) - FSREG f7, 30 * REGBYTES(sp) - FSREG f10, 31 * REGBYTES(sp) - FSREG f11, 32 * REGBYTES(sp) - FSREG f12, 33 * REGBYTES(sp) - FSREG f13, 34 * REGBYTES(sp) - FSREG f14, 35 * REGBYTES(sp) - FSREG f15, 36 * REGBYTES(sp) - FSREG f16, 37 * REGBYTES(sp) - FSREG f17, 38 * REGBYTES(sp) - FSREG f28, 39 * REGBYTES(sp) - FSREG f29, 40 * REGBYTES(sp) - FSREG f30, 41 * REGBYTES(sp) - FSREG f31, 42 * REGBYTES(sp) - frcsr t0 - SREG t0, 43 * REGBYTES(sp) -#endif - - addi sp, sp, -CALLEE_REG_SIZE - sw s0, REG_OFF_S0(sp) - sw s1, REG_OFF_S1(sp) - sw s2, REG_OFF_S2(sp) - sw s3, REG_OFF_S3(sp) - sw s4, REG_OFF_S4(sp) - sw s5, REG_OFF_S5(sp) - sw s6, REG_OFF_S6(sp) - sw s7, REG_OFF_S7(sp) - sw s8, REG_OFF_S8(sp) - sw s9, REG_OFF_S9(sp) - sw s10, REG_OFF_S10(sp) - sw s11, REG_OFF_S11(sp) -#ifdef OS_OPTION_FPU - addi sp, sp, -CALLEE_REG_SIZE - FSREG fs0, REG_OFF_S0(sp) - FSREG fs1, REG_OFF_S1(sp) - FSREG fs2, REG_OFF_S2(sp) - FSREG fs3, REG_OFF_S3(sp) - FSREG fs4, REG_OFF_S4(sp) - FSREG fs5, REG_OFF_S5(sp) - FSREG fs6, REG_OFF_S6(sp) - FSREG fs7, REG_OFF_S7(sp) - FSREG fs8, REG_OFF_S8(sp) - FSREG fs9, REG_OFF_S9(sp) - FSREG fs10, REG_OFF_S10(sp) - FSREG fs11, REG_OFF_S11(sp) -#endif - lw a0, g_runningTask - sw sp, 0(a0) - tail OsMainSchedule - -OsTaskSwitch: - li a0, NOS_TASK_SWITCH_MAGIC_NUM - ecall - ret - -OsTskContextLoad: - lw sp, 0(a0) -#ifdef OS_OPTION_FPU - FLREG fs0, REG_OFF_S0(sp) - FLREG fs1, REG_OFF_S1(sp) - FLREG fs2, REG_OFF_S2(sp) - FLREG fs3, REG_OFF_S3(sp) - FLREG fs4, REG_OFF_S4(sp) - FLREG fs5, REG_OFF_S5(sp) - FLREG fs6, REG_OFF_S6(sp) - FLREG fs7, REG_OFF_S7(sp) - FLREG fs8, REG_OFF_S8(sp) - FLREG fs9, REG_OFF_S9(sp) - FLREG fs10, REG_OFF_S10(sp) - FLREG fs11, REG_OFF_S11(sp) - addi sp, sp, CALLEE_REG_SIZE -#endif - - lw s0, REG_OFF_S0(sp) - lw s1, REG_OFF_S1(sp) - lw s2, REG_OFF_S2(sp) - lw s3, REG_OFF_S3(sp) - lw s4, REG_OFF_S4(sp) - lw s5, REG_OFF_S5(sp) - lw s6, REG_OFF_S6(sp) - lw s7, REG_OFF_S7(sp) - lw s8, REG_OFF_S8(sp) - lw s9, REG_OFF_S9(sp) - lw s10, REG_OFF_S10(sp) - lw s11, REG_OFF_S11(sp) - addi sp, sp, CALLEE_REG_SIZE - - -OsTskNaroContextLoad: - LREG t1, 1 * REGBYTES(sp) - LREG t2, 2 * REGBYTES(sp) - LREG a2, 5 * REGBYTES(sp) - LREG ra, 9 * REGBYTES(sp) - LREG a3, 10 * REGBYTES(sp) - LREG a4, 11 * REGBYTES(sp) - LREG a5, 12 * REGBYTES(sp) - LREG a6, 13 * REGBYTES(sp) - LREG a7, 14 * REGBYTES(sp) - LREG t3, 15 * REGBYTES(sp) - LREG t4, 16 * REGBYTES(sp) - LREG t5, 17 * REGBYTES(sp) - LREG t6, 18 * REGBYTES(sp) - -#ifdef OS_OPTION_FPU - FLREG f0, 23 * REGBYTES(sp) - FLREG f1, 24 * REGBYTES(sp) - FLREG f2, 25 * REGBYTES(sp) - FLREG f3, 26 * REGBYTES(sp) - FLREG f4, 27 * REGBYTES(sp) - FLREG f5, 28 * REGBYTES(sp) - FLREG f6, 29 * REGBYTES(sp) - FLREG f7, 30 * REGBYTES(sp) - FLREG f10, 31 * REGBYTES(sp) - FLREG f11, 32 * REGBYTES(sp) - FLREG f12, 33 * REGBYTES(sp) - FLREG f13, 34 * REGBYTES(sp) - FLREG f14, 35 * REGBYTES(sp) - FLREG f15, 36 * REGBYTES(sp) - FLREG f16, 37 * REGBYTES(sp) - FLREG f17, 38 * REGBYTES(sp) - FLREG f28, 39 * REGBYTES(sp) - FLREG f29, 40 * REGBYTES(sp) - FLREG f30, 41 * REGBYTES(sp) - FLREG f31, 42 * REGBYTES(sp) - LREG t0, 43 * REGBYTES(sp) - fscsr t0 -#endif - - LREG a0, 7 * REGBYTES(sp) /* load mstatus */ - LREG a1, 8 * REGBYTES(sp) /* load mepc */ -restore_mstatus: - csrw mstatus, a0 // close Global MIE - LREG t0, 19 * REGBYTES(sp) - andi t0, t0, TICK_IRQ_EN_NUM - csrs TICK_IRQ_EN_BASE, t0 - -restore_mepc: - LREG t0, 0 * REGBYTES(sp) - csrw mepc, a1 - LREG a0, 6 * REGBYTES(sp) /* load prithd */ - csrw PRITHD, a0 - LREG a1, 4 * REGBYTES(sp) /* 2 consecutive csrw instructions will have a bubble */ - LREG a0, 3 * REGBYTES(sp) - addi sp, sp, TOTAL_INT_SIZE_ON_STACK - mret - -NOS_IntUnLock: - csrrsi a0, mstatus, MSTATUS_MIE - ret - -NOS_IntLock: - csrrci a0, mstatus, MSTATUS_MIE - ret - -NOS_IntRestore: - andi a0, a0, MSTATUS_MIE - csrs mstatus, a0 - ret - -NOS_SystickLock: - csrrci a0, TICK_IRQ_EN_BASE, TICK_IRQ_EN_NUM - ret - -NOS_SystickRestore: - andi a0, a0, TICK_IRQ_EN_NUM - csrs TICK_IRQ_EN_BASE, a0 - ret \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/include/common/os_cpu_riscv.h b/src/middleware/hisilicon/nostask/include/common/os_cpu_riscv.h deleted file mode 100644 index d225f39f29824a0f6f31b0bbd6858e3d42013e58..0000000000000000000000000000000000000000 --- a/src/middleware/hisilicon/nostask/include/common/os_cpu_riscv.h +++ /dev/null @@ -1,191 +0,0 @@ -/** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder 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 HOLDER 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. - * @file os_cpu_riscv.h - */ - -#ifndef OS_CPU_RISCV_H -#define OS_CPU_RISCV_H - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -/* - * @ingroup NOS_task - * 任务上下文的结构体定义。 - */ -struct TskContext { - unsigned int fs0; - unsigned int fs1; - unsigned int fs2; - unsigned int fs3; - unsigned int fs4; - unsigned int fs5; - unsigned int fs6; - unsigned int fs7; - unsigned int fs8; - unsigned int fs9; - unsigned int fs10; - unsigned int fs11; - unsigned int s0; - unsigned int s1; - unsigned int s2; - unsigned int s3; - unsigned int s4; - unsigned int s5; - unsigned int s6; - unsigned int s7; - unsigned int s8; - unsigned int s9; - unsigned int s10; - unsigned int s11; - unsigned int t0; - unsigned int t1; - unsigned int t2; - unsigned int a0; - unsigned int a1; - unsigned int a2; - unsigned int prithd; - unsigned int mstatus; - unsigned int mepc; - unsigned int ra; - unsigned int a3; - unsigned int a4; - unsigned int a5; - unsigned int a6; - unsigned int a7; - unsigned int t3; - unsigned int t4; - unsigned int t5; - unsigned int t6; - unsigned int tickIntNum; - unsigned int rsvd[3]; - unsigned int f0; - unsigned int f1; - unsigned int f2; - unsigned int f3; - unsigned int f4; - unsigned int f5; - unsigned int f6; - unsigned int f7; - unsigned int f10; - unsigned int f11; - unsigned int f12; - unsigned int f13; - unsigned int f14; - unsigned int f15; - unsigned int f16; - unsigned int f17; - unsigned int f28; - unsigned int f29; - unsigned int f30; - unsigned int f31; - unsigned int fcsr; -}; - -/* - * @ingroup NOS_sys - * Description: 获取当前核ID。 - * - * @par 描述 - * 获取当前核ID。 - * - * @attention - *
    - *
  • 获取的核ID为硬件寄存器中的ID号。
  • - *
- * - * @param 无 - * - * @retval 物理核ID。 - * @par 依赖 - * @see NOS_GetNumberOfCores | NOS_GetPrimaryCore - */ -INLINE unsigned int NOS_GetCoreID(void) -{ - return 0; -} - -/* - * @ingroup NOS_sys - * Description: 开中断。 - * - * @par 描述 - * 开启全局可屏蔽中断。 - * - * @attention - *
  • 中断服务函数里慎用该接口,会引起中断优先级反转。
- * - * @param 无 - * - * @retval 开启全局中断前的中断状态值。 - * @par 依赖 - * @see NOS_IntLock | NOS_IntRestore - */ -extern uintptr_t NOS_IntUnLock(void); - -/* - * @ingroup NOS_sys - * Description: 关中断。 - * - * @par 描述 - * 关闭全局可屏蔽中断。 - * - * @attention - *
  • 在关全局中断后,禁止调用引起内核调度的相关接口,如NOS_TaskDelayInner接口。
- * - * @param 无 - * - * @retval 关闭全局中断前的中断状态值。 - * @par 依赖 - * @see NOS_IntUnLock | NOS_IntRestore - */ -extern uintptr_t NOS_IntLock(void); - -/* - * @ingroup NOS_sys - * Description: 恢复中断状态接口。 - * - * @par 描述 - * 恢复原中断状态寄存器。 - * - * @attention - *
    - *
  • 该接口必须和关闭全局中断或者是开启全局中断接口成对使用,以关全局中断或者开全局中断操作的返回值为入参
  • - *
  • 以保证中断可以恢复到关全局中断或者开全局中断操作前的状态
  • - *
- * @param intSave [IN]类型#UINTPTR,关全局中断NOS_IntLock和开全局中断NOS_IntUnLock的返回值。 - * - * @retval 无 - * @par 依赖 - * @see NOS_IntUnLock | NOS_IntLock - */ -extern void NOS_IntRestore(uintptr_t intSave); - -extern unsigned int NOS_SystickLock(void); -extern void NOS_SystickRestore(unsigned int intSave); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* OS_CPU_RISCV_H */ diff --git a/src/middleware/hisilicon/nostask/include/common/os_sys.h b/src/middleware/hisilicon/nostask/include/common/os_sys.h deleted file mode 100644 index fd16ddd05c667c80dd259f861c0f7bae429026ef..0000000000000000000000000000000000000000 --- a/src/middleware/hisilicon/nostask/include/common/os_sys.h +++ /dev/null @@ -1,412 +0,0 @@ -/** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder 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 HOLDER 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. - * @file os_sys.h - */ -#ifndef OS_SYS_H -#define OS_SYS_H - -#include "os_errno.h" -#include "os_module.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -/* - * @ingroup OS_sys - * 系统基本功能错误码:指针参数为空。 - * - * 值: 0x02000001 - * - * 解决方案: 请检查入参是否为空 - */ -#define OS_ERRNO_SYS_PTR_NULL OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x01) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:系统主频配置非法。 - * - * 值: 0x02000002 - * - * 解决方案: 在nos_config.h中配置合理的系统主频。 - */ -#define OS_ERRNO_SYS_CLOCK_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x02) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:用户的配置选项OS_SYS_CORE_MAX_NUM有误, - * 应该和芯片匹配,且OS_SYS_CORE_MAX_NUM值不能超过该芯片支持的最大核数。 - * - * 值: 0x02000003 - * - * 解决方案:修改配置选项OS_SYS_CORE_MAX_NUM,和芯片匹配。 - * - */ -#define OS_ERRNO_SYS_MAXNUMOFCORES_IS_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x03) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:配置的运行核数非法。 - * - * 值: 0x02000004 - * - * 解决方案:配置的运行核数必须小于配置的芯片最大核数,且不能为0. - * - */ -#define OS_ERRNO_SYS_CORE_RUNNUM_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x04) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:获取系统时间函数Cortex-AX平台配置为NULL。 - * - * 值: 0x02000006 - * - * 解决方案:配置获取系统时间函数时,Cortex-AX平台必须配置为非NULL。 - * - */ -#define OS_ERRNO_SYS_TIME_HOOK_NULL OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x06) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:镜像的个数配置错误。 - * - * 值: 0x02000007 - * - * 解决方案: 查看每个镜像配置的镜像个数是否不相等或者镜像个数为0或者大于最大镜像个数。 - * - */ -#define OS_ERRNO_SYS_IMAGE_NUM_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x07) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:镜像的镜像ID配置不可用。 - * - * 值: 0x02000008 - * - * 解决方案: 查看每个镜像配置的镜像ID是否有重复或者配置值错误。镜像ID值不能大于等于镜像个数。 - * - */ -#define OS_ERRNO_SYS_IMAGE_ID_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x08) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:用户的配置选项OS_SYS_CORE_MAX_NUM有误, - * 应该和芯片匹配,且OS_SYS_CORE_MAX_NUM值不能超过该芯片支持的最大核数。 - * - * 值: 0x02000009 - * - * 解决方案:修改配置选项OS_SYS_CORE_MAX_NUM,和芯片匹配。 - * - */ -#define OS_ERRNO_SYS_CORERUNNUM_IS_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x09) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:依赖的模块功能宏没有打开。 - * - * 值: 0x0200000a - * - * 解决方案:请打开相应的模块的功能宏。 - * - */ -#define OS_ERRNO_SYS_MODE_CLOSE OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x0a) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:配置的系统栈过小。 - * - * 值: 0x0200000b - * - * 解决方案:请增大配置的系统栈大小。 - * - */ -#define OS_ERRNO_SYS_STACK_SIZE_NOT_ENOUGH OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x0b) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:tskmon模块功能宏依赖的任务模块功能未打开。 - * - * 值: 0x0200000c - * - * 解决方案:检查依赖的任务模块裁剪开关是否打开。 - * - */ -#define OS_ERRNO_SYS_TASK_CLOSE OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x0c) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:任务饿死撑死功能控依赖的功能tskmon模块未打开。 - * - * 值: 0x0200000d - * - * 解决方案:检查依赖的tskmon模块裁剪开关是否打开。 - * - */ -#define OS_ERRNO_SYS_TASKMON_CLOSE OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x0d) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:任务监功能控依赖的功能TICK未打开。 - * - * 值: 0x0200000e - * - * 解决方案:检查依赖的TICK裁剪开关是否打开。 - * - */ -#define OS_ERRNO_SYS_TICK_CLOSE OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x0e) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:配置的系统模式不正确。 - * - * 值: 0x0200000f - * - * 解决方案:系统模式必须为super模式或者user模式。 - * - */ -#define OS_ERRNO_SYS_MODE_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x0f) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:CPUP告警被裁减 - * - * 值: 0x02000011 - * - * 解决方案:排除config项是否正确,该平台不支持CPUP告警 - * - */ -#define OS_ERRNO_SYS_NO_CPUP_WARN OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x11) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:获取或清除对应核初始化阶段状态时,核号错误。 - * - * 值: 0x02000013 - * - * 解决方案:确保入参核号不能大于等于OS_MAX_CORE_NUM。 - * - */ -#define OS_ERRNO_SYS_COREID_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x13) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:软中断模块已经被裁减。 - * - * 值: 0x0200001c - * - * 解决方案:排除config项是否正确,该平台不支持软中断,必须将配置项OS_TASK_INCLUDE配置为YES。 - * - */ -#define OS_ERRNO_SYS_NO_SWI OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x1c) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:init trace模块名字空间对象申请失败。 - * - * 值: 0x0200001d - * - * 解决方案:扩大名字空间大小。 - * - */ -#define OS_ERRNO_SYS_INIT_TRACE_NAME_ALLOC_FAIL OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x1d) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:获取系统栈信息时指定的出参结构体为空。 - * - * 值: 0x02000023 - * - * 解决方案: 检查获取系统栈时传入的结构体是否为空。 - */ -#define OS_ERRNO_SYS_STACKINFO_PTR_NULL OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x23) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:获取当前系统实例ID时的保存参数指针为空。 - * - * 值: 0x02000024 - * - * 解决方案: 请确保传入的用户存放实例ID的地址不为空。 - */ -#define OS_ERRNO_SYS_INST_ID_ADDR_NULL OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x24) - -/* - * @ingroup OS_sys - * init trace的地址为NULL - * - * 值: 0x02000025 - * - * 解决方案:可能是使用过早,建议在触发后使用。 - * - */ -#define OS_ERRNO_SYS_TRACE_ADDR_NULL OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x25) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:设置RND值的时候入参非法。 - * - * 值: 0x02000026 - * - * 解决方案: 请确保设置RND值时入参合法。 - */ -#define OS_ERRNO_SYS_RND_PARA_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x26) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:注册获取系统时间函数重复注册了 - * - * 值: 0x02000027 - * - * 解决方案:获取系统时间函数不允许重复注册 - * - */ -#define OS_ERRNO_SYS_TIME_HOOK_REGISTER_REPEATED OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x27) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:内存分区过小。 - * - * 值: 0x02000028 - * - * 解决方案: 请确保分区待截取的size小于分区大小。 - */ -#define OS_ERRNO_SYS_RND_OVERFLOW_PTSIZE OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x28) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:自检小版本Idle激活失败。 - * - * 值: 0x02000029 - * - * 解决方案: 请确保Idle钩子注册。 - */ -#define OS_ERRNO_SYS_IDLE_ACTIVE_FAILED OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x29) - -/* - * @ingroup OS_sys - * 系统基本功能错误码:配置的中断个数不正确 - * - * 值: 0x0200002a - * - * 解决方案: 检查配置的中断个数是否为0或者超过了硬件范围 - */ -#define OS_ERRNO_SYS_HWI_MAX_NUM_CONFIG_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_SYS, 0x2a) - -/* - * 系统初始化阶段状态 - */ -/* - * @ingroup OS_sys - * 表示初始态。 - * - */ -#define OS_DEFAULT_PHASE 0x00 - -/* - * @ingroup OS_sys - * 表示主核处于实模式启动阶段状态(该阶段主要完成MMU使能初始化),仅SD6183平台有效。 - * - */ -#define OS_MCORE_PHY_BOOT_PHASE 0x01 - -/* - * @ingroup OS_sys - * 表示主核处于虚模式启动阶段状态,仅SD6183平台有效。 - * - */ -#define OS_MCORE_VIR_BOOT_PHASE 0x02 - -/* - * @ingroup OS_sys - * 表示进入NOS_HardBootInit。 - * - */ -#define OS_BOOT_PHASE 0x03 - -/* - * @ingroup OS_sys - * 表示开始多实例启动参数配置。 - * - */ -#define OS_STARTPARAMCFG_PHASE 0x04 - -/* - * @ingroup OS_sys - * 表示退出NOS_HardBootInit。 - * - */ -#define OS_AFTER_BOOT_PHASE 0x05 - -/* - * @ingroup OS_sys - * 表示进入BSS段初始化。 - * - */ -#define OS_BSSINIT_PHASE 0x06 - -/* - * @ingroup OS_sys - * 表示Dcache初始化完毕,SD6183平台由于在reset中已经完成,故不支持该阶段状态。 - * - */ -#define OS_DCACHEINIT_PHASE 0x07 - -/* - * @ingroup OS_sys - * 表示进入C lib库初始化。 - * - */ -#define OS_LIBCINIT_PHASE 0x08 - -/* - * @ingroup OS_sys - * 表示系统在进行OS模块注册阶段,匹配MOUDLE_ID之后,标记进入MODULE_ID的注册。 - * - */ -#define OS_REGISTER_PHASE 0x09 - -/* - * @ingroup OS_sys - * 表示系统在进行OS模块初始化阶段,匹配MOUDLE_ID之后,标记进入MODULE_ID的初始化。 - * - */ -#define OS_INITIALIZE_PHASE 0x0a - -/* - * @ingroup OS_sys - * 表示系统在进行产品驱动初始化阶段,匹配MOUDLE_ID之后,标记进入MODULE_ID的初始化。 - * - */ -#define OS_DEVDRVINIT_PHASE 0x0b - -/* - * @ingroup OS_sys - * 表示系统在进行OS启动阶段,匹配MOUDLE_ID之后,标记进入MODULE_ID的启动。 - * - */ -#define OS_START_PHASE 0x0c - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* OS_SYS_H */ diff --git a/src/middleware/hisilicon/nostask/include/common/os_task.h b/src/middleware/hisilicon/nostask/include/common/os_task.h deleted file mode 100644 index ca05d971e07b97e382ffee9f324a0999f36f8f2f..0000000000000000000000000000000000000000 --- a/src/middleware/hisilicon/nostask/include/common/os_task.h +++ /dev/null @@ -1,1454 +0,0 @@ -/** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder 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 HOLDER 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. - * @file os_task.h - */ -#ifndef OS_TASK_H -#define OS_TASK_H - -#include "nos_buildef.h" -#include "os_typedef.h" -#include "os_cpu_riscv.h" -#include "os_errno.h" -#include "os_module.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -/* - * @ingroup OS_task - * 任务名的最大长度。 - * - * 任务名的最大长度,包括结尾符'\0'。 - */ -#define OS_TSK_NAME_LEN 16 - -/* - * @ingroup OS_task - * RX、HiTSP支持的优先级为(0~63),其他平台芯片支持的优先级(0~31),OS系统IDLE线程使用最低优先级(63或31),用户不能使用。 - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_00 0 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_01 1 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_02 2 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_03 3 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_04 4 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_05 5 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_06 6 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_07 7 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_08 8 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_09 9 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_10 10 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_11 11 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_12 12 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_13 13 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_14 14 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_15 15 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_16 16 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_17 17 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_18 18 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_19 19 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_20 20 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_21 21 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_22 22 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_23 23 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_24 24 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_25 25 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_26 26 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_27 27 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_28 28 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_29 29 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_30 30 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_31 31 - -/* - * @ingroup OS_task - * Cortex-AX支持的优先级为(0~63),下面优先级是32~63。 - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_32 32 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_33 33 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_34 34 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_35 35 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_36 36 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_37 37 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_38 38 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_39 39 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_40 40 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_41 41 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_42 42 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_43 43 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_44 44 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_45 45 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_46 46 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_47 47 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_48 48 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_49 49 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_50 50 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_51 51 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_52 52 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_53 53 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_54 54 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_55 55 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_56 56 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_57 57 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_58 58 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_59 59 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_60 60 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_61 61 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_62 62 - -/* - * @ingroup OS_task - * 可用的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_63 63 - -/* - * @ingroup OS_task - * 默认的任务优先级宏定义。 - * - */ -#define OS_TSK_PRIORITY_DEF 32 - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务控制块未被使用。 - */ -#define OS_TSK_UNUSED 0x0000U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务控制块被使用,任务被创建。 - */ -#define OS_TSK_INUSE 0x0001U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务被阻塞(等待VOS消息或事件) - */ -#define OS_TSK_VOS_PEND 0x0002U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务被挂起。 - */ -#define OS_TSK_SUSPEND 0x0004U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务被阻塞(等待信号量)。 - */ -#define OS_TSK_PEND 0x0008U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务在等待信号量或者事件的标志。 - */ -#define OS_TSK_TIMEOUT 0x0010U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务被延时。 - */ -#define OS_TSK_DELAY 0x0020U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务已就绪,已加入就绪队列。 - */ -#define OS_TSK_READY 0x0040U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务正运行,仍在就绪队列。 - */ -#define OS_TSK_RUNNING 0x0080 - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务被阻塞(等待快速信号量)。 - */ -#define OS_TSK_FSEM_PEND 0x0100U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务被阻塞(等待消息)。 - */ -#define OS_TSK_MSG_PEND 0x0200U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务被阻塞(等待核间信号量)。 - */ -#define OS_TSK_MCSEM_PEND 0x0400U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * OS_TSK_EVENT_PEND --- 任务阻塞于等待读事件。 - */ -#define OS_TSK_EVENT_PEND 0x0800U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * OS_TSK_EVENT_TYPE --- 任务读事件类型,0:ANY; 1:ALL。 - */ -#define OS_TSK_EVENT_TYPE 0x1000U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * OS_TSK_QUEUE_PEND --- 任务阻塞与等待队列。 - */ -#define OS_TSK_QUEUE_PEND 0x2000U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * OS_TSK_QUEUE_BUSY --- 队列正在读写数据。 - */ -#define OS_TSK_QUEUE_BUSY 0x4000U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * OS_TSK_DELETING --- 任务正在被删除。 - */ -#define OS_TSK_DELETING 0x8000U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务使用coprocessor的矢量寄存器现场已保存 - * 注意第16位已被用作82的矢量寄存器保存标志 - */ -#define OS_CP_CONTEXT_SAVED 0x10000U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * OS_TSK_CRG_IDLE_SUSPEND --- CRG执行队列空闲自动挂起。 - */ -#define OS_TSK_CRG_IDLE_SUSPEND 0x20000U - -/* - * @ingroup OS_task - * 任务或任务控制块状态标志。 - * - * 任务被延时。 - */ -#define OS_TSK_PERIOD 0x40000U - -/* - * 任务模块的错误码定义。 - */ -/* - * @ingroup OS_task - * 任务错误码:申请内存失败。 - * - * 值: 0x02000800 - * - * 解决方案: 分配更大的私有FSC内存分区 - * - */ -#define OS_ERRNO_TSK_NO_MEMORY OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x00) - -/* - * @ingroup OS_task - * 任务错误码:指针参数为空。 - * - * 值: 0x02000801 - * - * 解决方案: 检查参数指针是否为NUL。 - */ -#define OS_ERRNO_TSK_PTR_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x01) - -/* - * @ingroup OS_task - * 任务错误码:任务栈大小未按16字节大小对齐。 - * - * 值: 0x02000802 - * - * 解决方案: 检查入参任务栈大小是否按16字节对齐。 - */ -#define OS_ERRNO_TSK_STKSZ_NOT_ALIGN OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x02) - -/* - * @ingroup OS_task - * 任务错误码:任务优先级非法。 - * - * 值: 0x02000803 - * - * 解决方案: 检查入参任务优先级Balong平台不能大于63,其他平台不能大于31。 - */ -#define OS_ERRNO_TSK_PRIOR_ERROR OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x03) - -/* - * @ingroup OS_task - * 任务错误码:任务入口函数为空。 - * - * 值: 0x02000804 - * - * 解决方案: 检查入参任务入口函数是否为NULL。 - */ -#define OS_ERRNO_TSK_ENTRY_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x04) - -/* - * @ingroup OS_task - * 任务错误码:任务名的指针为空或任务名为空字符串。 - * - * 值: 0x02000805 - * - * 解决方案: 检查任务名指针和任务名。 - */ -#define OS_ERRNO_TSK_NAME_EMPTY OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x05) - -/* - * @ingroup OS_task - * 任务错误码:指定的任务栈空间太小。 - * - * 值: 0x02000806 - * - * 解决方案: 检查任务栈是否小于OS_TSK_MIN_STACK_SIZE。 - */ -#define OS_ERRNO_TSK_STKSZ_TOO_SMALL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x06) - -/* - * @ingroup OS_task - * 任务错误码:任务ID非法。 - * - * 值: 0x02000807 - * - * 解决方案: 检查当前运行任务的PID是否超过任务最大数或检查用户入参任务PID是否合法。 - */ -#define OS_ERRNO_TSK_ID_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x07) - -/* - * @ingroup OS_task - * 任务错误码:任务已被挂起。 - * - * 值: 0x02000808 - * - * 解决方案: 检查所挂起任务是否为已挂起任务。 - */ -#define OS_ERRNO_TSK_ALREADY_SUSPENDED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x08) - -/* - * @ingroup OS_task - * 任务错误码:任务未被挂起。 - * - * 值: 0x02000809 - * - * 解决方案: 检查所恢复任务是否未挂起。 - */ -#define OS_ERRNO_TSK_NOT_SUSPENDED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x09) - -/* - * @ingroup OS_task - * 任务错误码:任务未创建。 - * - * 值: 0x0200080a - * - * 解决方案: 检查任务是否创建。 - */ -#define OS_ERRNO_TSK_NOT_CREATED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x0a) - -/* - * @ingroup OS_task - * 任务错误码:在锁任务的状态下删除当前任务。 - * - * 值: 0x0300080b - * - * 解决方案: 用户确保删除任务时,将任务解锁。 - * - */ -#define OS_ERRNO_TSK_DELETE_LOCKED OS_ERRNO_BUILD_FATAL(OS_MID_TSK, 0x0b) - -/* - * @ingroup OS_task - * 任务错误码:任务待处理的消息数非零。 - * - * 值: 0x0200080c - * - * 解决方案: 检查所删除任务是否尚有未处理的消息。 - */ -#define OS_ERRNO_TSK_MSG_NONZERO OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x0c) - -/* - * @ingroup OS_task - * 任务错误码:在硬中断或软中断的处理中进行延时操作。 - * - * 值: 0x0300080d - * - * 解决方案: 此操作禁止在中断中进行调度。 - * - */ -#define OS_ERRNO_TSK_DELAY_IN_INT OS_ERRNO_BUILD_FATAL(OS_MID_TSK, 0x0d) - -/* - * @ingroup OS_task - * 任务错误码:在锁任务的状态下进行延时操作。 - * - * 值: 0x0200080e - * - * 解决方案: 检查是否锁任务。 - */ -#define OS_ERRNO_TSK_DELAY_IN_LOCK OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x0e) - -/* - * @ingroup OS_task - * 任务错误码:任务ID不在Yield操作指定的优先级队列中。 - * - * 值: 0x0200080f - * - * 解决方案: 检查操作的任务的优先级。 - */ -#define OS_ERRNO_TSK_YIELD_INVALID_TASK OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x0f) - -/* - * @ingroup OS_task - * 任务错误码:Yield操作指定的优先级队列中,就绪任务数小于2。 - * - * 值: 0x02000810 - * - * 解决方案: 检查指定优先级就绪任务,确保就绪任务数大于1。 - */ -#define OS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x10) - -/* - * @ingroup OS_task - * 任务错误码:没有可用的任务控制块资源或配置项中任务裁剪关闭。 - * - * 值: 0x02000811 - * - * 解决方案: 打开配置项中任务裁剪开关,并配置足够大的任务资源数。 - */ -#define OS_ERRNO_TSK_TCB_UNAVAILABLE OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x11) - -/* - * @ingroup OS_task - * 任务错误码:任务钩子不匹配,即要删除的钩子未注册或已取消。 - * - * 值: 0x02000812 - * - * 解决方案: 检查钩子是否已注册。 - */ -#define OS_ERRNO_TSK_HOOK_NOT_MATCH OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x12) - -/* - * @ingroup OS_task - * 任务错误码:操作IDLE任务。 - * - * 值: 0x02000814 - * - * 解决方案: 检查是否操作IDLE任务。 - */ -#define OS_ERRNO_TSK_OPERATE_IDLE OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x14) - -/* - * @ingroup OS_task - * 任务错误码:在锁任务的状态下挂起当前任务。 - * - * 值: 0x03000815 - * - * 解决方案: 确保任务挂起的时候,任务已经解锁。 - * - */ -#define OS_ERRNO_TSK_SUSPEND_LOCKED OS_ERRNO_BUILD_FATAL(OS_MID_TSK, 0x15) - -/* - * @ingroup OS_task - * 任务错误码:释放任务栈失败。 - * - * 值: 0x02000817 - * - * 解决方案: 检查是否踩内存导致内存块不能释放。 - */ -#define OS_ERRNO_TSK_FREE_STACK_FAILED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x17) - -/* - * @ingroup OS_task - * 任务错误码:任务栈区间配置太小。 - * - * 值: 0x02000818 - * - * 解决方案: 在nos_config.h中配置任务栈大小超过OS_TSK_MIN_STACK_SIZE 。 - */ -#define OS_ERRNO_TSK_STKAREA_TOO_SMALL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x18) - -/* - * @ingroup OS_task - * 任务错误码:系统初始化任务激活失败。 - * - * 值: 0x02000819 - * - * 解决方案: 查看任务栈是否配置错误。 - * - */ -#define OS_ERRNO_TSK_ACTIVE_FAILED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x19) - -/* - * @ingroup OS_task - * 任务错误码:配置的任务数量太多,配置的最大任务个数不能大于254减去配置的软中断个数, - * 总任务个数不包括Idle任务且不能为0。 - * - * 值: 0x0200081a - * - * 解决方案: 在任务配置项中将最大任务数改为小于等于254减去配置的软中断个数且大于0。 - */ -#define OS_ERRNO_TSK_MAX_NUM_NOT_SUITED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x1a) - -/* - * @ingroup OS_task - * 任务错误码:任务的coprocessor上下文保存区域未按16字节对齐。 - * - * 值: 0x0200081b - * - * 解决方案: 检查保存区起始地址是否16字节对齐。 - */ -#define OS_ERRNO_TSK_CP_SAVE_AREA_NOT_ALIGN OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x1b) - -/* - * @ingroup OS_task - * 任务错误码:任务的MSG队列个数超过15。 - * - * 值: 0x0200081d - * - * 解决方案: 确认任务创建的消息队列数不超过15。 - */ -#define OS_ERRNO_TSK_MSG_Q_TOO_MANY OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x1d) - -/* - * @ingroup OS_task - * 任务错误码:任务的coprocessor上下文保存区域的地址为空指针。 - * - * 值: 0x0200081e - * - * 解决方案: 检查保存区起始地址是否为NULL。 - */ -#define OS_ERRNO_TSK_CP_SAVE_AREA_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x1e) - -/* - * @ingroup OS_task - * 任务错误码:任务自删除时释放未接收消息的内存失败。 - * - * 值: 0x0200081f - * - * 解决方案: 无。 - */ -#define OS_ERRNO_TSK_SELF_DELETE_ERR OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x1f) - -/* - * @ingroup OS_task - * 任务错误码:获取任务信息时,用户实际欲获取任务数为0。 - * - * 值: 0x02000821 - * - * 解决方案: 获取任务信息时,用户实际输入的欲获取任务数不为0。 - */ -#define OS_ERRNO_TSK_INPUT_NUM_ERROR OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x21) - -/* - * @ingroup OS_task - * 任务错误码:用户配置的任务栈首地址未16字节对齐。 - * - * 值: 0x02000822 - * - * 解决方案: 配置进来任务栈首地址需16字节对齐。 - */ -#define OS_ERRNO_TSK_STACKADDR_NOT_ALIGN OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x22) - -/* - * @ingroup OS_task - * 任务错误码:任务正在操作队列。 - * - * 值: 0x02000823 - * - * 解决方案: 让被删除的任务得到调度读取完队列数据,即可删除。 - */ -#define OS_ERRNO_TSK_QUEUE_DOING OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x23) - -/* - * @ingroup OS_task - * 任务错误码:任务发生优先级继承。 - * - * 值: 0x02000824 - * - * 解决方案: 等待任务恢复优先级后再尝试设置任务的优先级。 - */ -#define OS_ERRNO_TSK_PRIORITY_INHERIT OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x24) - -/* - * @ingroup OS_task - * 任务错误码:任务阻塞在互斥信号量上。 - * - * 值: 0x02000825 - * - * 解决方案: 等待任务恢复调度后再尝试设置任务的优先级。 - */ -#define OS_ERRNO_TSK_PEND_ON_MUTEX OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x25) - -/* - * @ingroup OS_task - * 任务错误码:任务删除时持有互斥信号量。 - * - * 值: 0x02000826 - * - * 解决方案: 删除任务时必须将其持有的互斥信号量释放。 - */ -#define OS_ERRNO_TSK_HAVE_MUTEX_SEM OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x26) - -/* - * @ingroup OS_task - * 任务错误码:任务退出时没有完全释放资源。 - * - * 值: 0x03000827 - * - * 解决方案: 任务退出前确保完全释放其占有的资源(如消息,互斥信号量等)。 - * - */ -#define OS_ERRNO_TSK_EXIT_WITH_RESOURCE OS_ERRNO_BUILD_FATAL(OS_MID_TSK, 0x27) - -/* - * @ingroup OS_task - * 任务错误码:任务设置优先级时低于阻塞在它持有的互斥信号量的最高优先级任务的优先级。 - * - * 值: 0x02000828 - * - * 解决方案: 重设优先级时不能低于阻塞在目标任务持有的互斥信号量的最高优先级任务的优先级。 - * - */ -#define OS_ERRNO_TSK_PRIOR_LOW_THAN_PENDTSK OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x28) - -/* - * @ingroup OS_task - * 任务错误码:不能在当前正在运行的任务中获取当前任务的上下文信息。 - * - * 值: 0x02000829 - * - * 解决方案: 需要在中断中获取任务的上下文信息或者当前运行任务中获取其他任务的任务上下文信息。 - * - */ -#define OS_ERRNO_TSK_CONTEXT_NOT_GETED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x29) - -/* - * @ingroup OS_task - * 任务错误码:入参为NULL。 - * - * 值: 0x0200082a - * - * 解决方案: 检查入参是否不为NULL。 - */ -#define OS_ERRNO_TSK_PARA_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x2a) - -/* - * @ingroup OS_task - * 任务错误码:SMP绑定核的核掩码非法。 - * - * 值: 0x0200082b - * - * 解决方案: 检查有效的核掩码是否为0。 - */ -#define OS_ERRNO_TSK_BIND_CORE_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x2b) - -/* - * @ingroup OS_task - * 任务错误码:任务阻塞在优先级唤醒方式的信号量上。 - * - * 值: 0x0200082c - * - * 解决方案: 等待任务恢复调度后再尝试设置任务的优先级。 - */ -#define OS_ERRNO_TSK_PEND_ON_PRIOR OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x2c) - -/* - * @ingroup OS_task - * 任务错误码:查询目标核运行任务时指定的核号非法。 - * - * 值: 0x0200082d - * - * 解决方案: 传入正确的核号再查询当前运行任务ID。 - */ -#define OS_ERRNO_TSK_GET_CURRENT_COREID_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x2d) - -/* - * @ingroup OS_task - * 任务错误码:查询目标核还未开始运行任务。 - * - * 值: 0x0200082e - * - * 解决方案: 目标核开始运行任务后即可获取当前运行任务。 - */ -#define OS_ERRNO_TSK_DESTCORE_NOT_RUNNING OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x2e) - -/* - * @ingroup OS_task - * 任务错误码:指定的任务栈空间太小。 - * - * 值: 0x0200082f - * - * 解决方案: 检查任务栈是否小于OS_TSK_MIN_STACK_SIZE+多消息头。 - */ -#define OS_ERRNO_TSK_USR_STKSZ_TOO_SMALL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x2f) - -/* - * @ingroup OS_task - * 任务错误码:调度器trace的buffer内存申请失败。 - * - * 值: 0x02000840 - * - * 解决方案: 放大0号分区的内存空间大小。 - */ -#define OS_ERRNO_TSK_SCHED_TRACE_NO_MEMORY OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x40) - -/* - * @ingroup OS_task - * 任务错误码:锁任务调度的情况下绑定自身至其他核。 - * - * 值: 0x0200084c - * - * 解决方案: 锁任务调度的情况下不要将自身绑定至其他核。 - */ -#define OS_ERRNO_TSK_BIND_SELF_WITH_TASKLOCK OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x4c) - -/* - * @ingroup OS_task - * 任务错误码:任务在关键不可打断的操作中(如绑核,挂起,删任务,被删),不可以再对任务做这些操作。 - * - * 值: 0x0200084e - * - * 解决方案: 分析系统行为。 - */ -#define OS_ERRNO_TSK_OPERATION_BUSY OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x4e) - -/* - * @ingroup OS_task - * 任务错误码:内核启动过程中内核进程的所有线程(任务、软中断)数和用户进程数之和超过了255个 - * - * 值: 0x0200084f - * - * 解决方案: 检查内核OS模块注册过程中所有线程(任务、软中断)数和用户进程数配置之和不超过255个。 - */ -#define OS_ERRNO_TSK_LTID_OVERFLOW OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x4f) - -/* - * @ingroup OS_task - * 任务错误码:创建线程时没有可使用的GTID资源分配。 - * - * 值: 0x02000850 - * - * 解决方案: 检查当前创建的线程过多,分配资源数不够。 - */ -#define OS_ERRNO_TSK_NO_GTID_ALLOC_RESOURCE OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x50) - -/* - * @ingroup OS_task - * 任务错误码:进程中删除线程时线程TID对应的GTID资源不存在。 - * - * 值: 0x02000851 - * - * 解决方案: 检查当前进程中的删除的线程TID是否存在。 - */ -#define OS_ERRNO_TSK_NO_GTID_RESOURCE_DEL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x51) - -/* - * @ingroup OS_task - * 任务错误码:没有任务调度请求 - * - * 值: 0x02000852 - * - * 解决方案: 检查进程任务idle下是否存在其他用户进程切换。 - */ -#define OS_ERRNO_TSK_NO_SCHEDULE_REQ OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x52) - -/* - * @ingroup OS_task - * 任务错误码:在中断上下文绑定迁移任务。 - * - * 值: 0x02000853 - * - * 解决方案: 禁止在中断上下文绑定任务,中断互绑对方运行任务时可能会死循环。 - */ -#define OS_ERRNO_TSK_BIND_IN_HWI OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x53) - -/* - * @ingroup OS_task - * 任务错误码:解锁任务之前并未上锁。 - * - * 值: 0x02000854 - * - * 解决方案: 任务上锁解锁必须配对使用,不能不加锁,直接解锁,可能导致误解锁。 - */ -#define OS_ERRNO_TSK_UNLOCK_NO_LOCK OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x54) - -/* - * @ingroup OS_task - * 任务错误码:不支持任务删除。 - * - * 值: 0x03000855 - * - * 解决方案: 确保任务删除功能配置为YES。 - */ -#define OS_ERRNO_TSK_DEL_NOT_SUPPORT OS_ERRNO_BUILD_FATAL(OS_MID_TSK, 0x55) - -/* - * @ingroup OS_task - * 任务错误码:指定的任务栈size太大导致内存分配整形溢出。 - * - * 值: 0x02000856 - * - * 解决方案: 限制任务栈大小,确保内存大小不大于0xFFFFFFFF。 - */ -#define OS_ERRNO_TSK_STKSZ_TOO_BIG OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x56) - -/* - * @ingroup OS_task - * 任务错误码:指定的任务栈地址太大导致任务栈初始化的时候整形溢出。 - * - * 值: 0x02000857 - * - * 解决方案: 限制任务栈地址大小,确保任务栈初始化地址不大于0xFFFFFFFF。 - */ -#define OS_ERRNO_TSK_STACKADDR_TOO_BIG OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x57) -/* - * @ingroup OS_task - * 任务错误码:配置的任务数量太多,最多127个。 - * - * 值: 0x02000858 - * - * 解决方案: 确认任务创建的消息队列数不超过15。 - */ -#define OS_ERRNO_TSK_CONFIG_TOO_MANY OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x58) -/* - * @ingroup OS_task - * 任务错误码:任务钩子已达到最大允许的注册数。 - * - * 值: 0x02000859 - * - * 解决方案: 无 - */ -#define OS_ERRNO_TSK_HOOK_IS_FULL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x59) - -/* - * @ingroup OS_task - * 任务错误码:任务动态私有数据参数指针为空。 - * - * 值: 0x0200085a - * - * 解决方案: 排查接口参数是否合法。 - */ -#define OS_ERRNO_TSK_SPEC_DATA_PARA_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x5a) - -/* - * @ingroup OS_task - * 任务错误码:任务动态私有数据创建满,当前最多支持16个。 - * - * 值: 0x0200085b - * - * 解决方案: 排查是否有需要删除的动态私有数据并删除。 - */ -#define OS_ERRNO_TSK_SPEC_DATA_CREATE_FULL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x5b) - -/* - * @ingroup OS_task - * 任务错误码:任务动态私有数据参数句柄非法。 - * - * 值: 0x0200085c - * - * 解决方案: 排查接口中传入的句柄参数是否合法。 - */ -#define OS_ERRNO_TSK_SPEC_DATA_HANDLE_OVERFLOW OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x5c) - -/* - * @ingroup OS_task - * 任务错误码:任务动态私有数据参数句柄尚未创建。 - * - * 值: 0x0200085d - * - * 解决方案: 排查接口中传入的句柄参数是否合法,必须先创建再使用。 - */ -#define OS_ERRNO_TSK_SPEC_DATA_HANDLE_UNCREATE OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x5d) - -/* - * @ingroup OS_task - * 任务错误码:任务动态私有数据初始化时没有可用内存。 - * - * 值: 0x0200085e - * - * 解决方案: 扩大默认内存分区大小。 - */ -#define OS_ERRNO_TSK_SPEC_DATA_NO_MOMORY OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x5e) - -/* - * @ingroup OS_task - * 任务错误码:任务动态私有数据没有先设置再获取值。 - * - * 值: 0x0200085f - * - * 解决方案: 必须先对任务动态私有数据进行设置后使用。 - */ -#define OS_ERRNO_TSK_SPEC_DATA_HANDLE_UNSET OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x5f) - -/* - * @ingroup OS_task - * 任务错误码:任务动态私有数据在经过重新创建后没有先设置再获取值。 - * - * 值: 0x02000860 - * - * 解决方案: 必须先对任务动态私有数据进行设置后使用。 - */ -#define OS_ERRNO_TSK_SPEC_DATA_HANDLE_RECREATE_UNSET OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x60) - -/* - * @ingroup OS_task - * 任务切换类型。 - * - * 任务快速切换。 - */ -#define OS_TSK_FAST_TRAP 0x1 - -/* - * @ingroup OS_task - * 任务切换类型。 - * - * 任务普通切换。 - */ -#define OS_TSK_NORMAL_TRAP 0x0 - -/* - * *@ingroup OS_task - * 任务信息结构体 - */ -struct TskInfo { - /* 任务切换时的SP */ - uintptr_t sp; - /* 任务切换时的PC */ - uintptr_t pc; - /* 任务状态 */ - unsigned short taskStatus; - /* 任务优先级 */ - unsigned short taskPrio; - /* 任务栈的大小 */ - unsigned int stackSize; - /* 任务栈的栈顶 */ - uintptr_t topOfStack; - /* 任务接收到的消息数 */ - unsigned int numOfMsg; - /* 任务名 */ - char name[OS_TSK_NAME_LEN]; - /* 任务当前核 */ - unsigned int core; - /* 任务入口函数 */ - void *entry; - /* 任务控制块地址 */ - void *tcbAddr; - /* 栈底 */ - uintptr_t bottom; - /* 栈当前使用的大小 */ - unsigned int currUsed; - /* 栈使用的历史峰值 */ - unsigned int peakUsed; - /* 栈是否溢出 */ - bool ovf; - /* 任务上下文 */ - struct TskContext context; -}; - -/* - * @ingroup OS_task - * Description: 任务入口函数类型定义。 - * - * @par 描述 - * 用户通过任务入口函数类型定义任务入口函数,在任务创建触发之后调用该函数进行任务执行。 - * @attention 无。 - * - * @param param1 [IN] 类型#uintptr_t,传递给任务处理函数的第一个参数。 - * @param param2 [IN] 类型#uintptr_t,传递给任务处理函数的第二个参数。 - * @param param3 [IN] 类型#uintptr_t,传递给任务处理函数的第三个参数。 - * @param param4 [IN] 类型#uintptr_t,传递给任务处理函数的第四个参数。 - * - * @retval 无。 - * @par 依赖 - *
  • os_task.h:该接口声明所在的头文件。
- * @see 无。 - */ -typedef void (*TskEntryFunc)(uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4); - -/* - * @ingroup os_task - * Description: 任务创建钩子函数类型定义。 - * - * @par 描述 - * 用户通过任务创建钩子函数类型定义任务创建钩子,在系统创建任务时,调用该钩子。 - * @attention 无。 - * - * @param taskPid [IN] 类型#TskHandle,新创建任务的PID。 - * - * @retval 无。 - * @par 依赖 - *
  • os_task.h:该接口声明所在的头文件。
- * @see 无。 - */ -typedef unsigned int(*TskCreateHook)(unsigned int taskPid); - -/* - * @ingroup os_task - * Description: 任务删除钩子函数类型定义。 - * - * @par 描述 - * 用户通过任务删除钩子函数类型定义任务删除钩子,在系统对任务进行删除时,调用该钩子。 - * @attention 无。 - * - * @param taskPid [IN] 类型#TskHandle,删除任务的PID。 - * - * @retval 无。 - * @par 依赖 - *
  • os_task.h:该接口声明所在的头文件。
- * @see 无。 - */ -typedef unsigned int(*TskDeleteHook)(unsigned int taskPid); - -/* - * @ingroup os_task - * Description: 任务切换钩子函数类型定义。 - * - * @par 描述 - * 用户通过任务切换钩子函数类型定义任务切换钩子,在系统对任务进行切换时,调用该钩子。 - * @attention 无。 - * - * @param lastTaskPid [IN] 类型#TskHandle,上一个任务的PID。 - * @param nextTaskPid [IN] 类型#TskHandle,下一个任务的PID。 - * - * @retval 无。 - * @par 依赖 - *
  • os_task.h:该接口声明所在的头文件。
- * @see 无。 - */ -typedef unsigned int(*TskSwitchHook)(unsigned int lastTaskPid, unsigned int nextTaskPid); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* OS_TASK_H */ diff --git a/src/middleware/hisilicon/nostask/include/nos/nos_base_task.h b/src/middleware/hisilicon/nostask/include/nos/nos_base_task.h deleted file mode 100644 index 86e47dd69297c2e1d334a8bfb0e27df0dc1957e7..0000000000000000000000000000000000000000 --- a/src/middleware/hisilicon/nostask/include/nos/nos_base_task.h +++ /dev/null @@ -1,503 +0,0 @@ -/** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder 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 HOLDER 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. - * @file nos_base_task.h - */ - -/* - * @defgroup NOS_task 任务基本功能 - * @ingroup NOS_kernel - */ - -#ifndef NOS_BASE_TASK_H -#define NOS_BASE_TASK_H - -#include "nos_sys_external.h" -#include "nos_typedef.h" -#include "os_task.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -/* - * @ingroup OS_task - * 空任务ID。 - * - * 调用NOS_TaskYield时,使用OS_TSK_NULL_ID,由OS选择就绪队列中的第一个任务。 - */ -#define OS_TSK_NULL_ID 0xFFFFFFFF - -/* - * @ingroup NOS_task - * 任务创建参数的结构体定义。 - * - * 传递任务创建时指定的参数信息。 - */ -struct TskInitParam { - /* 任务入口函数 */ - TskEntryFunc taskEntry; - /* 任务优先级 */ - unsigned short taskPrio; - /* 任务参数,最多4个 */ - uintptr_t args[4]; - /* 任务栈的大小 */ - unsigned int stackSize; - /* 任务名 */ - const char *name; - /* - * 本任务的任务栈独立配置起始地址,用户必须对该成员进行初始化, - * 若配置为0表示从系统内部空间分配,否则用户指定栈起始地址 - */ - uintptr_t stackAddr; - /* 专属于本任务的私有数据 */ - uintptr_t privateData; -}; - -/* - * @ingroup NOS_task - * Description: 创建任务。 - * - * @par 描述 - * 创建一个任务。在系统OS初始化前创建的任务只是简单地加入就绪队列。 - * 系统初始化后创建的任务,如果优先级高于当前任务且未锁任务,则立即发生任务调度并被运行,否则加入就绪队列。 - * - * @attention - *
    - *
  • 若指定的任务栈独立配置起始地址不为0,则采用用户配置的独立任务栈进行栈空间分配,
  • - *
  • 并且系统会占用(消息队列个数乘以12字节)的空间用于消息队列头。
  • - *
  • 任务创建时,会对之前自删除任务的任务控制块和任务栈进行回收,用户独立配置的任务栈除外。
  • - *
  • 任务名的最大长度为16字节,含结束符。
  • - *
  • 创建任务时需要配置消息队列数。
  • - *
  • 同一核内任务名不允许重复,且不允许和软中断重名。
  • - *
  • 若指定的任务栈大小为0,则使用配置项#OS_TSK_DEFAULT_STACK_SIZE指定的默认的任务栈大小。
  • - *
  • 任务栈的大小必须按16字节大小对齐。确定任务栈大小的原则是,够用就行:多了浪费,少了任务栈溢出。
  • - *
  • 具体多少取决于需要消耗多少的栈内存,视情况而定:函数调用层次越深,栈内存开销越大,
  • - *
  • 局部数组越大,局部变量越多,栈内存开销也越大。
  • - *
  • 用户配置的任务栈首地址需16字节对齐,且配置的任务栈空间中,os会使用消息队列数乘以消息队列控制块的内存大小。
  • - *
  • 用户配置的任务栈空间需由用户保证其合法性,即对可cache空间的地址用户需要保证其任务栈首地址及栈大小cache
  • - *
  • line对齐,系统不做对齐处理,并在使用后需由用户进行释放。
  • - *
  • 任务创建时,任务创建参数中的任务栈大小配置建议不要使用最小任务栈大小OS_TSK_MIN_STACK_SIZE,
  • - *
  • 该项只是包含任务上下文预留的栈空间,任务调度时额外的任务开销需要由用户自行保证足够的任务栈空间配置。
  • - *
- * - * @param taskPid [OUT] 类型#unsigned int *,保存任务PID。 - * @param initParam [IN] 类型#struct TskInitParam *,任务创建参数, - * 其结构体中的成员参数stackAddr传入时必须进行初始化,若不采用用户配置的独立任务栈进行栈空间分配, - * 该成员必须初始化为0。 - * - * @retval #OS_ERRNO_TSK_NO_MEMORY 0x02000800,申请内存失败。 - * @retval #OS_ERRNO_TSK_PTR_NULL 0x02000801,指针参数为空。 - * @retval #OS_ERRNO_TSK_STKSZ_NOT_ALIGN 0x02000802,任务栈大小未按16字节大小对齐,HIAVP未按64字节对齐。 - * @retval #OS_ERRNO_TSK_PRIOR_ERROR 0x02000803,任务优先级非法。 - * @retval #OS_ERRNO_TSK_ENTRY_NULL 0x02000804,任务入口函数为空。 - * @retval #OS_ERRNO_TSK_NAME_EMPTY 0x02000805,任务名的指针为空或任务名为空字符串。 - * @retval #OS_ERRNO_TSK_STKSZ_TOO_SMALL 0x02000806,指定的任务栈空间太小。 - * @retval #OS_ERRNO_TSK_ID_INVALID 0x02000807,任务PID非法。 - * @retval #OS_ERRNO_TSK_NOT_SUSPENDED 0x02000809,任务未被挂起。 - * @retval #OS_ERRNO_TSK_FREE_STACK_FAILED 0x02000817,释放任务栈失败。 - * @retval #OS_ERRNO_TSK_TCB_UNAVAILABLE 0x02000811,没有可用的任务控制块资源。 - * @retval #OS_ERRNO_TSK_MSG_Q_TOO_MANY 0x0200081d,任务的MSG队列个数超过15。 - * @retval #OS_ERRNO_HUNT_THREAD_NAME_REPEAT 0x02001f01,创建任务时,线程名重名。 - * @retval #OS_ERRNO_TSK_STACKADDR_NOT_ALIGN 0x02000822,创建任务时,用户配置任务栈地址未16字节对齐。 - * @retval #NOS_OK 0x00000000,任务创建成功。 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskDeleteInner | NOS_TaskCreateInnerHookAdd | NOS_TaskCreateOnlyInner - */ -extern unsigned int NOS_TaskCreateInner(unsigned int *taskPid, struct TskInitParam *initParam); - -/* - * @ingroup NOS_task - * Description: 创建任务,但不激活任务。 - * - * @par 描述 - * 创建一个任务。该任务不加入就绪队列,只处于挂起状态,用户需要激活该任务需要通过调用NOS_TaskResumeInner函数将其激活。 - * - * @attention - *
    - *
  • 若指定的任务栈独立配置起始地址不为0,则采用用户配置的独立任务栈进行栈空间分配,并且系统会占用(queNum
  • - *
  • 12字节)的空间用于消息队列头。
  • - *
  • 任务创建时,会对之前自删除任务的任务控制块和任务栈进行回收,用户独立配置的任务栈除外。
  • - *
  • 任务名的最大长度为16字节,含结束符。
  • - *
  • 创建任务时需要配置消息队列数。
  • - *
  • 同一核内任务名不允许重复,且不允许和软中断重名。
  • - *
  • 若指定的任务栈大小为0,则使用配置项#OS_TSK_DEFAULT_STACK_SIZE指定的默认的任务栈大小。
  • - *
  • 任务栈的大小必须按16字节大小对齐。确定任务栈大小的原则是,够用就行:多了浪费,少了任务栈溢出。
  • - *
  • 具体多少取决于需要消耗多少的栈内存,视情况而定:函数调用层次越深,栈内存开销越大,
  • - *
  • 局部数组越大,局部变量越多,栈内存开销也越大。
  • - *
  • 用户配置的任务栈首地址需16字节对齐,且配置的任务栈空间中,os会使用消息队列数*消息队列控制块的内存大小。
  • - *
  • 用户配置的任务栈空间需由用户保证其合法性,即对可cache空间的地址用户需要保证其任务栈首地址及栈大小cache
  • - *
  • line对齐,系统不做对齐处理,并在使用后需由用户进行释放。
  • - *
  • 任务创建时,任务创建参数中的任务栈大小配置建议不要使用最小任务栈大小OS_TSK_MIN_STACK_SIZE,
  • - *
  • 该项只是包含任务上下文预留的栈空间,任务调度时额外的任务开销需要由用户自行保证足够的任务栈空间配置。
  • - *
- * - * @param taskPid [OUT] 类型#unsigned int *,保存任务PID。 - * @param initParam [IN] 类型#struct TskInitParam *,任务创建参数, - * 其结构体中的成员参数stackAddr传入时必须进行初始化,若不采用用户配置的独立任务栈进行栈空间分配, - * 该成员必须初始化为0。 - * - * @retval #OS_ERRNO_TSK_NO_MEMORY 0x02000800,申请内存失败。 - * @retval #OS_ERRNO_TSK_PTR_NULL 0x02000801,指针参数为空。 - * @retval #OS_ERRNO_TSK_STKSZ_NOT_ALIGN 0x02000802,任务栈大小未按16字节大小对齐。 - * @retval #OS_ERRNO_TSK_PRIOR_ERROR 0x02000803,任务优先级非法。 - * @retval #OS_ERRNO_TSK_ENTRY_NULL 0x02000804,任务入口函数为空。 - * @retval #OS_ERRNO_TSK_NAME_EMPTY 0x02000805,任务名的指针为空或任务名为空字符串。 - * @retval #OS_ERRNO_TSK_STKSZ_TOO_SMALL 0x02000806,指定的任务栈空间太小。 - * @retval #OS_ERRNO_TSK_ID_INVALID 0x02000807,任务PID非法。 - * @retval #OS_ERRNO_TSK_TCB_UNAVAILABLE 0x02000811,没有可用的任务控制块资源。 - * @retval #OS_ERRNO_TSK_MSG_Q_TOO_MANY 0x0200081d,任务的MSG队列个数超过15。 - * @retval #OS_ERRNO_HUNT_THREAD_NAME_REPEAT 0x02001f01,创建任务时,线程名重名. - * @retval #OS_ERRNO_TSK_STACKADDR_NOT_ALIGN 0x02000822,创建任务时,用户配置任务栈地址未16字节对齐. - * @retval #NOS_OK 0x00000000,任务创建成功。 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskDeleteInner | NOS_TaskCreateInnerHookAdd | NOS_TaskCreateInner - */ -extern unsigned int NOS_TaskCreateOnlyInner(unsigned int *taskPid, struct TskInitParam *initParam); - -/* - * @ingroup NOS_task - * Description: 恢复任务。 - * - * @par 描述 - * 恢复挂起的任务。 - * - * @attention - *
    - *
  • 在osStart之前不能调用该接口。
  • - *
  • 若任务仍处于延时、阻塞态,则只是取消挂起态,并不加入就绪队列。
  • - *
- * - * @param taskPid [IN] 类型#TskHandle,任务PID。 - * - * @retval #OS_ERRNO_TSK_ID_INVALID 0x02000807,任务PID非法。 - * @retval #OS_ERRNO_TSK_NOT_CREATED 0x0200080a,任务未创建。 - * @retval #OS_ERRNO_TSK_OPERATE_IDLE 0x02000814,操作IDLE任务。 - * @retval #OS_ERRNO_TSK_NOT_SUSPENDED 0x02000809,任务未被挂起。 - * @retval #NOS_OK 0x00000000,恢复任务成功。 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskSuspendInner - */ -extern unsigned int NOS_TaskResumeInner(unsigned int taskId); - -/* - * @ingroup NOS_task - * Description: 挂起任务。 - * - * @par 描述 - * 挂起指定的任务,任务将从就绪队列中被删除。 - * - * @attention - *
    - *
  • 在osStart之前不能调用该接口。
  • - *
  • 若为当前任务且已锁任务,则不能被挂起。
  • - *
  • IDLE任务不能被挂起。
  • - *
  • SMP多核并发操作NOS_TaskCoreBind,NOS_TaskDeleteInner,NOS_TaskSuspendInner时避免关中断调用,
  • - *
  • 否则核间中断无法响应造成死循环。
  • - *
- * - * @param taskPid [IN] 类型#TskHandle,任务PID。 - * - * @retval #OS_ERRNO_TSK_ID_INVALID 0x02000807,任务PID非法。 - * @retval #OS_ERRNO_TSK_ALREADY_SUSPENDED 0x02000808,任务已被挂起。 - * @retval #OS_ERRNO_TSK_NOT_CREATED 0x0200080a,任务未创建。 - * @retval #OS_ERRNO_TSK_OPERATE_IDLE 0x02000814,操作IDLE任务。 - * @retval #OS_ERRNO_TSK_SUSPEND_LOCKED 0x03000815,在锁任务的状态下挂起当前任务。 - * @retval #NOS_OK 0x00000000,挂起任务成功。 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskResumeInner | NOS_TaskLock - */ -extern unsigned int NOS_TaskSuspendInner(unsigned int taskPid); - -/* - * @ingroup NOS_task - * Description: 删除任务。 - * - * @par 描述 - * 删除指定的任务,释放任务栈和任务控制块资源。 - * - * @attention - *
    - *
  • 若为自删除,则任务控制块和任务栈在下一次创建任务时才回收。
  • - *
  • SMP多核并发操作NOS_TaskCoreBind,NOS_TaskDeleteInner,NOS_TaskSuspendInner时避免关中断调用,
  • - *
  • 否则核间中断无法响应造成死循环。
  • - *
  • 对于任务自删除,处理该任务相关的信号量和接收到的消息会强制删除。
  • - *
  • 任务自删除时,删除钩子不允许进行pend信号量、挂起等操作。
  • - *
- * - * @param taskPid [IN] 类型#TskHandle,任务PID。 - * - * @retval #OS_ERRNO_TSK_ID_INVALID 0x02000807,任务PID非法。 - * @retval #OS_ERRNO_TSK_NOT_CREATED 0x0200080a,任务未创建。 - * @retval #OS_ERRNO_TSK_DELETE_LOCKED 0x0300080b,在锁任务的状态下删除当前任务。 - * @retval #OS_ERRNO_TSK_MSG_NONZERO 0x0200080c,任务待处理的消息数非零。 - * @retval #OS_ERRNO_TSK_HAVE_MUTEX_SEM 0x02000826,任务持有互斥型信号量时删除该任务。 - * @retval #OS_ERRNO_TSK_OPERATE_IDLE 0x02000814,操作IDLE任务。 - * @retval #OS_ERRNO_TSK_QUEUE_DOING 0x02000823,任务正在操作队列。 - * @retval #NOS_OK 0x00000000,删除任务成功。 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskCreateInner | NOS_TaskDeleteInnerHookAdd - */ -extern unsigned int NOS_TaskDeleteInner(unsigned int taskPid); - -/* - * @ingroup NOS_task - * Description: 延迟正在运行的任务。 - * - * @par 描述 - * 延迟当前运行任务的执行。任务延时等待指定的Tick数后,重新参与调度。 - * - * @attention - *
    - *
  • 在osStart之前不能调用该接口。
  • - *
  • 硬中断或软中断处理中,或已锁任务,则延时操作失败。
  • - *
  • 若传入参数0,且未锁任务调度,则顺取同优先级队列中的下一个任务执行。如没有同级的就绪任务,
  • - *
  • 则不发生任务调度,继续执行原任务。
  • - *
- * - * @param tick [IN] 类型#U32,延迟的Tick数。 - * - * @retval #OS_ERRNO_TSK_PRIOR_ERROR 0x02000803,任务优先级非法。 - * @retval #OS_ERRNO_TSK_ID_INVALID 0x02000807,任务PID非法。 - * @retval #OS_ERRNO_TSK_YIELD_INVALID_TASK 0x0200080f,任务ID不在Yield操作指定的优先级队列中。 - * @retval #OS_ERRNO_TSK_DELAY_IN_INT 0x0300080d,在硬中断或软中断的处理中进行延时操作。 - * @retval #OS_ERRNO_TSK_DELAY_IN_LOCK 0x0200080e,在锁任务的状态下进行延时操作。 - * @retval #OS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK 0x02000810,Yield操作指定的优先级队列中,就绪任务数小于2。 - * @retval #NOS_OK 0x00000000,任务延时成功。 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskYield - */ -extern unsigned int NOS_TaskDelayInner(unsigned int tick); - - -extern unsigned int NOS_TaskStartPeriod(unsigned int taskPid, unsigned int timeout); -extern unsigned int NOS_TaskStopPeriod(unsigned int taskPid); -/* - * @ingroup NOS_task - * Description: 锁任务调度。 - * - * @par 描述 - * 锁任务调度。若任务调度被锁,则不发生任务切换。 - * - * @attention - *
    - *
  • 只是锁任务调度,并不关中断,因此任务仍可被中断打断。
  • - *
  • 执行此函数则锁计数值加1,解锁则锁计数值减1。因此,必须与#NOS_TaskUnlock配对使用。
  • - *
  • Cortex-RX SMP下,只会锁当前核的任务调度,其他核的调度不受影响。
  • - *
  • Cortex-RX SMP下,锁任务期间当前核不保证运行的是Top-N优先级任务,直至解锁后OS重新发起任务调度。
  • - *
- * - * @param 无。 - * - * @retval 无 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskUnlock - */ -extern void NOS_TaskLock(void); - -/* - * @ingroup NOS_task - * Description: 解锁任务调度。 - * - * @par 描述 - * 任务锁计数值减1。若嵌套加锁,则只有锁计数值减为0才真正的解锁了任务调度。 - * - * @attention - *
    - *
  • 在osStart之前不能调用该接口。
  • - *
  • 执行此函数则锁计数值加1,解锁则锁计数值减1。因此,必须与#NOS_TaskLock配对使用。
  • - *
- * - * @param 无。 - * - * @retval 无 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskLock - */ -extern void NOS_TaskUnlock(void); - -/* - * @ingroup NOS_task - * Description: 获取当前任务PID。 - * - * @par 描述 - * 获取处于运行态的任务PID。 - * - * @attention - *
    - *
  • 硬中断或软中断处理中,也可获取当前任务PID,即被中断打断的任务。
  • - *
  • 在任务切换钩子处理中调用时,获取的是切入任务的ID。
  • - *
- * - * @param taskPid [OUT] 类型#unsigned int *,保存任务PID。 - * - * @retval #OS_ERRNO_TSK_PTR_NULL 0x02000801,指针参数为空。 - * @retval #OS_ERRNO_TSK_ID_INVALID 0x02000807,任务ID非法。 - * @retval #NOS_OK 0x00000000,成功。 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskStatusGet | NOS_TaskInfoGet - */ -extern unsigned int NOS_TaskSelf(unsigned int *taskPid); - -/* - * @ingroup NOS_task - * Description: 获取私有数据。 - * - * @par 描述 - * 获取当前任务的私有数据。 - * - * @attention - *
    - *
  • 当当前任务正在运行时,调用该接口能获取当前任务的私有数据。
  • - *
  • 当任务被中断打断时,中断里调用该接口能获取被中断打断的任务的私有数据。
  • - *
- * - * @param 无。 - * - * @retval #当前任务的私有数据 任意值,如未设置,则返回的值不确定。 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskPrivateDataSet - */ -extern uintptr_t NOS_TaskPrivateDataGet(void); -extern uintptr_t NOS_TaskPrivateDataGetById(unsigned int taskPid); -/* - * @ingroup NOS_task - * Description: 设置私有数据值。 - * - * @par 描述 - * 设置当前任务的私有数据值。 - * - * @attention - *
    - *
  • 只能在任务处理中调用。若在中断中设置,则操作的是刚被打断的任务。
  • - *
- * - * @param privateData [IN] 类型#uintptr_t,数据值。 - * - * @retval 无 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskPrivateDataGet - */ -extern void NOS_TaskPrivateDataSet(uintptr_t privateData); - -/* - * @ingroup NOS_task - * Description: 获取优先级。 - * - * @par 描述 - * 获取指定任务的优先级。 - * - * @attention 无 - * - * @param taskPid [IN] 类型#TskHandle,任务PID。 - * @param taskPrio [OUT] 类型#unsigned short *,保存任务优先级指针。 - * - * @retval #OS_ERRNO_TSK_PTR_NULL 0x02000801,指针参数为空。 - * @retval #OS_ERRNO_TSK_ID_INVALID 0x02000807,任务PID非法。 - * @retval #OS_ERRNO_TSK_NOT_CREATED 0x0200080a,任务未创建。 - * @retval #NOS_OK 0x00000000,成功。 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskPrioritySetInner - */ -extern unsigned int NOS_TaskPriorityGetInner(unsigned int taskPid, unsigned short *taskPrio); - -/* - * @ingroup NOS_task - * Description: 设置优先级。 - * - * @par 描述 - * 设置指定任务的优先级。 - * - * @attention - *
    - *
  • 在osStart之前不能调用该接口。
  • - *
  • 若设置的优先级高于当前运行的任务,则可能引发任务调度。
  • - *
  • 若调整当前运行任务的优先级,同样可能引发任务调度。
  • - *
  • 若任务发生优先级继承,或者任务阻塞在互斥信号量或优先级唤醒模式的信号量上,不可以设置任务的优先级。
  • - *
- * - * @param taskPid [IN] 类型#TskHandle,任务PID。 - * @param taskPrio [IN] 类型#TskPrior,任务优先级。 - * - * @retval #OS_ERRNO_TSK_PRIOR_ERROR 0x02000803,任务优先级非法。 - * @retval #OS_ERRNO_TSK_ID_INVALID 0x02000807,任务PID非法。 - * @retval #OS_ERRNO_TSK_NOT_CREATED 0x0200080a,任务未创建。 - * @retval #OS_ERRNO_TSK_OPERATE_IDLE 0x02000814,操作IDLE任务。 - * @retval #OS_ERRNO_TSK_PRIORITY_INHERIT 0x02000824,任务发生优先级继承。 - * @retval #OS_ERRNO_TSK_PEND_ON_MUTEX 0x02000825,任务阻塞在互斥信号量上。 - * @retval #OS_ERRNO_TSK_PRIOR_LOW_THAN_PENDTSK 0x02000828,设置优先级低于阻塞于它持有的互斥信号量的 - * @retval 最高优先级任务的优先级 - * @retval #NOS_OK 0x00000000,成功。 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskPriorityGetInner - */ -extern unsigned int NOS_TaskPrioritySetInner(unsigned int taskPid, unsigned short taskPrio); - -/* - * @ingroup NOS_task - * Description: 调整指定优先级的任务调度顺序。 - * - * @par 描述 - * 若nextTask为#OS_TSK_NULL_ID,则优先级队列中的第一个就绪任务调整至队尾, - * 否则,将nextTask指定的任务调整至优先级队列的队首。 - * - * @attention - *
    - *
  • 在osStart之前不能调用该接口。
  • - *
  • 前提是指定优先级的就绪队列至少要有两个就绪任务,否则报错返回。
  • - *
  • Cortex-RX SMP下,只会对本核(本Run Queue)指定优先级的就绪队列进行调整。
  • - *
- * - * @param taskPrio [IN] 类型#TskPrior,任务taskPrio,指定任务优先级队列。 - * @param nextTask [IN] 类型#TskHandle,任务ID或OS_TSK_NULL_ID。 - * @param yieldTo [OUT] 类型#unsigned int *,保存被调整到队首的任务PID,可为NULL(不需要保存队首任务PID)。 - * - * @retval #OS_ERRNO_TSK_PRIOR_ERROR 0x02000803,任务优先级非法。 - * @retval #OS_ERRNO_TSK_ID_INVALID 0x02000807,任务PID非法。 - * @retval #OS_ERRNO_TSK_YIELD_INVALID_TASK 0x0200080f,任务PID不在Yield操作指定的优先级队列中。 - * @retval #OS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK 0x02000810,Yield操作指定的优先级队列中,就绪任务数小于2。 - * @retval #NOS_OK 0x00000000,成功。 - * @par 依赖 - *
  • nos_task.h:该接口声明所在的头文件。
- * @see NOS_TaskSuspendInner - */ -extern unsigned int NOS_TaskYield(unsigned short taskPrio, unsigned int nextTask, unsigned int *yieldTo); - -extern unsigned long long NOS_GetCycle(void); - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* NOS_IN_TASK_H */ diff --git a/src/middleware/hisilicon/nostask/kernel/include/nos_task_external.h b/src/middleware/hisilicon/nostask/kernel/include/nos_task_external.h deleted file mode 100644 index 43d06bcc72d1178eb1307949af0612f292ed57c9..0000000000000000000000000000000000000000 --- a/src/middleware/hisilicon/nostask/kernel/include/nos_task_external.h +++ /dev/null @@ -1,218 +0,0 @@ -/** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder 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 HOLDER 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. - * @file nos_task_external.h - */ -#ifndef NOS_TASK_EXTERNAL_H -#define NOS_TASK_EXTERNAL_H - -#include "nos_list_external.h" -#include "nos_sys_external.h" -#include "nos_cpu_external.h" - -#include "nos_config.h" - -#define OS_MAX_U32 0xFFFFFFFFU - -struct TagOsRunQue { - unsigned int taskReadyListBitMap; - struct TagListObject readyList[OS_TSK_NUM_OF_PRIORITIES]; -}; - -struct TagOsTskSortedDelayList { - /* 延时任务链表 */ - struct TagListObject tskList; -}; - -/* - * 任务线程及进程控制块的结构体统一定义, 64字节对齐。 - * - * stackPointer、taskStatus、priority、topOfStack、taskPID及 - * cpSaveAreaA、cpSaveAreaB、mmuBase、usp、cidr的位置不能变动,汇编中已写死。 - */ -struct TagTskCB { - /* 当前任务的SP */ - void *stackPointer; - /* 任务状态,后续内部全改成U32 */ - unsigned int taskStatus; - /* 任务的运行优先级 */ - unsigned short priority; - /* 超时次数 */ - unsigned int expirationCnt; - - /* 任务栈大小 */ - unsigned int stackSize; - /* 任务PID:SMP下为任务OS内部索引,AMP下为核号 | 任务索引 */ - unsigned int taskPid; - - /* 任务栈顶 */ - uintptr_t topOfStack; - - /* 任务入口函数 */ - TskEntryFunc taskEntry; - /* 任务的参数 */ - uintptr_t args[4]; - /* 任务的原始优先级 */ - unsigned short origPriority; - /* 任务栈配置标记 */ - unsigned short stackCfgFlg; - /* 期望接收消息的QID */ - unsigned char reserved; - /* 私有数据 */ - uintptr_t privateData; - /* 信号量链表指针 */ - struct TagListObject pendList; - /* 任务延时链表指针 */ - struct TagListObject timerList; - - /* 任务记录的最后一个错误码 */ - unsigned int lastErr; - - /* 任务恢复的时间点(单位Tick) */ - unsigned long long expirationTick; -}; - -extern unsigned short g_uniTaskLock; -extern unsigned int g_idleTaskID; -extern struct TagOsRunQue g_runQueue; -extern struct TagTskCB *g_runningTask; -extern struct TagTskCB *g_highestTask; -extern struct TagOsTskSortedDelayList g_tskSortedDelay; - -extern unsigned int g_tskMaxNum; - -#define OS_TSK_STACK_CFG_BY_USER 1 -#define OS_TSK_STACK_CFG_BY_SYS 0 - -#define OS_TSK_PARA_0 0 -#define OS_TSK_PARA_1 1 -#define OS_TSK_PARA_2 2 -#define OS_TSK_PARA_3 3 - -#define OS_TSK_STACK_TOP_MAGIC 0xAAAAAAAA - -#define OS_TSK_OP_FREE 0 -#define OS_TSK_OP_MIGRATING (1UL << 0) // 任务在迁移中,看到delete立即返回 -#define OS_TSK_OP_SUSPENDING (1UL << 2) // 任务在挂起中,看到delete立即返回 -#define OS_TSK_OP_RESUMING (1UL << 3) // 任务在恢复中,看到delete立即返回 -#define OS_TSK_OP_DELETING (1UL << 9) // 任务在删除中,必须等待上述迁移、挂起操作完 -#define OS_TSK_OP_MOVING (1UL << 10) // 任务在迁移/回迁过程中置该标志,确保当前不会被他人操作该任务 - -#define OS_TSK_SUSPEND_READY_BLOCK (OS_TSK_SUSPEND | OS_TSK_READY) -#define OS_TASK_LOCK_DATA g_uniTaskLock -#define IDLE_TASK_ID g_idleTaskID -#define RUNNING_TASK g_runningTask - -/* 内核进程的进程及线程调度控制块使用同一类型 */ -#define OS_MAX_TCB_NUM (OS_TSK_MAX_SUPPORT_NUM + 1 + 1) // (g_tskMaxNum + 1 + 1) 1个IDLE,1个无效任务 - -/* 定义任务的缺省任务栈大小 */ -#define OS_PST_ZOMBIE_TASK (&g_tskCBArray[OS_MAX_TCB_NUM - 1]) -#define GET_TCB_PEND(ptr) LIST_COMPONENT(ptr, struct TagTskCB, pendList) -#define OS_TSK_BLOCK \ - (OS_TSK_DELAY | OS_TSK_PEND | OS_TSK_SUSPEND | OS_TSK_FSEM_PEND | OS_TSK_MSG_PEND | OS_TSK_QUEUE_PEND | \ - OS_TSK_EVENT_PEND | OS_TSK_DELETING) - -extern struct TagTskCB g_tskCBArray[OS_MAX_TCB_NUM]; - -extern void OsTaskScan(void); -extern void OsTskUnlock(void); -extern void OsTskSchedule(void); -extern void OsTskEntry(unsigned int taskId); -extern void OsTaskExit(struct TagTskCB *tsk); -extern void OsTskReadyAdd(struct TagTskCB *task); -extern void OsTskReadyDel(struct TagTskCB *taskCB); -extern void OsTskSwitchHookCaller(unsigned int prevPid, unsigned int nextPid); -extern void OsTskTimerAdd(struct TagTskCB *taskCB, uintptr_t timeout); - -extern unsigned int OsIdleTskAMPCreate(void); -extern unsigned int OsTskMaxNumGet(void); -extern unsigned int OsTaskDelete(unsigned int taskPid); -extern unsigned int OsTaskPrivateDataGetById(unsigned int taskPid, uintptr_t *privateData); -extern unsigned int OsTaskCreateOnly(unsigned int *taskPid, struct TskInitParam *initParam, bool isSmpIdle); - -extern void OsTaskFirstTimeSwitch(void); - -/* get task tcb */ -INLINE struct TagTskCB *GetTcbHandle(unsigned int taskPid) -{ - return (struct TagTskCB *)g_tskCBArray + taskPid; -} - -/* 任务调度 */ -INLINE void OsTskScheduleFast(void) -{ - OsTskSchedule(); -} - -/* 任务调度 */ -INLINE void OsTskScheduleFastPS(uintptr_t intSave) -{ - (void)intSave; - OsTskSchedule(); -} - -/* 任务是否创建 */ -INLINE unsigned int TSK_IsUnused(struct TagTskCB *tsk) -{ - return tsk->taskStatus == OS_TSK_UNUSED; -} - -/* check task status */ -INLINE unsigned int TSK_StatusTst(struct TagTskCB *tsk, unsigned int statBit) -{ - return (tsk->taskStatus & statBit) != 0; -} - -/* status clear */ -INLINE unsigned int TSK_StatusClear(struct TagTskCB *tsk, unsigned int statBit) -{ - return tsk->taskStatus &= ~statBit; -} - -/* status set */ -INLINE unsigned int TSK_StatusSet(struct TagTskCB *tsk, unsigned int statBit) -{ - return tsk->taskStatus |= statBit; -} - -/* check pid */ -INLINE unsigned int CheckTaskPidOverflow(unsigned int taskId) -{ - return taskId >= OS_TSK_MAX_SUPPORT_NUM + 1; -} - -/* - * 模块内内联函数定义 - */ -INLINE void OsTskHighestSet(void) -{ - unsigned int rdyListIdx = OsGetLMB1(g_runQueue.taskReadyListBitMap); - struct TagListObject *readyList = &g_runQueue.readyList[rdyListIdx]; - - g_highestTask = GET_TCB_PEND(OS_LIST_FIRST(readyList)); -} - -/* - * 描述: 将任务添加到就绪队列。 - */ -INLINE void OsTskReadyAddBGD(struct TagTskCB *task) -{ - OsTskReadyAdd(task); -} - -#endif /* NOS_TASK_EXTERNAL_H */ diff --git a/src/middleware/hisilicon/nostask/kernel/nos_task_init.c b/src/middleware/hisilicon/nostask/kernel/nos_task_init.c deleted file mode 100644 index d1f5fc2fa2b027df3cadb622ca8228a832f25f15..0000000000000000000000000000000000000000 --- a/src/middleware/hisilicon/nostask/kernel/nos_task_init.c +++ /dev/null @@ -1,346 +0,0 @@ -/** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder 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 HOLDER 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. - * @file nos_task_init.c - */ -#include "nos_task_internal.h" -#include "nos_amp_task_internal.h" -#include "nos_buildef.h" - -/* Unused TCBs and ECBs that can be allocated. */ -struct TagListObject g_tskCBFreeList = LIST_OBJECT_INIT(g_tskCBFreeList); -struct TagListObject g_tskRecyleList = LIST_OBJECT_INIT(g_tskRecyleList); - -/* - * 描述: Task init function. - */ -unsigned int OsTskInit(void); -unsigned int OsTskInit(void) -{ - unsigned int ret; - - /* AMP task init */ - ret = OsTskAMPInit(); - if (ret != NOS_OK) { - return ret; - } - -#if defined(OS_OPTION_TICK) - /* tick 扫描 */ - g_taskScanHook = OsTaskScan; -#endif - - return NOS_OK; -} - -/* - * 描述: Active task manage, leave main. - */ -unsigned int OsActivate(void); -unsigned int OsActivate(void) -{ - unsigned int ret; - - ret = OsIdleTskAMPCreate(); - if (ret != NOS_OK) { - return ret; - } - - /* Indicate that background task is running. */ - UNI_FLAG |= OS_FLG_BGD_ACTIVE | OS_FLG_TSK_REQ; - - /* Start Multitasking. */ - OsFirstTimeSwitch(); - - return OS_ERRNO_TSK_ACTIVE_FAILED; -} - -/* - * 描述: All task entry - */ -void OsTskEntry(unsigned int taskId) -{ - struct TagTskCB *taskCB = NULL; - uintptr_t intSave; - - (void)taskId; - taskCB = RUNNING_TASK; - - taskCB->taskEntry(taskCB->args[OS_TSK_PARA_0], taskCB->args[OS_TSK_PARA_1], taskCB->args[OS_TSK_PARA_2], - taskCB->args[OS_TSK_PARA_3]); - - // 调度结束后会开中断,所以不需要自己添加开中断 - intSave = NOS_IntLock(); - - OS_TASK_LOCK_DATA = 0; - - /* NOS_TaskDeleteInner不能关中断操作,否则可能会导致它核发SGI等待本核响应时死等 */ - NOS_IntRestore(intSave); - - OsTaskExit(taskCB); -} - -/* - * 描述: Create a task - */ -unsigned int NOS_TaskCreateInner(unsigned int *taskPid, struct TskInitParam *initParam) -{ - unsigned int ret; - - /* 任务创建并挂起 */ - ret = NOS_TaskCreateOnlyInner(taskPid, initParam); - if (ret != NOS_OK) { - return ret; - } - - return NOS_TaskResumeInner(*taskPid); -} - -/* - * 描述: 创建任务参数检查 - */ -static unsigned int OsTaskCreateParaCheck(const unsigned int *taskPid, struct TskInitParam *initParam) -{ - if ((taskPid == NULL) || (initParam == NULL)) { - return OS_ERRNO_TSK_PTR_NULL; - } - - /* check callback */ - if (initParam->taskEntry == NULL) { - return OS_ERRNO_TSK_ENTRY_NULL; - } - - /* check Prio */ - if (initParam->taskPrio > OS_TSK_PRIORITY_LOWEST) { - return OS_ERRNO_TSK_PRIOR_ERROR; - } - - /* 创建任务线程时做校验 */ - if (initParam->name == NULL || initParam->name[0] == '\0') { - return OS_ERRNO_TSK_NAME_EMPTY; - } - - return NOS_OK; -} - -static unsigned int OsTaskCreateParaCheckStack(struct TskInitParam *initParam) -{ - unsigned long long stackAddrLen; - - /* 如未设置栈大小即赋予默认值 */ - if (initParam->stackSize == 0) { - initParam->stackSize = OS_TSK_DEFAULT_STACK_SIZE; - } - - if (((OS_TSK_STACK_SIZE_ALIGN - 1) & initParam->stackSize) != 0) { - return OS_ERRNO_TSK_STKSZ_NOT_ALIGN; - } - - /* 检查是否对齐 */ - if (((OS_TSK_STACK_SIZE_ALIGN - 1) & (uintptr_t)initParam->stackAddr) != 0) { - return OS_ERRNO_TSK_STACKADDR_NOT_ALIGN; - } - - /* 使用用户内存,则需要包含OS使用的资源,size最小值要包含OS的消耗 */ - if (initParam->stackAddr != 0) { - if (initParam->stackSize < OS_TSK_MIN_STACK_SIZE) { - return OS_ERRNO_TSK_USR_STKSZ_TOO_SMALL; - } - /* 保证栈空间在4G范围内不溢出 */ - stackAddrLen = (unsigned long long)(initParam->stackAddr) + (unsigned long long)(initParam->stackSize); - if (stackAddrLen > OS_MAX_U32) { - return OS_ERRNO_TSK_STACKADDR_TOO_BIG; - } - } else { - return OS_ERRNO_TSK_STACKADDR_TOO_BIG; - } - - return NOS_OK; -} - -void OsTskRecycle(void) -{ - struct TagTskCB *taskCB = NULL; - - /* 释放掉之前自删除任务的资源,自删除时,由于任务还处于运行态,不会及时释放资源 */ - /* 调用处已加recycle list锁 */ - while (!ListEmpty(&g_tskRecyleList)) { - taskCB = GET_TCB_PEND(OS_LIST_FIRST(&g_tskRecyleList)); - ListDelete(OS_LIST_FIRST(&g_tskRecyleList)); - ListTailAdd(&taskCB->pendList, &g_tskCBFreeList); - } -} - -/* - * 描述: 初始化栈 - */ -static void OsTskStackInit(unsigned int stackSize, uintptr_t topStack) -{ - unsigned int loop; - unsigned int stackMagicWord = OS_TSK_STACK_MAGIC; - - /* 初始化任务栈,并写入栈魔术字 */ - for (loop = 1; loop < (stackSize / sizeof(unsigned int)); loop++) { - *((unsigned int *)topStack + loop) = stackMagicWord; - } - *((unsigned int *)(topStack)) = OS_TSK_STACK_TOP_MAGIC; -} - -INLINE unsigned int OsTaskCreateChkAndGetTcb(struct TagTskCB **taskCB, bool isSmpIdle) -{ - (void)isSmpIdle; - -#if defined(OS_OPTION_TASK_DELETE) - /* 回收资源 */ - OsTskRecycle(); -#endif - - if (ListEmpty(&g_tskCBFreeList)) { - return OS_ERRNO_TSK_TCB_UNAVAILABLE; - } - - // 先获取到该控制块 - *taskCB = GET_TCB_PEND(OS_LIST_FIRST(&g_tskCBFreeList)); - // 成功,从空闲列表中移除 - ListDelete(OS_LIST_FIRST(&g_tskCBFreeList)); - - return NOS_OK; -} - -INLINE unsigned int OsTaskCreateRsrcInit(unsigned int taskId, struct TskInitParam *initParam, struct TagTskCB *taskCB, - uintptr_t **topStackOut, unsigned int *curStackSize) -{ - uintptr_t *topStack = NULL; - unsigned int ret = NOS_OK; - - (void)taskId; - - /* 查看用户是否配置了任务栈。 */ - if (initParam->stackAddr != 0) { - topStack = (void *)(initParam->stackAddr); - /* 如有,则标记为用户配置 */ - taskCB->stackCfgFlg = OS_TSK_STACK_CFG_BY_USER; - ret = OsTaskCreateUsrStkCfgInit(initParam, curStackSize, taskCB); - } else { -#ifdef OS_OPTION_306X - /* 如没有,则进行内存申请,并标记为系统配置 */ - ret = OS_ERRNO_TSK_NO_MEMORY; -#endif - } - - *topStackOut = topStack; - return ret; -} - -INLINE void OsTskCreateTcbInit(uintptr_t stackPtr, struct TskInitParam *initParam, - uintptr_t topStackAddr, uintptr_t curStackSize, struct TagTskCB *taskCB) -{ - /* Initialize the task's stack */ - taskCB->stackPointer = (void *)stackPtr; - taskCB->privateData = (uintptr_t)initParam->privateData; - /* 传参 */ - taskCB->args[OS_TSK_PARA_0] = (uintptr_t)initParam->args[OS_TSK_PARA_0]; - taskCB->args[OS_TSK_PARA_1] = (uintptr_t)initParam->args[OS_TSK_PARA_1]; - taskCB->args[OS_TSK_PARA_2] = (uintptr_t)initParam->args[OS_TSK_PARA_2]; - taskCB->args[OS_TSK_PARA_3] = (uintptr_t)initParam->args[OS_TSK_PARA_3]; - taskCB->topOfStack = topStackAddr; - /* 传参 */ - taskCB->stackSize = (unsigned int)curStackSize; - taskCB->priority = initParam->taskPrio; - taskCB->origPriority = initParam->taskPrio; - taskCB->taskEntry = initParam->taskEntry; - taskCB->lastErr = 0; - // SMP下就绪链表也做初始化,调度器会做维测,不允许其为空 - OS_LIST_INIT(&taskCB->pendList); - OS_LIST_INIT(&taskCB->timerList); - - return; -} - -INLINE void OsTskCreateTcbStatusSet(struct TagTskCB *taskCB, struct TskInitParam *initParam) -{ - (void)initParam; - /* 上锁之后置INUSE,保证外部判断可靠,且从这里开始任务控制块确实可用,任务创建成功 */ - OsSpinLockTaskRq(taskCB); - /* 设置任务状态 */ - taskCB->taskStatus = OS_TSK_SUSPEND | OS_TSK_INUSE; - OsSpinUnlockTaskRq(taskCB); - return; -} - -/* - * 描述: 创建一个任务但不进行激活 - */ -unsigned int OsTaskCreateOnly(unsigned int *taskPid, struct TskInitParam *initParam, bool isSmpIdle) -{ - unsigned int taskId; - uintptr_t intSave; - uintptr_t *topStack = NULL; - void *stackPtr = NULL; - struct TagTskCB *taskCB = NULL; - unsigned int ret; - unsigned int curStackSize = 0; - - /* check para */ - ret = OsTaskCreateParaCheck(taskPid, initParam); - if (ret != NOS_OK) { - return ret; - } - /* check task stack */ - ret = OsTaskCreateParaCheckStack(initParam); - if (ret != NOS_OK) { - return ret; - } - intSave = NOS_TaskIntLock(); - /* 获取Tcb资源 */ - ret = OsTaskCreateChkAndGetTcb(&taskCB, isSmpIdle); - if (ret != NOS_OK || taskCB == NULL) { - NOS_TaskIntRestore(intSave); - return ret; - } - - taskId = taskCB->taskPid; - - ret = OsTaskCreateRsrcInit(taskId, initParam, taskCB, &topStack, &curStackSize); - if (ret != NOS_OK) { - ListAdd(&taskCB->pendList, &g_tskCBFreeList); - NOS_TaskIntRestore(intSave); - return ret; - } - OsTskStackInit(curStackSize, (uintptr_t)topStack); - - stackPtr = OsTskContextInit(taskId, curStackSize, topStack, (uintptr_t)OsTskEntry); - - /* init Tcb */ - OsTskCreateTcbInit((uintptr_t)stackPtr, initParam, (uintptr_t)topStack, curStackSize, taskCB); - - /* set task status */ - OsTskCreateTcbStatusSet(taskCB, initParam); - // 出参ID传出 - *taskPid = taskId; - NOS_TaskIntRestore(intSave); - - return NOS_OK; -} - -/* - * 描述: 创建一个任务但不进行激活 - */ -unsigned int NOS_TaskCreateOnlyInner(unsigned int *taskPid, struct TskInitParam *initParam) -{ - return OsTaskCreateOnly(taskPid, initParam, FALSE); -} diff --git a/src/middleware/hisilicon/nostask/kernel/nos_task_minor.c b/src/middleware/hisilicon/nostask/kernel/nos_task_minor.c deleted file mode 100644 index 41ed973e16487dbcc2f24ec1075d62e54c009b4b..0000000000000000000000000000000000000000 --- a/src/middleware/hisilicon/nostask/kernel/nos_task_minor.c +++ /dev/null @@ -1,303 +0,0 @@ -/** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder 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 HOLDER 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. - * @file nos_task_minor.c - */ -#include "nos_task_internal.h" -#include "nos_buildef.h" - -#if defined(OS_OPTION_TASK_YIELD) -INLINE unsigned int OsTaskYieldProc(unsigned int nextTaskId, unsigned int taskPrio, unsigned int *yieldTo, - struct TagTskCB *currTask, struct TagListObject *tskPriorRdyList) -{ - struct TagTskCB *nextTask = NULL; - /* there is no task that user particularly wishes */ - /* therefore second task will become ready */ - if (nextTaskId == OS_TSK_NULL_ID) { - if (yieldTo != NULL) { - *yieldTo = (GET_TCB_PEND(OS_LIST_FIRST(&currTask->pendList)))->taskPid; - } - ListDelete(&currTask->pendList); - ListTailAdd(&currTask->pendList, tskPriorRdyList); - } else { - if (yieldTo != NULL) { - *yieldTo = nextTaskId; - } - - /* get task Tcb */ - nextTask = GetTcbHandle(nextTaskId); - if ((nextTask->priority == taskPrio) && TSK_StatusTst(nextTask, OS_TSK_READY)) { - ListDelete(&nextTask->pendList); - ListAdd(&nextTask->pendList, tskPriorRdyList); - } else { /* task is illegal */ - return OS_ERRNO_TSK_YIELD_INVALID_TASK; - } - } - - return NOS_OK; -} - -/* - * 描述: 调整指定优先级的任务调度顺序。调用者负责关中断 - * 备注: NA - */ -static unsigned int OsTaskYield(unsigned short taskPrio, unsigned int nextTaskId, unsigned int *yieldTo) -{ - unsigned int ret; - unsigned int tskCount = 0; - struct TagTskCB *currTask = NULL; - struct TagTskCB *runTask = NULL; - struct TagListObject *tskPriorRdyList = NULL; - struct TagListObject *currNode = NULL; - - runTask = RUNNING_TASK; - - // 锁当前running任务的rq,yield只操作本核 - OsSpinLockTaskRq(runTask); - tskPriorRdyList = &g_runQueue.readyList[taskPrio]; - /* In case there are more then one ready tasks at */ - /* this priority, remove first task and add it */ - /* to the end of the queue */ - currTask = GET_TCB_PEND(OS_LIST_FIRST(tskPriorRdyList)); - - for (currNode = tskPriorRdyList->next; currNode != tskPriorRdyList; currNode = currNode->next) { - tskCount++; - } - - if (tskCount > 1) { - ret = OsTaskYieldProc(nextTaskId, taskPrio, yieldTo, currTask, tskPriorRdyList); - if (ret != NOS_OK) { - OsSpinUnlockTaskRq(runTask); - return ret; - } - - // 如果是当前的running任务 - if (TSK_StatusTst(currTask, OS_TSK_RUNNING)) { - OsSpinUnlockTaskRq(runTask); - OsTskScheduleFast(); - - return NOS_OK; - } - } else { /* There is only one task or none */ - OsSpinUnlockTaskRq(runTask); - - return OS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK; - } - - OsSpinUnlockTaskRq(runTask); - - return NOS_OK; -} -#endif - -/* - * 描述: 延迟当前运行任务的执行 - */ -unsigned int NOS_TaskDelayInner(unsigned int tick) -{ - unsigned int ret; - uintptr_t intSave; - struct TagTskCB *runTask = NULL; - - intSave = NOS_TaskIntLock(); - // 注意:宏里面包含了UNI_FLAG的隐晦percpu变量,需要关中断保护,否则任务迁移读取的变量为它核变量 - if (OS_INT_ACTIVE) { - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_DELAY_IN_INT; - } - - /* 检查是否锁任务 */ - if (OS_TASK_LOCK_DATA != 0) { - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_DELAY_IN_LOCK; - } - /* 获取正在运行的任务 */ - runTask = RUNNING_TASK; - -#if defined(OS_OPTION_TICK) - if (tick > 0) { - OsSpinLockTaskRq(runTask); - OsTskReadyDel(runTask); - TSK_StatusSet(runTask, OS_TSK_DELAY); - OsTskTimerAdd(runTask, tick); - OsSpinUnlockTaskRq(runTask); - - /* 发生调度 */ - OsTskScheduleFastPS(intSave); - NOS_TaskIntRestore(intSave); - - return NOS_OK; - } -#else - (void)tick; - (void)runTask; -#endif - -#if defined(OS_OPTION_TASK_YIELD) - // 内部调用使用内部接口,避免for告警 - ret = OsTaskYield(runTask->priority, OS_TSK_NULL_ID, NULL); -#else - ret = NOS_OK; -#endif - NOS_TaskIntRestore(intSave); - - return ret; -} - -#if defined(OS_OPTION_TASK_YIELD) -/* - * 描述: 调整指定优先级的任务调度顺序。 - */ -unsigned int NOS_TaskYield(unsigned short taskPrio, unsigned int nextTask, unsigned int *yieldTo) -{ - uintptr_t intSave; - unsigned int ret; - - if (taskPrio > OS_TSK_PRIORITY_LOWEST) { - return OS_ERRNO_TSK_PRIOR_ERROR; - } - - /* check taskId */ - if ((nextTask != OS_TSK_NULL_ID) && (CheckTaskPidOverflow(nextTask))) { - return OS_ERRNO_TSK_ID_INVALID; - } - - /* 关中断 */ - intSave = NOS_IntLock(); - ret = OsTaskYield(taskPrio, nextTask, yieldTo); - NOS_IntRestore(intSave); - - return ret; -} -#endif - -/* - * 描述: 锁任务调度 - * 备注: NA - */ -void NOS_TaskLock(void) -{ - uintptr_t intSave; - - /* 关中断 */ - intSave = NOS_IntLock(); - - if (g_uniTaskLock == 0) { - UNI_FLAG &= (~OS_FLG_TSK_REQ); - } - - OS_TASK_LOCK_DATA++; - NOS_IntRestore(intSave); -} - -/* - * 描述: 锁任务调度 - * 备注: NA - */ -void NOS_TaskUnlock(void) -{ - /* 关中断 */ - uintptr_t intSave = NOS_IntLock(); - - if (UNLIKELY(g_uniTaskLock == 0)) { - NOS_IntRestore(intSave); - return; - } - - g_uniTaskLock--; - if (g_uniTaskLock == 0) { - if ((OS_FLG_BGD_ACTIVE & UNI_FLAG) != 0) { - OsTskScheduleFastPS(intSave); - } - } - - NOS_IntRestore(intSave); -} - -#if defined(OS_OPTION_306X) -unsigned long NOS_TaskUpdateExpirCnt(unsigned int taskPid) -{ - uintptr_t intSave; - unsigned int cnt = 0; - struct TagTskCB *taskCB = NULL; - /* check taskId */ - if (CheckTaskPidOverflow(taskPid)) { - return OS_ERRNO_TSK_ID_INVALID; - } - /* get task Tcb */ - taskCB = GetTcbHandle(taskPid); - intSave = NOS_TaskIntLock(); - /* 判断任务是否存在 */ - if (TSK_IsUnused(taskCB)) { - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_NOT_CREATED; - } - /* 判断超时次数 */ - cnt = taskCB->expirationCnt; - if (cnt > 0) { - taskCB->expirationCnt--; - } - NOS_TaskIntRestore(intSave); - return cnt; -} - -unsigned int NOS_TaskStartPeriod(unsigned int taskPid, unsigned int timeout) -{ - uintptr_t intSave; - struct TagTskCB *taskCB = NULL; - /* check taskId */ - if (CheckTaskPidOverflow(taskPid)) { - return OS_ERRNO_TSK_ID_INVALID; - } - /* get task Tcb */ - taskCB = GetTcbHandle(taskPid); - intSave = NOS_TaskIntLock(); - /* 判断任务是否存在 */ - if (TSK_IsUnused(taskCB)) { - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_NOT_CREATED; - } - TSK_StatusSet(taskCB, OS_TSK_PERIOD); - OsTskTimerAdd(taskCB, timeout); - NOS_TaskIntRestore(intSave); - return NOS_OK; -} - -unsigned int NOS_TaskStopPeriod(unsigned int taskPid) -{ - uintptr_t intSave; - struct TagTskCB *tcb = NULL; - /* check taskPid */ - if (CheckTaskPidOverflow(taskPid)) { - return OS_ERRNO_TSK_ID_INVALID; - } - /* get taskTcb */ - tcb = GetTcbHandle(taskPid); - intSave = NOS_TaskIntLock(); - /* 判断任务是否存在 */ - if (TSK_IsUnused(tcb)) { - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_NOT_CREATED; - } - if (((tcb->taskStatus) & OS_TSK_PERIOD) != 0) { - TSK_StatusClear(tcb, OS_TSK_PERIOD); - ListDelete(&tcb->timerList); - } - NOS_TaskIntRestore(intSave); - return NOS_OK; -} -#endif // OS_OPTION_306X diff --git a/src/middleware/hisilicon/nostask/nos_api/nos_task.c b/src/middleware/hisilicon/nostask/nos_api/nos_task.c deleted file mode 100644 index e5ff9012045b0f687011cd2f48e7f4df9f477440..0000000000000000000000000000000000000000 --- a/src/middleware/hisilicon/nostask/nos_api/nos_task.c +++ /dev/null @@ -1,240 +0,0 @@ -/** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the - * following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the - * following disclaimer in the documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder 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 HOLDER 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. - * @file nos_task.c - */ - -#include "nos_base_task.h" -#include "nos_config_internal.h" -#include "nos_config.h" -#include "nos_task.h" - -static NOS_SysConfig g_nosSysConfig = {.usecPerTick = 100, .cyclePerUs = 200}; - -/* - * 描述: 任务初始化。 - */ -int NOS_TaskInit(NOS_SysConfig *config) -{ - if (config == NULL || config->usecPerTick == 0 || config->getTickFunc == NULL || - config->cyclePerUs == 0) { - return -1; - } - - g_nosSysConfig.cyclePerUs = config->cyclePerUs; - g_nosSysConfig.usecPerTick = config->usecPerTick; - g_nosSysConfig.getTickFunc = config->getTickFunc; - /* set getTickFunc */ - NOS_SetNosParam(config->getTickFunc); - NOS_MoudleInit(); - return 0; -} - -unsigned long long NOS_GetCycle(void) -{ - unsigned int cycle, cycleh; - /* 时钟低32位寄存器 */ - asm volatile("csrr %0, cycle" : "=r"(cycle)); - /* 时钟高32位寄存器 */ - asm volatile("csrr %0, cycleh" : "=r"(cycleh)); - unsigned long long longCycle = (unsigned long long)cycle + (unsigned long long)cycleh * 0xFFFFFFFF; - return longCycle; -} - -int NOS_StartScheduler(void) -{ - /* OS start will switch to task_entry in system */ - return OsStart(); -} - -/* - * 描述: 任务创建但不激活。 - */ -int NOS_TaskCreateOnly(NOS_TaskInitParam *initParam, unsigned int *taskId) -{ - if (taskId == NULL) { - return -1; - } - /* 参数校验 */ - if ((initParam == NULL) || (initParam->priority > NOS_TASK_PRIORITY_LOWEST) || - (initParam->stackAddr == 0) || (initParam->stackSize == 0)) { - return -1; - } - *taskId = OS_TSK_MAX_SUPPORT_NUM + 1; - struct TskInitParam param = {0}; - param.taskEntry = (TskEntryFunc)initParam->taskEntry; - /* [0-NOS_TASK_PRIORITY_LOWEST] */ - param.taskPrio = initParam->priority; - param.name = initParam->name; - param.stackSize = initParam->stackSize; - param.stackAddr = initParam->stackAddr; - param.privateData = initParam->privateData; - param.args[0] = (uintptr_t)initParam->param; - /* 调用内部接口 */ - return (int)NOS_TaskCreateOnlyInner(taskId, ¶m); -} - -/* - * 描述: 任务创建。 - */ -int NOS_TaskCreate(NOS_TaskInitParam *initParam, unsigned int *taskId) -{ - if ((taskId == NULL) || (initParam == NULL)) { - return -1; - } - /* 参数校验 */ - if ((initParam->priority > NOS_TASK_PRIORITY_LOWEST) || - (initParam->stackAddr == 0) || (initParam->stackSize == 0)) { - return -1; - } - *taskId = OS_TSK_MAX_SUPPORT_NUM + 1; - struct TskInitParam param = {0}; - param.taskEntry = (TskEntryFunc)initParam->taskEntry; - /* [0-NOS_TASK_PRIORITY_LOWEST] */ - param.taskPrio = initParam->priority; - param.name = initParam->name; - param.stackAddr = initParam->stackAddr; - param.stackSize = initParam->stackSize; - param.args[0] = (uintptr_t)initParam->param; - param.privateData = initParam->privateData; - /* 调用内部接口 */ - return (int)NOS_TaskCreateInner(taskId, ¶m); -} - -/* - * 描述: 任务删除。 - */ -int NOS_TaskDelete(unsigned int taskId) -{ - return (int)NOS_TaskDeleteInner(taskId); -} - -/* - * 描述: 任务挂起。 - */ -int NOS_TaskSuspend(unsigned int taskId) -{ - return (int)NOS_TaskSuspendInner(taskId); -} - -/* - * 描述: 任务恢复。 - */ -int NOS_TaskResume(unsigned int taskId) -{ - return (int)NOS_TaskResumeInner(taskId); -} - -/* - * 描述: 任务延时。 - */ -int NOS_TaskDelay(unsigned int timeout) -{ - if (g_nosSysConfig.cyclePerUs == 0) { - return -1; - } - return (int)NOS_TaskDelayInner(timeout * g_nosSysConfig.cyclePerUs); -} - -/* - * 描述: 任务优先级设置。 - */ -int NOS_TaskPrioritySet(unsigned int taskId, unsigned short priority) -{ - return (int)NOS_TaskPrioritySetInner(taskId, priority); -} - -/* - * 描述: 任务优先级获取。 - */ -int NOS_TaskPriorityGet(unsigned int taskId, unsigned short *priority) -{ - return (int)NOS_TaskPriorityGetInner(taskId, priority); -} - -/* **********************timer task********************* */ - -/* - * 描述: timer task 回调函数。 - */ -unsigned long NOS_TaskUpdateExpirCnt(unsigned int taskPid); -static void PeriodTaskEntry(int param0, int param1, int param2, int param3) -{ - (void)(param2); - (void)(param3); - void *timerParam = (void *)(uintptr_t)param1; - unsigned int taskId; - /* 获取当前任务ID */ - NOS_TaskSelf(&taskId); - NOS_TimerCallBack callback = (NOS_TimerCallBack)(uintptr_t)param0; - if (callback == NULL) { - return; - } - while (1) { - /* 执行回调函数 */ - callback(timerParam); - if (NOS_TaskUpdateExpirCnt(taskId) == 0) { - /* 任务挂起 */ - NOS_TaskSuspendInner(taskId); - } - } -} - -/* - * 描述: 创建定时任务。 - */ -int NOS_CreateTimerTask(unsigned int *timerTaskId, NOS_TimerTaskInitParam *timerParam) -{ - /* 参数校验 */ - if (timerTaskId == NULL || timerParam == NULL || timerParam->callback == NULL || - g_nosSysConfig.usecPerTick == 0) { - return -1; - } - if ((timerParam->timeout < g_nosSysConfig.usecPerTick) || (timerParam->stackAddr == 0) || - (timerParam->stackSize == 0) || (timerParam->priority > NOS_TASK_PRIORITY_LOWEST)) { - return -1; - } - *timerTaskId = OS_TSK_MAX_SUPPORT_NUM + 1; - struct TskInitParam param = {0}; - param.taskEntry = (TskEntryFunc)PeriodTaskEntry; - /* [0-NOS_TASK_PRIORITY_LOWEST] */ - param.taskPrio = timerParam->priority; - param.name = timerParam->name; - param.stackSize = timerParam->stackSize; - param.stackAddr = timerParam->stackAddr; - param.privateData = (timerParam->timeout) * g_nosSysConfig.cyclePerUs; - /* real callback */ - param.args[0] = (uintptr_t)timerParam->callback; - param.args[1] = (uintptr_t)timerParam->callbackParam; - return (int)NOS_TaskCreateOnlyInner(timerTaskId, ¶m); -} - -/* cannot call this func before systick work on */ -int NOS_StartTimerTask(unsigned int taskId) -{ - /* notice: taskId must created by NOS_CreateTimerTask. */ - unsigned int timeout = (unsigned int)NOS_TaskPrivateDataGetById(taskId); - return (int)NOS_TaskStartPeriod(taskId, timeout); -} - -/* cannot call this func before systick work on */ -int NOS_StopTimerTask(unsigned int taskId) -{ - /* notice: taskId must created by NOS_CreateTimerTask. */ - return (int)NOS_TaskStopPeriod(taskId); -} - diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_adcCalibr.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_adcCalibr.h new file mode 100644 index 0000000000000000000000000000000000000000..87a21c0074b7507b2b256cf93de314208f033106 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_adcCalibr.h @@ -0,0 +1,55 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_adcCalibr.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration for adc bias calibration function. + */ +#ifndef McuMagicTag_MCS_ADCCALIB_H +#define McuMagicTag_MCS_ADCCALIB_H + +#include "adc.h" +#include "typedefs.h" + +/* Macro definitions --------------------------------------------------------------------------- */ +#define ADC_CNT_POINTS 50 /* the number of continuous adc results for calibration */ + +/** + * @brief ADC temperature calibration state. + */ +typedef enum { + ADC_CALIBR_NOT_FINISH = 0, + ADC_CALIBR_FINISH +} ADC_CALIBR_State; + +/** + * @brief Adc temperature shift calibration structure. + */ +typedef struct { + unsigned int adcShiftAccu; + unsigned int cnt; + ADC_CALIBR_State state; +} ADC_CALIBR_Handle; + + +void ADCCALIBR_Init(ADC_CALIBR_Handle *adcCalibr); + +unsigned int ADCCALIBR_Exec(ADC_CALIBR_Handle *adcCalibr, ADC_Handle *adcHandle, unsigned int soc); + +bool ADCCALIBR_IsFinish(ADC_CALIBR_Handle *adcCalibr); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_assert.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_assert.h new file mode 100644 index 0000000000000000000000000000000000000000..c61b1275c320343fdd8a3e76b93ba148a3186903 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_assert.h @@ -0,0 +1,57 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_assert.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of the assert. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_MCS_ASSERT_H +#define McuMagicTag_MCS_ASSERT_H + +/* Includes ------------------------------------------------------------------ */ +#include "baseinc.h" + +/** + * @defgroup MCS_ASSERT MCS_ASSERT + * @brief MCS ASSERT module. + * @{ + */ + +/** + * @defgroup ASSERT_Macro ASSERT Macro Function Definition + * @{ + */ +#ifdef MCS_PARAM_CHECK +#define MCS_ASSERT_PARAM BASE_FUNC_ASSERT_PARAM +#define MCS_PARAM_CHECK_NO_RET BASE_FUNC_PARAMCHECK_NO_RET +#define MCS_PARAM_CHECK_WITH_RET BASE_FUNC_PARAMCHECK_WITH_RET +#else +#define MCS_ASSERT_PARAM(para) ((void)0U) +#define MCS_PARAM_CHECK_NO_RET(para) ((void)0U) +#define MCS_PARAM_CHECK_WITH_RET(para, ret) ((void)0U) +#endif + +/** + * @} + */ + +/** + * @} + */ +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_brake.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_brake.h new file mode 100644 index 0000000000000000000000000000000000000000..e542949b3e7d7ecfcae05f79cc06cd242c801e6c --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_brake.h @@ -0,0 +1,89 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_brake.h + * @author MCU Algorithm Team + * @brief Math library. + * This file provides functions declaration of brake module. + */ + +#ifndef McuMagicTag_MCS_BRAKE_H +#define McuMagicTag_MCS_BRAKE_H + +#include "mcs_typedef.h" +#include "apt.h" +/* Typedef definitions ------------------------------------------------------------------------- */ + + +/** + * @brief Brake Param. + */ +typedef struct { + float brkTime; /**< brake time (s). */ + float maxBrkCurr; /**< maximum brake current (A). */ + + float blindDutyThr; /**< brake duty cycle when entering open-loop braking state */ + float blindBrkDutyStep; /**< large brake duty step per period. */ + + float fastBrkCurrCoeff; /**< current threshold coefficient for fast braking, recommend value: 0.5f. */ + float fastBrkDutyStep; /**< large brake duty step per period. */ + + float slowBrkDutyStep; /**< small brake duty step per period. */ + + unsigned short aptMaxCmp; /**< apt maximum count. */ +} BRAKE_Param; + +/** + * @brief Brake status enum. + */ +typedef enum { + BRAKE_CLOSED_LOOP = 0, /**< Closed loop. */ + BRAKE_OPEN_LOOP /**< Open loop. */ +} BRAKE_Status; + + +/** + * @brief Brake Stage. + */ +typedef enum { + BRAKE_INIT = 0, /**< Brake init, include APT configuration. */ + BRAKE_EXEC, /**< Brake exec, include brake current sample and brake duty adjust. */ + BRAKE_FINISHED /**< Brake finished. */ +} BRAKE_Stage; + + +/** + * @brief Brake Struct. + */ +typedef struct { + float ts; /**< control period (s). */ + float brkDuty; /**< pwm duty ratio of lower switch during brake condition (0~1). */ + float brkCurr; /**< brake current (A). */ + unsigned int tickCnt; /**< counter for calculating brake time. */ + unsigned int tickNum; /**< count number corresponding to brake time. */ + unsigned int brkFinished; /**< brake finish flag. */ + BRAKE_Stage stage; /**< brake stage. */ + BRAKE_Status status; /**< brake status. */ + BRAKE_Param brkParam; /**< brake parameter. */ +} BRAKE_Handle; + + +void BRAKE_Init(BRAKE_Handle *brake, BRAKE_Param brkParam, float ts); +void BRAKE_Clear(BRAKE_Handle *brake); +void BRAKE_Exec(BRAKE_Handle *brake, APT_RegStruct **aptAddr, float brkCurr); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_curr_ctrl.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_curr_ctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..da384be290df5720a3abbb2f1fb99c85155fb0f4 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_curr_ctrl.h @@ -0,0 +1,88 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_curr_ctrl.h + * @author MCU Algorithm Team + * @brief Current controller for motor control. + * This file provides functions declaration of the current controller module. + */ + +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_CURR_CTRL_H +#define McuMagicTag_MCS_CURR_CTRL_H + +/* Includes ------------------------------------------------------------------------------------ */ +#include "mcs_typedef.h" +#include "mcs_pid_ctrl.h" +#include "mcs_mtr_param.h" + +/** + * @defgroup CURRENT_CONTROLLER CURRENT CONTROLLER MODULE + * @brief The current controller function. + * @{ + */ + +/** + * @defgroup CURRENT_CONTROLLER_STRUCT CURRENT CONTROLLER STRUCT + * @brief The current controller's data structure definition. + * @{ + */ + +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief Current controller struct members and parameters. + */ +typedef struct { + DqAxis *idqRef; /**< Current reference in the d-q coordinate (A). */ + DqAxis *idqFbk; /**< Current feedback in the d-q coordinate (A). */ + DqAxis idqFf; /**< Current feedforward value (V). */ + PID_Handle dAxisPi; /**< d-axis current PI controller. */ + PID_Handle qAxisPi; /**< q-axis current PI controller. */ + MOTOR_Param *mtrParam; /**< Motor parameters. */ + float outLimit; /**< Current controller output voltage limitation (V). */ + float ts; /**< Current controller control period (s). */ +} CURRCTRL_Handle; +/** + * @} + */ + +/** + * @defgroup CURRENT_CONTROLLER_API CURRENT CONTROLLER API + * @brief The current controller's API declaration. + * @{ + */ + +void CURRCTRL_Init(CURRCTRL_Handle *currHandle, MOTOR_Param *mtrParam, DqAxis *idqRef, DqAxis *idqFbk, + const PI_Param dAxisPi, const PI_Param qAxisPi, float ts); + +void CURRCTRL_Reset(CURRCTRL_Handle *currHandle); + +void CURRCTRL_Clear(CURRCTRL_Handle *currHandle); + +void CURRCTRL_Exec(CURRCTRL_Handle *currHandle, DqAxis *vdqRef, float spdRef, int ffEnable); + +void CURRCTRL_SetTs(CURRCTRL_Handle *currHandle, float ts); + +/** + * @} + */ + +/** + * @} + */ + +#endif diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_curr_ff.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_curr_ff.h new file mode 100644 index 0000000000000000000000000000000000000000..7ed2012192932d304d032c3c6a9e1d4ab2a38695 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_curr_ff.h @@ -0,0 +1,31 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_curr_ff.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of current loop feedforward compensation. + */ + +#ifndef McuMagicTag_MCS_CURR_FF_H +#define McuMagicTag_MCS_CURR_FF_H + +#include "mcs_typedef.h" +#include "mcs_mtr_param.h" + +void CURRFF_Exec(DqAxis *vdqRef, DqAxis idqFbk, MOTOR_Param *param, float spdRef, int enable); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_filter.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_filter.h new file mode 100644 index 0000000000000000000000000000000000000000..78bfcb9d9fd22aecfdc8de6639eb57e43e9aa693 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_filter.h @@ -0,0 +1,62 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_filter.h + * @author MCU Algorithm Team + * @brief filter library. + * This file provides functions declaration of the filter module. + */ + +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_FILTER_H +#define McuMagicTag_MCS_FILTER_H + +/* Typedef definitions ------------------------------------------------------------------------- */ + +/** + * @brief 1st-order Filter struct members and parameters. + * LPF(low-pass filter): y(k)=a1*y(k-1)+b1*u(k) + * HPF(high-pass filter): y(k)=a1*y(k-1)+b1*u(k)+b2*u(k-1) + */ +typedef struct { + float yLast; /**< Last output of 1st-order filter. */ + float uLast; /**< Last input variable. */ + float fc; /**< 1st-order filter cut-off frequency (Hz). */ + float ts; /**< 1st-order filter running period. */ + float a1; /**< Coefficient of 1st-order filter. */ + float b1; /**< Coefficient of 1st-order filter. */ + float b2; /**< Coefficient of 1st-order filter. */ +} FOFLT_Handle; + + +/** + * @defgroup FILTER_API FILTER API + * @brief Filter function API declaration. + * Transfer Func: G(s) = kw/(s+w), k = 1. + */ + +void FOLPF_Init(FOFLT_Handle *lpfHandle, float ts, float fc); +void FOLPF_Clear(FOFLT_Handle *lpfHandle); +float FOLPF_Exec(FOFLT_Handle *lpfHandle, float u); +void FOLPF_SetTs(FOFLT_Handle *lpfHandle, float ts); +void FOLPF_SetFc(FOFLT_Handle *lpfHandle, float fc); + +/** + * @} + */ + +#endif diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_volt_det.c b/src/middleware/thirdparty/sysroot/include/control_library/mcs_fosmo.h similarity index 34% rename from src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_volt_det.c rename to src/middleware/thirdparty/sysroot/include/control_library/mcs_fosmo.h index 8768fcc1160e2eba1ef7f2975453a8bc0657fff8..eb4ef92914b5b6710a2a07466750bbee281a9f9c 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_volt_det.c +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_fosmo.h @@ -15,130 +15,93 @@ * 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. - * @file mcs_volt_det.c + * @file mcs_fosmo.h * @author MCU Algorithm Team - * @brief This file contains dc-link voltage protection api declaration. + * @brief Sliding-mode observer (SMO) for motor position acquisition. + * This file provides position SMO and Phase-locked loop (PLL) declaration for motor control. */ +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_FOSMO_H +#define McuMagicTag_MCS_FOSMO_H -#include "mcs_volt_det.h" -#include "mcs_assert.h" - +/* Includes ------------------------------------------------------------------------------------ */ +#include "mcs_mtr_param.h" +#include "mcs_typedef.h" +#include "mcs_pll.h" +#include "mcs_filter.h" /** - * @brief Initilization over voltage detection function. - * @param ovd Over temperature dectection handle. - * @param overVoltThr Over voltage value threshold. - * @param timeThr Over current time threshold (s). - * @param ts Ctrl period (s). - * @retval None. + * @defgroup FOSMO_MODULE FOSMO MODULE + * @brief The First Order Sliding Mode Observer module. + * @{ */ -void OVD_Init(OVD_Handle *ovd, float overVoltThr, float timeThr, float ts) -{ - MCS_ASSERT_PARAM(ovd != NULL); - MCS_ASSERT_PARAM(overVoltThr > 0.0f); - MCS_ASSERT_PARAM(timeThr > 0.0f); - MCS_ASSERT_PARAM(ts > 0.0f); - /* Time threshold and current threshold. */ - ovd->overVoltThr = overVoltThr; - ovd->timeThr = timeThr; - - ovd->ts = ts; - /* Detection time limit calculation. */ - ovd->detCntLimit = (unsigned int)(ovd->timeThr / ovd->ts); -} - /** - * @brief Over voltage detection. - * @param ovd Over voltage dectection handle. - * @param voltAmp Voltage vlaue. - * @retval Whether the motor is over current. + * @defgroup FOSMO_STRUCT FOSMO STRUCT + * @brief The First Order Sliding Mode Observer's data struct definition. + * @{ */ -bool OVD_Exec(OVD_Handle *ovd, float voltAmp) -{ - MCS_ASSERT_PARAM(ovd != NULL); - MCS_ASSERT_PARAM(voltAmp > 0.0f); - /* Voltage threshold judgment. */ - if (voltAmp < ovd->overVoltThr) { - ovd->detCnt = 0; - return false; - } - /* Over voltage detection time judgment. */ - if (ovd->detCnt < ovd->detCntLimit) { - ovd->detCnt++; - return false; - } - - return true; -} - +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief Position SMO struct members and parameters. + */ +typedef struct { + float ts; /**< SMO control period (s). */ + float a1; /**< Coefficient of differential equation. */ + float a2; /**< Coefficient of differential equation. */ + float kSmo; /**< SMO gain. */ + float lambda; /**< SMO coefficient of cut-off frequency, its value = lambda * we. */ + float emfLpfMinFreq; /**< The minimum cut-off frequency of back-EMF filter. */ + float pllBdw; /**< The PLL bandwidth. */ + float fcLpf; /**< The cut-off frequency of First-order LPF for speed (Hz). */ + float filCompAngle; /**< Compensation angle (atan(1/lambda)) for the back-EMF filter. */ + float elecAngle; /**< SMO estimated electronic angle (rad). */ + float spdEst; /**< SMO estimated electronic speed (Hz). */ + MOTOR_Param *mtrParam; + AlbeAxis emfEstUnFil; /**< Estimated back-EMF in the alpha-beta coordinate by differential equation. */ + AlbeAxis ialbeEst; /**< SMO estimated currents in the alpha-beta coordinate. */ + AlbeAxis ialbeEstLast; /**< SMO history values of estimated currents in the alpha-beta coordinate. */ + AlbeAxis emfEstFil; /**< SMO estimated back-EMF in the alpha-beta coordinate. */ + PLL_Handle pll; /**< PLL handle. */ + FOFLT_Handle spdFilter; /**< First-order LPF for speed. */ +} FOSMO_Handle; /** - * @brief Clear history value. - * @param ovd Over temperature dectection handle. - * @retval None. + * @} */ -void OVD_Clear(OVD_Handle *ovd) -{ - MCS_ASSERT_PARAM(ovd != NULL); - ovd->detCnt = 0; -} +typedef struct { + float gain; + float lambda; + float fcEmf; + float pllBdw; + float fcLpf; +} FOSMO_Param; /** - * @brief Initilization lower voltage detection function. - * @param lvd Over temperature dectection handle. - * @param lowerVoltThr Over voltage value threshold. - * @param timeThr Over current time threshold (s). - * @param ts Ctrl period (s). - * @retval None. + * @defgroup FOSMO_API FOSMO API + * @brief The First Order Sliding Mode Observer's API declaration. + * @{ */ -void LVD_Init(LVD_Handle *lvd, float lowerVoltThr, float timeThr, float ts) -{ - MCS_ASSERT_PARAM(lvd != NULL); - MCS_ASSERT_PARAM(lowerVoltThr > 0.0f); - MCS_ASSERT_PARAM(timeThr > 0.0f); - MCS_ASSERT_PARAM(ts > 0.0f); - /* Time threshold and current threshold. */ - lvd->lowerVoltThr = lowerVoltThr; - lvd->timeThr = timeThr; - - lvd->ts = ts; - /* Detection time limit calculation. */ - lvd->detCntLimit = (unsigned int)(lvd->timeThr / lvd->ts); -} +void FOSMO_Init(FOSMO_Handle *fosmo, FOSMO_Param foSmoParam, MOTOR_Param *mtrParam, float ts); + +void FOSMO_Exec(FOSMO_Handle *fosmo, const AlbeAxis *ialbeFbk, const AlbeAxis *valbeRef, float refHz); + +void FOSMO_ParamUpdate(FOSMO_Handle *fosmo, float gain, float pllBdw, float fc); + +void FOSMO_Clear(FOSMO_Handle *fosmo); + +void FOSMO_SetTs(FOSMO_Handle *fosmo, float ts); + +void FOSMO_SetLambda(FOSMO_Handle *fosmo, float lambda); /** - * @brief Over temperature detection. - * @param lvd Over temperature dectection handle. - * @param voltAmp Voltage vlaue. - * @retval Whether the motor is over current. + * @} */ -bool LVD_Exec(LVD_Handle *lvd, float voltAmp) -{ - MCS_ASSERT_PARAM(lvd != NULL); - MCS_ASSERT_PARAM(voltAmp > 0.0f); - /* Voltage threshold judgment. */ - if (voltAmp > lvd->lowerVoltThr) { - lvd->detCnt = 0; - return false; - } - /* Lower voltage detection time judgment. */ - if (lvd->detCnt < lvd->detCntLimit) { - lvd->detCnt++; - return false; - } - return true; -} /** - * @brief Clear history value. - * @param lvd Over temperature dectection handle. - * @retval None. + * @} */ -void LVD_Clear(LVD_Handle *lvd) -{ - MCS_ASSERT_PARAM(lvd != NULL); - lvd->detCnt = 0; -} \ No newline at end of file + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_fw_ctrl.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_fw_ctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..c5714bbefb48c214d75cc877a3942abe9b3e6e18 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_fw_ctrl.h @@ -0,0 +1,47 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + * @file mcs_fw_ctrl.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of Flux-Weakening control. + */ +#ifndef McuMagicTag_MCS_FW_CTRL_H +#define McuMagicTag_MCS_FW_CTRL_H + +#include "typedefs.h" +#include "mcs_typedef.h" + +typedef struct { + bool enable; + float udcThreshPer; /* thr * ONE_DIV_SQRT3 */ + float ts; + float idSlope; + float idRef; /* reference instruction value. */ + float idMaxAmp; /* Maximum id ingested */ + + float currMax; /* maximum phase current (A) */ + float currMaxSquare; /* square of maximum current. */ + float idDemag; /* demagnetizing d-axis current (A) */ +} FW_Handle; + +void FW_Init(FW_Handle *fw, float ts, bool enable, float currMax, float idDemag, float thr, float slope); + +void FW_Exec(FW_Handle *fw, DqAxis udqRef, float udc, DqAxis *idqRefRaw); + +void FW_SetTs(FW_Handle *fw, float ts); + +void FW_Clear(FW_Handle *fw); +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_if_ctrl.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_if_ctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..2448e832f912c1ebabdbecc19485df8b4b821e96 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_if_ctrl.h @@ -0,0 +1,77 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_if_ctrl.h + * @author MCU Algorithm Team + * @brief Current controller for motor I/F control. + * This file provides functions declaration of I/F control. + */ + +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_IF_CTRL_H +#define McuMagicTag_MCS_IF_CTRL_H + +/** + * @defgroup IF_MODULE I/F MODULE + * @brief The I/F motor control method module. + * @{ + */ + +/** + * @defgroup IF_STRUCT I/F STRUCT + * @brief The I/F motor control method data struct definition. + * @{ + */ +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief General IF controller struct members and parameters. + */ +typedef struct { + float anglePeriod; /**< Calculation period of the I/F angle (s). */ + float curAmpPeriod; /**< Calculation period of the I/F current amplitude (s). */ + + float targetAmp; /**< Target value of the I/F current (A). */ + float curAmp; /**< Current value of the I/F current (A). */ + float stepAmp; /**< Increment of the I/F current (A). */ + float angle; /**< I/F output angle. */ +} IF_Handle; + +/** + * @defgroup IF_API I/F API + * @brief The I/F motor control method API declaration. + * @{ + */ + +void IF_Init(IF_Handle *ifHandle, float targetAmp, float currSlope, float stepAmpPeriod, float anglePeriod); + +void IF_Clear(IF_Handle *ifHandle); + +float IF_CurrAmpCalc(IF_Handle *ifHandle); + +float IF_CurrAngleCalc(IF_Handle *ifHandle, float spdRef); + +void IF_SetAngleTs(IF_Handle *ifHandle, float ts); + +/** + * @} + */ + +/** + * @} + */ + +#endif diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_lpfRk4.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_lpfRk4.h new file mode 100644 index 0000000000000000000000000000000000000000..3cf8b2a7635095fbae0ec09e1c5a1348716ff662 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_lpfRk4.h @@ -0,0 +1,39 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_LpfRk4.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of 4-order low-pass filter. + */ +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_LPFRK4_H +#define McuMagicTag_MCS_LPFRK4_H + + +/** + * @brief First Order Low-pass-filter by RK4. + */ +typedef struct { + float y1; +} LPF_RK4_Handle; + + +void LPFRK4_Clear(LPF_RK4_Handle *lpf); + +float LPFRK4_Exec(LPF_RK4_Handle *lpf, float u, float freq, float ts); + +#endif \ No newline at end of file diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/common/mcs_fault_detection.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_math.h similarity index 45% rename from src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/common/mcs_fault_detection.h rename to src/middleware/thirdparty/sysroot/include/control_library/mcs_math.h index ff340fb7e8a101e57f0c9454064b891149a4e79c..9dab4d01745e1655c3686b340511334eeb23fe8b 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/common/mcs_fault_detection.h +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_math.h @@ -15,59 +15,85 @@ * 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. - * @file mcs_fault_detection.h + * @file mcs_math.h * @author MCU Algorithm Team - * @brief This file contains fault dection struct and api declaration. + * @brief Math library. + * This file provides math functions declaration of motor math module. */ -/* Define to prevent recursive inclusion ------------------------------------- */ -#ifndef McuMagicTag_MCS_FAULT_DETECTION_H -#define McuMagicTag_MCS_FAULT_DETECTION_H +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_MATH_H +#define McuMagicTag_MCS_MATH_H -#include "mcs_openphs_det.h" -#include "mcs_stall_det.h" -#include "mcs_unbalance_det.h" -#include "mcs_curr_det.h" -#include "mcs_temp_det.h" -#include "mcs_volt_det.h" -#include "mcs_stall_det.h" -#include "mcs_user_config.h" +/* Includes ------------------------------------------------------------------------------------ */ +#include "mcs_typedef.h" +#include "base_math.h" -typedef union { - unsigned short all; - struct { - unsigned short overCurrErr : 1; /**< Indicates that phase current(s) is over protected value. */ - unsigned short overVoltErr : 1; /**< Indicates that dc-link voltage is over protected value. */ - unsigned short lowerVoltErr : 1; /**< Indicates that dc-link voltage is lower than protected value */ - unsigned short overTempErr : 1; /**< Indicates that temperature is over protected value. */ - unsigned short motorStallErr : 1; /**< Indicates that rotor is stalling. */ - unsigned short unbalanceErr : 1; /**< Indicates that three phase currents is out-of-balance. */ - unsigned short phsOpenErr : 1; /**< Indicates that phase winding(s) is open. */ - unsigned short phsOpenU : 1; /**< Indicates that u phase fails when phsOpenErr occurs. */ - unsigned short phsOpenV : 1; /**< Indicates that v phase fails when phsOpenErr occurs. */ - unsigned short phsOpenW : 1; /**< Indicates that w phase fails when phsOpenErr occurs. */ - unsigned short multiPhs : 1; /**< Indicates that multi-phases fail when phsOpenErr occurs.*/ - } Bit; -} FAULT_Status; +/** + * @brief sin cos define + */ +typedef struct { + float sin; /**< The sine value of input angle. */ + float cos; /**< The cosine value of input angle. */ +} TrigVal; typedef struct { - FAULT_Status faultStatus; - OCD_Handle ocd; - OVD_Handle ovd; - LVD_Handle lvd; - OTD_Handle otd; - OPD_Handle opd; - STD_Handle std; - UNBAL_Handle unbal; -} FAULT_DET_Handle; + float sum; + float val; + unsigned int periodCnt; +} RMS_Handle; -void FaultDetect_Init(FAULT_DET_Handle *faultDet); +/** + * @brief This function returns the sliding average filtering result. + * @param newVal Current filtered value. + * @param oldVal Historical filter value. + * @param percent Filter percentage. + * @retval Sliding average filtering result. + */ +static inline float AvgFlt(float newVal, float oldVal, float percent) +{ + return newVal * percent + oldVal * (1.0f - percent); +} -bool FaultDetect_Exec(FAULT_DET_Handle *faultDet, float currAmp, float tempAmp, float voltAmp, float spdFbk); +/** + * @brief The internal round up/down function. + * @param x The input float x. + * @retval The integer value of round result. + */ +static inline int RoundInt(float x) +{ + return (int)(x + 0.5f); /* round function */ +} -void FaultDetect_Clear(FAULT_DET_Handle *faultDet); +/** + * @defgroup MATH_API MATH API + * @brief The common math API definition. + * @{ + */ +float GetSin(float angle); +float GetCos(float angle); +void TrigCalc(TrigVal *val, float angle); +void ParkCalc(const AlbeAxis *albe, float angle, DqAxis *dq); +void InvParkCalc(const DqAxis *dq, float angle, AlbeAxis *albe); +void ClarkeCalc(const UvwAxis *uvw, AlbeAxis *albe); +float Abs(float val); +float Clamp(float val, float upperLimit, float lowerLimit); +float Max(float val1, float val2); +float Min(float val1, float val2); +float Sqrt(float val); +float AngleSub(float angle1, float angle2); +float Mod(float val1, float val2); +float Sat(float u, float delta); +float Atan2(float x, float y); +unsigned short PreLookBinSearch(float u, const float *table, + unsigned short maxIndex, + float *fraction); +float RmsCalc(RMS_Handle *rms, float realVal, float freq, float ts); +/** + * @} + */ #endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_math_const.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_math_const.h new file mode 100644 index 0000000000000000000000000000000000000000..c2c779e8f52ab9bfdc7591f799b63b5f12cac9ca --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_math_const.h @@ -0,0 +1,74 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_math_const.h + * @author MCU Algorithm Team + * @brief This file provides math constant macro definition functionality for + * managing math calculation number definitions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_MCS_MATH_CONST_H +#define McuMagicTag_MCS_MATH_CONST_H + +/** + * @addtogroup MATH + * @brief Math const definition. + * @{ + */ + +/** + * @defgroup MATH_CONST MATH CONST + * @brief The common math const definition for motor control. + * @{ + */ +/* Macro definitions ---------------------------------------------------------*/ +#define ONE_DIV_THREE (0.3333333f) /**< 1/3 */ +#define TWO_DIV_THREE (0.6666667f) /**< 2/3 */ +#define ONE_PI_DIV_SIX (0.5235988f) /**< PI/6 */ +#define ONE_PI_DIV_THREE (1.047197f) /**< PI/3 */ +#define ONE_PI (3.141593f) /**< PI */ +#define DOUBLE_PI_DIV_THREE (2.094395f) /**< 2PI/3 */ +#define DOUBLE_PI (6.283185f) /**< 2*PI */ +#define SQRT3_DIV_TWO (0.8660254f) /**< Sqrt(3)/2 */ +#define ONE_DIV_SQRT3 (0.5773503f) /**< 1/sqrt(3) */ +#define ONE_DIV_DOUBLE_PI (0.1591549f) /**< 1/(2*PI) */ +#define RAD_TO_DEG (57.29578f) /**< 1/pi*180 */ +#define RAD_TO_DIGITAL (10430.06f) /**< 1/pi*32767 */ +#define DIGITAL_TO_RAD (0.00009587673f) /**< pi/32767 */ +#define HALF_PI (1.5707963f) /**< 0.5*pi */ +#define THREE_PI_DIV_TWO (4.7123890f) /**< 1.5*pi */ +#define ONE_DIV_SIX (0.16666667f) /**< 1/6 */ +#define SEVEN_DIV_SIX (1.16666667f) /**< 7/6 */ +#define SIXTY_FIVE_DIV_SIX (10.8333333f) /**< 65/6 */ +#define SEVENTY_ONE_DIV_SIX (11.8333333f) /**< 71/6 */ +#define ONE_DIV_NINE (0.11111111f) /**< 1/9 */ +#define ONE_DIV_TWELVE (0.08333333f) /**< 1/12 */ +#define SQRT2 (1.41421356f) /**< sqrt(2) */ +#define SQRT2_DIV_TWO (0.70710678f) /**< sqrt(2)/2 */ +#define SQRT3 (1.73205081f) /**< sqrt(3) */ +#define SMALL_FLOAT (0.00000001f) +#define LARGE_FLOAT (10000.0f) +/** + * @} + */ + + /** + * @} + */ + +#endif /* McuMagicTag_MCS_MATH_CONST_H */ diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_temp_det.c b/src/middleware/thirdparty/sysroot/include/control_library/mcs_mtr_param.h similarity index 51% rename from src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_temp_det.c rename to src/middleware/thirdparty/sysroot/include/control_library/mcs_mtr_param.h index 6d9f35020c4acfb0c53c8ab6cd955030582bcc00..d0b8200460eb710c5264b1853c968b744c53317a 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_temp_det.c +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_mtr_param.h @@ -15,66 +15,46 @@ * 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. - * @file mcs_temp_det.c + * @file mcs_mtr_param.h * @author MCU Algorithm Team - * @brief This file contains current protection data struct and api declaration. + * @brief This file provides data structure define of motor parameters. */ +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_MTR_PARAM_H +#define McuMagicTag_MCS_MTR_PARAM_H -#include "mcs_temp_det.h" +/* Typedef definitions ------------------------------------------------------------------------- */ #include "mcs_assert.h" - /** - * @brief Initilization over temperature detection function. - * @param otd Over temperature dectection handle. - * @param tempThr temperature value threshold. - * @param timeThr Over current time threshold (s). - * @param ts Ctrl period (s). - * @retval None. + * @defgroup MOTOR_PARAMETER MOTOR PARAMETER + * @brief The motor parameter definitions. + * @{ */ -void OTD_Init(OTD_Handle *otd, float tempThr, float timeThr, float ts) -{ - MCS_ASSERT_PARAM(otd != NULL); - MCS_ASSERT_PARAM(timeThr > 0.0f); - MCS_ASSERT_PARAM(ts > 0.0f); - /* Time threshold and current threshold. */ - otd->tempThr = tempThr; - otd->timeThr = timeThr; - - otd->ts = ts; - /* Detection time limit calculation. */ - otd->detCntLimit = (unsigned int)(otd->timeThr / otd->ts); -} - /** - * @brief Over temperature detection. - * @param otd Over temperature dectection handle. - * @param tempAmp Temperature vlaue. - * @retval Whether the motor is over current. + * @brief motor parameters data structure */ -bool OTD_Exec(OTD_Handle *otd, float tempAmp) -{ - MCS_ASSERT_PARAM(otd != NULL); - /* Current threshold judgment. */ - if (tempAmp < otd->tempThr) { - otd->detCnt = 0; - return false; - } - /* Over temperature detection time judgment. */ - if (otd->detCnt < otd->detCntLimit) { - otd->detCnt++; - return false; - } - return true; -} +typedef struct { + unsigned short mtrNp; /**< Numbers of pole pairs. */ + float mtrRs; /**< Resistor of stator, Ohm. */ + float mtrLd; /**< Inductance of D-axis, H. */ + float mtrLq; /**< Inductance of Q-axis, H. */ + float mtrLs; /**< Average inductance, H. */ + float mtrPsif; /**< Permanent magnet flux, Wb. */ + float mtrJ; /**< Rotor inertia, Kg*m2. */ + float maxElecSpd; /**< Max elec speed, Hz. */ + float maxCurr; /**< Max current, A. */ + float maxTrq; /**< Max torque, Nm. */ + float busVolt; /**< Bus voltage, V. */ + /* Encoder parameters */ + unsigned int mtrPPMR; /**< pulse per mechanical round */ + unsigned int zShift; /**< pulse Z shift */ +} MOTOR_Param; + +void MtrParamInit(MOTOR_Param *handle, const MOTOR_Param motorTable); /** - * @brief Clear history value. - * @param otd Over temperature dectection handle. - * @retval None. + * @} */ -void OTD_Clear(OTD_Handle *otd) -{ - MCS_ASSERT_PARAM(otd != NULL); - otd->detCnt = 0; -} \ No newline at end of file + +#endif diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_curr_det.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_openphs_det.h similarity index 72% rename from src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_curr_det.h rename to src/middleware/thirdparty/sysroot/include/control_library/mcs_openphs_det.h index 56b9242d67c7a622ddc07888717dc86863d75842..771953d8658c923029c5175b3eb1e0d69a0bd745 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_curr_det.h +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_openphs_det.h @@ -15,29 +15,37 @@ * 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. - * @file mcs_curr_det.h + * @file mcs_openphs_det.h * @author MCU Algorithm Team - * @brief This file contains current protection data struct and api declaration. + * @brief This file contains self-check open phase fault detection function data struct and api declaration. */ - + /* Define to prevent recursive inclusion ------------------------------------- */ -#ifndef McuMagicTag_MCS_CURR_DET_H -#define McuMagicTag_MCS_CURR_DET_H +#ifndef McuMagicTag_MCS_OPENPHS_DET_H +#define McuMagicTag_MCS_OPENPHS_DET_H #include "typedefs.h" +typedef enum { + OPD_U_V = 0, + OPD_V_U, + OPD_V_W, + OPD_W_V, + OPD_W_U, + OPD_U_W, + OPD_END +} OPD_Index; + typedef struct { - float currThr; /**< Current threshold. */ - float timeThr; /**< Detection time threshold. */ - - unsigned int detCnt; /**< Detection count. */ - unsigned int detCntLimit; /**< Detection count threshold. */ - float ts; /**< Control period (s). */ -} OCD_Handle; + float minOpenPhsCurr; /* Minimum current for open-phase detection (A). */ + bool isOpenPhsU; + bool isOpenPhsV; + bool isOpenPhsW; +} OPD_Handle; -void OCD_Init(OCD_Handle *ocd, float currThr, float timeThr, float ts); +void OPD_Init(OPD_Handle *opd, float minOpenPhsCurr); -bool OCD_Exec(OCD_Handle *ocd, float currAmp); +bool OPD_Exec(OPD_Handle *opd, const float *iuvw); -void OCD_Clear(OCD_Handle *ocd); +void OPD_Clear(OPD_Handle *opd); #endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_pid_ctrl.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_pid_ctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..8b967a5e4160e46497529a285f0e8e12d26ab8f0 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_pid_ctrl.h @@ -0,0 +1,109 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_pid_ctrl.h + * @author MCU Algorithm Team + * @brief General PI controller. + * This file provides functions declaration of the PI controller module. + */ + +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_PID_CTRL_H +#define McuMagicTag_MCS_PID_CTRL_H + +/** + * @defgroup PID PID + * @brief The PID module. + * @{ + */ + +/** + * @defgroup PID_STRUCT PID STRUCT + * @brief The PID control structure definition. + * @{ + */ +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief General PID Controller struct members and parameters. + */ +typedef struct { + float error; /**< Error feedback. */ + float errorLast; /**< Error feedback history values. */ + float fbkVal; /**< Current feedback value. */ + float fbkValLast; /**< Last feedback value. */ + float feedforward; /**< Feedforward item. */ + float integral; /**< Integral item. */ + float saturation; /**< Saturation value of the integral item. */ + float differ; /**< Differential item. */ + float kp; /**< Gained of the proportional item. */ + float ki; /**< Gained of the integral item, not multiplied by control period. */ + float kd; /**< Gained of the differential item. */ + float ns; /**< Filter parameter of the differential item. */ + float ka; /**< Gained of the saturation item. */ + float ts; /**< Control period (s) */ + float upperLimit; /**< The upper limit value of the pid comp output. */ + float lowerLimit; /**< The lower limit value of the pid output. */ +} PID_Handle; + +typedef struct { + float kp; + float ki; + float upperLim; + float lowerLim; +} PI_Param; + +typedef struct { + float kp; + float ki; + float kd; + float ns; /**< Filter parameter of the differential item. */ + float ka; /**< Gained of the saturation item. */ + float saturation; + float upperLim; + float lowerLim; +} PID_Param; +/** + * @} + */ + +/** + * @defgroup PID_API PID API + * @brief The PID control API definitions. + * @{ + */ + +void PID_Reset(PID_Handle *pidHandle); +void PID_Clear(PID_Handle *pidHandle); +float PI_Exec(PID_Handle *pidHandle); +float PID_Exec(PID_Handle *pidHandle); +float PID_ExecDiffWithFbk(PID_Handle *pidHandle); + +void PID_SetKp(PID_Handle *pidHandle, float kp); +void PID_SetKi(PID_Handle *pidHandle, float ki); +void PID_SetKd(PID_Handle *pidHandle, float kd); +void PID_SetNs(PID_Handle *pidHandle, float ns); +void PID_SetTs(PID_Handle *pidHandle, float ts); +void PID_SetLimit(PID_Handle *pidHandle, float limit); +/** + * @} + */ + +/** + * @} + */ + +#endif diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_pll.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_pll.h new file mode 100644 index 0000000000000000000000000000000000000000..b66eb8e05112e6be3e99d0d19a0090a7bc71138f --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_pll.h @@ -0,0 +1,72 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_pll.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of Phase-locked loop (PLL) module. + */ + +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_PLL_H +#define McuMagicTag_MCS_PLL_H + +/* Includes ------------------------------------------------------------------------------------ */ +#include "mcs_pid_ctrl.h" + +/** + * @defgroup PLL_MODULE PLL MODULE + * @brief The PLL module. + * @{ + */ + +/** + * @defgroup PLL_STRUCT PLL STRUCT + * @brief The PLL module data structure. + * @{ + */ +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief PLL struct. + */ +typedef struct { + PID_Handle pi; /**< PI controller for the PLL. */ + float minAmp; /**< Minimum value of the input value in case of the divergence of the PLL. */ + float ts; /**< Control period of the PLL. */ + float ratio; /**< Conversion factor, ts * 65535 / TWO_PI. */ + float freq; /**< Output estimated frequency (Hz). */ + float angle; /**< Output estimated phasse angle. */ +} PLL_Handle; + + +/** + * @defgroup PLL_API PLL API + * @brief The PLL module API definitions. + */ + +void PLL_Init(PLL_Handle *pllHandle, float ts, float bdw); + +void PLL_Reset(PLL_Handle *pllHandle); + +void PLL_Clear(PLL_Handle *pllHandle); + +void PLL_Exec(PLL_Handle *pllHandle, float sinVal, float cosVal); + +void PLL_SetTs(PLL_Handle *pllHandle, float ts); + +void PLL_ParamUpdate(PLL_Handle *pllHandle, float bdw); + +#endif diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_pos_ctrl.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_pos_ctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..f285a16c27903ef73e984b26294000847b55b64f --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_pos_ctrl.h @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2022 - 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_pos_ctrl.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of position control . + */ +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_MCS_POS_CTRL_H +#define McuMagicTag_MCS_MCS_POS_CTRL_H + +/* Includes ------------------------------------------------------------------------------------ */ +#include "mcs_typedef.h" +#include "mcs_pid_ctrl.h" +#include "mcs_ramp_mgmt.h" +#include "mcs_mtr_param.h" + + +/* Macro definitions --------------------------------------------------------------------------- */ + +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief Position control mode. + */ +typedef enum { + POSCTRL_MODE_CONTINUOUS = 0, + POSCTRL_MODE_TRAJ +} POSCTRL_Mode; + +typedef enum { + TRAJ_STAGE_INDEX_0 = 0, + TRAJ_STAGE_INDEX_1, + TRAJ_STAGE_INDEX_2, + TRAJ_STAGE_INDEX_3, + TRAJ_STAGE_INDEX_4, + TRAJ_STAGE_INDEX_5, + TRAJ_STAGE_INDEX_6, + TRAJ_STAGE_INDEX_7, +} POSCTRL_TRAJ_STAGE; + +/** + * @brief Position controller struct members and parameters. + */ +typedef struct { + PID_Handle posPid; /**< PID controller struct in the position controller. */ + float posTarget; /**< position controller input target value (rad) */ + float posTargetBk; + RMG_Handle posRmg; /**< position reference ramp management . */ + float ts; /**< position controller control period (s). */ + int angFbkLoop; /**< feedback position loop count. */ + float angFbkPrev; /**< feedback position in last cycle (rad). */ + float posFbk; /**< feedback position absolutely (rad). */ + float posIncRef; /**< position controller reference (rad) */ + float posIncRefPrev; /**< position controller reference in last cycle (rad) */ + float spdRef; /**< position controller outpur speed reference (Hz) */ + float posRef; /**< position controller reference (rad) */ + float posFbkPrev; + float posErr; + + /* trajectory planning */ + /* position controller work mode. 0: continuous mode; 1: trajectory control mode. */ + /* trajectory mode can only be enabled when input mode is set absolute position. */ + POSCTRL_Mode mode; + float posTargetShadow; + float runTime; /**< single trajectory control last time time (s). */ + float timeTick; /**< trajectory control inner timer (s) */ + float deltaTime; + float accMax; + float jerk; + float deltaTimeSq; + float deltaTimeCu; + float timeStg[7]; /* Seven-segment trajectory time */ +} POSCTRL_Handle; + +/** + * @defgroup POSITION_CONTROLLER_API POSITION CONTROLLER API + * @brief The position controller API declaration. + * @retval Speed Reference. + */ +void POSCTRL_Clear(POSCTRL_Handle *posHandle); +void POSCTRL_Init(POSCTRL_Handle *posHandle, const PID_Param *pidCtrlTable, float ts, float posSlope); +float POSCTRL_PidExec(POSCTRL_Handle *posHandle, float posErr); +void POSCTRL_ModeSelect(POSCTRL_Handle *posHandle, POSCTRL_Mode mode); +void POSCTRL_SetSlope(POSCTRL_Handle *posHandle, float slope); +void POSCTRL_SetTarget(POSCTRL_Handle *posHandle, float posTarget); +float POSCTRL_TrajCtrlExec(POSCTRL_Handle *posHandle, float posErr); +float POSCTRL_Exec(POSCTRL_Handle *posHandle, float posFbk); +float POSCTRL_AngleExpand(POSCTRL_Handle *posHandle, float angFbk); +void POSCTRL_SetKp(POSCTRL_Handle *posHandle, float kp); +void POSCTRL_SetKi(POSCTRL_Handle *posHandle, float ki); +void POSCTRL_SetKd(POSCTRL_Handle *posHandle, float kd); +void POSCTRL_SetNs(POSCTRL_Handle *posHandle, float ns); +void POSCTRL_TrajCtrlPrepare(POSCTRL_Handle *posHandle, float posFbk, float *posIncRef); + +#endif /* McuMagicTag_MCS_POS_CTRL_H */ \ No newline at end of file diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_temp_det.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_power_mgmt.h similarity index 66% rename from src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_temp_det.h rename to src/middleware/thirdparty/sysroot/include/control_library/mcs_power_mgmt.h index 89ef5e381124f748603fd6f299ceed7fd1724076..04c4f93bab0bc5e0f5815fc81b56e52d0a00853a 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_temp_det.h +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_power_mgmt.h @@ -15,29 +15,32 @@ * 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. - * @file mcs_temp_det.h + * @file mcs_power_mgmt.h * @author MCU Algorithm Team - * @brief his file contains over temperature protection api declaration. + * @brief This file provides functions of motor average power management. */ - /* Define to prevent recursive inclusion ------------------------------------- */ -#ifndef McuMagicTag_MCS_TEMP_DET_H -#define McuMagicTag_MCS_TEMP_DET_H +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_POWER_MGMT_H +#define McuMagicTag_MCS_POWER_MGMT_H -#include "typedefs.h" +#include "mcs_typedef.h" + +/* Typedef definitions ------------------------------------------------------------------------- */ typedef struct { - float tempThr; /**< Temperature threshold. */ - float timeThr; /**< Detection time threshold. */ + float power; /**< power. */ + + float fltCoeff; /**< Power filter coefficient. */ + DqAxis *idqFbk; /**< Current value of d, q axis. */ + DqAxis *vdqRef; /**< Voltage value of d, q axis. */ +} POWER_Handle; + - unsigned int detCnt; /**< Detection count. */ - unsigned int detCntLimit; /**< Detection count threshold. */ - float ts; /* Control period (s). */ -} OTD_Handle; +void MotorPowerInit(POWER_Handle *powerCalc, DqAxis *vdqRef, DqAxis *idqFbk, float fltCoeff); -void OTD_Init(OTD_Handle *otd, float tempThr, float timeThr, float ts); +float MotorPowerCalc(POWER_Handle *powerCalc); -bool OTD_Exec(OTD_Handle *otd, float currAmp); +void MotorPowerClear(POWER_Handle *powerCalc); -void OTD_Clear(OTD_Handle *otd); #endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_r1_svpwm.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_r1_svpwm.h new file mode 100644 index 0000000000000000000000000000000000000000..b8914feb0c30e2bd9f5a469a5c708991e81bc222 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_r1_svpwm.h @@ -0,0 +1,91 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_r1_svpwm.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of Space-vector pulse-width-modulation calculations. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_MCS_R1_SVPWM_H +#define McuMagicTag_MCS_R1_SVPWM_H + +/* Includes ------------------------------------------------------------------*/ +#include "mcs_typedef.h" +#include "mcs_svpwm.h" + +/** The ADC sampling twice for one resistor motor control application, SOCA + SOCB */ +#define SOCA 0 +#define SOCB 1 +#define R1_ADC_SAMPLE_NUMS 2 + +/** + * @brief Structure of temporary variables for R1SVPWM calculation. + */ +typedef struct { + SVPWM_CALC_Handle svCalc; + float compLeft[SVPWM_COMP_VAL_TOTAL]; + float compRight[SVPWM_COMP_VAL_TOTAL]; +} R1SVPWM_CALC_Handle; +/** + * @defgroup R1_SVPWM_MODULE R1 SVPWM MODULE + * @brief The SVPWM module for R1(One Resistor) application. + * @{ + */ + +/** + * @defgroup R1_SVPWM_STRUCT R1 SVPWM STRUCT + * @brief The SVPWM module's struct definition for R1(One Resistor) application. + * @{ + */ +/* Typedef definitions -------------------------------------------------------*/ +/** + * @brief R1SVPWM struct members and parameters. + */ +typedef struct { + float voltPu; /**< Voltage per unit value. */ + float oneDivVoltPu; /**< Reciprocal of voltage unit value. */ + float sampleWindow; /**< Sampling Window */ + float samplePointShift; /**< Sampling point phase shift */ + unsigned int voltIndex; /**< Index of voltage sector. */ + unsigned int voltIndexLast; /**< Index of last voltage sector. */ + float samplePoint[R1_ADC_SAMPLE_NUMS]; /**< Sample point of twice sample. */ +} R1SVPWM_Handle; +/** + * @} + */ + +/** + * @defgroup R1_SVPWM_API R1 SVPWM API + * @brief The SVPWM module's API declaration for R1(One Resistor) application. + * @{ + */ + +void R1SVPWM_Init(R1SVPWM_Handle *r1svHandle, float voltPu, float samplePointShift, float sampleWindow); +void R1SVPWM_Clear(R1SVPWM_Handle *r1svHandle); +void R1SVPWM_Exec(R1SVPWM_Handle *r1svHandle, const AlbeAxis *uAlbe, UvwAxis *dutyUvwLeft, UvwAxis *dutyUvwRight); +void R1SVPWM_PhaseShift(R1SVPWM_CALC_Handle *r1SvCalc, float sampleWindow); +void R1CurrReconstruct(unsigned int sectorIndex, float currSocA, float currSocB, UvwAxis *curr); +/** + * @} + */ + +/** + * @} + */ + +#endif /* McuMagicTag_MCS_SVPWM_H */ diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_ramp_mgmt.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_ramp_mgmt.h new file mode 100644 index 0000000000000000000000000000000000000000..5caa23f7d1c26efdd84cfec8ca35e9f1ae530ffd --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_ramp_mgmt.h @@ -0,0 +1,50 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_ramp_mgmt.h + * @author MCU Algorithm Team + * @brief Ramp generation and management for motor control. + * This file provides functions declaration of ramp generation and management module. + */ + +#ifndef McuMagicTag_MCS_RAMP_MGMT_H +#define McuMagicTag_MCS_RAMP_MGMT_H + + +/** + * @brief Ramp mgmt Struct. + */ +typedef struct { + float delta; /**< Step value per calculate period. */ + float yLast; /**< History value of output value. */ + float ts; /**< Control period of the RMG module. */ + float slope; /**< Slope, target value divide time of variation. */ +} RMG_Handle; + + +/** + * @defgroup RAMP_API RAMP API + * @brief The RAMP API definitions. + * @{ + */ + +void RMG_Init(RMG_Handle *rmg, float ts, float slope); +void RMG_Clear(RMG_Handle *rmg); +float RMG_Exec(RMG_Handle *rmg, float targetVal); +void RMG_SetTs(RMG_Handle *rmg, float ts); +void RMG_SetSlope(RMG_Handle *rmg, float slope); +#endif diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_spd_ctrl.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_spd_ctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..5767f3a29ba2bd306b503ea64bf50f830dfbdaa7 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_spd_ctrl.h @@ -0,0 +1,49 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_spd_ctrl.h + * @author MCU Algorithm Team + * @brief Speed controller for motor control. + * This file provides functions declaration of the speed controller module. + */ + +#ifndef McuMagicTag_MCS_SPD_CTRL_H +#define McuMagicTag_MCS_SPD_CTRL_H + +#include "mcs_typedef.h" +#include "mcs_pid_ctrl.h" +#include "mcs_mtr_param.h" + +/** + * @brief Speed controller struct members and parameters. + */ +typedef struct { + PID_Handle spdPi; /**< PI controller struct in the speed controller. */ + float outLimit; /**< Maximum of the speed controller output. */ + MOTOR_Param *mtrParam; /**< Motor parameters. */ + float ts; /**< Speed controller control period (s). */ +} SPDCTRL_Handle; + +void SPDCTRL_Init(SPDCTRL_Handle *spdHandle, MOTOR_Param *mtrParam, const PI_Param piParam, float ts); + +void SPDCTRL_Reset(SPDCTRL_Handle *spdHandle); + +void SPDCTRL_Clear(SPDCTRL_Handle *spdHandle); + +float SPDCTRL_Exec(SPDCTRL_Handle *spdHandle, float spdTarget, float spdFbk); + +#endif diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_stall_det.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_stall_det.h new file mode 100644 index 0000000000000000000000000000000000000000..67055498727e9c7d32170d9292e592e6bc6ebb94 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_stall_det.h @@ -0,0 +1,44 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_stall_det.h + * @author MCU Algorithm Team + * @brief This file contains motor stalling protection data struct and api declaration. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_MCS_STALL_DET_H +#define McuMagicTag_MCS_STALL_DET_H + +#include "typedefs.h" + + +typedef struct { + float currAmpLimit; /**< Feedback current higher than this value triggers fault. (A). */ + float spdLimit; /**< Feedback speed lower than this value triggers fault (Hz). */ + float timeLimit; /**< The threshold time that current and speed feedback over ranges (s). */ + float timer; /**< Timer to get speed and current over range time. */ + float ts; /**< Ctrl period (s). */ +} STD_Handle; + +void STD_Init(STD_Handle *stall, float currLimit, float spdLimit, float timeLimit, float ts); + +bool STD_Exec_ByCurrSpd(STD_Handle *stall, float spdFbk, float currAmp); + +void STD_Clear(STD_Handle *stall); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_startup.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_startup.h new file mode 100644 index 0000000000000000000000000000000000000000..e7d79d4760ef55fe0ad6996a5a6cfd9eb9896e15 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_startup.h @@ -0,0 +1,66 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_startup.h + * @author MCU Algorithm Team + * @brief Motor transition process from one speed and angle to another speed and angle. + */ + + +#ifndef McuMagicTag_MCS_STARTUP_H +#define McuMagicTag_MCS_STARTUP_H + +/** + * @brief Startup process enum. + * @details Speed transition stages: + * + STARTUP_STAGE_CURR -- Stage of current AMP is changing + * + STARTUP_STAGE_SPD -- Stage of speed is changing + * + STARTUP_STAGE_SWITCH -- Stage of switch + * + STARTUP_STAGE_DETECT -- Stage of detect switch open loop + */ +typedef enum { + STARTUP_STAGE_CURR = 1, + STARTUP_STAGE_SPD, + STARTUP_STAGE_SWITCH, + STARTUP_STAGE_DETECT, +} STARTUP_Stage; + +/** + * @brief Startup handover method struct members and parameters. + */ +typedef struct { + STARTUP_Stage stage; /**< Startup switching status. */ + float spdBegin; /**< Startup switching start speed (Hz). */ + float spdEnd; /**< Startup switching end speed (Hz). */ + float regionInv; /**< Inverse of the speed region. */ + float initCurr; /**< The initial current (A). */ +} STARTUP_Handle; + + +/** + * @defgroup STARTUP_API STARTUP API + * @brief The startup management API declaration. + * @{ + */ + +void STARTUP_Init(STARTUP_Handle *startHandle, float spdBegin, float spdEnd); +void STARTUP_Clear(STARTUP_Handle *startHandle); +float STARTUP_CurrCal(STARTUP_Handle *startHandle, float spdRef); +/** + * @} + */ +#endif diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_svpwm.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_svpwm.h new file mode 100644 index 0000000000000000000000000000000000000000..e02067affc2c0155893b1cce18ead7f6bada388c --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_svpwm.h @@ -0,0 +1,118 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_svpwm.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of Space-Vector Pulse-Width-Modulation(SVPWM) calculations. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_MCS_SVPWM_H +#define McuMagicTag_MCS_SVPWM_H + +/* Includes ------------------------------------------------------------------*/ +#include "mcs_typedef.h" + +/** Voltage vector sector */ +#define SVPWM_ANGLE_0_TO_60_DEG 3 +#define SVPWM_ANGLE_60_TO_120_DEG 1 +#define SVPWM_ANGLE_120_TO_180_DEG 5 +#define SVPWM_ANGLE_180_TO_240_DEG 4 +#define SVPWM_ANGLE_240_TO_300_DEG 6 +#define SVPWM_ANGLE_300_TO_360_DEG 2 + +/** The U-V-W phase compare value's index of APT timers. */ +#define SVPWM_COMP_VAL_MAX 2 +#define SVPWM_COMP_VAL_MID 1 +#define SVPWM_COMP_VAL_MIN 0 +#define SVPWM_COMP_VAL_TOTAL 3 + +/** The three voltage level to compare, for sector index decision. */ +#define SVPWM_VOLT_0 0 +#define SVPWM_VOLT_1 1 +#define SVPWM_VOLT_2 2 +#define SVPWM_VOLT_TOTAL 3 + +/** Sector index calculate: N = A + 2B + 4C */ +#define SVPWM_SECTOR_ADD_1 1 +#define SVPWM_SECTOR_ADD_2 2 +#define SVPWM_SECTOR_ADD_4 4 + +#define SVPWM_SECTOR_INDEX_MIN 1 +#define SVPWM_SECTOR_INDEX_MAX 6 + +/** + * @defgroup SVPWM_MODULE SVPWM MODULE + * @brief The Space-Vector Pulse-Width-Modulation(SVPWM) module. + * @{ + */ + +/** + * @defgroup SVPWM_STRUCT SVPWM STRUCT + * @brief The SVPWM module's data struct definition. + * @{ + */ + +/* Typedef definitions -------------------------------------------------------*/ +/** + * @brief SVPWM struct members and parameters. + */ +typedef struct { + float voltPu; /**< Voltage per unit value. */ + float oneDivVoltPu; /**< Reciprocal of voltage unit value. */ +} SVPWM_Handle; + +/** + * @brief Structure of temporary variables for SVPWM calculation. + */ +typedef struct { + float vAlpha; /**< Voltage vector. */ + float vBeta; /**< Voltage vector. */ + float t1; /**< T1 are the action times of the sequential action vectors. */ + float t2; /**< T2 are the action times of the sequential action vectors. */ + unsigned short indexU; /**< U-phase duty cycle conversion index */ + unsigned short indexV; /**< V-phase duty cycle conversion index */ + unsigned short indexW; /**< W-phase duty cycle conversion index */ + unsigned int sectorIndex; /**< Sector index */ + float volt[SVPWM_VOLT_TOTAL]; /**< temporary voltage to calculate sector index */ + float comp[SVPWM_COMP_VAL_TOTAL]; /**< Duty cycle corresponding to the comparison value */ +} SVPWM_CALC_Handle; + +/** + * @} + */ + +/** + * @defgroup SVPWM_API SVPWM API + * @brief The SVPWM module's API declaration. + * @{ + */ + +void SVPWM_Init(SVPWM_Handle *svHandle, float voltPu); +void SVPWM_SectorCalc(SVPWM_CALC_Handle *svCalc); +void SVPWM_CompareValCalc(SVPWM_CALC_Handle *svCalc); +void SVPWM_IndexConvert(SVPWM_CALC_Handle *svCalc); +void SVPWM_Exec(const SVPWM_Handle *svHandle, const AlbeAxis *uAlbe, UvwAxis *dutyUvw); +/** + * @} + */ + +/** + * @} + */ + +#endif /* McuMagicTag_MCS_SVPWM_H */ diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_sys_status.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_sys_status.h new file mode 100644 index 0000000000000000000000000000000000000000..c26301fc82001cba9191939d103ef2850dd9eab4 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_sys_status.h @@ -0,0 +1,188 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_sys_status.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of system status. + */ + +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_MCS_SYS_STATUS_H +#define McuMagicTag_MCS_SYS_STATUS_H + +/* Includes ------------------------------------------------------------------------------------ */ +#include "typedefs.h" +#include "mcs_assert.h" + +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief System status define + */ +typedef union { + unsigned short all; + struct { + unsigned short cmdStart : 1; /**< Indicates that a start system command has been received. */ + unsigned short cmdStop : 1; /**< Indicates that a stop system command has been received. */ + unsigned short isRunning : 1; /**< Indicates that the system is running (enable signal) */ + unsigned short sysError : 1; /**< Indicates that the system reports an error. */ + unsigned short poweron : 1; /**< Indicates that the power-on initialization phase is complete. */ + unsigned short capcharge : 1; /**< Indicates that the bootstrap capacitor charging phase is complete. */ + unsigned short adczero : 1; /**< The current sampling point is reset to zero after power-on. */ + } Bit; +} SysStatusReg; + +/** + * @brief Get status of Bit cmdStart. + * @param sysStatus System status register handle. + * @retval Status of Bit cmdStart. + */ +static inline bool SysGetCmdStart(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + bool ret; + ret = (sysStatus->Bit.cmdStart == 1) ? true : false; + return ret; +} + +/** + * @brief Set Bit cmdStart. + * @param sysStatus System status register handle. + * @retval None. + */ +static inline void SysCmdStartSet(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + sysStatus->Bit.cmdStart = 1; +} + +/** + * @brief Clear Bit cmdStart. + * @param handle System status register handle. + * @retval None. + */ +static inline void SysCmdStartClr(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + sysStatus->Bit.cmdStart = 0; +} + +/** + * @brief Get status of Bit cmdStop. + * @param sysStatus System status register handle. + * @retval Status of Bit cmdStart. + */ +static inline bool SysGetCmdStop(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + bool ret; + ret = (sysStatus->Bit.cmdStop == 1) ? true : false; + return ret; +} + +/** + * @brief Set Bit cmdStop. + * @param sysStatus System status register handle. + * @retval None. + */ +static inline void SysCmdStopSet(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + sysStatus->Bit.cmdStop = 1; +} + +/** + * @brief Clear Bit cmdStop. + * @param sysStatus System status register handle. + * @retval None. + */ +static inline void SysCmdStopClr(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + sysStatus->Bit.cmdStop = 0; +} + +/** + * @brief Get status of Bit isRunning. + * @param sysStatus System status register handle. + * @retval Status of Bit isRunning. + */ +static inline bool SysIsRunning(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + bool ret; + ret = (sysStatus->Bit.isRunning == 1) ? true : false; + return ret; +} + +/** + * @brief Set Bit isRuning. + * @param sysStatus System status register handle. + * @retval None. + */ +static inline void SysRunningSet(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + sysStatus->Bit.isRunning = 1; +} + +/** + * @brief Clear Bit isRuning. + * @param sysStatus System status register handle. + * @retval None. + */ +static inline void SysRunningClr(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + sysStatus->Bit.isRunning = 0; +} + +/** + * @brief Get status of Bit sysError. + * @param sysStatus System status register handle. + * @retval Status of Bit sysError. + */ +static inline bool SysIsError(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + bool ret; + ret = (sysStatus->Bit.sysError == 1) ? true : false; + return ret; +} + +/** + * @brief Set Bit sysError. + * @param sysStatus System status register handle. + * @retval None. + */ +static inline void SysErrorSet(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + sysStatus->Bit.sysError = 1; +} + +/** + * @brief Clear Bit sysError. + * @param sysStatus System status register handle. + * @retval None. + */ +static inline void SysErrorClr(SysStatusReg *sysStatus) +{ + MCS_ASSERT_PARAM(sysStatus != NULL); + sysStatus->Bit.sysError = 0; +} + +#endif diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_volt_det.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_typedef.h similarity index 56% rename from src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_volt_det.h rename to src/middleware/thirdparty/sysroot/include/control_library/mcs_typedef.h index e1c5e4cf084cc6493c8966f717b52899749f02b2..9a9fb890a7f6d090a6a412bb73d9a6d6319b1fc8 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_volt_det.h +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_typedef.h @@ -15,40 +15,45 @@ * 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. - * @file mcs_volt_det.h + * @file mcs_typedef.h * @author MCU Algorithm Team - * @brief This file contains dc-link voltage protection api declaration. + * @brief This file provides the definition of the motor basic data structure. */ - /* Define to prevent recursive inclusion ------------------------------------------------------- */ -#ifndef McuMagicTag_MCS__VOLT_DET_H -#define McuMagicTag_MCS__VOLT_DET_H +#ifndef McuMagicTag_MCS_TYPEDEF_H +#define McuMagicTag_MCS_TYPEDEF_H -#include "typedefs.h" +/** + * @defgroup MCS COORDINATE + * @brief Motor Basic coordinate data structures. + * @{ + */ + +/** + * @brief Rotor synchronous rotation coordinate frame Variables. + */ typedef struct { - float overVoltThr; /**< Over voltage threshold. */ - float timeThr; /**< Detection time threshold. */ + float d; /**< Component d of the rotor synchronous rotation coordinate variable. */ + float q; /**< Component q of the rotor synchronous rotation coordinate variable. */ +} DqAxis; - unsigned int detCnt; /**< Detection count. */ - unsigned int detCntLimit; /**< Detection count threshold. */ - float ts; /**< Control period (s). */ -} OVD_Handle; +/** + * @brief Two-phase stationary coordinate frame variable. + */ +typedef struct { + float alpha; /**< Component alpha of the two-phase stationary coordinate variable. */ + float beta; /**< Component beta of the two-phase stationary coordinate variable. */ +} AlbeAxis; +/** + * @brief Three-phase static coordinate frame variable. + */ typedef struct { - float lowerVoltThr; /**< Lower voltage threshold. */ - float timeThr; /**< Detection time threshold. */ - - unsigned int detCnt; /**< Detection count. */ - unsigned int detCntLimit; /**< Detection count threshold. */ - float ts; /**< Control period (s). */ -} LVD_Handle; - -void OVD_Init(OVD_Handle *ovd, float overVoltThr, float timeThr, float ts); -bool OVD_Exec(OVD_Handle *ovd, float voltAmp); -void OVD_Clear(OVD_Handle *ovd); - -void LVD_Init(LVD_Handle *lvd, float lowerVoltThr, float timeThr, float ts); -bool LVD_Exec(LVD_Handle *lvd, float voltAmp); -void LVD_Clear(LVD_Handle *lvd); -#endif \ No newline at end of file + float u; /**< Component u of the three-phase static coordinate frame variable. */ + float v; /**< Component v of the three-phase static coordinate frame variable. */ + float w; /**< Component w of the three-phase static coordinate frame variable. */ +} UvwAxis; + + +#endif /* McuMagicTag_MCS_TYPEDEF_H */ diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_unbalance_det.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_unbalance_det.h new file mode 100644 index 0000000000000000000000000000000000000000..ac94519e49ddaeb103f9d35bac773f05833b1d91 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_unbalance_det.h @@ -0,0 +1,55 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_unbalance_det.h + * @author MCU Algorithm Team + * @brief This file contains three-phase imbalance protection data struct and api declaration. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_MCS_UNBALANCE_DET_H +#define McuMagicTag_MCS_UNBALANCE_DET_H + +#include "typedefs.h" +#include "mcs_typedef.h" + +typedef struct { + unsigned int detCnt; + unsigned int detCntLimit; + unsigned int integralCnt; + unsigned int timeCnt; + unsigned int startupCnt; + bool startFlag; + bool startFlagLast; + bool zeroFlag; + bool calFlag; + float unbalDegree; + float unbalDegreeLimit; + float delta; + float ts; + float ia; + float ib; + float ic; +} UNBAL_Handle; + + +void UNBAL_Init(UNBAL_Handle *unbal, float currDelta, float timeThr, float unbalDegreeLim, float ts); + +bool UNBAL_Det(UNBAL_Handle *unbal, UvwAxis *iuvwFbk, float unbalFltCoeff); + +void UNBAL_Clear(UNBAL_Handle *unbal); +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/mcs_vf_ctrl.h b/src/middleware/thirdparty/sysroot/include/control_library/mcs_vf_ctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..5de22b3a0de93fde5284bdf1c6d6806f9466b307 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/mcs_vf_ctrl.h @@ -0,0 +1,53 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file mcs_vf_ctrl.h + * @author MCU Algorithm Team + * @brief This file provides functions declaration of v/f control. + * + */ + +#ifndef McuMagicTag_MCS_VF_CTRL_H +#define McuMagicTag_MCS_VF_CTRL_H + + +#include "mcs_typedef.h" +#include "mcs_ramp_mgmt.h" + + +typedef struct { + float spdCmd; /**< Motor target speed frequency (Hz). */ + float spdRef; /**< Motor reference speed frequency (Hz). */ + float vfAngle; /**< Vf control angle. */ + float ts; /**< Control period. */ + float spdThr[2]; /**< Minimum (spdThr[0]) and maximum(spdThr[1]) speed thresholds for ramp command. */ + float voltThr[2]; /**< Minimum (voltThr[0]) and maximum(voltThr[1]) voltage for thresholds ramp command. */ + float slope; /**< Slope of the voltage-speed curve. */ + DqAxis ratio; /**< Proportion of dq-axis reference voltage. */ + DqAxis vdqRef; /**< Dq-axis reference voltage. */ + RMG_Handle rmg; /**< Ramp management structure */ +} VF_Handle; + + +void VF_Init(VF_Handle *vf, const float *spdThr, const float *voltThr, float ts, float spdCmd, float spdSlope); +void VF_Exec(VF_Handle *vf, DqAxis *vdqRef); +void VF_Clear(VF_Handle *vf); +void VF_SetTs(VF_Handle *vf, float ts); +void VF_SetSpdSlope(VF_Handle *vf, float spdSlope); +void VF_SetDRatio(VF_Handle *vf, float dRatio); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/control_library/pfc_curr_ctrl.h b/src/middleware/thirdparty/sysroot/include/control_library/pfc_curr_ctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..d968b08223e563640b3e25bfd83455aacd55f199 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/pfc_curr_ctrl.h @@ -0,0 +1,82 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file pfc_curr_ctrl.h + * @author MCU Algorithm Team + * @brief Current loop control. This file provides function of power factor correction(PFC) current control + */ +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_PFC_CURR_CTRL_H +#define McuMagicTag_PFC_CURR_CTRL_H + +/* Includes ------------------------------------------------------------------------------------ */ +#include "mcs_pid_ctrl.h" + +/** + * @defgroup PFC_CURRENT_CONTROLLER PFC_CURRENT CONTROLLER MODULE + * @brief The current controller function. + * @{ + */ + +/** + * @defgroup PFC_CURRENT_CONTROLLER_STRUCT PFC_CURRENT CONTROLLER STRUCT + * @brief The current controller's data structure definition. + * @{ + */ + +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief current Controller Struct members and parameters. + */ +typedef struct { + float iacRef; + float iacFbk; + float vacFbk; /* < current loop control rectified feedback voltage(V) */ + float unitVacFbk; + float unitCoeff; + + float maxCurr; /* < current loop control max feedback current(A) */ + float startCurr; /* < current loop control start feedback current(A) */ + float stopCurr; /* < current loop control stop feedback current(A) */ + + float pwmDuty; /* < current loop control pulse width modulation(PWM) duty */ + PID_Handle currPi; /* < current loop controller define */ +} PFC_CURRCTRL_Handle; +/** + * @} + */ + +/** + * @defgroup PFC_CURRENT_CONTROLLER_API PFC_CURRENT CONTROLLER API + * @brief The current controller's API declaration. + * @{ + */ + +void PFC_CurrCtrlInit(PFC_CURRCTRL_Handle *currCtrl, PI_Param *piParam, float startCurr, \ + float stopCurr, float vacAmp, float ts); + +void PFC_CurrCtrlExec(PFC_CURRCTRL_Handle *currCtrl, float iacFbk); + +void PFC_CurrCtrlClear(PFC_CURRCTRL_Handle *currCtrl); +/** + * @} + */ + +/** + * @} + */ +#endif /* McuMagicTag_PFC_CURR_CTRL_H */ diff --git a/src/middleware/thirdparty/sysroot/include/control_library/pfc_volt_ctrl.h b/src/middleware/thirdparty/sysroot/include/control_library/pfc_volt_ctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..7edcb4329057bcf05e1525743078909d4686ecb8 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/control_library/pfc_volt_ctrl.h @@ -0,0 +1,73 @@ +/** + * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file pfc_volt_ctrl.h + * @author MCU Algorithm Team + * @brief Voltage loop control. This file provides function of power factor correction(PFC) voltage control + */ +/* Define to prevent recursive inclusion ------------------------------------------------------- */ +#ifndef McuMagicTag_PFC_VOLT_CTRL_H +#define McuMagicTag_PFC_VOLT_CTRL_H + +/* Includes ------------------------------------------------------------------------------------ */ +#include "mcs_pid_ctrl.h" + +/** + * @defgroup VOLTAGE_CONTROLLER VOLTAGE CONTROLLER MODULE + * @brief The voltage controller function. + * @{ + */ + +/** + * @defgroup VOLTAGE_CONTROLLER_STRUCT VOLTAGE CONTROLLER STRUCT + * @brief The voltage controller's data structure definition. + * @{ + */ + +/* Typedef definitions ------------------------------------------------------------------------- */ +/** + * @brief Voltage controller struct. + */ +typedef struct { + float vdcRef; /* Target bus voltage */ + float vdcFbk; /* < voltage loop control feedback voltage(V) */ + float iamp; /* Voltage loop output is current amplitude */ + PID_Handle voltPi; /* < voltage loop controller define */ +} PFC_VOLTCTRL_Handle; +/** + * @} + */ + +/** + * @defgroup VOLTAGE_CONTROLLER_API VOLTAGE CONTROLLER API + * @brief The voltage controller's API declaration. + * @{ + */ + +void PFC_VoltCtrlInit(PFC_VOLTCTRL_Handle *voltCtrl, PI_Param *piParam, float vdcRef, float ts); + +void PFC_VoltCtrlExec(PFC_VOLTCTRL_Handle *voltCtrl, float vdcFbk); + +void PFC_VoltCtrlClear(PFC_VOLTCTRL_Handle *voltCtrl); +/** + * @} + */ + +/** + * @} + */ +#endif /* McuMagicTag_PFC_VOLT_CTRL_H */ \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_ana.h b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_ana.h new file mode 100644 index 0000000000000000000000000000000000000000..38b69fc5fd8f1883d622f8d9f0981484ef83de54 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_ana.h @@ -0,0 +1,81 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_ana.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ana diagnose. + */ + +#ifndef DIAGNOSE_MCU_ANA_H +#define DIAGNOSE_MCU_ANA_H + +#include "function_safety_common.h" +#ifdef ADC0 /* ADC0 represent ip support adc controler, not means only adc0 */ +#include "adc.h" +#endif +#ifdef DAC0 /* DAC0 represent ip support dac controler, not means only dac0 */ +#include "dac.h" +#endif +#ifdef ACMP0 /* ACMP0 represent ip support acmp controler, not means only acmp0 */ +#include "acmp.h" +#endif +#ifdef PGA0 /* PGA0 represent ip support pga controler, not means only pga0 */ +#include "pga.h" +#endif + +#define MODULE_ADC 0x01 +#define MODULE_DAC 0x02 +#define MODULE_PGA 0x04 +#define MODULE_ACMP 0x08 + +#define FEATURE_ACCURACY 0x01 + +#define FAULT_1ST_OVER_ACCURACY 0x01 +#define FAULT_2ST_OVER_ACCURACY 0x02 +#define FAULT_3ST_OVER_ACCURACY 0x03 + +typedef struct { +#ifdef ADC0 + ADC_Handle* adcHandle; + ADC_SOCNumber socx; +#endif +#ifdef DAC0 + DAC_Handle* dacHandleRef; + DAC_Handle* dacHandleTarget; +#endif +#ifdef PGA0 + PGA_Handle* pgaHandle; +#endif +#ifdef ACMP0 + ACMP_Handle* acmpHandle; +#endif + unsigned int adcMaxRange; + unsigned int dacMaxRange; + unsigned int errRangePercent; +} ANA_DiagnoseHandle; + +#if defined(ADC0) && defined(DAC0) +FunctionSafetyState ANA_DiagnoseAdcSampleAccuracy(void* anaDiagnoseHandle, DiagnoseMoment moment); +#endif +#if defined(ADC0) && defined(DAC0) && defined(PGA0) +FunctionSafetyState ANA_DiagnosePgaInnerGainAccuracy(void* anaDiagnoseHandle, DiagnoseMoment moment); +#endif +#if defined(DAC0) && defined(ACMP0) +FunctionSafetyState ANA_DiagnoseAcmpThresholdAccuracy(void* anaDiagnoseHandle, DiagnoseMoment moment); +#endif + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_clock.h b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_clock.h new file mode 100644 index 0000000000000000000000000000000000000000..f1ca5d0bb165b90565ee56ce14bbd6096fb29d58 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_clock.h @@ -0,0 +1,73 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_clock.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for clock diagnose. + */ + +#ifndef DIAGNOSE_MCU_CLOCK_H +#define DIAGNOSE_MCU_CLOCK_H + +#include "function_safety_common.h" +#ifdef CRG +#include "crg.h" +#endif +#ifdef CMM +#include "cmm.h" +#endif +#ifdef CFD +#include "cfd.h" +#endif + +#define MODULE_CMM 0x01 +#define MODULE_CFD 0x02 + +#define FEATURE_CLOCK_ACCURACY_SINGLE_CHECK 0x01 +#define FEATURE_CLOCK_ACCURACY_CONTINUE_CHECK 0x02 +#define FEATURE_PLLREF_CLOCK_STOP_CHECK 0x03 + +#define FAULT_OVER_ACCURACY 0x01 +#define FAULT_PLLREF_CLOCK_STOP 0x02 + +typedef struct { +#ifdef CMM + CMM_Handle* cmmHandle; + unsigned int cmmTargetVal; + unsigned int cmmClockCount; + bool cmmIrqFlag; +#endif +#ifdef CFD + CFD_Handle* cfdHandle; + unsigned int cfdTargetVal; + unsigned int cfdClockCount; + bool cfdIrqFlag; +#endif + unsigned int checkEndDelayTimeUs; + unsigned int errRangePercent; +} CLOCK_DiagnoseHandle; + +#ifdef CMM +FunctionSafetyState CLOCK_CmmWindowsBoundCalculate(void* clockDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState CLOCK_CmmDiagnoseAccuracy(void* clockDiagnoseHandle, DiagnoseMoment moment); +#endif +#ifdef CFD +FunctionSafetyState CLOCK_CfdWindowsBoundCalculate(void* clockDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState CLOCK_CfdDiagnosePllRefClockStop(void* clockDiagnoseHandle, DiagnoseMoment moment); +#endif + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_compute.h b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_compute.h new file mode 100644 index 0000000000000000000000000000000000000000..d2740506f11f479c2d75bda1d54da355c69e370e --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_compute.h @@ -0,0 +1,50 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_compute.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for compute diagnose. + */ + +#ifndef DIAGNOSE_MCU_COMPUTE_H +#define DIAGNOSE_MCU_COMPUTE_H + +#include "function_safety_common.h" +#ifdef CRC +#include "crc.h" +#endif + +#define MODULE_CRC 0x01 + +#define FEATURE_COMPUTE_CORRECT 0x01 + +#define FAULT_CRC32_ALGORITHM_COMPUTE_UNCORRECT 0x01 + +typedef struct { +#ifdef CRC + CRC_Handle* crcHandle; +#endif + unsigned int inputTestData; + unsigned int inputDataSize; + unsigned int outputRefData; +} COMPUTE_DiagnoseHandle; + +#ifdef CRC +FunctionSafetyState COMPUTE_DiagnoseCrcAlgorithmCorrect(void* computeDiagnoseHandle, DiagnoseMoment moment); +#endif + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_connect.h b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_connect.h new file mode 100644 index 0000000000000000000000000000000000000000..290c3e018856206d2032a4a6d251e06a1a232f1a --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_connect.h @@ -0,0 +1,65 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_connect.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for connect diagnose. + */ + +#ifndef DIAGNOSE_MCU_CONNECT_H +#define DIAGNOSE_MCU_CONNECT_H + +#include "function_safety_common.h" +#ifdef I2C +#include "i2c.h" +#endif +#ifdef UART0 +#include "uart.h" +#endif +#ifdef SPI +#include "spi.h" +#endif +#ifdef CAN +#include "can.h" +#endif + +#define MODULE_I2C 0x01 +#define MODULE_UART 0x02 +#define MODULE_SPI 0x03 +#define MODULE_CAN 0x04 + +#define FEATURE_CONNECT_DATA_CORRECT 0x01 + +#define FAULT_CONNECT_DATA_UNCORRECT 0x01 + +typedef struct { +#ifdef I2C + I2C_Handle* i2cHandle; +#endif +#ifdef UART0 + UART_Handle* uartHandle; +#endif +#ifdef SPI + SPI_Handle* spiHandle; +#endif +#ifdef CAN + CAN_Handle* canHandle; +#endif +} CONNECT_DiagnoseHandle; + + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_core.h b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_core.h new file mode 100644 index 0000000000000000000000000000000000000000..0bfb299888179c103b6a34fea1f100720e1fedf0 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_core.h @@ -0,0 +1,55 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_core.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for core diagnose. + */ + +#ifndef DIAGNOSE_MCU_CORE_H +#define DIAGNOSE_MCU_CORE_H + +#include "function_safety_common.h" + +#define MODULE_CPU_REGISTER 0x01 +#define MODULE_PC_REGISTER 0x02 +#define MODULE_CPU_SOFT_INTTERRUPT 0x03 + +#define FEATURE_REG_WRITE_READ 0x01 +#define FEATURE_REG_PC_JUMP 0x02 +#define FEATURE_SYSCTRL_CPU_STATUS 0x03 +#define FEATURE_SOFT_INTERRUPT 0x04 + +#define FAULT_REG_SAF 0x01 +#define FAULT_REG_AF 0x02 +#define FAULT_REG_TF 0x03 +#define FAULT_REG_CF 0x04 +#define FAULT_PC_JUMP 0x05 +#define FAULT_PC_INVALID 0x06 +#define FAULT_SYSCTRL_CPU_STATUS 0x07 +#define FAULT_CPU_SOFT_INTTERRUPT 0x08 + +typedef struct { + void* param; +} CORE_DiagnoseHandle; + +FunctionSafetyState CORE_DiagnoseCpuSoftwareIrq(void* coreDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_DiagnoseCpuStatus(void* coreDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_DiagnoseCpuGeneralRegister(void* coreDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_DiagnosePcRegister(void* coreDiagnoseHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_dio.h b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_dio.h new file mode 100644 index 0000000000000000000000000000000000000000..d8c676e687b0b036e6825b1c4381e032eabc0e0b --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_dio.h @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_dio.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for dio diagnose. + */ + +#ifndef DIAGNOSE_MCU_DIO_H +#define DIAGNOSE_MCU_DIO_H + +#include "function_safety_common.h" +#ifdef GPIO0 +#include "gpio.h" +#endif +#define MODULE_GPIO 0x01 + +#define FEATURE_GPIO_BASIC 0x01 +#define FEATURE_GPIO_INTERRUPT 0x02 + +#define FAULT_GPIO_DIR_INPUT 0x01 +#define FAULT_GPIO_DIR_OUTPUT 0x02 +#define FAULT_GPIO_LEVEL_HIGH 0x03 +#define FAULT_GPIO_LEVEL_LOW 0x04 +#define FAULT_GPIO_INT_RISE_NACK 0x05 +#define FAULT_GPIO_INT_FALL_NACK 0x06 +#define FAULT_GPIO_INT_LOW_LEVEL_NACK 0x07 +#define FAULT_GPIO_INT_HIGH_LEVEL_NACK 0x08 +#define FAULT_GPIO_INT_BOTH_NACK 0x09 +#define FAULT_GPIO_INT_PINS_UNMATCH 0x0A + +typedef struct { +#ifdef GPIO0 + GPIO_Handle* gpioHandleRef; + GPIO_Handle* gpioHandleTarget; +#endif + bool irqFlag; +} DIO_DiagnoseHandle; + +#ifdef GPIO0 +FunctionSafetyState DIO_DiagnoseGpioDirectionAndLevel(void* dioDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState DIO_DiagnoseGpioInterrupt(void* dioDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState DIO_GpioIrqCheckCallback(void* dioDiagnoseHandle, DiagnoseMoment moment); +#endif + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_monitor.h b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_monitor.h new file mode 100644 index 0000000000000000000000000000000000000000..5b58dbe282778eaf7a9dfb6201c8b0fa9c7e2eac --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_monitor.h @@ -0,0 +1,99 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_monitor.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for monitor diagnose. + */ + +#ifndef DIAGNOSE_MCU_MONITOR_H +#define DIAGNOSE_MCU_MONITOR_H + +#include "function_safety_common.h" +#ifdef CRG +#include "crg.h" +#endif +#ifdef WDG +#include "wdg.h" +#endif +#ifdef WWDG +#include "wwdg.h" +#endif +#ifdef IWDG +#include "iwdg.h" +#endif +#ifdef PMC +#include "pmc.h" +#endif +#ifdef TSENSOR +#include "tsensor.h" +#endif +#ifdef SYSCTRL0 +#include "sysctrl.h" +#endif + +#define MODULE_WDG 0x01 +#define MODULE_IWDG 0x02 +#define MODULE_WWDG 0x03 +#define MODULE_PMC 0x04 +#define MODULE_TSENSOR 0x05 + +#define FEATURE_MONITOR_PROGRAM_STUCK 0x01 +#define FEATURE_MONITOR_WDG_RESET 0x02 +#define FEATURE_MONITOR_POWER_LOW_LEVEL 0x03 +#define FEATURE_MONITOR_CHIP_OVER_TEMPERATUR 0x04 + +#define FAULT_WDG_PROGRAM_STUCK_RESET 0x01 +#define FAULT_WDG_UNRESET 0x02 +#define FAULT_PMC_POWER_LOW_LEVEL 0x03 +#define FAULT_TSENSOR_CHIP_OVER_TEMPERATUR 0x04 + +typedef struct { +#ifdef WDG + WDG_Handle* wdgHandle; +#endif +#ifdef WWDG + WWDG_Handle* wwdgHandle; +#endif +#ifdef IWDG + IWDG_Handle* iwdgHandle; +#endif +#ifdef PMC + PMC_Handle* pmcHandle; +#endif + unsigned int startupResetTimeUs; + unsigned int runTimeResetTimeUs; + unsigned int overTemperatureValue; + bool pmcIrqFlag; +} MONITOR_DiagnoseHandle; + +#if defined(WDG) || defined(WWDG) +FunctionSafetyState MONITOR_DiagnoseProgramStuckByWdg(void* monitorDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_DiagnoseWdgResetFunction(void* monitorDiagnoseHandle, DiagnoseMoment moment); +#endif +#if defined(IWDG) +FunctionSafetyState MONITOR_DiagnoseProgramStuckByIwdg(void* monitorDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_DiagnoseIwdgResetFunction(void* monitorDiagnoseHandle, DiagnoseMoment moment); +#endif +#if defined(PMC) +FunctionSafetyState MONITOR_DiagnosePowerLowLevelByPmc(void* monitorDiagnoseHandle, DiagnoseMoment moment); +#endif +#if defined(TSENSOR) +FunctionSafetyState MONITOR_DiagnoseOverTemperatureByTsensor(void* monitorDiagnoseHandle, DiagnoseMoment moment); +#endif + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_ram.h b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_ram.h new file mode 100644 index 0000000000000000000000000000000000000000..a227f5c50903b217286a9d888f420d802c20dc7b --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_ram.h @@ -0,0 +1,53 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_ram.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ram diagnose. + */ + +#ifndef DIAGNOSE_MCU_RAM_H +#define DIAGNOSE_MCU_RAM_H + +#include "function_safety_common.h" + +#define MODULE_RAM_SRAM 0x01 +#define MODULE_RAM_STACK 0x02 + +#define FEATURE_SRAM_MARCH 0x01 +#define FEATURE_SRAM_PARITY 0x02 +#define FEATURE_STACK_OVERFLOW_CHECK 0x03 + +#define FAULT_DATA_NOT_INTEGRITY 0x01 +#define FAULT_SRAM_STEP_RANGE 0x02 +#define FAULT_SRAM_FULL_RANGE 0x03 +#define FAULT_SRAM_PARITY_ERROR 0x04 +#define FAULT_STACK_OVERFLOW 0x05 + +typedef struct { + unsigned int* sramStartAddr; + unsigned int* sramCurrentAddr; + unsigned int* sramCurrentAddrInv; + unsigned int* sramEndAddr; + unsigned int sramPattern; +} RAM_DiagnoseHandle; + +FunctionSafetyState RAM_DiagnoseSramByMarchAlgorithm(void* ramDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_DiagnoseSramByParityCheck(void* ramDiagnoseHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_DiagnoseStackOverflow(void* ramDiagnoseHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_rom.h b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_rom.h new file mode 100644 index 0000000000000000000000000000000000000000..9e6ce375fd4fb4f40f13338906e1a4b31a1da48b --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_rom.h @@ -0,0 +1,66 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_rom.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for rom diagnose. + */ + +#ifndef DIAGNOSE_MCU_ROM_H +#define DIAGNOSE_MCU_ROM_H + +#include "function_safety_common.h" +#ifdef CRC +#include "crc.h" +#endif +#ifdef EFC +#include "flash.h" +#endif + +#define MODULE_ROM_RANGE 0x01 +#define MODULE_ROM_EFLASH 0x02 + +#define FEATURE_ROM_INTEGRITY 0x01 +#define FEATURE_EFLASH_ECC 0x02 + +#define FAULT_DATA_NOT_INTEGRITY 0x01 +#define FAULT_ROM_STEP_RANGE 0x02 +#define FAULT_ROM_FULL_RANGE 0x03 +#define FAULT_EFLASH_ECC_ERROR 0x04 + +typedef struct { +#ifdef CRC + CRC_Handle* crcHandle; +#endif +#ifdef EFC + EFC_RegStruct* flashBase; + unsigned int eccIntRegVal; +#endif + unsigned int* startAddr; + unsigned int* indexPointer; + unsigned int* indexPointerInv; + unsigned int flashBlockSizeInWords; +} ROM_DiagnoseHandle; + +#ifdef CRC +FunctionSafetyState ROM_DiagnoseIntegrity(void* romDiagnoseHandle, DiagnoseMoment moment); +#endif +#ifdef EFC +FunctionSafetyState ROM_DiagnoseFlashEcc(void* romDiagnoseHandle, DiagnoseMoment moment); +#endif + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_timers.h b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_timers.h new file mode 100644 index 0000000000000000000000000000000000000000..d0824d52f3dcf512f238d9bc2fa16156e10c567f --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/diagnose_mcu_timers.h @@ -0,0 +1,88 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file diagnose_mcu_timers.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for timers diagnose. + */ + +#ifndef DIAGNOSE_MCU_TIMERS_H +#define DIAGNOSE_MCU_TIMERS_H + +#include "function_safety_common.h" +#ifdef CRG +#include "crg.h" +#endif +#ifdef TIMER0 +#include "timer.h" +#endif +#ifdef APT0 +#include "apt.h" +#endif +#ifdef QDM0 +#include "qdm.h" +#endif +#ifdef CAPM0 +#include "capm.h" +#endif +#ifdef GPT0 +#include "gpt.h" +#endif + +#define MODULE_TIMER 0x01 +#define MODULE_APT 0x02 +#define MODULE_QDM 0x03 +#define MODULE_CAPM 0x04 +#define MODULE_GPT 0x05 + +#define FEATURE_TIMER_INTERRUPT_ACCURACY 0x01 +#define FEATURE_APT_INTERRUPT_ACCURACY 0x02 +#define FEATURE_QDM_INTERRUPT_ACCURACY 0x03 +#define FEATURE_CAPM_INTERRUPT_ACCURACY 0x04 +#define FEATURE_GPT_INTERRUPT_ACCURACY 0x05 + +#define FAULT_INTERRUPT_ACCURACY 0x01 + +typedef struct { +#ifdef TIMER0 + TIMER_Handle* timerHandle; +#endif +#ifdef APT0 + APT_Handle* aptHandle; +#endif +#ifdef QDM0 + QDM_Handle* qdmHandle; +#endif +#ifdef CAPM0 + CAPM_Handle* capmHandle; +#endif +#ifdef GPT0 + GPT_Handle* gptHandle; +#endif + unsigned int setTimeUs; + unsigned int pretimeCycle; + unsigned int currenttimeCycle; + unsigned int durationUs; + unsigned int errRangeUs; + bool timerIrqFlag; +} TIMERS_DiagnoseHandle; + +#ifdef TIMER0 +FunctionSafetyState TIMERS_DiagnoseInterruptIntervalAccuracy(void* timersDiagnoseHandle, DiagnoseMoment moment); +#endif + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_ana.h b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_ana.h new file mode 100644 index 0000000000000000000000000000000000000000..f671ca1d8087d30617a53228e214c11577571d5e --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_ana.h @@ -0,0 +1,39 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_ana.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ana failsafe. + */ + +#ifndef FAILSAFE_MCU_ANA_H +#define FAILSAFE_MCU_ANA_H + +#include "function_safety_common.h" + +typedef struct { + ANA_DiagnoseHandle* anaDiagnoseHandle; + void* param; +} ANA_FailSafeHandle; + +FunctionSafetyState ANA_FailSafeHandler(void* anaFailSafeHandle, DiagnoseMoment moment); +#ifdef ADC0 +FunctionSafetyState ANA_AdcFailSafeHandler(void* anaFailSafeHandle, DiagnoseMoment moment); +#endif +__weak FunctionSafetyState ANA_DefaultFailSafe(void* anaFailSafeHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/nos_sys.c b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_clock.h similarity index 72% rename from src/middleware/hisilicon/nostask/kernel/nos_sys.c rename to src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_clock.h index 6ec3e8226d3015fce41a8411ed7bd2d4b4c9607d..b1e75d3d9cf864a59964e87fba0b2742f19cef0b 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_sys.c +++ b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_clock.h @@ -15,22 +15,22 @@ * 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. - * @file nos_sys.c + * @file failsafe_mcu_clock.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for clock failsafe. */ -#include "nos_sys_external.h" -/* tick中软件定时器扫描钩子 */ -TaskScanFunc g_taskScanHook; +#ifndef FAILSAFE_MCU_CLOCK_H +#define FAILSAFE_MCU_CLOCK_H -OsVoidFunc g_idleEntry; +#include "function_safety_common.h" -/* hidsp从核把栈越界模块放在dl中,所以变量放此处为了链接ok */ +typedef struct { + void *param; +} CLOCK_FailSafeHandle; -unsigned int g_threadNum; -/* Tick计数 */ -unsigned long long g_uniTicks; +FunctionSafetyState CLOCK_AccuracyFailSafe(void* clockFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState CLOCK_FailSafeHandler(void* clockFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState CLOCK_DefaultFailSafe(void* clockFailSafeHandle, DiagnoseMoment moment); -/* 系统状态标志位 */ -unsigned int g_uniFlag = 0; -unsigned int g_tickNoRespondCnt; -struct TagTskCB *g_runningTask = NULL; \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_compute.h b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_compute.h new file mode 100644 index 0000000000000000000000000000000000000000..04f1dcbf8f0ccdec28a077b439b376707a8a0bee --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_compute.h @@ -0,0 +1,36 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_compute.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for compute failsafe. + */ + +#ifndef FAILSAFE_MCU_COMPUTE_H +#define FAILSAFE_MCU_COMPUTE_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} COMPUTE_FailSafeHandle; + +FunctionSafetyState COMPUTE_DefaultFailSafe(void* computeFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState COMPUTE_FailSafeHandler(void* computeFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState COMPUTE_Crc32FailSafe(void* computeFailSafeHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_connect.h b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_connect.h new file mode 100644 index 0000000000000000000000000000000000000000..4fb000f5b057fef97f5119b37d6bdc11bd889fbb --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_connect.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_connect.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for connect failsafe. + */ + +#ifndef FAILSAFE_MCU_CONNECT_H +#define FAILSAFE_MCU_CONNECT_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} CONNECT_FailSafeHandle; + +FunctionSafetyState CONNECT_FailSafeHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_core.h b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_core.h new file mode 100644 index 0000000000000000000000000000000000000000..6d002a21caad5e5ec80b221e2ab16760555d8f09 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_core.h @@ -0,0 +1,37 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_core.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for core failsafe. + */ + +#ifndef FAILSAFE_MCU_CORE_H +#define FAILSAFE_MCU_CORE_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} CORE_FailSafeHandle; + +FunctionSafetyState CORE_FailSafeHandler(void* coreHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_DefaultFailSafe(void* coreHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_RegSafFailSafe(void* coreHandle, DiagnoseMoment moment); +FunctionSafetyState CORE_FailSafeHandler(void* coreHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_dio.h b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_dio.h new file mode 100644 index 0000000000000000000000000000000000000000..deb2f5e96b46387bd851fddb830a07b481ba9185 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_dio.h @@ -0,0 +1,37 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_dio.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for dio failsafe. + */ + +#ifndef FAILSAFE_MCU_DIO_H +#define FAILSAFE_MCU_DIO_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} DIO_FailSafeHandle; + +FunctionSafetyState DIO_FailSafeHandler(void* dioFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState DIO_InterruptFailSafe(void* dioFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState DIO_DirectionLevelFailSafe(void* dioFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState DIO_DefaultFailSafe(void* dioFailSafeHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_monitor.h b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_monitor.h new file mode 100644 index 0000000000000000000000000000000000000000..7fcb096481b255fc0f34b16143b00cf7c15e0403 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_monitor.h @@ -0,0 +1,38 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_monitor.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for monitor failsafe. + */ + +#ifndef FAILSAFE_MCU_MONITOR_H +#define FAILSAFE_MCU_MONITOR_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} MONITOR_FailSafeHandle; + +FunctionSafetyState MONITOR_FailSafeHandler(void* monitorFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_tsensorFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_pmcFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_wdgFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState MONITOR_DefaultFailSafe(void* monitorFailSafeHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_ram.h b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_ram.h new file mode 100644 index 0000000000000000000000000000000000000000..a3cfc0456a230fa0c500b5759bc85c3e8eeb7e4f --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_ram.h @@ -0,0 +1,39 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_ram.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ram failsafe. + */ + +#ifndef FAILSAFE_MCU_RAM_H +#define FAILSAFE_MCU_RAM_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} RAM_FailSafeHandle; + +FunctionSafetyState RAM_FailSafeHandler(void* ramFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_OverflowFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_ParityFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_FullRangeFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_StepRangeFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState RAM_DefaultFailSafe(void* ramFailSafeHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_rom.h b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_rom.h new file mode 100644 index 0000000000000000000000000000000000000000..bc43174f89873999d45de14354cbd07879a64841 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_rom.h @@ -0,0 +1,38 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_rom.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for rom failsafe. + */ + +#ifndef FAILSAFE_MCU_ROM_H +#define FAILSAFE_MCU_ROM_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} ROM_FailSafeHandle; + +FunctionSafetyState ROM_FailSafeHandler(void* romFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState ROM_IntegrityFailSafe(void* romFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState ROM_FullRangeFailSafe(void* romFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState ROM_StepRangeFailSafe(void* romFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState ROM_DefaultFailSafe(void* romFailSafeHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_timers.h b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_timers.h new file mode 100644 index 0000000000000000000000000000000000000000..46ae7138c8fc1e4a63f1224c01ad54d6fa1ac5b2 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/failsafe_mcu_timers.h @@ -0,0 +1,36 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file failsafe_mcu_timers.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for timers failsafe. + */ + +#ifndef FAILSAFE_MCU_TIMERS_H +#define FAILSAFE_MCU_TIMERS_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} TIMERS_FailSafeHandle; + +FunctionSafetyState TIMERS_FailSafeHandler(void* timersFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState TIMERS_InterruptFailSafe(void* timersFailSafeHandle, DiagnoseMoment moment); +FunctionSafetyState TIMERS_DefaultFailSafe(void* timersFailSafeHandle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_ana.h b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_ana.h new file mode 100644 index 0000000000000000000000000000000000000000..38eb5c23b98a3f0649608ff40eecfbb0993984f8 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_ana.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_ana.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ana faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_ANA_H +#define FAULTPREDICT_MCU_ANA_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} ANA_FaultPredictHandle; + +FunctionSafetyState ANA_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_clock.h b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_clock.h new file mode 100644 index 0000000000000000000000000000000000000000..6f1b4a96188dcf527239184c67aea115500f0f46 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_clock.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_clock.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for clock faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_CLOCK_H +#define FAULTPREDICT_MCU_CLOCK_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} CLOCK_FaultPredictHandle; + +FunctionSafetyState CLOCK_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_compute.h b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_compute.h new file mode 100644 index 0000000000000000000000000000000000000000..f223b380e770a48f739b9677156a5a6acf83bcbc --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_compute.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_compute.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for compute faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_COMPUTE_H +#define FAULTPREDICT_MCU_COMPUTE_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} COMPUTE_FaultPredictHandle; + +FunctionSafetyState COMPUTE_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_connect.h b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_connect.h new file mode 100644 index 0000000000000000000000000000000000000000..fe6ca4c9b00c32b0e75ed4b84a510e827807084b --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_connect.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_connect.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for connect faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_CONNECT_H +#define FAULTPREDICT_MCU_CONNECT_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} CONNECT_FaultPredictHandle; + +FunctionSafetyState CONNECT_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_core.h b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_core.h new file mode 100644 index 0000000000000000000000000000000000000000..eb41a076bf301364dc6764b408b51067c1a2502a --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_core.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_core.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for core faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_CORE_H +#define FAULTPREDICT_MCU_CORE_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} CORE_FaultPredictHandle; + +FunctionSafetyState CORE_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_dio.h b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_dio.h new file mode 100644 index 0000000000000000000000000000000000000000..cac625c90b89f358c9f316f68ce669c8e2cfdf2b --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_dio.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_dio.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for dio faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_DIO_H +#define FAULTPREDICT_MCU_DIO_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} DIO_FaultPredictHandle; + +FunctionSafetyState DIO_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_monitor.h b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_monitor.h new file mode 100644 index 0000000000000000000000000000000000000000..9391ea28ce7ef5450135b1d830c5f45a1256d424 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_monitor.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_monitor.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for monitor faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_MONITOR_H +#define FAULTPREDICT_MCU_MONITOR_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} MONITOR_FaultPredictHandle; + +FunctionSafetyState MONITOR_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_ram.h b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_ram.h new file mode 100644 index 0000000000000000000000000000000000000000..fa52a8a0ca58a6c460b76cd16609e05043fc7b94 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_ram.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_ram.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for ram faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_RAM_H +#define FAULTPREDICT_MCU_RAM_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} RAM_FaultPredictHandle; + +FunctionSafetyState RAM_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_rom.h b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_rom.h new file mode 100644 index 0000000000000000000000000000000000000000..4e3fe6c278d21a3302c57c8e4a90b50cae809baf --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_rom.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_rom.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for rom faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_ROM_H +#define FAULTPREDICT_MCU_ROM_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} ANA_FaultPredictHandle; + +FunctionSafetyState ANA_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_timers.h b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_timers.h new file mode 100644 index 0000000000000000000000000000000000000000..87ea327e45fd63666d4d668d82636cd4a5d18ee4 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/faultpredict_mcu_timers.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file faultpredict_mcu_timers.h + * @author MCU Driver Team + * @brief This file contains the handle and function declaration for timers faultpredict. + */ + +#ifndef FAULTPREDICT_MCU_TIMERS_H +#define FAULTPREDICT_MCU_TIMERS_H + +#include "function_safety_common.h" + +typedef struct { + void *param; +} ANA_FaultPredictHandle; + +FunctionSafetyState ANA_FaultPredictHandler(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/function_safety_common.h b/src/middleware/thirdparty/sysroot/include/function_safety/function_safety_common.h new file mode 100644 index 0000000000000000000000000000000000000000..1540ddb0b44e4fcab405c1bcfcb99dc1f9a88413 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/function_safety_common.h @@ -0,0 +1,247 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_battery.h + * @author MCU Driver Team + * @brief This file contains the function safety head file of battery. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef FUNCTION_SAFETYE_COMMON_H +#define FUNCTION_SAFETYE_COMMON_H + +#include "baseinc.h" +#include "sysctrl.h" +#include "crg.h" +#include "gpio.h" +/*--- Diagnose param check ----------------------------------------------------*/ +#ifdef DIAGNOSE_PARAM_CHECK +#define DIAGNOSE_PARAM_CHECK_WITH_STATE(param, state) \ + do { \ + if (!(param)) { \ + STATE_SetDiagnoseResult((FunctionSafetyState *)state, RESULT_FAIL); \ + STATE_SetDiagnoseFaultType((FunctionSafetyState *)state, FAULT_SOFTWARE_PARAM_INCORRECT); \ + return *(FunctionSafetyState *)state; \ + } \ + } while (0) +#else +#define DIAGNOSE_PARAM_CHECK_WITH_STATE(param, ret) ((void)0U) +#endif +/*--- Result definition ------------------------------------------------------*/ +#define RESULT_IS_RUNNING 0x00 +#define RESULT_WARNNING 0x01 +#define RESULT_FAIL 0x02 +#define RESULT_SUCCESS 0x03 + +/*--- Subsysterm definition --------------------------------------------------*/ +#define SUBSYS_CORE 0x01 +#define SUBSYS_CLOCK 0x02 +#define SUBSYS_COMPUTE 0x03 +#define SUBSYS_ROM 0x04 +#define SUBSYS_RAM 0x05 +#define SUBSYS_ANALOG_IO 0x06 +#define SUBSYS_DIGTAL_IO 0x07 +#define SUBSYS_TIMERS 0x08 +#define SUBSYS_CONNECT 0x09 +#define SUBSYS_MONITOR 0x0A + +/*--- Fault type definition --------------------------------------------------*/ +/* common fault type define in here, subsysterm fault type define in subsysterm file */ +#define FAULT_SOFTWARE_PARAM_INCORRECT 0x0F +#define FAULT_REPORT_TIMEOUT 0x0E +/*--- Error rate definition --------------------------------------------------*/ +#define ERROR_RATE_OVER_RANGE 0x7F +/*--- Fail safe measure definition -------------------------------------------*/ +/* common Fail safe measure define in here, subsysterm Fail safe measure define in subsysterm file */ +#define FAIL_SAFE_DEFAULT_MEASURE 0x0F + +typedef enum { + MOMENT_ALLTIME = 0U, + MOMENT_STARTUP, + MOMENT_RUNTIME, + MOMENT_IRQ, +} DiagnoseMoment; + +typedef union { + unsigned int code; + struct { + unsigned int result : 2; + unsigned int moment : 2; + unsigned int errorRate : 8; + unsigned int failSafeMeasure : 4; + unsigned int faultType : 4; + unsigned int feature : 4; + unsigned int moudule : 4; + unsigned int subsysterm : 4; + } BIT; +} FunctionSafetyState; +/** + * @brief set diagnose feature to state. + * @param state @ref FunctionSafetyState. + * @param moment moment. + * @retval None. + */ +static inline void STATE_SetDiagnoseMoment(FunctionSafetyState* state, unsigned int moment) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(moment < 4); /* 4: moment state value limit */ + state->BIT.moment = moment; +} +/** + * @brief set diagnose feature to state. + * @param state @ref FunctionSafetyState. + * @param result result. + * @retval None. + */ +static inline void STATE_SetDiagnoseResult(FunctionSafetyState* state, unsigned int result) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(result < 4); /* 4: result state value limit */ + state->BIT.result = result; +} +/** + * @brief set diagnose feature to state. + * @param state @ref FunctionSafetyState. + * @param subsysterm subsysterm. + * @retval None. + */ +static inline void STATE_SetDiagnoseSubsysterm(FunctionSafetyState* state, unsigned int subsysterm) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(subsysterm < 16); /* 16: subsysterm type value limit */ + state->BIT.subsysterm = subsysterm; +} +/** + * @brief set diagnose feature to state. + * @param state @ref FunctionSafetyState. + * @param moudule module. + * @retval None. + */ +static inline void STATE_SetDiagnoseMoudule(FunctionSafetyState* state, unsigned int moudule) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(moudule < 16); /* 16: moudule type value limit */ + state->BIT.moudule = moudule; +} +/** + * @brief set diagnose feature to state. + * @param state @ref FunctionSafetyState. + * @param feature feature. + * @retval None. + */ +static inline void STATE_SetDiagnoseFeature(FunctionSafetyState* state, unsigned int feature) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(feature < 16); /* 16: feature type value limit */ + state->BIT.feature = feature; +} +/** + * @brief set diagnose fault type to state. + * @param state @ref FunctionSafetyState. + * @param faultType fault type. + * @retval None. + */ +static inline void STATE_SetDiagnoseFaultType(FunctionSafetyState* state, unsigned int faultType) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(faultType < 16); /* 16: faultType value limit */ + state->BIT.faultType = faultType; +} +/** + * @brief set diagnose fail safe measure to state. + * @param state @ref FunctionSafetyState. + * @param failSafeMeasure fail safe measure. + * @retval None. + */ +static inline void STATE_SetDiagnoseFailSafeMeasure(FunctionSafetyState* state, unsigned int failSafeMeasure) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(failSafeMeasure < 16); /* 16: failSafeMeasure type value limit */ + state->BIT.failSafeMeasure = failSafeMeasure; +} +/** + * @brief set diagnose error rate to state. + * @param state @ref FunctionSafetyState. + * @param errorRate diagnose error rate. + * @retval None. + */ +static inline void STATE_SetDiagnoseErrorRate(FunctionSafetyState* state, unsigned int errorRate, bool unsignFlag) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + BASE_FUNC_PARAMCHECK_NO_RET(errorRate < 128); /* 128: errorRate type value limit */ + state->BIT.errorRate = unsignFlag == true ? errorRate : (0x80 | errorRate); +} +/** + * @brief store fail event state. + * @param state @ref FunctionSafetyState. + * @retval None. + */ +static inline void STATE_StoreFailEvent(FunctionSafetyState* state) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + unsigned int softIrqEventId = *(unsigned int*)(void*)state; + DCL_SYSCTRL_SetSoftInterruptEventId(softIrqEventId); /* set fail event */ +} +/** + * @brief Load fail event state. + * @param None. + * @retval state @ref FunctionSafetyState. + */ +static inline FunctionSafetyState STATE_LoadFailEvent(void) +{ + return (FunctionSafetyState)DCL_SYSCTRL_GetSoftInterruptEventId(); /* get fail event */ +} +/** + * @brief store current state. + * @param state @ref FunctionSafetyState. + * @retval None. + */ +static inline void STATE_StoreCurrentState(FunctionSafetyState* state) +{ + BASE_FUNC_ASSERT_PARAM(state != NULL); + SYSCTRL0->USER_REG0.reg = *(unsigned int*)(void*)state; /* store current state into USER_REG0 */ +} +/** + * @brief Load current state. + * @param None. + * @retval state @ref FunctionSafetyState. + */ +static inline FunctionSafetyState STATE_LoadCurrentState(void) +{ + return (FunctionSafetyState)SYSCTRL0->USER_REG0.reg; /* load current state from USER_REG0 */ +} +/** + * @brief Get cpu cycle. + * @param None. + * @retval current cpu cycle. + */ +static inline unsigned int BASE_GetCpuCycle(void) +{ + /* Get the Cpu Cycle Register(CSR) */ + unsigned int cycle; + asm volatile("csrr %0, cycle" : "=r"(cycle)); + return cycle; +} + +typedef void (* ConfigFunc)(void); +typedef FunctionSafetyState (* BackupFunc)(void* handle, DiagnoseMoment moment); +typedef FunctionSafetyState (* DiagnoseFunc)(void* handle, DiagnoseMoment moment); +typedef FunctionSafetyState (* FailSafeFunc)(void* handle, DiagnoseMoment moment); +typedef FunctionSafetyState (* FaultPredictFunc)(void* handle, DiagnoseMoment moment); +typedef FunctionSafetyState (* ResumeFunc)(void* handle, DiagnoseMoment moment); + +#endif \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/function_safety/function_safety_mcu.h b/src/middleware/thirdparty/sysroot/include/function_safety/function_safety_mcu.h new file mode 100644 index 0000000000000000000000000000000000000000..b0791a32b57c7fd7f09fc8e3b9c248e77f3b007b --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/function_safety/function_safety_mcu.h @@ -0,0 +1,55 @@ +/** + * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file function_safety_mcu.h + * @author MCU Driver Team + * @brief This file contains the function safety head file of mcu. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef FUNCTION_SAFETY_MCU_H +#define FUNCTION_SAFETY_MCU_H + +/* common --------------------------------------------------------------------*/ +#include "function_safety_common.h" +#include "function_safety_process.h" +/* diagnose ------------------------------------------------------------------*/ +#include "diagnose_mcu_core.h" +#include "diagnose_mcu_clock.h" +#include "diagnose_mcu_compute.h" +#include "diagnose_mcu_rom.h" +#include "diagnose_mcu_ram.h" +#include "diagnose_mcu_ana.h" +#include "diagnose_mcu_dio.h" +#include "diagnose_mcu_monitor.h" +#include "diagnose_mcu_timers.h" +#include "diagnose_mcu_connect.h" +/* fail safe -----------------------------------------------------------------*/ +#include "failsafe_mcu_ana.h" +#include "failsafe_mcu_core.h" +#include "failsafe_mcu_clock.h" +#include "failsafe_mcu_compute.h" +#include "failsafe_mcu_rom.h" +#include "failsafe_mcu_ram.h" +#include "failsafe_mcu_ana.h" +#include "failsafe_mcu_dio.h" +#include "failsafe_mcu_monitor.h" +#include "failsafe_mcu_timers.h" +#include "failsafe_mcu_connect.h" +/* fault predict -------------------------------------------------------------*/ + +#endif diff --git a/src/middleware/hisilicon/nostask/config/nos_buildef.h b/src/middleware/thirdparty/sysroot/include/function_safety/function_safety_process.h similarity index 58% rename from src/middleware/hisilicon/nostask/config/nos_buildef.h rename to src/middleware/thirdparty/sysroot/include/function_safety/function_safety_process.h index f010b30ef1553c47c678ffbdbbb1837ea473bf06..5f8754bfacb3107531d9ddcafe1e23dc10f61659 100644 --- a/src/middleware/hisilicon/nostask/config/nos_buildef.h +++ b/src/middleware/thirdparty/sysroot/include/function_safety/function_safety_process.h @@ -15,56 +15,39 @@ * 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. - * @file nos_buildef.h + * @file function_safety_process.h + * @author MCU Driver Team + * @brief function safety process module. + * @details function safety process handle and interfece. */ -#ifndef NOS_BUILDEF_H -#define NOS_BUILDEF_H -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif -#endif +#ifndef FUNCTION_SAFETY_PROCESS_H +#define FUNCTION_SAFETY_PROCESS_H -#define OS_ARCH_RISCV YES +#include "function_safety_common.h" -#ifndef OS_HARDWARE_PLATFORM -#define OS_HARDWARE_PLATFORM OS_RISCV -#endif +typedef struct { + BackupFunc contexBackupFunc; + ConfigFunc handleConfigFunc; + DiagnoseFunc diagnoseFunc; + FailSafeFunc failSafeFunc; + FaultPredictFunc faultPredictFunc; + ResumeFunc contexResumeFunc; + void* contexHandle; + void* diagnoseHandle; + void* failSafeHandle; + void* faultPredictHandle; + DiagnoseMoment moment; +} FunctionSafetyProcessHandle; -#ifndef OS_CPU_TYPE -#define OS_CPU_TYPE OS_HIMIDEER -#endif +typedef struct { + bool timeCycleRecordSwitch; + unsigned int diagnoseTimeCycle; + unsigned int failSafeTimeCycle; + unsigned int faultPredictTimeCycle; +} ProcessTimeCycle; -#define OS_MAX_CORE_NUM 1 -#define OS_OPTION_FPU YES +FunctionSafetyState FunctionSafetyProcess(void* processHandle, ProcessTimeCycle* processTime); -#define OS_OPTION_HWI_PRIORITY YES - -#define OS_OPTION_TASK YES - -#define OS_OPTION_TASK_DELETE YES - -#define OS_OPTION_TASK_YIELD YES - -#define OS_TSK_PRIORITY_HIGHEST 0 - -#define OS_TSK_PRIORITY_LOWEST 5 - -#define OS_TSK_NUM_OF_PRIORITIES 6 - -#define OS_TSK_CORE_BYTES_IN_PID 2 - -#define OS_OPTION_TICK YES - -#ifdef __cplusplus -#if __cplusplus -} -#endif -#endif - -/* common macros's definitions */ -#include "os_buildef_common.h" - -#endif +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/nos_api/nos_task.h b/src/middleware/thirdparty/sysroot/include/hisilicon/nos_task.h similarity index 100% rename from src/middleware/hisilicon/nostask/nos_api/nos_task.h rename to src/middleware/thirdparty/sysroot/include/hisilicon/nos_task.h diff --git a/src/middleware/thirdparty/sysroot/include/hisilicon/secinput.h b/src/middleware/thirdparty/sysroot/include/hisilicon/secinput.h new file mode 100644 index 0000000000000000000000000000000000000000..176ee05d96d42aff0aa5968686d4584e5c6a2d8c --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/hisilicon/secinput.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: Define macro, data struct, and declare function prototype, + * which is used by input.inl, secureinput_a.c and secureinput_w.c. + * Create: 2014-02-25 + */ + +#ifndef SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C +#define SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C +#include "securecutil.h" + +#define SECUREC_SCANF_EINVAL (-1) +#define SECUREC_SCANF_ERROR_PARA (-2) + +/* For internal stream flag */ +#define SECUREC_MEM_STR_FLAG 0x01U +#define SECUREC_FILE_STREAM_FLAG 0x02U +#define SECUREC_PIPE_STREAM_FLAG 0x04U +#define SECUREC_LOAD_FILE_TO_MEM_FLAG 0x08U + +#define SECUREC_UCS_BOM_HEADER_SIZE 2U +#define SECUREC_UCS_BOM_HEADER_BE_1ST 0xfeU +#define SECUREC_UCS_BOM_HEADER_BE_2ST 0xffU +#define SECUREC_UCS_BOM_HEADER_LE_1ST 0xffU +#define SECUREC_UCS_BOM_HEADER_LE_2ST 0xfeU +#define SECUREC_UTF8_BOM_HEADER_SIZE 3U +#define SECUREC_UTF8_BOM_HEADER_1ST 0xefU +#define SECUREC_UTF8_BOM_HEADER_2ND 0xbbU +#define SECUREC_UTF8_BOM_HEADER_3RD 0xbfU +#define SECUREC_UTF8_LEAD_1ST 0xe0U +#define SECUREC_UTF8_LEAD_2ND 0x80U + +#define SECUREC_BEGIN_WITH_UCS_BOM(s, len) ((len) == SECUREC_UCS_BOM_HEADER_SIZE && \ + (((unsigned char)((s)[0]) == SECUREC_UCS_BOM_HEADER_LE_1ST && \ + (unsigned char)((s)[1]) == SECUREC_UCS_BOM_HEADER_LE_2ST) || \ + ((unsigned char)((s)[0]) == SECUREC_UCS_BOM_HEADER_BE_1ST && \ + (unsigned char)((s)[1]) == SECUREC_UCS_BOM_HEADER_BE_2ST))) + +#define SECUREC_BEGIN_WITH_UTF8_BOM(s, len) ((len) == SECUREC_UTF8_BOM_HEADER_SIZE && \ + (unsigned char)((s)[0]) == SECUREC_UTF8_BOM_HEADER_1ST && \ + (unsigned char)((s)[1]) == SECUREC_UTF8_BOM_HEADER_2ND && \ + (unsigned char)((s)[2]) == SECUREC_UTF8_BOM_HEADER_3RD) + +#ifdef SECUREC_FOR_WCHAR +#define SECUREC_BOM_HEADER_SIZE SECUREC_UCS_BOM_HEADER_SIZE +#define SECUREC_BEGIN_WITH_BOM(s, len) SECUREC_BEGIN_WITH_UCS_BOM((s), (len)) +#else +#define SECUREC_BOM_HEADER_SIZE SECUREC_UTF8_BOM_HEADER_SIZE +#define SECUREC_BEGIN_WITH_BOM(s, len) SECUREC_BEGIN_WITH_UTF8_BOM((s), (len)) +#endif + +typedef struct { + unsigned int flag; /* Mark the properties of input stream */ + char *base; /* The pointer to the header of buffered string */ + const char *cur; /* The pointer to next read position */ + size_t count; /* The size of buffered string in bytes */ +#if SECUREC_ENABLE_SCANF_FILE + FILE *pf; /* The file pointer */ + size_t fileRealRead; + long oriFilePos; /* The original position of file offset when fscanf is called */ +#endif +} SecFileStream; + +#if SECUREC_ENABLE_SCANF_FILE +#define SECUREC_FILE_STREAM_INIT_FILE(stream, fp) do { \ + (stream)->pf = (fp); \ + (stream)->fileRealRead = 0; \ + (stream)->oriFilePos = 0; \ +} SECUREC_WHILE_ZERO +#else +/* Disable file */ +#define SECUREC_FILE_STREAM_INIT_FILE(stream, fp) +#endif + +/* This initialization for eliminating redundant initialization. */ +#define SECUREC_FILE_STREAM_FROM_STRING(stream, buf, cnt) do { \ + (stream)->flag = SECUREC_MEM_STR_FLAG; \ + (stream)->base = NULL; \ + (stream)->cur = (buf); \ + (stream)->count = (cnt); \ + SECUREC_FILE_STREAM_INIT_FILE((stream), NULL); \ +} SECUREC_WHILE_ZERO + +/* This initialization for eliminating redundant initialization. */ +#define SECUREC_FILE_STREAM_FROM_FILE(stream, fp) do { \ + (stream)->flag = SECUREC_FILE_STREAM_FLAG; \ + (stream)->base = NULL; \ + (stream)->cur = NULL; \ + (stream)->count = 0; \ + SECUREC_FILE_STREAM_INIT_FILE((stream), (fp)); \ +} SECUREC_WHILE_ZERO + +/* This initialization for eliminating redundant initialization. */ +#define SECUREC_FILE_STREAM_FROM_STDIN(stream) do { \ + (stream)->flag = SECUREC_PIPE_STREAM_FLAG; \ + (stream)->base = NULL; \ + (stream)->cur = NULL; \ + (stream)->count = 0; \ + SECUREC_FILE_STREAM_INIT_FILE((stream), SECUREC_STREAM_STDIN); \ +} SECUREC_WHILE_ZERO + +#ifdef __cplusplus +extern "C" { +#endif +int SecInputS(SecFileStream *stream, const char *cFormat, va_list argList); +void SecClearDestBuf(const char *buffer, const char *format, va_list argList); +#ifdef SECUREC_FOR_WCHAR +int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList); +void SecClearDestBufW(const wchar_t *buffer, const wchar_t *format, va_list argList); +#endif + +/* 20150105 For software and hardware decoupling,such as UMG */ +#ifdef SECUREC_SYSAPI4VXWORKS +#ifdef feof +#undef feof +#endif +extern int feof(FILE *stream); +#endif + +#if defined(SECUREC_SYSAPI4VXWORKS) || defined(SECUREC_CTYPE_MACRO_ADAPT) +#ifndef isspace +#define isspace(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n')) +#endif +#ifndef iswspace +#define iswspace(c) (((c) == L' ') || ((c) == L'\t') || ((c) == L'\r') || ((c) == L'\n')) +#endif +#ifndef isascii +#define isascii(c) (((unsigned char)(c)) <= 0x7f) +#endif +#ifndef isupper +#define isupper(c) ((c) >= 'A' && (c) <= 'Z') +#endif +#ifndef islower +#define islower(c) ((c) >= 'a' && (c) <= 'z') +#endif +#ifndef isalpha +#define isalpha(c) (isupper(c) || (islower(c))) +#endif +#ifndef isdigit +#define isdigit(c) ((c) >= '0' && (c) <= '9') +#endif +#ifndef isxupper +#define isxupper(c) ((c) >= 'A' && (c) <= 'F') +#endif +#ifndef isxlower +#define isxlower(c) ((c) >= 'a' && (c) <= 'f') +#endif +#ifndef isxdigit +#define isxdigit(c) (isdigit(c) || isxupper(c) || isxlower(c)) +#endif +#endif + +#ifdef __cplusplus +} +#endif +/* Reserved file operation macro interface, s is FILE *, i is fileno zero. */ +#ifndef SECUREC_LOCK_FILE +#define SECUREC_LOCK_FILE(s) +#endif + +#ifndef SECUREC_UNLOCK_FILE +#define SECUREC_UNLOCK_FILE(s) +#endif + +#ifndef SECUREC_LOCK_STDIN +#define SECUREC_LOCK_STDIN(i, s) +#endif + +#ifndef SECUREC_UNLOCK_STDIN +#define SECUREC_UNLOCK_STDIN(i, s) +#endif +#endif + diff --git a/src/middleware/thirdparty/sysroot/include/hisilicon/securec.h b/src/middleware/thirdparty/sysroot/include/hisilicon/securec.h new file mode 100644 index 0000000000000000000000000000000000000000..b1dea967d8f5a6a14010ebf706fa5082fb229b4f --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/hisilicon/securec.h @@ -0,0 +1,637 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: The user of this secure c library should include this header file in you source code. + * This header file declare all supported API prototype of the library, + * such as memcpy_s, strcpy_s, wcscpy_s,strcat_s, strncat_s, sprintf_s, scanf_s, and so on. + * Create: 2014-02-25 + * Notes: Do not modify this file by yourself. + */ + +#ifndef SECUREC_H_5D13A042_DC3F_4ED9_A8D1_882811274C27 +#define SECUREC_H_5D13A042_DC3F_4ED9_A8D1_882811274C27 + +#include "securectype.h" +#ifndef SECUREC_HAVE_STDARG_H +#define SECUREC_HAVE_STDARG_H 1 +#endif + +#if SECUREC_HAVE_STDARG_H +#include +#endif + +#ifndef SECUREC_HAVE_ERRNO_H +#define SECUREC_HAVE_ERRNO_H 1 +#endif + +/* EINVAL ERANGE may defined in errno.h */ +#if SECUREC_HAVE_ERRNO_H +#if SECUREC_IN_KERNEL +#include +#else +#include +#endif +#endif + +/* Define error code */ +#if defined(SECUREC_NEED_ERRNO_TYPE) || !defined(__STDC_WANT_LIB_EXT1__) || \ + (defined(__STDC_WANT_LIB_EXT1__) && (!__STDC_WANT_LIB_EXT1__)) +#ifndef SECUREC_DEFINED_ERRNO_TYPE +#define SECUREC_DEFINED_ERRNO_TYPE +/* Just check whether macrodefinition exists. */ +#ifndef errno_t +typedef int errno_t; +#endif +#endif +#endif + +/* Success */ +#ifndef EOK +#define EOK 0 +#endif + +#ifndef EINVAL +/* The src buffer is not correct and destination buffer can not be reset */ +#define EINVAL 22 +#endif + +#ifndef EINVAL_AND_RESET +/* Once the error is detected, the dest buffer must be reset! Value is 22 or 128 */ +#define EINVAL_AND_RESET 150 +#endif + +#ifndef ERANGE +/* The destination buffer is not long enough and destination buffer can not be reset */ +#define ERANGE 34 +#endif + +#ifndef ERANGE_AND_RESET +/* Once the error is detected, the dest buffer must be reset! Value is 34 or 128 */ +#define ERANGE_AND_RESET 162 +#endif + +#ifndef EOVERLAP_AND_RESET +/* Once the buffer overlap is detected, the dest buffer must be reset! Value is 54 or 128 */ +#define EOVERLAP_AND_RESET 182 +#endif + +/* If you need export the function of this library in Win32 dll, use __declspec(dllexport) */ +#ifndef SECUREC_API +#if defined(SECUREC_DLL_EXPORT) +#if defined(_MSC_VER) +#define SECUREC_API __declspec(dllexport) +#else /* build for linux */ +#define SECUREC_API __attribute__((visibility("default"))) +#endif /* end of _MSC_VER and SECUREC_DLL_EXPORT */ +#elif defined(SECUREC_DLL_IMPORT) +#if defined(_MSC_VER) +#define SECUREC_API __declspec(dllimport) +#else +#define SECUREC_API +#endif /* end of _MSC_VER and SECUREC_DLL_IMPORT */ +#else +/* + * Standardized function declaration. If a security function is declared in the your code, + * it may cause a compilation alarm,Please delete the security function you declared. + * Adding extern under windows will cause the system to have inline functions to expand, + * so do not add the extern in default + */ +#if defined(_MSC_VER) +#define SECUREC_API +#else +#define SECUREC_API extern +#endif +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Description: The GetHwSecureCVersion function get SecureC Version string and version number. + * Parameter: verNumber - to store version number (for example value is 0x500 | 0xa) + * Return: version string + */ +SECUREC_API const char *GetHwSecureCVersion(unsigned short *verNumber); + +#if SECUREC_ENABLE_MEMSET +/* + * Description: The memset_s function copies the value of c (converted to an unsigned char) into each of + * the first count characters of the object pointed to by dest. + * Parameter: dest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: c - the value to be copied + * Parameter: count - copies count bytes of value to dest + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t memset_s(void *dest, size_t destMax, int c, size_t count); +#endif + +#ifndef SECUREC_ONLY_DECLARE_MEMSET +#define SECUREC_ONLY_DECLARE_MEMSET 0 +#endif + +#if !SECUREC_ONLY_DECLARE_MEMSET + +#if SECUREC_ENABLE_MEMMOVE +/* + * Description: The memmove_s function copies n characters from the object pointed to by src + * into the object pointed to by dest. + * Parameter: dest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: src - source address + * Parameter: count - copies count bytes from the src + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count); +#endif + +#if SECUREC_ENABLE_MEMCPY +/* + * Description: The memcpy_s function copies n characters from the object pointed to + * by src into the object pointed to by dest. + * Parameter: dest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: src - source address + * Parameter: count - copies count bytes from the src + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t memcpy_s(void *dest, size_t destMax, const void *src, size_t count); +#endif + +#if SECUREC_ENABLE_STRCPY +/* + * Description: The strcpy_s function copies the string pointed to by strSrc (including + * the terminating null character) into the array pointed to by strDest + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) + * Parameter: strSrc - source address + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t strcpy_s(char *strDest, size_t destMax, const char *strSrc); +#endif + +#if SECUREC_ENABLE_STRNCPY +/* + * Description: The strncpy_s function copies not more than n successive characters (not including + * the terminating null character) from the array pointed to by strSrc to the array pointed to by strDest. + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) + * Parameter: strSrc - source address + * Parameter: count - copies count characters from the src + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t strncpy_s(char *strDest, size_t destMax, const char *strSrc, size_t count); +#endif + +#if SECUREC_ENABLE_STRCAT +/* + * Description: The strcat_s function appends a copy of the string pointed to by strSrc (including + * the terminating null character) to the end of the string pointed to by strDest. + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating null wide character) + * Parameter: strSrc - source address + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc); +#endif + +#if SECUREC_ENABLE_STRNCAT +/* + * Description: The strncat_s function appends not more than n successive characters (not including + * the terminating null character) + * from the array pointed to by strSrc to the end of the string pointed to by strDest. + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) + * Parameter: strSrc - source address + * Parameter: count - copies count characters from the src + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t strncat_s(char *strDest, size_t destMax, const char *strSrc, size_t count); +#endif + +#if SECUREC_ENABLE_VSPRINTF +/* + * Description: The vsprintf_s function is equivalent to the vsprintf function except for the parameter destMax + * and the explicit runtime-constraints violation + * Parameter: strDest - produce output according to a format,write to the character string strDest. + * Parameter: destMax - The maximum length of destination buffer(including the terminating null wide character) + * Parameter: format - format string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1. + */ +SECUREC_API int vsprintf_s(char *strDest, size_t destMax, const char *format, + va_list argList) SECUREC_ATTRIBUTE(3, 0); +#endif + +#if SECUREC_ENABLE_SPRINTF +/* + * Description: The sprintf_s function is equivalent to the sprintf function except for the parameter destMax + * and the explicit runtime-constraints violation + * Parameter: strDest - produce output according to a format ,write to the character string strDest. + * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') + * Parameter: format - format string + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1. +*/ +SECUREC_API int sprintf_s(char *strDest, size_t destMax, const char *format, ...) SECUREC_ATTRIBUTE(3, 4); +#endif + +#if SECUREC_ENABLE_VSNPRINTF +/* + * Description: The vsnprintf_s function is equivalent to the vsnprintf function except for + * the parameter destMax/count and the explicit runtime-constraints violation + * Parameter: strDest - produce output according to a format ,write to the character string strDest. + * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') + * Parameter: count - do not write more than count bytes to strDest(not including the terminating null byte '\0') + * Parameter: format - format string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1.Pay special attention to returning -1 when truncation occurs. + */ +SECUREC_API int vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format, + va_list argList) SECUREC_ATTRIBUTE(4, 0); +#endif + +#if SECUREC_ENABLE_SNPRINTF +/* + * Description: The snprintf_s function is equivalent to the snprintf function except for + * the parameter destMax/count and the explicit runtime-constraints violation + * Parameter: strDest - produce output according to a format ,write to the character string strDest. + * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') + * Parameter: count - do not write more than count bytes to strDest(not including the terminating null byte '\0') + * Parameter: format - format string + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1.Pay special attention to returning -1 when truncation occurs. + */ +SECUREC_API int snprintf_s(char *strDest, size_t destMax, size_t count, const char *format, + ...) SECUREC_ATTRIBUTE(4, 5); +#endif + +#if SECUREC_SNPRINTF_TRUNCATED +/* + * Description: The vsnprintf_truncated_s function is equivalent to the vsnprintf_s function except + * no count parameter and return value + * Parameter: strDest - produce output according to a format ,write to the character string strDest + * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') + * Parameter: format - format string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1.Pay special attention to returning destMax - 1 when truncation occurs +*/ +SECUREC_API int vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format, + va_list argList) SECUREC_ATTRIBUTE(3, 0); + +/* + * Description: The snprintf_truncated_s function is equivalent to the snprintf_s function except + * no count parameter and return value + * Parameter: strDest - produce output according to a format,write to the character string strDest. + * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') + * Parameter: format - format string + * Return: the number of characters printed(not including the terminating null byte '\0'), + * If an error occurred Return: -1.Pay special attention to returning destMax - 1 when truncation occurs. + */ +SECUREC_API int snprintf_truncated_s(char *strDest, size_t destMax, + const char *format, ...) SECUREC_ATTRIBUTE(3, 4); +#endif + +#if SECUREC_ENABLE_SCANF +/* + * Description: The scanf_s function is equivalent to fscanf_s with the argument stdin + * interposed before the arguments to scanf_s + * Parameter: format - format string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int scanf_s(const char *format, ...); +#endif + +#if SECUREC_ENABLE_VSCANF +/* + * Description: The vscanf_s function is equivalent to scanf_s, with the variable argument list replaced by argList + * Parameter: format - format string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int vscanf_s(const char *format, va_list argList); +#endif + +#if SECUREC_ENABLE_SSCANF +/* + * Description: The sscanf_s function is equivalent to fscanf_s, except that input is obtained from a + * string (specified by the argument buffer) rather than from a stream + * Parameter: buffer - read character from buffer + * Parameter: format - format string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int sscanf_s(const char *buffer, const char *format, ...); +#endif + +#if SECUREC_ENABLE_VSSCANF +/* + * Description: The vsscanf_s function is equivalent to sscanf_s, with the variable argument list + * replaced by argList + * Parameter: buffer - read character from buffer + * Parameter: format - format string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int vsscanf_s(const char *buffer, const char *format, va_list argList); +#endif + +#if SECUREC_ENABLE_FSCANF +/* + * Description: The fscanf_s function is equivalent to fscanf except that the c, s, and [ conversion specifiers + * apply to a pair of arguments (unless assignment suppression is indicated by a *) + * Parameter: stream - stdio file stream + * Parameter: format - format string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int fscanf_s(FILE *stream, const char *format, ...); +#endif + +#if SECUREC_ENABLE_VFSCANF +/* + * Description: The vfscanf_s function is equivalent to fscanf_s, with the variable argument list + * replaced by argList + * Parameter: stream - stdio file stream + * Parameter: format - format string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int vfscanf_s(FILE *stream, const char *format, va_list argList); +#endif + +#if SECUREC_ENABLE_STRTOK +/* + * Description: The strtok_s function parses a string into a sequence of strToken, + * replace all characters in strToken string that match to strDelimit set with 0. + * On the first call to strtok_s the string to be parsed should be specified in strToken. + * In each subsequent call that should parse the same string, strToken should be NULL + * Parameter: strToken - the string to be delimited + * Parameter: strDelimit - specifies a set of characters that delimit the tokens in the parsed string + * Parameter: context - is a pointer to a char * variable that is used internally by strtok_s function + * Return: On the first call returns the address of the first non \0 character, otherwise NULL is returned. + * In subsequent calls, the strtoken is set to NULL, and the context set is the same as the previous call, + * return NULL if the *context string length is equal 0, otherwise return *context. + */ +SECUREC_API char *strtok_s(char *strToken, const char *strDelimit, char **context); +#endif + +#if SECUREC_ENABLE_GETS && !SECUREC_IN_KERNEL +/* + * Description: The gets_s function reads at most one less than the number of characters specified + * by destMax from the stream pointed to by stdin, into the array pointed to by buffer + * Parameter: buffer - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) + * Return: buffer if there was no runtime-constraint violation,If an error occurred Return: NULL. + */ +SECUREC_API char *gets_s(char *buffer, size_t destMax); +#endif + +#if SECUREC_ENABLE_WCHAR_FUNC +#if SECUREC_ENABLE_MEMCPY +/* + * Description: The wmemcpy_s function copies n successive wide characters from the object pointed to + * by src into the object pointed to by dest. + * Parameter: dest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: src - source address + * Parameter: count - copies count wide characters from the src + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t wmemcpy_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count); +#endif + +#if SECUREC_ENABLE_MEMMOVE +/* + * Description: The wmemmove_s function copies n successive wide characters from the object + * pointed to by src into the object pointed to by dest. + * Parameter: dest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: src - source address + * Parameter: count - copies count wide characters from the src + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t wmemmove_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count); +#endif + +#if SECUREC_ENABLE_STRCPY +/* + * Description: The wcscpy_s function copies the wide string pointed to by strSrc(including the terminating + * null wide character) into the array pointed to by strDest + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer + * Parameter: strSrc - source address + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t wcscpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc); +#endif + +#if SECUREC_ENABLE_STRNCPY +/* + * Description: The wcsncpy_s function copies not more than n successive wide characters (not including the + * terminating null wide character) from the array pointed to by strSrc to the array pointed to by strDest + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character) + * Parameter: strSrc - source address + * Parameter: count - copies count wide characters from the src + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t wcsncpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count); +#endif + +#if SECUREC_ENABLE_STRCAT +/* + * Description: The wcscat_s function appends a copy of the wide string pointed to by strSrc (including the + * terminating null wide character) to the end of the wide string pointed to by strDest + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character) + * Parameter: strSrc - source address + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc); +#endif + +#if SECUREC_ENABLE_STRNCAT +/* + * Description: The wcsncat_s function appends not more than n successive wide characters (not including the + * terminating null wide character) from the array pointed to by strSrc to the end of the wide string pointed to + * by strDest. + * Parameter: strDest - destination address + * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character) + * Parameter: strSrc - source address + * Parameter: count - copies count wide characters from the src + * Return: EOK if there was no runtime-constraint violation + */ +SECUREC_API errno_t wcsncat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count); +#endif + +#if SECUREC_ENABLE_STRTOK +/* + * Description: The wcstok_s function is the wide-character equivalent of the strtok_s function + * Parameter: strToken - the string to be delimited + * Parameter: strDelimit - specifies a set of characters that delimit the tokens in the parsed string + * Parameter: context - is a pointer to a char * variable that is used internally by strtok_s function + * Return: a pointer to the first character of a token, or a null pointer if there is no token + * or there is a runtime-constraint violation. + */ +SECUREC_API wchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context); +#endif + +#if SECUREC_ENABLE_VSPRINTF +/* + * Description: The vswprintf_s function is the wide-character equivalent of the vsprintf_s function + * Parameter: strDest - produce output according to a format,write to the character string strDest + * Parameter: destMax - The maximum length of destination buffer(including the terminating null) + * Parameter: format - format string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of characters printed(not including the terminating null wide character), + * If an error occurred Return: -1. + */ +SECUREC_API int vswprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, va_list argList); +#endif + +#if SECUREC_ENABLE_SPRINTF +/* + * Description: The swprintf_s function is the wide-character equivalent of the sprintf_s function + * Parameter: strDest - produce output according to a format,write to the character string strDest + * Parameter: destMax - The maximum length of destination buffer(including the terminating null) + * Parameter: format - format string + * Return: the number of characters printed(not including the terminating null wide character), + * If an error occurred Return: -1. + */ +SECUREC_API int swprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, ...); +#endif + +#if SECUREC_ENABLE_FSCANF +/* + * Description: The fwscanf_s function is the wide-character equivalent of the fscanf_s function + * Parameter: stream - stdio file stream + * Parameter: format - format string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int fwscanf_s(FILE *stream, const wchar_t *format, ...); +#endif + +#if SECUREC_ENABLE_VFSCANF +/* + * Description: The vfwscanf_s function is the wide-character equivalent of the vfscanf_s function + * Parameter: stream - stdio file stream + * Parameter: format - format string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int vfwscanf_s(FILE *stream, const wchar_t *format, va_list argList); +#endif + +#if SECUREC_ENABLE_SCANF +/* + * Description: The wscanf_s function is the wide-character equivalent of the scanf_s function + * Parameter: format - format string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int wscanf_s(const wchar_t *format, ...); +#endif + +#if SECUREC_ENABLE_VSCANF +/* + * Description: The vwscanf_s function is the wide-character equivalent of the vscanf_s function + * Parameter: format - format string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int vwscanf_s(const wchar_t *format, va_list argList); +#endif + +#if SECUREC_ENABLE_SSCANF +/* + * Description: The swscanf_s function is the wide-character equivalent of the sscanf_s function + * Parameter: buffer - read character from buffer + * Parameter: format - format string + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int swscanf_s(const wchar_t *buffer, const wchar_t *format, ...); +#endif + +#if SECUREC_ENABLE_VSSCANF +/* + * Description: The vswscanf_s function is the wide-character equivalent of the vsscanf_s function + * Parameter: buffer - read character from buffer + * Parameter: format - format string + * Parameter: argList - instead of a variable number of arguments + * Return: the number of input items assigned, If an error occurred Return: -1. + */ +SECUREC_API int vswscanf_s(const wchar_t *buffer, const wchar_t *format, va_list argList); +#endif +#endif /* SECUREC_ENABLE_WCHAR_FUNC */ +#endif + +/* Those functions are used by macro,must declare hare, also for without function declaration warning */ +extern errno_t strncpy_error(char *strDest, size_t destMax, const char *strSrc, size_t count); +extern errno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc); + +#if SECUREC_WITH_PERFORMANCE_ADDONS +/* Those functions are used by macro */ +extern errno_t memset_sOptAsm(void *dest, size_t destMax, int c, size_t count); +extern errno_t memset_sOptTc(void *dest, size_t destMax, int c, size_t count); +extern errno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src, size_t count); +extern errno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src, size_t count); + +/* The strcpy_sp is a macro, not a function in performance optimization mode. */ +#define strcpy_sp(dest, destMax, src) ((__builtin_constant_p((destMax)) && \ + __builtin_constant_p((src))) ? \ + SECUREC_STRCPY_SM((dest), (destMax), (src)) : \ + strcpy_s((dest), (destMax), (src))) + +/* The strncpy_sp is a macro, not a function in performance optimization mode. */ +#define strncpy_sp(dest, destMax, src, count) ((__builtin_constant_p((count)) && \ + __builtin_constant_p((destMax)) && \ + __builtin_constant_p((src))) ? \ + SECUREC_STRNCPY_SM((dest), (destMax), (src), (count)) : \ + strncpy_s((dest), (destMax), (src), (count))) + +/* The strcat_sp is a macro, not a function in performance optimization mode. */ +#define strcat_sp(dest, destMax, src) ((__builtin_constant_p((destMax)) && \ + __builtin_constant_p((src))) ? \ + SECUREC_STRCAT_SM((dest), (destMax), (src)) : \ + strcat_s((dest), (destMax), (src))) + +/* The strncat_sp is a macro, not a function in performance optimization mode. */ +#define strncat_sp(dest, destMax, src, count) ((__builtin_constant_p((count)) && \ + __builtin_constant_p((destMax)) && \ + __builtin_constant_p((src))) ? \ + SECUREC_STRNCAT_SM((dest), (destMax), (src), (count)) : \ + strncat_s((dest), (destMax), (src), (count))) + +/* The memcpy_sp is a macro, not a function in performance optimization mode. */ +#define memcpy_sp(dest, destMax, src, count) (__builtin_constant_p((count)) ? \ + (SECUREC_MEMCPY_SM((dest), (destMax), (src), (count))) : \ + (__builtin_constant_p((destMax)) ? \ + (((size_t)(destMax) > 0 && \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_MEM_MAX_LEN)) ? \ + memcpy_sOptTc((dest), (destMax), (src), (count)) : ERANGE) : \ + memcpy_sOptAsm((dest), (destMax), (src), (count)))) + +/* The memset_sp is a macro, not a function in performance optimization mode. */ +#define memset_sp(dest, destMax, c, count) (__builtin_constant_p((count)) ? \ + (SECUREC_MEMSET_SM((dest), (destMax), (c), (count))) : \ + (__builtin_constant_p((destMax)) ? \ + (((((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_MEM_MAX_LEN)) ? \ + memset_sOptTc((dest), (destMax), (c), (count)) : ERANGE) : \ + memset_sOptAsm((dest), (destMax), (c), (count)))) + +#endif + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/src/middleware/thirdparty/sysroot/include/hisilicon/securectype.h b/src/middleware/thirdparty/sysroot/include/hisilicon/securectype.h new file mode 100644 index 0000000000000000000000000000000000000000..69e79c2f9013e38bf42e87633f9bb3f16c930de8 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/hisilicon/securectype.h @@ -0,0 +1,585 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: Define internal used macro and data type. The marco of SECUREC_ON_64BITS + * will be determined in this header file, which is a switch for part + * of code. Some macro are used to suppress warning by MS compiler. + * Create: 2014-02-25 + * Notes: User can change the value of SECUREC_STRING_MAX_LEN and SECUREC_MEM_MAX_LEN + * macro to meet their special need, but The maximum value should not exceed 2G. + */ +/* + * [Standardize-exceptions]: Performance-sensitive + * [reason]: Strict parameter verification has been done before use + */ + +#ifndef SECURECTYPE_H_A7BBB686_AADA_451B_B9F9_44DACDAE18A7 +#define SECURECTYPE_H_A7BBB686_AADA_451B_B9F9_44DACDAE18A7 + +#ifndef SECUREC_USING_STD_SECURE_LIB +#if defined(_MSC_VER) && _MSC_VER >= 1400 +#if defined(__STDC_WANT_SECURE_LIB__) && (!__STDC_WANT_SECURE_LIB__) +/* Security functions have been provided since vs2005, default use of system library functions */ +#define SECUREC_USING_STD_SECURE_LIB 0 +#else +#define SECUREC_USING_STD_SECURE_LIB 1 +#endif +#else +#define SECUREC_USING_STD_SECURE_LIB 0 +#endif +#endif + +/* Compatibility with older Secure C versions, shielding VC symbol redefinition warning */ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) && (!SECUREC_USING_STD_SECURE_LIB) +#ifndef SECUREC_DISABLE_CRT_FUNC +#define SECUREC_DISABLE_CRT_FUNC 1 +#endif +#ifndef SECUREC_DISABLE_CRT_IMP +#define SECUREC_DISABLE_CRT_IMP 1 +#endif +#else /* MSC VER */ +#ifndef SECUREC_DISABLE_CRT_FUNC +#define SECUREC_DISABLE_CRT_FUNC 0 +#endif +#ifndef SECUREC_DISABLE_CRT_IMP +#define SECUREC_DISABLE_CRT_IMP 0 +#endif +#endif + +#if SECUREC_DISABLE_CRT_FUNC +#ifdef __STDC_WANT_SECURE_LIB__ +#undef __STDC_WANT_SECURE_LIB__ +#endif +#define __STDC_WANT_SECURE_LIB__ 0 +#endif + +#if SECUREC_DISABLE_CRT_IMP +#ifdef _CRTIMP_ALTERNATIVE +#undef _CRTIMP_ALTERNATIVE +#endif +#define _CRTIMP_ALTERNATIVE /* Comment Microsoft *_s function */ +#endif + +/* Compile in kernel under macro control */ +#ifndef SECUREC_IN_KERNEL +#ifdef __KERNEL__ +#define SECUREC_IN_KERNEL 1 +#else +#define SECUREC_IN_KERNEL 0 +#endif +#endif + +/* make kernel symbols of functions available to loadable modules */ +#ifndef SECUREC_EXPORT_KERNEL_SYMBOL +#if SECUREC_IN_KERNEL +#define SECUREC_EXPORT_KERNEL_SYMBOL 1 +#else +#define SECUREC_EXPORT_KERNEL_SYMBOL 0 +#endif +#endif + +#if SECUREC_IN_KERNEL +#ifndef SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_SCANF_FILE 0 +#endif +#ifndef SECUREC_ENABLE_WCHAR_FUNC +#define SECUREC_ENABLE_WCHAR_FUNC 0 +#endif +#else /* SECUREC_IN_KERNEL */ +#ifndef SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_SCANF_FILE 1 +#endif +#ifndef SECUREC_ENABLE_WCHAR_FUNC +#define SECUREC_ENABLE_WCHAR_FUNC 1 +#endif +#endif + +/* Default secure function declaration, default declarations for non-standard functions */ +#ifndef SECUREC_SNPRINTF_TRUNCATED +#define SECUREC_SNPRINTF_TRUNCATED 1 +#endif + +#if SECUREC_USING_STD_SECURE_LIB +#if defined(_MSC_VER) && _MSC_VER >= 1400 +/* Declare secure functions that are not available in the VS compiler */ +#ifndef SECUREC_ENABLE_MEMSET +#define SECUREC_ENABLE_MEMSET 1 +#endif +/* VS 2005 have vsnprintf_s function */ +#ifndef SECUREC_ENABLE_VSNPRINTF +#define SECUREC_ENABLE_VSNPRINTF 0 +#endif +#ifndef SECUREC_ENABLE_SNPRINTF +/* VS 2005 have vsnprintf_s function Adapt the snprintf_s of the security function */ +#define snprintf_s _snprintf_s +#define SECUREC_ENABLE_SNPRINTF 0 +#endif +/* Before VS 2010 do not have v functions */ +#if _MSC_VER <= 1600 || defined(SECUREC_FOR_V_SCANFS) +#ifndef SECUREC_ENABLE_VFSCANF +#define SECUREC_ENABLE_VFSCANF 1 +#endif +#ifndef SECUREC_ENABLE_VSCANF +#define SECUREC_ENABLE_VSCANF 1 +#endif +#ifndef SECUREC_ENABLE_VSSCANF +#define SECUREC_ENABLE_VSSCANF 1 +#endif +#endif + +#else /* MSC VER */ +#ifndef SECUREC_ENABLE_MEMSET +#define SECUREC_ENABLE_MEMSET 0 +#endif +#ifndef SECUREC_ENABLE_SNPRINTF +#define SECUREC_ENABLE_SNPRINTF 0 +#endif +#ifndef SECUREC_ENABLE_VSNPRINTF +#define SECUREC_ENABLE_VSNPRINTF 0 +#endif +#endif + +#ifndef SECUREC_ENABLE_MEMMOVE +#define SECUREC_ENABLE_MEMMOVE 0 +#endif +#ifndef SECUREC_ENABLE_MEMCPY +#define SECUREC_ENABLE_MEMCPY 0 +#endif +#ifndef SECUREC_ENABLE_STRCPY +#define SECUREC_ENABLE_STRCPY 0 +#endif +#ifndef SECUREC_ENABLE_STRNCPY +#define SECUREC_ENABLE_STRNCPY 0 +#endif +#ifndef SECUREC_ENABLE_STRCAT +#define SECUREC_ENABLE_STRCAT 0 +#endif +#ifndef SECUREC_ENABLE_STRNCAT +#define SECUREC_ENABLE_STRNCAT 0 +#endif +#ifndef SECUREC_ENABLE_SPRINTF +#define SECUREC_ENABLE_SPRINTF 0 +#endif +#ifndef SECUREC_ENABLE_VSPRINTF +#define SECUREC_ENABLE_VSPRINTF 0 +#endif +#ifndef SECUREC_ENABLE_SSCANF +#define SECUREC_ENABLE_SSCANF 0 +#endif +#ifndef SECUREC_ENABLE_VSSCANF +#define SECUREC_ENABLE_VSSCANF 0 +#endif +#ifndef SECUREC_ENABLE_SCANF +#define SECUREC_ENABLE_SCANF 0 +#endif +#ifndef SECUREC_ENABLE_VSCANF +#define SECUREC_ENABLE_VSCANF 0 +#endif + +#ifndef SECUREC_ENABLE_FSCANF +#define SECUREC_ENABLE_FSCANF 0 +#endif +#ifndef SECUREC_ENABLE_VFSCANF +#define SECUREC_ENABLE_VFSCANF 0 +#endif +#ifndef SECUREC_ENABLE_STRTOK +#define SECUREC_ENABLE_STRTOK 0 +#endif +#ifndef SECUREC_ENABLE_GETS +#define SECUREC_ENABLE_GETS 0 +#endif + +#else /* SECUREC USE STD SECURE LIB */ + +#ifndef SECUREC_ENABLE_MEMSET +#define SECUREC_ENABLE_MEMSET 1 +#endif +#ifndef SECUREC_ENABLE_MEMMOVE +#define SECUREC_ENABLE_MEMMOVE 1 +#endif +#ifndef SECUREC_ENABLE_MEMCPY +#define SECUREC_ENABLE_MEMCPY 1 +#endif +#ifndef SECUREC_ENABLE_STRCPY +#define SECUREC_ENABLE_STRCPY 1 +#endif +#ifndef SECUREC_ENABLE_STRNCPY +#define SECUREC_ENABLE_STRNCPY 1 +#endif +#ifndef SECUREC_ENABLE_STRCAT +#define SECUREC_ENABLE_STRCAT 1 +#endif +#ifndef SECUREC_ENABLE_STRNCAT +#define SECUREC_ENABLE_STRNCAT 1 +#endif +#ifndef SECUREC_ENABLE_SPRINTF +#define SECUREC_ENABLE_SPRINTF 1 +#endif +#ifndef SECUREC_ENABLE_VSPRINTF +#define SECUREC_ENABLE_VSPRINTF 1 +#endif +#ifndef SECUREC_ENABLE_SNPRINTF +#define SECUREC_ENABLE_SNPRINTF 1 +#endif +#ifndef SECUREC_ENABLE_VSNPRINTF +#define SECUREC_ENABLE_VSNPRINTF 1 +#endif +#ifndef SECUREC_ENABLE_SSCANF +#define SECUREC_ENABLE_SSCANF 1 +#endif +#ifndef SECUREC_ENABLE_VSSCANF +#define SECUREC_ENABLE_VSSCANF 1 +#endif +#ifndef SECUREC_ENABLE_SCANF +#if SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_SCANF 1 +#else +#define SECUREC_ENABLE_SCANF 0 +#endif +#endif +#ifndef SECUREC_ENABLE_VSCANF +#if SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_VSCANF 1 +#else +#define SECUREC_ENABLE_VSCANF 0 +#endif +#endif + +#ifndef SECUREC_ENABLE_FSCANF +#if SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_FSCANF 1 +#else +#define SECUREC_ENABLE_FSCANF 0 +#endif +#endif +#ifndef SECUREC_ENABLE_VFSCANF +#if SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_VFSCANF 1 +#else +#define SECUREC_ENABLE_VFSCANF 0 +#endif +#endif + +#ifndef SECUREC_ENABLE_STRTOK +#define SECUREC_ENABLE_STRTOK 1 +#endif +#ifndef SECUREC_ENABLE_GETS +#define SECUREC_ENABLE_GETS 1 +#endif +#endif /* SECUREC_USE_STD_SECURE_LIB */ + +#if !SECUREC_ENABLE_SCANF_FILE +#if SECUREC_ENABLE_FSCANF +#undef SECUREC_ENABLE_FSCANF +#define SECUREC_ENABLE_FSCANF 0 +#endif +#if SECUREC_ENABLE_VFSCANF +#undef SECUREC_ENABLE_VFSCANF +#define SECUREC_ENABLE_VFSCANF 0 +#endif +#if SECUREC_ENABLE_SCANF +#undef SECUREC_ENABLE_SCANF +#define SECUREC_ENABLE_SCANF 0 +#endif +#if SECUREC_ENABLE_FSCANF +#undef SECUREC_ENABLE_FSCANF +#define SECUREC_ENABLE_FSCANF 0 +#endif + +#endif + +#if SECUREC_IN_KERNEL +#include +#include +#else +#ifndef SECUREC_HAVE_STDIO_H +#define SECUREC_HAVE_STDIO_H 1 +#endif +#ifndef SECUREC_HAVE_STRING_H +#define SECUREC_HAVE_STRING_H 1 +#endif +#ifndef SECUREC_HAVE_STDLIB_H +#define SECUREC_HAVE_STDLIB_H 1 +#endif +#if SECUREC_HAVE_STDIO_H +#include +#endif +#if SECUREC_HAVE_STRING_H +#include +#endif +#if SECUREC_HAVE_STDLIB_H +#include +#endif +#endif + +/* + * If you need high performance, enable the SECUREC_WITH_PERFORMANCE_ADDONS macro, default is enable. + * The macro is automatically closed on the windows platform and linux kernel + */ +#ifndef SECUREC_WITH_PERFORMANCE_ADDONS +#if SECUREC_IN_KERNEL +#define SECUREC_WITH_PERFORMANCE_ADDONS 0 +#else +#define SECUREC_WITH_PERFORMANCE_ADDONS 1 +#endif +#endif + +/* If enable SECUREC_COMPATIBLE_WIN_FORMAT, the output format will be compatible to Windows. */ +#if (defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)) && !defined(SECUREC_COMPATIBLE_LINUX_FORMAT) +#ifndef SECUREC_COMPATIBLE_WIN_FORMAT +#define SECUREC_COMPATIBLE_WIN_FORMAT +#endif +#endif + +#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) +/* On windows platform, can't use optimized function for there is no __builtin_constant_p like function */ +/* If need optimized macro, can define this: define __builtin_constant_p(x) 0 */ +#ifdef SECUREC_WITH_PERFORMANCE_ADDONS +#undef SECUREC_WITH_PERFORMANCE_ADDONS +#define SECUREC_WITH_PERFORMANCE_ADDONS 0 +#endif +#endif + +#if defined(__VXWORKS__) || defined(__vxworks) || defined(__VXWORKS) || defined(_VXWORKS_PLATFORM_) || \ + defined(SECUREC_VXWORKS_VERSION_5_4) +#ifndef SECUREC_VXWORKS_PLATFORM +#define SECUREC_VXWORKS_PLATFORM +#endif +#endif + +/* If enable SECUREC_COMPATIBLE_LINUX_FORMAT, the output format will be compatible to Linux. */ +#if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) && !defined(SECUREC_VXWORKS_PLATFORM) +#ifndef SECUREC_COMPATIBLE_LINUX_FORMAT +#define SECUREC_COMPATIBLE_LINUX_FORMAT +#endif +#endif + +#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT +#ifndef SECUREC_HAVE_STDDEF_H +#define SECUREC_HAVE_STDDEF_H 1 +#endif +/* Some system may no stddef.h */ +#if SECUREC_HAVE_STDDEF_H +#if !SECUREC_IN_KERNEL +#include +#endif +#endif +#endif + +/* + * Add the -DSECUREC_SUPPORT_FORMAT_WARNING=1 compiler option to supoort -Wformat=2. + * Default does not check the format is that the same data type in the actual code. + * In the product is different in the original data type definition of VxWorks and Linux. + */ +#ifndef SECUREC_SUPPORT_FORMAT_WARNING +#define SECUREC_SUPPORT_FORMAT_WARNING 0 +#endif + +#if SECUREC_SUPPORT_FORMAT_WARNING +#define SECUREC_ATTRIBUTE(x, y) __attribute__((format(printf, (x), (y)))) +#else +#define SECUREC_ATTRIBUTE(x, y) +#endif + +/* + * Add the -DSECUREC_SUPPORT_BUILTIN_EXPECT=0 compiler option, if compiler can not support __builtin_expect. + */ +#ifndef SECUREC_SUPPORT_BUILTIN_EXPECT +#define SECUREC_SUPPORT_BUILTIN_EXPECT 1 +#endif + +#if SECUREC_SUPPORT_BUILTIN_EXPECT && defined(__GNUC__) && ((__GNUC__ > 3) || \ + (defined(__GNUC_MINOR__) && (__GNUC__ == 3 && __GNUC_MINOR__ > 3))) +/* + * This is a built-in function that can be used without a declaration, if warning for declaration not found occurred, + * you can add -DSECUREC_NEED_BUILTIN_EXPECT_DECLARE to compiler options + */ +#ifdef SECUREC_NEED_BUILTIN_EXPECT_DECLARE +long __builtin_expect(long exp, long c); +#endif + +#define SECUREC_LIKELY(x) __builtin_expect(!!(x), 1) +#define SECUREC_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define SECUREC_LIKELY(x) (x) +#define SECUREC_UNLIKELY(x) (x) +#endif + +/* Define the max length of the string */ +#ifndef SECUREC_STRING_MAX_LEN +#define SECUREC_STRING_MAX_LEN 0x7fffffffUL +#endif +#define SECUREC_WCHAR_STRING_MAX_LEN (SECUREC_STRING_MAX_LEN / sizeof(wchar_t)) + +/* Add SECUREC_MEM_MAX_LEN for memcpy and memmove */ +#ifndef SECUREC_MEM_MAX_LEN +#define SECUREC_MEM_MAX_LEN 0x7fffffffUL +#endif +#define SECUREC_WCHAR_MEM_MAX_LEN (SECUREC_MEM_MAX_LEN / sizeof(wchar_t)) + +#if SECUREC_STRING_MAX_LEN > 0x7fffffffUL +#error "max string is 2G" +#endif + +#if (defined(__GNUC__) && defined(__SIZEOF_POINTER__)) +#if (__SIZEOF_POINTER__ != 4) && (__SIZEOF_POINTER__ != 8) +#error "unsupported system" +#endif +#endif + +#if defined(_WIN64) || defined(WIN64) || defined(__LP64__) || defined(_LP64) +#define SECUREC_ON_64BITS +#endif + +#if (!defined(SECUREC_ON_64BITS) && defined(__GNUC__) && defined(__SIZEOF_POINTER__)) +#if __SIZEOF_POINTER__ == 8 +#define SECUREC_ON_64BITS +#endif +#endif + +#if defined(__SVR4) || defined(__svr4__) +#define SECUREC_ON_SOLARIS +#endif + +#if (defined(__hpux) || defined(_AIX) || defined(SECUREC_ON_SOLARIS)) +#define SECUREC_ON_UNIX +#endif + +/* + * Codes should run under the macro SECUREC_COMPATIBLE_LINUX_FORMAT in unknown system on default, + * and strtold. + * The function strtold is referenced first at ISO9899:1999(C99), and some old compilers can + * not support these functions. Here provides a macro to open these functions: + * SECUREC_SUPPORT_STRTOLD -- If defined, strtold will be used + */ +#ifndef SECUREC_SUPPORT_STRTOLD +#define SECUREC_SUPPORT_STRTOLD 0 +#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) +#if defined(__USE_ISOC99) || \ + (defined(_AIX) && defined(_ISOC99_SOURCE)) || \ + (defined(__hpux) && defined(__ia64)) || \ + (defined(SECUREC_ON_SOLARIS) && (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \ + defined(_STDC_C99) || defined(__EXTENSIONS__)) +#undef SECUREC_SUPPORT_STRTOLD +#define SECUREC_SUPPORT_STRTOLD 1 +#endif +#endif +#if ((defined(SECUREC_WRLINUX_BELOW4) || defined(_WRLINUX_BELOW4_))) +#undef SECUREC_SUPPORT_STRTOLD +#define SECUREC_SUPPORT_STRTOLD 0 +#endif +#endif + +#if SECUREC_WITH_PERFORMANCE_ADDONS + +#ifndef SECUREC_TWO_MIN +#define SECUREC_TWO_MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +/* For strncpy_s performance optimization */ +#define SECUREC_STRNCPY_SM(dest, destMax, src, count) \ + (((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ + (SECUREC_TWO_MIN((size_t)(count), strlen(src)) + 1) <= (size_t)(destMax)) ? \ + (((size_t)(count) < strlen(src)) ? (memcpy((dest), (src), (count)), *((char *)(dest) + (count)) = '\0', EOK) : \ + (memcpy((dest), (src), strlen(src) + 1), EOK)) : (strncpy_error((dest), (destMax), (src), (count)))) + +#define SECUREC_STRCPY_SM(dest, destMax, src) \ + (((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ + (strlen(src) + 1) <= (size_t)(destMax)) ? (memcpy((dest), (src), strlen(src) + 1), EOK) : \ + (strcpy_error((dest), (destMax), (src)))) + +/* For strcat_s performance optimization */ +#if defined(__GNUC__) +#define SECUREC_STRCAT_SM(dest, destMax, src) ({ \ + int catRet_ = EOK; \ + if ((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \ + char *catTmpDst_ = (char *)(dest); \ + size_t catRestSize_ = (destMax); \ + while (catRestSize_ > 0 && *catTmpDst_ != '\0') { \ + ++catTmpDst_; \ + --catRestSize_; \ + } \ + if (catRestSize_ == 0) { \ + catRet_ = EINVAL; \ + } else if ((strlen(src) + 1) <= catRestSize_) { \ + memcpy(catTmpDst_, (src), strlen(src) + 1); \ + catRet_ = EOK; \ + } else { \ + catRet_ = ERANGE; \ + } \ + if (catRet_ != EOK) { \ + catRet_ = strcat_s((dest), (destMax), (src)); \ + } \ + } else { \ + catRet_ = strcat_s((dest), (destMax), (src)); \ + } \ + catRet_; \ +}) +#else +#define SECUREC_STRCAT_SM(dest, destMax, src) strcat_s((dest), (destMax), (src)) +#endif + +/* For strncat_s performance optimization */ +#if defined(__GNUC__) +#define SECUREC_STRNCAT_SM(dest, destMax, src, count) ({ \ + int ncatRet_ = EOK; \ + if ((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ + (((unsigned long long)(count) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \ + char *ncatTmpDest_ = (char *)(dest); \ + size_t ncatRestSize_ = (size_t)(destMax); \ + while (ncatRestSize_ > 0 && *ncatTmpDest_ != '\0') { \ + ++ncatTmpDest_; \ + --ncatRestSize_; \ + } \ + if (ncatRestSize_ == 0) { \ + ncatRet_ = EINVAL; \ + } else if ((SECUREC_TWO_MIN((count), strlen(src)) + 1) <= ncatRestSize_) { \ + if ((size_t)(count) < strlen(src)) { \ + memcpy(ncatTmpDest_, (src), (count)); \ + *(ncatTmpDest_ + (count)) = '\0'; \ + } else { \ + memcpy(ncatTmpDest_, (src), strlen(src) + 1); \ + } \ + } else { \ + ncatRet_ = ERANGE; \ + } \ + if (ncatRet_ != EOK) { \ + ncatRet_ = strncat_s((dest), (destMax), (src), (count)); \ + } \ + } else { \ + ncatRet_ = strncat_s((dest), (destMax), (src), (count)); \ + } \ + ncatRet_; \ +}) +#else +#define SECUREC_STRNCAT_SM(dest, destMax, src, count) strncat_s((dest), (destMax), (src), (count)) +#endif + +/* This macro do not check buffer overlap by default */ +#define SECUREC_MEMCPY_SM(dest, destMax, src, count) \ + (!(((size_t)(destMax) == 0) || \ + (((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \ + ((size_t)(count) > (size_t)(destMax)) || ((void *)(dest)) == NULL || ((const void *)(src) == NULL)) ? \ + (memcpy((dest), (src), (count)), EOK) : \ + (memcpy_s((dest), (destMax), (src), (count)))) + +#define SECUREC_MEMSET_SM(dest, destMax, c, count) \ + (!((((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \ + ((void *)(dest) == NULL) || ((size_t)(count) > (size_t)(destMax))) ? \ + (memset((dest), (c), (count)), EOK) : \ + (memset_s((dest), (destMax), (c), (count)))) + +#endif +#endif + diff --git a/src/middleware/thirdparty/sysroot/include/hisilicon/securecutil.h b/src/middleware/thirdparty/sysroot/include/hisilicon/securecutil.h new file mode 100644 index 0000000000000000000000000000000000000000..7e3bd691f9ece9decd2fcb3c239697c806597246 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/hisilicon/securecutil.h @@ -0,0 +1,574 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: Define macro, data struct, and declare internal used function prototype, + * which is used by secure functions. + * Create: 2014-02-25 + */ + +#ifndef SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F +#define SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F +#include "securec.h" + +#if (defined(_MSC_VER)) && (_MSC_VER >= 1400) +/* Shield compilation alerts using discarded functions and Constant expression to maximize code compatibility */ +#define SECUREC_MASK_MSVC_CRT_WARNING __pragma(warning(push)) \ + __pragma(warning(disable : 4996 4127)) +#define SECUREC_END_MASK_MSVC_CRT_WARNING __pragma(warning(pop)) +#else +#define SECUREC_MASK_MSVC_CRT_WARNING +#define SECUREC_END_MASK_MSVC_CRT_WARNING +#endif +#define SECUREC_WHILE_ZERO SECUREC_MASK_MSVC_CRT_WARNING while (0) SECUREC_END_MASK_MSVC_CRT_WARNING + +/* Automatically identify the platform that supports strnlen function, and use this function to improve performance */ +#ifndef SECUREC_HAVE_STRNLEN +#if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L) +#if SECUREC_IN_KERNEL +#define SECUREC_HAVE_STRNLEN 0 +#else +#if defined(__GLIBC__) && __GLIBC__ >= 2 && defined(__GLIBC_MINOR__) && __GLIBC_MINOR__ >= 10 +#define SECUREC_HAVE_STRNLEN 1 +#else +#define SECUREC_HAVE_STRNLEN 0 +#endif +#endif +#else +#define SECUREC_HAVE_STRNLEN 0 +#endif +#endif + +#if SECUREC_IN_KERNEL +/* In kernel disable functions */ +#ifndef SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_SCANF_FILE 0 +#endif +#ifndef SECUREC_ENABLE_SCANF_FLOAT +#define SECUREC_ENABLE_SCANF_FLOAT 0 +#endif +#ifndef SECUREC_ENABLE_SPRINTF_FLOAT +#define SECUREC_ENABLE_SPRINTF_FLOAT 0 +#endif +#ifndef SECUREC_HAVE_MBTOWC +#define SECUREC_HAVE_MBTOWC 0 +#endif +#ifndef SECUREC_HAVE_WCTOMB +#define SECUREC_HAVE_WCTOMB 0 +#endif +#ifndef SECUREC_HAVE_WCHART +#define SECUREC_HAVE_WCHART 0 +#endif +#else /* Not in kernel */ +/* Systems that do not support file, can define this macro to 0. */ +#ifndef SECUREC_ENABLE_SCANF_FILE +#define SECUREC_ENABLE_SCANF_FILE 1 +#endif +#ifndef SECUREC_ENABLE_SCANF_FLOAT +#define SECUREC_ENABLE_SCANF_FLOAT 1 +#endif +/* Systems that do not support float, can define this macro to 0. */ +#ifndef SECUREC_ENABLE_SPRINTF_FLOAT +#define SECUREC_ENABLE_SPRINTF_FLOAT 1 +#endif +#ifndef SECUREC_HAVE_MBTOWC +#define SECUREC_HAVE_MBTOWC 1 +#endif +#ifndef SECUREC_HAVE_WCTOMB +#define SECUREC_HAVE_WCTOMB 1 +#endif +#ifndef SECUREC_HAVE_WCHART +#define SECUREC_HAVE_WCHART 1 +#endif +#endif + +#ifndef SECUREC_ENABLE_INLINE +#define SECUREC_ENABLE_INLINE 0 +#endif + +#ifndef SECUREC_INLINE +#if SECUREC_ENABLE_INLINE +#define SECUREC_INLINE static inline +#else +#define SECUREC_INLINE static +#endif +#endif + +#ifndef SECUREC_WARP_OUTPUT +#if SECUREC_IN_KERNEL +#define SECUREC_WARP_OUTPUT 1 +#else +#define SECUREC_WARP_OUTPUT 0 +#endif +#endif + +#ifndef SECUREC_STREAM_STDIN +#define SECUREC_STREAM_STDIN stdin +#endif + +#define SECUREC_MUL_SIXTEEN(x) ((x) << 4U) +#define SECUREC_MUL_EIGHT(x) ((x) << 3U) +#define SECUREC_MUL_TEN(x) ((((x) << 2U) + (x)) << 1U) +/* Limited format input and output width, use signed integer */ +#define SECUREC_MAX_WIDTH_LEN_DIV_TEN 21474836 +#define SECUREC_MAX_WIDTH_LEN (SECUREC_MAX_WIDTH_LEN_DIV_TEN * 10) +/* Is the x multiplied by 10 greater than */ +#define SECUREC_MUL_TEN_ADD_BEYOND_MAX(x) (((x) > SECUREC_MAX_WIDTH_LEN_DIV_TEN)) + +#define SECUREC_FLOAT_BUFSIZE (309 + 40) /* Max length of double value */ +#define SECUREC_FLOAT_BUFSIZE_LB (4932 + 40) /* Max length of long double value */ +#define SECUREC_FLOAT_DEFAULT_PRECISION 6 + +/* This macro does not handle pointer equality or integer overflow */ +#define SECUREC_MEMORY_NO_OVERLAP(dest, src, count) \ + (((src) < (dest) && ((const char *)(src) + (count)) <= (char *)(dest)) || \ + ((dest) < (src) && ((char *)(dest) + (count)) <= (const char *)(src))) + +#define SECUREC_MEMORY_IS_OVERLAP(dest, src, count) \ + (((src) < (dest) && ((const char *)(src) + (count)) > (char *)(dest)) || \ + ((dest) < (src) && ((char *)(dest) + (count)) > (const char *)(src))) + +/* + * Check whether the strings overlap, len is the length of the string not include terminator + * Length is related to data type char or wchar , do not force conversion of types + */ +#define SECUREC_STRING_NO_OVERLAP(dest, src, len) \ + (((src) < (dest) && ((src) + (len)) < (dest)) || \ + ((dest) < (src) && ((dest) + (len)) < (src))) + +/* + * Check whether the strings overlap for strcpy wcscpy function, dest len and src Len are not include terminator + * Length is related to data type char or wchar , do not force conversion of types + */ +#define SECUREC_STRING_IS_OVERLAP(dest, src, len) \ + (((src) < (dest) && ((src) + (len)) >= (dest)) || \ + ((dest) < (src) && ((dest) + (len)) >= (src))) + +/* + * Check whether the strings overlap for strcat wcscat function, dest len and src Len are not include terminator + * Length is related to data type char or wchar , do not force conversion of types + */ +#define SECUREC_CAT_STRING_IS_OVERLAP(dest, destLen, src, srcLen) \ + (((dest) < (src) && ((dest) + (destLen) + (srcLen)) >= (src)) || \ + ((src) < (dest) && ((src) + (srcLen)) >= (dest))) + +#if SECUREC_HAVE_STRNLEN +#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) do { \ + *(outLen) = strnlen((str), (maxLen)); \ +} SECUREC_WHILE_ZERO +#define SECUREC_CALC_STR_LEN_OPT(str, maxLen, outLen) do { \ + if ((maxLen) > 8) { \ + /* Optimization or len less then 8 */ \ + if (*((str) + 0) == '\0') { \ + *(outLen) = 0; \ + } else if (*((str) + 1) == '\0') { \ + *(outLen) = 1; \ + } else if (*((str) + 2) == '\0') { \ + *(outLen) = 2; \ + } else if (*((str) + 3) == '\0') { \ + *(outLen) = 3; \ + } else if (*((str) + 4) == '\0') { \ + *(outLen) = 4; \ + } else if (*((str) + 5) == '\0') { \ + *(outLen) = 5; \ + } else if (*((str) + 6) == '\0') { \ + *(outLen) = 6; \ + } else if (*((str) + 7) == '\0') { \ + *(outLen) = 7; \ + } else if (*((str) + 8) == '\0') { \ + /* Optimization with a length of 8 */ \ + *(outLen) = 8; \ + } else { \ + /* The offset is 8 because the performance of 8 byte alignment is high */ \ + *(outLen) = 8 + strnlen((str) + 8, (maxLen) - 8); \ + } \ + } else { \ + SECUREC_CALC_STR_LEN((str), (maxLen), (outLen)); \ + } \ +} SECUREC_WHILE_ZERO +#else +#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) do { \ + const char *strEnd_ = (const char *)(str); \ + size_t availableSize_ = (size_t)(maxLen); \ + while (availableSize_ > 0 && *strEnd_ != '\0') { \ + --availableSize_; \ + ++strEnd_; \ + } \ + *(outLen) = (size_t)(strEnd_ - (str)); \ +} SECUREC_WHILE_ZERO +#define SECUREC_CALC_STR_LEN_OPT SECUREC_CALC_STR_LEN +#endif + +#define SECUREC_CALC_WSTR_LEN(str, maxLen, outLen) do { \ + const wchar_t *strEnd_ = (const wchar_t *)(str); \ + size_t len_ = 0; \ + while (len_ < (maxLen) && *strEnd_ != L'\0') { \ + ++len_; \ + ++strEnd_; \ + } \ + *(outLen) = len_; \ +} SECUREC_WHILE_ZERO + +/* + * Performance optimization, product may disable inline function. + * Using function pointer for MEMSET to prevent compiler optimization when cleaning up memory. + */ +#ifdef SECUREC_USE_ASM +#define SECUREC_MEMSET_FUNC_OPT memset_opt +#define SECUREC_MEMCPY_FUNC_OPT memcpy_opt +#else +#define SECUREC_MEMSET_FUNC_OPT memset +#define SECUREC_MEMCPY_FUNC_OPT memcpy +#endif + +#define SECUREC_MEMCPY_WARP_OPT(dest, src, count) (void)SECUREC_MEMCPY_FUNC_OPT((dest), (src), (count)) + +#ifndef SECUREC_MEMSET_BARRIER +#if defined(__GNUC__) +/* Can be turned off for scenarios that do not use memory barrier */ +#define SECUREC_MEMSET_BARRIER 1 +#else +#define SECUREC_MEMSET_BARRIER 0 +#endif +#endif + +#ifndef SECUREC_MEMSET_INDIRECT_USE +/* Can be turned off for scenarios that do not allow pointer calls */ +#define SECUREC_MEMSET_INDIRECT_USE 1 +#endif + +#if SECUREC_MEMSET_BARRIER +#define SECUREC_MEMORY_BARRIER(dest) __asm__ __volatile__("": : "r"(dest) : "memory") +#else +#define SECUREC_MEMORY_BARRIER(dest) +#endif + +#if SECUREC_MEMSET_BARRIER +#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count) do { \ + (void)SECUREC_MEMSET_FUNC_OPT(dest, value, count); \ + SECUREC_MEMORY_BARRIER(dest); \ +} SECUREC_WHILE_ZERO +#elif SECUREC_MEMSET_INDIRECT_USE +#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count) do { \ + void *(* const volatile fn_)(void *s_, int c_, size_t n_) = SECUREC_MEMSET_FUNC_OPT; \ + (void)(*fn_)((dest), (value), (count)); \ +} SECUREC_WHILE_ZERO +#else +#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count) (void)SECUREC_MEMSET_FUNC_OPT((dest), (value), (count)) +#endif + +#ifdef SECUREC_FORMAT_OUTPUT_INPUT +#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) || defined(__ARMCC_VERSION) +typedef __int64 SecInt64; +typedef unsigned __int64 SecUnsignedInt64; +#if defined(__ARMCC_VERSION) +typedef unsigned int SecUnsignedInt32; +#else +typedef unsigned __int32 SecUnsignedInt32; +#endif +#else +typedef unsigned int SecUnsignedInt32; +typedef long long SecInt64; +typedef unsigned long long SecUnsignedInt64; +#endif + +#ifdef SECUREC_FOR_WCHAR +#if defined(SECUREC_VXWORKS_PLATFORM) && !defined(__WINT_TYPE__) +typedef wchar_t wint_t; +#endif +#ifndef WEOF +#define WEOF ((wchar_t)(-1)) +#endif +#define SECUREC_CHAR(x) L ## x +typedef wchar_t SecChar; +typedef wchar_t SecUnsignedChar; +typedef wint_t SecInt; +typedef wint_t SecUnsignedInt; +#else /* no SECUREC_FOR_WCHAR */ +#define SECUREC_CHAR(x) (x) +typedef char SecChar; +typedef unsigned char SecUnsignedChar; +typedef int SecInt; +typedef unsigned int SecUnsignedInt; +#endif +#endif + +/* + * Determine whether the address is 8-byte aligned + * Some systems do not have uintptr_t type, so use NULL to clear tool alarm 507 + */ +#define SECUREC_ADDR_ALIGNED_8(addr) ((((size_t)(addr)) & 7U) == 0) /* Use 7 to check aligned 8 */ + +/* + * If you define the memory allocation function, you need to define the function prototype. + * You can define this macro as a header file. + */ +#if defined(SECUREC_MALLOC_PROTOTYPE) +SECUREC_MALLOC_PROTOTYPE +#endif + +#ifndef SECUREC_MALLOC +#define SECUREC_MALLOC(x) malloc((size_t)(x)) +#endif + +#ifndef SECUREC_FREE +#define SECUREC_FREE(x) free((void *)(x)) +#endif + +/* Improve performance with struct assignment, buf1 is not defined to avoid tool false positive */ +#define SECUREC_COPY_VALUE_BY_STRUCT(dest, src, n) do { \ + *(SecStrBuf##n *)(void *)(dest) = *(const SecStrBuf##n *)(const void *)(src); \ +} SECUREC_WHILE_ZERO + +typedef struct { + unsigned char buf[2]; /* Performance optimization code structure assignment length 2 bytes */ +} SecStrBuf2; +typedef struct { + unsigned char buf[3]; /* Performance optimization code structure assignment length 3 bytes */ +} SecStrBuf3; +typedef struct { + unsigned char buf[4]; /* Performance optimization code structure assignment length 4 bytes */ +} SecStrBuf4; +typedef struct { + unsigned char buf[5]; /* Performance optimization code structure assignment length 5 bytes */ +} SecStrBuf5; +typedef struct { + unsigned char buf[6]; /* Performance optimization code structure assignment length 6 bytes */ +} SecStrBuf6; +typedef struct { + unsigned char buf[7]; /* Performance optimization code structure assignment length 7 bytes */ +} SecStrBuf7; +typedef struct { + unsigned char buf[8]; /* Performance optimization code structure assignment length 8 bytes */ +} SecStrBuf8; +typedef struct { + unsigned char buf[9]; /* Performance optimization code structure assignment length 9 bytes */ +} SecStrBuf9; +typedef struct { + unsigned char buf[10]; /* Performance optimization code structure assignment length 10 bytes */ +} SecStrBuf10; +typedef struct { + unsigned char buf[11]; /* Performance optimization code structure assignment length 11 bytes */ +} SecStrBuf11; +typedef struct { + unsigned char buf[12]; /* Performance optimization code structure assignment length 12 bytes */ +} SecStrBuf12; +typedef struct { + unsigned char buf[13]; /* Performance optimization code structure assignment length 13 bytes */ +} SecStrBuf13; +typedef struct { + unsigned char buf[14]; /* Performance optimization code structure assignment length 14 bytes */ +} SecStrBuf14; +typedef struct { + unsigned char buf[15]; /* Performance optimization code structure assignment length 15 bytes */ +} SecStrBuf15; +typedef struct { + unsigned char buf[16]; /* Performance optimization code structure assignment length 16 bytes */ +} SecStrBuf16; +typedef struct { + unsigned char buf[17]; /* Performance optimization code structure assignment length 17 bytes */ +} SecStrBuf17; +typedef struct { + unsigned char buf[18]; /* Performance optimization code structure assignment length 18 bytes */ +} SecStrBuf18; +typedef struct { + unsigned char buf[19]; /* Performance optimization code structure assignment length 19 bytes */ +} SecStrBuf19; +typedef struct { + unsigned char buf[20]; /* Performance optimization code structure assignment length 20 bytes */ +} SecStrBuf20; +typedef struct { + unsigned char buf[21]; /* Performance optimization code structure assignment length 21 bytes */ +} SecStrBuf21; +typedef struct { + unsigned char buf[22]; /* Performance optimization code structure assignment length 22 bytes */ +} SecStrBuf22; +typedef struct { + unsigned char buf[23]; /* Performance optimization code structure assignment length 23 bytes */ +} SecStrBuf23; +typedef struct { + unsigned char buf[24]; /* Performance optimization code structure assignment length 24 bytes */ +} SecStrBuf24; +typedef struct { + unsigned char buf[25]; /* Performance optimization code structure assignment length 25 bytes */ +} SecStrBuf25; +typedef struct { + unsigned char buf[26]; /* Performance optimization code structure assignment length 26 bytes */ +} SecStrBuf26; +typedef struct { + unsigned char buf[27]; /* Performance optimization code structure assignment length 27 bytes */ +} SecStrBuf27; +typedef struct { + unsigned char buf[28]; /* Performance optimization code structure assignment length 28 bytes */ +} SecStrBuf28; +typedef struct { + unsigned char buf[29]; /* Performance optimization code structure assignment length 29 bytes */ +} SecStrBuf29; +typedef struct { + unsigned char buf[30]; /* Performance optimization code structure assignment length 30 bytes */ +} SecStrBuf30; +typedef struct { + unsigned char buf[31]; /* Performance optimization code structure assignment length 31 bytes */ +} SecStrBuf31; +typedef struct { + unsigned char buf[32]; /* Performance optimization code structure assignment length 32 bytes */ +} SecStrBuf32; +typedef struct { + unsigned char buf[33]; /* Performance optimization code structure assignment length 33 bytes */ +} SecStrBuf33; +typedef struct { + unsigned char buf[34]; /* Performance optimization code structure assignment length 34 bytes */ +} SecStrBuf34; +typedef struct { + unsigned char buf[35]; /* Performance optimization code structure assignment length 35 bytes */ +} SecStrBuf35; +typedef struct { + unsigned char buf[36]; /* Performance optimization code structure assignment length 36 bytes */ +} SecStrBuf36; +typedef struct { + unsigned char buf[37]; /* Performance optimization code structure assignment length 37 bytes */ +} SecStrBuf37; +typedef struct { + unsigned char buf[38]; /* Performance optimization code structure assignment length 38 bytes */ +} SecStrBuf38; +typedef struct { + unsigned char buf[39]; /* Performance optimization code structure assignment length 39 bytes */ +} SecStrBuf39; +typedef struct { + unsigned char buf[40]; /* Performance optimization code structure assignment length 40 bytes */ +} SecStrBuf40; +typedef struct { + unsigned char buf[41]; /* Performance optimization code structure assignment length 41 bytes */ +} SecStrBuf41; +typedef struct { + unsigned char buf[42]; /* Performance optimization code structure assignment length 42 bytes */ +} SecStrBuf42; +typedef struct { + unsigned char buf[43]; /* Performance optimization code structure assignment length 43 bytes */ +} SecStrBuf43; +typedef struct { + unsigned char buf[44]; /* Performance optimization code structure assignment length 44 bytes */ +} SecStrBuf44; +typedef struct { + unsigned char buf[45]; /* Performance optimization code structure assignment length 45 bytes */ +} SecStrBuf45; +typedef struct { + unsigned char buf[46]; /* Performance optimization code structure assignment length 46 bytes */ +} SecStrBuf46; +typedef struct { + unsigned char buf[47]; /* Performance optimization code structure assignment length 47 bytes */ +} SecStrBuf47; +typedef struct { + unsigned char buf[48]; /* Performance optimization code structure assignment length 48 bytes */ +} SecStrBuf48; +typedef struct { + unsigned char buf[49]; /* Performance optimization code structure assignment length 49 bytes */ +} SecStrBuf49; +typedef struct { + unsigned char buf[50]; /* Performance optimization code structure assignment length 50 bytes */ +} SecStrBuf50; +typedef struct { + unsigned char buf[51]; /* Performance optimization code structure assignment length 51 bytes */ +} SecStrBuf51; +typedef struct { + unsigned char buf[52]; /* Performance optimization code structure assignment length 52 bytes */ +} SecStrBuf52; +typedef struct { + unsigned char buf[53]; /* Performance optimization code structure assignment length 53 bytes */ +} SecStrBuf53; +typedef struct { + unsigned char buf[54]; /* Performance optimization code structure assignment length 54 bytes */ +} SecStrBuf54; +typedef struct { + unsigned char buf[55]; /* Performance optimization code structure assignment length 55 bytes */ +} SecStrBuf55; +typedef struct { + unsigned char buf[56]; /* Performance optimization code structure assignment length 56 bytes */ +} SecStrBuf56; +typedef struct { + unsigned char buf[57]; /* Performance optimization code structure assignment length 57 bytes */ +} SecStrBuf57; +typedef struct { + unsigned char buf[58]; /* Performance optimization code structure assignment length 58 bytes */ +} SecStrBuf58; +typedef struct { + unsigned char buf[59]; /* Performance optimization code structure assignment length 59 bytes */ +} SecStrBuf59; +typedef struct { + unsigned char buf[60]; /* Performance optimization code structure assignment length 60 bytes */ +} SecStrBuf60; +typedef struct { + unsigned char buf[61]; /* Performance optimization code structure assignment length 61 bytes */ +} SecStrBuf61; +typedef struct { + unsigned char buf[62]; /* Performance optimization code structure assignment length 62 bytes */ +} SecStrBuf62; +typedef struct { + unsigned char buf[63]; /* Performance optimization code structure assignment length 63 bytes */ +} SecStrBuf63; +typedef struct { + unsigned char buf[64]; /* Performance optimization code structure assignment length 64 bytes */ +} SecStrBuf64; + +/* + * User can change the error handler by modify the following definition, + * such as logging the detail error in file. + */ +#if defined(_DEBUG) || defined(DEBUG) +#if defined(SECUREC_ERROR_HANDLER_BY_ASSERT) +#define SECUREC_ERROR_INVALID_PARAMTER(msg) assert(msg "invalid argument" == NULL) +#define SECUREC_ERROR_INVALID_RANGE(msg) assert(msg "invalid dest buffer size" == NULL) +#define SECUREC_ERROR_BUFFER_OVERLAP(msg) assert(msg "buffer overlap" == NULL) +#elif defined(SECUREC_ERROR_HANDLER_BY_PRINTF) +#if SECUREC_IN_KERNEL +#define SECUREC_ERROR_INVALID_PARAMTER(msg) printk("%s invalid argument\n", msg) +#define SECUREC_ERROR_INVALID_RANGE(msg) printk("%s invalid dest buffer size\n", msg) +#define SECUREC_ERROR_BUFFER_OVERLAP(msg) printk("%s buffer overlap\n", msg) +#else +#define SECUREC_ERROR_INVALID_PARAMTER(msg) printf("%s invalid argument\n", msg) +#define SECUREC_ERROR_INVALID_RANGE(msg) printf("%s invalid dest buffer size\n", msg) +#define SECUREC_ERROR_BUFFER_OVERLAP(msg) printf("%s buffer overlap\n", msg) +#endif +#elif defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG) +#define SECUREC_ERROR_INVALID_PARAMTER(msg) LogSecureCRuntimeError(msg " EINVAL\n") +#define SECUREC_ERROR_INVALID_RANGE(msg) LogSecureCRuntimeError(msg " ERANGE\n") +#define SECUREC_ERROR_BUFFER_OVERLAP(msg) LogSecureCRuntimeError(msg " EOVERLAP\n") +#endif +#endif + +/* Default handler is none */ +#ifndef SECUREC_ERROR_INVALID_PARAMTER +#define SECUREC_ERROR_INVALID_PARAMTER(msg) +#endif +#ifndef SECUREC_ERROR_INVALID_RANGE +#define SECUREC_ERROR_INVALID_RANGE(msg) +#endif +#ifndef SECUREC_ERROR_BUFFER_OVERLAP +#define SECUREC_ERROR_BUFFER_OVERLAP(msg) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Assembly language memory copy and memory set for X86 or MIPS ... */ +#ifdef SECUREC_USE_ASM +void *memcpy_opt(void *dest, const void *src, size_t n); +void *memset_opt(void *s, int c, size_t n); +#endif + +#if defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG) +void LogSecureCRuntimeError(const char *errDetail); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif + diff --git a/src/middleware/thirdparty/sysroot/include/hisilicon/secureprintoutput.h b/src/middleware/thirdparty/sysroot/include/hisilicon/secureprintoutput.h new file mode 100644 index 0000000000000000000000000000000000000000..dc483f58c10905cb94205b1a9bd6a3dccfb3b279 --- /dev/null +++ b/src/middleware/thirdparty/sysroot/include/hisilicon/secureprintoutput.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. + * Licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: Define macro, enum, data struct, and declare internal used function + * prototype, which is used by output.inl, secureprintoutput_w.c and + * secureprintoutput_a.c. + * Create: 2014-02-25 + */ + +#ifndef SECUREPRINTOUTPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C +#define SECUREPRINTOUTPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C +#include "securecutil.h" + +/* Shield compilation alerts about using sprintf without format attribute to format float value. */ +#ifndef SECUREC_HANDLE_WFORMAT +#define SECUREC_HANDLE_WFORMAT 1 +#endif + +#if defined(__clang__) +#if SECUREC_HANDLE_WFORMAT && defined(__GNUC__) && ((__GNUC__ >= 5) || \ + (defined(__GNUC_MINOR__) && (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))) +#define SECUREC_MASK_WFORMAT_WARNING _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") +#define SECUREC_END_MASK_WFORMAT_WARNING _Pragma("GCC diagnostic pop") +#else +#define SECUREC_MASK_WFORMAT_WARNING +#define SECUREC_END_MASK_WFORMAT_WARNING +#endif +#else +#if SECUREC_HANDLE_WFORMAT && defined(__GNUC__) && ((__GNUC__ >= 5 ) || \ + (defined(__GNUC_MINOR__) && (__GNUC__ == 4 && __GNUC_MINOR__ > 7))) +#define SECUREC_MASK_WFORMAT_WARNING _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") \ + _Pragma("GCC diagnostic ignored \"-Wmissing-format-attribute\"") \ + _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=format\"") +#define SECUREC_END_MASK_WFORMAT_WARNING _Pragma("GCC diagnostic pop") +#else +#define SECUREC_MASK_WFORMAT_WARNING +#define SECUREC_END_MASK_WFORMAT_WARNING +#endif +#endif + +#define SECUREC_MASK_VSPRINTF_WARNING SECUREC_MASK_WFORMAT_WARNING \ + SECUREC_MASK_MSVC_CRT_WARNING + +#define SECUREC_END_MASK_VSPRINTF_WARNING SECUREC_END_MASK_WFORMAT_WARNING \ + SECUREC_END_MASK_MSVC_CRT_WARNING + +/* + * Flag definitions. + * Using macros instead of enumerations is because some of the enumerated types under the compiler are 16bit. + */ +#define SECUREC_FLAG_SIGN 0x00001U +#define SECUREC_FLAG_SIGN_SPACE 0x00002U +#define SECUREC_FLAG_LEFT 0x00004U +#define SECUREC_FLAG_LEADZERO 0x00008U +#define SECUREC_FLAG_LONG 0x00010U +#define SECUREC_FLAG_SHORT 0x00020U +#define SECUREC_FLAG_SIGNED 0x00040U +#define SECUREC_FLAG_ALTERNATE 0x00080U +#define SECUREC_FLAG_NEGATIVE 0x00100U +#define SECUREC_FLAG_FORCE_OCTAL 0x00200U +#define SECUREC_FLAG_LONG_DOUBLE 0x00400U +#define SECUREC_FLAG_WIDECHAR 0x00800U +#define SECUREC_FLAG_LONGLONG 0x01000U +#define SECUREC_FLAG_CHAR 0x02000U +#define SECUREC_FLAG_POINTER 0x04000U +#define SECUREC_FLAG_I64 0x08000U +#define SECUREC_FLAG_PTRDIFF 0x10000U +#define SECUREC_FLAG_SIZE 0x20000U +#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT +#define SECUREC_FLAG_INTMAX 0x40000U +#endif + +/* State definitions. Identify the status of the current format */ +typedef enum { + STAT_NORMAL, + STAT_PERCENT, + STAT_FLAG, + STAT_WIDTH, + STAT_DOT, + STAT_PRECIS, + STAT_SIZE, + STAT_TYPE, + STAT_INVALID +} SecFmtState; + +#ifndef SECUREC_BUFFER_SIZE +#if SECUREC_IN_KERNEL +#define SECUREC_BUFFER_SIZE 32 +#elif defined(SECUREC_STACK_SIZE_LESS_THAN_1K) +/* + * SECUREC BUFFER SIZE Can not be less than 23 + * The length of the octal representation of 64-bit integers with zero lead + */ +#define SECUREC_BUFFER_SIZE 256 +#else +#define SECUREC_BUFFER_SIZE 512 +#endif +#endif +#if SECUREC_BUFFER_SIZE < 23 +#error SECUREC_BUFFER_SIZE Can not be less than 23 +#endif +/* Buffer size for wchar, use 4 to make the compiler aligns as 8 bytes as possible */ +#define SECUREC_WCHAR_BUFFER_SIZE 4 + +#define SECUREC_MAX_PRECISION SECUREC_BUFFER_SIZE +/* Max. # bytes in multibyte char,see MB_LEN_MAX */ +#define SECUREC_MB_LEN 16 +/* The return value of the internal function, which is returned when truncated */ +#define SECUREC_PRINTF_TRUNCATE (-2) + +#define SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, maxLimit) \ + ((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) + +#define SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, maxLimit) do { \ + if ((strDest) != NULL && (destMax) > 0 && (destMax) <= (maxLimit)) { \ + *(strDest) = '\0'; \ + } \ +} SECUREC_WHILE_ZERO + +#ifdef SECUREC_COMPATIBLE_WIN_FORMAT +#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, maxLimit) \ + (((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) || \ + ((count) > (SECUREC_STRING_MAX_LEN - 1) && (count) != (size_t)(-1))) + +#else +#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, maxLimit) \ + (((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) || \ + ((count) > (SECUREC_STRING_MAX_LEN - 1))) +#endif + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef SECUREC_FOR_WCHAR +int SecVswprintfImpl(wchar_t *string, size_t count, const wchar_t *format, va_list argList); +#else +int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList); +#endif +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/middleware/thirdparty/sysroot/include/mcs_smo_4th.h b/src/middleware/thirdparty/sysroot/include/mcs_smo_4th.h index 5fb9a507342867de955d0520bcf20139f572603d..2acca4bef3ec606cdbfe8a94dec5a79416e09a51 100644 --- a/src/middleware/thirdparty/sysroot/include/mcs_smo_4th.h +++ b/src/middleware/thirdparty/sysroot/include/mcs_smo_4th.h @@ -30,9 +30,6 @@ typedef struct { /* Model parameters */ - float ld; - float lq; - float rs; float ts; float kd; float kq; @@ -40,6 +37,7 @@ typedef struct { float fcLpf; /**< The cut-off frequency of First-order LPF for speed (Hz). */ float elecAngle; float spdEst; + MOTOR_Param *mtrParam; /* Internal variable */ AlbeAxis ialbeEst; AlbeAxis ealbeEst; @@ -58,7 +56,7 @@ typedef struct { } SMO4TH_Param; -void SMO4TH_Init(SMO4TH_Handle *smo4th, const SMO4TH_Param smo4thParam, const MOTOR_Param mtrParam, float ts); +void SMO4TH_Init(SMO4TH_Handle *smo4th, SMO4TH_Param smo4thParam, MOTOR_Param *mtrParam, float ts); void SMO4TH_Exec(SMO4TH_Handle *smo4th, const AlbeAxis *ialbeFbk, const AlbeAxis *valbeRef); diff --git a/src/middleware/thirdparty/sysroot/lib/libbounds_check.a b/src/middleware/thirdparty/sysroot/lib/libbounds_check.a new file mode 100644 index 0000000000000000000000000000000000000000..89c20bbdf52381eeae5a6efce77166f34cce7b0f Binary files /dev/null and b/src/middleware/thirdparty/sysroot/lib/libbounds_check.a differ diff --git a/src/middleware/thirdparty/sysroot/lib/libcontrol_library_3061m.a b/src/middleware/thirdparty/sysroot/lib/libcontrol_library_3061m.a new file mode 100644 index 0000000000000000000000000000000000000000..801875293ebe4e8f04b619724c9149f3dd72f40e Binary files /dev/null and b/src/middleware/thirdparty/sysroot/lib/libcontrol_library_3061m.a differ diff --git a/src/middleware/thirdparty/sysroot/lib/libcontrol_library_3066m.a b/src/middleware/thirdparty/sysroot/lib/libcontrol_library_3066m.a new file mode 100644 index 0000000000000000000000000000000000000000..801875293ebe4e8f04b619724c9149f3dd72f40e Binary files /dev/null and b/src/middleware/thirdparty/sysroot/lib/libcontrol_library_3066m.a differ diff --git a/src/middleware/thirdparty/sysroot/lib/libcontrol_library_306xh.a b/src/middleware/thirdparty/sysroot/lib/libcontrol_library_306xh.a new file mode 100644 index 0000000000000000000000000000000000000000..02a105a48ba1d0f4ca128a3d5e07155275ae1336 Binary files /dev/null and b/src/middleware/thirdparty/sysroot/lib/libcontrol_library_306xh.a differ diff --git a/src/middleware/thirdparty/sysroot/lib/libfunction_safety_3061m.a b/src/middleware/thirdparty/sysroot/lib/libfunction_safety_3061m.a new file mode 100644 index 0000000000000000000000000000000000000000..122b34cb99050913e3fb7d69a0f0a75d64c17d99 Binary files /dev/null and b/src/middleware/thirdparty/sysroot/lib/libfunction_safety_3061m.a differ diff --git a/src/middleware/thirdparty/sysroot/lib/libfunction_safety_3066m.a b/src/middleware/thirdparty/sysroot/lib/libfunction_safety_3066m.a new file mode 100644 index 0000000000000000000000000000000000000000..31567fdbaf4df7ff26aeee8c03376f720c1c9b14 Binary files /dev/null and b/src/middleware/thirdparty/sysroot/lib/libfunction_safety_3066m.a differ diff --git a/src/middleware/thirdparty/sysroot/lib/libfunction_safety_306xh.a b/src/middleware/thirdparty/sysroot/lib/libfunction_safety_306xh.a new file mode 100644 index 0000000000000000000000000000000000000000..672c7be4f6b362e6d5cb0d50523f480070e67bd9 Binary files /dev/null and b/src/middleware/thirdparty/sysroot/lib/libfunction_safety_306xh.a differ diff --git a/src/middleware/thirdparty/sysroot/lib/libmcs_smo_4th.a b/src/middleware/thirdparty/sysroot/lib/libmcs_smo_4th.a index 2852d63db2444ccc666bce64872c3e6db1d23d31..7895879a915aa82cfbf115ebf6abfa4e7056dcc7 100644 Binary files a/src/middleware/thirdparty/sysroot/lib/libmcs_smo_4th.a and b/src/middleware/thirdparty/sysroot/lib/libmcs_smo_4th.a differ diff --git a/src/middleware/thirdparty/sysroot/lib/libnostask.a b/src/middleware/thirdparty/sysroot/lib/libnostask.a index 2dd6fe666747eb1f9fcf764a7fa5b2c5130cdde3..72d2ec002e680ebc859591164c946ac45d861fa2 100644 Binary files a/src/middleware/thirdparty/sysroot/lib/libnostask.a and b/src/middleware/thirdparty/sysroot/lib/libnostask.a differ diff --git a/src/tools/hispark_trace/README.md b/src/tools/hispark_trace/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f0e77fc7a01bb827b67f908560daefe39abe8b93 --- /dev/null +++ b/src/tools/hispark_trace/README.md @@ -0,0 +1,53 @@ +# 编译构建依赖 + +## 工具依赖 + ++ 编译构建需要依赖make工具和python工具,请确保机器上已安装。 ++ 依赖“gcc-arm-none-eabi-10.3-2021.07”交叉编译工具链 + +## 第三方库依赖 + ++ DAPLink开源包“DAPLink-0257.tar.gz”DAPLink ++ STM32MP153驱动包“STM32CubeMP1-1.4.0.tar.gz” ++ 安全函数库“libboundscheck_v1.1.16” + +# 编译工具链安装与配置 + +## Windows + ++ 解压下载好的编译工具链压缩包"gcc-arm-none-eabi-10.3-2021.07-win32.zip"。 ++ 新建环境变量“TOOLCHAIN_DIR”值配置为工具链的根目录。注意目录分隔符。例如:“D:/tools/gcc-arm-none-eabi-10.3-2021.07-win32”。 ++ 把工具链bin文件夹路径加入Path环境变量,值为%TOOLCHAIN_DIR%\bin。 + +## Linux X86_64 + ++ 解压下载好的编译工具链压缩包“gcc-arm-none-eabi-10.3-2021.07-x86_64-linux.tar.bz2”。 ++ 新增环境变量“TOOLCHAIN_DIR”工具链目录,值配置为工具链根目录,例如:export TOOLCHAIN_DIR=~/tools/gcc-arm-none-eabi-10.3-2021.07。 ++ 把工具链bin文件夹路径加入PATH环境变量;export PATH=$TOOLCHAIN_DIR/bin:$PATH。 + +# 版本编译 + ++ 把DAPLink开源包和STM32MP153驱动包的压缩包拷贝到open_source目录下 ++ HiSpark-Trace源码的根目录下执行编译构建脚本“build.sh”,例如:./build.sh all + +**【注意事项】** ++ linux环境下可以直接执行build.sh脚本。windows环境下需要依赖shell执行工具命令窗口执行build.sh脚本。 ++ HiSpark-Trace编译构建依赖SDK“SDK\middleware\hisilicon\libboundscheck_v1.1.16”目录下的安全函数库,请确保该目录下安全函数源码存在。如果需要修改安全函数库存放路径,请修改build.sh脚本中“SECURE_CODE_SRC”变量指向新路径。 + +**【编译脚本的传参和对应的动作】** +> build.sh : same of build.sh ca7 +> build.sh prepare : create the directory of build and tar +> build.sh clean : remove the output and intermediate files +> build.sh boot : build boot +> build.sh boot clean : remove output and intermediate file of boot +> build.sh ca7 : build daplink code in Cortex-A +> build.sh ca7 clean : remove output and intermediate file of Cortex-A +> build.sh cm4 : build daplink code in Cortex-M +> build.sh boot clean : remove output and intermediate file of Cortex-M +> build.sh mkimages : create images +> build.sh all : build and create images +> build.sh rebuild : clean all and rebuild and create images +> build.sh build : build and create imagesbuild.sh -h|--help : print help message + +**【须知】** ++ 更详细的HiSpark-Trace编译构建教程,请参阅《HiSpark-Trace硬件本体软件编译构建指导》。 \ No newline at end of file diff --git a/src/tools/hispark_trace/build.sh b/src/tools/hispark_trace/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..bb7cbfe19b7e3e19cb86252a2041703068f04656 --- /dev/null +++ b/src/tools/hispark_trace/build.sh @@ -0,0 +1,453 @@ +#!/bin/bash +# Compiling and Building HiSpark-Trace Codes. +# Copyright (c) 2024, HiSilicon Technologies Co., Ltd. All rights reserved. + +function global_env_init() +{ + GCC_TOOLCHAIN_PATH="" #please input your toolchain path + #set gcc toolchain path + #export PATH=/$GCC_TOOLCHAIN_PATH/gcc-arm-10.3-2021.07-x86_64-arm-none-eabi/bin:$PATH + #set gcc lib path + #export TOOLCHAIN_DIR=/$GCC_TOOLCHAIN_PATH/gcc-arm-10.3-2021.07-x86_64-arm-none-eabi +} + +function glogal_variable_init() +{ + CUR_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)" + if [[ -z "$CUR_DIR" ]];then + CUR_DIR='.' + fi + BUILD="build" + BUILD_BOOT="build/boot" + BUILD_CA7="build/CA7" + BUILD_CM4="build/CM4" + BUILD_CA7_SOURCE="build/CA7/source" + SECURE_CODE_SRC="../../middleware/hisilicon/libboundscheck_v1.1.16" + DAPLINK_SRC="open_source/DAPLink-0257.tar.gz" + SDK_SRC="open_source/STM32CubeMP1-1.4.0.tar.gz" + HISPARK="hispark" + BOOT="boot" + TMP_DIR=".tmp" + IMAGES_DIR="images" + STM32MP1XX=$BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx + STM32MP1XX_HAL=$STM32MP1XX/STM32MP1xx_HAL_Driver +} + +function create_stm32mp1xx_dir() +{ + SRC=$1 + DST=$2 + cp $SRC/*.c $DST + cp $SRC/*.h $DST + rm $DST/usbd_STM32F103.c + mkdir -p $DST/gcc + mkdir -p $DST/cmsis + chmod -R 777 $DST +} + +function recursive_copy() +{ + dirlist=$(ls $1) + for name in ${dirlist[*]} + do + if [ -f "$1"/"$name" ]; then + if [ ! -f "$2"/"$name" ]; then + cp $1/$name $2/$name + fi + elif [ -d "$1"/"$name" ]; then + if [ ! -d "$2"/"$name" ]; then + mkdir -p $2/$name + fi + recursive_copy $1/$name $2/$name + fi + done +} + +function do_patch() +{ + echo "do_patch..." + cd build + PATCHS=patchs/$1 + patchlist=$(ls $PATCHS) + for name in ${patchlist[*]} + do + echo $name + if [ -f "$PATCHS"/"$name" ]; then + patch -p1 < $PATCHS/$name + fi + done + cd - + echo "do_patch done" +} + +function build_common_prepare() +{ + #将DAPLINK解压到build目录 + mkdir -p $BUILD + tar -xf $DAPLINK_SRC -C $BUILD + mv $BUILD/$(basename $DAPLINK_SRC .tar.gz) $BUILD_CA7 + + #基于STM32F103XB和STM32MP1XX SDK构造stm32mp1xx目录 + tar -xf $SDK_SRC + mv $(basename $SDK_SRC .tar.gz) $TMP_DIR + + recursive_copy $HISPARK $BUILD + + #拷贝打补丁前的DAP到CM4 + CORE=$BUILD_CM4/Core + chmod -R 777 $CORE + if [ ! -f "$CORE"/Src/JTAG_DP.c ]; then + cp $BUILD_CA7_SOURCE/daplink/cmsis-dap/JTAG_DP.c $CORE/Src + fi + if [ ! -f "$CORE"/Inc/SW_DP.c ]; then + cp $BUILD_CA7_SOURCE/daplink/cmsis-dap/SW_DP.c $CORE/Src + fi + if [ ! -f "$CORE"/Inc/DAP.h ]; then + cp $BUILD_CA7_SOURCE/daplink/cmsis-dap/DAP.h $CORE/Inc + fi + if [ ! -f "$CORE"/Inc/DAP_Config.h ]; then + cp $BUILD_CA7_SOURCE/hic_hal/stm32/stm32f103xb/DAP_config.h $CORE/Inc + fi +} + +function build_ca7_prepare() +{ + echo "prepare ca7 files ..." + echo "copy STM32MP1xx_HAL_Driver to build ..." + mkdir -p $BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx + #基于stm32f103文件目录创建vendorHM的family + mkdir -p $BUILD_CA7_SOURCE/family/vendorHM/306x + cp $BUILD_CA7_SOURCE/family/st/stm32f103rb/*.c $BUILD_CA7_SOURCE/family/vendorHM/306x + + cp -rf $TMP_DIR/Drivers/STM32MP1xx_HAL_Driver $BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx + + #删除不要的文件,这里主要是LL文件和template文件 + SRC_PATH=$BUILD_CA7_SOURCE/hic_hal/stm32/stm32f103xb + rm $STM32MP1XX/STM32MP1xx_HAL_Driver/Inc/*_ll_*.h + rm $STM32MP1XX/STM32MP1xx_HAL_Driver/Src/*_ll_*.c + rm $STM32MP1XX/STM32MP1xx_HAL_Driver/Src/*template.c + create_stm32mp1xx_dir $SRC_PATH $STM32MP1XX + + cp $TMP_DIR/Drivers/CMSIS/Device/ST/STM32MP1xx/Include/stm32mp1xx.h $STM32MP1XX + cp $TMP_DIR/Drivers/CMSIS/Device/ST/STM32MP1xx/Include/stm32mp153dxx_ca7.h $STM32MP1XX + cp $TMP_DIR/Drivers/CMSIS/Device/ST/STM32MP1xx/Include/system_stm32mp1xx.h $STM32MP1XX/cmsis + cp $TMP_DIR/Drivers/CMSIS/Device/ST/STM32MP1xx/Source/Templates/system_stm32mp1xx.c $STM32MP1XX/cmsis + cp $TMP_DIR/Drivers/CMSIS/Core_A/Include/cmsis_cp15.h $BUILD_CA7_SOURCE/cmsis-core + cp $TMP_DIR/Drivers/CMSIS/Core_A/Include/core_ca.h $BUILD_CA7_SOURCE/cmsis-core + cp $TMP_DIR/Projects/STM32MP157C-EV1/Examples/QSPI/QSPI_ReadWrite_IT/Src/stm32mp1xx_hal_msp.c $STM32MP1XX/cmsis + cp $TMP_DIR/Projects/STM32MP157C-EV1/Examples/QSPI/QSPI_ReadWrite_IT/Src/stm32mp1xx_hal_msp.c $STM32MP1XX/cmsis + cp $TMP_DIR/Projects/STM32MP157C-EV1/Templates/Inc/stm32mp1xx_hal_conf.h $STM32MP1XX/STM32MP1xx_HAL_Driver + + mkdir -p $BUILD_CA7_SOURCE/securec + cp -rf $SECURE_CODE_SRC/* $BUILD_CA7_SOURCE/securec + + do_patch "CA7" + echo "prepare ca7 files done" +} + +function build_cm4_prepare() +{ + echo "prepare cm4 files..." + DRIVERS=$BUILD_CM4/Drivers + if [ ! -e "$DRIVERS" ]; then + mkdir $DRIVERS + cp -rf $STM32MP1XX_HAL $DRIVERS + cp -rf $TMP_DIR/Drivers/CMSIS $DRIVERS + + cp $DRIVERS/CMSIS/Device/ST/STM32MP1xx/Source/Templates/system_stm32mp1xx.c $BUILD_CM4/Core/Src + cp $STM32MP1XX_HAL/stm32mp1xx_hal_conf.h $BUILD_CM4/Core/Inc + cp $TMP_DIR/Projects/STM32MP157C-DK2/Applications/OpenAMP/OpenAMP_raw/STM32CubeIDE/CM4/Application/User/*.c $BUILD_CM4/Core/Src + fi + + #拷贝A核Msg_Queue代码到M核,两者使用相同的代码 + if [ ! -f "$CORE"/Src/msg_queue.c ]; then + cp $BUILD_CA7_SOURCE/hispark_trace/msgQueue/*.c $CORE/Src + fi + if [ ! -f "$CORE"/Inc/msg_queue.h ]; then + cp $BUILD_CA7_SOURCE/hispark_trace/msgQueue/*.h $CORE/Inc + fi + + #拷贝A核debug代码到M核,两者使用相同的代码 + if [ ! -f "$CORE"/Src/debug.c ]; then + cp $BUILD_CA7_SOURCE/hispark_trace/debug/*.c $CORE/Src + fi + if [ ! -f "$CORE"/Inc/debug.h ]; then + cp $BUILD_CA7_SOURCE/hispark_trace/debug/*.h $CORE/Inc + fi + + mkdir -p $BUILD_CM4/securec + cp -rf $SECURE_CODE_SRC/* $BUILD_CM4/securec + + do_patch "CM4" + echo "prepare cm4 files done" +} + +function build_boot_prepare() +{ + echo "prepare boot files..." + BUILD_BOOT_SOURCE=$BUILD_BOOT/source + cp -rf $BUILD_CA7_SOURCE/cmsis-core $BUILD_BOOT_SOURCE + cp -rf $BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver $BUILD_BOOT_SOURCE/hic_hal/stm32/stm32mp1xx + mkdir $BUILD_BOOT_SOURCE/crc + cp $BUILD_CA7_SOURCE/hispark_trace/crc/crc32.* $BUILD_BOOT_SOURCE/crc + cp -rf $BUILD_CA7_SOURCE/hispark_trace/drivers/oled $BUILD_BOOT_SOURCE/mmi + cp -rf $BUILD_CA7_SOURCE/hispark_trace/drivers/key $BUILD_BOOT_SOURCE/mmi + cp $BUILD_CA7_SOURCE/hic_hal/sdk.h $BUILD_BOOT_SOURCE/hic_hal + cp $BUILD_CA7_SOURCE/hic_hal/FlashPrg.h $BUILD_BOOT_SOURCE/hic_hal + cp $BUILD_CA7_SOURCE/hic_hal/flash_hal.h $BUILD_BOOT_SOURCE/hic_hal + + cp -rf $BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx/cmsis $BUILD_BOOT_SOURCE/hic_hal/stm32/stm32mp1xx + cp $BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx/stm32mp153dxx_ca7.h $BUILD_BOOT_SOURCE/hic_hal/stm32/stm32mp1xx + cp $BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx/stm32mp1xx.h $BUILD_BOOT_SOURCE/hic_hal/stm32/stm32mp1xx + cp $BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx/IO_Config.h $BUILD_BOOT_SOURCE/hic_hal/stm32/stm32mp1xx + cp $BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx/daplink_addr.h $BUILD_BOOT_SOURCE/hic_hal/stm32/stm32mp1xx + cp $BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx/sdk.c $BUILD_BOOT_SOURCE/hic_hal/stm32/stm32mp1xx + cp $BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx/flash.c $BUILD_BOOT_SOURCE/hic_hal/stm32/stm32mp1xx + + mkdir -p $BUILD_BOOT/source/securec + cp -rf $SECURE_CODE_SRC/* $BUILD_BOOT/source/securec + echo "prepare boot files done" +} + +function remove_unused_files() +{ + #删除不需要的文件,如加入编译有告警 + if [ -f "$BUILD_CA7_SOURCE"/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_cortex.c ]; then + rm $BUILD_CA7_SOURCE/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_cortex.c + fi + if [ -f "$BUILD_CA7_SOURCE"/daplink/sdk_stub.c ]; then + rm $BUILD_CA7_SOURCE/daplink/sdk_stub.c + fi + if [ -f "$BUILD_BOOT_SOURCE"/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_cortex.c ]; then + rm $BUILD_BOOT_SOURCE/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_cortex.c + fi +} + +function build_prepare() +{ + if [ ! -d "$BUILD" ]; then + build_common_prepare + build_ca7_prepare + build_cm4_prepare + build_boot_prepare + remove_unused_files + chmod -R 777 $BUILD + fi + [ -n "${TMP_DIR}" ] && rm -rf ${TMP_DIR} +} + +function build_ca7() +{ + echo "build ca7..." + cd $BUILD_CA7 + make + cd - + echo "build ca7 done" +} + +function build_ca7_clean() +{ + cd $BUILD_CA7 + make clean +} + +function build_cm4() +{ + echo "build cm4..." + cd $BUILD_CM4 + make + cd - + echo "build cm4 done" +} + +function build_cm4_clean() +{ + cd $BUILD_CM4 + make clean + cd - +} + +function build_boot() +{ + echo "build boot..." + cd $BUILD_BOOT + make + cd - + echo "build boot done" +} + +function build_boot_clean() +{ + cd $BUILD_BOOT + make clean + cd - +} + +function clean_up() +{ + [ -n "${BUILD}" ] && rm -rf ${BUILD} + [ -n "${TMP_DIR}" ] && rm -rf ${TMP_DIR} + [ -n "${IMAGES_DIR}" ] && rm -rf $IMAGES_DIR +} + +function create_images() +{ + python ./tools/daplink_create_loader.py + chmod 777 images/daplink_boot.stm32 + chmod 777 images/HiSpark-Trace_Boot_CRC32_forDAPLINK.bin + python ./tools/daplink_create_allinone_interface_1M_CRC32.py + chmod 777 images/allinone_upgrade_1M_CRC32.bin + python ./tools/daplink_create_HiSpark_Trace_allinone.py + chmod 777 images/HiSpark-Trace_allinone.bin + python ./tools/daplink_create_HiSpark_Trace_Firmware.py + chmod 777 images/HiSpark-Trace_Firmware_forDAPLINK.bin +} + +function delete_tmp_bin() +{ + rm images/daplink_*.bin + rm images/*CRC32.bin + rm images/*.stm32 +} + +function make_images() +{ + DIR=$(cd $(dirname $0) && pwd ) + + if [ ! -d "$IMAGES_DIR" ]; then + mkdir $IMAGES_DIR + fi + if [ ! -f "$BUILD_BOOT"/out/daplink_boot.bin ]; then + echo "daplink boot bin not exist" + exit $? + else + cp $BUILD_BOOT/out/daplink_boot.bin $IMAGES_DIR + fi + if [ ! -f "$BUILD_CA7"/out/daplink_A7.bin ]; then + echo "daplink ca7 bin not exist" + exit $? + else + cp $BUILD_CA7/out/daplink_A7.bin $IMAGES_DIR + fi + if [ ! -f "$BUILD_CM4"/out/daplink_M4.bin ]; then + echo "daplink cm4 bin not exist" + exit $? + else + cp $BUILD_CM4/out/daplink_M4.bin $IMAGES_DIR + fi + + create_images + delete_tmp_bin +} + +function print_usage() { + local usage="\ + Usage: + build.sh : same of build.sh ca7 + build.sh prepare : create the directory of build and tar + build.sh clean : remove the output and intermediate files + build.sh boot : build boot + build.sh boot clean : remove output and intermediate file of boot + build.sh ca7 : build daplink code in Cortex-A + build.sh ca7 clean : remove output and intermediate file of Cortex-A + build.sh cm4 : build daplink code in Cortex-M + build.sh boot clean : remove output and intermediate file of Cortex-M + build.sh mkimages : create images + build.sh all : build and create images + build.sh rebuild : clean all and rebuild and create images + build.sh build : build and create images + build.sh -h|--help : print help message + " + echo "$usage" +} + +function main() +{ + global_env_init + glogal_variable_init + if [[ $# -ne 0 ]]; then + case "$1" in + clean) + clean_up + exit $? + ;; + prepare) + build_prepare + exit $? + ;; + boot) + if [[ $# -eq 2 ]]; then + if [ "$2" == "clean" ]; then + build_boot_clean + fi + else + build_prepare + build_boot + fi + exit $? + ;; + ca7) + if [[ $# -eq 2 ]]; then + if [ "$2" == "clean" ]; then + build_ca7_clean + fi + else + build_prepare + build_ca7 + fi + exit $? + ;; + cm4) + if [[ $# -eq 2 ]]; then + if [ "$2" == "clean" ]; then + build_cm4_clean + fi + else + build_prepare + build_cm4 + fi + exit $? + ;; + mkimages) + make_images + exit $? + ;; + all) + build_prepare + build_cm4 + build_ca7 + build_boot + make_images + exit $? + ;; + rebuild) + clean_up + build_prepare + build_cm4 + build_ca7 + build_boot + make_images + exit $? + ;; + build) + build_boot_clean + build_cm4_clean + build_ca7_clean + build_cm4 + build_ca7 + build_boot + make_images + exit $? + ;; + -h|--help|*) + print_usage + exit $? + ;; + esac + else + build_prepare + build_ca7 + fi +} + +main "$@" diff --git a/src/tools/hispark_trace/hispark/CA7/Makefile b/src/tools/hispark_trace/hispark/CA7/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d390e4053fe735357379bd611b6fd5b351554450 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/Makefile @@ -0,0 +1,170 @@ +ARCH := arm +CROSS_COMPILE := arm-none-eabi- +ifeq ($(OS), Windows_NT) +PLATFORM="Windows" +COMPILE_TIME = $(shell echo %date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%) +else +PLATFORM="Unix-Like" +COMPILE_TIME = $(date + "%Y-%M-%d %H:%M:%s") +endif + + +AR := $(CROSS_COMPILE)ar +CC := $(CROSS_COMPILE)gcc +NM := $(CROSS_COMPILE)nm +CPP := $(CROSS_COMPILE)cpp +LD := $(CROSS_COMPILE)ld +OBJCOPY := $(CROSS_COMPILE)objcopy +OBJDUMP := $(CROSS_COMPILE)objdump + +TOP_DIR := . + +OUT = $(TOP_DIR)/out +TARGET := daplink_A7 +TARGET_ELF := $(OUT)/$(TARGET).elf +TARGET_BIN := $(OUT)/$(TARGET).bin +TARGET_HEX := $(OUT)/$(TARGET).hex +TARGET_ASM := $(OUT)/$(TARGET).asm +TARGET_MAP := $(OUT)/$(TARGET).map + +OBJCPFLAGS_ELF_TO_BIN = -Obinary +OBJCPFLAGS_ELF_TO_HEX = -Ibinary -Oihex +OBJCPFLAGS_ELF_TO_LIST = -S + +CFLAGS = -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -std=gnu11 -fno-strict-aliasing -fno-PIE -Os -fno-stack-protector -fno-delete-null-pointer-checks -fmacro-prefix-map=./= -g -fstack-usage -Wno-format-nonliteral -Werror=date-time -D__ARM__ -Wa,-mimplicit-it=always -mthumb -mthumb-interwork -mabi=aapcs-linux -mword-relocations -fPIE -fPIC -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -pipe -march=armv7-a -mtune=generic-armv7-a +CFLAGS += -fshort-wchar -fno-strict-aliasing +CFLAGS += -mfloat-abi=soft +CFLAGS += -fshort-enums +CFLAGS += -DNO_RTOS -DUSE_HAL_TICK -DDAPLINK_UART +CFLAGS += -DCORE_CA7 -DSTM32MP153Dxx -D__NO_USB_LIB_C -DDAPLINK_HIC_ID=0x97969949 -DUSE_HAL_DRIVER -DINTERFACE_STM32MP153 -DUSE_LEGACY_CMSIS_RTOS -DOS_CLOCK=25000000 +CFLAGS += -DDRAG_N_DROP_SUPPORT -D__OTG_HS_EMBEDDED_PHY +CFLAGS += -DDAPLINK_VERSION=10002000 -DMSC_ENDPOINT +CFLAGS += -DWINUSB_INTERFACE +CFLAGS += -DBULK_ENDPOINT +CFLAGS += -DCDC_ENDPOINT +CFLAGS += -DCONFIG_HAS_VBAR +CFLAGS += -DM4BIN_SIZE_ADDR=0xC004 -DM4_TEXT_BASEADDR=0xBB000 +CFLAGS += -DDAPLINK_BASEADDR=0x2FFCA500 +CFLAGS += -DSECUREC_HAVE_ERRNO_H=0 +CFLAGS += -DDAPLINK_COMPILE_TIME=\"$(COMPILE_TIME)\" +CFLAGS += -DSOFTWARE_VERSION=\"1.0.0.17\" +CFLAGS += -DHISPARK_TRACE -DROLE_MASTER +ASFLAGS = -Wall -march=armv7-a -mtune=cortex-a7 -nostidinc -fno-PIE -g -D__ARM__ -D__ASSEMBLY__ -Wa,-mimplicit-it=always -mthumb -mthumb-interwork -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -pipe -D__LINUX_ARM_ARCH__=7 -mtune=generic-armv7-a + +LDSCRIPT = $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/daplink.lds + +SRC = $(TOP_DIR)/source/board/stm32mp1xx.c +SRC += $(wildcard $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/cmsis/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/Src/*.c) +SRC += $(wildcard $(TOP_DIR)/source/usb/*.c) +SRC += $(wildcard $(TOP_DIR)/source/usb/winusb/*.c) +SRC += $(wildcard $(TOP_DIR)/source/usb/bulk/*.c) +SRC += $(wildcard $(TOP_DIR)/source/usb/cdc/*.c) +SRC += $(wildcard $(TOP_DIR)/source/usb/hid/*.c) +SRC += $(wildcard $(TOP_DIR)/source/usb/msc/*.c) +SRC += $(wildcard $(TOP_DIR)/source/daplink/interface/*.c) +SRC += $(wildcard $(TOP_DIR)/source/daplink/settings/*.c) +SRC += $(wildcard $(TOP_DIR)/source/daplink/drag-n-drop/*.c) +SRC += $(wildcard $(TOP_DIR)/source/daplink/cmsis-dap/*.c) +SRC += $(wildcard $(TOP_DIR)/source/daplink/usb2uart/*.c) +SRC += $(wildcard $(TOP_DIR)/source/daplink/*.c) +SRC += $(wildcard $(TOP_DIR)/source/family/vendorHM/306x/*.c) +SRC += $(wildcard $(TOP_DIR)/source/rtos_none/*.c) +SRC += $(wildcard $(TOP_DIR)/source/target/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hispark_trace/fatfs/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hispark_trace/debug/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hispark_trace/drivers/oled/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hispark_trace/drivers/key/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hispark_trace/remoteproc/src/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hispark_trace/msgQueue/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hispark_trace/offline_download/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hispark_trace/display/src/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hispark_trace/dap_ext_features/source/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hispark_trace/crc/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hispark_trace/interrupt/*.c) +SRC += $(wildcard $(TOP_DIR)/source/securec/src/*.c) + +ASM_SRC = ${wildcard $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/gcc/*.S} + +INC = -I $(TOP_DIR)/source/daplink +INC += -I $(TOP_DIR)/source/daplink/settings +INC += -I $(TOP_DIR)/source/daplink/interface +INC += -I $(TOP_DIR)/source/daplink/cmsis-dap +INC += -I $(TOP_DIR)/source/daplink/drag-n-drop +INC += -I $(TOP_DIR)/source/rtos_none +INC += -I $(TOP_DIR)/source/hic_hal +INC += -I $(TOP_DIR)/source/hic_hal/stm32 +INC += -I $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx +INC += -I $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/cmsis +INC += -I $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver +INC += -I $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/Inc +INC += -I $(TOP_DIR)/source/usb +INC += -I $(TOP_DIR)/source/cmsis-core +INC += -I $(TOP_DIR)/Drivers/CMSIS/Device/ST/STM32MP1xx/Include +INC += -I $(TOP_DIR)/source/target +INC += -I $(TOP_DIR)/source/hispark_trace/fatfs +INC += -I $(TOP_DIR)/source/hispark_trace/debug +INC += -I $(TOP_DIR)/source/hispark_trace/drivers/oled +INC += -I $(TOP_DIR)/source/hispark_trace/drivers/key +INC += -I $(TOP_DIR)/source/hispark_trace/remoteproc/inc +INC += -I $(TOP_DIR)/source/hispark_trace/msgQueue +INC += -I $(TOP_DIR)/source/hispark_trace/offline_download +INC += -I $(TOP_DIR)/source/hispark_trace/display/inc +INC += -I $(TOP_DIR)/source/hispark_trace/dap_ext_features/include +INC += -I $(TOP_DIR)/source/hispark_trace/crc +INC += -I $(TOP_DIR)/source/hispark_trace/interrupt +INC += -I $(TOP_DIR)/source/securec/include + +NORMOM_CFLAGS :=$(CFLAGS) $(INC) +NORMOM_ASFLAGS :=$(CFLAGS) -I $(TOP_DIR)/include +LDFLAGS = -nostdlib -T $(LDSCRIPT) -nostartfiles -Wl,--gc-sections -pie -lc -static -Wl,--no-wchar-size-warning +#Set the TOOLCHAIN_DIR in /root/.bashrc or build.sh(the tool chain is gcc-arm-10.3-2021.07-x86_64-arm-none-eabi). +#TOOLCHAIN_DIR=CI_ENV +LIBS = $(TOOLCHAIN_DIR)/lib/gcc/arm-none-eabi/10.3.1/libgcc.a +LIBS += $(TOOLCHAIN_DIR)/arm-none-eabi/lib/libc.a + + +OBJ := $(SRC:%.c=%.o) +ASMOBJ := $(ASM_SRC:%.S=%.o) + +DEF += + +STARTUP_RAW = $(wildcard $(STARTUP)) +STARTUP_OBJ = $(STARTUP_RAW:%.c=%.o) + +daplink_OBJ = ./out/*.o + +all: $(OUT) $(TARGET_BIN) +$(TARGET_BIN): $(TARGET_ELF) + $(Q)$(OBJCOPY) $(OBJCPFLAGS_ELF_TO_BIN) $(TARGET_ELF) $(TARGET_BIN) + $(Q)$(OBJDUMP) -d $(TARGET_ELF) > $(TARGET_ASM) + $(Q)$(OBJDUMP) -stD $(TARGET_ELF) > $(TARGET_MAP) + +$(TARGET_ELF):$(OBJ) $(ASMOBJ) + $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ + +$(OBJ):%.o:%.c + @echo Compile $< + $(CC) $(NORMOM_CFLAGS) -c $< -o $@ + +$(ASMOBJ):%.o:%.S + @echo Compile $< + $(CC) $(NORMOM_ASFLAGS) -c $< -o $@ + +$(OUT): + mkdir -p $(OUT) + +.PHONY: clean +ifeq ($(OS), Windows_NT) +RM := del /s/q +clean: + $(RM) ..\CA7\*.o + $(RM) ..\CA7\*.su + $(RM) out +else +clean : + find . -name "*.o" | xargs rm -f + find . -name "*.su" | xargs rm -f + -rm -rf $(OUT)/* +endif diff --git a/src/tools/hispark_trace/hispark/CA7/source/board/stm32mp1xx.c b/src/tools/hispark_trace/hispark/CA7/source/board/stm32mp1xx.c new file mode 100644 index 0000000000000000000000000000000000000000..a6d4f7b34501e0c780e76a5bbeccc545fc80c1c8 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/board/stm32mp1xx.c @@ -0,0 +1,31 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file stm32mp1xx.c + * @author MCU Driver Team + * @brief set board information + */ + +#include "target_family.h" +#include "target_board.h" + +const board_info_t g_board_info = { + .info_version = kBoardInfoVersion, + .board_id = "0710", + .family_id = kStub_HWReset_FamilyID, + .target_cfg = &target_device, +}; diff --git a/src/tools/hispark_trace/hispark/CA7/source/daplink/cmsis-dap/swd_jtag_config.c b/src/tools/hispark_trace/hispark/CA7/source/daplink/cmsis-dap/swd_jtag_config.c new file mode 100644 index 0000000000000000000000000000000000000000..bf899ab090b46369d3ff9322fcb605d1f4680eb2 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/daplink/cmsis-dap/swd_jtag_config.c @@ -0,0 +1,177 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file swd_jtag_config.c + * @author MCU Driver Team + * @brief swd and jtag config. + */ +#include "DAP_config.h" +#include "DAP.h" +#include "config_storage_update.h" +#include "swd_jtag_config.h" + +#define SWD_JTAG_MAX_LEVEL_CNT 11 + +#define SWD_JTAG_MIN_CLOCK_LEVEL_0 6000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_1 5000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_2 4000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_3 3000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_4 2000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_5 1000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_6 800000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_7 500000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_8 300000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_9 100000 + +#define SWD_JTAG_CLOCK_VAL_0 6000000 +#define SWD_JTAG_CLOCK_VAL_1 5000000 +#define SWD_JTAG_CLOCK_VAL_2 4000000 +#define SWD_JTAG_CLOCK_VAL_3 3000000 +#define SWD_JTAG_CLOCK_VAL_4 2000000 +#define SWD_JTAG_CLOCK_VAL_5 1000000 +#define SWD_JTAG_CLOCK_VAL_6 800000 +#define SWD_JTAG_CLOCK_VAL_7 500000 +#define SWD_JTAG_CLOCK_VAL_8 300000 +#define SWD_JTAG_CLOCK_VAL_9 100000 + +typedef struct { + uint32_t clockLevel; + uint32_t minClockLevel; + uint32_t clockVal; +} SwdJtagClockCfg; + +const SwdJtagClockCfg g_swdJtagClockCfgList[SWD_JTAG_MAX_LEVEL_CNT] = { + {SWD_JTAG_CLOCK_LEVEL_0, SWD_JTAG_MIN_CLOCK_LEVEL_0, SWD_JTAG_CLOCK_VAL_0}, + {SWD_JTAG_CLOCK_LEVEL_1, SWD_JTAG_MIN_CLOCK_LEVEL_1, SWD_JTAG_CLOCK_VAL_1}, + {SWD_JTAG_CLOCK_LEVEL_2, SWD_JTAG_MIN_CLOCK_LEVEL_2, SWD_JTAG_CLOCK_VAL_2}, + {SWD_JTAG_CLOCK_LEVEL_3, SWD_JTAG_MIN_CLOCK_LEVEL_3, SWD_JTAG_CLOCK_VAL_3}, + {SWD_JTAG_CLOCK_LEVEL_4, SWD_JTAG_MIN_CLOCK_LEVEL_4, SWD_JTAG_CLOCK_VAL_4}, + {SWD_JTAG_CLOCK_LEVEL_5, SWD_JTAG_MIN_CLOCK_LEVEL_5, SWD_JTAG_CLOCK_VAL_5}, + {SWD_JTAG_CLOCK_LEVEL_6, SWD_JTAG_MIN_CLOCK_LEVEL_6, SWD_JTAG_CLOCK_VAL_6}, + {SWD_JTAG_CLOCK_LEVEL_7, SWD_JTAG_MIN_CLOCK_LEVEL_7, SWD_JTAG_CLOCK_VAL_7}, + {SWD_JTAG_CLOCK_LEVEL_8, SWD_JTAG_MIN_CLOCK_LEVEL_8, SWD_JTAG_CLOCK_VAL_8}, + {SWD_JTAG_CLOCK_LEVEL_9, SWD_JTAG_MIN_CLOCK_LEVEL_9, SWD_JTAG_CLOCK_VAL_9}, + {SWD_JTAG_CLOCK_LEVEL_LOW, 0, SWD_JTAG_CLOCK_VAL_9} +}; + +int SwdTurnaroundSet(int turnaround) +{ + DAP_Data.swd_conf.turnaround = turnaround; + return 0; +} + +int SwdTurnaroundGet(void) +{ + return DAP_Data.swd_conf.turnaround; +} + +int SwdDataPhaseSet(int phase) +{ + DAP_Data.swd_conf.data_phase = phase; + return 0; +} + +int SwdDataPhaseGet(void) +{ + return DAP_Data.swd_conf.data_phase; +} + +int SwdIdleCyclesSet(int cycles) +{ + DAP_Data.transfer.idle_cycles = cycles; + return 0; +} + +int SwdIdleCyclesGet(void) +{ + return DAP_Data.transfer.idle_cycles; +} + +int SwdJtagClockLevelSet(int clock) +{ + DAP_Data.clock_delay = 1; + for (int i = 0; i < SWD_JTAG_MAX_LEVEL_CNT; i++) { + if (clock >= g_swdJtagClockCfgList[i].minClockLevel) { + DAP_Data.clock_level = g_swdJtagClockCfgList[i].clockLevel; + break; + } + } + return 0; +} + +uint32_t SwdJtagClockGet(void) +{ + uint32_t currentClock; + for (int i = 0; i < SWD_JTAG_MAX_LEVEL_CNT; i++) { + if (g_swdJtagClockCfgList[i].clockLevel == DAP_Data.clock_level) { + currentClock = g_swdJtagClockCfgList[i].clockVal; + break; + } + } + return currentClock; +} + +int SwJtagClockLevelLevelSet(int level) +{ + DAP_Data.clock_level = level; + return 0; +} + +int SwdJtagClockLevelGet(void) +{ + return DAP_Data.clock_level; +} + +int SwdJtagClockDelaySet(uint32_t clock) +{ + DAP_Data.clock_delay = clock; + return 0; +} + +int SwdJtagClockDelayGet(void) +{ + return DAP_Data.clock_delay; +} + +uint8_t SwdJtagDebugPortGet(void) +{ + uint32_t port; + + port = ConfigDebugPorFlagRead(); + switch (port) { + case DAP_PORT_JTAG: + DAP_Data.debug_port = DAP_PORT_JTAG; + break; + case DAP_PORT_SWD: + DAP_Data.debug_port = DAP_PORT_SWD; + break; + default: + DAP_Data.debug_port = DAP_PORT_SWD; + port = DAP_PORT_SWD; + ConfigDebugPortFlagSave(port); + break; + } + return DAP_Data.debug_port; +} + +int SwdJtagDebugPortSet(uint8_t port) +{ + uint32_t tmpPort = port; + DAP_Data.debug_port = port; + ConfigDebugPortFlagSave(tmpPort); + return 0; +} diff --git a/src/tools/hispark_trace/hispark/CA7/source/daplink/cmsis-dap/swd_jtag_config.h b/src/tools/hispark_trace/hispark/CA7/source/daplink/cmsis-dap/swd_jtag_config.h new file mode 100644 index 0000000000000000000000000000000000000000..0410ef47a21853445ff9e24c0036f8d67f59822e --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/daplink/cmsis-dap/swd_jtag_config.h @@ -0,0 +1,53 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file swd_jtag_config.h + * @author MCU Driver Team + * @brief swd and jtag config. + */ +#ifndef SWD_JTAG_CONFIG_H +#define SWD_JTAG_CONFIG_H +#include + +#define SWD_JTAG_CLOCK_LEVEL_0 0 +#define SWD_JTAG_CLOCK_LEVEL_1 1 +#define SWD_JTAG_CLOCK_LEVEL_2 2 +#define SWD_JTAG_CLOCK_LEVEL_3 3 +#define SWD_JTAG_CLOCK_LEVEL_4 4 +#define SWD_JTAG_CLOCK_LEVEL_5 5 +#define SWD_JTAG_CLOCK_LEVEL_6 6 +#define SWD_JTAG_CLOCK_LEVEL_7 7 +#define SWD_JTAG_CLOCK_LEVEL_8 8 +#define SWD_JTAG_CLOCK_LEVEL_9 9 +#define SWD_JTAG_CLOCK_LEVEL_LOW 300 + + +int SwdTurnaroundSet(int turnaround); +int SwdTurnaroundGet(void); +int SwdDataPhaseSet(int phase); +int SwdDataPhaseGet(void); +int SwdIdleCyclesSet(int cycles); +int SwdIdleCyclesGet(void); +int SwdJtagClockLevelSet(int clock); +int SwJtagClockLevelLevelSet(int level); +int SwdJtagClockLevelGet(void); +uint32_t SwdJtagClockGet(void); +int SwdJtagClockDelaySet(uint32_t clock); +int SwdJtagClockDelayGet(void); +uint8_t SwdJtagDebugPortGet(void); +int SwdJtagDebugPortSet(uint8_t port); +#endif diff --git a/src/tools/hispark_trace/hispark/CA7/source/daplink/version_git.h b/src/tools/hispark_trace/hispark/CA7/source/daplink/version_git.h new file mode 100644 index 0000000000000000000000000000000000000000..a4b866b027c804e72cd9807525715bcfd26f57e9 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/daplink/version_git.h @@ -0,0 +1,29 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file version git + * @author MCU Driver Team + * @brief git version dummy header file, just for compiler + */ + +#ifndef VERSION_GIT_H +#define VERSION_GIT_H + +#define GIT_COMMIT_SHA "abcdddaaaaaaa" +#define GIT_LOCAL_MODS 0xABAB + +#endif diff --git a/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/daplink.lds b/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/daplink.lds new file mode 100644 index 0000000000000000000000000000000000000000..501489a589df5f4072e6314367da0ed7b5946d1a --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/daplink.lds @@ -0,0 +1,117 @@ +/* create for stmp32mp157, A7_CODE run in sysram */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH("arm") +ENTRY(_start) + +SYSRAM_ADDR = 0x2FFC0000; +SRAM2_ADDR = 0x10020000; +SRAM4_ADDR = 0x10050000; +START_ADDR = SYSRAM_ADDR + 0xA500; + +MEMORY +{ + A7_CODE(RX) : ORIGIN = START_ADDR, LENGTH = 158K + A7_SRAM(RW) : ORIGIN = START_ADDR + 158K, LENGTH = 56K + MSGQ_SHM(RW) : ORIGIN = SRAM4_ADDR, LENGTH = 20K + STACK(RW) : ORIGIN = SRAM4_ADDR + 20K, LENGTH = 12K + CFGRAM(RW) : ORIGIN = SRAM4_ADDR + 32K, LENGTH = 1K + CFGROM(RW) : ORIGIN = SRAM4_ADDR + 33K, LENGTH = 1K + HEAP(RW) : ORIGIN = SRAM4_ADDR + 34K, LENGTH = 4K + + VARQ_SHM(RW) : ORIGIN = SRAM2_ADDR, LENGTH = 120K +} + +__HEAP_START__ = ORIGIN(HEAP); +__HEAP_END__ = ORIGIN(HEAP)+LENGTH(HEAP); +SECTIONS +{ + . = ALIGN(4); + .text.entry : + { + KEEP(*(.text.entry)) + } > A7_CODE + + .text : + { + *(.text*) + *(.ram.text*) + } > A7_CODE + + .rodata : + { + . = ALIGN(4); + *(SORT_BY_ALIGNMENT(.rodata*)) + *(.got*) + } > A7_CODE + + .data : + { + . = ALIGN(4); + __data_load = LOADADDR(.data); + __data_start = .; + *(SORT_BY_ALIGNMENT(.data*)) + . = ALIGN(4); + __data_end = .; + } > A7_SRAM AT > A7_CODE + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } > A7_SRAM + + .stack (NOLOAD) : + { + . = ALIGN(4); + __SYSTEM_STACK_BEGIN__ = ORIGIN(STACK); + KEEP(*(.stacks)) + __SYSTEM_STACK_END__ = ORIGIN(STACK) + LENGTH(STACK); + } > STACK + STACK_TOP = __SYSTEM_STACK_END__; + + .cfgram : + { + . = ALIGN(4); + __cfgram_load = LOADADDR(.cfgram); + __cfgram_start = .; + *(cfgram) + . = ALIGN(4); + __cfgram_end = .; + } > CFGRAM AT > A7_CODE + + .cfgrom : + { + . = ALIGN(4); + __cfgrom_load = LOADADDR(.cfgrom); + __cfgrom_start = .; + *(cfgrom) + . = ALIGN(4); + __cfgrom_end = .; + } > CFGROM AT > A7_CODE + + .msgq : + { + . = ALIGN(4); + __msgq_start = .; + *(.msgq_section) + . = ALIGN(4); + __msgq_end = .; + } > MSGQ_SHM + g_msgQStart = __msgq_start; + + .varq : + { + . = ALIGN(4); + __varq_start = .; + *(.varq_section) + . = ALIGN(4); + __varq_end = .; + } > VARQ_SHM + g_vargStart = __varq_start; + + .interp : { *(.interp*) } +} diff --git a/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/gcc/startup_stm32mp1xx.S b/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/gcc/startup_stm32mp1xx.S new file mode 100644 index 0000000000000000000000000000000000000000..149f9fc7f3d74e2af400e041ccc748b9abb87b0f --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/gcc/startup_stm32mp1xx.S @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * armboot - Startup Code for STM32MP1xx of HiSparkTrace + */ +#define ASM_NL ; +#define SYMBOL_NAME_STR(X) #X +#define SYMBOL_NAME(X) X +#ifdef __STDC__ +#define SYMBOL_NAME_LABEL(X) X##: +#else +#define SYMBOL_NAME_LABEL(X) X: +#endif +#define ALIGN .align 2 + +#define LENTRY(name) \ + ALIGN ASM_NL \ + SYMBOL_NAME_LABEL(name) + +#define ENTRY(name) \ + .globl SYMBOL_NAME(name) ASM_NL \ + LENTRY(name) + +#define END(name) \ + .size name, .-name + +#define ENDPROC(name) \ + .type name STT_FUNC ASM_NL \ + END(name) + +/************************************************************************* + * + * Startup Code (reset vector) + * + * Do important init only if we don't start from memory! + * Setup memory and board specific bits prior to relocation. + * Relocate armboot to ram. Setup stack. + * + *************************************************************************/ + .section .text.entry + + .globl _start + .globl save_boot_params_ret + .extern InterruptEntry + .type save_boot_params_ret,%function + .global raise + +_start: + /* 创建中断向量表 */ + ldr pc, =Reset_Handler /* 复位中断 */ + ldr pc, =Undefined_Handler /* 未定义指令中断 */ + ldr pc, =SVC_Handler /* Supervisor中断 */ + ldr pc, =PrefAbort_Handler /* 预取终止中断 */ + ldr pc, =DataAbort_Handler /* 数据终止中断 */ + ldr pc, =NotUsed_Handler /* 未使用中断 */ + ldr pc, =IRQ_Handler /* IRQ中断 */ + ldr pc, =FIQ_Handler /* FIQ中断 */ + +Reset_Handler: + /* Allow the board to save important registers */ + b save_boot_params + +/* 未定义指令中断函数 */ +Undefined_Handler: + b . + +/* Supervisor中断服务函数 */ +SVC_Handler: + b . + +/* 预取终止中断服务函数 */ +PrefAbort_Handler: + b . + +/* 数据终止中断服务函数 */ +DataAbort_Handler: + b . + +/* 未使用的中断服务函数 */ +NotUsed_Handler: + b . + +/* FIQ中断服务函数 */ +FIQ_Handler: + b . + +/* IRQ中断服务函数 */ +IRQ_Handler: + push {lr} + push {r0-r3, r12} + + mrs r0, spsr + push {r0} + + mov r1, #0xA0000000 + add r1, r1, #0x20000 + add r1, r1, #0x2000 // 见RM0442_STM32MP153参考手册 P154, GICC(CIC CPU Interface) + ldr r0, [r1, #0xC] // 读CICC_IAR,获取中断ID + push {r0, r1} + cps #0x13 //进入SVC模式,允许中断嵌套 + push {lr} //保存SVC模式的lr + ldr r2, =InterruptEntry // C中断程序入口,函数入参为中断id,保存在r0中 + cpsie i + blx r2 + cpsid i + pop {lr} + cps #0x12 + pop {r0, r1} + str r0, [r1, #0x10] + + pop {r0} + msr spsr_cxsf, r0 + + pop {r0-r3, r12} + pop {lr} + subs pc, lr, #4 //设置PC指针 + +save_boot_params_ret: + /* + * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, + * except if in HYP mode already + */ + mrs r0, cpsr + and r1, r0, #0x1f @ mask mode bits + teq r1, #0x1a @ test for HYP mode + bicne r0, r0, #0x1f @ clear all mode bits + orrne r0, r0, #0x13 @ set SVC mode + orr r0, r0, #0xc0 @ disable FIQ and IRQ + msr cpsr,r0 + +/* + * Setup vector: + */ + /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ + mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register + bic r0, #(1<<13) @ V = 0 + mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register + + /* Set vector address in CP15 VBAR register */ + ldr r0, =_start + mcr p15, 0, r0, c12, c0, 0 @Set VBAR + + /* the mask ROM code should have PLL and others stable */ + bl cpu_init_cp15 + + bl _main + +raise: + b . + + +/************************************************************************* + * + * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) + * __attribute__((weak)); + * + * Stack pointer is not yet initialized at this moment + * Don't save anything to stack even if compiled with -O0 + * + *************************************************************************/ +ENTRY(save_boot_params) + b save_boot_params_ret @ back to my caller +ENDPROC(save_boot_params) + +/************************************************************************* + * + * cpu_init_cp15 + * + * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless + * CONFIG_SYS_ICACHE_OFF is defined. + * + *************************************************************************/ +ENTRY(cpu_init_cp15) + /* + * Invalidate L1 I/D + */ + mov r0, #0 @ set up for MCR + mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs + mcr p15, 0, r0, c7, c5, 0 @ invalidate icache + mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array + mcr p15, 0, r0, c7, c10, 4 @ DSB + mcr p15, 0, r0, c7, c5, 4 @ ISB + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002000 @ clear bits 13 (--V-) + bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) + orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align + orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB + orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache + mcr p15, 0, r0, c1, c0, 0 + + mov r5, lr @ Store my Caller + mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR) + mov r3, r1, lsr #20 @ get variant field + and r3, r3, #0xf @ r3 has CPU variant + and r4, r1, #0xf @ r4 has CPU revision + mov r2, r3, lsl #4 @ shift variant field for combined value + orr r2, r4, r2 @ r2 has combined CPU variant + revision + + ldr r0, =(STACK_TOP) + bic r0, r0, #7 /* 8-byte alignment for ABI compliance */ + mov sp, r0 + mov pc, r5 @ back to my caller +ENDPROC(cpu_init_cp15) + +ENTRY(data_copy) + ldr r4, =(__data_load) + ldr r5, =(__data_start) + ldr r6, =(__data_end) +copy_loop: + ldr r7, [r4] + str r7, [r5] + add r4, r4, #4 + add r5, r5, #4 + cmp r5, r6 + blt copy_loop + mov pc, lr +ENDPROC(data_copy) + +ENTRY(bss_clear) + ldr r4, =(__bss_start) + ldr r5, =(__bss_end) + mov r6, #0 +clear_loop: + str r6, [r4] + add r4, r4, #4 + cmp r4, r5 + blt clear_loop + mov pc, lr +ENDPROC(bss_clear) + +ENTRY(_main) + bl data_copy + bl bss_clear + bl main + +ENDPROC(_main) diff --git a/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/usbd_STM32MP153_HS.c b/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/usbd_STM32MP153_HS.c new file mode 100644 index 0000000000000000000000000000000000000000..5f14c383e176d7302b3d270e78a334229233c3cc --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/usbd_STM32MP153_HS.c @@ -0,0 +1,1199 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file usbd_STM32MP153_HS.c + * @author MCU Driver Team + * @brief usbd hs for STM32MP15x + */ + +#include +#include "interrupt.h" +#include "usb_def.h" +#include "usb_config.c" +#include "usbd_STM32MP153_HS.h" + +uint32_t g_outMaxPacketSize[5] = {USBD_MAX_PACKET0, 0, 0, 0, 0}; +uint8_t g_outPacketCnt[5] = {1, 0, 0, 0, 0}; +uint8_t g_inPacketCnt[5] = {1, 0, 0, 0, 0}; + +#if (USBD_HID_ENABLE == 1) +uint32_t g_hidIntInPacketData[WORD_CNT(USBD_HID_MAX_PACKET)]; +#endif + +#if (USBD_CDC_ACM_ENABLE == 1) +uint32_t g_cdcAcmIntInPacketData[WORD_CNT(USBD_CDC_ACM_MAX_PACKET)]; +#endif + +uint32_t *g_inPacketDataPtr[5] = { +/* endpoint 0 */ + 0, +/* endpoint 1 */ +#if ((USBD_HID_ENABLE == 1) && (USBD_HID_EP_INTIN == 1)) + g_hidIntInPacketData, +#elif ((USBD_CDC_ACM_ENABLE == 1) && (USBD_CDC_ACM_EP_INTIN == 1)) + g_cdcAcmIntInPacketData, +#else + 0, +#endif +/* endpoint 2 */ +#if ((USBD_HID_ENABLE == 1) && (USBD_HID_EP_INTIN == 2)) + g_hidIntInPacketData, +#elif ((USBD_CDC_ACM_ENABLE == 1) && (USBD_CDC_ACM_EP_INTIN == 2)) + g_cdcAcmIntInPacketData, +#else + 0, +#endif +/* endpoint 3 */ +#if ((USBD_HID_ENABLE == 1) && (USBD_HID_EP_INTIN == 3)) + g_hidIntInPacketData, +#elif ((USBD_CDC_ACM_ENABLE == 1) && (USBD_CDC_ACM_EP_INTIN == 3)) + g_cdcAcmIntInPacketData, +#else + 0, +#endif +/* endpoint 4 */ +#if ((USBD_HID_ENABLE == 1) && (USBD_HID_EP_INTIN == 4)) + g_hidIntInPacketData, +#elif ((USBD_CDC_ACM_ENABLE == 1) && (USBD_CDC_ACM_EP_INTIN == 4)) + g_cdcAcmIntInPacketData, +#else + 0, +#endif +}; + +uint32_t g_inPacketDataCnt[5] = {0}; +uint32_t g_inPacketDataReady = 0; +uint32_t g_syncWriteEp = 0; + +/* Get USB Device Out packet counter + * + * Return Value: out packet counter + */ +static inline uint32_t USBD_OutPktCnt(uint32_t epNum) +{ + return (USBX_OUTEP(epNum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_PKTCNT) >> USB_OTG_DOEPTSIZ_PKTCNT_Pos; +} + +/* Get USB Device setup packet counter + * + * Return Value: setup packet counter + */ +static inline uint32_t USBD_SetupPktCnt(uint32_t epNum) +{ + return (USBX_OUTEP(epNum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_STUPCNT) >> USB_OTG_DOEPTSIZ_STUPCNT_Pos; +} + +/* + * USB Device Interrupt enable + * Called by USBD_Init to enable the USB Interrupt + * Return Value: None + */ +void USBD_IntrEna(void) +{ + IRQ_Enable(OTG_IRQn, OTG_INT_LEVEL, OTG_HS_IRQHandler); +} + +/* + * Get USB device phyc pll params + * Called by USBD_PhycPllInit + * Return Value: None + */ +static void USBD_PhycGetPllParams(uint32_t clkRate, PllParams *pllParams) +{ +#define PLL_FVCO 2880 +#define FACTOR (1 << 16) + unsigned long long fvco; + unsigned long long ndiv; + unsigned long long frac; + + /* + * | FVCO = INFF*2*(NDIV + FRACT/2^16 ) when DITHER_DISABLE[1] = 1 + * | FVCO = 2880MHz + * | NDIV = integer part of input bits to set the LDF + * | FRACT = fractional part of input bits to set the LDF + * => PLLNDIV = integer part of (FVCO / (INFF*2)) + * => PLLFRACIN = fractional part of(FVCO / INFF*2) * 2^16 + * <=> PLLFRACIN = ((FVCO / (INFF*2)) - PLLNDIV) * 2^16 + */ + fvco = (unsigned long long)PLL_FVCO * MHZ; /* In Hz */ + + ndiv = fvco; + ndiv /= (clkRate * 2); // multi * 2 + pllParams->ndiv = (uint8_t)ndiv; + + frac = fvco * FACTOR; + frac /= (clkRate * 2); // multi * 2 + frac -= (ndiv * FACTOR); + pllParams->frac = (uint16_t)frac; +} + +/* + * Get USB device phyc pll Init + * Called by USBD_Init + * Return Value: None + */ +static void USBD_PhycPllInit(void) +{ + const uint32_t clkRate = USBD_CLK_RATE; + uint32_t usbPhycPll; + PllParams pllPara; + + USBD_PhycGetPllParams(clkRate, &pllPara); + + /* Disable pll */ + USBPHYC->PLL &= ~USBPHYC_PLLEN; + + /* Calc Pll */ + usbPhycPll = USBPHYC_PLLDITHEN1 | USBPHYC_PLLDITHEN0 | USBPHYC_PLLSTRBYP; + usbPhycPll |= ((pllPara.ndiv << PLLNDIV_SHIFT) & PLLNDIV); + if (pllPara.frac) { + usbPhycPll |= PLLFRACCTL; + usbPhycPll |= ((pllPara.frac << PLLFRACIN_SHIFT) & PLLFRACIN); + } + /* Set Pll */ + USBPHYC->PLL = usbPhycPll; + HAL_Delay(1); + + /* Enable pll */ + USBPHYC->PLL |= USBPHYC_PLLEN; + if (!(USBPHYC->PLL & USBPHYC_PLLEN)) { + return; + } + HAL_Delay(1); + return; +} + +/* + * USB Device Rcc Config + * Called by the USBD_Init + * Return Value: None + */ +static void USBD_RccConfig(void) +{ + RCC->USBCKSELR = RCC_USBCKSELR_USBOSRC; // USBPHYSRC=0, hse_ker_ck clock + + RCC->MP_APB4ENSETR |= RCC_MP_APB4ENSETR_USBPHYEN; + HAL_Delay(10); /* Wait ~10 ms */ + RCC->APB4RSTSETR |= RCC_APB4RSTSETR_USBPHYRST; + HAL_Delay(10); /* Wait ~10 ms */ + RCC->APB4RSTCLRR |= RCC_APB4RSTCLRR_USBPHYRST; /* Reset OTG HS clock */ + HAL_Delay(10); /* Wait ~10 ms */ + RCC->MP_APB4ENSETR |= RCC_MP_APB4ENSETR_USBPHYEN; + HAL_Delay(10); /* Wait ~10 ms */ + RCC->MC_APB4ENSETR |= RCC_MC_APB4ENSETR_USBPHYEN; + HAL_Delay(10); /* Wait ~10 ms */ + RCC->MP_APB4LPENSETR |= RCC_MP_APB4LPENSETR_USBPHYLPEN; + HAL_Delay(10); /* Wait ~10 ms */ + + RCC->MP_AHB2ENSETR |= RCC_MP_AHB2ENSETR_USBOEN; + HAL_Delay(10); /* Wait ~10 ms */ + RCC->AHB2RSTSETR |= RCC_AHB2RSTSETR_USBORST; + HAL_Delay(10); /* Wait ~10 ms */ + RCC->AHB2RSTCLRR |= RCC_AHB2RSTCLRR_USBORST; /* Reset OTG HS clock */ /* H743, USB1OTGRST */ + HAL_Delay(10); /* Wait ~10 ms */ + + RCC->MP_AHB2ENSETR |= RCC_MP_AHB2ENSETR_USBOEN; + HAL_Delay(10); /* Wait ~10 ms */ + RCC->MC_AHB2ENSETR |= RCC_MC_AHB2ENSETR_USBOEN; // USBOLPEN + HAL_Delay(10); /* Wait ~10 ms */ + RCC->MP_AHB2LPENSETR |= RCC_MP_AHB2LPENSETR_USBOLPEN; // USBOLPEN + HAL_Delay(10); /* Wait ~10 ms */ +} + +/* + * Wait USB Device AHB master is idle + * Called by USBD_Init + * Return Value: None + */ +static inline void USBD_WatiAhbIdle(void) +{ + int32_t tout = 1000; // Wait max 1000 ms for AHBIDL = 0 + while (!(OTG->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) && (tout-- > 0)) { + HAL_Delay(1); // Wait 1 ms + } +} + +/* + * USB Device OTG reset + * Called by USBD_Init + * Return Value: None + */ +static inline void USBD_OtgReset(void) +{ + int32_t tout = 1000; // Wait max 1000 ms for CRST = 0 + OTG->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; + while ((OTG->GRSTCTL & USB_OTG_GRSTCTL_CSRST) && (tout-- > 0)) { + HAL_Delay(1); // Wait 1 ms + } + HAL_Delay(3); // Wait 3 ms +} + +/* + * USB Device Wait Global out nak config effective + * Called by USBD_Init + * Return Value: None + */ +static inline void USBD_WaitGlobalOutNakEffective(void) +{ + int32_t wcnt = 1000; /* Up to 1000 attempts */ + while (!(OTG->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF)) { + // wait until global NAK + if ((wcnt--) == 0) { + break; + } + } +} + +/* + * USB Device Wait Global out nak config effective + * Called by USBD_DisableEP + * Parameters: epNum: Device Endpoint Number + * epNum.0..3: Address + * epNum.7: Dir + * Return Value: None + */ +static inline void USBD_WaitEndpointInterruptDisabled(U32 epNum) +{ + int32_t wcnt = 1000; /* Up to 1000 attempts */ + while (!(USBX_OUTEP(epNum)->DOEPINT & USB_OTG_DOEPINT_EPDISD)) { + // wait until EP disabled + if ((wcnt--) == 0) { + break; + } + } +} + +/* + * ReInit Tx/Rx/non-periodicc Tx Fifo Size + * Called by USBD_Init + * Return Value: None + */ +static void USBD_FifoSizeReInit(void) +{ + uint32_t fifoOffset; + uint16_t fifoSize[] = { + TX1_FIFO_SIZE, TX2_FIFO_SIZE, TX3_FIFO_SIZE, TX4_FIFO_SIZE + }; + + /* Set Rx Fifo Size */ + OTG->GRXFSIZ = RX_FIFO_SIZE / sizeof(int); + /* Set host non-periodic transmit FIFO */ + OTG->DIEPTXF0_HNPTXFSIZ = (RX_FIFO_SIZE / sizeof(int)) | HIGH_HALF_WORD(TX0_FIFO_SIZE / sizeof(int)); + + OTG->DIEPTXF[0] = + ((RX_FIFO_SIZE + TX0_FIFO_SIZE) / sizeof(int)) | (HIGH_HALF_WORD(TX1_FIFO_SIZE /sizeof(int))); + + /* DIEPTXF1 */ + OTG->DIEPTXF[1] = ((RX_FIFO_SIZE + TX0_FIFO_SIZE + TX1_FIFO_SIZE) / sizeof(int)) | + (HIGH_HALF_WORD(TX2_FIFO_SIZE / sizeof(int))); + + /* DIEPTXF2 */ + OTG->DIEPTXF[2] = + ((RX_FIFO_SIZE + TX0_FIFO_SIZE + TX1_FIFO_SIZE + TX2_FIFO_SIZE) / sizeof(int)) | + (HIGH_HALF_WORD(TX3_FIFO_SIZE / sizeof(int))); + + /* DIEPTXF3 */ + OTG->DIEPTXF[3] = ((RX_FIFO_SIZE + TX0_FIFO_SIZE + TX1_FIFO_SIZE + + TX2_FIFO_SIZE + TX3_FIFO_SIZE) /sizeof(int)) | + (HIGH_HALF_WORD(TX4_FIFO_SIZE / sizeof(int))); +} + +/* + * Synchronous Write USB Device Endpoint Data to intermediate Buffer and synchronously + * transferred to FIFO on next NAK event. + * Parameters: epNum: Device Endpoint Number + * epNum.0..3: Address + * epNum.7: Dir + * pData: Pointer to Data Buffer + * cnt: Number of bytes to write + * Return Value: Number of bytes written + */ +static uint32_t USBD_SynWriteToBuffer(U32 epNum, U8 *pData, U32 cnt) +{ + /* + get space in Ep TxFIFO + Reset the IN endpoint if we can't get enough space. Usually this + means something goes wrong on this endpoint and usb host stops + sending IN token. + */ + uint32_t startTs = HAL_GetTick(); + uint32_t curTs; + uint32_t delta; + + /* Wait until the FIFO has sufficient space to receive data. */ + while ((cnt > 0) && ((USBX_INEP(epNum)->DTXFSTS * sizeof(int)) < cnt)) { + curTs = HAL_GetTick(); + delta = (curTs >= startTs) ? (curTs - startTs) : 0xFFFFFFFF - startTs + curTs; + if (delta >= TXFIFO_WAIT_TIMEOUT_MS) { + USBD_ResetEP(epNum | USB_ENDPOINT_DIRECTION_MASK); + return 0; + } + } + + /* set transfer size and packet count */ + USBX_INEP(epNum)->DIEPTSIZ = cnt | + (g_inPacketCnt[epNum] << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | + (g_inPacketCnt[epNum] << USB_OTG_DIEPTSIZ_MULCNT_Pos); + + /* enable ep and clear NAK */ + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK; + if (cnt) { + uint32_t val = WORD_CNT(cnt); + while (val--) { + /* copy data to endpoint TxFIFO */ + USBX_DFIFO((uint32_t)epNum) = __UNALIGNED_UINT32_READ(pData); + pData += sizeof(int); + } + } + g_inPacketDataReady &= ~(1 << epNum); + return cnt; +} + + +/* + * Asynchronous Write USB Device Endpoint Data to intermediate Buffer and synchronously + * transferred to FIFO on next NAK event. + * Parameters: epNum: Device Endpoint Number + * epNum.0..3: Address + * epNum.7: Dir + * pData: Pointer to Data Buffer + * cnt: Number of bytes to write + * Return Value: Number of bytes written + */ +static uint32_t USBD_AsynWriteToBuffer(U32 epNum, U8 *pData, U32 cnt) +{ + U32 *ptr = g_inPacketDataPtr[epNum]; + uint32_t val = WORD_CNT(cnt); + + if ((g_inPacketDataReady & (1 << epNum)) != 0) { /* already, done */ + return 0; + } + g_inPacketDataCnt[epNum] = cnt; /* save Data size */ + while (val) { + // save data to intermediate buffer + *ptr++ = *((U32 *)pData); + pData += sizeof(U32); + --val; + } + g_inPacketDataReady |= 1 << epNum; + // Set NAK to enable interrupt on NAK + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK; + // INEPNEM = 1, IN EP NAK efective msk + USBX_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_INEPNEM; + return cnt; +} + +/* + * USB Device Initialize Function + * Called by the User to initialize USB + * Return Value: None + */ +void USBD_Init(void) +{ + USBD_RccConfig(); + USBD_IntrEna(); + USBD_PhycPllInit(); + USBPHYC->MISC = 0; // 0x0:No clock gating. PHY dedicated 60 MHz Port1/Port2 clocks are always delivered to + // target controller. PHY 48 MHz output clock is always delivered to target controller + +#ifdef __OTG_HS_EMBEDDED_PHY + OTG->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; +#endif + HAL_Delay(20); // Wait ~20 ms + USBD_WatiAhbIdle(); + USBD_OtgReset(); + + OTG->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT; // Disable interrupts + // No VBUS sensing + // ToDo(elee): do we want this disabled? + OTG->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + USBX_DEVICE->DCTL |= USB_OTG_DCTL_SDIS; // soft disconnect enabled + + // Force device mode + OTG->GUSBCFG = USB_OTG_GUSBCFG_FDMOD | + USB_OTG_GUSBCFG_TRDT_3 | + USB_OTG_GUSBCFG_TRDT_0 | + USB_OTG_GUSBCFG_TOCAL; + HAL_Delay(100); // Wait min 25 ms, we wait ~100 ms + +#ifndef __OTG_HS_EMBEDDED_PHY + USBX_DEVICE->DCFG &= ~USB_OTG_DCFG_DSPD; // High speed phy +#else + USBX_DEVICE->DCFG &= ~USB_OTG_DCFG_DSPD; // Full speed phy +#endif + HAL_Delay(2); // Wait 2 ms + + OTG->GINTMSK = + USB_OTG_GINTMSK_USBSUSPM | // suspend int unmask + USB_OTG_GINTMSK_USBRST | // reset int unmask + USB_OTG_GINTMSK_ENUMDNEM | // enumeration done int unmask + USB_OTG_GINTMSK_RXFLVLM | // receive fifo non-empty int unmask + USB_OTG_GINTMSK_IEPINT | // IN EP int unmask + USB_OTG_GINTMSK_OEPINT | // OUT EP int unmask + USB_OTG_GINTMSK_WUIM | // resume int unmask + ((USBD_P_SOF_Event != 0) ? USB_OTG_GINTMSK_SOFM : 0); // SOF int unmask + OTG->GAHBCFG |= USB_OTG_GAHBCFG_GINT | + USB_OTG_GAHBCFG_HBSTLEN_0 | + USB_OTG_GAHBCFG_HBSTLEN_1 | + USB_OTG_GAHBCFG_TXFELVL; +} + +/* + * USB Device Connect Function + * Called by the User to Connect/Disconnect USB Device + * Parameters: con: Connect/Disconnect + * Return Value: None + */ + +void USBD_Connect(BOOL con) +{ + if (con) { +#ifdef __OTG_HS_EMBEDDED_PHY + OTG->GCCFG &= ~USB_OTG_GCCFG_PWRDWN; // power down activated +#endif + USBX_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS; // soft disconnect disabled + } else { + USBX_DEVICE->DCTL |= USB_OTG_DCTL_SDIS; // soft disconnect enabled +#ifdef __OTG_HS_EMBEDDED_PHY + OTG->GCCFG |= USB_OTG_GCCFG_PWRDWN; // power down deactivated +#endif + } +} + +/* + * USB Device Reset Function + * Called automatically on USB Device Reset + * Return Value: None + */ + +void USBD_Reset(void) +{ + g_syncWriteEp = 0; + g_inPacketDataReady = 0; + USBX_DEVICE->DOEPMSK = 0; + USBX_DEVICE->DIEPMSK = 0; + + for (uint32_t i = 0; i < (USBD_EP_NUM + 1); i++) { + if (USBX_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) { + // OUT EP disable, Set NAK + USBX_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK; + } + if (USBX_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) { + // IN EP disable, Set NAK + USBX_INEP(i)->DIEPCTL = + USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK; + } + + USBX_INEP(i)->DIEPINT = 0x1B; + USBX_OUTEP(i)->DOEPINT = 0x1B; // clear OUT Ep interrupts + } + + USBD_SetAddress(0, 1); + + USBX_DEVICE->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | // unmask IN&OUT EP0 interruts + (1 << USB_OTG_DAINTMSK_IEPM_Pos); + USBX_DEVICE->DOEPMSK = USB_OTG_DOEPMSK_STUPM | // setup phase done + USB_OTG_DOEPMSK_EPDM | // endpoint disabled + USB_OTG_DOEPMSK_XFRCM; // transfer complete + USBX_DEVICE->DIEPMSK = USB_OTG_DIEPMSK_EPDM | // endpoint disabled + USB_OTG_DIEPMSK_XFRCM; // transfer completed + + USBD_FifoSizeReInit(); /* ReInit Fifo Size registers */ + + USBX_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT_0 | // setup count = 1 + (1 << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | // packet count + USBD_MAX_PACKET0; +} + +/* + * USB Device Suspend Function + * Called automatically on USB Device Suspend + * Return Value: None + */ + +void USBD_Suspend(void) {} + +/* + * USB Device Resume Function + * Called automatically on USB Device Resume + * Return Value: None + */ + +void USBD_Resume(void) {} + +/* + * USB Device Remote Wakeup Function + * Called automatically on USB Device Remote Wakeup + * Return Value: None + */ + +void USBD_WakeUp(void) +{ + USBX_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG; // remote wakeup signaling + HAL_Delay(5); // Wait ~5 ms + USBX_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; +} + +/* + * USB Device Remote Wakeup Configuration Function + * Parameters: cfg: Device Enable/Disable + * Return Value: None + */ + +void USBD_WakeUpCfg(BOOL cfg) +{ +} + +/* + * USB Device Set Address Function + * Parameters: adr: USB Device Address + * Return Value: None + */ + +void USBD_SetAddress(U32 adr, U32 setup) +{ + if (setup) { + USBX_DEVICE->DCFG = (USBX_DEVICE->DCFG & ~USB_OTG_DCFG_DAD) | + (adr << USB_OTG_DCFG_DAD_Pos); + } +} + +/* + * USB Device Flush IN Endpoint Transmit Fifo + * Parameters: adr: USB Device Address + * Return Value: None + */ +static void USBD_FlushInEpFifo(uint32_t epNum) +{ + uint32_t wcnt; + + epNum &= ~USB_ENDPOINT_DIRECTION_MASK; + OTG->GRSTCTL = (OTG->GRSTCTL & ~USB_OTG_GRSTCTL_TXFNUM) | + (epNum << USB_OTG_GRSTCTL_TXFNUM_Pos) | + USB_OTG_GRSTCTL_TXFFLSH; + /* wait until fifo is flushed 10 cnt */ + wcnt = 10; + while (OTG->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) { + if ((wcnt--) == 0) { + break; + } + } +} + +/* + * USB Device Configure Function + * Parameters: cfg: Device Configure/Deconfigure + * Return Value: None + */ + +void USBD_Configure(BOOL cfg) +{ + g_inPacketDataReady &= ~1UL; +} + +/* + * Configure USB Device Endpoint according to Descriptor + * Parameters: pEPD: Pointer to Device Endpoint Descriptor + * Return Value: None + */ + +void USBD_ConfigEP(USB_ENDPOINT_DESCRIPTOR *pEPD) +{ + uint32_t num; + uint32_t val; + uint32_t type; + + num = pEPD->bEndpointAddress & ~(USB_ENDPOINT_DIRECTION_MASK); + val = pEPD->wMaxPacketSize; + type = pEPD->bmAttributes & USB_ENDPOINT_TYPE_MASK; + + if (pEPD->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) { + g_inPacketCnt[num] = 1; + + USBX_DEVICE->DAINTMSK |= (1 << num); // unmask IN EP int + USBX_INEP(num)->DIEPCTL = (num << USB_OTG_DIEPCTL_TXFNUM_Pos) | // fifo number + (type << USB_OTG_DIEPCTL_EPTYP_Pos) | // ep type + (val & USB_OTG_DIEPCTL_MPSIZ); // max packet size + if ((type == USB_ENDPOINT_TYPE_BULK) || (type == USB_ENDPOINT_TYPE_INTERRUPT)) { + // if interrupt or bulk EP + USBX_INEP(num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; + } + } else { + g_outMaxPacketSize[num] = val & USB_OTG_DOEPCTL_MPSIZ; + g_outPacketCnt[num] = 1; + + USBX_DEVICE->DAINTMSK |= (1 << (num + USB_OTG_DAINTMSK_OEPM_Pos)); // unmask OUT EP int + + USBX_OUTEP(num)->DOEPCTL = (type << USB_OTG_DOEPCTL_EPTYP_Pos) | // EP type + (val & USB_OTG_DOEPCTL_MPSIZ); // max packet size + + USBX_OUTEP(num)->DOEPTSIZ = (g_outPacketCnt[num] << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | // packet count + (val & USB_OTG_DOEPCTL_MPSIZ); // transfer size + if ((type == USB_ENDPOINT_TYPE_BULK) || (type == USB_ENDPOINT_TYPE_INTERRUPT)) { + // if int or bulk EP + USBX_OUTEP(num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; + } + } +} + +/* + * Set Direction for USB Device Control Endpoint + * Parameters: dir: Out (dir == 0), In (dir <> 0) + * Return Value: None + */ + +void USBD_DirCtrlEP(U32 dir) +{ +} + +/* + * Enable USB Device Endpoint + * Parameters: epNum: Device Endpoint Number + * epNum.0..3: Address + * epNum.7: Dir + * Return Value: None + */ + +void USBD_EnableEP(U32 epNum) +{ + if (epNum & USB_ENDPOINT_DIRECTION_MASK) { + epNum &= ~USB_ENDPOINT_DIRECTION_MASK; + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_USBAEP | // EP active + USB_OTG_DIEPCTL_SNAK; // set EP NAK + if (USBX_INEP(epNum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) { + // disable EP + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS; + } + + g_inPacketDataReady &= ~(1 << epNum); + } else { + USBX_OUTEP(epNum)->DOEPCTL |= USB_OTG_DOEPCTL_USBAEP | // EP active + USB_OTG_DOEPCTL_EPENA | // enable EP + USB_OTG_DOEPCTL_CNAK; // clear EP NAK + } +} + +/* + * Disable USB Endpoint + * Parameters: epNum: Endpoint Number + * epNum.0..3: Address + * epNum.7: Dir + * Return Value: None + */ + +void USBD_DisableEP(U32 epNum) +{ + // Disable IN Endpoint + if (epNum & USB_ENDPOINT_DIRECTION_MASK) { + epNum &= ~USB_ENDPOINT_DIRECTION_MASK; + g_inPacketDataReady &= ~(1 << epNum); + + if (USBX_INEP(epNum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) { + // disable EP + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS; + } + // set EP NAK + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK; + // deactivate EP + USBX_INEP(epNum)->DIEPCTL &= ~USB_OTG_DIEPCTL_USBAEP; + } else { + // Disable OUT Endpoint + // set global out nak + USBX_DEVICE->DCTL |= USB_OTG_DCTL_SGONAK; + + USBD_WaitGlobalOutNakEffective(); + + if (USBX_OUTEP(epNum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) { + // disable EP + USBX_OUTEP(epNum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS; + } + // set EP NAK + USBX_OUTEP(epNum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK; + // deactivate EP + USBX_OUTEP(epNum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP; + + USBD_WaitEndpointInterruptDisabled(epNum); + // clear global nak + USBX_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK; + } +} + +/* + * Reset USB Device Endpoint + * Parameters: epNum: Device Endpoint Number + * epNum.0..3: Address + * epNum.7: Dir + * Return Value: None + */ + +void USBD_ResetEP(U32 epNum) +{ + // Reset IN Endpoint + if (epNum & USB_ENDPOINT_DIRECTION_MASK) { + epNum &= ~USB_ENDPOINT_DIRECTION_MASK; + g_inPacketDataReady &= ~(1 << epNum); + if (USBX_INEP(epNum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) { + // disable EP + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS; + } + // set EP NAK + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK; + + // Flush endpoint fifo + USBD_FlushInEpFifo(epNum | USB_ENDPOINT_DIRECTION_MASK); + } +} + +/* + * Set Stall for USB Device Endpoint + * Parameters: epNum: Device Endpoint Number + * epNum.0..3: Address + * epNum.7: Dir + * Return Value: None + */ + +void USBD_SetStallEP(U32 epNum) +{ + if (!(epNum & USB_ENDPOINT_DIRECTION_MASK)) { + // Stall OUT Endpoint + + // set global out nak + USBX_DEVICE->DCTL |= USB_OTG_DCTL_SGONAK; + + USBD_WaitGlobalOutNakEffective(); // set global out nak + + if (USBX_OUTEP(epNum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) { + // disable EP + USBX_OUTEP(epNum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS; + } + // set stall + USBX_OUTEP(epNum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL; + USBD_WaitEndpointInterruptDisabled(epNum); + + // clear global nak + USBX_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK; + } else { + // Stall IN endpoint + epNum &= ~USB_ENDPOINT_DIRECTION_MASK; + if (USBX_INEP(epNum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) { + // disable endpoint + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS; + } + // set stall + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL; + + USBD_FlushInEpFifo(epNum | USB_ENDPOINT_DIRECTION_MASK); + } +} + +/* + * Clear Stall for USB Device Endpoint + * Parameters: epNum: Device Endpoint Number + * epNum.0..3: Address + * epNum.7: Dir + * Return Value: None + */ + +void USBD_ClrStallEP(U32 epNum) +{ + if (!(epNum & USB_ENDPOINT_DIRECTION_MASK)) { + // Clear OUT endpoint Stall + if (EP_OUT_TYPE(epNum) > USB_ENDPOINT_TYPE_ISOCHRONOUS) { + // if EP type Bulk or Interrupt + // Set DATA0 PID + USBX_OUTEP(epNum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; + // Clear stall + USBX_OUTEP(epNum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; + } + } else { + // Clear IN Endpoint Stall + epNum &= ~USB_ENDPOINT_DIRECTION_MASK; + + if (USBX_INEP(epNum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) { + // disable endpoint + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS; + } + + // Flush endpoint fifo + USBD_FlushInEpFifo(epNum | USB_ENDPOINT_DIRECTION_MASK); + + if (EP_IN_TYPE(epNum) > USB_ENDPOINT_TYPE_ISOCHRONOUS) { + // if Interrupt or bulk EP, Set DATA0 PID + USBX_INEP(epNum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; + } + + // clear Stall + USBX_INEP(epNum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; + } +} + +/* + * Clear USB Device Endpoint Buffer + * Parameters: epNum: Device Endpoint Number + * epNum.0..3: Address + * epNum.7: Dir + * Return Value: None + */ +void USBD_ClearEPBuf(U32 epNum) +{ + if (epNum & USB_ENDPOINT_DIRECTION_MASK) { + USBD_FlushInEpFifo(epNum | USB_OTG_GRSTCTL_RXFFLSH); + } else { + OTG->GRSTCTL |= USB_OTG_GRSTCTL_RXFFLSH; + /* delay 4x4 nop */ + for (int i = 0; i < 4; i++) { + __NOP(); + } + } +} + +/* + * Read USB Device Endpoint Data + * Parameters: epNum: Device Endpoint Number + * epNum.0..3: Address + * epNum.7: Dir + * pData: Pointer to Data Buffer + * Return Value: Number of bytes read + */ + +uint32_t USBD_ReadEP(U32 epNum, U8 *pData, uint32_t bufsz) +{ + U32 val; + U32 sz; + + if ((USBX_OUTEP(epNum)->DOEPCTL & USB_OTG_DOEPCTL_USBAEP) == 0) { + // if Ep not active + return (0); + } + + sz = (OTG->GRXSTSP & USB_OTG_BCNT_Msk) >> USB_OTG_BCNT_Pos; // get available data size + + /* elee: copy from the f103 code, tbd, still required? + Commit 5ffac262f, and 3d1a68b768c57cb403bab9d5598f3e9f1d3506a2 (for the + core) If smaller data is read here, is the rest of the data pulled in + later? */ + if (sz > bufsz) { + sz = bufsz; + } + + // copy data from fifo if Isochronous Ep: data is copied to intermediate buffer + for (val = 0; val < (uint32_t)WORD_CNT(sz); val++) { + __UNALIGNED_UINT32_WRITE(pData, USBX_DFIFO(0U)); + pData += sizeof(int); + } + + // wait RxFIFO non-empty (OUT transfer completed or Setup trans. completed) + while ((OTG->GINTSTS & USB_OTG_GINTMSK_RXFLVLM) == 0) { + } + OTG->GRXSTSP; + OTG->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; // unmask RxFIFO non-empty interrupt + + return (sz); +} + +/* + * Write USB Device Endpoint Data + * If write was requested synchronously from IRQ then data is written to FIFO + * directly else data is written to the intermediate buffer and synchronously + * transferred to FIFO on next NAK event. + * Parameters: epNum: Device Endpoint Number + * epNum.0..3: Address + * epNum.7: Dir + * pData: Pointer to Data Buffer + * cnt: Number of bytes to write + * Return Value: Number of bytes written + */ + +uint32_t USBD_WriteEP(U32 epNum, U8 *pData, U32 cnt) +{ + epNum &= ~USB_ENDPOINT_DIRECTION_MASK; + + if ((USBX_INEP(epNum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0) { + // if Ep not active + return (0); + } + + /* Asynchronous write to intermediate buffer */ + if (!g_syncWriteEp && g_inPacketDataPtr[epNum]) { + return USBD_AsynWriteToBuffer(epNum, pData, cnt); + } else { + return USBD_SynWriteToBuffer(epNum, pData, cnt); + } +} + +/* + * Get USB Device Last Frame Number + * Parameters: None + * Return Value: Frame Number + */ + +uint32_t USBD_GetFrame(void) +{ + return (USBX_DEVICE->DSTS & USB_OTG_DSTS_FNSOF) >> USB_OTG_DSTS_FNSOF_Pos; +} + +/* + * USB Device Interrupt Service Routine + */ +void OTG_HS_IRQHandler(void) +{ + GIC_DisableIRQ(OTG_IRQn); + USBD_SignalHandler(); +} + +void USBD_ResetProcess(void) +{ + USBD_Reset(); + usbd_reset_core(); +#ifdef __RTX + if (USBD_RTX_DevTask) { + isr_evt_set(USBD_EVT_RESET, USBD_RTX_DevTask); + } +#else + if (USBD_P_Reset_Event) { + USBD_P_Reset_Event(); + } +#endif + OTG->GINTSTS = USB_OTG_GINTSTS_USBRST; +} + +static unsigned int FindNextEpIndex(unsigned int *start, unsigned int *mask) +{ + unsigned int i; + unsigned int num = 0; + + for (i = *start; i < (USBD_EP_NUM + 1); i++) { + if ((*mask & (1 << i)) != 0) { + num = i; + *mask &= ~(1 << i); + break; + } + } + *start = i; + return num; +} + +static void USBD_SuspendProcess(void) +{ + USBD_Suspend(); +#ifdef __RTX + if (USBD_RTX_DevTask) { + isr_evt_set(USBD_EVT_SUSPEND, USBD_RTX_DevTask); + } +#else + if (USBD_P_Suspend_Event) { + USBD_P_Suspend_Event(); + } +#endif + OTG->GINTSTS = USB_OTG_GINTSTS_USBSUSP; +} + +static void USBD_ResumeProcess(void) +{ + USBD_Resume(); +#ifdef __RTX + if (USBD_RTX_DevTask) { + isr_evt_set(USBD_EVT_RESUME, USBD_RTX_DevTask); + } +#else + if (USBD_P_Resume_Event) { + USBD_P_Resume_Event(); + } +#endif + OTG->GINTSTS = USB_OTG_GINTSTS_WKUINT; +} + +static void USBD_SpeedEnumDoneProcess(void) +{ + if (!((USBX_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) >> USB_OTG_DSTS_ENUMSPD_Pos)) { + USBD_HighSpeed = 1; + } + USBX_INEP(0)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ; + USBX_INEP(0)->DIEPCTL |= g_outMaxPacketSize[0]; /* EP0 max packet */ + USBX_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK; // clear global IN NAK + USBX_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK; // clear global OUT NAK + OTG->GINTSTS |= USB_OTG_GINTSTS_ENUMDNE; +} + +static void USBD_StartFrameProcess(void) +{ +#ifdef __RTX + if (USBD_RTX_DevTask) { + isr_evt_set(USBD_EVT_SOF, USBD_RTX_DevTask); + } +#else + if (USBD_P_SOF_Event) { + USBD_P_SOF_Event(); + } +#endif + OTG->GINTSTS = USB_OTG_GINTSTS_SOF; +} + +static void USBD_RxDataProcess(void) +{ + uint32_t val = OTG->GRXSTSR; + uint32_t num = val & USB_OTG_GRXSTSP_EPNUM; + + switch ((val & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) { + // setup packet + case OTG_GRXSTSR_PKTSTS_SETUP_DATA_PKT: + OTG->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM; + if (USBD_P_EP[num]) { + USBD_P_EP[num](USBD_EVT_SETUP); + } + break; + + // OUT packet + case OTG_GRXSTSR_PKTSTS_OUT_DATA_PKT: + OTG->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM; + if (USBD_P_EP[num]) { + USBD_P_EP[num](USBD_EVT_OUT); + } + break; + default: + OTG->GRXSTSP; + break; + } +} + +static void USBD_OutEndPointInterruptProcess(void) +{ + unsigned int mask; + unsigned int i = 0; + + /* process all endpoint with interrupt */ + mask = ((USBX_DEVICE->DAINT & USBX_DEVICE->DAINTMSK) & USB_OTG_DAINTMSK_OEPM) >> USB_OTG_DAINTMSK_OEPM_Pos; + while (mask != 0) { + unsigned int num = FindNextEpIndex(&i, &mask); /* Find EpNum */ + // Endpoint disabled + if (USBX_OUTEP(num)->DOEPINT & USB_OTG_DOEPINT_EPDISD) { + USBX_OUTEP(num)->DOEPINT |= USB_OTG_DOEPINT_EPDISD; + } + + // Transfer complete interrupt + if ((USBX_OUTEP(num)->DOEPINT & USB_OTG_DOEPINT_XFRC) | (USBX_OUTEP(num)->DOEPINT & USB_OTG_DOEPINT_STUP)) { + USBX_OUTEP(num)->DOEPTSIZ = + (g_outPacketCnt[num] << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | /* packet count */ + (g_outMaxPacketSize[num]); /* transfer size */ + if (num == 0) { + USBX_OUTEP(0)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT_0; + } + USBX_OUTEP(num)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; + USBX_OUTEP(num)->DOEPINT |= USB_OTG_DOEPINT_XFRC; + } + } +} + +static void USBD_InEndPointNakProcess(unsigned int epNum) +{ + g_syncWriteEp = 1; + USBD_WriteEP(epNum, (uint8_t *)g_inPacketDataPtr[epNum], + g_inPacketDataCnt[epNum]); + g_syncWriteEp = 0; + if (!g_inPacketDataReady) { + // No more pending IN transfers and disable IN NAK interrupts + USBX_DEVICE->DIEPMSK &= ~USB_OTG_DIEPMSK_INEPNEM; + } +} + +static void USBD_InEndPointInterruptProcess(void) +{ + unsigned int mask; + unsigned int i = 0; + + /* process all endpoint with interrupt */ + mask = (USBX_DEVICE->DAINT & USBX_DEVICE->DAINTMSK & USB_OTG_DAINTMSK_IEPM); + while (mask != 0) { + unsigned int num = FindNextEpIndex(&i, &mask); + // Endpoint disabled + if (USBX_INEP(num)->DIEPINT & USB_OTG_DIEPINT_EPDISD) { + USBX_INEP(num)->DIEPINT = USB_OTG_DIEPINT_EPDISD; + } + + // IN endpoint NAK effective + if (USBX_INEP(num)->DIEPINT & USB_OTG_DIEPINT_INEPNE) { + if ((g_inPacketDataPtr[num] != 0) && + ((g_inPacketDataReady & (1 << num)) != 0)) { + USBD_InEndPointNakProcess(num); + continue; + } else { + USBX_INEP(num)->DIEPCTL |= USB_OTG_DIEPCTL_CNAK; + } + USBX_INEP(num)->DIEPINT = USB_OTG_DIEPINT_INEPNE; + } + + // Transmit completed + if (USBX_INEP(num)->DIEPINT & USB_OTG_DIEPINT_XFRC) { + USBX_INEP(num)->DIEPINT = USB_OTG_DIEPINT_XFRC; + g_syncWriteEp = 1; + if (USBD_P_EP[num]) { + USBD_P_EP[num](USBD_EVT_IN); + } + g_syncWriteEp = 0; + } + } +} + +/* + * USB Handler Process + */ +void USBD_Handler(void) +{ + uint32_t istr = OTG->GINTSTS & OTG->GINTMSK; + + // reset interrupt + if (istr & USB_OTG_GINTSTS_USBRST) { + USBD_ResetProcess(); + } + + // suspend interrupt + if (istr & USB_OTG_GINTSTS_USBSUSP) { + USBD_SuspendProcess(); + } + + // resume interrupt + if (istr & USB_OTG_GINTSTS_WKUINT) { + USBD_ResumeProcess(); + } + + // speed enumeration completed + if (istr & USB_OTG_GINTSTS_ENUMDNE) { + USBD_SpeedEnumDoneProcess(); + } + + // Start Of Frame + if (istr & USB_OTG_GINTSTS_SOF) { + USBD_StartFrameProcess(); + } + + // RxFIFO non-empty + if (istr & USB_OTG_GINTSTS_RXFLVL) { + USBD_RxDataProcess(); + } + + // OUT Packet + if (istr & USB_OTG_GINTSTS_OEPINT) { + USBD_OutEndPointInterruptProcess(); + } + + // IN Packet + if (istr & USB_OTG_GINTSTS_IEPINT) { + USBD_InEndPointInterruptProcess(); + } + + IRQ_Enable(OTG_IRQn, OTG_INT_LEVEL, OTG_HS_IRQHandler); +} diff --git a/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/usbd_STM32MP153_HS.h b/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/usbd_STM32MP153_HS.h new file mode 100644 index 0000000000000000000000000000000000000000..f6d442555c85f43dff681aedca61748a78d00a82 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hic_hal/stm32/stm32mp1xx/usbd_STM32MP153_HS.h @@ -0,0 +1,90 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file usbd_STM32MP153_HS.h + * @author MCU Driver Team + * @brief usbd hs for STM32MP15x + */ +#ifndef USBD_STM32MP153_HS_H +#define USBD_STM32MP153_HS_H + +#include +#include "stm32mp1xx.h" + +#define RX_FIFO_SIZE 1024 +#define TX0_FIFO_SIZE 1024 +#define TX1_FIFO_SIZE 512 +#define TX2_FIFO_SIZE 512 +#define TX3_FIFO_SIZE 512 +#define TX4_FIFO_SIZE 512 +#define TX5_FIFO_SIZE 128 +#define TX6_FIFO_SIZE 128 +#define TX7_FIFO_SIZE 128 +#define TX8_FIFO_SIZE 128 + +#define WORD_CNT(x) (((x) + 3) / 4) +#define OTG_INT_LEVEL (1 << 3) /* priority = 1, low 3 bit is must be kept at reset value */ +#define MHZ 1000000 +#define USBD_DELAY_10MS 10 + +/* See register OTG_GRXSTSR field PKTSTS */ +enum { + OTG_GRXSTSR_PKTSTS_GLOBAL_OUT_NAK = 1, + OTG_GRXSTSR_PKTSTS_OUT_DATA_PKT = 2, + OTG_GRXSTSR_PKTSTS_OUT_TRANSFER_COMPLETED = 3, + OTG_GRXSTSR_PKTSTS_SETUP_TRANSACTION_COMPLETED = 4, + OTG_GRXSTSR_PKTSTS_SETUP_DATA_PKT = 6, +}; + +#define OTG USB1_OTG_HS +#define USB1_OTG_HS_PERIPH_BASE (MCU_AHB2_PERIPH_BASE + 0x1000000) // (0x5800D000UL ) +#define USBX_BASE USB1_OTG_HS_PERIPH_BASE +#define USBX_DEVICE ((USB_OTG_DeviceTypeDef *)(USBX_BASE + USB_OTG_DEVICE_BASE)) + +#define USBX_INEP(i) ((USB_OTG_INEndpointTypeDef *)(USBX_BASE + USB_OTG_IN_ENDPOINT_BASE + ((i)*USB_OTG_EP_REG_SIZE))) +#define USBX_OUTEP(i) \ + ((USB_OTG_OUTEndpointTypeDef *)(USBX_BASE + USB_OTG_OUT_ENDPOINT_BASE + ((i)*USB_OTG_EP_REG_SIZE))) +#define USBX_DFIFO(i) *(__IO uint32_t *)(USBX_BASE + USB_OTG_FIFO_BASE + ((i)*USB_OTG_FIFO_SIZE)) + +#define TX_FIFO(n) *((__packed volatile uint32_t *)(USB1_OTG_HS + USB_OTG_FIFO_BASE + (n)*USB_OTG_FIFO_SIZE)) +#define RX_FIFO *((__packed volatile uint32_t *)(USB1_OTG_HS + USB_OTG_FIFO_BASE)) + +#define EP_IN_TYPE(num) ((USBX_INEP(num)->DIEPCTL >> USB_OTG_DIEPCTL_EPTYP_Pos) & 3) +#define EP_OUT_TYPE(num) ((USBX_OUTEP(num)->DOEPCTL >> USB_OTG_DIEPCTL_EPTYP_Pos) & 3) + +#define HIGH_HALF_WORD(x) ((x) << 16) +#define TXFIFO_WAIT_TIMEOUT_MS (5) + +#define PLLNDIV_SHIFT 0 +#define PLLNDIV 0x7F +#define PLLFRACIN_SHIFT 10 +#define PLLFRACIN (0xFFFF << 10) +#define PLLFRACCTL (1 << 29) +#define USBPHYC_PLLEN (1 << 26) +#define USBPHYC_PLLDITHEN1 (1 << 31) +#define USBPHYC_PLLDITHEN0 (1 << 30) +#define USBPHYC_PLLSTRBYP (1 << 28) + +#define USBD_CLK_RATE 24000000U +#define CLEAR_FIFO_TRY_TIMES 200000U + +typedef struct { + uint8_t ndiv; + uint16_t frac; +} PllParams; + +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/crc32.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/crc32.c new file mode 100644 index 0000000000000000000000000000000000000000..028fb898ce4fe6c5ae5fdd79cae9ccab03777660 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/crc32.c @@ -0,0 +1,84 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file crc32.c + * @author MCU Driver Team + * @brief crc32 module. + */ +#include +#include "crc32.h" + +#define CRC32_TABLE_LEN 256 + +static uint32_t g_crc32Table[CRC32_TABLE_LEN] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x76dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x9b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x1db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x6b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0xf00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x86d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x3b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x4db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0xd6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0xa00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x26d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x5005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0xcb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0xbdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +/* + * Generate CRC32 with init value + */ +uint32_t Crc32Continue(uint32_t prevCrc, const uint8_t *data, int32_t nBytes) +{ + uint8_t index; + uint32_t crc = prevCrc ^ 0xFFFFFFFF; /* Get crc init value */ + const uint8_t *p = data; + for (int32_t i = 0; i < nBytes; i++) { + index = (*p ^ crc) & 0xFF; + crc = (crc >> 8) ^ g_crc32Table[index]; /* 8 bits processed at a time */ + p++; + } + return crc ^ 0xFFFFFFFF; +} + +/* + * Generate CRC32 without value(force init value = 0) + */ +uint32_t Crc32Check(const uint8_t *data, int32_t nBytes) +{ + return Crc32Continue(0, data, nBytes); +} diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/crc32.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/crc32.h new file mode 100644 index 0000000000000000000000000000000000000000..340e63fa17a1b26efc6a055a18710478fd46fc9f --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/crc32.h @@ -0,0 +1,30 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file crc32.h + * @author MCU Driver Team + * @brief crc32 module header + */ +#ifndef CRC32_H +#define CRC32_H + +#include + +uint32_t Crc32Continue(uint32_t prevCrc, const uint8_t *data, int32_t nBytes); +uint32_t Crc32Check(const uint8_t *data, int32_t nBytes); + +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/nos_amp_task_minor.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/user_crc.c similarity index 40% rename from src/middleware/hisilicon/nostask/kernel/nos_amp_task_minor.c rename to src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/user_crc.c index 593fa27e7f64ac0e1617f9dbfab222123d261932..3b8a31d70594022647f5bc0b944468384ed8a029 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_amp_task_minor.c +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/user_crc.c @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,92 +15,92 @@ * 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. - * @file nos_amp_task_minor.c + * @file user_crc32.c + * @author MCU Driver Team + * @brief user crc32 module. */ -#include "nos_task_internal.h" +#include +#include "securec.h" +#include "flash_intf.h" +#include "FlashPrg.h" +#include "crc32.h" +#include "user_crc.h" -/* - * 描述: Suspend task - */ -unsigned int NOS_TaskSuspendInner(unsigned int taskPid) -{ - uintptr_t intSave; - struct TagTskCB *taskCB = NULL; - - /* check taskId */ - if (taskPid == IDLE_TASK_ID || CheckTaskPidOverflow(taskPid)) { - return OS_ERRNO_TSK_ID_INVALID; - } - - /* get taskTCB */ - taskCB = GetTcbHandle(taskPid); +#define ONECE_CHECK_LEN 1024 - intSave = NOS_TaskIntLock(); +static uint32_t g_currentCrcValue = 0; +static uint32_t g_currentCheckValue = 0; - if (taskCB->taskStatus == OS_TSK_UNUSED) { - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_NOT_CREATED; - } - - /* If task is suspended then return */ - if ((OS_TSK_SUSPEND & taskCB->taskStatus) != 0) { - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_ALREADY_SUSPENDED; - } - - if (((OS_TSK_RUNNING & taskCB->taskStatus) != 0) && (g_uniTaskLock != 0)) { - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_SUSPEND_LOCKED; - } +void UserCrcInit(uint32_t initValue, uint32_t checkValue) +{ + g_currentCrcValue = initValue; + g_currentCheckValue = checkValue; +} - /* If task is ready then remove from ready list */ - if ((OS_TSK_READY & taskCB->taskStatus) != 0) { - OsTskReadyDel(taskCB); - } +void UserCrc32(const uint8_t *data, int nBytes) +{ + g_currentCrcValue = Crc32Continue(g_currentCrcValue, data, nBytes); +} - taskCB->taskStatus |= OS_TSK_SUSPEND; +uint32_t UserCurrentCrc32Get(void) +{ + return g_currentCrcValue; +} - if ((OS_TSK_RUNNING & taskCB->taskStatus) != 0) { - OsTskScheduleFastPS(intSave); +uint32_t IsCheckSuccess(void) +{ + if (g_currentCrcValue == g_currentCheckValue) { + return 1; } - - NOS_TaskIntRestore(intSave); - return NOS_OK; + return 0; } -/* - * 描述: Resume suspend task - */ -unsigned int NOS_TaskResumeInner(unsigned int taskId) +int32_t CheckCrcFromFlash(const flash_intf_t *flash_intf, uint32_t startAddr, uint32_t len) { - uintptr_t intSave; - struct TagTskCB *taskCB = NULL; - - if (CheckTaskPidOverflow(taskId)) { - return OS_ERRNO_TSK_ID_INVALID; + int status; + uint8_t buf[ONECE_CHECK_LEN]; + uint32_t checkLen = len; + uint32_t addr = startAddr; + uint32_t currentCheckLen = 0; + + status = flash_intf->init(); + if (ERROR_SUCCESS != status) { + flash_intf->uninit(); + return USER_CRC_CHECK_NOT_CONNECT; } - /* get taskTCB */ - taskCB = GetTcbHandle(taskId); - - intSave = NOS_TaskIntLock(); - - if (TSK_IsUnused(taskCB)) { - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_NOT_CREATED; + if (flash_intf->flash_algo_set) { + status = flash_intf->flash_algo_set(startAddr); + if (ERROR_SUCCESS != status) { + flash_intf->uninit(); + return USER_CRC_CHECK_ALGO_ERROR; + } } - /* If task is not suspended then return */ - if ((OS_TSK_SUSPEND & taskCB->taskStatus) == 0) { - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_NOT_SUSPENDED; + while (checkLen > 0) { + if (memset_s(buf, ONECE_CHECK_LEN, 0, ONECE_CHECK_LEN) != EOK) { + flash_intf->uninit(); + return USER_CRC_CHECK_READ_FAIL; + } + + if (checkLen >= ONECE_CHECK_LEN) { + currentCheckLen = ONECE_CHECK_LEN; + checkLen -= ONECE_CHECK_LEN; + } else { + currentCheckLen = checkLen; + checkLen = 0; + } + status = flash_intf->read(addr, buf, currentCheckLen); + if (ERROR_SUCCESS != status) { + flash_intf->uninit(); + return USER_CRC_CHECK_READ_FAIL; + } + addr += currentCheckLen; + g_currentCrcValue = Crc32Continue(g_currentCrcValue, buf, currentCheckLen); } - - TSK_StatusClear(taskCB, OS_TSK_SUSPEND); - - /* If task is not blocked then move it to ready list */ - OsMoveTaskToReady(taskCB); - NOS_TaskIntRestore(intSave); - - return NOS_OK; + flash_intf->uninit(); + if (g_currentCrcValue == g_currentCheckValue) { + return USER_CRC_CHECK_SUCCESS; + } + return USER_CRC_CHECK_ERROR; } diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/user_crc.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/user_crc.h new file mode 100644 index 0000000000000000000000000000000000000000..054218fddcf4edb49731dea7d0c974e9e11bc46e --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/crc/user_crc.h @@ -0,0 +1,44 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file user_crc.h + * @author MCU Driver Team + * @brief user crc32 module. + */ +#ifndef USER_CRC_H +#define USER_CRC_H + +#include +#include "flash_intf.h" + +#define USER_CRC_CHECK_SUCCESS 1 +#define USER_CRC_CHECK_FAIL 2 +#define USER_CRC_CHECK_NOT_CONNECT 3 +#define USER_CRC_CHECK_ERROR 4 +#define USER_CRC_CHECK_READ_FAIL 5 +#define USER_CRC_CHECK_BAD_FILE 6 +#define USER_CRC_CHECK_ALGO_ERROR 7 +#define USER_CRC_CHECK_NO_ALGO 8 + + +void UserCrcInit(uint32_t initValue, uint32_t checkValue); +void UserCrc32(const uint8_t *data, int nBytes); +uint32_t UserCurrentCrc32Get(void); +uint32_t IsCheckSuccess(void); +int32_t CheckCrcFromFlash(const flash_intf_t *flash_intf, uint32_t startAddr, uint32_t len); + +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/DAP_vendor_ex.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/DAP_vendor_ex.h new file mode 100644 index 0000000000000000000000000000000000000000..78b0303e60d868781165f4d35f0f60bc80548839 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/DAP_vendor_ex.h @@ -0,0 +1,53 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file DAP_vendor_ex.h + * @author MCU Driver Team + * @brief Process DAP Vendor Command from the Extended Command range. + */ +#ifndef DAP_VENDOR_EX_H +#define DAP_VENDOR_EX_H +#include "DAP.h" + +#define ID_DAP_VENDOR_OFFLINE_HEAD 0xB0U +#define ID_DAP_WENDOR_OFFLINE_DATA 0xB1U +#define ID_DAP_WENDOR_OFFLINE_STOP 0xB2U + +typedef enum { + ID_DAP_VENDOR_EX32_I2C_READ = ID_DAP_VendorExFirst, + ID_DAP_VENDOR_EX33_I2C_WRITE, + ID_DAP_VENDOR_EX34_GPIO, + ID_DAP_VENDOR_EX35_DUT_PWR_CTRL, + ID_DAP_VENDOR_EX36_VERSION_DETAILS, + ID_DAP_VENDOR_EX37_HOLD_IN_BL, + ID_DAP_VENDOR_EX38_RESET_DAPLINK, + ID_DAP_VENDOR_EX39_READ_UDC_ADAPTER_TYPE_ADC, + ID_DAP_VENDOR_EX40_VAR_MONITOR = ID_DAP_VENDOR_VAR_MONITOR, + ID_DAP_VENDOR_EX41_READ_VAR = ID_DAP_VENDOR_READ_VAR, + ID_DAP_VENDOR_EX42_WRITE_VAR = ID_DAP_VENDOR_WRITE_VAR, + ID_DAP_VENDOR_EX43_STOP_VARMONITOR = ID_DAP_VENDOR_STOP_VARMONITOR, + ID_DAP_VENDOR_EX44_PAUSE_VARMONITOR = ID_DAP_VENDOR_PAUSE_VARMONITOR, + + ID_DAP_VENDOR_EX50_OFFLINE_HEAD = ID_DAP_VENDOR_OFFLINE_HEAD, + ID_DAP_WENDOR_EX51_OFFLINE_DATA = ID_DAP_WENDOR_OFFLINE_DATA, + ID_DAP_WENDOR_EX52_OFFLINE_STOP = ID_DAP_WENDOR_OFFLINE_STOP, + // Add new commands before the last command + ID_DAP_VENDOR_EX126_LAST = ID_DAP_VendorExLast, +} DapVendorExCmdE; + +uint32_t DAP_ProcessVendorCommandEx(const uint8_t *request, uint8_t *response); +#endif /* #ifndef DAP_VENDOR_EX_H */ diff --git a/src/middleware/hisilicon/nostask/config/nos_config_internal.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/alloc.h similarity index 77% rename from src/middleware/hisilicon/nostask/config/nos_config_internal.h rename to src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/alloc.h index 24113b133c5a8fd10089cbb2f41c0c9d209fc905..481c80c0b98b5ee9358d1acf33ec46db1ec93e39 100644 --- a/src/middleware/hisilicon/nostask/config/nos_config_internal.h +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/alloc.h @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,28 +15,34 @@ * 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. - * @file nos_config_internal.h + * @file alloc.h + * @author MCU Driver Team + * @brief Memory Alloc header */ -#ifndef NOS_CONFIG_INTERNAL_H -#define NOS_CONFIG_INTERNAL_H + + +/* + * @file alloc.h + * @brief Memory allocation process header + */ + +#ifndef MCU_MAGIC_TAG_ALLOC_H +#define MCU_MAGIC_TAG_ALLOC_H #include -#include "nos_config.h" -#include "os_init.h" #ifdef __cplusplus -#if __cplusplus extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ +#endif + +void *MemAlloc(uint32_t size); + +void MemFree(void *ptr); -int NOS_MoudleInit(void); -unsigned int OsStart(void); +/** @} */ #ifdef __cplusplus -#if __cplusplus } -#endif /* __cplusplus */ -#endif /* __cplusplus */ +#endif -#endif /* NOS_CONFIG_INTERNAL_H */ +#endif /* MCU_MAGIC_TAG_ALLOC_H */ diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/dap_offline_load_process.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/dap_offline_load_process.h new file mode 100644 index 0000000000000000000000000000000000000000..d8905df06b8d35b00fb9e42d217925a6834623a5 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/dap_offline_load_process.h @@ -0,0 +1,30 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file dap_offline_load_process.h + * @author MCU Driver Team + * @details This file describes the interface for storing offline burning files through the DAP. + */ +#ifndef DAP_OFFLINE_LOAD_PROCESS_H +#define DAP_OFFLINE_LOAD_PROCESS_H +#include "DAP.h" +#include "DAP_config.h" + +uint32_t DAP_OfflineHeadProc(const uint8_t *request, uint8_t *response); +uint32_t DAP_OfflineDataProc(const uint8_t *request, uint8_t *response); +uint32_t DAP_OfflineStopProc(const uint8_t *request, uint8_t *response); +#endif /* #ifndef DAP_OFFLINE_LOAD_PROCESS_H */ \ No newline at end of file diff --git a/src/middleware/thirdparty/sysroot/include/nos_task.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/var_monitor_process.h similarity index 40% rename from src/middleware/thirdparty/sysroot/include/nos_task.h rename to src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/var_monitor_process.h index 78ff812782b72318909c186f070b8b7a1696172a..f48dcdd73ec4aec69c17315defb411c80c289bc3 100644 --- a/src/middleware/thirdparty/sysroot/include/nos_task.h +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/var_monitor_process.h @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,70 +15,72 @@ * 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. - * @file nos_task.h + * @file var_monitor_process.h + * @author MCU Driver Team + * @brief Variable monitoring protocol, The functions are as follows: + * + starting variable monitoring. + * + stopping variable monitoring. + * + suspending variable monitoring. + * + uploading variable monitoring data. + * + modifying variable values... */ +#ifndef VAR_MONITOR_PROCESS_H +#define VAR_MONITOR_PROCESS_H +#include "DAP.h" +#include "DAP_config.h" -#ifndef NOS_TASK_H -#define NOS_TASK_H -#define NOS_TASK_PRIORITY_LOWEST 4 +#define DAP_TRANSFER_MAX_PACKET_SIZE (DAP_PACKET_SIZE - 8) +#define MAX_VAR_NUM 60 +#define DISCONNECT_SESSION_TIMEOUT 5000000 +#define VAR_LIST_PROTOCOL_POS 8 -typedef void (*NOS_TaskEntryFunc)(void* param); -typedef void (*NOS_TimerCallBack)(void* param); -typedef struct { - const char *name; - NOS_TaskEntryFunc taskEntry; - void* param; - unsigned int priority; /* scope:[0-NOS_TASK_PRIORITY_LOWEST] */ - unsigned int stackAddr; /* notice: addr must 16Bytes align && not zero */ - unsigned int stackSize; - unsigned int privateData; -} NOS_TaskInitParam; - -typedef struct { - const char *name; - unsigned int timeout; // us - NOS_TimerCallBack callback; - void *callbackParam; - unsigned int priority; /* scope:[0-NOS_TASK_PRIORITY_LOWEST] */ - unsigned int stackSize; - unsigned int stackAddr; -}NOS_TimerTaskInitParam; - -typedef struct { - unsigned int cyclePerUs; - unsigned int usecPerTick; - unsigned long long (*getTickFunc)(void); -}NOS_SysConfig; - -int NOS_TaskInit(NOS_SysConfig *config); - -int NOS_StartScheduler(void); - -int NOS_TaskCreateOnly(NOS_TaskInitParam *initParam, unsigned int *taskId); +#define MAGICNUMBE_BYTES sizeof(unsigned int) +#define SAMPLECOUNT_BYTES sizeof(unsigned int) -int NOS_TaskCreate(NOS_TaskInitParam *initParam, unsigned int *taskId); +#define SHIFTS_8_BIT 8 +#define SHIFTS_16_BIT 16 +#define SHIFTS_24_BIT 24 -int NOS_TaskDelete(unsigned int taskId); +#define MASK_POS_0 0x000000ff +#define MASK_POS_8 0x0000ff00 +#define MASK_POS_16 0x00ff0000 +#define MASK_POS_24 0xff000000 -int NOS_TaskSuspend(unsigned int taskId); +#define MASK_LOW_32 0xffffffff -int NOS_TaskResume(unsigned int taskId); +#define MAGIC_NUMBER 0x44332211 -int NOS_TaskDelay(unsigned int timeout); +#define MAX_WRITE_BYTE_VALUE 8 -int NOS_TaskPrioritySet(unsigned int taskId, unsigned short priority); - -int NOS_TaskPriorityGet(unsigned int taskId, unsigned short *priority); - -/* **********************timer task********************* */ - -int NOS_CreateTimerTask(unsigned int *timerTaskId, NOS_TimerTaskInitParam *timerParam); - -/* 接口约束 必须systick启动后. taskId 必须是 NOS_CreateTimerTask 创建的 */ -int NOS_StartTimerTask(unsigned int taskId); +typedef struct { + unsigned int varAddress; + unsigned int varNumBytes; +} DapVarList; -/* 接口约束 必须systick启动后. taskId 必须是 NOS_CreateTimerTask 创建的 */ -int NOS_StopTimerTask(unsigned int taskId); +typedef struct { + unsigned int isSample; + unsigned int periodUs; + unsigned int varNum; + DapVarList *varList; +} DapVarMonitor; -#endif // NOS_TASK_H +typedef struct { + unsigned int address; + unsigned int len; + unsigned char value[MAX_WRITE_BYTE_VALUE]; +} DapWriteVar; + +extern uint32_t GetTickDelta(uint32_t curTicks, uint32_t preTicks); +extern uint32_t HAL_GetTickUs(void); + +uint32_t DAP_VarMonitor(const uint8_t *request, uint8_t *response); +uint32_t DAP_ReadVar(const uint8_t *request, uint8_t *response); +uint32_t DAP_StopVarMonitor(uint8_t *response); +uint32_t DAP_PauseVarMonitor(const uint8_t *request, uint8_t *response); +uint32_t DAP_WriteVar(const uint8_t *request, uint8_t *response); +void SetPerformanceTest(unsigned int flag); +uint32_t GetPerformanceTest(void); +void DAP_StatusDetection(void); +void UpdateDapStatistics(void); +#endif /* #ifndef VAR_MONITOR_PROCESS_H */ \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/nos_sched_single.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/var_monitor_queue.h similarity index 55% rename from src/middleware/hisilicon/nostask/kernel/nos_sched_single.c rename to src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/var_monitor_queue.h index c800e657cc31799aff689a238fac5d7ae4c8382a..1a93d53d4c30e69d351481ea8a80de775923f339 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_sched_single.c +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/include/var_monitor_queue.h @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,45 +15,40 @@ * 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. - * @file nos_sched_single.c + * @file var_monitor_queue.h + * @author MCU Driver Team + * @brief Shared queue for storing variable monitoring data. */ -#include "nos_task_external.h" +#ifndef VAR_MONITOR_QUEUE_H +#define VAR_MONITOR_QUEUE_H -/* - * 描述: 调度的主入口 - * 备注: NA - */ - void OsMainSchedule(void); - void OsMainSchedule(void) -{ - if ((UNI_FLAG & OS_FLG_TSK_REQ) != 0) { - /* 有任务切换钩子&最高优先级任务等待调度 */ - if (RUNNING_TASK != g_highestTask) { - OsTskSwitchHookCaller(RUNNING_TASK->taskPid, g_highestTask->taskPid); - } - /* 清除OS_FLG_TSK_REQ标记位 */ - UNI_FLAG &= ~OS_FLG_TSK_REQ; +#define VARQ_SECTION __attribute__((section(".varq_section"))) +#define VARQ_SIZE (0x1E000 - 18 * sizeof(unsigned int)) /* (120k - 72)bytes */ - RUNNING_TASK->taskStatus &= ~OS_TSK_RUNNING; - g_highestTask->taskStatus |= OS_TSK_RUNNING; +/** + * VarQueue - queue structure + * @read: position of read + * @write: position of write + * @size: buffer size + * @totalReadSize: Read the total size. + * @totalWriteSize: Write the total size. + */ +typedef struct { + unsigned long long read; + unsigned long long write; + unsigned long long size; + unsigned long long totalReadSize; + unsigned long long totalWriteSize; + unsigned long long totalSampleCount; + unsigned long long totalOverflowCount; + unsigned long long totalErrorCount; + unsigned int exceptionExitFlag; + unsigned int errorRate; + char buf[VARQ_SIZE]; +} volatile VarQueue; - RUNNING_TASK = g_highestTask; - } - // 如果中断没有驱动一个任务ready,直接回到被打断的任务 - OsTskContextLoad((uintptr_t)RUNNING_TASK); -} +unsigned int ReadQueue(VarQueue *q, unsigned char *buf, unsigned int len); +unsigned long long QueueReadableLength(VarQueue *q); -/* - * 描述: 系统启动时的首次任务调度 - * 备注: NA - */ -void OsFirstTimeSwitch(void) -{ - OsTskHighestSet(); - RUNNING_TASK = g_highestTask; - TSK_StatusSet(RUNNING_TASK, OS_TSK_RUNNING); - OsTskContextLoad((uintptr_t)RUNNING_TASK); - // never get here - return; -} +#endif /* #ifndef VAR_MONITOR_QUEUE_H */ \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/nos_base_task.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/DAP_vendor_ex.c similarity index 41% rename from src/middleware/hisilicon/nostask/kernel/nos_base_task.c rename to src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/DAP_vendor_ex.c index 51214a66825b6671d98de1a9ca0172a97adf2920..dd117155f7866769c7c44e16ac21334b87c5d0ff 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_base_task.c +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/DAP_vendor_ex.c @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,88 +15,68 @@ * 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. - * @file nos_base_task.c + * @file DAP_vendor_ex.c + * @author MCU Driver Team + * @brief Process DAP Vendor Command from the Extended Command range. */ -#include "nos_amp_task_internal.h" -#include "nos_base_task.h" +#include +#include "DAP.h" +#include "DAP_config.h" +#include "settings.h" +#include "cortex_m.h" +#include "var_monitor_process.h" +#include "dap_offline_load_process.h" +#include "DAP_vendor_ex.h" -INLINE void OsTskReadyAddOnly(struct TagTskCB *task) -{ - struct TagOsRunQue *rq = &g_runQueue; - - // 本核还未启动时,允许加入本核运行队列 - TSK_StatusSet(task, OS_TSK_READY); - - /* 入队 */ - OsEnqueueTaskAmp(rq, task); - - OsIncNrRunning(rq); - - return; -} - -/* - * 描述: 将任务添加到就绪队列, 调用者确保不会换核,并锁上rq - * 备注: SMP/AMP归一 - */ -void OsTskReadyAdd(struct TagTskCB *task) -{ - /* 将任务添加到就绪队列 */ - OsTskReadyAddOnly(task); -} - -/* - * 描述: 将任务添加到就绪链表头,关中断外部保证 - * 备注: SMP/AMP归一 - */ -void OsTskReadyDel(struct TagTskCB *taskCB) -{ - struct TagOsRunQue *runQue = NULL; - TSK_StatusClear(taskCB, OS_TSK_READY); - - runQue = &g_runQueue; - // 出队 - OsDequeueTaskAmp(runQue, taskCB); - - // 更新源运行队列的功耗值 - OsDecNrRunning(runQue); - - return; -} -/* - * 描述: 添加任务到超时链表,TCB锁由外部调用者保证,TCB已在外部锁 - * 备注: SMP/AMP归一 - */ -void OsTskTimerAdd(struct TagTskCB *taskCB, uintptr_t timeout) +/** + * @brief Process DAP Vendor Command from the Extended Command range and prepare Response Data. + * @param request pointer to request data. + * @param response pointer to response data. + * @retval number of bytes in response (lower 16 bits),number of bytes in request (upper 16 bits). + */ +uint32_t DAP_ProcessVendorCommandEx(const uint8_t *request, uint8_t *response) { - struct TagTskCB *tskDelay = NULL; - struct TagOsTskSortedDelayList *tskDlyBase = NULL; - struct TagListObject *taskList = NULL; + uint32_t num = (1U << 16) | 1U; // count the Command ID byte - tskDlyBase = &g_tskSortedDelay; + *response++ = *request; // copy Command ID - /* get tick */ - unsigned long long curTick = NOS_GetCycle(); - if (curTick == 0) { - return; - } - - taskCB->expirationTick = curTick + timeout; - taskList = &tskDlyBase->tskList; - - if (!ListEmpty(taskList)) { - /* Put the task to right location */ - LIST_FOR_EACH(tskDelay, taskList, struct TagTskCB, timerList) { - if (tskDelay->expirationTick > taskCB->expirationTick) { - break; - } + switch (*request++) { // first byte in request is Command ID + case ID_DAP_VENDOR_EX40_VAR_MONITOR: { + num += DAP_VarMonitor(request, response); + break; + } + case ID_DAP_VENDOR_EX41_READ_VAR: { + num += DAP_ReadVar(request, response); + break; } - ListTailAdd(&taskCB->timerList, &tskDelay->timerList); - } else { - /* 加入超时链表尾部 */ - ListTailAdd(&taskCB->timerList, taskList); + case ID_DAP_VENDOR_EX42_WRITE_VAR: { + num += DAP_WriteVar(request, response); + break; + } + case ID_DAP_VENDOR_EX43_STOP_VARMONITOR: { + num += DAP_StopVarMonitor(response); + break; + } + case ID_DAP_VENDOR_EX44_PAUSE_VARMONITOR: { + num += DAP_PauseVarMonitor(request, response); + break; + } + case ID_DAP_VENDOR_EX50_OFFLINE_HEAD: { + num += DAP_OfflineHeadProc(request, response); + break; + } + case ID_DAP_WENDOR_EX51_OFFLINE_DATA: { + num += DAP_OfflineDataProc(request, response); + break; + } + case ID_DAP_WENDOR_EX52_OFFLINE_STOP: { + num += DAP_OfflineStopProc(request, response); + break; + } + default: break; } - return; + return (num); } + diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/alloc.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/alloc.c new file mode 100644 index 0000000000000000000000000000000000000000..da86a57ab63c04a24f4c8df0ac8bbe86e3521ca3 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/alloc.c @@ -0,0 +1,234 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file alloc.c + * @author MCU Driver Team + * @brief Memory Alloc Process + */ +#include +#include +#include +#include "debug.h" +#include "securec.h" + +#pragma pack(1) +typedef struct MemBlock { /* Memory Mangement Block Struct */ + void *memPtr; /* Managed Address of memory block */ + struct MemBlock *nextPtr; /* Next memory block */ + uint32_t memSize; /* Memory Size */ + bool memUsed; /* Used or Free */ +} MemBlock; +#pragma pack() +extern uint32_t __HEAP_START__; /* defined by linker script */ +extern uint32_t __HEAP_END__; /* defined by linker script */ + +#define MEM_SIZE ((size_t)((void *)&__HEAP_END__ - (void *)&__HEAP_START__)) +static const void *MEM_START = (void *)&__HEAP_START__; +static const void *MEM_END = (void *)&__HEAP_END__; +static const uint32_t BLOCK_SIZE = sizeof(MemBlock); +static MemBlock *g_hdrNode = NULL; +static bool g_memInited = false; /* Memory Management Inited Flag */ + +/* + * Init Memory Management + */ +static void Init(void) +{ + uint32_t *heap = NULL; + MemBlock *node = NULL; + errno_t ret; + + /* Init hdr node, don't change g_hdrNode anymore */ + g_hdrNode = (MemBlock *)(MEM_END - BLOCK_SIZE); + + heap = (uint32_t *)MEM_START; + ret = memset_s((void*)heap, MEM_SIZE, 0, MEM_SIZE); + if (ret != EOK) { + return; + } + + /* Init first node */ + node = g_hdrNode; + node->memPtr = (void *)MEM_START; + node->nextPtr = g_hdrNode; + node->memSize = (uint32_t)(MEM_SIZE - BLOCK_SIZE); + node->memUsed = false; + + g_memInited = true; /* Init done */ +} + +/* + * Find Suit Node In Free Nodes + */ +static MemBlock *FindSuitNode(uint32_t nbytes) +{ + uint32_t suitSize = (uint32_t)-1; + MemBlock *hdrNode = g_hdrNode; /* always find begin with hdr node */ + MemBlock *tmpNode = g_hdrNode; + MemBlock *suitNode = NULL; + + while (true) { + if (!tmpNode->memUsed) { /* Only check unused node */ + /* find node with suit size */ + if ((nbytes <= tmpNode->memSize) && (tmpNode->memSize < suitSize)) { + suitNode = tmpNode; /* update suit node and size */ + suitSize = suitNode->memSize; + } + } + tmpNode = tmpNode->nextPtr; + if (tmpNode == hdrNode) { + break; /* already check all nodes, break */ + } + } + return suitNode; +} + +/* + * Find Suit Node In Free Nodes + */ +static void *AllocNode(MemBlock *suitNode, uint32_t nbytes) +{ + /* Create a new node from suit nodes */ + MemBlock *tmpNode = (MemBlock *)suitNode->memPtr; + tmpNode = (MemBlock *)((unsigned char *)tmpNode + nbytes); + tmpNode->memPtr = suitNode->memPtr; + tmpNode->nextPtr = suitNode->nextPtr; + tmpNode->memSize = nbytes; + tmpNode->memUsed = true; + + /* update suit node Pointer to the next unused memory */ + suitNode->memPtr = (MemBlock *)((unsigned char *)tmpNode + BLOCK_SIZE); + suitNode->nextPtr = tmpNode; + suitNode->memSize -= (nbytes + BLOCK_SIZE); + suitNode->memUsed = false; + + return tmpNode->memPtr; /* return the new node */ +} + +/* + * Free Node, merge two unused node + */ +static void MergeFreeNode(MemBlock *freeNode, MemBlock *mergeNode) +{ + /* update free node */ + freeNode->memPtr = mergeNode->memPtr; + freeNode->nextPtr = mergeNode->nextPtr; + freeNode->memSize += mergeNode->memSize + BLOCK_SIZE; + freeNode->memUsed = false; +} + +/* + * Find Node by address + */ +static void *FindNode(const void *ptr) +{ + MemBlock *hdrNode = g_hdrNode; + MemBlock *tmpNode = g_hdrNode; + + while (true) { + if (tmpNode->memPtr == ptr) { + if (tmpNode->memUsed) { + /* find the node and is used, make it unused(free) */ + tmpNode->memUsed = false; + break; + } else { + /* find the node and is unused, it's free already, return */ + DBG_PRINTF("ptr:0x%08x already free\r\n", ptr); + return NULL; + } + } + /* try next node */ + tmpNode = tmpNode->nextPtr; + if (tmpNode == hdrNode) { + /* ERROR: we have check all nodes and can't find the node */ + DBG_PRINTF("%s %d, can't find the node, free fail\r\n", __func__, __LINE__); + return NULL; + } + } + return tmpNode; +} + +/* + * Combine all consecutive Free nodes. + */ +static void MergeAllFreeNodes(void) +{ + MemBlock *hdrNode = g_hdrNode; + MemBlock *tmpNode = g_hdrNode; + MemBlock *nextNode = NULL; + + while (true) { + nextNode = tmpNode->nextPtr; + if (nextNode == hdrNode) { + break; /* only one node, don't need merge */ + } + /* If two nodes are adjacent and both nodes are free nodes, + combine the two nodes. */ + if (!tmpNode->memUsed && !nextNode->memUsed) { + MergeFreeNode(tmpNode, nextNode); + hdrNode = g_hdrNode; + tmpNode = g_hdrNode; + continue; + } + tmpNode = nextNode; /* Try next node */ + } +} + +/* + * Combine all consecutive Free nodes. + */ +void *MemAlloc(uint32_t nbytes) +{ + MemBlock *suitNode = NULL; + + if (nbytes == 0) { /* don't alloc if size = 0 */ + DBG_PRINTF("Invalid Paramter"); + return NULL; + } + if (!g_memInited) { /* if memory isn't init, do init */ + Init(); + } + /* find the suit node */ + suitNode = FindSuitNode(nbytes); + if (suitNode == NULL) { + return NULL; /* can't find a suit node, return null */ + } + if ((nbytes <= suitNode->memSize) && ((nbytes + BLOCK_SIZE) >= suitNode->memSize)) { + suitNode->memUsed = true; /* find a suit and unused node, used it */ + return suitNode->memPtr; + } else if (suitNode->memSize >= (nbytes + BLOCK_SIZE)) { + /* don't find a suit and unused node, creat it */ + return AllocNode(suitNode, nbytes); + } else { + DBG_PRINTF("%s,size err!\r\n", __func__); + } + return NULL; +} + +/* + * Free Node by addr + */ +void MemFree(void *ptr) +{ + if ((ptr == NULL) || (!g_memInited)) { + return; + } + /* find the node and do combine process */ + if (FindNode(ptr) != NULL) { + MergeAllFreeNodes(); + } +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/dap_offline_load_process.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/dap_offline_load_process.c new file mode 100644 index 0000000000000000000000000000000000000000..adcaf816155f7dd3f9e6da6a1aa563ea74100fae --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/dap_offline_load_process.c @@ -0,0 +1,483 @@ +/** + * @copyright Copyright (c) 2024, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file dap_offline_load_process.c + * @author MCU Driver Team + * @details This file is used to describe the implementation of the interface for storing offline burning files + * through the DAP. + */ +#include "securec.h" +#include "flash_decoder.h" +#include "flash_intf.h" +#include "config_storage_update.h" +#include "target_lib_manager.h" +#include "offline_sys_config.h" +#include "user_crc.h" +#include "status.h" +#include "dap_offline_load_process.h" + +#define SHIFTS_8_BIT 8 +#define SHIFTS_16_BIT 16 +#define SHIFTS_24_BIT 24 +#define REQUEST_DATA_LENGTH 4 + +#define MASK_POS_0 0x000000ff +#define MASK_POS_8 0x0000ff00 +#define MASK_POS_16 0x00ff0000 +#define MASK_POS_24 0xff000000 + +#define OFFLINE_STOP_STATUS_DONE 1 +#define OFFLINE_STOP_STATUS_FAIL 2 + +#define OFFLINE_LOAD_HEAD_LEN FLASH_DECODER_MIN_SIZE + +typedef struct { + uint8_t headBuf[OFFLINE_LOAD_HEAD_LEN]; + uint32_t flashAddr; + uint8_t nameBuf[TARGET_LIB_IMAGE_NAME_MAX_LEN]; + uint8_t nameBufPos; + uint8_t imageFlag; + const flash_intf_t *flash_intf; +} OfflineLoadState; + +static OfflineLoadState g_offlineLoadState = {0}; + +/** + * @brief Processing file headers. + * @param info File header information. + * @param targetFlashInfo Target flash information. + * @retval errno_t. + */ +static int ParsingHeader(flash_decoder_head_t *info, TargetFlashInfo *targetFlashInfo) +{ + errno_t rc = EOK; + + /* Copy the file header data and structured data from the global buffer. */ + rc = memcpy_s(info, OFFLINE_LOAD_HEAD_LEN, g_offlineLoadState.headBuf, OFFLINE_LOAD_HEAD_LEN); + if (rc != EOK) { + return rc; + } + /* Parsing header data */ + targetFlashInfo->regioninfo = info->region_info; + targetFlashInfo->flashID = info->vendor_flash_algo; + targetFlashInfo->fileSize = info->size; + targetFlashInfo->modelID = info->vendor_model; + targetFlashInfo->vendorID = info->vendor; + targetFlashInfo->version = info->version; + targetFlashInfo->fileCrc32 = info->crc_value; + targetFlashInfo->oldNamelen = info->nameLen; + /* Burned target address. */ + targetFlashInfo->targetAddr = info->targetAddr; + /* Maximum number of times that the program can be programmed. */ + targetFlashInfo->maxLoads = info->maxLoads; + return rc; +} + +/** + * @brief Processing the image header. + * @param request request buffer pointer. + * @param dataLen request data len. + * @retval errno_t. + */ +static int ProcessImageHead(const uint8_t *request, uint32_t dataLen) +{ + errno_t rc = EOK; + flash_decoder_head_t info; + TargetFlashInfo targetFlashInfo; + flash_decoder_type_t flashType; + + g_offlineLoadState.nameBufPos = 0; + /* Parse the file data header. */ + rc = ParsingHeader(&info, &targetFlashInfo); + if (rc != EOK) { + return rc; + } + + if (dataLen < info.nameLen) { + return rc; + } + /* Parse and store file names */ + rc = memcpy_s(g_offlineLoadState.nameBuf, TARGET_LIB_IMAGE_NAME_MAX_LEN, request, info.nameLen); + if (rc != EOK) { + return rc; + } + + /* Processes the offline file list based on whether it is factory mode or normal mode. */ + if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { + FactoryImageChange(targetFlashInfo, g_offlineLoadState.nameBuf, info.nameLen); + } else { + TargetLibImageAdd(targetFlashInfo, g_offlineLoadState.nameBuf, info.nameLen); + } + g_offlineLoadState.nameBufPos = info.nameLen; + /* Parse the file header and obtain the type and storage address. */ + flashType = flash_decoder_detect_type(g_offlineLoadState.headBuf, OFFLINE_LOAD_HEAD_LEN, 0, false); + rc = flash_decoder_get_flash(flashType, 0, false, &g_offlineLoadState.flashAddr, + &g_offlineLoadState.flash_intf); + if (rc != EOK) { + return rc; + } + /* Storage header data. */ + rc = flash_decoder_write(g_offlineLoadState.flashAddr, g_offlineLoadState.headBuf, OFFLINE_LOAD_HEAD_LEN); + return rc; +} + +/** + * @brief Interface file transfer completion processing function. + * @param None. + * @retval None. + */ +static void InterfaceDoneHandle(void) +{ + DapLinkStatus daplinkStatus; + + /* Obtain the partition where the current app is running and + configure the partition flag for the app to be upgraded. */ + if (SysStartFlagGet() == CONFIG_STRAT_FLAG_A) { + ConfigStartFlagSave(CONFIG_STRAT_FLAG_B); + } else { + ConfigStartFlagSave(CONFIG_STRAT_FLAG_A); + } + /* The debugger shows that the upgrade is successful. */ + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.fwUpgradeStatus = FIMRWARE_UPGRADE_SUCCESS; + DapLinkStatusSet(&daplinkStatus); +} + +/** + * @brief Image file transfer completion processing function. + * @param None. + * @retval None. + */ +static void ImageDoneHandle(void) +{ + DapLinkStatus daplinkStatus; + TargetImageLibInfo currentLibImage; + int currentIndex; + const flash_intf_t *currentIntf; + + /* Obtains the current file information. */ + if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { + FactoryLibCurrentImageGet(¤tLibImage); + } else { + TargetLibCurrentImageGet(¤tLibImage, (int32_t *)¤tIndex); + } + /* Perform CRC verification on the file. */ + UserCrcInit(0, currentLibImage.info.fileCrc32); + currentIntf = flash_intf_iap_protected; + if (CheckCrcFromFlash(currentIntf, currentLibImage.startAddr, currentLibImage.info.fileSize) + != USER_CRC_CHECK_SUCCESS) { + /* The debugger displays the crc error status. */ + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.imageStoreStatus = IMAGE_STORE_CRC_ERROR; + DapLinkStatusSet(&daplinkStatus); + } else { + /* Set the stored file to the available state. */ + if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { + currentIndex = FactoryLibImageIndexGetFormStartAddr(currentLibImage.startAddr); + FactoryLibFileStatusChange(TARGET_LIB_TYPE_IMAGE, currentIndex, TARGET_LIB_FILE_STATUS_NORMAL); + } else { + currentIndex = TargetLibImageIndexGetFormStartAddr(currentLibImage.startAddr); + TargetLibFileStatusChange(TARGET_LIB_TYPE_IMAGE, currentIndex, TARGET_LIB_FILE_STATUS_NORMAL); + } + /* The debugger displays the success status. */ + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.imageStoreStatus = IMAGE_STORE_SUCCESS; + DapLinkStatusSet(&daplinkStatus); + } +} + +/** + * @brief Algo file transfer completion processing function. + * @param None. + * @retval None. + */ +static void AlgoDoneHandle(void) +{ + DapLinkStatus daplinkStatus; + int currentIndex; + uint32_t fileStatus; + TargetAlgoLibInfo currentLibAlgo; + const flash_intf_t *currentIntf; + + /* Obtains the current file information. */ + TargetLibCurrentAlgoGet(¤tLibAlgo); + UserCrcInit(0, currentLibAlgo.info.fileCrc32); + currentIntf = flash_intf_iap_protected; + if (CheckCrcFromFlash(currentIntf, currentLibAlgo.startAddr, currentLibAlgo.info.fileSize) + != USER_CRC_CHECK_SUCCESS) { + /* The debugger displays the crc error status. */ + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.algoStoreStatus = ALGORITHM_STORE_CRC_ERROR; + DapLinkStatusSet(&daplinkStatus); + } else { + /* Set the stored file to the available state. */ + if ((currentLibAlgo.info.regioninfo & 0xFFFF0000) == TARGET_LIB_SEC_REGION) { + fileStatus = TARGET_LIB_FILE_STATUS_SECURITY; + } else { + fileStatus = TARGET_LIB_FILE_STATUS_NORMAL; + } + + currentIndex = TargetLibAlgoIndexGetFormStartAddr(currentLibAlgo.startAddr); + TargetLibFileStatusChange(TARGET_LIB_TYPE_ALGO, currentIndex, fileStatus); + /* The debugger displays the success status. */ + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.algoStoreStatus = ALGORITHM_STORE_SUCCESS; + DapLinkStatusSet(&daplinkStatus); + } +} + + +/** + * @brief Processing function for data transmission completion. + * @param None. + * @retval None. + */ +static void TransferUpdateDoneHandle(void) +{ + int loadType; + + /* Obtains the file type that is being processed. */ + loadType = ConfigLoadTypeGet(); + switch (loadType) { + case CONFIG_LOAD_TYPE_INTERFACE: /* Debugger APP Firmware. */ + InterfaceDoneHandle(); + break; + case CONFIG_LOAD_TYPE_IMAGE: /* Target image file */ + ImageDoneHandle(); + break; + case CONFIG_LOAD_TYPE_ALGO: /* Target algo file */ + AlgoDoneHandle(); + break; + default: + break; + } +} + +/** + * @brief Parses the flash drive and storage address based on the file type. + * @param flashType file type. + * @retval errno_t. + */ +static int ParseAddrAndFlashIntf(flash_decoder_type_t flashType) +{ + errno_t rc = EOK; + flash_decoder_head_t info; + TargetFlashInfo targetFlashInfo; + + /* Processing algorithm file headers */ + if (flashType == FLASH_DECODER_TYPE_TARGET_ALGO) { + rc = ParsingHeader(&info, &targetFlashInfo); + if (rc != EOK) { + return rc; + } + + if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { + FactoryAlgoChange(targetFlashInfo); + } else { + TargetLibAlgoAdd(targetFlashInfo); + } + } + /* Obtains the flash drive and file storage start address based on the file type. */ + rc = flash_decoder_get_flash(flashType, 0, false, &g_offlineLoadState.flashAddr, + &g_offlineLoadState.flash_intf); + if (rc != EOK) { + return rc; + } + flash_decoder_open(); + /* Delayed processing of image files */ + if (flashType == FLASH_DECODER_TYPE_TARGET_IMAGE) { + g_offlineLoadState.imageFlag = 1; /* image flag set 1 */ + return EOK; + } + /* Storage header data. */ + rc = flash_decoder_write(g_offlineLoadState.flashAddr, g_offlineLoadState.headBuf, OFFLINE_LOAD_HEAD_LEN); + if (rc != EOK) { + return rc; + } + return EOK; +} + +/** + * @brief Processing the Header of an Offline Burning File. + * @param request request buffer pointer. + * @param response response buffer pointer. + * @retval high 16-bits is request length, low 16-bits is responce length. + */ +uint32_t DAP_OfflineHeadProc(const uint8_t *request, uint8_t *response) +{ + errno_t rc = EOK; + flash_decoder_type_t flashType; + + unsigned int maskPos0; + unsigned int maskPos8; + unsigned int maskPos16; + unsigned int maskPos24; + uint32_t dataLen = 0; + + if (request == NULL || response == NULL) { + /* high 16-bits is request length, low 16-bits is responce length. */ + return (0U << 16U) | 1U; + } + + maskPos0 = (*(request++) & MASK_POS_0); + maskPos8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPos16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPos24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + dataLen = maskPos0 | maskPos8 | maskPos16 | maskPos24; + + if (dataLen < FLASH_DECODER_MIN_SIZE) { + *response = DAP_ERROR; + /* high 16-bits is request length, low 16-bits is responce length is 1. */ + return ((dataLen + REQUEST_DATA_LENGTH) << 16U) | 1U; + } + g_offlineLoadState.imageFlag = 0; /* image type flag set 0 */ + rc = memset_s(g_offlineLoadState.headBuf, OFFLINE_LOAD_HEAD_LEN, + 0, OFFLINE_LOAD_HEAD_LEN); + if (rc != EOK) { + *response = DAP_ERROR; + /* high 16-bits is request length, low 16-bits is responce length is 1. */ + return ((dataLen + REQUEST_DATA_LENGTH) << 16U) | 1U; + } + + rc = memcpy_s(g_offlineLoadState.headBuf, OFFLINE_LOAD_HEAD_LEN, + request, OFFLINE_LOAD_HEAD_LEN); + if (rc != EOK) { + *response = DAP_ERROR; + /* high 16-bits is request length, low 16-bits is responce length is 1. */ + return ((dataLen + REQUEST_DATA_LENGTH) << 16U) | 1U; + } + + flashType = flash_decoder_detect_type(g_offlineLoadState.headBuf, OFFLINE_LOAD_HEAD_LEN, 0, false); + if (flashType == FLASH_DECODER_TYPE_UNKNOWN || flashType == FLASH_DECODER_TYPE_TARGET) { + *response = DAP_ERROR; + /* high 16-bits is request length, low 16-bits is responce length is 1. */ + return ((dataLen + REQUEST_DATA_LENGTH) << 16U) | 1U; + } + + rc = ParseAddrAndFlashIntf(flashType); + if (rc != EOK) { + *response = DAP_ERROR; + /* high 16-bits is request length, low 16-bits is responce length is 1. */ + return ((dataLen + REQUEST_DATA_LENGTH) << 16U) | 1U; + } + + *response = DAP_OK; + /* high 16-bits is request length, low 16-bits is responce length is 1. */ + return ((dataLen + REQUEST_DATA_LENGTH) << 16U) | 1U; +} + +/** + * @brief Processing Offline Burning File Data. + * @param request request buffer pointer. + * @param response response buffer pointer. + * @retval high 16-bits is request length, low 16-bits is responce length. + */ +uint32_t DAP_OfflineDataProc(const uint8_t *request, uint8_t *response) +{ + errno_t rc = EOK; + flash_decoder_type_t flashType; + uint32_t startAddr; + + unsigned int maskPos0; + unsigned int maskPos8; + unsigned int maskPos16; + unsigned int maskPos24; + uint32_t dataLen = 0; + uint32_t writeLen = 0; + + if (request == NULL || response == NULL) { + flash_decoder_close(); + /* high 16-bits is request length, low 16-bits is responce length is 1. */ + return (0U << 16U) | 1U; + } + /* Length of the parsed data */ + maskPos0 = (*(request++) & MASK_POS_0); + maskPos8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPos16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPos24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + dataLen = maskPos0 | maskPos8 | maskPos16 | maskPos24; + writeLen = dataLen; + /* process image head */ + if (g_offlineLoadState.imageFlag == 1) { /* image flag set 1 */ + g_offlineLoadState.imageFlag = 0; + rc = ProcessImageHead(request, dataLen); + if ((rc != EOK) && (rc != ERROR_SUCCESS_DONE)) { + flash_decoder_close(); + *response = DAP_ERROR; + /* high 16-bits is request length, low 16-bits is responce length is 1. */ + return ((dataLen + REQUEST_DATA_LENGTH) << 16U) | 1U; + } + request += g_offlineLoadState.nameBufPos; + writeLen -= g_offlineLoadState.nameBufPos; + } + + rc = flash_decoder_write(g_offlineLoadState.flashAddr, request, writeLen); + if ((rc != EOK) && (rc != ERROR_SUCCESS_DONE)) { + flash_decoder_close(); + *response = DAP_ERROR; + /* high 16-bits is request length, low 16-bits is responce length is 1. */ + return ((dataLen + REQUEST_DATA_LENGTH) << 16U) | 1U; + } + g_offlineLoadState.flashAddr += writeLen; + *response = DAP_OK; + /* high 16-bits is request length, low 16-bits is responce length is 1. */ + return ((dataLen + REQUEST_DATA_LENGTH) << 16U) | 1U; +} + +/** + * @brief Stop processing offline burning. + * @param request request buffer pointer. + * @param response response buffer pointer. + * @retval high 16-bits is request length, low 16-bits is responce length. + */ +uint32_t DAP_OfflineStopProc(const uint8_t *request, uint8_t *response) +{ + uint8_t status = 0; + int loadType; + DapLinkStatus daplinkStatus; + + flash_decoder_close(); + status = *(request++); + if (status == OFFLINE_STOP_STATUS_DONE) { + TransferUpdateDoneHandle(); + } else { + /* Debugger displays failure information */ + loadType = ConfigLoadTypeGet(); + switch (loadType) { + case CONFIG_LOAD_TYPE_INTERFACE: /* Debugger APP Firmware. */ + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.fwUpgradeStatus = FIMRWARE_UPGRADE_CRC_ERROR; + DapLinkStatusSet(&daplinkStatus); + break; + case CONFIG_LOAD_TYPE_IMAGE: /* Target image file */ + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.imageStoreStatus = IMAGE_STORE_FAIL; + DapLinkStatusSet(&daplinkStatus); + break; + case CONFIG_LOAD_TYPE_ALGO: /* Target algo file */ + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.algoStoreStatus = ALGORITHM_STORE_FAIL; + DapLinkStatusSet(&daplinkStatus); + break; + default : + break; + } + } + *response = DAP_OK; + /* high 16-bits is request length, low 16-bits is responce length is 1. */ + return (sizeof(uint8_t) << 16U) | (1U); +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/var_monitor_process.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/var_monitor_process.c new file mode 100644 index 0000000000000000000000000000000000000000..a7dfbf5ff89380699099d2eac073f426fd046009 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/var_monitor_process.c @@ -0,0 +1,673 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file var_monitor_process.c + * @author MCU Driver Team + * @brief Variable monitoring protocol, The functions are as follows: + * + starting variable monitoring. + * + stopping variable monitoring. + * + suspending variable monitoring. + * + uploading variable monitoring data. + * + modifying variable values... + */ +#include +#include "securec.h" +#include "cmsis_os2.h" +#include "var_monitor_queue.h" +#include "debug.h" +#include "alloc.h" +#include "msg_queue.h" +#include "status.h" +#include "var_monitor_process.h" + + +struct DapStatistics { + unsigned long long totalSampleCount; + unsigned long long totalOverflowCount; + unsigned long long totalErrorCount; + unsigned int errorRate; +} g_dapStat = {0, 0, 0, 0}; +extern unsigned int g_vargStart; +static VarQueue *g_dapVarMonitorQueue = (VarQueue *)&g_vargStart; +static DapVarMonitor g_dapVarMonitor; +static DapWriteVar g_dapWriteVar; +static unsigned int g_dapVarMonitorQueueSize; +static uint8_t *g_dapVarFrameBuffer = NULL; +static uint32_t g_iSPerformanceTest = 0; +static uint32_t g_timeoutTimer = 0; +static int g_sendEndFlag = 1; +static unsigned int g_sendNum = 0; +static int g_framingCompatibleFlag; + +/** + * @brief Sends the variable list to the M core. + * @param varMonitorHandle Variable list information. + * @retval type: DAP_OK, DAP_ERROR. + */ +static int StartVariableSampling(DapVarMonitor *varMonitorHandle) +{ + DapLinkStatus daplinkStatus; + MsgBuf msgBuf; + unsigned int timeout = 10; + errno_t ret; + + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.dapDbgInfo.status = DAP_STATUS_SAMPLING; + DapLinkStatusSet(&daplinkStatus); + varMonitorHandle->isSample = true; + + /* Start Variable Sampling */ + msgBuf.type = MSG_TYPE_SAMPLING; + unsigned int bufLen1 = sizeof(unsigned int) + sizeof(unsigned int) + sizeof(unsigned int); + ret = memcpy_s((void *)&msgBuf.buf, bufLen1, (void *)varMonitorHandle, bufLen1); + if (ret != EOK) { + return DAP_ERROR; + } + unsigned int bufLen2 = varMonitorHandle->varNum * sizeof(DapVarList); + ret = memcpy_s((void *)&msgBuf.buf[bufLen1], bufLen2, (void *)varMonitorHandle->varList, bufLen2); + if (ret != EOK) { + return DAP_ERROR; + } + msgBuf.bufLen = bufLen1 + bufLen2; + MSGQ_SendMsg(&msgBuf); + memset_s(&msgBuf, sizeof(MsgBuf), 0, sizeof(MsgBuf)); + + while (MSGQ_ReceiveMsg(&msgBuf) && (timeout > 0)) { + timeout--; + osDelay(1); + } + if ((timeout == 0) || msgBuf.type != MSG_TYPE_SAMPLING || (msgBuf.buf[0] != MSG_OK)) { + return DAP_ERROR; + } + + /* Timestamp 4-byte. */ + g_dapVarMonitorQueueSize = 4; + for (unsigned int i = 0; i < varMonitorHandle->varNum; i++) { + g_dapVarMonitorQueueSize += varMonitorHandle->varList[i].varNumBytes; + } + + MemFree(varMonitorHandle->varList); + varMonitorHandle->varList = NULL; + + g_dapVarFrameBuffer = (uint8_t *)MemAlloc(DAP_TRANSFER_MAX_PACKET_SIZE * sizeof(uint8_t)); + if (g_dapVarFrameBuffer == NULL) { + return DAP_ERROR; + } + /* Start Timer */ + g_timeoutTimer = HAL_GetTickUs(); + + return DAP_OK; +} + +/** + * @brief Batch Receive Variable List. + * @param varMonitorHandle Variable list information. + * @param request request buffer pointer. + * @param sendLength Length of the message sent to core M. + * @retval type: DAP_OK, DAP_ERROR. + */ +static int BatchVarTransfer(DapVarMonitor *varMonitorHandle, const uint8_t *request, unsigned int *sendLength) +{ + unsigned int lastSendNum; + int ret = DAP_OK; + unsigned int maskPos0; + unsigned int maskPos8; + unsigned int maskPos16; + unsigned int maskPos24; + + if (g_sendNum == 0) { + /* The first eight bytes are the sampling frequency and the number of variables. */ + request += VAR_LIST_PROTOCOL_POS; + } + lastSendNum = g_sendNum; + maskPos0 = (*(request++) & MASK_POS_0); + maskPos8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPos16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPos24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + g_sendNum = maskPos0 | maskPos8 | maskPos16 | maskPos24; + + /* The sent length is 4 + g_sendNum * 8. */ + *sendLength = (4 + g_sendNum * 8); + g_sendNum += lastSendNum; + if (g_sendNum == varMonitorHandle->varNum) { + g_sendEndFlag = 1; + } + + for (unsigned int i = lastSendNum; i < g_sendNum; i++) { + maskPos0 = (*(request++) & MASK_POS_0); + maskPos8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPos16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPos24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + varMonitorHandle->varList[i].varAddress = maskPos0 | maskPos8 | maskPos16 | maskPos24; + maskPos0 = (*(request++) & MASK_POS_0); + maskPos8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPos16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPos24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + varMonitorHandle->varList[i].varNumBytes = maskPos0 | maskPos8 | maskPos16 | maskPos24; + } + + if (g_sendEndFlag != 0) { + ret = StartVariableSampling(varMonitorHandle); + } + + return ret; +} + +/** + * @brief One-time Receive Variable List. + * @param varMonitorHandle Variable list information. + * @param request request buffer pointer. + * @retval type: DAP_OK, DAP_ERROR. + */ +static int OneTimeVarTransfer(DapVarMonitor *varMonitorHandle, const uint8_t *request) +{ + int ret; + unsigned int maskPosition0; + unsigned int maskPosition8; + unsigned int maskPosition16; + unsigned int maskPosition24; + + /* The first eight bytes are the sampling frequency and the number of variables. */ + request += VAR_LIST_PROTOCOL_POS; + for (unsigned int i = 0; i < varMonitorHandle->varNum; i++) { + maskPosition0 = (*(request++) & MASK_POS_0); + maskPosition8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPosition16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPosition24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + varMonitorHandle->varList[i].varAddress = maskPosition0 | maskPosition8 | maskPosition16 | maskPosition24; + maskPosition0 = (*(request++) & MASK_POS_0); + maskPosition8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPosition16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPosition24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + varMonitorHandle->varList[i].varNumBytes = maskPosition0 | maskPosition8 | maskPosition16 | maskPosition24; + } + + ret = StartVariableSampling(varMonitorHandle); + + return ret; +} + +/** + * @brief Obtains the parameters of variable sampling. + * @param varMonitorHandle Variable list information. + * @param request request buffer pointer. + * @retval type: DAP_OK, DAP_ERROR. + */ +static int GetVarMonitorParam(DapVarMonitor *varMonitorHandle, const uint8_t *request) +{ + unsigned int maskPos0; + unsigned int maskPos8; + unsigned int maskPos16; + unsigned int maskPos24; + + maskPos0 = (*(request++) & MASK_POS_0); + maskPos8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPos16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPos24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + varMonitorHandle->periodUs = maskPos0 | maskPos8 | maskPos16 | maskPos24; + maskPos0 = (*(request++) & MASK_POS_0); + maskPos8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPos16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPos24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + varMonitorHandle->varNum = maskPos0 | maskPos8 | maskPos16 | maskPos24; + if (varMonitorHandle->varNum <= MAX_VAR_NUM) { + g_framingCompatibleFlag = 1; + } else { + g_framingCompatibleFlag = 0; + } + g_sendNum = 0; + + varMonitorHandle->varList = (DapVarList *)MemAlloc(varMonitorHandle->varNum * sizeof(DapVarList)); + if (varMonitorHandle->varList == NULL) { + DBG_PRINTF("varList malloc fail!\r\n"); + return DAP_ERROR; + } + + return DAP_OK; +} + +/** + * @brief The release interface is used to read variable data in the shared memory. + * @param maxTimes Maximum number of reads. + * @param response response buffer pointer. + * @retval Number of bytes actually read. + */ +static unsigned int ReadVarRelease(unsigned int maxTimes, uint8_t *response) +{ + unsigned long long readableSampleTimes; + unsigned long long maxTimesLong = maxTimes; + unsigned long long readFrameCountLong; + unsigned int readFrameCount; + unsigned int readQueueSize; + unsigned int retLen; + + if (g_framingCompatibleFlag != 0) { + readableSampleTimes = QueueReadableLength(g_dapVarMonitorQueue) / g_dapVarMonitorQueueSize; + } else { + readableSampleTimes = QueueReadableLength(g_dapVarMonitorQueue); + } + readFrameCountLong = readableSampleTimes > maxTimesLong ? maxTimesLong : readableSampleTimes; + readFrameCount = readFrameCountLong & MASK_LOW_32; + *response++ = (readFrameCount) & MASK_POS_0; + *response++ = (readFrameCount >> SHIFTS_8_BIT) & MASK_POS_0; + *response++ = (readFrameCount >> SHIFTS_16_BIT) & MASK_POS_0; + *response++ = (readFrameCount >> SHIFTS_24_BIT) & MASK_POS_0; + if (g_framingCompatibleFlag != 0) { + readQueueSize = readFrameCount * g_dapVarMonitorQueueSize; + } else { + readQueueSize = readFrameCount; + } + retLen = ReadQueue(g_dapVarMonitorQueue, response, readQueueSize); + /* No data in the queue exits the loop. */ + if (retLen != readQueueSize) { + readQueueSize = 0; + } + + return readQueueSize; +} + +/** + * @brief Frees the memory of the variable list. + * @param None. + * @retval None. + */ +static void FreeVarList(void) +{ + if (g_dapVarMonitor.varList != NULL) { + MemFree(g_dapVarMonitor.varList); + g_dapVarMonitor.varList = NULL; + } +} + +/** + * @brief Receives variable monitoring information and sends it to the M core. + * @param request request buffer pointer. + * @param response response buffer pointer. + * @retval high 16-bits is request length, low 16-bits is responce length. + */ +uint32_t DAP_VarMonitor(const uint8_t *request, uint8_t *response) +{ + unsigned int requestLength = 0; + unsigned int batchSendLength = 0; + int ret; + *response = DAP_OK; + + if (g_sendEndFlag != 0) { + g_sendEndFlag = 0; + ret = GetVarMonitorParam(&g_dapVarMonitor, request); + if (ret == DAP_ERROR) { + FreeVarList(); + *response = DAP_ERROR; + return (requestLength << 16U) | 1U; + } + + /* sizeof(periodUs + varNum) = 8 */ + requestLength = 8; + if (g_framingCompatibleFlag != 0) { + g_sendEndFlag = 1; + + ret = OneTimeVarTransfer(&g_dapVarMonitor, request); + if (ret == DAP_ERROR) { + FreeVarList(); + *response = DAP_ERROR; + return (requestLength << 16U) | 1U; + } + /* sizeof(DapVarList) = 8 */ + requestLength += g_dapVarMonitor.varNum * 8; + return (requestLength << 16U) | 1U; + } + } + + ret = BatchVarTransfer(&g_dapVarMonitor, request, &batchSendLength); + requestLength += batchSendLength; + if (ret == DAP_ERROR) { + FreeVarList(); + *response = DAP_ERROR; + return (requestLength << 16U) | 1U; + } + return (requestLength << 16U) | 1U; +} + +/** + * @brief Read variable data and upload it. + * @param request request buffer pointer. + * @param response response buffer pointer. + * @retval high 16-bits is request length, low 16-bits is responce length. + */ +uint32_t DAP_ReadVar(const uint8_t *request, uint8_t *response) +{ + unsigned int maxSampleTimes; + unsigned int readQueueSize; + unsigned int maskPos0; + unsigned int maskPos8; + unsigned int maskPos16; + unsigned int maskPos24; + errno_t ret = EOK; + + if (!g_dapVarMonitor.isSample) { + *response++ = 0; + *response++ = 0; + *response++ = 0; + *response++ = 0; + return (0U << 16U) | 4U; + } + + /* Clear the timer. */ + g_timeoutTimer = HAL_GetTickUs(); + + if (g_framingCompatibleFlag != 0) { + maxSampleTimes = DAP_TRANSFER_MAX_PACKET_SIZE / g_dapVarMonitorQueueSize; + ret = memset_s(g_dapVarFrameBuffer, g_dapVarMonitorQueueSize * maxSampleTimes, + 0, g_dapVarMonitorQueueSize * maxSampleTimes); + } else { + maskPos0 = (*(request++) & MASK_POS_0); + maskPos8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPos16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPos24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + maxSampleTimes = maskPos0 | maskPos8 | maskPos16 | maskPos24; + ret = memset_s(g_dapVarFrameBuffer, maxSampleTimes, 0, maxSampleTimes); + } + if (ret != EOK) { + return (0U << 16U) | 4U; + } + readQueueSize = ReadVarRelease(maxSampleTimes, response); + if (readQueueSize == 0) { + *response++ = 0; + *response++ = 0; + *response++ = 0; + *response++ = 0; + } + + return (0U << 16U) | (readQueueSize + 4U); +} + +/** + * @brief Sending a sampling stop instruction to the M core. + * @param None. + * @retval type: DAP_OK, DAP_ERROR. + */ +static uint32_t StopVarMonitor(void) +{ + uint32_t ret = DAP_OK; + MsgBuf msgBuf; + unsigned int timeout = 10; + errno_t rc = EOK; + + /* Stop Variable Sampling */ + g_dapVarMonitor.isSample = false; + msgBuf.type = MSG_TYPE_SAMPLING; + msgBuf.bufLen = sizeof(unsigned int); + rc = memcpy_s((void *)&msgBuf.buf, msgBuf.bufLen, (void *)&g_dapVarMonitor, msgBuf.bufLen); + if (rc != EOK) { + ret = DAP_ERROR; + goto STOP_ERR; + } + MSGQ_SendMsg(&msgBuf); + rc = memset_s(&msgBuf, sizeof(MsgBuf), 0, sizeof(MsgBuf)); + if (rc != EOK) { + ret = DAP_ERROR; + goto STOP_ERR; + } + while (MSGQ_ReceiveMsg(&msgBuf) && (timeout > 0)) { + timeout--; + osDelay(1); + } + if ((timeout <= 0) || msgBuf.type != MSG_TYPE_SAMPLING || (msgBuf.buf[0] != MSG_OK)) { + ret = DAP_ERROR; + } + +STOP_ERR: + if (g_dapVarFrameBuffer != NULL) { + MemFree(g_dapVarFrameBuffer); + g_dapVarFrameBuffer = NULL; + } + return ret; +} + +/** + * @brief End sampling. + * @param response response buffer pointer. + * @retval high 16-bits is request length, low 16-bits is responce length. + */ +uint32_t DAP_StopVarMonitor(uint8_t *response) +{ + uint32_t ret; + DapLinkStatus daplinkStatus; + ret = StopVarMonitor(); + + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.dapDbgInfo.status = DAP_STATUS_NOTWORKING; + DapLinkStatusSet(&daplinkStatus); + if (ret) { + *response = DAP_ERROR; + return (1U); + } + + *response = DAP_OK; + return (1U); +} + +/** + * @brief Pause/resume sampling. + * @param request request buffer pointer. + * @param response response buffer pointer. + * @retval high 16-bits is request length, low 16-bits is responce length. + */ +uint32_t DAP_PauseVarMonitor(const uint8_t *request, uint8_t *response) +{ + MsgBuf msgBuf; + unsigned int timeout = 10; + errno_t rc = EOK; + + msgBuf.type = MSG_TYPE_PAUSESAMPLING; + msgBuf.bufLen = sizeof(uint8_t); + rc= memcpy_s((void *)&msgBuf.buf, msgBuf.bufLen, request, msgBuf.bufLen); + if (rc != EOK) { + *response = DAP_ERROR; + return (sizeof(uint8_t) << 16U) | (1U); + } + MSGQ_SendMsg(&msgBuf); + rc = memset_s(&msgBuf, sizeof(MsgBuf), 0, sizeof(MsgBuf)); + if (rc != EOK) { + *response = DAP_ERROR; + return (sizeof(uint8_t) << 16U) | (1U); + } + while (MSGQ_ReceiveMsg(&msgBuf) && (timeout > 0)) { + timeout--; + osDelay(1); + } + if ((timeout <= 0) || msgBuf.type != MSG_TYPE_PAUSESAMPLING || (msgBuf.buf[0] != MSG_OK)) { + *response = DAP_ERROR; + return (sizeof(uint8_t) << 16U) | (1U); + } + + *response = DAP_OK; + return (sizeof(uint8_t) << 16U) | (1U); +} + +/** + * @brief Status detection. + * @param None. + * @retval None. + */ +void DAP_StatusDetection(void) +{ + uint32_t curTicks; + uint32_t delta; + DapLinkStatus daplinkStatus; + + if (g_dapVarMonitor.isSample) { + curTicks = HAL_GetTickUs(); + delta = GetTickDelta(curTicks, g_timeoutTimer); + if (delta >= DISCONNECT_SESSION_TIMEOUT) { + StopVarMonitor(); + DBG_PRINTF("SAMPLEOFFEXCEPTION\r\n"); + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.dapDbgInfo.status = DAP_STATUS_SAMPLEOFFEXCEPTION; + DapLinkStatusSet(&daplinkStatus); + } + if (g_dapVarMonitorQueue->exceptionExitFlag) { + StopVarMonitor(); + DBG_PRINTF("GDBEXCEPTIONEXIT\r\n"); + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.dapDbgInfo.status = DAP_STATUS_GDBEXCEPTIONEXIT; + daplinkStatus.dapDbgInfo.errorRate = g_dapVarMonitorQueue->errorRate; + DapLinkStatusSet(&daplinkStatus); + } + } +} + +/** + * @brief Update DAP statistics. + * @param None. + * @retval None. + */ +void UpdateDapStatistics(void) +{ + uint32_t flag = 0; + if (!g_dapVarMonitor.isSample) { + return; + } + if (g_dapVarMonitorQueue->totalSampleCount != g_dapStat.totalSampleCount) { + g_dapStat.totalSampleCount = g_dapVarMonitorQueue->totalSampleCount; + flag = 1; + } + if (g_dapVarMonitorQueue->totalOverflowCount != g_dapStat.totalOverflowCount) { + g_dapStat.totalOverflowCount = g_dapVarMonitorQueue->totalOverflowCount; + flag = 1; + } + if (g_dapVarMonitorQueue->totalErrorCount != g_dapStat.totalErrorCount) { + g_dapStat.totalErrorCount = g_dapVarMonitorQueue->totalErrorCount; + flag = 1; + } + if (g_dapVarMonitorQueue->errorRate != g_dapStat.errorRate) { + g_dapStat.errorRate = g_dapVarMonitorQueue->errorRate; + flag = 1; + } + if (flag) { + DapLinkStatus daplinkStatus; + DapLinkStatusGet(&daplinkStatus); + daplinkStatus.dapDbgInfo.totalSampleCount = g_dapStat.totalSampleCount; + daplinkStatus.dapDbgInfo.totalOverflowCount = g_dapStat.totalOverflowCount; + daplinkStatus.dapDbgInfo.totalErrorCount = g_dapStat.totalErrorCount; + daplinkStatus.dapDbgInfo.errorRate = g_dapStat.errorRate; + DapLinkStatusSet(&daplinkStatus); + } +} + +/** + * @brief Writing Variables. + * @param request request buffer pointer. + * @param response response buffer pointer. + * @retval high 16-bits is request length, low 16-bits is responce length. + */ +uint32_t DAP_WriteVar(const uint8_t *request, uint8_t *response) +{ + MsgBuf msgBuf; + unsigned int timeout = 10; + unsigned int maskPos0; + unsigned int maskPos8; + unsigned int maskPos16; + unsigned int maskPos24; + errno_t rc = EOK; + + maskPos0 = (*(request++) & MASK_POS_0); + maskPos8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPos16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPos24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + g_dapWriteVar.address = maskPos0 | maskPos8 | maskPos16 | maskPos24; + maskPos0 = (*(request++) & MASK_POS_0); + maskPos8 = ((*(request++) << SHIFTS_8_BIT) & MASK_POS_8); + maskPos16 = ((*(request++) << SHIFTS_16_BIT) & MASK_POS_16); + maskPos24 = ((*(request++) << SHIFTS_24_BIT) & MASK_POS_24); + g_dapWriteVar.len = maskPos0 | maskPos8 | maskPos16 | maskPos24; + /* sizeof(value) = 8 */ + rc = memcpy_s(&g_dapWriteVar.value, MAX_WRITE_BYTE_VALUE, request, MAX_WRITE_BYTE_VALUE); + if (rc != EOK) { + *response = DAP_ERROR; + return (sizeof(DapWriteVar) << 16U) | (1U); + } + + msgBuf.type = MSG_TYPE_WRITEVAR; + msgBuf.bufLen = sizeof(DapWriteVar); + rc = memcpy_s((void *)&msgBuf.buf, msgBuf.bufLen, (void *)&g_dapWriteVar, msgBuf.bufLen); + if (rc != EOK) { + *response = DAP_ERROR; + return (sizeof(DapWriteVar) << 16U) | (1U); + } + MSGQ_SendMsg(&msgBuf); + rc = memset_s(&msgBuf, sizeof(MsgBuf), 0, sizeof(MsgBuf)); + if (rc != EOK) { + *response = DAP_ERROR; + return (sizeof(DapWriteVar) << 16U) | (1U); + } + while (MSGQ_ReceiveMsg(&msgBuf) && (timeout > 0)) { + timeout--; + osDelay(1); + } + if ((timeout <= 0) || msgBuf.type != MSG_TYPE_WRITEVAR || (msgBuf.buf[0] != MSG_OK)) { + *response = DAP_ERROR; + return (sizeof(DapWriteVar) << 16U) | (1U); + } + + *response = DAP_OK; + return (sizeof(DapWriteVar) << 16U) | (1U); +} + +/** + * @brief Performance test interface. + * @param flag performance test flag. + * @retval None. + */ +void SetPerformanceTest(unsigned int flag) +{ + MsgBuf msgBuf; + unsigned int timeout = 10; + errno_t rc = EOK; + + msgBuf.type = MSG_TYPE_PERFORMANCE_TEST; + msgBuf.bufLen = sizeof(unsigned int); + rc = memcpy_s((void *)&msgBuf.buf, msgBuf.bufLen, (void *)&flag, msgBuf.bufLen); + if (rc != EOK) { + return; + } + MSGQ_SendMsg(&msgBuf); + + rc = memset_s(&msgBuf, sizeof(MsgBuf), 0, sizeof(MsgBuf)); + if (rc != EOK) { + return; + } + while (MSGQ_ReceiveMsg(&msgBuf) && (timeout > 0)) { + timeout--; + osDelay(1); + } + if ((timeout <= 0) || msgBuf.type != MSG_TYPE_PERFORMANCE_TEST || (msgBuf.buf[0] != MSG_OK)) { + DBG_PRINTF("SetPerformanceTest fail!!"); + } else { + g_iSPerformanceTest = flag; + } +} + +/** + * @brief get Performance test flag. + * @param None. + * @retval Performance test flag. + */ +uint32_t GetPerformanceTest(void) +{ + return g_iSPerformanceTest; +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/var_monitor_queue.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/var_monitor_queue.c new file mode 100644 index 0000000000000000000000000000000000000000..cd9afaeb264e64d07f672b187d56054b94711804 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/dap_ext_features/source/var_monitor_queue.c @@ -0,0 +1,93 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file var_monitor_queue.h + * @author MCU Driver Team + * @brief Shared queue for storing variable monitoring data. + */ +#include +#include +#include "securec.h" +#include "var_monitor_queue.h" + + +/** + * @brief whether a queue is empty. + * @param q pointer of queue. + * @retval Whether the value is empty. + */ +static bool QueueEmpty(VarQueue *q) +{ + return (q->totalReadSize == q->totalWriteSize); +} + +/** + * @brief read buffers from queue. + * @param q pointer of queue. + * @param buf pointer of read buffer. + * @param len read length. + * @retval Length of a successful read. + */ +unsigned int ReadQueue(VarQueue *q, unsigned char *buf, unsigned int len) +{ + unsigned long long rest = q->size - q->read; + unsigned int ret = 0; + errno_t rc = EOK; + unsigned long long length = q->totalWriteSize - q->totalReadSize; + + if (q->totalReadSize >= q->totalWriteSize) { + return ret; + } + if (QueueEmpty(q)) { + return ret; + } + + if (length >= len) { + ret = len; + if (rest >= len) { + rc = memcpy_s((void *)buf, len, (void *)(q->buf + q->read), len); + if (rc != EOK) { + return 0; + } + q->read = (q->read + len) % q->size; + q->totalReadSize += len; + } else { + rc = memcpy_s((void *)buf, len, (void *)(q->buf + q->read), rest); + if (rc != EOK) { + return 0; + } + q->read = 0; + rc = memcpy_s((void *)(buf + rest), len, (void *)q->buf, len - rest); + if (rc != EOK) { + return 0; + } + q->read = len - rest; + q->totalReadSize += len; + } + } + return ret; +} + +/** + * @brief the readable length in the queue. + * @param q pointer of queue. + * @retval the readable length in the queue. + */ +unsigned long long QueueReadableLength(VarQueue *q) +{ + return (q->totalWriteSize - q->totalReadSize); +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/debug/debug.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/debug/debug.c new file mode 100644 index 0000000000000000000000000000000000000000..80bb68da98bc25158e7d2505d9e47bacd6ae2266 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/debug/debug.c @@ -0,0 +1,342 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file debug.c + * @author MCU Driver Team + * @brief DEBUG module driver. + * This file provides functions to manage the following functionalities of the DEBUG module. + * + Initialization and de-initialization functions + * + Format string print function + */ + +/* Includes ------------------------------------------------------------------*/ +#include "debug.h" + +/* Macro definitions ---------------------------------------------------------*/ +#if (DBG_PRINTF_USE == DBG_USE_CUSTOM_PRINTF) +/* Macro definitions of stdarg.h to prevent using standard library */ +#define VA_START(v, l) __builtin_va_start(v, l) +#define VA_ARG(v, l) __builtin_va_arg(v, l) +#define VA_END(v) __builtin_va_end(v) + +#define DECIMAL_BASE 10U /**< Cardinality of decimal numbers */ +#define HALF_ADJUST_BOUNDARY 5U /**< The boundary for rounding the floating number */ +#define FLOAT_PRECISION 5U /**< Precision of the decimal part in floating number */ +/* FLOAT_SCALE = DECIMAL_BASE ^ (FLOAT_PRECISION + 1) */ +#define FLOAT_SCALE DBG_Pow(DECIMAL_BASE, (FLOAT_PRECISION + 1)) /**< Scale of the decimal part in floating number */ +#endif + +/* Typedef definitions ----------------------------------------------------------------*/ +typedef __builtin_va_list va_list; + +#if (DBG_PRINTF_USE == DBG_USE_CUSTOM_PRINTF) +/** + * @brief Cardinality of binary, octal, decimal, and hexadecimal numbers. + */ +typedef enum { + BINARY = 2U, + OCTAL = 8U, + DECIMAL = 10U, + HEXADECIMAL = 16U, +} NumBase; +#endif + +/* Initialization and de-initialization functions -------------------------------------*/ +#if (DBG_PRINTF_USE == DBG_USE_CUSTOM_PRINTF) +/** + * @brief Initialize the UART port for DBG_UartPrintf(). + * @param baudRate The baud rate of UART port. + * @retval BSP_StatusType BSP return type: OK, ERROR, BUSY, TIMEOUT. + */ +BSP_StatusType DBG_UartPrintInit(unsigned int baudRate) +{ +#ifdef NEED_UART_INIT + UART_Init(baudRate); +#endif + return BSP_OK; +} + +/** + * @brief De-initialize the UART port for DBG_UartPrintf(). + * @retval BSP_StatusType BSP return type: OK, ERROR, BUSY, TIMEOUT. + */ +BSP_StatusType DBG_UartPrintDeInit(void) +{ + return BSP_OK; +} +#endif + +/* Format string print function -------------------------------------------------------*/ +#if (DBG_PRINTF_USE == DBG_USE_CUSTOM_PRINTF) +/** + * @brief Write a character to the UART port. + * @param ch The int promotion of the character to be written. + * @retval None. + */ +static void DBG_PrintCh(unsigned int ch) +{ + UART_Out(ch); +} + +/** + * @brief Print a string through the UART port. + * @param str The string to be printed. + * @retval int If successed, the total number of characters printed is returned. + * If the input paremeter is wrong, a BSP_ERROR is returned. + */ +static int DBG_PrintStr(const char *str) +{ + DEBUG_ASSERT_PARAM(str != NULL); + int cnt = 0; + const char *p = str; + while (*p != '\0') { + DBG_PrintCh(*p); + p++; + cnt++; + } + return cnt; +} + +/** + * @brief Raise base value to the power exponent value. + * @param base Base value. + * @param exponent Exponent value. + * @retval unsigned long The result of raising base to the power exponent. + */ +static unsigned long DBG_Pow(unsigned int base, unsigned int exponent) +{ + unsigned long ret = 1; + unsigned int exp = exponent; + while (exp--) { + ret *= base; + } + return ret; /* ret = base ^ exponent */ +} + +/** + * @brief Count the digits of the number. + * @param num The number to be counted. + * @param base The number base of num. + * @retval unsigned int The number of digits. + */ +static unsigned int DBG_CountDigits(int num, NumBase base) +{ + unsigned int cnt = 0; + int n = num; + if (base == 0) { + return 0; + } + while (n != 0) { + cnt++; + n /= base; + } + return cnt; +} + +/** + * @brief Print unsigned number through UART port. + * @param num The unsigned number to be printed. + * @param base The number base of num. + * @param digits The digits of num. + */ +static void DBG_PutUnsignedNum(unsigned int num, NumBase base, unsigned int digits) +{ + unsigned char ch; + unsigned int d = digits; + unsigned int n = num; + while (d != 0) { + ch = n / DBG_Pow(base, d - 1); + n %= DBG_Pow(base, d - 1); + if (base == DECIMAL) { + DBG_PrintCh(ch + '0'); + } else if (base == HEXADECIMAL) { + if (ch < DECIMAL_BASE) { + DBG_PrintCh(ch + '0'); + } else { + DBG_PrintCh(ch - DECIMAL_BASE + 'A'); + } + } + d--; + } +} + +/** + * @brief Print decimal number through UART port. + * @param intNum The decimal number to be printed. + * @retval unsigned int The total number of characters printed. + */ +static unsigned int DBG_PrintInt(int intNum) +{ + unsigned int cnt; + int num = intNum; + if (num == 0) { + DBG_PrintCh('0'); + return 1; + } + if (num < 0) { + DBG_PrintCh('-'); + num = -num; + } + cnt = DBG_CountDigits(num, DECIMAL); + DBG_PutUnsignedNum(num, DECIMAL, cnt); + return cnt; +} + +/** + * @brief Print hexadecimal number through UART port. + * @param hexNum The hexadecimal number to be printed. + * @retval unsigned int The total number of characters printed. + */ +static unsigned int DBG_PrintHex(unsigned int hexNum) +{ + unsigned int cnt; + if (hexNum == 0) { + DBG_PrintCh('0'); + return 1; + } + cnt = DBG_CountDigits(hexNum, HEXADECIMAL); + DBG_PutUnsignedNum(hexNum, HEXADECIMAL, cnt); + return cnt; +} + +/** + * @brief Print floating-point number through UART port. + * @param fltNum The floating-point number to be printed. + * @retval unsigned int The total number of characters printed. + */ +static unsigned int DBG_PrintFlt(float fltNum) +{ + unsigned int cnt = 0; + float f = fltNum; + if (f < 0) { + DBG_PrintCh('-'); + cnt += 1; + f = -f; + } + int integerVal = (int)f; + int floatVal = (long)(FLOAT_SCALE * (f - integerVal)); + /* Half-adjust: round up or round down */ + if (floatVal % DECIMAL_BASE >= HALF_ADJUST_BOUNDARY) { + floatVal = floatVal / DECIMAL_BASE + 1; + } else { + floatVal = floatVal / DECIMAL_BASE; + } + cnt += DBG_PrintInt(integerVal); + DBG_PrintCh('.'); + cnt += 1; + /* Pad 0 in float part */ + unsigned int fltCnt = DBG_CountDigits(floatVal, DECIMAL); + if (FLOAT_PRECISION > fltCnt) { + for (unsigned int i = 0; i < FLOAT_PRECISION - fltCnt; i++) { + DBG_PrintCh('0'); + } + } + DBG_PutUnsignedNum(floatVal, DECIMAL, fltCnt); + cnt += FLOAT_PRECISION; + return cnt; +} + +/** + * @brief Parse the format specifier and print the parameter by format. + * @param ch The format specifier. + * @param paramList The pointer of the variable parameter list. + * @retval unsigned int The total number of characters printed. + */ +static unsigned int ParseSpecifier(const char ch, const va_list *paramList) +{ + unsigned int cnt = 0; + unsigned int tmpCnt; + char chVal = 0; + const char *strVal = NULL; + int intVal = 0; + unsigned int unsignedVal = 0; + unsigned int hexVal = 0; + float fltVal = 0; + switch (ch) { + case 'c': + chVal = VA_ARG(*paramList, int); /* Use type int because of byte alignment */ + DBG_PrintCh(chVal); + cnt += 1; + break; + case 's': + strVal = VA_ARG(*paramList, const char *); + cnt += DBG_PrintStr(strVal); + break; + case 'd': + intVal = VA_ARG(*paramList, int); + cnt += DBG_PrintInt(intVal); + break; + case 'u': + unsignedVal = VA_ARG(*paramList, unsigned int); + tmpCnt = DBG_CountDigits(unsignedVal, DECIMAL); + DBG_PutUnsignedNum(unsignedVal, DECIMAL, tmpCnt); + cnt += tmpCnt; + break; + case 'x': + case 'X': + case 'p': + hexVal = VA_ARG(*paramList, unsigned int); + cnt += DBG_PrintHex(hexVal); + break; + case 'f': + fltVal = VA_ARG(*paramList, double); + cnt += DBG_PrintFlt(fltVal); + break; + default: + DBG_PrintCh(ch); + cnt += 1; + break; + } + return cnt; +} + +/** + * @brief Print format string through UART port, supporting %c, %s, %d, %u, %x, %X, %p, %f. + * %c To print a character. + * %s To print a string. + * %d To print a decimal value. + * %u To print an unsigned decimal value. + * %x, %X To print a hexadecimal value using upper case letters. + * %p To print a pointer as a hexadecimal value. + * %f To print a floating-point number with a fixed precision determined by FLOAT_PRECISION. + * @param format A string that contains the text to be printed and the format specifiers. + * @param ... Variable parameter list. + * @retval int If successed, the total number of characters printed is returned. + * If the input paremeter is wrong, return BSP_ERROR. + */ +int DBG_UartPrintf(const char *format, ...) +{ + DEBUG_ASSERT_PARAM(format != NULL); + int cnt = 0; + const char *p = format; + va_list paramList; + VA_START(paramList, format); + + while (*p != '\0') { + if (*p != '%') { + DBG_PrintCh(*p); + cnt += 1; + } else { + p++; + cnt += ParseSpecifier(*p, ¶mList); + } + p++; + } + VA_END(paramList); + return cnt; +} +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/debug/debug.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/debug/debug.h new file mode 100644 index 0000000000000000000000000000000000000000..2f523f3e404a70cb88cdd9f74f2373d98d794bd7 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/debug/debug.h @@ -0,0 +1,73 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file debug.h + * @author MCU Driver Team + * @brief Header file containing functions prototypes of DEBUG module. + * + Initialization and de-initialization functions + * + Format print function + */ + +/* Define to prevent recursive inclusion --------------------------------------------*/ +#ifndef MCU_MAGIC_TAG_DEBUG_H +#define MCU_MAGIC_TAG_DEBUG_H + +/* Includes -------------------------------------------------------------------------*/ +#include "uart.h" + +/* Macro definitions ----------------------------------------------------------------*/ +#ifdef DEBUG_PARAM_CHECK +#define DEBUG_ASSERT_PARAM BSP_ASSERT_PARAM +#else +#define DEBUG_ASSERT_PARAM(para) ((void)0U) +#endif + +typedef enum { + BSP_OK = 0x00000000U, + BSP_ERROR = 0x00000001U, + BSP_BUSY = 0x00000002U, + BSP_TIMEOUT = 0x00000003U +} BSP_StatusType; + +/* Macro definitions for enabling the function of DEBUG_PRINT submodule */ +#define DBG_USE_NO_PRINTF 1U +#define DBG_USE_CUSTOM_PRINTF 2U + +#define DBG_PRINTF_USE DBG_USE_NO_PRINTF /**< Select the format print function */ +#define DBG_UART_PORT UART4 /**< Select the UART PORT used for format print */ + +#if (DBG_PRINTF_USE == DBG_USE_NO_PRINTF) +static inline int DBG_Dummy(const char *format, ...) +{ + return 0; +} +#define DBG_PRINTF DBG_Dummy /**< Delete all print statement */ +#endif + +#if (DBG_PRINTF_USE == DBG_USE_CUSTOM_PRINTF) +#define DBG_PRINTF_UART_PORT DBG_UART_PORT +#define DBG_PRINTF DBG_UartPrintf /**< Select the customized printf function */ +#endif + +/* Initialization and de-initialization functions of DEBUG module ------------------*/ +BSP_StatusType DBG_UartPrintInit(unsigned int baudRate); +BSP_StatusType DBG_UartPrintDeInit(void); + +/* Format print function -----------------------------------------------------------*/ +int DBG_UartPrintf(const char *format, ...); /* Supported format: %c, %s, %d, %u, %x, %X, %p, %f */ + +#endif /* MCU_MAGIC_TAG_DEBUG_H */ diff --git a/src/middleware/hisilicon/nostask/include/common/os_errno.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/display.h similarity index 36% rename from src/middleware/hisilicon/nostask/include/common/os_errno.h rename to src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/display.h index 9be95b69c7002516577df0c230deaec683a92fe7..3e76d6989658ed1ff0702e3c696718beb3bfceb9 100644 --- a/src/middleware/hisilicon/nostask/include/common/os_errno.h +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/display.h @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,95 +15,112 @@ * 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. - * @file os_errno.h + * @file display.h + * @author MCU Driver Team + * @brief Display Header */ -#ifndef OS_ERRNO_H -#define OS_ERRNO_H - -#include "os_typedef.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -/* - * @ingroup OS_err - * OS错误码标记位。(0x00表示Guest OS,0xFF表示DRV,0x01表示Host OS - * - */ -#define ERRNO_OS_ID (0x00U << 16) - -/* - * @ingroup OS_err - * 定义错误的等级:提示级别 - * - */ -#define ERRTYPE_NORMAL (0x00U << 24) - -/* - * @ingroup OS_err - * 定义错误的等级:告警级别 - * - */ -#define ERRTYPE_WARN (0x01U << 24) - -/* - * @ingroup OS_err - * 定义错误的等级:严重级别 - * - */ -#define ERRTYPE_ERROR (0x02U << 24) - -/* - * @ingroup OS_err - * 定义错误的等级:致命级别 - * - */ -#define ERRTYPE_FATAL (0x03U << 24) - -/* - * @ingroup OS_err - * Description: 定义OS致命错误。 - * - * @par 描述 - * 宏定义,定义OS致命错误。 - * - * @attention 无 - * - * @param mid [IN] 模块ID编号。 - * @param errno [IN] 错误码编号。 - * - * @retval 无 - * @par 依赖 - * os_errno.h: 该宏定义所在的头文件。 - * @see OS_ERRNO_BUILD_ERROR | OS_ERRNO_BUILD_WARN | OS_ERRNO_BUILD_NORMAL - */ -#define OS_ERRNO_BUILD_FATAL(mid, errno) (ERRTYPE_FATAL | ERRNO_OS_ID | ((unsigned int)(mid) << 8) | (errno)) - -/* - * @ingroup OS_err - * Description: 定义OS严重错误 - * - * @par 描述 - * 宏定义,定义OS严重错误 - * - * @attention 无 - * @param mid [IN] 模块ID编号。 - * @param errno [IN] 错误码编号。 - * - * @retval 无 - * @par 依赖 - * os_errno.h: 该宏定义所在的头文件。 - * @see OS_ERRNO_BUILD_FATAL | OS_ERRNO_BUILD_WARN | OS_ERRNO_BUILD_NORMAL - */ -#define OS_ERRNO_BUILD_ERROR(mid, errno) (ERRTYPE_ERROR | ERRNO_OS_ID | ((unsigned int)(mid) << 8) | (errno)) - -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#endif /* OS_ERRNO_H */ + +#ifndef DISPLAY_H +#define DISPLAY_H + +#include +#include "display_common.h" + +#ifndef SOFTWARE_VERSION +#define SOFTWARE_VERSION "1.0.0.5B06" +#endif + +#define SOFTWARE_B_VERSION "B001" +#define HARDWARE_VERSION "V1.00" + +#define ITEM_LIST_MAX_LEN 128 +#define EXT_INFO_MAX_LEN 72 + +#define LED_LINE_LEN 24 + +typedef enum { + ALIGN_MID = 0, + ALIGN_LEFT = 1, +} DisplayAlignMode; + +typedef struct ItemStruct Item; +typedef struct FrameStruct Frame; + +typedef void (*SelectedProc)(Frame *frame); +typedef unsigned int (*GetExtText)(char *buf, unsigned int len); +typedef void (*CreateDynItemProc)(Frame *frame); +typedef void (*PopUpMsg)(Frame *frame); + +typedef enum { + FRAME_STATIC = 0, + FRAME_SHOW_MSG, + FRAME_DYN_ITEMS, +} FrameType; + +typedef struct { + unsigned int width; + unsigned int high; +} WinSize; + +struct ItemStruct { + char *text[LANGUAGE_NUM]; + SelectedProc itemSelectedProc; + Frame *linkFrame; + GetExtText getInfo; + unsigned short windowsMenu; + unsigned short title; + unsigned int userData; +}; + +struct FrameStruct { + unsigned char pointer; + unsigned char begin; + unsigned char winSize; + size_t lineNumber; + size_t staticItemNum; + unsigned char rollEn; + unsigned char minPointer; + unsigned char onlySupportSelected; + Item *pItem; + CreateDynItemProc genDynItems; + PopUpMsg popupMsg; + char *name; + Frame *dynItemSelectFrame; + Frame *dynFailItemSelectFrame; + Frame *moveToEndFrame; + unsigned int userData; +}; + +typedef struct { + unsigned char name[FILENAME_MAX_LEN]; +} FileName; + +typedef struct { + unsigned int width; + unsigned int high; + unsigned int showLineMask; + Language language; + Frame *frame; +} WinInfo; + +void DisplayInit(void); + +void FrameShow(Frame *frame); +Frame *GetCurFrame(void); +Language GetWinLanguage(void); +void SetWinLanguage(Language lang); +void FrameMoveUp(void); +void FrameMoveDown(void); +void FrameItemSelect(void); +void FramePopMsg(const Frame *frame, const char *msg); +bool GetFWVersion(char *buf, unsigned int bufLen); +bool GetHWVersion(char *buf, unsigned int bufLen); +bool GetSN(char *buf, unsigned int bufLen); +void FrameShowStatusBar(const Frame *frame, const char *status); +void ReservedScreen(void); +void FramePopMsgWithFont(const Frame *frame, const char *msg, int font); +void FramePopMsgWithTitle(const Frame *frame, const char *title, const char **msg, int msgNum, DisplayAlignMode mode); +void UpdateActiveFrame(Frame *frame); +void DownLoadLedOn(Frame *frame); +void ForceAllLineUsed(void); +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/display_common.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/display_common.h new file mode 100644 index 0000000000000000000000000000000000000000..ae21eff72371400d896f37925c26740f2df95b85 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/display_common.h @@ -0,0 +1,49 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file display_common.h + * @author MCU Driver Team + * @brief Display Common Header + */ + +#ifndef DISPLAY_COMMON_H +#define DISPLAY_COMMON_H + +#include "util.h" + +#ifndef NULL +#define NULL (void *)0 +#endif + +#define MULTI_LANGUAGE(x) {x##_EN, x##_ZH} +#define GET_MULTILANGE_STR(x, language) ((language) == LANGUAGE_EN ? x##_EN : x##_ZH) + +#define WIN_HEIGHT (16 * 6) +#define WIN_WIDTH (24 * 8) +#define FONT_SIZE 16 +#define BIG_FONT_SIZE 32 +#define WIN_MAX_LINE ((WIN_HEIGHT) / (FONT_SIZE)) +#define ITEM_CONTEXT_MAX_LEN 48 +#define FILENAME_MAX_LEN 128 + +typedef enum { + LANGUAGE_EN = 0, + LANGUAGE_CN = 1, + LANGUAGE_NUM = 2, +} Language; + +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/menu_tbl.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/menu_tbl.h new file mode 100644 index 0000000000000000000000000000000000000000..c8b31eb648bae7a105adfaf84a66897ae3f842b8 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/menu_tbl.h @@ -0,0 +1,42 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file menu_tbl.h + * @author MCU Driver Team + * @brief menu table Header + */ + +#ifndef MENU_TBL_H +#define MENU_TBL_H + +#include +#include "display.h" + +Frame *GetDefaultFrame(void); +Frame *GetFactoryImageAlgoNoMatchFrame(void); +Frame *GetFactoryImageProgramFrame(void); +Frame *GetFactoryImageRestrictedFrame(void); +Frame *GetFactoryImageProgramSuccFrame(void); +Frame *GetFactoryImageProgramFailFrame(void); +Frame *GetImageProgramFailFrame(void); + +bool IsDbgStatusFrame(void); +bool IsFactoryImageProgramSuccFrame(void); +bool IsProgramFailFrame(void); +void SettingFrameItemsWithNoPowerSupply(void); + +#endif diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/proc.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/proc.h new file mode 100644 index 0000000000000000000000000000000000000000..2a47fdd6cfde4b62ee1b0cbe4cb5eb42b98266cc --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/proc.h @@ -0,0 +1,102 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file proc.h + * @author MCU Driver Team + * @brief Display process Header + */ + +#ifndef PROC_H +#define PROC_H + +#include "target_lib_manager.h" + +#define MSG_MAX_LEN 128 +#define SN_MAX_LEN 24 +#define VER_MAX_LEN 12 + +typedef struct { + unsigned int enableMultiCopies; + char swVersion[VER_MAX_LEN]; + char hwVersion[VER_MAX_LEN]; + char sn[SN_MAX_LEN]; + unsigned int enableHsSampling; + unsigned int enablePowerSupply; + unsigned int enableFactory; +} DeviceConfig; + +void DbgFrameProc(Frame *frame); +void FirmwareUpgradeMsgPopup(Frame *frame); +void ImageUpgradeMsgPopup(Frame *frame); +void ErrorImageUpgradeMsgPopup(Frame *frame); +void FactoryImageUpgradeMsgPopup(Frame *frame); +void CrcCheckMsgPopup(Frame *frame); +void GetMoreImageMsgPopup(Frame *frame); +void RestoreFactory(Frame *frame); +void CreateSelectImageListFrame(Frame *frame); +void CreateDeleteImageListFrame(Frame *frame); +void CreateShowImageListFrame(Frame *frame); +void CreateFactoryImageListFrame(Frame *frame); +void AlgoSelectFrameProc(Frame *frame); +void ErrorAlgoSelectedMsgPopup(Frame *frame); +void CreateDeleteAlgoListFrame(Frame *frame); +void CreateShowAlgoListFrame(Frame *frame); +void CreateEraseListFrame(Frame *frame); +void DeleteAllImage(Frame *frame); +void DeleteAllAlgo(Frame *frame); +void SetLanguageToCN(Frame *frame); +void SetLanguageToEN(Frame *frame); +void SetInterfaceToSwd(Frame *frame); +void SetInterfaceToJtag(Frame *frame); +void EnableHsSampling(Frame *frame); +void DisableHsSampling(Frame *frame); +void EnablePowerSupply(Frame *frame); +void DisablePowerSupply(Frame *frame); +void EnableMultiCopies(Frame *frame); +void DisableMultiCopies(Frame *frame); +void GetMoreAlgoMsgPopup(Frame *frame); +void ImageDeleteMsgPopup(Frame *frame); +void AlgoDeleteMsgPopup(Frame *frame); +void NoImageMsgPopup(Frame *frame); +void NoAlgoMsgPopup(Frame *frame); +void NoFlashAlgoMsgPopup(Frame *frame); +bool LanguageEnglishSelected(char *buf, unsigned int len); +bool LanguageChineseSelected(char *buf, unsigned int len); +bool SwdInterfaceSelected(char *buf, unsigned int len); +bool JtagInterfaceSelected(char *buf, unsigned int len); +void RecoveryFactoryMsgPopup(Frame *frame); +bool GetMultiEnableSelected(char *buf, unsigned int len); +bool GetMultiDisableSelected(char *buf, unsigned int len); +bool GetHsSamplingEnableSelected(char *buf, unsigned int len); +bool GetHsSamplingDisableSelected(char *buf, unsigned int len); +bool GetPowerSupplyEnableSelected(char *buf, unsigned int len); +bool GetPowerSupplyDisableSelected(char *buf, unsigned int len); +void FactoryImageAlgoDelete(Frame *frame); +void ProcInit(void); +DeviceConfig *GetDevConfig(void); +void ExitFactoryMode(Frame *frame); +void EntryFactoryMode(Frame *frame); +void FactoryImageUpgrade(Frame *frame); +void FactoryDeleteMsgPopup(Frame *frame); +void CreateShowImageAndAlgoListFrame(Frame *frame); +void CreateDeleteImageAndAlgoListFrame(Frame *frame); +void CreateUnMatchAlgoListFrame(Frame *frame); +void EraseChipMsgPopup(Frame *frame); +void FlashProtectOffMsgPopup(Frame *frame); +void CreateImageRestrictedListFrame(Frame *frame); + +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/res_en.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/res_en.h new file mode 100644 index 0000000000000000000000000000000000000000..2ff893bc16e938bf9678b9fc4bb837e546742726 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/res_en.h @@ -0,0 +1,202 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file res_en.h + * @author MCU Driver Team + * @brief resource string of english header + */ +#ifndef RES_EN_H +#define RES_EN_H + +#define DBG_STATUS_EN "1.Debug Status" +#define FACTORY_MODE_EN "2.Factory Flasher" +#define FLASHER_MODE_EN "3.Flasher Mode" +#define FLASHER_ERASE_EN "4.Flasher Erase" +#define FLASHER_UNLOCK_EN "5.Flash Protection Off" +#define SETTING_EN "6.Setting" + +#define IMAGE_SELECT_EN "1.Upgrade Target Image" +#define IMAGE_DELETE_EN "2.Delete Target Image" +#define ALGO_SELECT_EN "3.Select Flash Algorithm" +#define ALGO_DELETE_EN "4.Delete Flash Algorithm" +#define ENABLE_MULTI_EN "5.Enable Multiple Copies" + +#define FACTORY_IMAGE_LOAD_EN "1.Upgrade Target Image" +#define FACTORY_CRC_CHECK_EN "2.Check Target Image" +#define FACTORY_VIEW_EN "3.View" +#define FACTORY_DELETE_EN "4.Delete" +#define FACTORY_EXIT_EN "5.Exit" + +#define LANGUAGE_SELECT_EN "1.Language" +#define POWER_SUPPLY_EN "2.Power Supply" +#define DBG_INTERFACE_EN "3.Debug Interface" +#define FW_VER_EN "4.Firmware: " +#define FW_UPGRADE_EN "5.Firmware Upgrade" +#define HW_VER_EN "6.Hardware: " +#define SN_EN "7.SN:" +#define HS_SAMPLE_SIMU_EN "8.HS Sampling Simulation" +#define RESTORE_EN "9.Restore Factory" + +#define OLD_DBG_INTERFACE_EN "2.Debug Interface" +#define OLD_FW_VER_EN "3.Firmware: " +#define OLD_FW_UPGRADE_EN "4.Firmware Upgrade" +#define OLD_HW_VER_EN "5.Hardware: " +#define OLD_SN_EN "6.SN:" +#define OLD_HS_SAMPLE_SIMU_EN "7.HS Sampling Simulation" +#define OLD_RESTORE_EN "8.Restore Factory" + +#define BACK_EN "Back" +#define TARGET_NOT_CONNECT_EN "Target Not Connected" +#define CONNECTED_EN "Connected" +#define TARGET_IS_RUNNING_EN "Target is running" +#define TARGET_IS_HALT_EN "Target is halt" +#define TARGET_IS_RESET_EN "Target is reset" + +#define IMAGE_STORED_EN "Image Stored!" +#define IMAGE_FAIL_EN "Image Fail!" +#define MULTI_COPIES_FAIL_EN "Can't Store Multiple Copies" +#define IMAGE_CRC_FAIL_EN "Image CRC Fail!" + +#define ALGO_STORED_EN "Alogrithm Stored!" +#define ALGO_DEFAULT_EN "Set as default" +#define ALGO_STORED_FAIL_EN "Algorithm Store Fail!" +#define ALGO_STORED_MULTI_COPIES_FAIL_EN "Algorithm Store Fail, Can't Store Multiple Copies" +#define ALGO_CRC_FAIL_EN "Algorithm CRC Fail!" + +#define FW_UPGRADEING_EN "Firmware Upgrade..." +#define FW_UPGRADE_SUCC_EN "Upgrade Success!" +#define FW_CRC_FAIL_EN "Firmware CRC Fail!" + +#define DAP_NOT_SAMPLING_EN "Not Working" +#define DAP_DEBGU_EN "Debuging" +#define DAP_SAMPLING_EN "Sampling" +#define DAP_TARGET_STOP_EN "Target Stop Sampling" +#define DAP_PC_STOP_EN "PC Stop Sampling" + + +#define DAP_SAMPLE_CNT_EN "Sampling:" +#define DAP_SAMPLE_ERROR_EN "Error:" +#define DAP_ERROR_RATE_EN "ErrorRate:" +#define DAP_OVERFLOW_CNT_EN "OverFlow:" + +#define SELECTED_EN "(Seleted)" + +#define DELETE_ALL_EN "1.Delete All" + +#define ON_EN "1.On" +#define OFF_EN "2.Off" + +#define LANGUAGE_SELECT_EN "1.Language" +#define FW_UPGRADE_MSG_EN "Please download firmware to this probe by PC tool" +#define GET_MORE_IMAGE_EN "Please download Image to this probe by PC tool" +#define GET_MORE_ALGO_EN "Please download Algorithm to this probe by PC tool" +#define GET_MORE_IMAGE_ALGO_EN "Please download Image and Algorithm to this probe by PC tool" + +#define GET_FLASH_ALGO_EN "Please download Algorithm to this probe by PC tool" +#define NO_FLASH_ALGO_EN "Flash drive missing" + +#define DEBUGGER_RST_EN "Factory Reset..." +#define DEBUGGER_RST_SUCC_EN "Factory Reset Done" + +#define CHINESE_EN "" +#define ENGLISH_EN "English" + +#define TARGET_UPGRADE_SUCC_EN "Target Upgrade Success" +#define TARGET_VERIFY_FAIL_EN "Target Verify Fail" +#define TARGET_WRITE_FAIL_EN "Target Write Fail" +#define TARGET_GET_IMAGE_FAIL_EN "Get Image Fail" +#define TARGET_VERIFYING_EN "Target Verifying..." +#define TARGET_PROGRAMMING_EN "Target Programing..." +#define TARGET_GET_ALGO_FAIL_EN "The Corresponding Algorithm was not found, please check whether it exists" +#define TARGET_CONNECTED_FAIL_EN "Target Connected Fail" +#define TARGET_NO_CONNECTED_EN "Target Not Connected" +#define TARGET_IMAGE_ERROR_EN "Image Error" +#define TARGET_ALGO_ERROR_EN "Algorithm Error" +#define IMAGE_UPGRADEING_EN "Image Upgrading..." +#define TARGET_RUN_ALGO_FAIL_EN "Run algo fail" +#define WELCOME_EN "Welcome to HiSpark-Trace" +#define TARGET_IMAGE_MAX_LOADS_ERROR_EN "The number of burning times exceeds the maximum" + +#define DELETEING_EN "Deleting..." +#define DELETE_SUCCESS_EN "Delete Success" +#define DELETE_FAIL_EN "Delete Fail" + +#define ERASEING_EN "Erasing..." +#define ERASE_SUCCESS_EN "Erase OK" +#define ERASE_FAIL_EN "Erase Fail" + +#define FACTORY_MODE_TITLE_EN " Factory Mode " + +#define MENU_EN "Menu" +#define CONNECT_RATE_EN " Rate:" +#define CRC_EXPECT_EN "Expected CRC:" +#define CRC_ACTUAL_EN "Actual CRC: " +#define CRC_CHK_LENGTH_EN "Chk Length:" +#define CRC_CHK_ADDR_EN "Chk Addr:" +#define CRC_CHK_SUCC_EN " CRC Is Correct " +#define CRC_CHK_FAIL_EN " Incorrect CRC " + +#define END_OF_LIST_EN "Reached the end of the list" +#define GET_IMAGE_FAIL_EN "Get Target Image Fail" + +#define IMAGE_EN "Image: " +#define ALGO_EN "Algorithm: " +#define EMPTY_EN "" +#define NO_IMAGE_EN "Image:" +#define NO_ALGO_EN "Algorithm:" + +#define MISS_IMAGE_EN "Miss Image" +#define MISS_ALGO_EN "Miss Algorithm" +#define MISS_IMAGE_ALGO_EN "Miss Image and Algorithm" + +#define IMAGE_ERROR_EN "Image Error" +#define ALGO_ERROR_EN "Algorithm Error" +#define IMAGE_ALGO_ERROR_EN "Image and Algorithm Error" + +#define IMAGE_ALGO_NO_MATCH_EN "Image and Algorithm not match" + +#define FACTORY_DEL_IMAGE_ALGO_EN "Delete Image and Algorithm" +#define FACTORY_DEL_IMAGE_EN "Delete Image:" +#define FACTORY_DEL_ALGO_EN "Delete Algo:" + +#define TIMES_EN "" +#define FILE_ERR_EN "CRC is incorrect" +#define FILE_ERROR_EN "(Bad)" + +#define DELETE_ALL_TITLE_EN " Delete All " +#define FACTORY_RESET_TITLE_EN " Factory Reset " +#define YES_EN "1.Yes" +#define NO_EN "2.No" + +#define IMAGE_ALGO_NO_MATCH_TITLE_EN "Image and Algo Not Match" +#define IMAGE_RESTRICTED_TITLE_EN " Prohibit Target Upgrade" + +#define CONTINUE_PROGRAM_EN "Program Continue" +#define CHIP_ERASE_TITLE_EN " Chip Erase " +#define READ_CRC_TITLE_EN " Read CRC " + +#define FLASH_PROTECT_OFF_RUNING_EN " Flash Protection Off..." +#define FLASH_PROTECT_OFF_EN " Flash Protection Off " +#define FLASH_PROTECT_OFF_SUCC_EN " Flash Protection Off OK" +#define FLASH_PROTECT_OFF_FAIL_EN " Flash Protection Off Fail " + +#define DOWNLOAD_EN "Cur" +#define PERIMIT_EN "Max" + +#define SWD_EN "SWD" +#define JTAG_EN "JTAG" +#endif diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/res_zh.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/res_zh.h new file mode 100644 index 0000000000000000000000000000000000000000..c2f22bee04d611a0f66a663366c756ca85ad3735 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/res_zh.h @@ -0,0 +1,200 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file res_zh.h + * @author MCU Driver Team + * @brief resource string of chinese header + */ + +#ifndef RES_ZH_H +#define RES_ZH_H + +#define DBG_STATUS_ZH "1.״̬" +#define FACTORY_MODE_ZH "2.¼" +#define FLASHER_MODE_ZH "3.ļ¼" +#define FLASHER_ERASE_ZH "4.Ƭ" +#define FLASHER_UNLOCK_ZH "5.Flash" +#define SETTING_ZH "6.ϵͳ" + +#define IMAGE_SELECT_ZH "1.ļ¼" +#define IMAGE_DELETE_ZH "2.ɾ¼ļ" +#define ALGO_SELECT_ZH "3.ѡĬק¼㷨" +#define ALGO_DELETE_ZH "4.ɾ¼㷨" +#define ENABLE_MULTI_ZH "5.洢汾" + +#define FACTORY_IMAGE_LOAD_ZH "1.¼" +#define FACTORY_CRC_CHECK_ZH "2.CRC" +#define FACTORY_VIEW_ZH "3.鿴" +#define FACTORY_DELETE_ZH "4.ɾ" +#define FACTORY_EXIT_ZH "5.˳" + +#define LANGUAGE_SELECT_ZH "1.ѡ" +#define POWER_SUPPLY_ZH "2.3.3V" +#define DBG_INTERFACE_ZH "3.Խӿ" +#define FW_VER_ZH "4.汾: " +#define FW_UPGRADE_ZH "5." +#define HW_VER_ZH "6.Ӳ汾: " +#define SN_ZH "7.к:" +#define HS_SAMPLE_SIMU_ZH "8.ٲģ(IDE)" +#define RESTORE_ZH "9.ָ" + +#define OLD_DBG_INTERFACE_ZH "2.Խӿ" +#define OLD_FW_VER_ZH "3.汾: " +#define OLD_FW_UPGRADE_ZH "4." +#define OLD_HW_VER_ZH "5.Ӳ汾: " +#define OLD_SN_ZH "6.к:" +#define OLD_HS_SAMPLE_SIMU_ZH "7.ٲģ(IDE)" +#define OLD_RESTORE_ZH "8.ָ" + +#define BACK_ZH "" +#define TARGET_NOT_CONNECT_ZH "Ŀ쳣" +#define CONNECTED_ZH "ĿOK" +#define TARGET_IS_RUNNING_ZH "Ŀ" +#define TARGET_IS_HALT_ZH "Ŀͣ" +#define TARGET_IS_RESET_ZH "Ŀ򱻸λ" + +#define IMAGE_STORED_ZH "¼ļɹ!" +#define IMAGE_FAIL_ZH "¼ļʧ!" +#define MULTI_COPIES_FAIL_ZH "洢汾" +#define IMAGE_CRC_FAIL_ZH "ļCRCУʧ!" + +#define ALGO_STORED_ZH "㷨ɹ!" +#define ALGO_DEFAULT_ZH "ΪĬ㷨" +#define ALGO_STORED_FAIL_ZH "㷨ʧ!" +#define ALGO_STORED_MULTI_COPIES_FAIL_ZH "㷨ʧ,洢汾" +#define ALGO_CRC_FAIL_ZH "㷨CRCУʧ!" + +#define FW_UPGRADEING_ZH "..." +#define FW_UPGRADE_SUCC_ZH "ɹ!" +#define FW_CRC_FAIL_ZH "CRCУʧ!" + +#define DAP_NOT_SAMPLING_ZH "ֹͣ" +#define DAP_DEBGU_ZH "" +#define DAP_SAMPLING_ZH "ڱ" +#define DAP_TARGET_STOP_ZH "쳣ֹͣ" +#define DAP_PC_STOP_ZH "Զ쳣ֹͣ" + +#define DAP_SAMPLE_CNT_ZH ":" +#define DAP_SAMPLE_ERROR_ZH ":" +#define DAP_ERROR_RATE_ZH ":" +#define DAP_OVERFLOW_CNT_ZH ":" + +#define SELECTED_ZH "(ѡ)" + +#define DELETE_ALL_ZH "1.ɾȫ" + +#define ON_ZH "1." +#define OFF_ZH "2.ر" + +#define FW_UPGRADE_MSG_ZH "ڵ\"ļع\"\"¼\"¼" +#define GET_MORE_IMAGE_ZH "ڵ\"ļع\"ѻ¼ļ" +#define GET_MORE_ALGO_ZH "ڵ\"ļع\"¼㷨" +#define GET_MORE_IMAGE_ALGO_ZH "ڵ\"ļع\"¼ļ㷨" + +#define GET_FLASH_ALGO_ZH "ڵ\"ļع\"㷨" +#define NO_FLASH_ALGO_ZH "ȱĿоƬFLASH" + + +#define DEBUGGER_RST_ZH "ڻָ..." +#define DEBUGGER_RST_SUCC_ZH "ָ" + +#define CHINESE_ZH "" +#define ENGLISH_ZH "English" + +#define TARGET_UPGRADE_SUCC_ZH "¼OK" +#define TARGET_VERIFY_FAIL_ZH "Уʧ" +#define TARGET_WRITE_FAIL_ZH "¼ʧ" +#define TARGET_GET_IMAGE_FAIL_ZH "ȡ¼ļʧ" +#define TARGET_VERIFYING_ZH "У..." +#define TARGET_PROGRAMMING_ZH "д..." +#define TARGET_GET_ALGO_FAIL_ZH "ȡ㷨ʧܣǷжӦ㷨" +#define TARGET_CONNECTED_FAIL_ZH "Ŀδ" +#define TARGET_IMAGE_ERROR_ZH "¼ļ" +#define TARGET_ALGO_ERROR_ZH "㷨" +#define TARGET_RUN_ALGO_FAIL_ZH "Ŀ㷨ʧ" +#define IMAGE_UPGRADEING_ZH "׼..." +#define WELCOME_ZH "ӭʹHiSpark-Trace" +#define TARGET_IMAGE_MAX_LOADS_ERROR_ZH "¼" + +#define DELETEING_ZH "ɾ..." +#define DELETE_SUCCESS_ZH "ɾɹ" +#define DELETE_FAIL_ZH "ɾʧ" + +#define ERASEING_ZH "Ƭ..." +#define ERASE_SUCCESS_ZH "ƬOK" +#define ERASE_FAIL_ZH "Ƭʧ" + +#define FACTORY_MODE_TITLE_ZH " ¼ " + +#define MENU_ZH "˵" +#define CONNECT_RATE_ZH ":" +#define CRC_EXPECT_ZH "ԤCRC:" +#define CRC_ACTUAL_ZH "ʵCRC:" +#define CRC_CHK_LENGTH_ZH "У鳤:" +#define CRC_CHK_ADDR_ZH "Уַ:" +#define CRC_CHK_SUCC_ZH " CRCȷ " +#define CRC_CHK_FAIL_ZH " CRC " + +#define END_OF_LIST_ZH "ѵбĩβ" + +#define GET_IMAGE_FAIL_ZH "Ŀļʧ" +#define IMAGE_ZH "ļ:" +#define ALGO_ZH "㷨:" +#define EMPTY_ZH "<>" +#define NO_IMAGE_ZH "ļ:<>" +#define NO_ALGO_ZH "㷨:<>" + +#define MISS_IMAGE_ZH " ļ<> " +#define MISS_ALGO_ZH "ȱ¼㷨" +#define MISS_IMAGE_ALGO_ZH "ȱ¼ļ㷨" +#define IMAGE_ERROR_ZH "¼ļ" +#define ALGO_ERROR_ZH "㷨" +#define IMAGE_ALGO_ERROR_ZH "¼ļ㷨" +#define IMAGE_ALGO_NO_MATCH_ZH "¼ļ㷨ƥ" + +#define FACTORY_DEL_IMAGE_ALGO_ZH "ɾļ㷨" +#define FACTORY_DEL_IMAGE_ZH "ɾļ:" +#define FACTORY_DEL_ALGO_ZH "ɾ㷨:" + +#define TIMES_ZH "" +#define FILE_ERR_ZH "CRCȷ" +#define FILE_ERROR_ZH "()" + +#define DELETE_ALL_TITLE_ZH " ɾȫ " +#define FACTORY_RESET_TITLE_ZH " ָ " + +#define YES_ZH "1.ȷ" +#define NO_ZH "2.ȡ" + +#define IMAGE_ALGO_NO_MATCH_TITLE_ZH " ȱ㷨 " +#define IMAGE_RESTRICTED_TITLE_ZH "ļ¼ﵽ" + +#define CONTINUE_PROGRAM_ZH "¼" +#define CHIP_ERASE_TITLE_ZH " Ƭ " +#define READ_CRC_TITLE_ZH " CRC " + +#define FLASH_PROTECT_OFF_RUNING_ZH " Flash... " +#define FLASH_PROTECT_OFF_ZH " Flash " +#define FLASH_PROTECT_OFF_SUCC_ZH " Flashɹ " +#define FLASH_PROTECT_OFF_FAIL_ZH " Flashʧ " + +#define DOWNLOAD_ZH "" +#define PERIMIT_ZH "" + +#define SWD_ZH "SWD" +#define JTAG_ZH "JTAG" +#endif diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/status.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/status.h new file mode 100644 index 0000000000000000000000000000000000000000..a8eb4c702ac36ae0a9edeb35d3d87be2f5551bed --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/inc/status.h @@ -0,0 +1,154 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file status.h + * @author MCU Driver Team + * @brief status header + */ + +#ifndef STATUS_H +#define STATUS_H + +typedef enum { + TARGET_DISCONNECT, + TARGET_CONNECTED, +} TARGET_CONNECT_STATUS; + +typedef enum { + TARGET_CONNECT_SWD, + TARGET_CONNECT_JTAG, +} TARGET_CONNECT_TYPE; + +typedef struct { + TARGET_CONNECT_STATUS status; + TARGET_CONNECT_TYPE type; + unsigned int rate; +} TargetConnectInfo; + +typedef enum { + IMAGE_STORE_SUCCESS, + IMAGE_STORE_FAIL, + IMAGE_STORE_NOT_SUPPORT_MULTI_COPIES, + IMAGE_STORE_CRC_ERROR, + IMAGE_STORE_FILE_ERROR, + IMAGE_STORE_ALGO_ERROR, + IMAGE_STORE_IDLE, + IMAGE_STORE_STATUS_NUM, +} IMAGE_STORE_STATUS; + +typedef enum { + IMAGE_UPGRADE_START, + IMAGE_UPGRADE_SUCCESS, + IMAGE_UPGRADE_TARGET_CONNECT_FAIL, + IMAGE_UPGRADE_GET_ALGO_FAIL, + IMAGE_UPGRADE_WRITE_RUNNING, + IMAGE_UPGRADE_VERIFY_RUNNING, + IMAGE_UPGRADE_WRITE_FAIL, + IMAGE_UPGRADE_GET_IMAGE_FAIL, + IMAGE_UPGRADE_VERIFY_FAIL, + IMAGE_UPGRADE_IMAGE_ERROR, + IMAGE_UPGRADE_ALGO_ERROR, + IMAGE_UPGRADE_ALGO_RUN_ERROR, + IMAGE_UPGRADE_IDLE, + IMAGE_UPGREADE_MAX_LOAD_ERROR, + IMAGE_UPGRADE_STATUS_NUM, +} IMAGE_UPGRADE_STATUS; + +typedef enum { + ALGORITHM_STORE_SUCCESS, + ALGORITHM_STORE_FAIL, + ALGORITHM_STORE_NOT_SUPPORT_MULTI_COPIES, + ALGORITHM_STORE_CRC_ERROR, + ALGORITHM_STORE_IDLE, + ALGORITHM_STORE_STATUS_NUM, +} ALGORITHM_STORE_STATUS; + +typedef enum { + FIRMWARE_UPGRADE_RUNNING, + FIMRWARE_UPGRADE_SUCCESS, + FIMRWARE_UPGRADE_CRC_ERROR, + FIRMWARE_UPGRADE_IDLE, + FIRMWARE_UPGRADE_STATUS_NUM, +} FIRMWARE_UPGRADE_STATUS; + +typedef enum { + IMAGE_DELETE_RUNNING, + IMAGE_DELETE_SUCCESS, + IMAGE_DELETE_FAIL, + IMAGE_DELETE_IDLE, + IMAGE_DELETE_STATUS_NUM, +} IMAGE_DELETE_STATUS; + +typedef enum { + ALGORITHM_DELETE_RUNNING, + ALGORITHM_DELETE_SUCCESS, + ALGORITHM_DELETE_FAIL, + ALGORITHM_DELETE_IDLE, + ALGORITHM_DELETE_STATUS_NUM, +} ALGORITHM_DELETE_STATUS; + +typedef enum { + DAP_STATUS_NOTWORKING, + DAP_STATUS_DEBUGING, + DAP_STATUS_SAMPLING, + DAP_STATUS_SAMPLEOFFEXCEPTION, + DAP_STATUS_GDBEXCEPTIONEXIT, + DAP_STATUS_IDLE, + DAP_STATUS_NUM, +} DAP_STATUS; + +typedef struct { + DAP_STATUS status; + unsigned long long totalSampleCount; + unsigned long long totalOverflowCount; + unsigned long long totalErrorCount; + unsigned int errorRate; +} DapDebugInfo; + +typedef enum { + STATUS_STATUS_NO_CHANGE = 0x00000000, + STATUS_CHANGE_MASK_CONNECT_STATUS = 0x00000001, + STATUS_CHANGE_MASK_IMAGE_STORE_STATUS = 0x00000002, + STATUS_CHANGE_MASK_IMAGE_UPGRADE_STATUS = 0x00000004, + STATUS_CHANGE_MASK_ALGO_STORE_STATUS = 0x00000008, + STATUS_CHANGE_MASK_FW_UPGRADE_STATUS = 0x00000010, + STATUS_CHANGE_MASK_IMAGE_DELETE_STATUS = 0x00000020, + STATUS_CHANGE_MASK_ALGO_DELETE_STATUS = 0x00000040, + STATUS_CHANGE_MASK_DAP_SAMPLING_STATUS = 0x00000080, +} STATUS_CHANGE_MASK; + +typedef void (*StatusChangeCallback)(void); +typedef struct { + TargetConnectInfo connectInfo; + IMAGE_STORE_STATUS imageStoreStatus; + IMAGE_UPGRADE_STATUS imageUpgradeStatus; + ALGORITHM_STORE_STATUS algoStoreStatus; + FIRMWARE_UPGRADE_STATUS fwUpgradeStatus; + IMAGE_DELETE_STATUS imageDeleteStatus; + ALGORITHM_DELETE_STATUS algoDeleteStatus; + DapDebugInfo dapDbgInfo; + unsigned int statusChangeMask; + unsigned int upgradeRate; + StatusChangeCallback cbFunc; +} DapLinkStatus; + +void DapLinkStatusGet(DapLinkStatus *status); +void DapLinkStatusSet(DapLinkStatus *status); +void RegisterDaplinkStatusCallBackFunc(StatusChangeCallback func); +void UnRegisterDaplinkStatusCallBackFunc(void); + +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/display.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/display.c new file mode 100644 index 0000000000000000000000000000000000000000..f1fd6da88ad47f71a7e06b0fa40b86a7c093e673 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/display.c @@ -0,0 +1,494 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file display.c + * @author MCU Driver Team + * @brief Display process + */ + +#include +#include +#include "securec.h" +#include "oled.h" +#include "menu_tbl.h" +#include "status.h" +#include "offline_sys_config.h" +#include "proc.h" +#include "display.h" + + +static char *MergeStr(char *const buf, unsigned int bufLen, char *part1, const char *part2); +static void PopupMsgProc(void); +static void DownLoadLedOff(Frame *curFrame); +static Frame *g_ledOnFrame = NULL; +static bool g_ledOn = false; + +WinInfo g_WinInfo = { + .width = WIN_WIDTH / (FONT_SIZE / 2), /* 默认为显示英文字符 */ + .high = WIN_HEIGHT / FONT_SIZE, + .showLineMask = 0, + .language = LANGUAGE_CN, +}; + +/** + * @brief Get Language + * @retval None + */ +Language GetWinLanguage(void) +{ + return g_WinInfo.language; +} + +/** + * @brief Set Language + * @retval None + */ +void SetWinLanguage(Language lang) +{ + g_WinInfo.language = lang; + SysLanguageSet((lang == LANGUAGE_CN) ? SYS_LANGUAGE_CN : SYS_LANGUAGE_EN); +} + +/** + * @brief Force all Line used, then all line will be clear + * @retval None + */ +void ForceAllLineUsed(void) +{ + g_WinInfo.showLineMask = (unsigned int)-1; +} + +/** + * @brief Is support power supply, base on board type id + * @retval bool, true: support, false : don't support + */ +static bool IsSupportPowerSupply(void) +{ + unsigned int boardId = (unsigned int)SysBoardIdGet(); + return ((boardId == SYS_ALINK_BOARD_VB_10M) || (boardId == SYS_ALINK_BOARD_VB_16M)); +} + +/** + * @brief Display Module Init + * @retval None + */ +void DisplayInit(void) +{ + ProcInit(); + RegisterDaplinkStatusCallBackFunc(PopupMsgProc); + if (!IsSupportPowerSupply()) { + SettingFrameItemsWithNoPowerSupply(); + } + SetWinLanguage((SysLanguageGet() == SYS_LANGUAGE_EN) ? LANGUAGE_EN : LANGUAGE_CN); + g_WinInfo.frame = GetDefaultFrame(); + UpdateActiveFrame(GetCurFrame()); +} + +/** + * @brief Need Move to end frame when it's popup message + * @retval bool true: need do move to end, false: no + */ +static bool IsNeedPopMoveToEndFrame(const Frame * frame) +{ + return frame->lineNumber > frame->staticItemNum; +} + +/** + * @brief Frame Move up + * @retval No + */ +void FrameMoveUp(void) +{ + Frame *frame = GetCurFrame(); + if (frame->onlySupportSelected) { + /* Don't support move up/down, return */ + return; + } + + if (frame->pointer > frame->minPointer) { + /* select items move down */ + frame->pointer--; + if (frame->pointer >= g_WinInfo.high - 1) { + frame->begin--; + } + } else { + /* Move to the top of frame */ + if (frame->rollEn) { + /* if roll enable, goto the bottom items of frame */ + unsigned int end = frame->lineNumber; + frame->pointer = end - 1; + if (end >= g_WinInfo.high) { + frame->begin = end - g_WinInfo.high; + } else { + frame->begin = 0; + } + } + } + FrameShow(frame); +} + +/** + * @brief Frame Move down + * @retval No + */ +void FrameMoveDown(void) +{ + Frame *frame = GetCurFrame(); + bool rollDown = false; + if (frame->onlySupportSelected) { + /* don't support Move up/down action */ + return; + } + if (frame->pointer < frame->lineNumber - 1) { + /* select items move up */ + frame->pointer++; + if (frame->pointer >= g_WinInfo.high) { + frame->begin++; + } + } else { + /* Move to the bottom of frame */ + rollDown = true; + if (frame->rollEn) { + /* if roll enable, goto the top items of frame */ + frame->pointer = frame->pItem[0].title ? 1 : 0; + frame->begin = 0; + } + } + if (rollDown && IsNeedPopMoveToEndFrame(frame) && frame->moveToEndFrame) { + /* if move to bottom line of frame, popup message */ + UpdateActiveFrame(frame->moveToEndFrame); + return; + } + FrameShow(frame); +} + +/** + * @brief Frame Selected + * @retval No + */ +void FrameItemSelect(void) +{ + Frame *frame = GetCurFrame(); + Item *item = &frame->pItem[frame->pointer]; + if (!item) { /* item don't exist */ + /* don't be herer */ + return; + } + if (item->itemSelectedProc) { + /* Selected Process, transfer user data of line to frame, then Process can used the parameter */ + frame->userData = item->userData; + item->itemSelectedProc(frame); + } + if (item->linkFrame) { + if (GetFactoryImageProgramFailFrame() == frame) { /* Force to exit item if image upgrade fail in factory mode */ + item->linkFrame->pointer = item->linkFrame->lineNumber - 1; + } + /* transfer user data of line to link frame, then Process can used the parameter */ + item->linkFrame->userData = item->userData; + UpdateActiveFrame(item->linkFrame); + } + return; +} + +/** + * @brief Get Line number of item text + * @retval No + */ +static inline unsigned int GetItemTextLines(const char *p) +{ + unsigned int len = (unsigned int)strlen(p); + return ((len + g_WinInfo.width - 1) / g_WinInfo.width); +} + +/** + * @brief 重新计算frames能显示的items数,因为当前选中的item可能占用多行 + * @retval No + */ +static void GetShowItemsRange(const Frame *frame, unsigned int *beginIdx) +{ + char *p = frame->pItem[frame->pointer].text[g_WinInfo.language]; + unsigned int occupyLines = GetItemTextLines(p); + if (occupyLines <= 1) { /* item occupy only one line, return */ + return; + } + unsigned int end = frame->pointer + occupyLines - 1; + if ((end - frame->begin) >= (g_WinInfo.high - 1)) { + *beginIdx += occupyLines - 1; /* 1: all item already occupy one line */ + } + if (*beginIdx > frame->pointer) { + *beginIdx = frame->pointer; /* force set beginIdx */ + } +} + +/** + * @brief Show windows Menu + * @retval No + */ +static inline bool WindowsMenuShow(const Frame *frame, unsigned int line) +{ + if (frame->pItem[0].windowsMenu) { /* Is menu */ + (void)OledShowMenuItem(line, + frame->pItem->text[GetWinLanguage()], + FONT_SIZE, + (frame->pointer == line) ? 0 : 1); /* highlight items when the pointer ptr to */ + return true; + } + return false; +} + +/** + * @brief Show windows Title + * @retval No + */ +static inline bool TitleShow(const Frame *frame, unsigned int line) +{ + if (frame->pItem[0].title) { + OledShowMsg(0, frame->pItem[0].text[GetWinLanguage()], FONT_SIZE); + return true; + } + return false; +} + +/** + * @brief Clear Lines + * @retval No + */ +static void ClearLines(unsigned int startLines) +{ + unsigned int line; + for (line = startLines; line < g_WinInfo.high; ++line) { + OledClearLine(line, 0, g_WinInfo.width); + } +} + +static unsigned int ShowItems(Frame *frame, unsigned int beginIdx, unsigned int startLine) +{ + char itemText[ITEM_LIST_MAX_LEN] = {0}; + unsigned int line = startLine; + + if (frame->pointer >= frame->lineNumber) { + /* can't be here */ + frame->pointer = (frame->lineNumber >= 1) ? (frame->lineNumber - 1) : 0; + } + for (unsigned int i = beginIdx; i < frame->lineNumber && line < g_WinInfo.high; ++i) { + uint8_t reversed = (i == frame->pointer) ? 0 : 1; + char *p = frame->pItem[i].text[g_WinInfo.language]; + char *dynStr; + uint8_t showLines; + uint8_t calcLines; + if (frame->pItem[i].getInfo) { + char extInfo[EXT_INFO_MAX_LEN]; + memset_s(extInfo, sizeof(extInfo), 0, sizeof(extInfo)); + if (frame->pItem[i].getInfo(extInfo, sizeof(extInfo))) { + /* Get ext info and append to the behind of item text */ + dynStr = extInfo; + p = MergeStr(itemText, sizeof(itemText), p, dynStr); + } + } + showLines = OledShowMenuItem(line, p, FONT_SIZE, reversed); + calcLines = GetItemTextLines(p); + if (showLines < calcLines) { + showLines = calcLines; + } + /* The selected menu is displayed according to the line occupied by the actual character string. */ + line += (reversed == 0) ? showLines : 1; + } + return line; +} + +/** + * @brief Frame Show + * @retval No + */ +void FrameShow(Frame *frame) +{ + unsigned int line = 0; + unsigned int beginIdx; + + if (!frame) { + return; + } + + beginIdx = frame->begin; + + if (frame->genDynItems) { + /* Generate dynamic items before show */ + frame->genDynItems(frame); + } + + if (WindowsMenuShow(frame, line)) { + beginIdx++; /* The menu always occupies one line. */ + line++; + } + if (TitleShow(frame, line)) { + beginIdx++; + line++; + } + GetShowItemsRange(frame, &beginIdx); + line = ShowItems(frame, beginIdx, line); + + /* mask all show lines */ + for (unsigned int i = 1; i <= line; ++i) { + g_WinInfo.showLineMask |= 1 << i; + } + ClearLines(line); + if (frame->popupMsg) { + frame->popupMsg(frame); + } +} + +/** + * @brief Active Frame + * @retval No + */ +void UpdateActiveFrame(Frame *frame) +{ + g_WinInfo.frame = frame; + if (IsFactoryImageProgramSuccFrame()) { + /* Indicates the first item of the clock execution menu for special frames. */ + frame->pointer = 1; + } + /* Reinit show config */ + SetGlobalDisaplyaMode(DISPLAY_NORMAL); + DownLoadLedOff(frame); + FrameShow(frame); +} + +/** + * @brief Get current frame + * @retval current frame + */ +Frame *GetCurFrame(void) +{ + return g_WinInfo.frame; +} + +/** + * @brief Merge two string + * @retval No + */ +static char *MergeStr(char *const buf, unsigned int bufLen, char *part1, const char *part2) +{ + char *p = buf; + errno_t rc = EOK; + if (part2 == NULL) { + return part1; /* only one string, don't merge */ + } + + rc = strcpy_s(p, bufLen, part1); + if (rc != EOK) { + return part1; + } + rc = strncat_s(p, bufLen, part2, bufLen - strlen(p)); + if (rc != EOK) { + return part1; + } + return p; +} + +/** + * @brief Popup Message + * @retval No + */ +void FramePopMsg(const Frame *frame, const char *msg) +{ + unsigned int pointer = frame->lineNumber + 1; + ClearLines(frame->lineNumber); + OledShowMsg(pointer, msg, FONT_SIZE); + g_WinInfo.showLineMask = 0xFF; +} + +/** + * @brief Popup Message with title + * @retval No + */ +void FramePopMsgWithTitle(const Frame *frame, const char *title, const char **msg, int msgNum, DisplayAlignMode mode) +{ + unsigned int pointer = frame->lineNumber; + unsigned int width = (WIN_WIDTH * 2) / FONT_SIZE; + ClearLines(pointer); + if (title) { + OledShowMsg(pointer++, title, FONT_SIZE); /* Title in middle of line */ + } + for (int i = 0; i < msgNum; ++i) { + if (mode == ALIGN_MID) { + /* items show in middle of line */ + OledShowMsg(pointer, msg[i], FONT_SIZE); + } else { + /* items show in begin of line */ + (void)OledShowString(0, pointer, msg[i], FONT_SIZE, 1); + } + /* pointer add line number of message */ + pointer += ((unsigned int)(strlen(msg[i])) + width - 1) / width; + } + g_WinInfo.showLineMask = 0xFF; +} + +/** + * @brief Popup Message with specified font + * @retval No + */ +void FramePopMsgWithFont(const Frame *frame, const char *msg, int font) +{ + unsigned int pointer = frame->lineNumber; + ClearLines(pointer); + OledShowMsg(pointer, msg, font); + g_WinInfo.showLineMask = 0xFF; +} + +/** + * @brief Show status on bottom of window + * @retval No + */ +void FrameShowStatusBar(const Frame *frame, const char *status) +{ + uint8_t idx = g_WinInfo.high - 1; + OledShowMsg(idx, status, FONT_SIZE); + g_WinInfo.showLineMask |= (1 << idx); +} + +/* Called when status changed */ +void PopupMsgProc(void) +{ + Frame *frame = GetCurFrame(); + if (frame->popupMsg) { + frame->popupMsg(frame); + } +} + +/** + * @brief Led On + * @retval No + */ +void DownLoadLedOn(Frame *frame) +{ + g_ledOnFrame = frame; + g_ledOn = true; + OfflineLoadLedSet(SYS_OFFLINE_LED_ON); +} + +/** + * @brief Led OFf + * @retval No + */ +static void DownLoadLedOff(Frame *curFrame) +{ + if (g_ledOn && (curFrame != g_ledOnFrame)) { + g_ledOn = false; + OfflineLoadLedSet(SYS_OFFLINE_LED_OFF); + } +} diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/menu_tbl.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/menu_tbl.c new file mode 100644 index 0000000000000000000000000000000000000000..5a36adf26eecba86981bdae61f4d488f3b16a3cd --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/menu_tbl.c @@ -0,0 +1,692 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file menu_tbl.c + * @author MCU Driver Team + * @brief daplink boot menu display process + */ +#include +#include "display_common.h" +#include "display.h" +#include "res_en.h" +#include "res_zh.h" +#include "proc.h" + +static Frame mainMenuFrame; +static Frame dbgStatusMenuFrame; +static Frame flashMenuFrame; +static Frame flashEraseFrame; +static Frame flashProtectOffFrame; +static Frame settingMenuFrame; +static Frame selectImageMenuFrame; +static Frame deleteImageMenuFrame; +static Frame selectAlgoMenuFrame; +static Frame deleteAlgoMenuFrame; +static Frame enableMultiCopiesMenuFrame; +static Frame softwareUpgradeMenuFrame; +static Frame languageMenuFrame; +static Frame dbgInterfaceMenuFrame; +static Frame imageSelectedFrame; +static Frame imageGetMoreFrame; +static Frame algoSelectedFrame; +static Frame algoDeleteFrame; +static Frame algoDeleteAllFrame; +static Frame imageDeleteFrame; +static Frame imageDeleteAllFrame; +static Frame algoGetMoreFrame; +static Frame factoryResetMenuFrame; +static Frame hsSamplingSimuFrame; +static Frame powerSupplyFrame; +static Frame factoryModeFrame; +static Frame factoryImageSelectedFrame; +static Frame factoryCrcCheckFrame; +static Frame factoryShowImageMenuFrame; +static Frame factoryShowAlgoMenuFrame; +static Frame factoryViewFrame; +static Frame factoryDeleteFrame; +static Frame factoryDeleteImageAlgoMenuFrame; +static Frame factoryDeleteAlgoMenuFrame; +static Frame errImageSelectedFrame; +static Frame errAlgoSelectedFrame; +static Frame fatoryResetFrame; +static Frame factoryImageListFrame; +static Frame factoryImageSelectedSuccFrame; +static Frame factoryImageSelectedFailFrame; +static Frame imageSelectedFailFrame; +static Frame eraseAlgoSelectedFrame; +static Frame flashProtectOffDoneFrame; +static Frame factoryDeleteImageAlgoConfirmMenuFrame; + +#define FRAME_INIT_WITH_POINTER(x, NAME, rollEnable, pointerIdx) \ + .pointer = (pointerIdx), \ + .lineNumber = ARRAY_SIZE(x), \ + .staticItemNum = ARRAY_SIZE(x), \ + .begin = 0, \ + .pItem = (x), \ + .name = (NAME), \ + .rollEn = (rollEnable) + +#define FRAME_INIT(x, NAME, rollEnable) FRAME_INIT_WITH_POINTER(x, NAME, rollEnable, 0) + +#define BACK_ITEM_INIT(LINKFRAME) \ +{ \ + .text = MULTI_LANGUAGE(BACK), \ + .itemSelectedProc = 0, \ + .linkFrame = &(LINKFRAME), \ + .getInfo = 0, \ + .windowsMenu = 1 \ +} + +#define TITLE_ITEM_INIT(titleTxt) \ +{ \ + .text = titleTxt, \ + .itemSelectedProc = 0, \ + .linkFrame = NULL, \ + .getInfo = 0, \ + .title = 1 \ +} + +/* 菜单显示元素 */ +/* TOP Menu */ +static Item mainItems[] = { + {MULTI_LANGUAGE(DBG_STATUS), NULL, &dbgStatusMenuFrame}, + {MULTI_LANGUAGE(FACTORY_MODE), EntryFactoryMode, &factoryModeFrame}, + {MULTI_LANGUAGE(FLASHER_MODE), NULL, &flashMenuFrame }, + {MULTI_LANGUAGE(FLASHER_ERASE), NULL, &flashEraseFrame }, + {MULTI_LANGUAGE(FLASHER_UNLOCK), NULL, &flashProtectOffFrame}, + {MULTI_LANGUAGE(SETTING), NULL, &settingMenuFrame}, +}; + +/* Level 2 */ +static Item dbgStatusItems[] = { + {MULTI_LANGUAGE(MENU), NULL, &mainMenuFrame }, +}; + +static Item flasherItems[] = { + BACK_ITEM_INIT(mainMenuFrame), + {MULTI_LANGUAGE(IMAGE_SELECT), NULL, &selectImageMenuFrame}, + {MULTI_LANGUAGE(IMAGE_DELETE), NULL, &deleteImageMenuFrame}, + {MULTI_LANGUAGE(ALGO_SELECT), NULL, &selectAlgoMenuFrame }, + {MULTI_LANGUAGE(ALGO_DELETE), NULL, &deleteAlgoMenuFrame }, +}; + +static Item eraseItems[] = { + BACK_ITEM_INIT(mainMenuFrame), +}; + +static Item flashProtectOffItems[] = { + TITLE_ITEM_INIT(MULTI_LANGUAGE(FLASH_PROTECT_OFF)), + {MULTI_LANGUAGE(YES), NULL, &flashProtectOffDoneFrame}, + {MULTI_LANGUAGE(NO), NULL, &mainMenuFrame}, +}; + +static Item flashProtectOffDoneItems[] = { + BACK_ITEM_INIT(mainMenuFrame), +}; + +static Item factoryModeItems[] = { + TITLE_ITEM_INIT(MULTI_LANGUAGE(FACTORY_MODE_TITLE)), + {MULTI_LANGUAGE(FACTORY_IMAGE_LOAD), FactoryImageUpgrade, &factoryImageSelectedFrame}, + {MULTI_LANGUAGE(FACTORY_CRC_CHECK), NULL, &factoryImageListFrame}, + {MULTI_LANGUAGE(FACTORY_VIEW), NULL, &factoryViewFrame}, + {MULTI_LANGUAGE(FACTORY_DELETE), NULL, &factoryDeleteFrame}, + {MULTI_LANGUAGE(FACTORY_EXIT), ExitFactoryMode, &mainMenuFrame}, +}; + +static Item settingItems[] = { + BACK_ITEM_INIT(mainMenuFrame), + {MULTI_LANGUAGE(LANGUAGE_SELECT), NULL, &languageMenuFrame}, + {MULTI_LANGUAGE(POWER_SUPPLY), NULL, &powerSupplyFrame}, + {MULTI_LANGUAGE(DBG_INTERFACE), NULL, &dbgInterfaceMenuFrame}, + {MULTI_LANGUAGE(FW_VER), NULL, NULL, GetFWVersion}, + {MULTI_LANGUAGE(FW_UPGRADE), NULL, &softwareUpgradeMenuFrame}, + {MULTI_LANGUAGE(HW_VER), NULL, NULL, GetHWVersion}, + {MULTI_LANGUAGE(SN), NULL, NULL, GetSN}, + {MULTI_LANGUAGE(HS_SAMPLE_SIMU), NULL, &hsSamplingSimuFrame}, + {MULTI_LANGUAGE(RESTORE), NULL, &factoryResetMenuFrame}, +}; + +static Item settingNoPowerSupplyItems[] = { + BACK_ITEM_INIT(mainMenuFrame), + {MULTI_LANGUAGE(LANGUAGE_SELECT), NULL, &languageMenuFrame}, + {MULTI_LANGUAGE(OLD_DBG_INTERFACE), NULL, &dbgInterfaceMenuFrame}, + {MULTI_LANGUAGE(OLD_FW_VER), NULL, NULL, GetFWVersion}, + {MULTI_LANGUAGE(OLD_FW_UPGRADE), NULL, &softwareUpgradeMenuFrame}, + {MULTI_LANGUAGE(OLD_HW_VER), NULL, NULL, GetHWVersion}, + {MULTI_LANGUAGE(OLD_SN), NULL, NULL, GetSN}, + {MULTI_LANGUAGE(OLD_HS_SAMPLE_SIMU), NULL, &hsSamplingSimuFrame}, + {MULTI_LANGUAGE(OLD_RESTORE), NULL, &factoryResetMenuFrame}, +}; + +/* Level 3 for flasher */ +static Item selectImageItems[] = { + BACK_ITEM_INIT(flashMenuFrame), +}; + +static Item deleteImageItems[] = { + BACK_ITEM_INIT(flashMenuFrame), + {MULTI_LANGUAGE(DELETE_ALL), NULL, &imageDeleteAllFrame}, +}; + +static Item selectAlgoItems[] = { + BACK_ITEM_INIT(flashMenuFrame), +}; + +static Item deleteAlgoItems[] = { + BACK_ITEM_INIT(flashMenuFrame), + {MULTI_LANGUAGE(DELETE_ALL), NULL, &algoDeleteAllFrame}, +}; + +static Item enableMultiCopiesItems[] = { + BACK_ITEM_INIT(flashMenuFrame), + {MULTI_LANGUAGE(ON), EnableMultiCopies, NULL, GetMultiEnableSelected}, + {MULTI_LANGUAGE(OFF), DisableMultiCopies, NULL, GetMultiDisableSelected}, +}; + +/* Level 3 for setting */ +static Item languageItems[] = { + BACK_ITEM_INIT(settingMenuFrame), + {MULTI_LANGUAGE(CHINESE), SetLanguageToCN, NULL, LanguageChineseSelected}, + {MULTI_LANGUAGE(ENGLISH), SetLanguageToEN, NULL, LanguageEnglishSelected}, +}; + +static Item dbgInterfaceItems[] = { + BACK_ITEM_INIT(settingMenuFrame), + {MULTI_LANGUAGE(SWD), SetInterfaceToSwd, NULL, SwdInterfaceSelected}, + {MULTI_LANGUAGE(JTAG), SetInterfaceToJtag, NULL, JtagInterfaceSelected}, +}; + +static Item factoryResetItems[] = { + TITLE_ITEM_INIT(MULTI_LANGUAGE(FACTORY_RESET_TITLE)), + {MULTI_LANGUAGE(YES), RestoreFactory, &fatoryResetFrame}, + {MULTI_LANGUAGE(NO), NULL, &mainMenuFrame}, +}; + +static Item factoryResetDoneItems[] = { + BACK_ITEM_INIT(settingMenuFrame), +}; + +static Item hsSamplingSimuItems[] = { + BACK_ITEM_INIT(settingMenuFrame), + {MULTI_LANGUAGE(ON), EnableHsSampling, NULL, GetHsSamplingEnableSelected}, + {MULTI_LANGUAGE(OFF), DisableHsSampling, NULL, GetHsSamplingDisableSelected}, +}; + +static Item powerSupplyItems[] = { + BACK_ITEM_INIT(settingMenuFrame), + {MULTI_LANGUAGE(ON), EnablePowerSupply, NULL, GetPowerSupplyEnableSelected}, + {MULTI_LANGUAGE(OFF), DisablePowerSupply, NULL, GetPowerSupplyDisableSelected}, +}; + +static Item softwareUpgradeItems[] = { + BACK_ITEM_INIT(settingMenuFrame), +}; + +/* Level 4 */ +static Item imageSelectedItems[] = { + BACK_ITEM_INIT(selectImageMenuFrame), +}; + +static Item imageGetMoreItems[] = { + BACK_ITEM_INIT(selectImageMenuFrame), +}; + +static Item uploadImageItmes[] = { + BACK_ITEM_INIT(selectImageMenuFrame), +}; + +static Item imageDeleteItems[] = { + BACK_ITEM_INIT(deleteImageMenuFrame), +}; + +static Item imageDeleteDialogItems[] = { + TITLE_ITEM_INIT(MULTI_LANGUAGE(DELETE_ALL_TITLE)), + {MULTI_LANGUAGE(YES), DeleteAllImage, &imageDeleteFrame}, + {MULTI_LANGUAGE(NO), NULL, &deleteImageMenuFrame}, +}; + +static Item selectedAlgoItems[] = { + BACK_ITEM_INIT(selectAlgoMenuFrame), +}; + +static Item algoGetMoreItems[] = { + BACK_ITEM_INIT(selectAlgoMenuFrame), +}; + +static Item algoDeleteItems[] = { + BACK_ITEM_INIT(deleteAlgoMenuFrame), +}; + +static Item algoDeleteDialogItems[] = { + TITLE_ITEM_INIT(MULTI_LANGUAGE(DELETE_ALL_TITLE)), + {MULTI_LANGUAGE(YES), DeleteAllAlgo, &algoDeleteFrame}, + {MULTI_LANGUAGE(NO), NULL, &deleteAlgoMenuFrame}, +}; + +static Item eraseAlgoSelectedItems[] = { + BACK_ITEM_INIT(flashEraseFrame), +}; + +static Item uploadAlgoItmes[] = { + BACK_ITEM_INIT(selectAlgoMenuFrame), +}; + +/* 描述菜单链接关系和动作 */ +static Frame mainMenuFrame = { + FRAME_INIT(mainItems, "mainMenu", true), +}; + +static Frame dbgStatusMenuFrame = { + FRAME_INIT(dbgStatusItems, "dbgMenu", true), + .popupMsg = DbgFrameProc, +}; + +static Frame flashMenuFrame = { + FRAME_INIT(flasherItems, "flashMenu", true), +}; + +static Frame flashEraseFrame = { + FRAME_INIT(eraseItems, "eraseMenu", true), + .genDynItems = CreateEraseListFrame, + .dynItemSelectFrame = &eraseAlgoSelectedFrame, + .popupMsg = NoFlashAlgoMsgPopup, +}; + +static Frame flashProtectOffFrame = { + FRAME_INIT(flashProtectOffItems, "protectOffMenu", true), +}; + +static Frame flashProtectOffDoneFrame = { + FRAME_INIT(flashProtectOffDoneItems, "protectOffDoneMenu", true), + .popupMsg = FlashProtectOffMsgPopup, +}; + +static Frame settingMenuFrame = { + FRAME_INIT(settingItems, "settingMenu", true), +}; + +/* Level 3 Menu */ +/* Level 3 menu for flasher */ +static Frame selectImageMenuFrame = { + FRAME_INIT(selectImageItems, "selectImage", true), + .genDynItems = CreateSelectImageListFrame, + .dynItemSelectFrame = &imageSelectedFrame, + .dynFailItemSelectFrame = &errImageSelectedFrame, + .popupMsg = NoImageMsgPopup, +}; + +static Frame deleteImageMenuFrame = { + FRAME_INIT(deleteImageItems, "deleteImage", true), + .genDynItems = CreateDeleteImageListFrame, + .dynItemSelectFrame = &imageDeleteFrame, +}; + +static Frame selectAlgoMenuFrame = { + FRAME_INIT(selectAlgoItems, "selectAlgo", true), + .genDynItems = AlgoSelectFrameProc, + .dynItemSelectFrame = NULL, + .dynFailItemSelectFrame = &errAlgoSelectedFrame, + .popupMsg = NoAlgoMsgPopup, +}; + +static Frame deleteAlgoMenuFrame = { + FRAME_INIT(deleteAlgoItems, "deleteAlgo", true), + .genDynItems = CreateDeleteAlgoListFrame, + .dynItemSelectFrame = &algoDeleteFrame, +}; + +static Frame enableMultiCopiesMenuFrame = { + FRAME_INIT(enableMultiCopiesItems, "enableMulti", true), +}; + +/* Level 3 Menu */ +/* Level 3 menu for factory */ +static Item factoryShowImageItems[] = { + BACK_ITEM_INIT(factoryImageListFrame), +}; + +static Frame factoryShowImageMenuFrame = { + FRAME_INIT(factoryShowImageItems, "showImage", true), + .genDynItems = CreateShowImageListFrame, + .popupMsg = NoImageMsgPopup, +}; + +static Item factoryImageItems[] = { + BACK_ITEM_INIT(factoryModeFrame), +}; + +static Frame factoryErrImageSelectedFrame = { + FRAME_INIT(factoryImageItems, "ImageSelected", true), + .popupMsg = ErrorImageUpgradeMsgPopup, +}; + +static Frame factoryImageListFrame = { + FRAME_INIT(factoryImageItems, "selectImage", true), + .genDynItems = CreateFactoryImageListFrame, + .dynItemSelectFrame = &factoryCrcCheckFrame, + .popupMsg = NoImageMsgPopup, +}; + +static Item factoryShowAlgoItems[] = { + BACK_ITEM_INIT(factoryModeFrame), +}; + +static Frame factoryShowAlgoMenuFrame = { + FRAME_INIT(factoryShowAlgoItems, "showAlgo", true), + .genDynItems = CreateShowAlgoListFrame, + .popupMsg = NoAlgoMsgPopup, +}; + +/* Level 3 menu for Setting */ +static Frame languageMenuFrame = { + FRAME_INIT(languageItems, "langSet", true), +}; + +static Frame dbgInterfaceMenuFrame = { + FRAME_INIT(dbgInterfaceItems, "dbgInterface", true), +}; + +static Frame factoryResetMenuFrame = { + FRAME_INIT(factoryResetItems, "recovery", true), +}; + +static Frame softwareUpgradeMenuFrame = { + FRAME_INIT(softwareUpgradeItems, "swUpgrade", true), + .popupMsg = FirmwareUpgradeMsgPopup, +}; + +static Frame hsSamplingSimuFrame = { + FRAME_INIT(hsSamplingSimuItems, "HsSampling", true), +}; + +static Frame powerSupplyFrame = { + FRAME_INIT(powerSupplyItems, "powerSupply", true), +}; + +static Frame factoryModeFrame = { + FRAME_INIT_WITH_POINTER(factoryModeItems, "factoryMode", true, 1), + .minPointer = 1, +}; + +static Frame imageSelectedFrame = { + FRAME_INIT(imageSelectedItems, "ImageSelected", true), + .popupMsg = ImageUpgradeMsgPopup, +}; + +static Frame errImageSelectedFrame = { + FRAME_INIT(imageSelectedItems, "ImageSelected", true), + .popupMsg = ErrorImageUpgradeMsgPopup, +}; + +static Frame imageGetMoreFrame = { + FRAME_INIT(imageGetMoreItems, "GetMoreImage", true), + .popupMsg = GetMoreImageMsgPopup, +}; + +static Frame imageDeleteAllFrame = { + FRAME_INIT(imageDeleteDialogItems, "ImageDelete", true), +}; + +static Frame imageDeleteFrame = { + FRAME_INIT(imageDeleteItems, "ImageDelete", true), + .popupMsg = ImageDeleteMsgPopup, +}; + +static Frame algoSelectedFrame = { + FRAME_INIT(selectedAlgoItems, "AlgoSelected", true), +}; + +static Frame errAlgoSelectedFrame = { + FRAME_INIT(selectedAlgoItems, "ImageSelected", true), + .popupMsg = ErrorAlgoSelectedMsgPopup, +}; + +static Frame algoDeleteFrame = { + FRAME_INIT(algoDeleteItems, "AlgoDelte", true), + .popupMsg = AlgoDeleteMsgPopup, +}; + +static Frame algoDeleteAllFrame = { + FRAME_INIT(algoDeleteDialogItems, "AlgoDelte", true), +}; + +static Frame algoGetMoreFrame = { + FRAME_INIT(algoGetMoreItems, "AlgoGetMore", true), + .popupMsg = GetMoreAlgoMsgPopup, +}; + +static Frame fatoryResetFrame = { + FRAME_INIT(factoryResetDoneItems, "FactoryResetDone", true), + .popupMsg = RecoveryFactoryMsgPopup, +}; + +static Item factoryImageSelectedItems[] = { + BACK_ITEM_INIT(factoryModeFrame), +}; + +static Frame factoryImageSelectedFrame = { + FRAME_INIT(factoryImageSelectedItems, "factoryImageSelectedFrame", true), + .popupMsg = FactoryImageUpgradeMsgPopup, +}; + +static Item factoryImageSelectedSuccItems[] = { + BACK_ITEM_INIT(factoryModeFrame), + {MULTI_LANGUAGE(CONTINUE_PROGRAM), FactoryImageUpgrade, &factoryImageSelectedFrame}, +}; + +static Frame factoryImageSelectedSuccFrame = { + FRAME_INIT_WITH_POINTER(factoryImageSelectedSuccItems, "FactoryImageSelected", true, 1), +}; + +static Item factoryImageSelectedFailItems[] = { + BACK_ITEM_INIT(factoryModeFrame), +}; + +static Frame factoryImageSelectedFailFrame = { + FRAME_INIT_WITH_POINTER(factoryImageSelectedFailItems, "FactoryImageSelected", true, 1), +}; + +static Item imageSelectedFailItems[] = { + BACK_ITEM_INIT(selectImageMenuFrame), +}; + +static Frame imageSelectedFailFrame = { + FRAME_INIT_WITH_POINTER(imageSelectedFailItems, "ImageSelected", true, 1), +}; + + +static Frame eraseAlgoSelectedFrame = { + FRAME_INIT(eraseAlgoSelectedItems, "eraseAlgoSelected", true), + .popupMsg = EraseChipMsgPopup, +}; + +static Item factoryCrcCheckItems[] = { + BACK_ITEM_INIT(factoryImageListFrame), +}; + +static Frame factoryCrcCheckFrame = { + FRAME_INIT(factoryCrcCheckItems, "FactoryCrcCheck", true), + .popupMsg = CrcCheckMsgPopup, + .onlySupportSelected = true, +}; + +static Item factoryViewItems[] = { + BACK_ITEM_INIT(factoryModeFrame), +}; + +static Frame factoryViewFrame = { + FRAME_INIT(factoryViewItems, "FactoryView", true), + .genDynItems = CreateShowImageAndAlgoListFrame, +}; + +static Item factoryDeleteItems[] = { + BACK_ITEM_INIT(factoryModeFrame), + {MULTI_LANGUAGE(FACTORY_DEL_IMAGE_ALGO), NULL, &factoryDeleteImageAlgoConfirmMenuFrame}, +}; + +static Frame factoryDeleteFrame = { + FRAME_INIT(factoryDeleteItems, "FactoryDelete", true), + .genDynItems = CreateDeleteImageAndAlgoListFrame, + .dynItemSelectFrame = &factoryDeleteImageAlgoMenuFrame, +}; + +static Item factoryDeleteImageAlgoItems[] = { + BACK_ITEM_INIT(factoryDeleteFrame), +}; + +static Frame factoryDeleteImageAlgoMenuFrame = { + FRAME_INIT(factoryDeleteImageAlgoItems, "ImageAlgoDel", true), + .popupMsg = FactoryDeleteMsgPopup, +}; + +static Item factoryDeleteImageAlgoConfirmItems[] = { + TITLE_ITEM_INIT(MULTI_LANGUAGE(DELETE_ALL_TITLE)), + {MULTI_LANGUAGE(YES), FactoryImageAlgoDelete, &factoryDeleteImageAlgoMenuFrame}, + {MULTI_LANGUAGE(NO), NULL, &factoryDeleteFrame}, +}; + +static Frame factoryDeleteImageAlgoConfirmMenuFrame = { + FRAME_INIT(factoryDeleteImageAlgoConfirmItems, "factoryDelImageAlgoConfirm", true), +}; + +static Item factoryDeleteImageItems[] = { + BACK_ITEM_INIT(factoryDeleteFrame), +}; + +static Item factoryImageAlgoNoMatchFrameItems[] = { + BACK_ITEM_INIT(factoryModeFrame), + {MULTI_LANGUAGE(IMAGE_ALGO_NO_MATCH_TITLE), NULL, NULL}, +}; + +static Frame factoryImageAlgoNoMatchFrame = { + FRAME_INIT(factoryImageAlgoNoMatchFrameItems, "dynFrame", true), + .genDynItems = CreateUnMatchAlgoListFrame, +}; + +static Item factoryImageRestrictedItems[] = { + BACK_ITEM_INIT(factoryModeFrame), + {MULTI_LANGUAGE(IMAGE_RESTRICTED_TITLE), NULL, NULL}, +}; + +static Frame factoryImageRestrictedFrame = { + FRAME_INIT(factoryImageRestrictedItems, "restrictedFrame", true), + .genDynItems = CreateImageRestrictedListFrame, +}; + +static Item factoryImageAlgoFrameItems[] = { + BACK_ITEM_INIT(factoryModeFrame), + {MULTI_LANGUAGE(IMAGE), NULL, NULL}, + {MULTI_LANGUAGE(ALGO), NULL, NULL}, +}; + +static Frame factoryImageAlgoFrame = { + FRAME_INIT(factoryImageAlgoFrameItems, "dynFrame", true), +}; + +/** + * @brief Get default frame + * @retval ptr to frame + */ +Frame *GetDefaultFrame(void) +{ + DeviceConfig *cfg = GetDevConfig(); + return cfg->enableFactory ? &factoryModeFrame : &dbgStatusMenuFrame; +} + +/** + * @brief Get Factory Image and Algo not match Frame + * @retval ptr to frame + */ +Frame *GetFactoryImageAlgoNoMatchFrame(void) +{ + return &factoryImageAlgoNoMatchFrame; +} + +/** + * @brief Get Factory Image Restricte Frame + * @retval ptr to frame + */ +Frame *GetFactoryImageRestrictedFrame(void) +{ + return &factoryImageRestrictedFrame; +} + +/** + * @brief Get Factory Image Program success Frame pointer + * @retval ptr to frame + */ +Frame *GetFactoryImageProgramSuccFrame(void) +{ + return &factoryImageSelectedSuccFrame; +} + +/** + * @brief Get Factory Image Program Fail Frame pointer + * @retval ptr to frame + */ +Frame *GetFactoryImageProgramFailFrame(void) +{ + return &factoryImageSelectedFailFrame; +} + +/** + * @brief Get Image Program Fail Frame pointer + * @retval ptr to frame + */ +Frame *GetImageProgramFailFrame(void) +{ + return &imageSelectedFailFrame; +} + +/** + * @brief Is Debug Status Frame + * @retval true: yes, false: not + */ +bool IsDbgStatusFrame(void) +{ + return GetCurFrame() == &dbgStatusMenuFrame; +} + +/** + * @brief Is FActory Image Program success frame + * @retval ptr to frame + */ +bool IsFactoryImageProgramSuccFrame(void) +{ + return GetCurFrame() == GetFactoryImageProgramSuccFrame(); +} + +/** + * @brief Is Image Program fail frame + * @retval ptr to frame + */ +bool IsProgramFailFrame(void) +{ + return ((GetCurFrame() == GetFactoryImageProgramFailFrame()) || + (GetCurFrame() == GetImageProgramFailFrame())); +} + +/** + * @brief Set Menu Frame without Power supply item + * @retval No + */ +void SettingFrameItemsWithNoPowerSupply(void) +{ + settingMenuFrame.pItem = settingNoPowerSupplyItems; + settingMenuFrame.lineNumber = ARRAY_SIZE(settingNoPowerSupplyItems); + settingMenuFrame.staticItemNum = ARRAY_SIZE(settingNoPowerSupplyItems); +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/proc.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/proc.c new file mode 100644 index 0000000000000000000000000000000000000000..ecbb666e83264fe791c6af04b36cac465c3fe098 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/proc.c @@ -0,0 +1,2173 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file proc.c + * @author MCU Driver Team + * @brief display process + */ +#include +#include "securec.h" +#include "res_en.h" +#include "res_zh.h" +#include "display.h" +#include "util.h" +#include "oled.h" +#include "target_lib_manager.h" +#include "offline_download.h" +#include "status.h" +#include "DAP_vendor_ex.h" +#include "factory_manager.h" +#include "offline_sys_config.h" +#include "user_crc.h" +#include "menu_tbl.h" +#include "target_algo_parse.h" +#include "config_storage_update.h" +#include "var_monitor_process.h" +#include "swd_jtag_config.h" +#include "proc.h" + +char *g_hwVersion[] = { + "NULL", + "NULL", + "NULL", + "VER.B 16M", + "NULL", + "NULL", + "VER.B 10M", + "VER.A 10M" +}; + +DeviceConfig devConfig = { + .enableMultiCopies = 1, + .swVersion = {0}, + .hwVersion = HARDWARE_VERSION, + .enableHsSampling = 0, + .enableFactory = 0, + .sn = "HISI001ABCDE", +}; + +#define MSG_LINE_SIZE LED_LINE_LEN +#define IMAGE_ALGO_NAME_EXT_SIZE 35 +#define DIGITAL_HEX_MSG_LEN 11 +#define DIGITAL_RATE_MSG_LEN 12 +#define DAP_MSG_LINES 4 +#define CRC_MSG_LINES 4 +#define DAP_DATA_RATE_CHARS 20 +#define PROC_NAME_MAX_LEN (TARGET_LIB_IMAGE_NAME_MAX_LEN + IMAGE_ALGO_NAME_EXT_SIZE) + +#define IMAGE_UPGRADE_FAIL_MSG_MAX_LEN 24 + +typedef enum { + DYN_ITEM_SELECT, + DYN_ITEM_DELETE, + DYN_ITEM_SHOW, + FACTORY_ITEM_SELECT, + DYN_ITEM_NUM, +} DynItemType; + +static Item g_imageDynItem[DYN_ITEM_NUM][TARGET_LIB_IMAGE_MAX_NUM + 1]; +static Item g_algoDynItem[DYN_ITEM_NUM][TARGET_LIB_ALGO_MAX_NUM + 1]; +static Item g_imageAlgoDynItem[DYN_ITEM_NUM][TARGET_LIB_IMAGE_MAX_NUM + TARGET_LIB_ALGO_MAX_NUM + 3]; +static char g_imageName[TARGET_LIB_IMAGE_MAX_NUM][TARGET_LIB_IMAGE_NAME_MAX_LEN + IMAGE_ALGO_NAME_EXT_SIZE]; +static char g_algoName[TARGET_LIB_IMAGE_MAX_NUM][TARGET_LIB_IMAGE_NAME_MAX_LEN + IMAGE_ALGO_NAME_EXT_SIZE]; +static Item g_imageUnMatchDynItem[TARGET_LIB_IMAGE_MAX_NUM + 1]; +static Item g_imageRestrictedDynItem[TARGET_LIB_IMAGE_MAX_NUM + 1]; +static Item g_eraseListItem[TARGET_LIB_ALGO_MAX_NUM + 1]; +static bool g_loadChkSucc = false; +char g_imageUpgradeFailMsg[IMAGE_UPGRADE_FAIL_MSG_MAX_LEN + 1]; + +static bool FormatConnectRate(unsigned int rate, char *const rateStr, unsigned int length); +static bool ConnectStatusShow(Frame *frame, TargetConnectInfo *connectInfo); +static void ImageStoreStatusShow(Frame *frame, IMAGE_STORE_STATUS status); +static void ImageUpgradeStatusShow(Frame *frame, IMAGE_UPGRADE_STATUS status); +static void AlgoStoreStatusShow(Frame *frame, ALGORITHM_STORE_STATUS status); +static void FirmwareUpgradeStatusShow(Frame *frame, FIRMWARE_UPGRADE_STATUS status); +static void ImageSelectedProc(Frame *frame); +static void ImageDeleteProc(Frame *frame); +static void AlgoSelectedProc(Frame *frame); +static void AlgoDeleteProc(Frame *frame); +static void ImageDeleteStatusShow(const Frame *frame, IMAGE_DELETE_STATUS status); +static bool DapSamplingStatusShow(const Frame *frame, const DapDebugInfo *dbgInfo); +static void AlgoDeleteStatusShow(const Frame *frame, ALGORITHM_DELETE_STATUS status); +static bool CreateDynAlgoListFrame(Frame *frame, Item *dynItems, SelectedProc selectProc); +static bool CreateDynImageListFrame(Frame *frame, Item *dynItems, SelectedProc selectProc); +static void WelcomeMsg(const Frame *frame); +static bool HasValidImage(int imageCnt); +static bool HasValidAlgo(int algoCnt); +static void CreateFactoryImageAndAlgoFrame(Frame *frame, Item *dynItems, SelectedProc selectedProc, + SelectedProc algoSelectProc); +static void CreateDynEraseListFrame(Frame *frame, Item *dynItems, SelectedProc selectedProc); +static void FactoryImageDeleteProc(Frame *frame); +static bool GreateImageDownloadDetailInfo(char *const name, uint32_t nameLen, uint32_t maxLoads, uint32_t loadCnt); +static void FactoryImageListDummyProc(Frame *frame); +static void SetImageUpgradeFailMsg(const char *msg); +static char *GetImageUpgradeFailMsg(void); +static void ImageUpgradeFailPeriodShow(const Frame *frame); + +#define KHZ (1000) +#define MHZ (KHZ * KHZ) + +/** + * @brief Debug Frame Process, base on the Daplink Status + * @retval None + */ +void DbgFrameProc(Frame *frame) +{ + DapLinkStatus status; + DapLinkStatusGet(&status); /* Get daplink status */ + + /* What type of status is changed? Invoke the corresponding function. */ + switch (status.statusChangeMask) { + case STATUS_CHANGE_MASK_CONNECT_STATUS: + ConnectStatusShow(frame, &status.connectInfo); + break; + case STATUS_CHANGE_MASK_IMAGE_STORE_STATUS: + ImageStoreStatusShow(frame, status.imageStoreStatus); + status.statusChangeMask &= ~STATUS_CHANGE_MASK_IMAGE_STORE_STATUS; /* Clear image store status */ + break; + case STATUS_CHANGE_MASK_IMAGE_UPGRADE_STATUS: + ImageUpgradeStatusShow(frame, status.imageUpgradeStatus); + status.statusChangeMask &= ~STATUS_CHANGE_MASK_IMAGE_UPGRADE_STATUS; /* Clear image upgrade status */ + break; + case STATUS_CHANGE_MASK_ALGO_STORE_STATUS: + AlgoStoreStatusShow(frame, status.algoStoreStatus); + status.statusChangeMask &= ~STATUS_CHANGE_MASK_ALGO_STORE_STATUS; /* Clear algo store status */ + break; + case STATUS_CHANGE_MASK_FW_UPGRADE_STATUS: + FirmwareUpgradeStatusShow(frame, status.fwUpgradeStatus); + status.statusChangeMask &= ~STATUS_CHANGE_MASK_FW_UPGRADE_STATUS; + break; + case STATUS_CHANGE_MASK_DAP_SAMPLING_STATUS: + DapSamplingStatusShow(frame, &status.dapDbgInfo); + status.statusChangeMask &= ~STATUS_CHANGE_MASK_DAP_SAMPLING_STATUS; + break; + default: + WelcomeMsg(frame); /* Default: welcome */ + break; + } + DapLinkStatusSet(&status); /* Set daplink status */ + return; +} + +/** + * @brief Show Welcome message + * @retval None + */ +static void WelcomeMsg(const Frame *frame) +{ + char *msg[] = MULTI_LANGUAGE(WELCOME); + FramePopMsg(frame, msg[GetWinLanguage()]); +} + +/** + * @brief Formate Data and Time + * @retval None + */ +static void SetDateAndTimeStr(char *buf, unsigned int len) +{ + errno_t rc = EOK; + char *p = SOFTWARE_VERSION; + rc = strncpy_s(buf, len, p, len - 1); + if (rc != EOK) { + return; + } + buf[len - 1] = 0; +} + +/** + * @brief Proc Init + * @retval None + */ +void ProcInit(void) +{ + errno_t rc = EOK; + /* Get Factory, hs-sampling and powerSupply from flash */ + devConfig.enableFactory = (FactoryStatusGet() == FACTORY_FLAG_IS_SET) ? true : false; + devConfig.enableHsSampling = GetPerformanceTest(); + devConfig.enablePowerSupply = (SysExternalPowerStatusGet() == SYS_EXTERNAL_POWER_ON) ? true : false; + + /* Get board id and software version */ + uint32_t boardId = SysBoardIdGet(); + rc = strcpy_s(devConfig.hwVersion, VER_MAX_LEN, g_hwVersion[boardId & 0x7]); + if (rc != EOK) { + return; + } + SetDateAndTimeStr(devConfig.swVersion, sizeof(devConfig.swVersion)); +} + +/** + * @brief firmware upgrade popup + * @retval None + */ +void FirmwareUpgradeMsgPopup(Frame *frame) +{ + DapLinkStatus status; + DapLinkStatusGet(&status); + if (status.statusChangeMask == STATUS_CHANGE_MASK_FW_UPGRADE_STATUS) { + /* Refresh upgrade status */ + FirmwareUpgradeStatusShow(frame, status.fwUpgradeStatus); + return; + } + /* show upgrading */ + char *msg[] = MULTI_LANGUAGE(FW_UPGRADE_MSG); + FramePopMsg(frame, msg[GetWinLanguage()]); +} + +/** + * @brief get more image popup with title + * @retval None + */ +static void GetMoreImageMsgPopupWithTitle(const Frame *frame, const char *title) +{ + Language lang; + + lang = GetWinLanguage(); + const char *msg[1]; + msg[0] = GET_MULTILANGE_STR(GET_MORE_IMAGE, lang); + FramePopMsgWithTitle(frame, title, msg, sizeof(msg) / sizeof(msg[0]), ALIGN_LEFT); +} + +/** + * @brief get more image popup + * @retval None + */ +void GetMoreImageMsgPopup(Frame *frame) +{ + Language lang = GetWinLanguage(); + char *title = GET_MULTILANGE_STR(END_OF_LIST, lang); + GetMoreImageMsgPopupWithTitle(frame, title); +} + +/** + * @brief no image popup + * @retval None + */ +void NoImageMsgPopup(Frame *frame) +{ + if (frame->lineNumber > frame->staticItemNum) { + /* At least one image is available, return */ + return; + } + /* Show Message with title style, title=message */ + Language lang = GetWinLanguage(); + char *title = GET_MULTILANGE_STR(NO_IMAGE, lang); + GetMoreImageMsgPopupWithTitle(frame, title); +} + +/** + * @brief get more algo popup with title + * @retval None + */ +static void GetMoreAlgoMsgPopupWithTitle(const Frame *frame, const char *title) +{ + Language lang; + lang = GetWinLanguage(); + const char *msg[1]; + msg[0] = GET_MULTILANGE_STR(GET_MORE_ALGO, lang); + FramePopMsgWithTitle(frame, title, msg, sizeof(msg) / sizeof(msg[0]), ALIGN_LEFT); +} + +/** + * @brief get flash algo popup with title + * @retval None + */ +static void GetFlashAlgoMsgPopupWithTitle(const Frame *frame, const char *title) +{ + Language lang; + lang = GetWinLanguage(); + const char *msg[1]; + msg[0] = GET_MULTILANGE_STR(GET_FLASH_ALGO, lang); + FramePopMsgWithTitle(frame, title, msg, sizeof(msg) / sizeof(msg[0]), ALIGN_LEFT); +} + +/** + * @brief get more algo popup + * @retval None + */ +void GetMoreAlgoMsgPopup(Frame *frame) +{ + Language lang = GetWinLanguage(); + char *title = GET_MULTILANGE_STR(END_OF_LIST, lang); + GetMoreAlgoMsgPopupWithTitle(frame, title); +} + +/** + * @brief no algo popup + * @retval None + */ +void NoAlgoMsgPopup(Frame *frame) +{ + if (frame->lineNumber > frame->staticItemNum) { + /* At least one algo is available, return */ + return; + } + Language lang = GetWinLanguage(); + char *title = GET_MULTILANGE_STR(NO_ALGO, lang); + GetMoreAlgoMsgPopupWithTitle(frame, title); +} + +/** + * @brief no flash algo popup + * @retval None + */ +void NoFlashAlgoMsgPopup(Frame *frame) +{ + if (frame->lineNumber > frame->staticItemNum) { + /* At least one flash algo is available, return */ + return; + } + Language lang = GetWinLanguage(); + char *title = GET_MULTILANGE_STR(NO_FLASH_ALGO, lang); + GetFlashAlgoMsgPopupWithTitle(frame, title); +} + +/** + * @brief recovery factory mode + * @retval None + */ +void RecoveryFactoryMsgPopup(Frame *frame) +{ + DapLinkStatus status; + DapLinkStatusGet(&status); + /* Check algo delete status, if not success, show reseting */ + if (status.statusChangeMask == STATUS_CHANGE_MASK_ALGO_DELETE_STATUS) { + if (status.algoDeleteStatus != ALGORITHM_DELETE_SUCCESS) { + char *msg[LANGUAGE_NUM] = MULTI_LANGUAGE(DEBUGGER_RST); + FramePopMsg(frame, msg[GetWinLanguage()]); + } + } + /* Algo delete success, show reset success */ + char *msg[LANGUAGE_NUM] = MULTI_LANGUAGE(DEBUGGER_RST_SUCC); + FramePopMsg(frame, msg[GetWinLanguage()]); +} + +/** + * @brief image upgrade popup + * @retval None + */ +void ImageUpgradeMsgPopup(Frame *frame) +{ + DapLinkStatus status; + DapLinkStatusGet(&status); + if (status.statusChangeMask == STATUS_CHANGE_MASK_IMAGE_UPGRADE_STATUS) { + ImageUpgradeStatusShow(frame, status.imageUpgradeStatus); + status.statusChangeMask &= ~STATUS_CHANGE_MASK_IMAGE_UPGRADE_STATUS; + DapLinkStatusSet(&status); + return; + } + char *msg[LANGUAGE_NUM] = MULTI_LANGUAGE(IMAGE_UPGRADEING); + FramePopMsg(frame, msg[GetWinLanguage()]); +} + +/** + * @brief error image upgrade popup + * @retval None + */ +void ErrorImageUpgradeMsgPopup(Frame *frame) +{ + char *msg[LANGUAGE_NUM] = MULTI_LANGUAGE(TARGET_IMAGE_ERROR); + FramePopMsg(frame, msg[GetWinLanguage()]); +} + +/** + * @brief image delete popup + * @retval None + */ +void ImageDeleteMsgPopup(Frame *frame) +{ + DapLinkStatus status; + + DapLinkStatusGet(&status); + if (status.statusChangeMask == STATUS_CHANGE_MASK_IMAGE_DELETE_STATUS) { + ImageDeleteStatusShow(frame, status.imageDeleteStatus); + return; + } + char *msg[LANGUAGE_NUM] = MULTI_LANGUAGE(DELETEING); + FramePopMsg(frame, msg[GetWinLanguage()]); +} + +/** + * @brief algo delete popup + * @retval None + */ +void AlgoDeleteMsgPopup(Frame *frame) +{ + DapLinkStatus status; + + DapLinkStatusGet(&status); + if (status.statusChangeMask == STATUS_CHANGE_MASK_ALGO_DELETE_STATUS) { + AlgoDeleteStatusShow(frame, status.algoDeleteStatus); + return; + } + char *msg[LANGUAGE_NUM] = MULTI_LANGUAGE(DELETEING); + FramePopMsg(frame, msg[GetWinLanguage()]); +} + +/** + * @brief error algo select popup + * @retval None + */ +void ErrorAlgoSelectedMsgPopup(Frame *frame) +{ + char *msg[LANGUAGE_NUM] = MULTI_LANGUAGE(TARGET_ALGO_ERROR); + FramePopMsg(frame, msg[GetWinLanguage()]); +} + +/** + * @brief factory mode image or algo delete Popup + * @retval None + */ +void FactoryDeleteMsgPopup(Frame *frame) +{ + char *msg[LANGUAGE_NUM] = MULTI_LANGUAGE(DELETE_SUCCESS); + FramePopMsg(frame, msg[GetWinLanguage()]); +} + +/** + * @brief Erase Chip Popup + * @retval None + */ +void EraseChipMsgPopup(Frame *frame) +{ + int algoIdx = frame->userData; + Language lang = GetWinLanguage(); + + char *msg[LANGUAGE_NUM] = MULTI_LANGUAGE(ERASEING); + FramePopMsg(frame, msg[lang]); + + TargetEraseList algoHandle; + int ret = TargetLibEraseListGet(&algoHandle, sizeof(algoHandle)); + if ((ret != TARGET_LIB_OK) || (algoIdx >= algoHandle.count)) { + return; + } + + const char *eraseMsg[2]; // 2 msg, 1 for name, 2 for result + eraseMsg[0] = algoHandle.eraseList[algoIdx].name; + if (OfflineEraseChip(algoHandle.eraseList[algoIdx].index) == OFFLINE_DOWNLOAD_OK) { + eraseMsg[1] = GET_MULTILANGE_STR(ERASE_SUCCESS, lang); + } else { + eraseMsg[1] = GET_MULTILANGE_STR(ERASE_FAIL, lang); + } + FramePopMsgWithTitle(frame, 0, eraseMsg, sizeof(eraseMsg) / sizeof(eraseMsg[0]), ALIGN_MID); +} + +static void FactoryNoImageAlgoMsgPopup(Frame *frame, int imageCnt, int algoCnt) +{ + Language lang = GetWinLanguage(); + const char *title; + const char *msg[1]; + if (!HasValidImage(imageCnt) && !HasValidAlgo(algoCnt)) { + title = GET_MULTILANGE_STR(MISS_IMAGE_ALGO, lang); + msg[0] = GET_MULTILANGE_STR(GET_MORE_IMAGE_ALGO, lang); + } else if (!HasValidImage(imageCnt)) { + title = GET_MULTILANGE_STR(MISS_IMAGE, lang); + msg[0] = GET_MULTILANGE_STR(GET_MORE_IMAGE, lang); + } else { + title = GET_MULTILANGE_STR(MISS_ALGO, lang); + msg[0] = GET_MULTILANGE_STR(GET_MORE_ALGO, lang); + } + FramePopMsgWithTitle(frame, title, msg, sizeof(msg)/sizeof(msg[0]), ALIGN_LEFT); + return; +} + +static void FactoryImageAlgoErrorMsgPopup(Frame *frame, int imageStatus, int algoStatus) +{ + Language lang = GetWinLanguage(); + char *title; + const char *msg[1]; + if ((imageStatus == TARGET_LIB_FILE_STATUS_BAD) && (algoStatus == TARGET_LIB_FILE_STATUS_BAD)) { + title = GET_MULTILANGE_STR(IMAGE_ALGO_ERROR, lang); + msg[0] = GET_MULTILANGE_STR(GET_MORE_IMAGE_ALGO, lang); + } else if (imageStatus == TARGET_LIB_FILE_STATUS_BAD) { + title = GET_MULTILANGE_STR(IMAGE_ERROR, lang); + msg[0] = GET_MULTILANGE_STR(GET_MORE_IMAGE, lang); + } else { + title = GET_MULTILANGE_STR(ALGO_ERROR, lang); + msg[0] = GET_MULTILANGE_STR(GET_MORE_ALGO, lang); + } + FramePopMsgWithTitle(frame, title, msg, sizeof(msg)/sizeof(msg[0]), ALIGN_LEFT); + return; +} + +static void FactoryImageAlgoNoMatchMsgPopup(Frame *frame) +{ + frame = frame; + Frame *popupFrame = GetFactoryImageAlgoNoMatchFrame(); + UpdateActiveFrame(popupFrame); +} + +static void FactoryImageRestrictedMsgPopup(Frame *frame) +{ + frame = frame; + Frame *popupFrame = GetFactoryImageRestrictedFrame(); + UpdateActiveFrame(popupFrame); +} + +/** + * @brief Image upgrade message popup + * @retval None + */ +void FactoryImageUpgradeMsgPopup(Frame *frame) +{ + FactoryImageHandle imageHandle; + + FactoryImageListGet(&imageHandle); + if (!HasValidImage(imageHandle.count)) { + FactoryNoImageAlgoMsgPopup(frame, imageHandle.count, 1); + return; + } + + if (g_loadChkSucc == false) { + FactoryImageRestrictedMsgPopup(frame); + return; + } + + FactoryAlgoNoMatchList noMatchList; + if (FactoryAlgoMatchCheck(&noMatchList)) { + FactoryImageAlgoNoMatchMsgPopup(frame); + return; + } + ImageUpgradeMsgPopup(frame); +} + +/** + * @brief Flash protect off + * @retval None + */ +void FlashProtectOffMsgPopup(Frame *frame) +{ + Language lang = GetWinLanguage(); + char *msg = GET_MULTILANGE_STR(FLASH_PROTECT_OFF_RUNING, lang); + FramePopMsg(frame, msg); + + if (SysUnlockSecurity() == true) { + msg = GET_MULTILANGE_STR(FLASH_PROTECT_OFF_SUCC, lang); + } else { + msg = GET_MULTILANGE_STR(FLASH_PROTECT_OFF_FAIL, lang); + } + FramePopMsg(frame, msg); +} + +/** + * @brief Show CRC value + * @retval true or false + */ +static bool CrcCheckShowCrc(Frame *frame, FactoryCrcStatus *status) +{ + char *title = NULL; + char msgBody[CRC_MSG_LINES][MSG_LINE_SIZE] = {0}; + char hex[DIGITAL_HEX_MSG_LEN] = {'0', 'x'}; + char len[DIGITAL_RATE_MSG_LEN] = {0}; + char *p = len; + const char *msg[CRC_MSG_LINES]; + Language lang = GetWinLanguage(); + /* Get title */ + if ((status->results == USER_CRC_CHECK_SUCCESS) && (status->preCrc == status->currentCrc)) { + title = GET_MULTILANGE_STR(CRC_CHK_SUCC, lang); + } else { + title = GET_MULTILANGE_STR(CRC_CHK_FAIL, lang); + } + int i = 0; /* Avoid using magic words directly, code check */ + char *pHex = &hex[strlen("0x")]; // skip 2 bytes of "0x" + if (strcat_s(msgBody[i], MSG_LINE_SIZE, " ") != EOK) { + return false; + } + /* Expect CRC */ + if (strcat_s(msgBody[i], MSG_LINE_SIZE, GET_MULTILANGE_STR(CRC_EXPECT, lang)) != EOK) { + return false; + } + util_write_hex32(pHex, status->preCrc); + if (strcat_s(msgBody[i], MSG_LINE_SIZE, hex) != EOK) { + return false; + } + /* Actual CRC */ + if (strcat_s(msgBody[++i], MSG_LINE_SIZE, " ") != EOK) { + return false; + } + if (strcat_s(msgBody[i], MSG_LINE_SIZE, GET_MULTILANGE_STR(CRC_ACTUAL, lang)) != EOK) { + return false; + } + util_write_hex32(pHex, status->currentCrc); + if (strcat_s(msgBody[i], MSG_LINE_SIZE, hex) != EOK) { + return false; + } + /* CRC length */ + if (strcat_s(msgBody[++i], MSG_LINE_SIZE, " ") != EOK) { + return false; + } + if (strcat_s(msgBody[i], MSG_LINE_SIZE, GET_MULTILANGE_STR(CRC_CHK_LENGTH, lang)) != EOK) { + return false; + } + util_write_uint32(p, status->checkLen); + if (strcat_s(msgBody[i], MSG_LINE_SIZE, p) != EOK) { + return false; + } + /* CRC offset in image */ + if (strcat_s(msgBody[++i], MSG_LINE_SIZE, " ") != EOK) { + return false; + } + if (strcat_s(msgBody[i], MSG_LINE_SIZE, GET_MULTILANGE_STR(CRC_CHK_ADDR, lang)) != EOK) { + return false; + } + util_write_hex32(pHex, status->checkStartAddr); + if (strcat_s(msgBody[i], MSG_LINE_SIZE, hex) != EOK) { + return false; + } + + for (i = 0; i < sizeof(msg) / sizeof(msg[0]); ++i) { + msg[i] = msgBody[i]; + } + /* show title and crc items */ + FramePopMsgWithTitle(frame, title, msg, sizeof(msg)/sizeof(msg[0]), ALIGN_LEFT); + return true; +} + +/** + * @brief CRC Error Popup + * @retval None + */ +static void CrcCheckErrorStatusPopup(Frame *frame, FactoryCrcStatus *status) +{ + Language lang = GetWinLanguage(); + char *msg = 0; + /* init message */ + switch (status->results) { + case FACTORY_CRC_CHECK_RES_NOT_CONNECT: + msg = GET_MULTILANGE_STR(TARGET_CONNECTED_FAIL, lang); /* Connection failed. */ + break; + case FACTORY_CRC_CHECK_RES_FAIL: + msg = GET_MULTILANGE_STR(TARGET_VERIFY_FAIL, lang); /* Verification failed. */ + break; + case FACTORY_CRC_CHECK_RES_READ_FAIL: + msg = GET_MULTILANGE_STR(GET_IMAGE_FAIL, lang); /* Failed to obtain the image. */ + break; + case FACTORY_CRC_CHECK_RES_BAD_FILE: + msg = GET_MULTILANGE_STR(IMAGE_ERROR, lang); /* The image is incorrect. */ + break; + case FACTORY_CRC_CHECK_RES_ALGO_ERROR: + msg = GET_MULTILANGE_STR(TARGET_RUN_ALGO_FAIL, lang); /* Failed to run the algorithm. */ + break; + case FACTORY_CRC_CHECK_RES_NO_ALGO: + msg = GET_MULTILANGE_STR(TARGET_GET_ALGO_FAIL, lang); /* Failed to obtain the algorithm. */ + break; + default: + break; + } + /* popup msg */ + if (msg) { + FramePopMsg(frame, msg); + } +} + +/** + * @brief CRC Check result popup + * @retval None + */ +void CrcCheckMsgPopup(Frame *frame) +{ + FactoryCrcStatus status; + FactoryImageHandle imageHandle; + int ret; + int imageIdx = frame->userData; + Language lang = GetWinLanguage(); + + FactoryImageListGet(&imageHandle); + if (imageHandle.libInfo[imageIdx].fileStatus == TARGET_LIB_FILE_STATUS_BAD) { + /* if image is bad, don't check alog and force it's normal */ + FactoryImageAlgoErrorMsgPopup(frame, imageHandle.libInfo[imageIdx].fileStatus, TARGET_LIB_FILE_STATUS_NORMAL); + return; + } + /* if image is ok, show verify, crc check maybe take some seconds or one minute */ + FramePopMsg(frame, GET_MULTILANGE_STR(TARGET_VERIFYING, lang)); + + /* Do Crc check */ + ret = FactoryCrcget(&status, imageIdx); + if (ret != FACTORY_STATUS_OK) { /* fail */ + FramePopMsg(frame, GET_MULTILANGE_STR(GET_IMAGE_FAIL, lang)); + return; + } + + if ((status.results == FACTORY_CRC_CHECK_RES_SUCCESS) || (status.results == FACTORY_CRC_CHECK_RES_ERROR)) { + /* crc check done, show result */ + CrcCheckShowCrc(frame, &status); + } else { + /* other crc check status, popup */ + CrcCheckErrorStatusPopup(frame, &status); + } +} + +/** + * @brief Restory Factory Frame + * @retval None + */ +void RestoreFactory(Frame *frame) +{ + ConfigRestoreFactory(); +} + +/** + * @brief Generate dynmaic itmes + * @retval None + */ +static void CreateDynItem(Item *item, char *filename, const SelectedProc proc, Frame *linkFrame, unsigned int userData) +{ + Item fileItem; + for (int i = 0; i < sizeof(fileItem.text) / sizeof(fileItem.text[0]); ++i) { + fileItem.text[i] = filename; /* Chinese and English use the same filename */ + } + fileItem.itemSelectedProc = proc; + fileItem.linkFrame = linkFrame; + fileItem.getInfo = 0; + fileItem.userData = userData; + *item = fileItem; +} + +/** + * @brief copy static items to dynamic itmes + * @retval None + */ +static unsigned int CopyStaticItem(Item *dstItem, const Frame *frame) +{ + unsigned int i = 0; + for (i = 0; i < frame->staticItemNum; ++i) { + dstItem[i] = frame->pItem[i]; + } + return i; +} + +/** + * @brief combine file name and index + * @retval true or false + */ +static bool Translate2ItemNameByFileName(char *itemName, const char *filename, int idx) +{ + errno_t rc = EOK; + int2str(itemName, idx); + rc = strcat_s(itemName, PROC_NAME_MAX_LEN, "."); + if (rc != EOK) { + return false; + } + rc = strcat_s(itemName, PROC_NAME_MAX_LEN, filename); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Create selected images Frame + * @retval None + */ +void CreateSelectImageListFrame(Frame *frame) +{ + CreateDynImageListFrame(frame, g_imageDynItem[DYN_ITEM_SELECT], ImageSelectedProc); +} + +/** + * @brief Create delete images Frame + * @retval None + */ +void CreateDeleteImageListFrame(Frame *frame) +{ + CreateDynImageListFrame(frame, g_imageDynItem[DYN_ITEM_DELETE], ImageDeleteProc); +} + +/** + * @brief Create show images Frame + * @retval None + */ +void CreateShowImageListFrame(Frame *frame) /* for factory mode */ +{ + CreateDynImageListFrame(frame, g_imageDynItem[DYN_ITEM_SHOW], NULL); +} + +/** + * @brief Create factory images Frame + * @retval None + */ +void CreateFactoryImageListFrame(Frame *frame) +{ + CreateDynImageListFrame(frame, g_imageDynItem[FACTORY_ITEM_SELECT], FactoryImageListDummyProc); +} + +/** + * @brief Create Dynamic images Frame + * @retval true or false + */ +static bool CreateDynImageListFrame(Frame *frame, Item *dynItems, SelectedProc selectedProc) +{ + TargetImageHandle imageHandle; + int idx = 0; + errno_t rc = EOK; + Language lang = GetWinLanguage(); + /* Obtains images in factory or non-factory mode. */ + if (devConfig.enableFactory) { + FactoryImageListGet((FactoryImageHandle *)((void *)&imageHandle)); + } else { + TargetLibImageListGet(&imageHandle); + } + idx = CopyStaticItem(&dynItems[idx], frame); /* Copy Static Items first */ + Frame *nextFrame; + SelectedProc proc; + for (int i = 0; i < imageHandle.count; ++i, ++idx) { + memset_s(g_imageName[i], sizeof(g_imageName[i]), 0, sizeof(g_imageName[i])); + char *p = g_imageName[i]; + /* Add an index before the file name. */ + Translate2ItemNameByFileName(p, imageHandle.libInfo[i].name, i + 1); + proc = selectedProc; + nextFrame = frame->dynItemSelectFrame; /* Jump frame after confirmation */ + if (imageHandle.libInfo[i].fileStatus == TARGET_LIB_FILE_STATUS_BAD) { + rc = strcat_s(p, sizeof(g_imageName[i]), GET_MULTILANGE_STR(FILE_ERROR, lang)); + if (rc != EOK) { + return false; + } + if (selectedProc == ImageSelectedProc) { + nextFrame = frame->dynFailItemSelectFrame; /* show fail frame */ + proc = 0; + } + } else { + if (selectedProc != FactoryImageListDummyProc) { + /* Need add load/max load information behind image name */ + uint32_t maxLoads = imageHandle.libInfo[i].info.maxLoads; + uint32_t loadCnt = TargetImageLoadCntGet(i); + GreateImageDownloadDetailInfo(p, sizeof(g_imageName[0]), maxLoads, loadCnt); + } + } + CreateDynItem(&dynItems[idx], p, proc, nextFrame, idx - frame->staticItemNum); + } + /* Update frame */ + frame->lineNumber = idx; + frame->pItem = dynItems; + return true; +} + +/** + * @brief Show images and algo Frame + * @retval None + */ +void CreateShowImageAndAlgoListFrame(Frame *frame) /* for factory mode */ +{ + CreateFactoryImageAndAlgoFrame(frame, g_imageAlgoDynItem[DYN_ITEM_SHOW], NULL, NULL); +} + +/** + * @brief Delete images and algo Frame + * @retval None + */ +void CreateDeleteImageAndAlgoListFrame(Frame *frame) +{ + CreateFactoryImageAndAlgoFrame(frame, g_imageAlgoDynItem[DYN_ITEM_DELETE], FactoryImageDeleteProc, AlgoDeleteProc); +} + +/** + * @brief Create images download detail information + * @retval true or false + */ +static bool GreateImageDownloadDetailInfo(char *const name, uint32_t nameLen, uint32_t maxLoads, uint32_t loadCnt) +{ + errno_t rc = EOK; + if (maxLoads == 0) { + return false; + } + Language lang = GetWinLanguage(); + char number[11] = {0}; // 11 is the max digits number of max value of unsigned int + char *p = number; + rc = strcat_s(name, nameLen, "("); + if (rc != EOK) { + return false; + } + rc = strcat_s(name, nameLen, GET_MULTILANGE_STR(DOWNLOAD, lang)); + if (rc != EOK) { + return false; + } + util_write_uint32(p, loadCnt); /* download times */ + rc = strcat_s(name, nameLen, p); + if (rc != EOK) { + return false; + } + rc = strcat_s(name, nameLen, GET_MULTILANGE_STR(TIMES, lang)); + if (rc != EOK) { + return false; + } + rc = strcat_s(name, nameLen, "/"); + if (rc != EOK) { + return false; + } + rc = strcat_s(name, nameLen, GET_MULTILANGE_STR(PERIMIT, lang)); + if (rc != EOK) { + return false; + } + memset_s(p, sizeof(number), 0, sizeof(number)); + util_write_uint32(p, maxLoads); /* max permit times */ + rc = strcat_s(name, nameLen, p); + if (rc != EOK) { + return false; + } + rc = strcat_s(name, nameLen, GET_MULTILANGE_STR(TIMES, lang)); + if (rc != EOK) { + return false; + } + rc = strcat_s(name, nameLen, ")"); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Create Factory images items + * @retval true or false + */ +static bool GreateFactoryImageFrame(Frame *frame, Item *dynItems, SelectedProc selectedProc, int *index) +{ + FactoryImageHandle imageHandle; + Language lang = GetWinLanguage(); + int idx = 0; + errno_t rc = EOK; + + FactoryImageListGet(&imageHandle); + idx = CopyStaticItem(&dynItems[idx], frame); + Frame *nextFrame = frame->dynItemSelectFrame; /* Display frame if items is selected */ + if (HasValidImage(imageHandle.count)) { /* valid images */ + CreateDynItem(&dynItems[idx++], GET_MULTILANGE_STR(IMAGE, lang), 0, 0, 0); + for (int i = 0; i < imageHandle.count; ++i, ++idx) { + memset_s(g_imageName[i], sizeof(g_imageName[i]), 0, sizeof(g_imageName[i])); + Translate2ItemNameByFileName(g_imageName[i], imageHandle.libInfo[i].name, i + 1); + if (imageHandle.libInfo[i].fileStatus == TARGET_LIB_FILE_STATUS_BAD) { + rc = strcat_s(g_imageName[i], sizeof(g_imageName[i]), GET_MULTILANGE_STR(FILE_ERROR, lang)); + } else { + /* Add extern info of images behind the file name */ + uint32_t maxLoads = imageHandle.libInfo[i].info.maxLoads; + uint32_t loadCnt = FactoryImageLoadCntGet(i); + GreateImageDownloadDetailInfo(g_imageName[i], sizeof(g_imageName[i]), maxLoads, loadCnt); + } + if (rc != EOK) { + return false; + } + CreateDynItem(&dynItems[idx], g_imageName[i], selectedProc, nextFrame, i); + } + } else { /* No valid image */ + CreateDynItem(&dynItems[idx++], GET_MULTILANGE_STR(NO_IMAGE, lang), 0, 0, 0); + } + *index = idx; + return true; +} + +/** + * @brief Create Factory Algo items + * @retval true or false + */ +static bool GreateFactoryAlgoFrame(Frame *frame, Item *dynItems, SelectedProc selectedProc, int *index) +{ + FactoryAlgoHandle algoHandle; + Language lang = GetWinLanguage(); + int idx = *index; + errno_t rc = EOK; + Frame *nextFrame = frame->dynItemSelectFrame; /* Display frame if items is selected */ + + FactoryAlgoListGet(&algoHandle); + if (HasValidAlgo(algoHandle.count)) { /* valid algo */ + CreateDynItem(&dynItems[idx++], GET_MULTILANGE_STR(ALGO, lang), 0, 0, 0); + for (int i = 0; i < algoHandle.count; ++i, ++idx) { + memset_s(g_algoName[i], sizeof(g_algoName[i]), 0, sizeof(g_algoName[i])); + Translate2ItemNameByFileName(g_algoName[i], algoHandle.libInfo[i].name, i + 1); + if (algoHandle.libInfo[i].fileStatus == TARGET_LIB_FILE_STATUS_BAD) { + /* add error */ + rc = strcat_s(g_algoName[i], sizeof(g_algoName[i]), GET_MULTILANGE_STR(FILE_ERROR, lang)); + } + if (rc != EOK) { + return false; + } + CreateDynItem(&dynItems[idx], g_algoName[i], selectedProc, nextFrame, i); + } + } else { /* No valid algo */ + CreateDynItem(&dynItems[idx++], GET_MULTILANGE_STR(NO_ALGO, lang), 0, 0, 0); + } + *index = idx; + return true; +} + +/** + * @brief Create Factory Image and Algo Frame + * @retval None + */ +static void CreateFactoryImageAndAlgoFrame(Frame *frame, Item *dynItems, SelectedProc selectedProc, + SelectedProc algoSelectProc) +{ + int idx = 0; + GreateFactoryImageFrame(frame, dynItems, selectedProc, &idx); /* out: idx */ + GreateFactoryAlgoFrame(frame, dynItems, algoSelectProc, &idx); /* inout:idx */ + frame->lineNumber = idx; + frame->pItem = dynItems; +} + +/** + * @brief Show unmatch algo List frame + * @retval None + */ +void CreateUnMatchAlgoListFrame(Frame *frame) +{ + FactoryAlgoNoMatchList list; + FactoryAlgoMatchCheck(&list); + Item *dynItems = &g_imageUnMatchDynItem[0]; + int idx = CopyStaticItem(dynItems, frame); + + /* Generate dynamic items of un match algo names */ + for (int i = 0; i < list.count; ++i, ++idx) { + memset_s(g_algoName[i], sizeof(g_algoName[i]), 0, sizeof(g_algoName[i])); + char *p = g_algoName[i]; + char *name = list.algoInfo[i].name; + Translate2ItemNameByFileName(p, name, i + 1); + CreateDynItem(&dynItems[idx], p, 0, 0, 0); + } + /* Updata frame */ + frame->lineNumber = idx; + frame->pItem = dynItems; +} + +/** + * @brief Show Restricted Images List + * @retval None + */ +void CreateImageRestrictedListFrame(Frame *frame) +{ + FactoryRestrictedImageList list; + FactoryImageLoadCntCheck(&list); /* Get Image with load times restrict */ + Item *dynItems = &g_imageRestrictedDynItem[0]; + int idx = CopyStaticItem(dynItems, frame); + + /* Generate dynamic items of image names */ + for (int i = 0; i < list.count; ++i, ++idx) { + memset_s(g_algoName[i], sizeof(g_algoName[i]), 0, sizeof(g_algoName[i])); + char *p = g_algoName[i]; + char *name = list.imageInfo[i].name; + Translate2ItemNameByFileName(p, name, i + 1); + CreateDynItem(&dynItems[idx], p, 0, 0, 0); + } + /* Updata frame */ + frame->lineNumber = idx; + frame->pItem = dynItems; +} + +/** + * @brief Show Algo Select List + * @retval None + */ +void AlgoSelectFrameProc(Frame *frame) +{ + CreateDynAlgoListFrame(frame, g_algoDynItem[DYN_ITEM_SELECT], AlgoSelectedProc); +} + +/** + * @brief Show Algo Delete List + * @retval None + */ +void CreateDeleteAlgoListFrame(Frame *frame) +{ + CreateDynAlgoListFrame(frame, g_algoDynItem[DYN_ITEM_DELETE], AlgoDeleteProc); +} + +/** + * @brief Show Algo List + * @retval None + */ +void CreateShowAlgoListFrame(Frame *frame) +{ + CreateDynAlgoListFrame(frame, g_algoDynItem[DYN_ITEM_SHOW], NULL); +} + +/** + * @brief Genearte Algo List + * @retval true or false + */ +static bool CreateDynAlgoListFrame(Frame *frame, Item *dynItems, SelectedProc selectedProc) +{ + TargetAlgoHandle algoHandle; + unsigned int idx = 0; + Frame *nextFrame; + SelectedProc proc; + Language lang = GetWinLanguage(); + errno_t rc = EOK; + + TargetLibAlgoListGet(&algoHandle); + idx = CopyStaticItem(&dynItems[idx], frame); + for (int i = 0, algoIdx = 0; i < algoHandle.count; ++i) { + memset_s(g_algoName[i], sizeof(g_algoName[i]), 0, sizeof(g_algoName[i])); + proc = selectedProc; + nextFrame = frame->dynItemSelectFrame; + /* Add Item Index of file */ + Translate2ItemNameByFileName(g_algoName[algoIdx], algoHandle.libInfo[i].name, idx); + if (algoHandle.libInfo[i].fileStatus == TARGET_LIB_FILE_STATUS_BAD) { + rc = strcat_s(g_algoName[algoIdx], sizeof(g_algoName[algoIdx]), GET_MULTILANGE_STR(FILE_ERROR, lang)); + if (rc != EOK) { + return false; + } + if (selectedProc == AlgoSelectedProc) { + /* If select algo file is bad, show special frame */ + nextFrame = frame->dynFailItemSelectFrame; + proc = 0; + } + } + + if (selectedProc == AlgoSelectedProc) { + if (algoHandle.libInfo[i].fileStatus == TARGET_LIB_FILE_STATUS_SECURITY) { + /* Don't show if file status is security */ + continue; + } + /* Show (Selected) behind file name */ + if (ConfigCurrentAlgoIndexRead() == i) { + rc = strcat_s(g_algoName[algoIdx], sizeof(g_algoName[algoIdx]), GET_MULTILANGE_STR(SELECTED, lang)); + } + if (rc != EOK) { + return false; + } + } + CreateDynItem(&dynItems[idx], g_algoName[algoIdx], proc, nextFrame, i); + /* Update item index and algo index */ + ++idx; + ++algoIdx; + } + /* Updata frame items number and dynamic items */ + frame->lineNumber = idx; + frame->pItem = dynItems; + return true; +} + +/** + * @brief Create erase file list frame + * @retval None + */ +void CreateEraseListFrame(Frame *frame) +{ + CreateDynEraseListFrame(frame, g_eraseListItem, NULL); +} + +/** + * @brief Create Dynamic Erase file list + * @retval None + */ +static void CreateDynEraseListFrame(Frame *frame, Item *dynItems, SelectedProc selectedProc) +{ + TargetEraseList algoHandle; + int ret = TargetLibEraseListGet(&algoHandle, sizeof(algoHandle)); + if (ret != TARGET_LIB_OK) { /* Get erase list fail and ret */ + return; + } + unsigned int idx = 0; + Frame *nextFrame; + SelectedProc proc; + + idx = CopyStaticItem(&dynItems[idx], frame); + /* Copy the file name to items */ + for (int i = 0, algoIdx = 0; i < algoHandle.count; ++i) { + memset_s(g_algoName[i], sizeof(g_algoName[i]), 0, sizeof(g_algoName[i])); + proc = selectedProc; + nextFrame = frame->dynItemSelectFrame; + Translate2ItemNameByFileName(g_algoName[algoIdx], algoHandle.eraseList[i].name, idx); + CreateDynItem(&dynItems[idx], g_algoName[algoIdx], proc, nextFrame, i); + ++idx; + ++algoIdx; + } + /* update the frame line number and dynmaic items pointer */ + frame->lineNumber = idx; + frame->pItem = dynItems; +} + +/** + * @brief Displayed in Chinese + * @retval None + */ +void SetLanguageToCN(Frame *frame) +{ + if (GetWinLanguage() != LANGUAGE_CN) { + SetWinLanguage(LANGUAGE_CN); + FrameShow(frame); + } +} + +/** + * @brief Displayed in English + * @retval None + */ +void SetLanguageToEN(Frame *frame) +{ + if (GetWinLanguage() != LANGUAGE_EN) { + SetWinLanguage(LANGUAGE_EN); + FrameShow(frame); + } +} + +/** + * @brief Set debug interface to SWD + * @retval None + */ +void SetInterfaceToSwd(Frame *frame) +{ + if (SwdJtagDebugPortGet() != DAP_PORT_SWD) { + SwdJtagDebugPortSet(DAP_PORT_SWD); + FrameShow(frame); + } +} + +/** + * @brief Set debug interface to Jtag + * @retval None + */ +void SetInterfaceToJtag(Frame *frame) +{ + if (SwdJtagDebugPortGet() != DAP_PORT_JTAG) { + SwdJtagDebugPortSet(DAP_PORT_JTAG); + FrameShow(frame); + } +} + +/** + * @brief Enable Multi Copies and Show + * @retval None + */ +void EnableMultiCopies(Frame *frame) +{ + if (devConfig.enableMultiCopies != true) { + devConfig.enableMultiCopies = true; + FrameShow(frame); + } +} + +/** + * @brief Disable Multi Copies and Show + * @retval None + */ +void DisableMultiCopies(Frame *frame) +{ + if (devConfig.enableMultiCopies != false) { + devConfig.enableMultiCopies = false; + FrameShow(frame); + } +} + +/** + * @brief Enable High speed sampling and Show + * @retval None + */ +void EnableHsSampling(Frame *frame) +{ + if (devConfig.enableHsSampling != true) { + devConfig.enableHsSampling = true; + SetPerformanceTest(true); + FrameShow(frame); + } +} + +/** + * @brief Disable High speed sampling and Show + * @retval None + */ +void DisableHsSampling(Frame *frame) +{ + if (devConfig.enableHsSampling != false) { + devConfig.enableHsSampling = false; + SetPerformanceTest(false); + FrameShow(frame); + } +} + +/** + * @brief Factory Image upgrade + * @retval None + */ +void EnablePowerSupply(Frame *frame) +{ + if (devConfig.enablePowerSupply != true) { + devConfig.enablePowerSupply = true; + SysExternalPowerSet(SYS_EXTERNAL_POWER_ON); + FrameShow(frame); + } +} + +/** + * @brief Factory Image upgrade + * @retval None + */ +void DisablePowerSupply(Frame *frame) +{ + if (devConfig.enablePowerSupply != false) { + devConfig.enablePowerSupply = false; + SysExternalPowerSet(SYS_EXTERNAL_POWER_OFF); + FrameShow(frame); + } +} + +/** + * @brief Exit Factory Mode + * @retval None + */ +void ExitFactoryMode(Frame *frame) +{ + frame->pointer = 1; /* 指向工厂模式 */ + devConfig.enableFactory = false; + FactoryModeExit(); +} + +/** + * @brief Entry Factory Mode + * @retval None + */ +void EntryFactoryMode(Frame *frame) +{ + frame->pointer = 1; /* 始终指向烧录 */ + devConfig.enableFactory = true; + FactoryModeEnter(); +} + +/** + * @brief Deleting All Algorithms and Images in Factory Mode + * @retval None + */ +void FactoryImageAlgoDelete(Frame *frame) +{ + frame = frame; + FactoryImageFreeAll(); + FactoryAlgoFreeAll(); +} + +/** + * @brief Factory Image upgrade + * @retval None + */ +void FactoryImageUpgrade(Frame *frame) +{ + FactoryImageHandle imageHandle; + + FactoryImageListGet(&imageHandle); + if (!HasValidImage(imageHandle.count)) { /* valid check */ + return; + } + FactoryRestrictedImageList restrictedList; + g_loadChkSucc = true; + /* check image upgrade times */ + if (FactoryImageLoadCntCheck(&restrictedList)) { + g_loadChkSucc = false; + return; + } + /* Check image and algo match or not */ + FactoryAlgoNoMatchList noMatchList; + if (FactoryAlgoMatchCheck(&noMatchList)) { + return; + } + OfflineDownLoadStart(); +} + +/** + * @brief Deleting All Image in No-Factory + * @retval None + */ +void DeleteAllImage(Frame *frame) +{ + TargetLibImageDeleteAll(); + FrameShow(frame); +} + +/** + * @brief Deleting All Algorithms in No-Factory + * @retval None + */ +void DeleteAllAlgo(Frame *frame) +{ + frame = frame; + TargetLibAlgoDeleteAll(); +} + +/** + * @brief Get HiSparkTrace software version + * @retval true or false + */ +bool GetFWVersion(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if (!buf) { + return false; + } + rc = strncpy_s(buf, len, GetDevConfig()->swVersion, len); + if (rc !=EOK) { + return false; + } + return true; +} + +/** + * @brief Get HiSparkTrace hardware version + * @retval true or false + */ +bool GetHWVersion(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if (!buf) { + return false; + } + rc = strncpy_s(buf, len, GetDevConfig()->hwVersion, len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Get HiSparkTrace Serial number + * @retval true or false + */ +bool GetSN(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if (!buf) { + return false; + } + rc = strncpy_s(buf, len, GetDevConfig()->sn, len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Multi copies enable prompt + * @retval true or false + */ +bool GetMultiEnableSelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if ((devConfig.enableMultiCopies == false) || !buf) { + return false; + } + char *msg[] = MULTI_LANGUAGE(SELECTED); + rc = strncpy_s(buf, len, msg[GetWinLanguage()], len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Multi copies disable prompt + * @retval true or false + */ +bool GetMultiDisableSelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if ((devConfig.enableMultiCopies == true) || !buf) { + return false; + } + char *msg[] = MULTI_LANGUAGE(SELECTED); + rc = strncpy_s(buf, len, msg[GetWinLanguage()], len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief High speed sampling enable prompt + * @retval true or false + */ +bool GetHsSamplingEnableSelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if ((devConfig.enableHsSampling != true) || !buf) { + return false; + } + char *msg[] = MULTI_LANGUAGE(SELECTED); + rc = strncpy_s(buf, len, msg[GetWinLanguage()], len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief High speed sampling disable promptt + * @retval true or false + */ +bool GetHsSamplingDisableSelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if ((devConfig.enableHsSampling == true) || !buf) { + return false; + } + char *msg[] = MULTI_LANGUAGE(SELECTED); + rc = strncpy_s(buf, len, msg[GetWinLanguage()], len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Power supply enable prompt + * @retval true or false + */ +bool GetPowerSupplyEnableSelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if ((devConfig.enablePowerSupply != true) || !buf) { + return false; + } + char *msg[] = MULTI_LANGUAGE(SELECTED); + rc = strncpy_s(buf, len, msg[GetWinLanguage()], len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Power supply disable prompt + * @retval true or false + */ +bool GetPowerSupplyDisableSelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if ((devConfig.enablePowerSupply == true) || !buf) { + return false; + } + char *msg[] = MULTI_LANGUAGE(SELECTED); + rc = strncpy_s(buf, len, msg[GetWinLanguage()], len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Factory Mode Enable prompt + * @retval true or false + */ +bool GetFactoryModeEnableSelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if ((devConfig.enableFactory != true) || !buf) { + return false; + } + char *msg[] = MULTI_LANGUAGE(SELECTED); + rc = strncpy_s(buf, len, msg[GetWinLanguage()], len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief English selection prompt + * @retval true or false + */ +bool LanguageEnglishSelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + Language lang = GetWinLanguage(); + if ((lang != LANGUAGE_EN) || !buf) { + return false; + } + char *msg[] = MULTI_LANGUAGE(SELECTED); + rc = strncpy_s(buf, len, msg[lang], len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Chinese selection prompt + * @retval true or false + */ +bool LanguageChineseSelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + Language lang = GetWinLanguage(); + if ((lang != LANGUAGE_CN) || !buf) { + return false; + } + char *msg[] = MULTI_LANGUAGE(SELECTED); + rc = strncpy_s(buf, len, msg[lang], len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief SWD selection prompt + * @retval true or false + */ +bool SwdInterfaceSelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if ((SwdJtagDebugPortGet() != DAP_PORT_SWD) || !buf) { + return false; + } + char *msg[] = MULTI_LANGUAGE(SELECTED); + rc = strncpy_s(buf, len, msg[GetWinLanguage()], len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief JTAG selection prompt + * @retval true or false + */ +bool JtagInterfaceSelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + if ((SwdJtagDebugPortGet() != DAP_PORT_JTAG) || !buf) { + return false; + } + char *msg[] = MULTI_LANGUAGE(SELECTED); + rc = strncpy_s(buf, len, msg[GetWinLanguage()], len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Hook function for periodically refreshing the display. + * @retval None + */ +void DisplayPeriodProcHook(void) +{ + if (IsProgramFailFrame()) { + /* Periodically refreshes the upgrade failure information (blinking effect). */ + ImageUpgradeFailPeriodShow(GetCurFrame()); + } +} + +/** + * @brief Obtain the configuration of the display screen. + * @retval Pointer to the configuration structure of the screen. + */ +DeviceConfig *GetDevConfig(void) +{ + return &devConfig; +} + +/** + * @brief Format the connection rate + * @retval true or false + */ +static bool FormatConnectRate(unsigned int rate, char *const rateStr, unsigned int length) +{ + unsigned int formateRate; + char buf[MSG_MAX_LEN] = {0}; + errno_t rc = EOK; + + if (rate > MHZ) { + /* If the speed is greater than MHz, the speed is displayed in MHz. */ + formateRate = rate / MHZ; + int2str(buf, formateRate); + formateRate = (rate % MHZ) / KHZ; + if (formateRate != 0) { + rc = strcat_s(buf, MSG_MAX_LEN, "."); + if (rc != EOK) { + return false; + } + int2str(buf + strlen(buf), formateRate); + } + rc = strcat_s(buf, MSG_MAX_LEN, "MHz"); + if (rc != EOK) { + return false; + } + } else { + /* If the speed is less than MHz, the speed is displayed in KHz. */ + formateRate = rate / KHZ; + int2str(buf, formateRate); + formateRate = rate % KHZ; + if (formateRate != 0) { + rc = strcat_s(buf, MSG_MAX_LEN, "."); + if (rc != EOK) { + return false; + } + int2str(buf + strlen(buf), formateRate); + } + rc = strcat_s(buf, MSG_MAX_LEN, "KHz"); + if (rc != EOK) { + return false; + } + } + rc = strncpy_s(rateStr, length, buf, length); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Show connect status + * @retval true or false + */ +static bool ConnectStatusShow(Frame *frame, TargetConnectInfo *connectInfo) +{ + errno_t rc = EOK; + if (connectInfo->status == TARGET_DISCONNECT) { + /* Show welcome screen when not connected */ + WelcomeMsg(frame); + return false; + } + + /* Show Connect Mode and rate */ + char buf[MSG_MAX_LEN + 1] = {0}; + char rateBuf[MSG_MAX_LEN + 1] = {0}; + char *msg[] = MULTI_LANGUAGE(CONNECTED); + rc = strncpy_s(buf, sizeof(buf), msg[GetWinLanguage()], strlen(msg[GetWinLanguage()])); + if (rc != EOK) { + return false; + } + rc = strcat_s(buf, sizeof(buf), (SwdJtagDebugPortGet() == DAP_PORT_SWD) ? " SWD " : " JTAG "); + if (rc != EOK) { + return false; + } + FormatConnectRate(connectInfo->rate, rateBuf, MSG_MAX_LEN - strlen(buf)); + rc = strcat_s(buf, sizeof(buf), rateBuf); + if (rc != EOK) { + return false; + } + char *p = buf; + p[MSG_MAX_LEN] = 0; /* make sure it's end with 0 */ + FramePopMsg(frame, p); /* Popup Message */ + return true; +} + +/** + * @brief Show store status + * @retval None + */ +static void ImageStoreStatusShow(Frame *frame, IMAGE_STORE_STATUS status) +{ + Language lang; + + /* All Store Status */ + char *msg[IMAGE_STORE_STATUS_NUM][LANGUAGE_NUM] = { + MULTI_LANGUAGE(IMAGE_STORED), + MULTI_LANGUAGE(IMAGE_FAIL), + MULTI_LANGUAGE(MULTI_COPIES_FAIL), + MULTI_LANGUAGE(TARGET_IMAGE_ERROR), + MULTI_LANGUAGE(TARGET_IMAGE_ERROR), + MULTI_LANGUAGE(TARGET_ALGO_ERROR), + MULTI_LANGUAGE(WELCOME), + }; + if (status >= IMAGE_STORE_STATUS_NUM) { + /* Invalid state, return */ + return; + } + /* Popup the store status */ + lang = GetWinLanguage(); + FramePopMsg(frame, msg[status][lang]); +} + +/** + * @brief Get Connect rate and copy to buf + * @retval true or false + */ +static bool GetConnectStatus(char *buf, int len) +{ + char *connRate[2] = MULTI_LANGUAGE(CONNECT_RATE); /* 2 languages */ + char *p = buf; + char rateBuf[MSG_LINE_SIZE] = {0}; + errno_t rc = EOK; + + rc = strcpy_s, len, (p, (SwdJtagDebugPortGet() == DAP_PORT_SWD) ? "SWD" : "JTAG"); + if (rc != EOK) { + return false; + } + rc = strcat_s(p, len, connRate[GetWinLanguage()]); + if (rc != EOK) { + return false; + } + FormatConnectRate(SwdJtagClockGet(), rateBuf, len - strlen(buf)); + rc = strcat_s(p, len, rateBuf); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Popup Upgrade success Message + * @retval None + */ +static void ImageUpgradeSuccessShow(Frame *frame, const char *msg) +{ + /* Power ON LED show upgrade success */ + DownLoadLedOn(frame); + + /* The success message in big font is displayed on the screen. */ + SetGlobalDisaplyaMode(DISPLAY_REVERSE); + OledClearFromStartYPixel(FONT_SIZE); + ForceAllLineUsed(); + FramePopMsgWithFont(frame, msg, BIG_FONT_SIZE); + SetGlobalDisaplyaMode(DISPLAY_NORMAL); +} + +/** + * @brief Popup Upgrade Fail Message + * @retval None + */ +static void ImageUpgradeFailShow(const Frame *frame, const char *msg) +{ + /* The Fail message in big font is displayed on the screen. */ + OledClearFromStartYPixel(FONT_SIZE); + ForceAllLineUsed(); + FramePopMsgWithFont(frame, msg, BIG_FONT_SIZE); +} + +/** + * @brief The upgrade failure information blinks periodically. + * @retval None + */ +static void ImageUpgradeFailPeriodShow(const Frame *frame) +{ + static unsigned int cnt = 0; + SetGlobalDisaplyaMode((cnt++ & 1) ? DISPLAY_REVERSE : DISPLAY_NORMAL); + ImageUpgradeFailShow(frame, GetImageUpgradeFailMsg()); +} + +/** + * @brief Display image upgrade status. + * @retval None + */ +static void ImageUpgradeStatusShow(Frame *frame, IMAGE_UPGRADE_STATUS status) +{ + /* all image upgrade status */ + char *msg[IMAGE_UPGRADE_STATUS_NUM][LANGUAGE_NUM] = { + MULTI_LANGUAGE(IMAGE_UPGRADEING), + MULTI_LANGUAGE(TARGET_UPGRADE_SUCC), + MULTI_LANGUAGE(TARGET_CONNECTED_FAIL), + MULTI_LANGUAGE(TARGET_GET_ALGO_FAIL), + MULTI_LANGUAGE(TARGET_PROGRAMMING), + MULTI_LANGUAGE(TARGET_VERIFYING), + MULTI_LANGUAGE(TARGET_WRITE_FAIL), + MULTI_LANGUAGE(TARGET_GET_IMAGE_FAIL), + MULTI_LANGUAGE(TARGET_VERIFY_FAIL), + MULTI_LANGUAGE(TARGET_IMAGE_ERROR), + MULTI_LANGUAGE(TARGET_ALGO_ERROR), + MULTI_LANGUAGE(TARGET_RUN_ALGO_FAIL), + MULTI_LANGUAGE(WELCOME), + MULTI_LANGUAGE(TARGET_IMAGE_MAX_LOADS_ERROR), + }; + + if (status >= IMAGE_UPGRADE_STATUS_NUM) { + return; /* return if status is invalid */ + } + + Language lang = GetWinLanguage(); + + if ((status == IMAGE_UPGRADE_WRITE_FAIL) || (status == IMAGE_UPGRADE_VERIFY_FAIL)) { + /* if upgrade write fail or verify fail, Show special Fail message */ + Frame *tmpFrame = frame; + if (devConfig.enableFactory) { + tmpFrame = GetFactoryImageProgramFailFrame(); + } else { + tmpFrame = GetImageProgramFailFrame(); + } + /* Switch to the dedicated fail frame for special processing. */ + UpdateActiveFrame(tmpFrame); + SetImageUpgradeFailMsg(msg[status][lang]); + return ImageUpgradeFailShow(tmpFrame, msg[status][lang]); + } + + if (status == IMAGE_UPGRADE_SUCCESS) { + /* if upgrade success, Show special success message */ + Frame *tmpFrame = frame; + if (devConfig.enableFactory) { + /* Switch to the dedicated success frame for special processing. */ + tmpFrame = GetFactoryImageProgramSuccFrame(); + UpdateActiveFrame(tmpFrame); + } + return ImageUpgradeSuccessShow(tmpFrame, msg[status][GetWinLanguage()]); + } + /* Other status, show as normal */ + FramePopMsg(frame, msg[status][GetWinLanguage()]); + char msgBuf[MSG_MAX_LEN + 1] = {0}; + GetConnectStatus(msgBuf, sizeof(msgBuf) - 1); + char *p = msgBuf; + p[MSG_MAX_LEN] = 0; /* make sure end with 0 */ + FrameShowStatusBar(frame, p); +} + +/** + * @brief Display algo store status. + * @retval None + */ +static void AlgoStoreStatusShow(Frame *frame, ALGORITHM_STORE_STATUS status) +{ + Language lang; + /* all algo store status */ + char *msg[ALGORITHM_STORE_STATUS_NUM][LANGUAGE_NUM] = { + MULTI_LANGUAGE(ALGO_STORED), + MULTI_LANGUAGE(ALGO_STORED_FAIL), + MULTI_LANGUAGE(ALGO_STORED_MULTI_COPIES_FAIL), + MULTI_LANGUAGE(ALGO_CRC_FAIL), + MULTI_LANGUAGE(WELCOME), + }; + if (status >= ALGORITHM_STORE_STATUS_NUM) { + return; + } + /* popup status */ + lang = GetWinLanguage(); + FramePopMsg(frame, msg[status][lang]); +} + +/** + * @brief Firmware upgrade status. + * @retval None + */ +static void FirmwareUpgradeStatusShow(Frame *frame, FIRMWARE_UPGRADE_STATUS status) +{ + Language lang = GetWinLanguage(); + /* all firmware store status */ + char *msg[FIRMWARE_UPGRADE_STATUS_NUM][LANGUAGE_NUM] = { + MULTI_LANGUAGE(FW_UPGRADEING), + MULTI_LANGUAGE(FW_UPGRADE_SUCC), + MULTI_LANGUAGE(FW_CRC_FAIL), + MULTI_LANGUAGE(WELCOME), + }; + if (status > FIRMWARE_UPGRADE_STATUS_NUM) { + return; + } + /* popup status */ + FramePopMsg(frame, msg[status][lang]); +} + +/** + * @brief DAP sampline status. + * @retval true or false + */ +static bool DapSamplingStatusShow(const Frame *frame, const DapDebugInfo *dbgInfo) +{ + Language lang = GetWinLanguage(); + /* all DAP store status */ + char *title[DAP_STATUS_NUM][LANGUAGE_NUM] = { + MULTI_LANGUAGE(DAP_NOT_SAMPLING), + MULTI_LANGUAGE(DAP_DEBGU), + MULTI_LANGUAGE(DAP_SAMPLING), + MULTI_LANGUAGE(DAP_PC_STOP), + MULTI_LANGUAGE(DAP_TARGET_STOP), + MULTI_LANGUAGE(WELCOME), + }; + if (dbgInfo->status > DAP_STATUS_NUM) { + return false; + } + + char msgBuf[DAP_MSG_LINES][MSG_LINE_SIZE + 1] = {0}; + char digits[DAP_MSG_LINES][DAP_DATA_RATE_CHARS] = {0}; + uint8_t i = 0; + /* Get Total Sampling, error, overflow count */ + util_write_uint64_with_delimiter(digits[i++], dbgInfo->totalSampleCount); + util_write_uint64_with_delimiter(digits[i++], dbgInfo->totalErrorCount); + util_write_uint32(digits[i++], dbgInfo->errorRate); + util_write_uint64_with_delimiter(digits[i++], dbgInfo->totalOverflowCount); + i = 0; + /* Format the numbers */ + if (strcat_s(msgBuf[i], sizeof(msgBuf[i]), GET_MULTILANGE_STR(DAP_SAMPLE_CNT, lang)) != EOK) { + return false; + } + if (strcat_s(msgBuf[i], sizeof(msgBuf[i]), digits[i]) != EOK) { + return false; + } + if (strcat_s(msgBuf[i], sizeof(msgBuf[i]), GET_MULTILANGE_STR(TIMES, lang)) != EOK) { + return false; + } + if (strcat_s(msgBuf[++i], sizeof(msgBuf[i]), GET_MULTILANGE_STR(DAP_SAMPLE_ERROR, lang)) != EOK) { + return false; + } + if (strcat_s(msgBuf[i], sizeof(msgBuf[i]), digits[i]) != EOK) { + return false; + } + if (strcat_s(msgBuf[i], sizeof(msgBuf[i]), GET_MULTILANGE_STR(TIMES, lang)) != EOK) { + return false; + } + if (strcat_s(msgBuf[++i], sizeof(msgBuf[i]), GET_MULTILANGE_STR(DAP_ERROR_RATE, lang)) != EOK) { + return false; + } + if (strcat_s(msgBuf[i], sizeof(msgBuf[i]), digits[i]) != EOK) { + return false; + } + if (strcat_s(msgBuf[i], sizeof(msgBuf[i]), "%") != EOK) { + return false; + } + if (strcat_s(msgBuf[++i], sizeof(msgBuf[i]), GET_MULTILANGE_STR(DAP_OVERFLOW_CNT, lang)) != EOK) { + return false; + } + if (strcat_s(msgBuf[i], sizeof(msgBuf[i]), digits[i]) != EOK) { + return false; + } + if (strcat_s(msgBuf[i], sizeof(msgBuf[i]), GET_MULTILANGE_STR(TIMES, lang)) != EOK) { + return false; + } + char *msg[DAP_MSG_LINES]; + + /* Each item of data is regarded as an item. */ + for (i = 0; i < sizeof(msg) / sizeof(msg[0]); ++i) { + msg[i] = msgBuf[i]; + } + /* Use the DAP status as the header and the count as the display item. */ + FramePopMsgWithTitle(frame, title[dbgInfo->status][lang], (const char **)msg, sizeof(msg) / sizeof(msg[0]), + ALIGN_LEFT); + return true; +} + +/** + * @brief Image delete status. + * @retval None + */ +static void ImageDeleteStatusShow(const Frame *frame, IMAGE_DELETE_STATUS status) +{ + Language lang; + /* all image delete status */ + char *msg[IMAGE_DELETE_STATUS_NUM][LANGUAGE_NUM] = { + MULTI_LANGUAGE(DELETEING), + MULTI_LANGUAGE(DELETE_SUCCESS), + MULTI_LANGUAGE(DELETE_FAIL), + MULTI_LANGUAGE(WELCOME), + }; + if (status >= IMAGE_DELETE_STATUS_NUM) { + return; + } + lang = GetWinLanguage(); + FramePopMsg(frame, msg[status][lang]); +} + +/** + * @brief Algo delete status. + * @retval None + */ +static void AlgoDeleteStatusShow(const Frame *frame, ALGORITHM_DELETE_STATUS status) +{ + Language lang; + char *msg[ALGORITHM_DELETE_STATUS_NUM][LANGUAGE_NUM] = { + MULTI_LANGUAGE(DELETEING), + MULTI_LANGUAGE(DELETE_SUCCESS), + MULTI_LANGUAGE(DELETE_FAIL), + MULTI_LANGUAGE(WELCOME), + }; + if (status >= ALGORITHM_DELETE_STATUS_NUM) { + return; + } + lang = GetWinLanguage(); + FramePopMsg(frame, msg[status][lang]); +} + +/** + * @brief Image selected process + * @retval None + */ +static void ImageSelectedProc(Frame *frame) +{ + TargetLibImageSelect(frame->pointer - frame->staticItemNum); + OfflineDownLoadStart(); +} + +/** + * @brief Image delete process + * @retval None + */ +static void ImageDeleteProc(Frame *frame) +{ + unsigned int imageIdx = frame->userData; + TargetLibImageDelete(imageIdx); +} + +/** + * @brief Image dummy process, do nothing + * @retval None + */ +static void FactoryImageListDummyProc(Frame *frame) +{ + frame = frame; +} + +/** + * @brief Factory Image delete process + * @retval None + */ +static void FactoryImageDeleteProc(Frame *frame) +{ + unsigned int imageIdx = frame->userData; + FactoryImageFree(imageIdx); +} + +/** + * @brief Factory Algo selected process + * @retval None + */ +static void AlgoSelectedProc(Frame *frame) +{ + unsigned int algoId = frame->userData; + TargetAlgoConfig(algoId); + FrameShow(frame); +} + +/** + * @brief Algo selected process + * @retval None + */ +static void AlgoDeleteProc(Frame *frame) +{ + unsigned int algoId = frame->userData; + TargetLibAlgoDelete(algoId); +} + +/** + * @brief Check has valid image + * @retval true or fail + */ +static bool HasValidImage(int imageCnt) +{ + return ((imageCnt > 0) && (imageCnt <= TARGET_LIB_FACTORY_IMAGE_MAX_NUM)); +} + +/** + * @brief Check has valid algo + * @retval true or fail + */ +static bool HasValidAlgo(int algoCnt) +{ + return ((algoCnt > 0) && (algoCnt <= TARGET_LIB_FACTORY_ALGO_MAX_NUM)); +} + +/** + * @brief Stores image upgrade failure information. This information + * is required by the function that periodically displays messages. + * @retval true or fail + */ +static void SetImageUpgradeFailMsg(const char *msg) +{ + errno_t ret = EOK; + /* Recording error information. */ + ret = strncpy_s(g_imageUpgradeFailMsg, IMAGE_UPGRADE_FAIL_MSG_MAX_LEN, msg, sizeof(g_imageUpgradeFailMsg)); + if (ret != EOK) { + return; + } + g_imageUpgradeFailMsg[IMAGE_UPGRADE_FAIL_MSG_MAX_LEN] = 0; +} + +/** + * @brief Get stores image upgrade failure information. + * @retval true or fail + */ +static char *GetImageUpgradeFailMsg(void) +{ + return g_imageUpgradeFailMsg; /* String of fail message */ +} diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/status.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/status.c new file mode 100644 index 0000000000000000000000000000000000000000..c70f112ab1e03a64bea4081a249f93d91915846c --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/display/src/status.c @@ -0,0 +1,157 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file status.c + * @author MCU Driver Team + * @brief status process + */ + +#include +#include "display_common.h" +#include "swd_jtag_config.h" +#include "display.h" +#include "menu_tbl.h" +#include "status.h" + +DapLinkStatus g_dapLinkStatus = { + .connectInfo = {.status = TARGET_DISCONNECT, .type = TARGET_CONNECT_SWD, .rate = 0}, + .imageStoreStatus = IMAGE_STORE_IDLE, + .imageUpgradeStatus = IMAGE_UPGRADE_IDLE, + .algoStoreStatus = ALGORITHM_STORE_IDLE, + .fwUpgradeStatus = FIMRWARE_UPGRADE_SUCCESS, + .imageDeleteStatus = IMAGE_DELETE_IDLE, + .algoDeleteStatus = ALGORITHM_DELETE_IDLE, + .statusChangeMask = STATUS_CHANGE_MASK_CONNECT_STATUS, + .dapDbgInfo = {.status = DAP_STATUS_NOTWORKING, .totalSampleCount = 0, + .totalOverflowCount = 0, .totalErrorCount = 0, .errorRate = 0}, +}; + +/** + * @brief Check Whether the Connect Information changes + * @retval None + */ +static bool IsConnectInfoChanged(TargetConnectInfo *info) +{ + return (info->status != g_dapLinkStatus.connectInfo.status) || + (info->type != g_dapLinkStatus.connectInfo.type) || + (info->rate != g_dapLinkStatus.connectInfo.rate); +} + +/** + * @brief Check Whether the Debug Information changes + * @retval None + */ +static bool IsDapDbgInfoChanged(DapDebugInfo *info) +{ + /* status or statistics changed */ + return (info->status != g_dapLinkStatus.dapDbgInfo.status) || + (info->totalSampleCount != g_dapLinkStatus.dapDbgInfo.totalSampleCount) || + (info->totalOverflowCount != g_dapLinkStatus.dapDbgInfo.totalOverflowCount) || + (info->totalErrorCount != g_dapLinkStatus.dapDbgInfo.totalErrorCount) || + (info->errorRate != g_dapLinkStatus.dapDbgInfo.errorRate); +} + +/** + * @brief Get Daplink status + * @retval None + */ +void DapLinkStatusGet(DapLinkStatus *status) +{ + *status = g_dapLinkStatus; +} + +/** + * @brief Get Daplink status changed mask + * @retval changed mask + */ +static unsigned int DaplinkGetImageAlgoStatusMask(DapLinkStatus *status) +{ + unsigned int mask; + uint32_t rate = SwdJtagClockGet(); /* Get Connect rate */ + if (status->imageStoreStatus != g_dapLinkStatus.imageStoreStatus) { + mask = STATUS_CHANGE_MASK_IMAGE_STORE_STATUS; + } else if ((status->imageUpgradeStatus != g_dapLinkStatus.imageUpgradeStatus) || + (status->upgradeRate != 0 && status->upgradeRate != rate)) { + mask = STATUS_CHANGE_MASK_IMAGE_UPGRADE_STATUS; /* image upgrade status changed */ + status->upgradeRate = rate; + } else if (status->algoStoreStatus != g_dapLinkStatus.algoStoreStatus) { + mask = STATUS_CHANGE_MASK_ALGO_STORE_STATUS; /* algo upgrade status changed */ + } else if (status->fwUpgradeStatus != g_dapLinkStatus.fwUpgradeStatus) { + mask = STATUS_CHANGE_MASK_FW_UPGRADE_STATUS; /* fireware upgrade status changed */ + } else if (status->imageDeleteStatus != g_dapLinkStatus.imageDeleteStatus) { + mask = STATUS_CHANGE_MASK_IMAGE_DELETE_STATUS; /* delete image status changed */ + } else if (status->algoDeleteStatus != g_dapLinkStatus.algoDeleteStatus) { + mask = STATUS_CHANGE_MASK_ALGO_DELETE_STATUS; /* delete algo status changed */ + } else { + mask = 0; + } + return mask; +} + +/** + * @brief Get Daplink status changed mask + * @retval changed mask + */ +static unsigned int DaplinkGetStatusMask(DapLinkStatus *status) +{ + unsigned int mask = 0; + + if (IsConnectInfoChanged(&status->connectInfo)) { + mask = STATUS_CHANGE_MASK_CONNECT_STATUS; /* connect info changed */ + } else if (IsDapDbgInfoChanged(&status->dapDbgInfo)) { + mask = STATUS_CHANGE_MASK_DAP_SAMPLING_STATUS; + } else { + mask = DaplinkGetImageAlgoStatusMask(status); + } + return mask; +} + +/** + * @brief Set Daplink status + * @retval None + */ +void DapLinkStatusSet(DapLinkStatus *status) +{ + unsigned int mask; + if (status == NULL) { + return; + } + mask = DaplinkGetStatusMask(status); /* Get Status changed mask */ + if (mask != 0) { + g_dapLinkStatus = *status; /* update status and changed mask */ + g_dapLinkStatus.statusChangeMask = mask; + if ((mask == STATUS_CHANGE_MASK_IMAGE_STORE_STATUS) || + (mask == STATUS_CHANGE_MASK_ALGO_STORE_STATUS)) { + if (IsDbgStatusFrame() == false) { + return; + } + } + /* call daplink hook process */ + if (g_dapLinkStatus.cbFunc != NULL) { + g_dapLinkStatus.cbFunc(); + } + } +} + +/** + * @brief Register Daplink hook process + * @retval None + */ +void RegisterDaplinkStatusCallBackFunc(StatusChangeCallback func) +{ + g_dapLinkStatus.cbFunc = func; +} diff --git a/src/middleware/hisilicon/nostask/kernel/nos_task_priority.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/key/key.c similarity index 39% rename from src/middleware/hisilicon/nostask/kernel/nos_task_priority.c rename to src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/key/key.c index a5a6990582f186256e785329f12292b1e45bce9a..1540039936f252ec0fd9929a7717818617328542 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_task_priority.c +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/key/key.c @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,112 +15,96 @@ * 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. - * @file nos_task_priority.c + * @file key.c + * @author MCU Driver Team + * @brief key press process */ -#include "nos_task_internal.h" -#include "nos_task_external.h" +#include +#include "stm32mp1xx.h" +#include "stm32mp1xx_hal.h" +#include "key.h" -/* - * 描述: 获取指定任务的优先级 +/** + * @brief Key Init + * @param No + * @retval No */ -unsigned int NOS_TaskPriorityGetInner(unsigned int taskPid, unsigned short *taskPrio) +void KeyInit(void) { - uintptr_t intSave; - struct TagTskCB *taskCB = NULL; - - if (CheckTaskPidOverflow(taskPid)) { - return OS_ERRNO_TSK_ID_INVALID; - } - - if (taskPrio == NULL) { - return OS_ERRNO_TSK_PTR_NULL; - } - - /* get task Tcb */ - taskCB = GetTcbHandle(taskPid); - - intSave = NOS_IntLock(); - - /* 判断任务是否存在 */ - if (TSK_IsUnused(taskCB)) { - NOS_IntRestore(intSave); - - return OS_ERRNO_TSK_NOT_CREATED; - } - - *taskPrio = taskCB->priority; - - NOS_IntRestore(intSave); - - return NOS_OK; + GPIO_InitTypeDef gpio_init_struct; + /* Key gpio clock enable */ + KeyUpGpioClkEnable(); + KeyDownGpioClkEnable(); + KeyConfirmGpioClkEnable(); + + /* GPIO config */ + gpio_init_struct.Pin = KEY_UP_GPIO_PIN; + gpio_init_struct.Mode = GPIO_MODE_INPUT; + gpio_init_struct.Pull = GPIO_PULLDOWN; + gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(KEY_UP_GPIO_PORT, &gpio_init_struct); + + gpio_init_struct.Pin = KEY_DOWN_GPIO_PIN; + HAL_GPIO_Init(KEY_DOWN_GPIO_PORT, &gpio_init_struct); + + gpio_init_struct.Pin = KEY_CONFIRM_GPIO_PIN; + HAL_GPIO_Init(KEY_CONFIRM_GPIO_PORT, &gpio_init_struct); } -/* - * 描述: 设置优先级前做参数检查 +/** + * @brief Is Key press enough time to press the keys + * @param mode:0: short key, 1: long key + * @param keyCnt: Statistics on consecutive key presses + * @retval true or false */ -INLINE unsigned int OsTaskPrioritySetCheck(unsigned int taskPid, unsigned short taskPrio) +static unsigned int IsKey(uint8_t mode, unsigned int keyCnt) { - /* 检查优先级是否合法 */ - if (taskPrio > OS_TSK_PRIORITY_LOWEST) { - return OS_ERRNO_TSK_PRIOR_ERROR; +#define KEY_VALID_TIMES 2 + if (mode == LONG_KEY) { + return (keyCnt >= KEY_VALID_TIMES); } - - if (CheckTaskPidOverflow(taskPid)) { - return OS_ERRNO_TSK_ID_INVALID; - } - - if (taskPid == IDLE_TASK_ID) { - return OS_ERRNO_TSK_OPERATE_IDLE; - } - return NOS_OK; + return (keyCnt == KEY_VALID_TIMES); } -/* - * 描述: 设置指定任务的优先级 +/** + * @brief Key scan press process + * @param mode: + * @retval KeyValue */ -unsigned int NOS_TaskPrioritySetInner(unsigned int taskPid, unsigned short taskPrio) +uint8_t KeyScan(uint8_t mode) { - unsigned int ret; - bool isReady = FALSE; - uintptr_t intSave; - struct TagTskCB *taskCB = NULL; - - ret = OsTaskPrioritySetCheck(taskPid, taskPrio); - if (ret != NOS_OK) { - return ret; - } - - /* get task Tcb */ - taskCB = GetTcbHandle(taskPid); - intSave = NOS_TaskIntLock(); - OsSpinLockTaskRq(taskCB); - /* 判断任务是否存在 */ - if (TSK_IsUnused(taskCB)) { - OsSpinUnlockTaskRq(taskCB); - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_NOT_CREATED; + static unsigned int key0Cnt = 0; + static unsigned int key1Cnt = 0; + static unsigned int key2Cnt = 0; + uint8_t keyval = 0; + + if (KEY2 == 0) { /* Confirm Key Pressed */ + key2Cnt++; + key0Cnt = 0; + key1Cnt = 0; + } else if (KEY1 == 0) { /* MoveDown Key Pressed */ + key1Cnt++; + key0Cnt = 0; + key2Cnt = 0; + } else if (KEY0 == 0) { /* MoveUp Key Pressed */ + key0Cnt++; + key1Cnt = 0; + key2Cnt = 0; + } else { /* No Key Pressed, Clear KeyPress Count */ + key0Cnt = 0; + key1Cnt = 0; + key2Cnt = 0; } - - /* 获取任务状态 */ - isReady = (OS_TSK_READY & taskCB->taskStatus); - - /* delete the task & insert with right priority into ready queue */ - if (isReady) { - OsTskReadyDel(taskCB); - taskCB->priority = taskPrio; - OsTskReadyAdd(taskCB); + /* If Key Pressed, set key value */ + if (IsKey(mode, key2Cnt)) { + keyval = KEY_CONFIRM; + } else if (IsKey(mode, key1Cnt)) { + keyval = KEY_DOWN; + } else if (IsKey(mode, key0Cnt)) { + keyval = KEY_UP; } else { - taskCB->priority = taskPrio; + keyval = 0; /* Invalid value */ } - - taskCB->origPriority = taskPrio; - OsSpinUnlockTaskRq(taskCB); - - /* reschedule if ready changed */ - if (isReady) { - OsTskSchedule(); - } - - NOS_TaskIntRestore(intSave); - return NOS_OK; + /* return key press value */ + return keyval; } diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/key/key.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/key/key.h new file mode 100644 index 0000000000000000000000000000000000000000..4b625ce6bcb9ef1a84c68693986c5f7c0e45feab --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/key/key.h @@ -0,0 +1,67 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file key.h + * @author MCU Driver Team + * @brief key press process + */ +#ifndef KEY_H +#define KEY_H + +#include +#include "stm32mp1xx.h" + +/******************************************************************************************/ + +#define KEY_UP_GPIO_PORT GPIOA +#define KEY_UP_GPIO_PIN GPIO_PIN_10 +static inline void KeyUpGpioClkEnable(void) +{ + __HAL_RCC_GPIOB_CLK_ENABLE(); +} + +#define KEY_DOWN_GPIO_PORT GPIOC +#define KEY_DOWN_GPIO_PIN GPIO_PIN_8 +static inline void KeyDownGpioClkEnable(void) +{ + __HAL_RCC_GPIOC_CLK_ENABLE(); +} + +#define KEY_CONFIRM_GPIO_PORT GPIOC +#define KEY_CONFIRM_GPIO_PIN GPIO_PIN_9 +static inline void KeyConfirmGpioClkEnable(void) +{ + __HAL_RCC_GPIOC_CLK_ENABLE(); +} + +/******************************************************************************************/ + +#define KEY0 HAL_GPIO_ReadPin(KEY_UP_GPIO_PORT, KEY_UP_GPIO_PIN) +#define KEY1 HAL_GPIO_ReadPin(KEY_DOWN_GPIO_PORT, KEY_DOWN_GPIO_PIN) +#define KEY2 HAL_GPIO_ReadPin(KEY_CONFIRM_GPIO_PORT, KEY_CONFIRM_GPIO_PIN) + +#define KEY_DOWN 1 +#define KEY_UP 2 +#define KEY_CONFIRM 3 + +#define SHORT_KEY 0 +#define LONG_KEY 1 + +void KeyInit(void); +uint8_t KeyScan(uint8_t mode); + +#endif diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/oled/oled.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/oled/oled.c new file mode 100644 index 0000000000000000000000000000000000000000..70a526847cdb503849d9a4a7d7f21773e2790a8a --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/oled/oled.c @@ -0,0 +1,820 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file oled.c + * @author MCU Driver Team + * @brief oled process Header + */ + +#include +#include +#include "stm32mp1xx.h" +#include "stm32mp1xx_hal.h" +#include "key.h" +#include "oled.h" + +#define LCD_WIDTH 192 +#define Y_PAGE_BASE 5 /* Page起始值 */ +#define LCD_MAX_PAGE 17 +#define LCD_PIXEL_PER_PAGE 8 /* 每个page占用的pixel点数 */ +#define PIXEL_32 32 /* 占用pixel个数为32 */ +#define PIXEL_16 16 /* 占用pixel个数为16 */ +#define PIXEL_8 8 /* 占用pixel个数为8 */ + +#define BITS_IN_BYTE 8 + +#define CHARS_OF_CHINESE_WORD 2 /* 每中文字符占两个英文字符 */ +#define CHARS_OF_AISCII 1 /* 每ASICII字符占1个英文字符 */ + +typedef struct { + uint8_t width; + uint8_t height; +} FontSize; + +static bool g_reverseDisplay = false; /* global reserved display enable or not */ + +static uint8_t GetDataFromRom(void); +static void SendCommandToRom(uint8_t data); +static void TransferCommandLcd(uint8_t cmd); +static void TransferDataLcd(uint32_t dataValue, bool reversedDisplay); +static void TransferData(uint32_t data); + +/** + * @brief get pages number base on row number + * @param row: row number + * @retval page number + */ +static inline uint8_t PageOf(uint8_t row) +{ + return row / LCD_PIXEL_PER_PAGE; +} + +/** + * @brief get row number base on page + * @param page: page number + * @retval row number + */ +static inline uint8_t RowOf(uint8_t page) +{ + return (uint8_t)(page * LCD_PIXEL_PER_PAGE); +} + +/** + * @brief Set global display mode + * @param mode: @see DisplayMode + * @retval None + */ +void SetGlobalDisaplyaMode(DisplayMode mode) +{ + g_reverseDisplay = (mode == DISPLAY_REVERSE) ? true : false; +} + +/** + * @brief Check the two char is GB2312 + * @param a: the first char + * @param b: the seconde char + * @retval bool: check result + */ +static inline bool IsWordOfGB2312(char a, char b) +{ + return (a >= 0xb0) && (a <= 0xf7) && (b >= 0xa1); +} + +/** + * @brief Check the two char is GB2312 + * @param a: the first char + * @param b: the seconde char + * @retval bool: check result + */ +static inline bool IsCharOfGB2312(char a, char b) +{ + return (a >= 0xa1) && (a <= 0xa3) && (b >= 0xa1); +} + +/** + * @brief Check the char is ASIIC + * @param c: the char + * @retval bool: check result + */ +static inline bool IsASCII(char c) +{ + return (c >= 0x20) && (c <= 0x7e); +} + +/** + * @brief Check the char is ASIIC + * @param c: the char + * @retval bool: check result + */ +static inline uint32_t GetGB2312Pixel16X16FontAddr(char a, char b) +{ + // 国标简体(GB2312)汉字在晶联讯字库IC中的地址由以下公式来计算: + // Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32+ BaseAdd;BaseAdd=0x2c9d0 + uint32_t fontAddr = ((unsigned char)a - 0xb0) * 0x5e; + fontAddr += ((unsigned char)b - 0xa1) + 0x34e; + fontAddr *= 0x20; + fontAddr += 0x2c9d0; + return fontAddr; +} + +/** + * @brief Check word address of 15x16 character of GB2312 + * @param a: the first char + * @param b: the seconde char + * @retval the word address + */ +static inline uint32_t GetGB2312Pixel15X16FontAddr(char a, char b) +{ + // 国标简体(GB2312)15x16点的字符在晶联讯字库IC中的地址由以下公式来计算: + // Address = ((MSB - 0xa1) * 94 + (LSB - 0xA1))*32+ BaseAdd;BaseAdd=0x2c9d0 + uint32_t fontAddr = ((unsigned char)a - 0xa1) * 0x5e; + fontAddr += ((unsigned char)b - 0xa1); + fontAddr *= 0x20; + fontAddr += 0x2c9d0; + return fontAddr; +} + +/** + * @brief Check word address of 8x16 character of ASIIC + * @param c: the first char + * @retval the word address + */ +static inline uint32_t GetAISCIIPixel8X16FontAddr(char c) +{ + // AISCII 8x16点的字符在晶联讯字库IC中的地址由以下公式来计算: + // Address = ((MSB - 0xa1) * 94 + (LSB - 0xA1))*32+ BaseAdd;BaseAdd=0x1DD780 + uint32_t fontAddr = ((unsigned char)c - 0x20); + fontAddr *= 0x10; + fontAddr += 0x1DD780; + return fontAddr; +} + +/** + * @brief Check word address of 32x32 character of GB2312 + * @param a: the first char + * @param b: the seconde char + * @retval the word address + */ +static inline uint32_t GetGB2312Pixel32X32FontAddr(char a, char b) +{ + // 国标简体(GB2312)汉字在晶联讯字库IC中的地址由以下公式来计算: + // Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*128+ BaseAdd;BaseAdd=0xedf00 + uint32_t fontAddr = ((unsigned char)a - 0xb0) * 0x5e; + fontAddr += ((unsigned char)b - 0xa1) + 0x34e; + fontAddr *= 0x80; + fontAddr += 0xedf00; + return fontAddr; +} + +/** + * @brief Check word address of 31x32 character of GB2312 + * @param a: the first char + * @param b: the seconde char + * @retval the word address + */ +static inline uint32_t GetGB2312Pixel31X32FontAddr(char a, char b) +{ + // 国标简体(GB2312)汉字在晶联讯字库IC中的地址由以下公式来计算: + // Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1))*128+ BaseAdd;BaseAdd=0xedf00 + uint32_t fontAddr = ((unsigned char)a - 0xb0) * 0x5e; + fontAddr += ((unsigned char)b - 0xa1); + fontAddr *= 0x80; + fontAddr += 0xedf00; + return fontAddr; +} + +/** + * @brief Check word address of 16x32 character of ASIIC + * @param a: the first char + * @retval the word address + */ +static inline uint32_t GetPixel16X32FontAddr(char a) +{ + // 英文字符在晶联讯字库IC中的地址由以下公式来计算: + // Address = ((MSB - 0x20) * 64 + BaseAdd;BaseAdd=0x1e5a50 + // 由于担心8位单片机有乘法溢出问题,所以分三部取地址 + uint32_t fontAddr = ((unsigned char)a - 0x20); + fontAddr *= 0x40; + fontAddr += 0x1e5a50; + return fontAddr; +} + +/** + * @brief Check whether line breaks are required. + */ +static inline void ProcWrap(uint8_t beginPage, uint8_t beginColumn, + uint8_t pageHeight, uint8_t *page, uint8_t pageTh) +{ + if (beginPage <= pageTh && beginColumn <= LCD_WIDTH) { + *page += pageHeight; + } +} + +/** + * @brief Change Phyiscal page to logic page + */ +static uint8_t PhyPageToLogicPage(uint8_t page) +{ + uint8_t pageHeight = PageOf(PIXEL_16); + if (pageHeight == 0) { + return 0; /* can't be here */ + } + return (uint8_t)((page - Y_PAGE_BASE) / pageHeight); +} + +/** + * @brief Change logic page to Phyiscal page + */ +static uint8_t LogicPageToPhyPage(uint8_t pageValue) +{ + uint32_t pageHeight = PageOf(PIXEL_16); + uint32_t page = pageValue * pageHeight + Y_PAGE_BASE; + if (page > LCD_MAX_PAGE) { + page = 0; /* Protection, shouldn't be here */ + } + return page & 0xFF; +} + +/** + * @brief 从指定Pixel清除该行 + * @param X: 为起始的列地址 + * @param Y: 为起始的行地址 + * @param xTotal: 列地址起点到终点的差值 + * @param yTotal: 行地址的起点到终点的差值 + * @retval 无 + */ +static void LcdAddress(uint32_t x, uint32_t y, uint32_t xTotal, uint32_t yTotal) +{ + uint32_t newY = (y > 0) ? (y - 1) : 0; + + TransferCommandLcd(0x15); // Set Column Address + TransferData(x); + TransferData(x + xTotal - 1); + + TransferCommandLcd(0x75); // Set Page Address + TransferData(newY); + TransferData(newY + yTotal - 1); + TransferCommandLcd(0x30); + TransferCommandLcd(0x5c); +} + +/* + * OLED的显存 + * 每个字节表示8个像素, 128,表示有128列, 8表示有64行, 高位表示第行数. + * 比如:g_oled_gram[0][0],包含了第一列,第1~8行的数据. g_oled_gram[0][0].7,即表示坐标(0,0) + * 类似的: g_oled_gram[1][0].6,表示坐标(1,1), g_oled_gram[10][1].5,表示坐标(10,10), + * + * 存放格式如下(高位表示低行数). + * [0]0 1 2 3 ... 127 + * [1]0 1 2 3 ... 127 + * [2]0 1 2 3 ... 127 + * [3]0 1 2 3 ... 127 + * [4]0 1 2 3 ... 127 + * [5]0 1 2 3 ... 127 + * [6]0 1 2 3 ... 127 + * [7]0 1 2 3 ... 127 + */ +static void GetAndWriteCommon(uint32_t fontaddr, uint8_t column, uint8_t page, + uint8_t type, FontSize *fontSize) +{ + uint8_t i; + uint8_t j; + uint8_t dispData; + + OledRomCsSet(0); + SendCommandToRom(0x03); + SendCommandToRom(((fontaddr & 0xff0000) >> 16) & 0xFF); // Get address[23:16] + SendCommandToRom(((fontaddr & 0xff00) >> 8) & 0xFF); // Get address[15:8] + SendCommandToRom(fontaddr & 0xFF); // Get address[7:0] + uint8_t pageNum = PageOf(fontSize->height); + LcdAddress(column, page, fontSize->width, pageNum); + for (i = 0; i < pageNum; i++) { + for (j = 0; j < fontSize->width; j++) { + dispData = GetDataFromRom(); + TransferDataLcd(dispData, type); // 写数据到LCD,每写完1字节的数据后列地址自动加1 + } + } + OledRomCsSet(1); +} + +/** + * @brief Write 32 x 32 character of GB2312 + */ +static void GetAndWrite32x32(uint32_t fontaddr, uint8_t column, uint8_t page, uint8_t type) +{ + FontSize fontSize = {PIXEL_32, PIXEL_32}; + GetAndWriteCommon(fontaddr, column, page, type, &fontSize); +} + +/** + * @brief Write 16 x 32 character of ASIIC + */ +static void GetAndWrite16x32(uint32_t fontaddr, uint8_t column, uint8_t page, uint8_t type) +{ + FontSize fontSize = {PIXEL_16, PIXEL_32}; + GetAndWriteCommon(fontaddr, column, page, type, &fontSize); +} + +/** + * @brief Write 16 x 16 character of GB2312 + */ +static void GetAndWrite16x16(uint32_t fontaddr, uint8_t column, uint8_t page, uint8_t type) +{ + FontSize fontSize = {PIXEL_16, PIXEL_16}; + GetAndWriteCommon(fontaddr, column, page, type, &fontSize); +} + +/** + * @brief Write 8 x 16 character of ASIIC + */ +static void GetAndWrite8x16(uint32_t fontaddr, uint8_t column, uint8_t page, uint8_t type) +{ + FontSize fontSize = {PIXEL_8, PIXEL_16}; + GetAndWriteCommon(fontaddr, column, page, type, &fontSize); +} + +/** + * @brief 向OLED写入一个字节 + * @param data: 要输出的数据 + * @param cmd: 命令标志 0,表示命令;1,表示数据; + * @retval 无 + */ +static void TransferCommon(uint8_t data) +{ + uint8_t i; + uint8_t val = data; + OledCsSet(0); /* 片选引脚拉低,选中SSD1306 */ + for (i = 0; i < BITS_IN_BYTE; i++) { + OledSclkSet(0); + if ((val & 0x80) != 0) { /* 高位在前 */ + OledSdinSet(1); /* 写1 */ + } else { + OledSdinSet(0); /* 写0 */ + } + OledSclkSet(1); + val <<= 1; + } +} + +// =============transfer command to LCM=============== +static void TransferCommandLcd(uint8_t cmd) +{ + OledRsSet(0); /* cmd为0,表示命令;cmd为1,表示数据 */ + TransferCommon(cmd); +} + +/** + * @brief 向OLED写数据 + * @param data: 要输出的数据 + * @retval 无 + */ +static void TransferData(uint32_t data) +{ + OledRsSet(1); /* cmd为0,表示命令;cmd为1,表示数据 */ + TransferCommon(data & 0xFF); +} + +/** + * @brief 向LCD写数据 + * @param data: 要输出的数据 + * @param reversedDisplay: 是否需要反显 + * @retval 无 + */ +static void TransferDataLcd(uint32_t dataValue, bool reversedDisplay) +{ + uint8_t i; + uint8_t type = (g_reverseDisplay == true) ? !reversedDisplay : reversedDisplay; + uint32_t data = dataValue; + OledRsSet(1); /* cmd为0,表示命令;cmd为1,表示数据 */ + OledCsSet(0); /* 片选引脚拉低,选中SSD1306 */ + + for (i = 0; i < BITS_IN_BYTE; i++) { + OledSclkSet(0); + if (type != 0) { + if ((data & 0x80) != 0) { /* 高位在前 */ + OledSdinSet(1); /* 写1 */ + } else { + OledSdinSet(0); /* 写0 */ + } + } else { + if ((data & 0x80) != 0) { /* 高位在前 */ + OledSdinSet(0); /* 写1 */ + } else { + OledSdinSet(1); /* 写0 */ + } + } + OledSclkSet(1); + data <<= 1; /* 左移 */ + } + OledCsSet(1); /* 关闭片选 */ + OledRsSet(1); /* DC电平恢复至初始态 */ +} + +static uint8_t OledShowStringBold(uint8_t column, uint8_t pageNum, const char *text, uint8_t size, uint8_t type) +{ + uint32_t fontaddr = 0; + uint8_t i = 0; + uint8_t pageHeight = size / LCD_PIXEL_PER_PAGE; + uint8_t page = pageNum; + uint8_t showLines = 1; + uint8_t col = column; + + page = (uint8_t)(page * pageHeight + Y_PAGE_BASE); + if (page > LCD_MAX_PAGE) { + return showLines; /* Protection, shouldn't be here */ + } + + while ((text[i] > 0x00)) { + if (IsWordOfGB2312(text[i], text[i + 1])) { /* Chinese characters (GB2312) */ + fontaddr = GetGB2312Pixel32X32FontAddr(text[i], text[i + 1]); + GetAndWrite32x32(fontaddr, col, page, type); + i += CHARS_OF_CHINESE_WORD; + col += PIXEL_32; + } else if (IsCharOfGB2312(text[i], text[i + 1])) { /* Chinese punctuation marks (GB2312) */ + GetGB2312Pixel31X32FontAddr(text[i], text[i + 1]); + GetAndWrite32x32(fontaddr, col, page, type); + i += CHARS_OF_CHINESE_WORD; + col += PIXEL_32; + } else if ((text[i] >= 0x20) && (text[i] <= 0x7e)) { /* English */ + fontaddr = GetPixel16X32FontAddr(text[i]); + GetAndWrite16x32(fontaddr, col, page, type); + i += 1; + col += PIXEL_16; + } else { /* Unsupported characters, skip it */ + i++; + } + } + return showLines; /* Large font, which can be used to display only one line. */ +} + +/** + * @brief 换行 + * @retval 无 + */ +static void OledLineWrap(uint8_t *col, uint8_t *page, uint8_t *line, uint8_t pageHeight) +{ + if (*col >= LCD_WIDTH) { + /* If the number of characters in a line exceeds the maximum, switch to a new page. */ + *page += pageHeight; + *col = 0; + (*line)++; + } +} + +/** + * @brief Obtains the address of the GB2312 character. + * @retval font address + */ +static uint32_t GetGB2312FontAddr(int8_t a, int8_t b) +{ + uint32_t fontaddr = 0; + if (IsWordOfGB2312(a, b) || IsCharOfGB2312(a, b)) { + /* Obtain the address based on the Chinese and Chinese punctuation marks. */ + if (IsCharOfGB2312(a, b)) { + fontaddr = GetGB2312Pixel15X16FontAddr(a, b); + } else { + fontaddr = GetGB2312Pixel16X16FontAddr(a, b); + } + } + return fontaddr; +} + +/** + * @brief Display a string of chinese(GB2312) or english in oled + * @retval Number of lines occupied by a character string + */ +uint8_t OledShowString(uint8_t startColumn, uint8_t startPage, const char *text, uint8_t size, uint8_t type) +{ + if (size == PIXEL_32) { + return OledShowStringBold(startColumn, startPage, text, size, type); + } + + uint8_t pageHeight = size / LCD_PIXEL_PER_PAGE; + uint8_t pageCharNum = LCD_WIDTH / PIXEL_8; + uint8_t charIdx = 0; + uint8_t showLines = 1; + uint8_t col = startColumn; + uint8_t page = startPage * pageHeight + Y_PAGE_BASE; /* logic page to phy page */ + + if (page > LCD_MAX_PAGE) { + return showLines; /* don't show, return */ + } + + for (uint8_t i = 0; text[i] > 0x00;) { + uint32_t fontaddr = 0; + OledLineWrap(&col, &page, &showLines, pageHeight); + + /* Get Char begin index */ + charIdx = ((col + LCD_PIXEL_PER_PAGE - 1) / LCD_PIXEL_PER_PAGE); + fontaddr = GetGB2312FontAddr(text[i], text[i + 1]); + if (fontaddr != 0) { + if ((col + PIXEL_16) > LCD_WIDTH) { /* The width is insufficient for display. Line feeds. */ + OledClearLine(PhyPageToLogicPage(page), charIdx, pageCharNum); + ProcWrap(startPage, startColumn, pageHeight, &page, LCD_MAX_PAGE - PageOf(PIXEL_16)); + col = 0; + showLines++; + } + /* Read the data from the specified address and write it to the specified (page, column) + coordinates of the LCD. */ + GetAndWrite16x16(fontaddr, col, page, type); + i += CHARS_OF_CHINESE_WORD; + col += PIXEL_16; + } else if (IsASCII(text[i])) { + fontaddr = GetAISCIIPixel8X16FontAddr(text[i]); + if ((col + PIXEL_8) > LCD_WIDTH) { /* The width is not enough for display. */ + OledClearLine(PhyPageToLogicPage(page), charIdx, pageCharNum); + ProcWrap(startPage, startColumn, pageHeight, &page, LCD_MAX_PAGE - PageOf(PIXEL_8)); + col = 0; + showLines++; + } + GetAndWrite8x16(fontaddr, col, page, type); + i += CHARS_OF_AISCII; + col += PIXEL_8; + } else { + i++; /* Skip unsupported characters */ + } + } + /* set char index(idle) and clear from the char index */ + charIdx = ((col + LCD_PIXEL_PER_PAGE - 1) / LCD_PIXEL_PER_PAGE); + OledClearLine(PhyPageToLogicPage(page), charIdx, pageCharNum); + return showLines; +} + +/* ***Send instructions to Jinglianxun font library IC** */ +static void SendCommandToRom(uint8_t data) +{ + uint8_t i; + uint8_t d = data; + for (i = 0; i < BITS_IN_BYTE; i++) { + if ((d & 0x80) != 0) { + OledRomInSet(1); + } else { + OledRomInSet(0); + } + d = d << 1; + OledRomSckSet(0); + OledRomSckSet(1); + } +} + +/* ***Obtain Chinese characters or character data (1 byte) from Jinglianxun font library IC.** */ +static uint8_t GetDataFromRom(void) +{ + uint8_t i; + uint8_t retData = 0; + OledRomSckSet(1); + for (i = 0; i < BITS_IN_BYTE; i++) { + OledRomOutSet(1); + OledRomSckSet(0); + retData >>= 1; + + if (OledReadRomOut() != 0) { + retData += 0x80; + } + OledRomSckSet(1); + } + return (retData); +} + +// ------------------------------------------------------------------------------ +/** + * @brief Clear screen function, clear screen, the whole screen is black! It's like it's not lit.!!! + * @param None + * @retval None + */ +void OledClear(void) +{ + OledClearFromStartYPixel(0); +} + +/** + * @brief Clears the row from the specified Pixel + * @param startYPixel the specified Pixel + * @retval 无 + */ +void OledClearFromStartYPixel(uint32_t startYPixel) +{ + int i; + int j; + LcdAddress(0, startYPixel, LCD_WIDTH, LCD_MAX_PAGE); + for (i = 0; i < LCD_MAX_PAGE; i++) { + for (j = 0; j < LCD_WIDTH; j++) { + TransferDataLcd(0x00, 1); + } + } +} + +/** + * @brief clear 8*16 points + * @param column: colum + * @param page: page number + * @param xTotal: The difference between the start point and end point of the column address + * @retval None + */ +static void Clear8x16(uint8_t column, uint8_t page, bool reverseDisplay) +{ + OledRomCsSet(0); + LcdAddress(column, page, PIXEL_8, PageOf(PIXEL_16)); + for (uint8_t i = 0; i < PageOf(PIXEL_16); i++) { + for (uint8_t j = 0; j < PIXEL_8; j++) { + /* When data is written to the LCD, the column address is automatically increased + by 1 after one byte of data is written. */ + TransferDataLcd(0, reverseDisplay ? 0 : 1); + } + } + OledRomCsSet(1); +} + +/** + * @brief Clear Lines + */ +void OledClearLine(uint8_t page, uint8_t begin, uint8_t end) +{ + uint8_t beginRow = RowOf(begin); + uint8_t endRow = RowOf(end); + uint8_t phyPage = LogicPageToPhyPage(page); + for (uint8_t i = beginRow; i < endRow; i += PIXEL_8) { + Clear8x16(i, phyPage, false); + } +} + +/** + * @brief Show Menu items + */ +uint8_t OledShowMenuItem(uint8_t page, const char *context, uint8_t size, uint8_t reversed) +{ + return OledShowString(0, page, context, size, reversed); +} + +/** + * @brief Show Message common process + */ +static void OledShowMsgCommon(uint8_t page, const char *context, uint8_t size, bool highLight) +{ + size_t len = strlen(context); + uint8_t begin = 0; + uint8_t width = (uint8_t)(LCD_WIDTH / (size >> 1)); /* The width is calculated based on English characters. + The width of English characters is only 1/2 of the size. */ + if (len < width - 1) { + begin = (uint8_t)((width - len) >> 1); /* Make the message character appear in the middle of the current line */ + } + (void)OledShowString(((uint8_t)(begin * size) >> 1), page, context, size, highLight ? 0 : 1); +} + +/** + * @brief Show Message with normal font + */ +void OledShowMsg(uint8_t page, const char *context, uint8_t size) +{ + OledShowMsgCommon(page, context, size, 0); +} + +static void TxCmdToLcd(void) +{ + TransferCommandLcd(0x30); // EXT=0 + TransferCommandLcd(0x94); // Sleep out + TransferCommandLcd(0x31); // EXT=1 + TransferCommandLcd(0xD7); // Autoread disable + TransferDataLcd(0X9F, 1); // + + TransferCommandLcd(0x32); // Analog SET + TransferDataLcd(0x00, 1); // OSC Frequency adjustment + TransferDataLcd(0x01, 1); // Frequency on booster capacitors->6KHz + TransferDataLcd(0x03, 1); // Bias=1/11 + + TransferCommandLcd(0x31); // EXT=1 + TransferCommandLcd(0xf0); // 此指令比较重要,不加此指令升压会慢0.5s + TransferDataLcd(0x0f, 1); + TransferDataLcd(0x0f, 1); + TransferDataLcd(0x0f, 1); + TransferDataLcd(0x0f, 1); + + TransferCommandLcd(0x20); // Gray Level + uint32_t data[] = { + 0x01, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x10, + 0x11, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f + }; + for (int i = 0; i < sizeof(data) / sizeof(data[0]); ++i) { + TransferDataLcd(data[i], 1); + } + + TransferCommandLcd(0x30); // EXT=0 + TransferCommandLcd(0x75); // Page Address setting + TransferDataLcd(0X00, 1); // XS=0 + TransferDataLcd(0X14, 1); // XE=159 0x28 + TransferCommandLcd(0x15); // Clumn Address setting + TransferDataLcd(0X00, 1); // XS=0 + TransferDataLcd(0Xff, 1); // XE=256 + + TransferCommandLcd(0xBC); // Data scan direction + TransferDataLcd(0x00, 1); // MX.MY=Normal + TransferDataLcd(0xA6, 1); + + TransferCommandLcd(0x08); // Data scan direction + + TransferCommandLcd(0xCA); // Display Control + TransferDataLcd(0X00, 1); // + TransferDataLcd(0X7F, 1); // Duty=128 + TransferDataLcd(0X20, 1); // Nline=off + + TransferCommandLcd(0xF0); // Display Mode + TransferDataLcd(0X10, 1); // 10=Monochrome Mode,11=4Gray + + TransferCommandLcd(0x81); // 设置对比度 + TransferDataLcd(0x22, 1); // 微调对比度,范围OX00-OXFF + TransferDataLcd(0x03, 1); // 粗调对比度,范围OX00-0X07 + TransferCommandLcd(0x20); // Power control + + TransferDataLcd(0x0B, 1); // D0=regulator ; D1=follower ; D3=booste, on:1 off:0 + HAL_Delay(1); + TransferCommandLcd(0xAF); // Display on +} + +/** + * @brief Oled Clock Init + * @param 无 + * @retval 无 + */ +static void OledClkInit(void) +{ + /* 使能GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOH和GPIOI时钟 */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOI_CLK_ENABLE(); +} + +/** + * @brief 初始化OLED(SSD1306) + * @param 无 + * @retval 无 + */ +void OledInit(void) +{ + GPIO_InitTypeDef gpio_init_struct; + + OledClkInit(); + gpio_init_struct.Pin = OLED_SPI_RST_PIN; + gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */ + gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */ + gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; /* 高速 */ + HAL_GPIO_Init(OLED_SPI_RST_PORT, &gpio_init_struct); /* RST引脚模式设置 */ + + gpio_init_struct.Pin = OLED_SPI_CS_PIN; + HAL_GPIO_Init(OLED_SPI_CS_PORT, &gpio_init_struct); /* CS引脚模式设置 */ + + gpio_init_struct.Pin = OLED_SPI_RS_PIN; + HAL_GPIO_Init(OLED_SPI_RS_PORT, &gpio_init_struct); /* RS引脚模式设置 */ + + gpio_init_struct.Pin = OLED_SPI_SCLK_PIN; + HAL_GPIO_Init(OLED_SPI_SCLK_PORT, &gpio_init_struct); /* SCLK引脚模式设置 */ + + gpio_init_struct.Pin = OLED_SPI_SDIN_PIN; + HAL_GPIO_Init(OLED_SPI_SDIN_PORT, &gpio_init_struct); /* SDIN引脚模式设置 */ + + OledSdinSet(1); /* 设置SDIN引脚 */ + OledSclkSet(1); /* 设置SCLK引脚 */ + + // 字库管脚配置 + gpio_init_struct.Pin = ROM_IN_PIN; + HAL_GPIO_Init(ROM_IN_PORT, &gpio_init_struct); + + gpio_init_struct.Pin = ROM_SCK_PIN; + HAL_GPIO_Init(ROM_SCK_PORT, &gpio_init_struct); + + gpio_init_struct.Pin = ROM_CS_PIN; + HAL_GPIO_Init(ROM_CS_PORT, &gpio_init_struct); + + gpio_init_struct.Pin = ROM_OUT_PIN; + gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */ + HAL_GPIO_Init(ROM_OUT_PORT, &gpio_init_struct); + + OledCsSet(1); + OledRsSet(1); + + OledRstSet(0); + HAL_Delay(100); // Delay 100ms + OledRstSet(1); + HAL_Delay(100); // Delay 100ms + + TxCmdToLcd(); + + OledClear(); +} diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/oled/oled.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/oled/oled.h new file mode 100644 index 0000000000000000000000000000000000000000..35e001e170a0635b51fc1f78daf0caeec7e3b629 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/drivers/oled/oled.h @@ -0,0 +1,200 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file oled.h + * @author MCU Driver Team + * @brief oled process Header + */ + +#ifndef OLED_H +#define OLED_H + +#include +#include "stm32mp1xx.h" + +/* OLED模式设置 + * 0: 4线串行模式 (模块的BS1,BS2均接GND) + * 1: 并行8080模式 (模块的BS1,BS2均接VCC) + */ +#define OLED_MODE 0 /* 默认使用8080并口模式 */ + +/********************************OLED SPI模式引脚 定义************************************************/ +/* 注意:这里仅定义了 OLED 4线SPI模式驱动时的 引脚定义. 8位并口访问, 由于引脚太多,就不单独定义了. */ + +#define OLED_SPI_RST_PORT GPIOE +#define OLED_SPI_RST_PIN GPIO_PIN_3 +static inline void OledSpiRstClkEnable(void) +{ + __HAL_RCC_GPIOE_CLK_ENABLE(); +} + +#define OLED_SPI_CS_PORT GPIOE +#define OLED_SPI_CS_PIN GPIO_PIN_4 +static inline void OledSpiCsClkEnable(void) +{ + __HAL_RCC_GPIOE_CLK_ENABLE(); +} + +#define OLED_SPI_RS_PORT GPIOE +#define OLED_SPI_RS_PIN GPIO_PIN_5 +static inline void OledSpiRsClkEnable(void) +{ + __HAL_RCC_GPIOE_CLK_ENABLE(); +} + +#define OLED_SPI_SCLK_PORT GPIOE +#define OLED_SPI_SCLK_PIN GPIO_PIN_2 +static inline void OledSpiSclkClkEnable(void) +{ + __HAL_RCC_GPIOE_CLK_ENABLE(); +} + +#define OLED_SPI_SDIN_PORT GPIOE +#define OLED_SPI_SDIN_PIN GPIO_PIN_6 +static inline void OledSpiSdinClkEnable(void) +{ + __HAL_RCC_GPIOE_CLK_ENABLE(); +} + +/********************************IC库引脚定义************************************************/ +#define ROM_IN_PORT GPIOB +#define ROM_IN_PIN GPIO_PIN_15 /* ROM_IN */ + +#define ROM_SCK_PORT GPIOB +#define ROM_SCK_PIN GPIO_PIN_13 + +#define ROM_OUT_PORT GPIOB +#define ROM_OUT_PIN GPIO_PIN_14 /* ROM_OUT */ + +#define ROM_CS_PORT GPIOB +#define ROM_CS_PIN GPIO_PIN_12 + +/*****************************OLED SPI和8080并口模式相关端口控制函数 定义***************************************/ + +/* + * 注意:OLED_RST/OLED_CS/OLED_RS,这三个是和80并口模式共用的,即80模式也必须实现这3个函数! + */ +static inline void OledRstSet(uint8_t val) +{ + if (val == 0) { + HAL_GPIO_WritePin(OLED_SPI_RST_PORT, OLED_SPI_RST_PIN, GPIO_PIN_RESET); + } else { + HAL_GPIO_WritePin(OLED_SPI_RST_PORT, OLED_SPI_RST_PIN, GPIO_PIN_SET); + } +} + +static inline void OledCsSet(uint8_t val) +{ + if (val == 0) { + HAL_GPIO_WritePin(OLED_SPI_CS_PORT, OLED_SPI_CS_PIN, GPIO_PIN_RESET); + } else { + HAL_GPIO_WritePin(OLED_SPI_CS_PORT, OLED_SPI_CS_PIN, GPIO_PIN_SET); + } +} + +static inline void OledRsSet(uint8_t val) +{ + if (val == 0) { + HAL_GPIO_WritePin(OLED_SPI_RS_PORT, OLED_SPI_RS_PIN, GPIO_PIN_RESET); + } else { + HAL_GPIO_WritePin(OLED_SPI_RS_PORT, OLED_SPI_RS_PIN, GPIO_PIN_SET); + } +} + +static inline void OledSclkSet(uint8_t val) +{ + if (val == 0) { + HAL_GPIO_WritePin(OLED_SPI_SCLK_PORT, OLED_SPI_SCLK_PIN, GPIO_PIN_RESET); + } else { + HAL_GPIO_WritePin(OLED_SPI_SCLK_PORT, OLED_SPI_SCLK_PIN, GPIO_PIN_SET); + } +} + +static inline void OledSdinSet(uint8_t val) +{ + if (val == 0) { + HAL_GPIO_WritePin(OLED_SPI_SDIN_PORT, OLED_SPI_SDIN_PIN, GPIO_PIN_RESET); + } else { + HAL_GPIO_WritePin(OLED_SPI_SDIN_PORT, OLED_SPI_SDIN_PIN, GPIO_PIN_SET); + } +} + +/**********************字库IC引脚定义*********************************************************/ +static inline void OledRomInSet(uint8_t val) +{ + if (val == 0) { + HAL_GPIO_WritePin(ROM_IN_PORT, ROM_IN_PIN, GPIO_PIN_RESET); + } else { + HAL_GPIO_WritePin(ROM_IN_PORT, ROM_IN_PIN, GPIO_PIN_SET); + } +} + +static inline void OledRomSckSet(uint8_t val) +{ + if (val == 0) { + HAL_GPIO_WritePin(ROM_SCK_PORT, ROM_SCK_PIN, GPIO_PIN_RESET); + } else { + HAL_GPIO_WritePin(ROM_SCK_PORT, ROM_SCK_PIN, GPIO_PIN_SET); + } +} + +static inline void OledRomOutSet(uint8_t val) +{ + if (val == 0) { + HAL_GPIO_WritePin(ROM_OUT_PORT, ROM_OUT_PIN, GPIO_PIN_RESET); + } else { + HAL_GPIO_WritePin(ROM_OUT_PORT, ROM_OUT_PIN, GPIO_PIN_SET); + } +} + +static inline GPIO_PinState OledReadRomOut(void) +{ + return HAL_GPIO_ReadPin(ROM_OUT_PORT, ROM_OUT_PIN); +} + +static inline void OledRomCsSet(uint8_t val) +{ + if (val == 0) { + HAL_GPIO_WritePin(ROM_CS_PORT, ROM_CS_PIN, GPIO_PIN_RESET); + } else { + HAL_GPIO_WritePin(ROM_CS_PORT, ROM_CS_PIN, GPIO_PIN_SET); + } +} + +/*********************************命令/数据 定义*************************************************/ + +#define OLED_CMD 0 /* 写命令 */ +#define OLED_DATA 1 /* 写数据 */ + +typedef enum { + DISPLAY_NORMAL, + DISPLAY_REVERSE, +} DisplayMode; + +/*********************************函数声明*************************************************/ + +void OledInit(void); /* OLED初始化 */ +void OledClear(void); /* OLED清屏 */ +void OledClearFromStartYPixel(uint32_t startYPixel); +uint8_t OledShowString(uint8_t startColumn, uint8_t startPage, const char *text, uint8_t size, uint8_t type); + +uint8_t OledShowMenuItem(uint8_t page, const char *context, uint8_t size, uint8_t reversed); +void OledShowMsg(uint8_t page, const char *context, uint8_t size); +void OledClearLine(uint8_t page, uint8_t begin, uint8_t end); + +void SetGlobalDisaplyaMode(DisplayMode mode); +#endif diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_curr_det.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/interrupt/interrupt.c similarity index 46% rename from src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_curr_det.c rename to src/tools/hispark_trace/hispark/CA7/source/hispark_trace/interrupt/interrupt.c index 9e7a1713be4f615c2857f0ee629fc672c62cdd4e..313caed3029e5cc81fd180da9bbdd77d4f9d79fd 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/mcs_curr_det.c +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/interrupt/interrupt.c @@ -1,5 +1,5 @@ /** - * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,70 +15,99 @@ * 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. - * @file mcs_curr_det.c - * @author MCU Algorithm Team - * @brief This file contains current protection data struct and api declaration. + * @file interrupt.c + * @author MCU Driver Team + * @brief gic interrupt process */ +#include "stm32mp1xx.h" +#include "util.h" +#include "interrupt.h" +/** + * Interrupt vector table, supports up to IRQ_MAX interrupts, except for IRQ_VECTOR_CNT internal + * standard interrupts, which can be configured according to actual conditions. + */ +IRQ_PROC_FUNC g_irqCallbackFunc[MAX_IRQ_n]; -#include "mcs_curr_det.h" -#include "mcs_assert.h" -#include "mcs_math.h" +/** + * Default handler for GIC + */ +static void IRQ_DefaultHandler(void) +{ + ; +} +/** + * Init IRQ table + */ +static void IRQ_TableInit(void) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(g_irqCallbackFunc); ++i) { + g_irqCallbackFunc[i] = IRQ_DefaultHandler; + } +} /** - * @brief Initilization over current detection function. - * @param ocd Over current detection handle. - * @param currThr Over current value threshold. - * @param timeThr Over current time threshold (s). - * @param ts Ctrl period (s). - * @retval None. + * Interrupt entry, called by start.S */ -void OCD_Init(OCD_Handle *ocd, float currThr, float timeThr, float ts) +void InterruptEntry(unsigned int irqNum) { - MCS_ASSERT_PARAM(ocd != NULL); - MCS_ASSERT_PARAM(currThr > 0.0f); - MCS_ASSERT_PARAM(timeThr > 0.0f); - MCS_ASSERT_PARAM(ts > 0.0f); - /* Time threshold and current threshold. */ - ocd->currThr = currThr; - ocd->timeThr = timeThr; + if (irqNum >= MAX_IRQ_n) { + return; + } + g_irqCallbackFunc[irqNum](); +} - ocd->ts = ts; - /* Detection time limit calculation. */ - ocd->detCntLimit = (unsigned int)(ocd->timeThr / ocd->ts); +/** + * IRQ Module Init + */ +void IRQ_Init(void) +{ + __enable_irq(); + GIC_Enable(); + IRQ_TableInit(); } /** - * @brief Over current detection. - * @param ocd Over current detection handle. - * @param currAmp Current vlaue. - * @retval Whether the motor is over current. + * Register callback function for IRQ */ -bool OCD_Exec(OCD_Handle *ocd, float currAmp) +unsigned int IRQ_Register(unsigned int irqNum, IRQ_PROC_FUNC func) { - MCS_ASSERT_PARAM(ocd != NULL); - float currAbs = Abs(currAmp); - /* Current threshold judgment. */ - if (currAbs < ocd->currThr) { - ocd->detCnt = 0; - return false; + if (irqNum >= MAX_IRQ_n) { + return -1; } - /* Over current detection time judgment. */ - if (ocd->detCnt < ocd->detCntLimit) { - ocd->detCnt++; - return false; + + g_irqCallbackFunc[irqNum] = func; + return 0; +} + +/** + * UnRegister callback function for IRQ + */ +void IRQ_UnRegister(unsigned int irqNum, IRQ_PROC_FUNC func) +{ + if (irqNum >= MAX_IRQ_n) { + return; } - return true; + g_irqCallbackFunc[irqNum] = IRQ_DefaultHandler; } /** - * @brief Clear history value. - * @param ocd Over current detection handle. - * @retval None. + * Disable interrupt */ -void OCD_Clear(OCD_Handle *ocd) +void IRQ_Disable(IRQn_Type irqNum) { - MCS_ASSERT_PARAM(ocd != NULL); - ocd->detCnt = 0; -} \ No newline at end of file + GIC_DisableIRQ(irqNum); + GIC_EndInterrupt(irqNum); +} + +/** + * Enable interrupt + */ +void IRQ_Enable(IRQn_Type irqNum, unsigned int priority, IRQ_PROC_FUNC irqHandler) +{ + GIC_SetPriority(irqNum, priority); + GIC_EnableIRQ(irqNum); + IRQ_Register(irqNum, irqHandler); +} diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/interrupt/interrupt.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/interrupt/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..e536f3cd0e9438fea313cbb4a95b3e98b9002a93 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/interrupt/interrupt.h @@ -0,0 +1,35 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file interrupt.h + * @author MCU Driver Team + * @brief gic interrupt process header + */ +#ifndef INTERRPUT_H +#define INTERRPUT_H + +#include "stm32mp153dxx_ca7.h" + +typedef void (* IRQ_PROC_FUNC)(void); + +void IRQ_Init(void); +void InterruptEntry(unsigned int irqNum); +unsigned int IRQ_Register(unsigned int irqNum, IRQ_PROC_FUNC func); +void IRQ_UnRegister(unsigned int irqNum, IRQ_PROC_FUNC func); +void IRQ_Disable(IRQn_Type irqNum); +void IRQ_Enable(IRQn_Type irqNum, unsigned int priority, IRQ_PROC_FUNC irqHandler); +#endif // INTERRPUT_H \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/nos_amp_task_del.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/msgQueue/msg_queue.c similarity index 39% rename from src/middleware/hisilicon/nostask/kernel/nos_amp_task_del.c rename to src/tools/hispark_trace/hispark/CA7/source/hispark_trace/msgQueue/msg_queue.c index f758f478d61ec8f2a532361daea0a9e1af06d3d1..9d81b36d9fbd91a35f28218a687226fc9bba67d6 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_amp_task_del.c +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/msgQueue/msg_queue.c @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,102 +15,101 @@ * 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. - * @file nos_amp_task_del.c + * @file msg_queue.c + * @author MCU Driver Team + * @brief Message Queue Process between Cortex-A and Cortex-M */ -#include "nos_task_internal.h" -#include "nos_buildef.h" +#include +#include +#include "securec.h" +#include "debug.h" +#include "msg_queue.h" -#if defined(OS_OPTION_TASK_DELETE) -/* 删除任务,重置Tcb块状态 */ -static void OsTaskDeleteResInit(unsigned int taskPid, struct TagTskCB *taskCB) -{ - (void)taskPid; - /* 判断任务状态 */ - if (((OS_TSK_PEND | OS_TSK_QUEUE_PEND) & taskCB->taskStatus) != 0) { - ListDelete(&taskCB->pendList); - } +extern int g_msgQStart; /* defined by linker script */ +MsgQCtrl *g_msgQCtrl = (MsgQCtrl *)&g_msgQStart; - if (((OS_TSK_DELAY | OS_TSK_TIMEOUT | OS_TSK_PERIOD) & taskCB->taskStatus) != 0) { - ListDelete(&taskCB->timerList); +/** + * @brief Message Queue Init + * @retval None + */ +void MSGQ_Init(void) +{ +#ifdef ROLE_MASTER + volatile MsgQ *p; + for (unsigned int i = 0; i < sizeof(g_msgQCtrl->msgQ) / sizeof(g_msgQCtrl->msgQ[0]); ++i) { + p = &g_msgQCtrl->msgQ[i]; + p->num = sizeof(g_msgQCtrl->msgQ[i].msg) / sizeof(g_msgQCtrl->msgQ[i].msg[0]); + p->send = 0; + p->rcv = 0; } - - if ((OS_TSK_READY & taskCB->taskStatus) != 0) { - /* 从就绪队列中删除 */ - OsTskReadyDel(taskCB); + g_msgQCtrl->initFlg = 1; +#else + while (g_msgQCtrl->initFlg == 0) { + ; /* Wait Master Init done */ } +#endif +} - taskCB->taskStatus &= (~(OS_TSK_SUSPEND)); - taskCB->taskStatus |= OS_TSK_UNUSED; - - return; +/** + * @brief Check whether the message queue is full. + * @retval true: full, false: not full + */ +static inline bool MSGQ_TxIsFull(void) +{ + volatile MsgQ *p = &g_msgQCtrl->msgQ[MSG_QUEUE_TX]; + return (((p->send + 1) % p->num) == p->rcv); } -/* - * 描述: 删除一个任务线程 - */ -unsigned int OsTaskDelete(unsigned int taskPid) +/** + * @brief Check whether the message queue is empty. + * @retval true: empty, false: not empty + */ +bool MSGQ_RxIsEmpty(void) { - unsigned int ret; - uintptr_t intSave; - struct TagTskCB *taskCB = NULL; + volatile MsgQ *p = &g_msgQCtrl->msgQ[MSG_QUEUE_RX]; + return (p->rcv == p->send); +} - if (taskPid == IDLE_TASK_ID) { - return OS_ERRNO_TSK_OPERATE_IDLE; +/** + * @brief Send Message to queue + * @retval result + */ +unsigned int MSGQ_SendMsg(MsgBuf *msg) +{ + errno_t rc = EOK; + volatile MsgQ *p = &g_msgQCtrl->msgQ[MSG_QUEUE_TX]; + if (msg == NULL) { + return QUEUE_ERROR; } - - if (CheckTaskPidOverflow(taskPid)) { - return OS_ERRNO_TSK_ID_INVALID; + if (MSGQ_TxIsFull() == true) { + return QUEUE_FULL; } - - intSave = NOS_TaskIntLock(); - - /* get task Tcb */ - taskCB = GetTcbHandle(taskPid); - /* 任务是否创建 */ - if (TSK_IsUnused(taskCB)) { - NOS_TaskIntRestore(intSave); - return OS_ERRNO_TSK_NOT_CREATED; + rc = memcpy_s((void *)&p->msg[p->send], sizeof(*msg), (void *)msg, sizeof(*msg)); + if (rc != EOK) { + return QUEUE_ERROR; } + p->send = (p->send + 1) % p->num; /* update send ptr */ + return QUEUE_OK; +} - /* check task status */ - ret = OsTaskDelStatusCheck(taskCB); - if (ret != NOS_OK) { - NOS_TaskIntRestore(intSave); - return ret; +/** + * @brief Receive Message from queue + * @retval result + */ +unsigned int MSGQ_ReceiveMsg(MsgBuf *msg) +{ + errno_t rc = EOK; + volatile MsgQ *p = &g_msgQCtrl->msgQ[MSG_QUEUE_RX]; + if (msg == NULL) { + return QUEUE_ERROR; } - - /* 删除任务 */ - OsTaskDeleteResInit(taskPid, taskCB); - - /* 寻找最高优先级任务 */ - OsTskHighestSet(); - - if ((OS_TSK_RUNNING & taskCB->taskStatus) != 0) { - UNI_FLAG |= OS_FLG_TSK_REQ; - - ListTailAdd(&taskCB->pendList, &g_tskRecyleList); - - RUNNING_TASK = OS_PST_ZOMBIE_TASK; - RUNNING_TASK->taskPid = taskPid; - RUNNING_TASK->taskStatus = taskCB->taskStatus; - - taskCB->taskStatus = OS_TSK_UNUSED; - - if (OS_INT_INACTIVE) { - OsTaskTrap(); - NOS_TaskIntRestore(intSave); - - return NOS_OK; - } - } else { - taskCB->taskStatus = OS_TSK_UNUSED; - ListAdd(&taskCB->pendList, &g_tskCBFreeList); + if (MSGQ_RxIsEmpty() == true) { + return QUEUE_EMPTY; } - - NOS_TaskIntRestore(intSave); - - /* if deleteing current task this is unreachable. */ - return NOS_OK; -} - -#endif \ No newline at end of file + rc = memcpy_s((void *)msg, sizeof(*msg), (void *)&p->msg[p->rcv], sizeof(*msg)); + if (rc != EOK) { + return QUEUE_ERROR; + } + p->rcv = (p->rcv + 1) % p->num; /* update receive ptr */ + return QUEUE_OK; +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/msgQueue/msg_queue.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/msgQueue/msg_queue.h new file mode 100644 index 0000000000000000000000000000000000000000..eb74fb8d1269fb20ccaa68bb2cd232b54b978668 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/msgQueue/msg_queue.h @@ -0,0 +1,101 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file msg_queue.h + * @author MCU Driver Team + * @brief Message Queue Process between Cortex-A and Cortex-M + */ + +#ifndef MSG_QUEUE_H +#define MSG_QUEUE_H + +#include +#include + +/* A核与M核共享的消息队列, 由A核初始化 */ +#ifdef ROLE_MASTER +#define MSGQ_SECTION __attribute__((section(".msgq_section"))) +#endif + +#define Q_TRUE 1 +#define Q_FALSE 0 + +#define WRITE_Q_START_ADDR 0x10050000 +#define WRITE_Q_SIZE 0x8000 +#define READ_Q_START_ADDR 0x10058000 +#define READ_Q_SIZE 0x8000 + +#define MSG_SIZE 3072 +#define MSG_NUM 2 + +typedef enum { + MSG_ERROR, + MSG_OK +} MSG_ACK; + +typedef enum { + MSG_TYPE_DEBUG, + MSG_TYPE_SAMPLING, + MSG_TYPE_WRITEVAR, + MSG_TYPE_CLK_CFG, + MSG_TYPE_PERFORMANCE_TEST, + MSG_TYPE_DEBUG_PORT_SET, + MSG_TYPE_PAUSESAMPLING, +} MSG_TYPE; + +typedef enum { +#ifdef ROLE_MASTER + MSG_QUEUE_TX, + MSG_QUEUE_RX, +#else + MSG_QUEUE_RX, + MSG_QUEUE_TX, +#endif + MSG_QUEUE_NUN +} MSG_QUEUE_EN; + +typedef struct { + unsigned int type; + unsigned int bufLen; + unsigned char buf[MSG_SIZE - (sizeof(unsigned int) + sizeof(int))]; +} MsgBuf; + +typedef enum { + QUEUE_ERROR = -1, + QUEUE_OK = 0, + QUEUE_FULL = 1, + QUEUE_EMPTY = 2, +} QUEUE_RETVAL; + +typedef struct { + size_t num; + unsigned int send; + unsigned int rcv; + MsgBuf msg[MSG_NUM]; +} MsgQ; + +typedef struct { + unsigned int initFlg; + MsgQ msgQ[MSG_QUEUE_NUN]; +} volatile MsgQCtrl; + +void MSGQ_Init(void); +unsigned int MSGQ_SendMsg(MsgBuf *msg); +unsigned int MSGQ_ReceiveMsg(MsgBuf *msg); +bool MSGQ_RxIsEmpty(void); + +#endif /* MSG_QUEUE_H */ \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/config_storage_update.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/config_storage_update.c new file mode 100644 index 0000000000000000000000000000000000000000..be3abafd2ef32104a5642a050cf1fde2134eb587 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/config_storage_update.c @@ -0,0 +1,888 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file config_storage_update.c + * @author MCU Driver Team + * @brief config storage update driver. + */ +#include +#include +#include "securec.h" +#include "FlashPrg.h" +#include "config_storage_update.h" + +#define ONE_PAGE_SIZE 256 + +#define ONE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE (TARGET_LIB_FACTORY_IMAGE_MAX_NUM * 4) +#define ONE_IMAGE_LOAD_CNT_LIST_SIZE (TARGET_LIB_IMAGE_MAX_NUM * 4) +#define ALL_CFG_MEM_LEN (CONFIG_STORAGE_UPDATE_CFG_END_OFFSET - CONFIG_STORAGE_UPDATE_CFG_START_OFFSET) + +static int g_configLoadType = CONFIG_LOAD_TYPE_UNKNOW; +static int g_configLoadEndAddr = 0; +static uint32_t g_configLoadFileSize = 0; +static uint32_t g_imageLoadCntListStartAddr = CONFIG_FLASH_BASS_ADDR + CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_OFFSET; +static uint32_t g_factoryImageLoadCntListStartAddr = CONFIG_FLASH_BASS_ADDR + \ + CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_OFFSET; + +/** + * @brief Flash segment storage processing + * @param addr Storage start address + * @param buf Pointer to stored data + * @param len Storage data length + * @retval None + */ +static void ProgramPageHandle(uint32_t addr, uint8_t *buf, uint32_t len) +{ + uint32_t pageCnt; + uint32_t tempAddr = addr; + uint32_t sz = len; + uint8_t *tempBuf = buf; + + pageCnt = sz / ONE_PAGE_SIZE; + for (uint32_t i = 0; i < pageCnt; i++) { + /* Full page writing */ + ProgramPage(tempAddr, ONE_PAGE_SIZE, (uint32_t *)tempBuf); + tempAddr += ONE_PAGE_SIZE; + sz -= ONE_PAGE_SIZE; + tempBuf += ONE_PAGE_SIZE; + } + if (sz > 0) { + /* Finally, write less than one page of data. */ + ProgramPage(tempAddr, sz, (uint32_t *)tempBuf); + } +} + +/** + * @brief Update the configuration. + * @param data Data to be updated + * @param dataSize Data length + * @param offset Offset position + * @retval None + */ +static void ConfigUpdate(const uint8_t *data, uint32_t dataSize, uint32_t offset) +{ + uint8_t cfgBuff[ALL_CFG_MEM_LEN] = {0}; + uint32_t addr; + errno_t rc = EOK; + + UnInit(0); + Init(0, 0, 0); + /* Backup image list. */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_CFG_START_OFFSET; + FlashRead(addr, ALL_CFG_MEM_LEN, (uint8_t *)cfgBuff); + rc = memcpy_s((cfgBuff + offset), dataSize, data, dataSize); + if (rc != EOK) { + UnInit(0); + return; + } + EraseSector(addr); + ProgramPageHandle(addr, cfgBuff, ALL_CFG_MEM_LEN); + UnInit(0); +} + +/** + * @brief Save the algorithm list. + * @param list Algorithm list + * @param listSize list size + * @retval Success or Failure Result + */ +int32_t ConfigAlgoListSave(TargetAlgoHandle *list, uint32_t listSize) +{ + TargetImageHandle tempImage; + uint32_t addr; + uint32_t sz; + uint8_t *buf = NULL; + + UnInit(0); + Init(0, 0, 0); + /* Backup image list. */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_IMAGE_LIST_OFFSET; + FlashRead(addr, sizeof(tempImage), (uint8_t *)&tempImage); + + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_ALGO_LIST_OFFSET; + EraseSector(addr); + /* save algo */ + sz = listSize; + buf = (uint8_t*)list; + ProgramPageHandle(addr, buf, sz); + + /* save image */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_IMAGE_LIST_OFFSET; + sz = sizeof(tempImage); + buf = (uint8_t*)&tempImage; + ProgramPageHandle(addr, buf, sz); + + UnInit(0); + return 0; +} + +/** + * @brief Read the algorithm list. + * @param list Algorithm list + * @param listSize list size + * @retval Success or Failure Result + */ +int32_t ConfigAlgoListRead(TargetAlgoHandle *list, uint32_t listSize) +{ + uint32_t addr; + + if (list == NULL) { + return -1; + } + + UnInit(0); + Init(0, 0, 0); + /* Read algorithm list */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_ALGO_LIST_OFFSET; + FlashRead(addr, listSize, (uint8_t *)list); + UnInit(0); + return 0; +} + +/** + * @brief Save the image list. + * @param list image list + * @param listSize list size + * @retval Success or Failure Result + */ +int32_t ConfigImageListSave(TargetImageHandle *list, uint32_t listSize) +{ + if (list == NULL) { + return -1; + } + TargetAlgoHandle tempAlgo; + uint32_t addr; + uint32_t sz; + uint8_t *buf = NULL; + /* Initialize the debugger flash operation. */ + UnInit(0); + Init(0, 0, 0); + /* Backup algorithm list. */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_ALGO_LIST_OFFSET; + FlashRead(addr, sizeof(tempAlgo), (uint8_t *)&tempAlgo); + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_ALGO_LIST_OFFSET; + EraseSector(addr); + /* save image */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_IMAGE_LIST_OFFSET; + sz = listSize; + buf = (uint8_t*)list; + ProgramPageHandle(addr, buf, sz); + + /* save algo */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_ALGO_LIST_OFFSET; + sz = sizeof(tempAlgo); + buf = (uint8_t*)&tempAlgo; + ProgramPageHandle(addr, buf, sz); + + UnInit(0); + return 0; +} + +/** + * @brief Read the image list. + * @param list image list + * @param listSize list size + * @retval Success or Failure Result + */ +int32_t ConfigImageListRead(TargetImageHandle *list, uint32_t listSize) +{ + uint32_t addr; + + UnInit(0); + Init(0, 0, 0); + /* Read image list */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_IMAGE_LIST_OFFSET; + FlashRead(addr, listSize, (uint8_t *)list); + UnInit(0); + return 0; +} + +/** + * @brief Holds an array of flags indicating whether the algorithm storage area is free. + * @param flagArry Idle flag array + * @param arrySize Array Length + * @retval Success or Failure Result + */ +int32_t ConfigFreeAlgoFlagSave(const bool *flagArry, uint32_t arrySize) +{ + uint32_t offset = CONFIG_STORAGE_UPDATE_FREE_ALGO_FLAG_ARRY_OFFSET - \ + CONFIG_STORAGE_UPDATE_CFG_START_OFFSET; + + if (flagArry == NULL) { + return -1; + } + + ConfigUpdate((const uint8_t *)flagArry, arrySize, offset); + return 0; +} + +/** + * @brief Indicates the flag array for reading whether the storage area of the flag algorithm is idle. + * @param flagArry Idle flag array + * @param arrySize Array Length + * @retval Success or Failure Result + */ +int32_t ConfigFreeAlgoFlagRead(bool *flagArry, uint32_t arrySize) +{ + uint32_t addr; + + UnInit(0); + Init(0, 0, 0); + /* Read free algorithm storage space flag. */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FREE_ALGO_FLAG_ARRY_OFFSET; + FlashRead(addr, arrySize, (uint8_t *)flagArry); + UnInit(0); + return 0; +} + +/** + * @brief Stores the array indicating whether the image storage area is idle. + * @param flagArry Idle flag array + * @param arrySize Array Length + * @retval Success or Failure Result + */ +int32_t ConfigFreeImageFlagSave(const bool *flagArry, uint32_t arrySize) +{ + uint32_t offset = CONFIG_STORAGE_UPDATE_FREE_IMAGE_FLAG_ARRY_OFFSET - \ + CONFIG_STORAGE_UPDATE_CFG_START_OFFSET; + + if (flagArry == NULL) { + return -1; + } + ConfigUpdate((const uint8_t *)flagArry, arrySize, offset); + return 0; +} + +/** + * @brief Reads the array indicating whether the image storage area is idle. + * @param flagArry Idle flag array + * @param arrySize Array Length + * @retval Success or Failure Result + */ +int32_t ConfigFreeImageFlagRead(bool *flagArry, uint32_t arrySize) +{ + uint32_t addr; + + UnInit(0); + Init(0, 0, 0); + /* Read image free list */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FREE_IMAGE_FLAG_ARRY_OFFSET; + FlashRead(addr, arrySize, (uint8_t *)flagArry); + UnInit(0); + return 0; +} + +/** + * @brief Stores the array indicating whether the image file storage area is idle in factory mode. + * @param flagArry Idle flag array + * @param arrySize Array Length + * @retval Success or Failure Result + */ +int32_t ConfigFactoryFreeImageFlagSave(const bool *flagArry, uint32_t arrySize) +{ + uint32_t offset = CONFIG_STORAGE_UPDATE_FREE_FACTORY_IMAGE_FLAG_ARRY_OFFSET - \ + CONFIG_STORAGE_UPDATE_CFG_START_OFFSET; + + if (flagArry == NULL) { + return -1; + } + + ConfigUpdate((const uint8_t *)flagArry, arrySize, offset); + return 0; +} + +/** + * @brief Read the array indicating whether the image file storage area is idle in factory mode. + * @param flagArry Idle flag array + * @param arrySize Array Length + * @retval Success or Failure Result + */ +int32_t ConfigFactoryFreeImageFlagRead(bool *flagArry, uint32_t arrySize) +{ + uint32_t addr; + + UnInit(0); + Init(0, 0, 0); + /* Read free image flag */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FREE_FACTORY_IMAGE_FLAG_ARRY_OFFSET; + FlashRead(addr, arrySize, (uint8_t *)flagArry); + UnInit(0); + return 0; +} + +/** + * @brief Save Startup Flag. + * @param flag Startup Flag + * @retval Success or Failure Result + */ +int32_t ConfigStartFlagSave(uint32_t flag) +{ + uint32_t offset = CONFIG_STORAGE_UPDATE_STARTUP_FLAG_OFFSET - \ + CONFIG_STORAGE_UPDATE_CFG_START_OFFSET; + ConfigUpdate((const uint8_t *)&flag, sizeof(flag), offset); + return 0; +} + +/** + * @brief Read Startup Flag. + * @retval Startup Flag + */ +uint32_t ConfigStartFlagRead(void) +{ + uint32_t addr; + uint32_t startFlag; + + UnInit(0); + Init(0, 0, 0); + /* Read start flag */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_STARTUP_FLAG_OFFSET; + FlashRead(addr, sizeof(startFlag), (uint8_t *)&startFlag); + UnInit(0); + return startFlag; +} + +/** + * @brief Saves the current algorithm index. + * @param index Indicates the current algorithm index + * @retval Success or Failure Result + */ +int32_t ConfigCurrentAlgoIndexSave(int32_t index) +{ + uint32_t offset = CONFIG_STORAGE_UPDATE_CURRENT_ALGO_INDEX_OFFSET - \ + CONFIG_STORAGE_UPDATE_CFG_START_OFFSET; + ConfigUpdate((const uint8_t *)&index, sizeof(index), offset); + return 0; +} + +/** + * @brief Read the current algorithm index. + * @retval current algorithm index + */ +int32_t ConfigCurrentAlgoIndexRead(void) +{ + uint32_t addr; + int32_t algoIndex; + + UnInit(0); + Init(0, 0, 0); + /* Read algorithm index */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_CURRENT_ALGO_INDEX_OFFSET; + FlashRead(addr, sizeof(algoIndex), (uint8_t *)&algoIndex); + UnInit(0); + return algoIndex; +} + +/** + * @brief Stores the list of image files in factory mode. + * @param list image files list + * @param listSize list size + * @retval Success or Failure Result + */ +int32_t ConfigFactoryImageListSave(FactoryImageHandle *list, uint32_t listSize) +{ + uint32_t addr; + uint32_t sz; + uint8_t *buf = NULL; + + UnInit(0); + Init(0, 0, 0); + /* Erase the flash partition of the image list file in factory mode. */ + addr = CONFIG_FLASH_BASS_ADDR + CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LIST_OFFSET; + EraseSector(addr); + sz = listSize; + buf = (uint8_t*)list; + /* Update data */ + ProgramPageHandle(addr, buf, sz); + + UnInit(0); + return 0; +} + +/** + * @brief Read the list of image files in factory mode. + * @param list image files list + * @param listSize list size + * @retval Success or Failure Result + */ +int32_t ConfigFactoryImageListRead(FactoryImageHandle *list, uint32_t listSize) +{ + uint32_t addr; + + if (list == NULL) { + return -1; + } + UnInit(0); + Init(0, 0, 0); + /* Read image list */ + addr = CONFIG_FLASH_BASS_ADDR + CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LIST_OFFSET; + FlashRead(addr, listSize, (uint8_t *)list); + UnInit(0); + return 0; +} + +/** + * @brief Save Factory Mode Flag + * @param flag Factory Mode Flag + * @retval Success or Failure Result + */ +int32_t ConfigFactoryFlagSave(uint32_t flag) +{ + uint32_t offset = CONFIG_STORAGE_UPDATE_FACTORY_FLAG_OFFSET - \ + CONFIG_STORAGE_UPDATE_CFG_START_OFFSET; + ConfigUpdate((const uint8_t *)&flag, sizeof(flag), offset); + return 0; +} + +/** + * @brief Read Factory Mode Flag + * @retval Factory Mode Flag + */ +uint32_t ConfigFactoryFlagRead(void) +{ + uint32_t addr; + uint32_t factoryFlag; + + UnInit(0); + Init(0, 0, 0); + /* Read factory flag */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FACTORY_FLAG_OFFSET; + FlashRead(addr, sizeof(factoryFlag), (uint8_t *)&factoryFlag); + UnInit(0); + return factoryFlag; +} + +/** + * @brief Save the external power supply status flag. + * @param flag External power supply status flag + * @retval Success or Failure Result + */ +int32_t ConfigPowerStatusFlagSave(uint32_t flag) +{ + uint32_t offset = CONFIG_STORAGE_UPDATE_POWER_STATUS_FLAG_OFFSET - \ + CONFIG_STORAGE_UPDATE_CFG_START_OFFSET; + ConfigUpdate((const uint8_t *)&flag, sizeof(flag), offset); + return 0; +} + +/** + * @brief Read the external power supply status flag. + * @retval External power supply status flag + */ +uint32_t ConfigPowerStatusFlagRead(void) +{ + uint32_t powerStatus; + uint32_t addr; + + UnInit(0); + Init(0, 0, 0); + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_POWER_STATUS_FLAG_OFFSET; + FlashRead(addr, sizeof(powerStatus), (uint8_t *)&powerStatus); + UnInit(0); + return powerStatus; +} + +/** + * @brief Save Language Configuration Flag. + * @param flag Language configuration flag + * @retval Success or Failure Result + */ +int32_t ConfigLanguageFlagSave(uint32_t flag) +{ + uint32_t offset = CONFIG_STORAGE_UPDATE_LANGUAGE_FLAG_OFFSET - \ + CONFIG_STORAGE_UPDATE_CFG_START_OFFSET; + ConfigUpdate((const uint8_t *)&flag, sizeof(flag), offset); + return 0; +} + +/** + * @brief Reads the language configuration flag. + * @retval Language configuration flag + */ +uint32_t ConfigLanguageFlagRead(void) +{ + uint32_t languageFlag; + uint32_t addr; + + UnInit(0); + Init(0, 0, 0); + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_LANGUAGE_FLAG_OFFSET; + FlashRead(addr, sizeof(languageFlag), (uint8_t *)&languageFlag); + UnInit(0); + return languageFlag; +} + +/** + * @brief Save Debug Port Configuration. + * @param flag Debug Port Configuration flag + * @retval Success or Failure Result + */ +int32_t ConfigDebugPortFlagSave(uint32_t flag) +{ + uint32_t offset = CONFIG_STORAGE_UPDATE_DEBUG_PORT_FLAG_OFFSET - \ + CONFIG_STORAGE_UPDATE_CFG_START_OFFSET; + ConfigUpdate((const uint8_t *)&flag, sizeof(flag), offset); + return 0; +} + +/** + * @brief Read Debug Port Configuration. + * @retval Debug Port Configuration + */ +uint32_t ConfigDebugPorFlagRead(void) +{ + uint32_t debugPortFlag; + uint32_t addr; + + UnInit(0); + Init(0, 0, 0); + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_DEBUG_PORT_FLAG_OFFSET; + FlashRead(addr, sizeof(debugPortFlag), (uint8_t *)&debugPortFlag); + UnInit(0); + return debugPortFlag; +} + +/** + * @brief Save the list of download times. + * @param list image load cnt list + * @param listSize list size + * @retval Success or Failure Result + */ +int32_t ConfigImageLoadCntSave(const TargetImageLoadCntList *list, uint32_t listSize) +{ + uint32_t addr; + uint32_t left; + TargetImageLoadCntList tempList; + uint32_t flag = 0; + uint8_t *temp = (uint8_t*)&tempList; + + UnInit(0); + Init(0, 0, 0); + /* Obtains the remaining size of the storage area. */ + left = CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_OFFSET + \ + CONFIG_FLASH_BASS_ADDR + \ + CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_SIZE - g_imageLoadCntListStartAddr; + if (left >= ONE_IMAGE_LOAD_CNT_LIST_SIZE) { + /* The storage address is moved backward by a group of units. */ + addr = g_imageLoadCntListStartAddr + ONE_IMAGE_LOAD_CNT_LIST_SIZE; + } else { + /* The storage area is used up. Erase the entire flash memory again. + The storage start address is looped back to the start position. */ + addr = CONFIG_FLASH_BASS_ADDR + CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_OFFSET; + EraseSector(addr); + } + /* Avoid false positives in the first storage area. */ + if (g_imageLoadCntListStartAddr == (CONFIG_FLASH_BASS_ADDR + \ + CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_OFFSET)) { + addr = g_imageLoadCntListStartAddr; + FlashRead(addr, sizeof(TargetImageLoadCntList), (uint8_t *)&tempList); + flag = 0; + /* Determine whether data has been stored in the first block area */ + for (uint32_t i = 0; i < sizeof(TargetImageLoadCntList); i++) { + if (temp[i] != 0xFF) { + flag = 1; + break; + } + } + if (flag != 0) { + addr = g_imageLoadCntListStartAddr + ONE_IMAGE_LOAD_CNT_LIST_SIZE; + } + } + + ProgramPage(addr, listSize, (uint32_t *)list); + g_imageLoadCntListStartAddr = addr; + return 0; +} + +/** + * @brief Read the list of download times. + * @param list image load cnt list + * @param listSize list size + * @retval Success or Failure Result + */ +int32_t ConfigImageLoadCntRead(TargetImageLoadCntList *list, uint32_t listSize) +{ + uint32_t addr; + + UnInit(0); + Init(0, 0, 0); + addr = g_imageLoadCntListStartAddr; + FlashRead(addr, listSize, (uint8_t *)list); + UnInit(0); + return 0; +} + +/** + * @brief Address for storing the number of times the calibration image is downloaded. + * @retval Success or Failure Result + */ +int32_t ConfigImageLoadCntAddrCalibration(void) +{ + TargetImageLoadCntList tempList; + uint32_t i; + uint32_t addr = g_imageLoadCntListStartAddr; + uint32_t left = CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_SIZE; + uint32_t flag = 0; + uint8_t *temp = (uint8_t*)&tempList; + + UnInit(0); + Init(0, 0, 0); + /* Find the first unstored area from left to right. */ + while (left > ONE_IMAGE_LOAD_CNT_LIST_SIZE) { + FlashRead(addr, sizeof(TargetImageLoadCntList), (uint8_t *)&tempList); + flag = 0; + for (i = 0; i < sizeof(TargetImageLoadCntList); i++) { + /* If a value other than 0xFF is found in a storage area, + data has been written to the area. */ + if (temp[i] != 0xFF) { + flag = 1; + break; + } + } + /* Confirm the location of the next set of updated data stores */ + if (flag == 0) { + if (addr == (CONFIG_FLASH_BASS_ADDR + CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_OFFSET)) { + g_imageLoadCntListStartAddr = addr; + } else { + g_imageLoadCntListStartAddr = addr - ONE_IMAGE_LOAD_CNT_LIST_SIZE; + } + break; + } + addr += ONE_IMAGE_LOAD_CNT_LIST_SIZE; + left = CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_OFFSET + \ + CONFIG_FLASH_BASS_ADDR + \ + CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_SIZE - addr; + } + /* When all regions have been written, the address loops back to the start position. */ + if (flag != 0) { + g_imageLoadCntListStartAddr = addr - ONE_IMAGE_LOAD_CNT_LIST_SIZE; + } + UnInit(0); + return 0; +} + +/** + * @brief Clear the list of image download times. + * @retval Success or Failure Result + */ +int32_t ConfigImageLoadCntClean(void) +{ + uint32_t addr; + + UnInit(0); + Init(0, 0, 0); + + addr = CONFIG_FLASH_BASS_ADDR + CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_OFFSET; + EraseSector(addr); + g_imageLoadCntListStartAddr = addr; + UnInit(0); + return 0; +} + +/** + * @brief Saves the list of download times in factory mode. + * @param list image load cnt list + * @param listSize list size + * @retval Success or Failure Result + */ +int32_t ConfigFactoryImageLoadCntSave(const FactoryImageLoadCntList *list, uint32_t listSize) +{ + uint32_t addr; + uint32_t left; + FactoryImageLoadCntList tempList; + uint8_t *temp = (uint8_t*)&tempList; + uint32_t flag = 0; + + UnInit(0); + Init(0, 0, 0); + /* Obtains the remaining size of the storage area. */ + left = CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_OFFSET + \ + CONFIG_FLASH_BASS_ADDR + \ + CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE - g_factoryImageLoadCntListStartAddr; + if (left >= ONE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE) { + /* The storage address is moved backward by a group of units. */ + addr = g_factoryImageLoadCntListStartAddr + ONE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE; + } else { + /* The storage area is used up. Erase the entire flash memory again. + The storage start address is looped back to the start position. */ + addr = CONFIG_FLASH_BASS_ADDR + CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_OFFSET; + EraseSector(addr); + } + /* Avoid false positives in the first storage area. */ + if (g_factoryImageLoadCntListStartAddr == (CONFIG_FLASH_BASS_ADDR + \ + CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_OFFSET)) { + addr = g_factoryImageLoadCntListStartAddr; + FlashRead(addr, sizeof(FactoryImageLoadCntList), (uint8_t *)&tempList); + flag = 0; + /* Determine whether data has been stored in the first block area */ + for (uint32_t i = 0; i < sizeof(FactoryImageLoadCntList); i++) { + if (temp[i] != 0xFF) { + flag = 1; + break; + } + } + if (flag != 0) { + addr = g_factoryImageLoadCntListStartAddr + ONE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE; + } + } + + ProgramPage(addr, listSize, (uint32_t *)list); + g_factoryImageLoadCntListStartAddr = addr; + return 0; +} + +/** + * @brief Read the list of download times in factory mode. + * @param list image load cnt list + * @param listSize list size + * @retval Success or Failure Result + */ +int32_t ConfigFactoryImageLoadCntRead(FactoryImageLoadCntList *list, uint32_t listSize) +{ + uint32_t addr; + + UnInit(0); + Init(0, 0, 0); + addr = g_factoryImageLoadCntListStartAddr; + FlashRead(addr, listSize, (uint8_t *)list); + UnInit(0); + return 0; +} + +/** + * @brief Address for downloading calibration images in factory mode. + * @retval Success or Failure Result + */ +int32_t ConfigFactoryImageLoadCntAddrCalibration(void) +{ + FactoryImageLoadCntList tempList; + uint32_t i; + uint32_t addr = g_factoryImageLoadCntListStartAddr; + uint32_t left = CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE; + uint32_t flag = 0; + uint8_t *temp = (uint8_t*)&tempList; + + UnInit(0); + Init(0, 0, 0); + /* Find the first unstored area from left to right. */ + while (left > ONE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE) { + FlashRead(addr, sizeof(FactoryImageLoadCntList), (uint8_t *)&tempList); + flag = 0; + for (i = 0; i < sizeof(FactoryImageLoadCntList); i++) { + /* If a value other than 0xFF is found in a storage area, + data has been written to the area. */ + if (temp[i] != 0xFF) { + flag = 1; + break; + } + } + /* Confirm the location of the next set of updated data stores */ + if (flag == 0) { + if (addr == (CONFIG_FLASH_BASS_ADDR + CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_OFFSET)) { + g_factoryImageLoadCntListStartAddr = addr; + } else { + g_factoryImageLoadCntListStartAddr = addr - ONE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE; + } + break; + } + addr += ONE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE; + left = CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_OFFSET + \ + CONFIG_FLASH_BASS_ADDR + \ + CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE - addr; + } + /* When all regions have been written, the address loops back to the start position. */ + if (flag != 0) { + g_factoryImageLoadCntListStartAddr = addr - ONE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE; + } + UnInit(0); + return 0; +} + +/** + * @brief Clear the list of image download times in factory mode. + * @retval Success or Failure Result + */ +int32_t ConfigFactoryImageLoadCntClean(void) +{ + uint32_t addr; + + UnInit(0); + Init(0, 0, 0); + addr = CONFIG_FLASH_BASS_ADDR + CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_OFFSET; + EraseSector(addr); + g_factoryImageLoadCntListStartAddr = addr; + return 0; +} + +/** + * @brief Download Type set + * @param type Download Type + * @retval Success or Failure Result + */ +int32_t ConfigLoadTypeSet(int32_t type) +{ + g_configLoadType = type; + return 0; +} + +/** + * @brief Download Type get + * @retval Download Type + */ +int32_t ConfigLoadTypeGet(void) +{ + return g_configLoadType; +} + +/** + * @brief Download End Address set + * @param addr Download End Address + * @retval Success or Failure Result + */ +int32_t ConfigLoadEndAddrSet(int32_t addr) +{ + g_configLoadEndAddr = addr; + return 0; +} + +/** + * @brief Download End Address get + * @retval Download End Address + */ +int32_t ConfigLoadEndAddrGet(void) +{ + return g_configLoadEndAddr; +} + +/** + * @brief Current file length set + * @param len Current file length + * @retval Success or Failure Result + */ +int32_t ConfigLoadCurrentFileSizeSet(uint32_t len) +{ + g_configLoadFileSize = len; + return 0; +} + +/** + * @brief Current file length get + * @retval Current file length + */ +uint32_t ConfigLoadCurrentFileSizeGet(void) +{ + return g_configLoadFileSize; +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/config_storage_update.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/config_storage_update.h new file mode 100644 index 0000000000000000000000000000000000000000..9459fbda1de61c93cfeb087782017c2a5611b6c5 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/config_storage_update.h @@ -0,0 +1,162 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file config_storage_update.h + * @author MCU Driver Team + * @brief config storage update driver. + */ +#ifndef CONFIG_STORAGE_UPDATE_H +#define CONFIG_STORAGE_UPDATE_H + +#include +#include "target_lib_manager.h" +#include "factory_manager.h" + +#define CONFIG_LOAD_TYPE_UNKNOW 0 +#define CONFIG_LOAD_TYPE_INTERFACE 1 +#define CONFIG_LOAD_TYPE_BOOT 2 +#define CONFIG_LOAD_TYPE_IMAGE 3 +#define CONFIG_LOAD_TYPE_ALGO 4 +#define CONFIG_LOAD_TYPE_TARGET 5 + +#define CONFIG_FLASH_BASS_ADDR 0x10048000 + +#define CONFIG_STRAT_FLAG_A 0xFFFFFFFF +#define CONFIG_STRAT_FLAG_B 0 + +#define CONFIG_STORAGE_MAX_BOOT_SIZE 0x8000 +#define CONFIG_STORAGE_MAX_INFACR_SIZE 0x100000 +#define CONFIG_STORAGE_ONE_IMAGE_MAX_SIZE TARGET_LIB_ONE_IMAGE_SIZE +#define CONFIG_STORAGE_ONE_ALGO_MAX_SIZE TARGET_LIB_ONE_ALGO_SIZE + +#define CONFIG_STORAGE_MAX_SIZE 0x2000 +#define CONFIG_STORAGE_UPDATE_BASE_ADDR (0x10048000 + 0x8000) +#define CONFIG_STORAGE_UPDATE_BACKUP_BASE_ADDR (CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_MAX_SIZE) + +#define CONFIG_STORAGE_UPDATE_ALGO_LIST_OFFSET 0x0 +#define CONFIG_STORAGE_UPDATE_ALGO_LIST_SIZE 0x800 + +#define CONFIG_STORAGE_UPDATE_IMAGE_LIST_OFFSET 0x800 +#define CONFIG_STORAGE_UPDATE_IMAGE_LIST_SIZE 0x800 + +/* cfg start offset address */ +#define CONFIG_STORAGE_UPDATE_CFG_START_OFFSET 0x1000 + +#define CONFIG_STORAGE_UPDATE_STARTUP_FLAG_OFFSET 0x1000 +#define CONFIG_STORAGE_UPDATE_STARTUP_FLAG_SIZE 0x4 + +#define CONFIG_STORAGE_UPDATE_FREE_ALGO_FLAG_ARRY_OFFSET 0x1004 +#define CONFIG_STORAGE_UPDATE_FREE_ALGO_FLAG_ARRY_SIZE 0x50 + +#define CONFIG_STORAGE_UPDATE_FREE_IMAGE_FLAG_ARRY_OFFSET 0x1054 /* 4 * 10 byte */ +#define CONFIG_STORAGE_UPDATE_FREE_IMAGE_FLAG_ARRY_SIZE 0x28 + +#define CONFIG_STORAGE_UPDATE_FREE_FACTORY_IMAGE_FLAG_ARRY_OFFSET 0x107C /* 4 * 10 byte */ +#define CONFIG_STORAGE_UPDATE_FREE_FACTORY_IMAGE_FLAG_ARRY_SIZE 0x28 + +#define CONFIG_STORAGE_UPDATE_CURRENT_ALGO_INDEX_OFFSET 0x10A4 +#define CONFIG_STORAGE_UPDATE_CURRENT_ALGO_INDEX_SIZE 0x4 + +#define CONFIG_STORAGE_UPDATE_FACTORY_ALGO_LIST_OFFSET 0x1100 +#define CONFIG_STORAGE_UPDATE_FACTORY_ALGO_LIST_SIZE 0xD0 + +#define CONFIG_STORAGE_UPDATE_FACTORY_FLAG_OFFSET 0x12D0 +#define CONFIG_STORAGE_UPDATE_FACTORY_FLAG_SIZE 0x4 + +#define CONFIG_STORAGE_UPDATE_POWER_STATUS_FLAG_OFFSET 0x12D4 +#define CONFIG_STORAGE_UPDATE_POWER_STATUS_FLAG_SIZE 0x4 + +#define CONFIG_STORAGE_UPDATE_LANGUAGE_FLAG_OFFSET 0x12D8 +#define CONFIG_STORAGE_UPDATE_LANGUAGE_FLAG_SIZE 0x4 + +#define CONFIG_STORAGE_UPDATE_DEBUG_PORT_FLAG_OFFSET 0x12DC +#define CONFIG_STORAGE_UPDATE_DEBUG_PORT_FLAG_SIZE 0x4 + +/* cfg send offset address */ +#define CONFIG_STORAGE_UPDATE_CFG_END_OFFSET 0x12E0 + + +/* No add base config addr */ +#define CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LIST_OFFSET 0x210000 +#define CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LIST_SIZE 0x800 + +#define CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_OFFSET 0x20C000 +#define CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_SIZE 0x1000 + +#define CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_OFFSET 0x20E000 +#define CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE 0x1000 + + +int32_t ConfigAlgoListSave(TargetAlgoHandle *list, uint32_t listSize); +int32_t ConfigAlgoListRead(TargetAlgoHandle *list, uint32_t listSize); + +int32_t ConfigImageListSave(TargetImageHandle *list, uint32_t listSize); +int32_t ConfigImageListRead(TargetImageHandle *list, uint32_t listSize); + +int32_t ConfigFreeAlgoFlagSave(const bool *flagArry, uint32_t arrySize); +int32_t ConfigFreeAlgoFlagRead(bool *flagArry, uint32_t arrySize); + +int32_t ConfigFreeImageFlagSave(const bool *flagArry, uint32_t arrySize); +int32_t ConfigFreeImageFlagRead(bool *flagArry, uint32_t arrySize); + +int32_t ConfigFactoryFreeImageFlagSave(const bool *flagArry, uint32_t arrySize); +int32_t ConfigFactoryFreeImageFlagRead(bool *flagArry, uint32_t arrySize); + +int32_t ConfigStartFlagSave(uint32_t flag); +uint32_t ConfigStartFlagRead(void); + +int32_t ConfigCurrentAlgoIndexSave(int32_t index); +int32_t ConfigCurrentAlgoIndexRead(void); + +int32_t ConfigFactoryAlgoListSave(FactoryAlgoHandle *list, uint32_t listSize); +int32_t ConfigFactoryAlgoListRead(FactoryAlgoHandle *list, uint32_t listSize); + +int32_t ConfigFactoryImageListSave(FactoryImageHandle *list, uint32_t listSize); +int32_t ConfigFactoryImageListRead(FactoryImageHandle *list, uint32_t listSize); + +int32_t ConfigFactoryFlagSave(uint32_t flag); +uint32_t ConfigFactoryFlagRead(void); + +int32_t ConfigPowerStatusFlagSave(uint32_t flag); +uint32_t ConfigPowerStatusFlagRead(void); + +int32_t ConfigLanguageFlagSave(uint32_t flag); +uint32_t ConfigLanguageFlagRead(void); + +int32_t ConfigDebugPortFlagSave(uint32_t flag); +uint32_t ConfigDebugPorFlagRead(void); + +int32_t ConfigImageLoadCntSave(const TargetImageLoadCntList *list, uint32_t listSize); +int32_t ConfigImageLoadCntRead(TargetImageLoadCntList *list, uint32_t listSize); +int32_t ConfigImageLoadCntAddrCalibration(void); +int32_t ConfigImageLoadCntClean(void); + +int32_t ConfigFactoryImageLoadCntSave(const FactoryImageLoadCntList *list, uint32_t listSize); +int32_t ConfigFactoryImageLoadCntRead(FactoryImageLoadCntList *list, uint32_t listSize); +int32_t ConfigFactoryImageLoadCntAddrCalibration(void); +int32_t ConfigFactoryImageLoadCntClean(void); + +int32_t ConfigLoadTypeSet(int32_t type); +int32_t ConfigLoadTypeGet(void); + +int32_t ConfigLoadEndAddrSet(int32_t addr); +int32_t ConfigLoadEndAddrGet(void); + +int32_t ConfigLoadCurrentFileSizeSet(uint32_t len); +uint32_t ConfigLoadCurrentFileSizeGet(void); + +#endif /* #ifndef CONFIG_STORAGE_UPDATE_H */ \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/factory_manager.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/factory_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..9492a71716844426efea8997e436e3dece70f166 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/factory_manager.c @@ -0,0 +1,956 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file factory_manager.c + * @author MCU Driver Team + * @brief factory manager driver. + */ +#include "securec.h" +#include "FlashPrg.h" +#include "target_board.h" +#include "flash_manager.h" +#include "target_vendor_config.h" +#include "config_storage_update.h" +#include "target_algo_parse.h" +#include "swd_jtag_config.h" +#include "user_crc.h" +#include "status.h" +#include "factory_manager.h" + +static uint32_t g_factoryFlag = 0; +static FactoryImageHandle g_factoryImageList; +static int32_t g_currentFactoryImageIndex = 0; +static bool g_freeFactoryImageFlag[TARGET_LIB_FACTORY_IMAGE_MAX_NUM]; +static FactoryImageLoadCntList g_factoryImageLoadCntList; + +/** + * @brief Updates the factory image list. + * @retval None. + */ +static void TargetFactoryImageUpdateList(void) +{ + TargetImageLibInfo tempInfo; + uint32_t i; + int32_t tempCnt; + uint32_t tempLoadCnt; + if (g_currentFactoryImageIndex == (g_factoryImageList.count - 1) || + g_factoryImageList.count <= 0) { + return; + } + /* Temporary Storage List End File */ + tempInfo = g_factoryImageList.libInfo[g_factoryImageList.count - 1]; + tempLoadCnt = g_factoryImageLoadCntList.list[g_factoryImageList.count - 1]; + g_factoryImageList.libInfo[g_factoryImageList.count - 1] = g_factoryImageList.libInfo[g_currentFactoryImageIndex]; + g_factoryImageLoadCntList.list[g_factoryImageList.count - 1] = \ + g_factoryImageLoadCntList.list[g_currentFactoryImageIndex]; + /* To obtain the number of moves, subtract 2 from the number of moves. */ + tempCnt = g_factoryImageList.count - g_currentFactoryImageIndex - 2; + /* Move the file position to the left. */ + for (i = 0; i < tempCnt; i++) { + g_factoryImageList.libInfo[g_currentFactoryImageIndex + i] = \ + g_factoryImageList.libInfo[g_currentFactoryImageIndex + 1 + i]; + g_factoryImageLoadCntList.list[g_currentFactoryImageIndex + i] = \ + g_factoryImageLoadCntList.list[g_currentFactoryImageIndex + 1 + i]; + } + g_factoryImageList.libInfo[g_factoryImageList.count - 2] = tempInfo; /* Last Move Forward 2 */ + g_factoryImageLoadCntList.list[g_factoryImageList.count - 2] = tempLoadCnt; /* Last Move Forward 2 */ + g_currentFactoryImageIndex = g_factoryImageList.count - 1; +} + +/** + * @brief Get the factory mode idle address and save it. + * @retval Free Address + */ +static uint32_t FreeFactoryImageAddrGet(void) +{ + int i; + /* Query the first idle area address in the list. */ + for (i = 0; i < TARGET_LIB_FACTORY_IMAGE_MAX_NUM; i++) { + if (g_freeFactoryImageFlag[i]) { + g_freeFactoryImageFlag[i] = false; + ConfigFactoryFreeImageFlagSave(g_freeFactoryImageFlag, sizeof(g_freeFactoryImageFlag)); + return TARGET_LIB_FACTORY_IMAGE_START + i * TARGET_LIB_ONE_FACTORY_IMAGE_SIZE; + } + } + + return g_factoryImageList.libInfo[0].startAddr; +} + +/** + * @brief Set the idle address state in factory mode without saving it. + * @param addr Image addr + * @param state Free state + * @retval TARGET_LIB_OK + */ +static int32_t FreeFactoryImageAddrSetNoSave(uint32_t addr, bool state) +{ + uint32_t index; + index = (addr - TARGET_LIB_FACTORY_IMAGE_START) / TARGET_LIB_ONE_FACTORY_IMAGE_SIZE; + g_freeFactoryImageFlag[index] = state; + return TARGET_LIB_OK; +} + +/** + * @brief Set the idle address state in factory mode and saving it. + * @param addr Image addr + * @param state Free state + * @retval TARGET_LIB_OK + */ +static int32_t FreeFactoryImageAddrSet(uint32_t addr, bool state) +{ + FreeFactoryImageAddrSetNoSave(addr, state); + ConfigFactoryFreeImageFlagSave(g_freeFactoryImageFlag, sizeof(g_freeFactoryImageFlag)); + return TARGET_LIB_OK; +} + +/** + * @brief The factory mode image is released based on the index and is not saved. + * @param index Image index + * @retval FACTORY_STATUS_OK or FACTORY_STATUS_ERROR + */ +static int32_t FactoryImageFreeNosave(uint32_t index) +{ + uint32_t updataCnt; + uint32_t i; + errno_t rc = EOK; + + if (g_factoryImageList.count >= TARGET_LIB_FACTORY_IMAGE_MAX_NUM) { + return FACTORY_STATUS_ERROR; + } + /* Idle address flag configuration */ + FreeFactoryImageAddrSetNoSave(g_factoryImageList.libInfo[index].startAddr, true); + if (index < g_factoryImageList.count - 1) { + updataCnt = g_factoryImageList.count - index - 1; + for (i = 0; i < updataCnt; i++) { + g_factoryImageList.libInfo[index + i] = g_factoryImageList.libInfo[index + i + 1]; + g_factoryImageLoadCntList.list[index + i] = g_factoryImageLoadCntList.list[index + i + 1]; + } + } + rc = memset_s(&g_factoryImageList.libInfo[g_factoryImageList.count - 1], sizeof(TargetImageLibInfo), + 0, sizeof(TargetImageLibInfo)); + if (rc != EOK) { + return FACTORY_STATUS_ERROR; + } + g_factoryImageLoadCntList.list[g_factoryImageList.count - 1] = TARGET_LIB_LOAD_CNT_INVALIA; + g_factoryImageList.count--; + return FACTORY_STATUS_OK; +} + +/** + * @brief Factory Mode Module Initialization. + * @retval FACTORY_STATUS_OK + */ +int32_t FactoryInit(void) +{ + g_factoryFlag = ConfigFactoryFlagRead(); + ConfigFactoryImageListRead(&g_factoryImageList, sizeof(g_factoryImageList)); + if (g_factoryImageList.count > TARGET_LIB_FACTORY_IMAGE_MAX_NUM) { + g_factoryImageList.count = 0; + } + ConfigFactoryFreeImageFlagRead(g_freeFactoryImageFlag, sizeof(g_freeFactoryImageFlag)); + ConfigFactoryImageLoadCntRead(&g_factoryImageLoadCntList, + sizeof(g_factoryImageLoadCntList)); + return FACTORY_STATUS_OK; +} + +/** + * @brief Enter factory mode. + * @retval FACTORY_STATUS_OK + */ +int32_t FactoryModeEnter(void) +{ + g_factoryFlag = FACTORY_FLAG_IS_SET; + ConfigFactoryFlagSave(g_factoryFlag); + return FACTORY_STATUS_OK; +} + +/** + * @brief Exit factory mode. + * @retval FACTORY_STATUS_OK + */ +int32_t FactoryModeExit(void) +{ + g_factoryFlag = 0; + ConfigFactoryFlagSave(g_factoryFlag); + return FACTORY_STATUS_OK; +} + +/** + * @brief Obtains the factory mode status. + * @retval factory mode status + */ +uint32_t FactoryStatusGet(void) +{ + return g_factoryFlag; +} + +/** + * @brief Configuration for obtaining the CRC value in factory mode + * @param verifyStartAddr CRC check start address + * @param index Indicates the image index for CRC check + * @retval Node + */ +static void FactoryCrcGetConfig(uint32_t *verifyStartAddr, int32_t index) +{ + if (g_board_info.target_cfg) { + region_info_t *region = g_board_info.target_cfg->flash_regions; + for (; region->start != 0 || region->end != 0; ++region) { + if (g_factoryImageList.libInfo[index].info.version > 0) { + *verifyStartAddr = g_factoryImageList.libInfo[index].info.targetAddr; + } else { + *verifyStartAddr = region->start; + } + if (kRegionIsDefault == region->flags) { + break; + } + } + } +} + +/** + * @brief Obtains the CRC value and length based on the index. + * @param checkValue Crc check value + * @param checkLen Crc check len + * @param index Indicates the image index for CRC check + * @retval Node + */ +static void FactoryCrcCheckValueAndLenGet(uint32_t *checkValue, uint32_t *checkLen, int32_t index) +{ + uint32_t tempAddr; + + *checkValue = g_factoryImageList.libInfo[index].info.fileCrc32; + if (*checkValue == FACTORY_CRC_CHECK_SPE_VALUE) { + *checkLen = g_factoryImageList.libInfo[index].info.fileSize - 4; /* Subtract the last 4 bytes */ + Init(0, 0, 0); + tempAddr = g_factoryImageList.libInfo[index].startAddr + *checkLen; + if (FlashRead(tempAddr, 4, (uint8_t*)checkValue) != 0) { /* Read the last 4 bytes */ + UnInit(0); + return; + } + UnInit(0); + } else { + *checkLen = g_factoryImageList.libInfo[index].info.fileSize; + } +} + +/** + * @brief Check input var. + * @param status CRC check result + * @param index Indicates the image index for CRC check + * @retval CRC var check result + */ +static int32_t FactoryCrcVarCheck(FactoryCrcStatus *status, int32_t index) +{ + if (status == NULL || index >= TARGET_LIB_FACTORY_IMAGE_MAX_NUM || index < 0) { + return FACTORY_STATUS_ERROR; + } + return FACTORY_STATUS_OK; +} + +/** + * @brief CRC check target chip + * @param flash_intf Flash drive interface + * @param startAddr Check Start Address + * @param len Check length + * @retval CRC var check result + */ +static int32_t FactoryTargetCrcCheck(uint32_t startAddr, uint32_t len) +{ + int32_t clockLevel; + int32_t ret = USER_CRC_CHECK_NOT_CONNECT; + const flash_intf_t *currentIntf = NULL; + + currentIntf = flash_intf_target; + clockLevel = SwdJtagClockLevelGet(); + while (1) { + if (clockLevel <= SWD_JTAG_CLOCK_LEVEL_9) { + SwJtagClockLevelLevelSet(clockLevel); + clockLevel++; + } else { + break; + } + ret = CheckCrcFromFlash(currentIntf, startAddr, len); + if (ret == USER_CRC_CHECK_SUCCESS || ret == USER_CRC_CHECK_ERROR) { + return ret; + } + } + return ret; +} + +/** + * @brief Obtaining the Image CRC of the Target Board in Factory Mode + * @param status CRC check result + * @param index Indicates the image index for CRC check + * @retval CRC check result + */ +int32_t FactoryCrcget(FactoryCrcStatus *status, int32_t index) +{ + uint32_t verifyStartAddr = 0; + FactoryCrcStatus tempStatus; + uint32_t checkValue; + uint32_t checkLen; + int32_t algoIndex; + + if (FactoryCrcVarCheck(status, index) != FACTORY_STATUS_OK) { + return FACTORY_STATUS_ERROR; + } + tempStatus.results = USER_CRC_CHECK_FAIL; + *status = tempStatus; + + algoIndex = TargetLibAlgoIndexGetFormFlashInfo(g_factoryImageList.libInfo[index].info); + if (algoIndex < 0) { + tempStatus.results = USER_CRC_CHECK_NO_ALGO; + *status = tempStatus; + return FACTORY_STATUS_OK; + } + + if (TargetAlgoConfig(algoIndex) != TARGET_ALGO_PARSE_OK) { + return FACTORY_STATUS_ERROR; + } + + if (g_factoryImageList.libInfo[index].fileStatus == TARGET_LIB_FILE_STATUS_BAD) { + return FACTORY_STATUS_ERROR; + } + + FactoryCrcGetConfig(&verifyStartAddr, index); + FactoryCrcCheckValueAndLenGet(&checkValue, &checkLen, index); + + tempStatus.checkLen = checkLen; + UserCrcInit(0, checkValue); + tempStatus.preCrc = checkValue; + tempStatus.checkStartAddr = verifyStartAddr; + int32_t ret = FactoryTargetCrcCheck(verifyStartAddr, checkLen); + if (ret != USER_CRC_CHECK_SUCCESS) { + if (ret == USER_CRC_CHECK_ERROR) { + tempStatus.currentCrc = UserCurrentCrc32Get(); + UserCrcInit(0, g_factoryImageList.libInfo[index].info.fileCrc32); + if (CheckCrcFromFlash(flash_intf_iap_protected, g_factoryImageList.libInfo[index].startAddr, + g_factoryImageList.libInfo[index].info.fileSize) != USER_CRC_CHECK_SUCCESS) { + FactoryLibFileStatusChange(TARGET_LIB_TYPE_IMAGE, index, TARGET_LIB_FILE_STATUS_BAD); + ret = FACTORY_CRC_CHECK_RES_BAD_FILE; + } + } + tempStatus.results = ret; + } else { + tempStatus.results = USER_CRC_CHECK_SUCCESS; + tempStatus.currentCrc = checkValue; + } + *status = tempStatus; + return FACTORY_STATUS_OK; +} + +/** + * @brief Obtaining the Flash Algorithm List in Factory Mode + * @param handle Flash Algorithm List handle + * @retval FACTORY_STATUS_ERROR or FACTORY_STATUS_OK + */ +int32_t FactoryAlgoListGet(FactoryAlgoHandle *handle) +{ + if (handle == NULL) { + return FACTORY_STATUS_ERROR; + } + TargetLibAlgoListGet(handle); + return FACTORY_STATUS_OK; +} + +/** + * @brief Obtaining the Flash Algorithm List in Factory Mode and Performing CRC + * @param handle Flash Algorithm List handle + * @retval FACTORY_STATUS_ERROR or FACTORY_STATUS_OK + */ +int32_t FactoryAlgoListGetWithCrcCheck(FactoryAlgoHandle *handle) +{ + int32_t ret; + int32_t status = FactoryAlgoListGet(handle); + if (status != FACTORY_STATUS_OK) { + return status; + } + for (uint32_t i = 0; i < handle->count; i++) { + TargetAlgoLibInfo *libInfo = &handle->libInfo[i]; + UserCrcInit(0, libInfo->info.fileCrc32); + ret = CheckCrcFromFlash(flash_intf_iap_protected, libInfo->startAddr, libInfo->info.fileSize); + if (ret != USER_CRC_CHECK_SUCCESS) { + return FACTORY_STATUS_CRC_ERROR; + } + } + return FACTORY_STATUS_OK; +} + +/** + * @brief List of algorithms to be changed in factory mode + * @param info Flash information of the target chip + * @retval FACTORY_STATUS_OK + */ +int32_t FactoryAlgoChange(TargetFlashInfo info) +{ + TargetLibAlgoAdd(info); + return FACTORY_STATUS_OK; +} + +/** + * @brief Delete the flash algorithm file based on the index + * @param index Indicates the index of the flash algorithm file + * @retval FACTORY_STATUS_OK + */ +int32_t FactoryAlgoFree(int32_t index) +{ + TargetLibAlgoDelete(index); + return FACTORY_STATUS_OK; +} + +/** + * @brief Delete all flash algorithm files in factory mode. + * @retval FACTORY_STATUS_OK + */ +int32_t FactoryAlgoFreeAll(void) +{ + TargetLibAlgoDeleteAll(); + return FACTORY_STATUS_OK; +} + +/** + * @brief Obtaining the File List in Factory Mode + * @param handle Factory image Information handle + * @retval FACTORY_STATUS_OK or FACTORY_STATUS_ERROR + */ +int32_t FactoryImageListGet(FactoryImageHandle *handle) +{ + if (handle == NULL) { + return FACTORY_STATUS_ERROR; + } + *handle = g_factoryImageList; + return FACTORY_STATUS_OK; +} + +/** + * @brief Obtaining and Verifying the File List in Factory Mode + * @param handle Factory image Information handle + * @retval Obtain the result status + */ +int32_t FactoryImageListGetWithCrcCheck(FactoryImageHandle *handle) +{ + int32_t ret; + if (FactoryImageListGet(handle) != FACTORY_STATUS_OK) { + return FACTORY_STATUS_ERROR; + } + + for (uint32_t i = 0; i < handle->count; i++) { + TargetImageLibInfo *libInfo = &handle->libInfo[i]; + UserCrcInit(0, libInfo->info.fileCrc32); + ret = CheckCrcFromFlash(flash_intf_iap_protected, libInfo->startAddr, libInfo->info.fileSize); + if (ret != USER_CRC_CHECK_SUCCESS) { + return FACTORY_STATUS_CRC_ERROR; + } + } + return USER_CRC_CHECK_SUCCESS; +} + +/** + * @brief Concatenate the image name in factory mode. + * @param info Flash chip information + * @param tempName Name after splicing + * @param nameLen Name len + * @retval Refreshing succeeded or failed + */ +static int32_t FactorySplicingImageName(TargetFlashInfo info, char *tempName, uint32_t nameLen) +{ + errno_t rc = EOK; + rc = strcat_s(tempName, nameLen, "("); /* Splice Brackets */ + if (rc != EOK) { + return FACTORY_STATUS_ERROR; /* Error check */ + } + switch (info.vendorID) { /* Splicing Manufacturer */ + case TARGET_VENDOR_HM: /* vendor open harmony */ + rc = strcat_s(tempName, nameLen, g_vendorHMModelName[info.modelID]); + break; + case TARGET_VENDOR_AUCU: + rc = strcat_s(tempName, nameLen, g_aucuModelName[info.modelID]); + break; + case TARGET_VENDOR_HISILICON: + rc = strcat_s(tempName, nameLen, g_hiModelName[info.modelID]); + break; + default: + break; + } + if (rc != EOK) { + return FACTORY_STATUS_ERROR; /* Error check */ + } + rc = strcat_s(tempName, nameLen, g_regionInfo[info.regioninfo & 0xFF]); + if (rc != EOK) { + return FACTORY_STATUS_ERROR; + } + rc = strcat_s(tempName, nameLen, ")"); /* Splice Brackets */ + if (rc != EOK) { + return FACTORY_STATUS_ERROR; + } + return FACTORY_STATUS_OK; +} + +/** + * @brief Refreshing the image list in factory mode. + * @param info Flash chip information + * @param imageName target image name + * @param nameLen target image name len + * @param index target image index + * @retval Refreshing succeeded or failed + */ +static int32_t FactoryImageRefresh(TargetFlashInfo info, const char *imageName, uint32_t nameLen, int32_t index) +{ + errno_t rc = EOK; + g_factoryImageList.libInfo[index].fileStatus = TARGET_LIB_FILE_STATUS_BAD; + g_factoryImageList.libInfo[index].info = info; + rc = memset_s(g_factoryImageList.libInfo[index].name, TARGET_LIB_IMAGE_NAME_MAX_LEN, + 0, sizeof(g_factoryImageList.libInfo[index].name)); + if (rc != EOK) { + return FACTORY_STATUS_ERROR; + } + rc = memcpy_s(g_factoryImageList.libInfo[index].name, TARGET_LIB_IMAGE_NAME_MAX_LEN, imageName, nameLen); + if (rc != EOK) { + return FACTORY_STATUS_ERROR; + } + g_factoryImageList.libInfo[index].nameLen = nameLen; + g_currentFactoryImageIndex = index; + g_factoryImageLoadCntList.list[index] = 0; + TargetFactoryImageUpdateList(); + ConfigFactoryImageListSave(&g_factoryImageList, sizeof(g_factoryImageList)); + ConfigFactoryImageLoadCntSave(&g_factoryImageLoadCntList, sizeof(g_factoryImageLoadCntList)); + return FACTORY_STATUS_OK; +} + +/** + * @brief Factory Mode Duplicate Address Handling. + * @param info Flash chip information + * @retval None + */ +static void FactoryImageDuplicateAddressHandle(TargetFlashInfo info) +{ + uint32_t freeIndex = 0; + + while (freeIndex < g_factoryImageList.count) { + if (((info.targetAddr <= g_factoryImageList.libInfo[freeIndex].info.targetAddr) && + ((info.targetAddr + info.fileSize) > g_factoryImageList.libInfo[freeIndex].info.targetAddr)) || + ((g_factoryImageList.libInfo[freeIndex].info.targetAddr < info.targetAddr) && + ((g_factoryImageList.libInfo[freeIndex].info.targetAddr + + g_factoryImageList.libInfo[freeIndex].info.fileSize) > info.targetAddr))) { + FactoryImageFreeNosave(freeIndex); + } else { + freeIndex++; + } + } +} + +/** + * @brief Refresh the image list in factory mode and save it. + * @param info Flash chip information + * @param imageName target image name + * @param nameLen target image name len + * @retval Refreshing succeeded or failed + */ +int32_t FactoryImageChange(TargetFlashInfo info, uint8_t *imageName, uint32_t nameLen) +{ + int32_t index = -1; + uint32_t templen = 0; + errno_t rc = EOK; + + char tempName[TARGET_LIB_IMAGE_NAME_MAX_LEN]; + + if (imageName == NULL || nameLen > TARGET_LIB_IMAGE_IN_NAME_MAX_LEN) { + return TARGET_LIB_ERROR; + } + + FactoryImageDuplicateAddressHandle(info); + ConfigFactoryFreeImageFlagSave(g_freeFactoryImageFlag, sizeof(g_freeFactoryImageFlag)); + ConfigFactoryImageListSave(&g_factoryImageList, sizeof(g_factoryImageList)); + memset_s(tempName, TARGET_LIB_IMAGE_NAME_MAX_LEN, 0, sizeof(tempName)); + rc = memcpy_s(tempName, TARGET_LIB_IMAGE_NAME_MAX_LEN, imageName, nameLen); + if (rc != EOK) { + return TARGET_LIB_ERROR; + } + FactorySplicingImageName(info, tempName, TARGET_LIB_IMAGE_NAME_MAX_LEN); + templen = strlen(tempName); + + for (int i = 0; i < g_factoryImageList.count; i++) { + if (g_factoryImageList.libInfo[i].nameLen != templen) { + continue; + } + + if (strncmp(tempName, g_factoryImageList.libInfo[i].name, templen) == 0) { + index = i; + break; + } + } + + if (index == -1) { + if (g_factoryImageList.count == TARGET_LIB_IMAGE_MAX_NUM) { + index = 0; + } else { + index = g_factoryImageList.count; + g_factoryImageList.libInfo[index].startAddr = FreeFactoryImageAddrGet(); + g_factoryImageList.count++; + } + } + FactoryImageRefresh(info, tempName, templen, index); + return FACTORY_STATUS_OK; +} + +/** + * @brief In factory mode, the image file is deleted based on the index. + * @param index Indicates the image index. + * @retval Refreshing succeeded or failed + */ +int32_t FactoryImageFree(int32_t index) +{ + DapLinkStatus status; + int32_t updataCnt; + uint32_t i; + errno_t rc = EOK; + + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_RUNNING; + DapLinkStatusSet(&status); + if (g_factoryImageList.count >= TARGET_LIB_FACTORY_IMAGE_MAX_NUM) { + return FACTORY_STATUS_ERROR; + } + FreeFactoryImageAddrSet(g_factoryImageList.libInfo[index].startAddr, true); + if (index < g_factoryImageList.count - 1) { + updataCnt = g_factoryImageList.count - index - 1; + for (i = 0; i < updataCnt; i++) { + g_factoryImageLoadCntList.list[index + i] = g_factoryImageLoadCntList.list[index + i + 1]; + g_factoryImageList.libInfo[index + i] = g_factoryImageList.libInfo[index + i + 1]; + } + } + rc = memset_s(&g_factoryImageList.libInfo[g_factoryImageList.count - 1], sizeof(TargetImageLibInfo), + 0, sizeof(TargetImageLibInfo)); + if (rc != EOK) { + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_FAIL; + DapLinkStatusSet(&status); + return FACTORY_STATUS_ERROR; + } + g_factoryImageLoadCntList.list[g_factoryImageList.count - 1] = TARGET_LIB_LOAD_CNT_INVALIA; + g_factoryImageList.count--; + ConfigFactoryImageListSave(&g_factoryImageList, sizeof(g_factoryImageList)); + ConfigFactoryImageLoadCntSave(&g_factoryImageLoadCntList, sizeof(g_factoryImageLoadCntList)); + + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_SUCCESS; + DapLinkStatusSet(&status); + return FACTORY_STATUS_OK; +} + +/** + * @brief Delete all image files in factory mode. + * @retval Refreshing succeeded or failed + */ +int32_t FactoryImageFreeAll(void) +{ + uint32_t i; + errno_t rc = EOK; + + DapLinkStatus status; + + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_RUNNING; + DapLinkStatusSet(&status); + + for (i = 0; i < TARGET_LIB_FACTORY_IMAGE_MAX_NUM; i++) { + g_freeFactoryImageFlag[i] = true; + rc = memset_s(&g_factoryImageList.libInfo[i], sizeof(g_factoryImageList.libInfo[i]), + 0, sizeof(g_factoryImageList.libInfo[i])); + if (rc != EOK) { + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_FAIL; + DapLinkStatusSet(&status); + return FACTORY_STATUS_ERROR; + } + g_factoryImageLoadCntList.list[i] = TARGET_LIB_LOAD_CNT_INVALIA; + } + ConfigFactoryFreeImageFlagSave(g_freeFactoryImageFlag, sizeof(g_freeFactoryImageFlag)); + g_factoryImageList.count = 0; + ConfigFactoryImageListSave(&g_factoryImageList, sizeof(g_factoryImageList)); + ConfigFactoryImageLoadCntSave(&g_factoryImageLoadCntList, sizeof(g_factoryImageLoadCntList)); + + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_SUCCESS; + DapLinkStatusSet(&status); + return FACTORY_STATUS_OK; +} + +/** + * @brief Modifying the File Status Based on the Index in Factory Mode. + * @param type File Type + * @param index File index + * @param status Status of the file to be modified + * @retval Refreshing succeeded or failed + */ +int32_t FactoryLibFileStatusChange(TargetLibType type, int32_t index, uint32_t status) +{ + if (index >= TARGET_LIB_FACTORY_IMAGE_MAX_NUM || index < 0) { + return FACTORY_STATUS_ERROR; + } + + if (type == TARGET_LIB_TYPE_IMAGE) { + g_factoryImageList.libInfo[index].fileStatus = status; + ConfigFactoryImageListSave(&g_factoryImageList, sizeof(g_factoryImageList)); + } else { + return FACTORY_STATUS_ERROR; + } + return FACTORY_STATUS_OK; +} + +/** + * @brief Obtaining the Start Address of the Image File in Factory Mode. + * @param type File Type + * @retval image file start address + */ +uint32_t FactoryLibStartAddrGet(TargetLibType type) +{ + if (type == TARGET_LIB_TYPE_IMAGE) { + return g_factoryImageList.libInfo[g_currentFactoryImageIndex].startAddr; + } else { + return 0; + } +} + +/** + * @brief Obtaining the File Index Based on the Start Address in Factory Mode. + * @param startAddr image start address + * @retval image file index + */ +int32_t FactoryLibImageIndexGetFormStartAddr(uint32_t startAddr) +{ + int32_t i; + int32_t index = -1; + + for (i = 0; i < g_factoryImageList.count; i++) { + if (startAddr == g_factoryImageList.libInfo[i].startAddr) { + index = i; + break; + } + } + return index; +} + +/** + * @brief Obtain the image file that is being processed in factory mode. + * @param info Image file information + * @retval Failure or Success Result + */ +int32_t FactoryLibCurrentImageGet(TargetImageLibInfo *info) +{ + if (info == NULL) { + return TARGET_LIB_ERROR; + } + *info = g_factoryImageList.libInfo[g_currentFactoryImageIndex]; + return TARGET_LIB_OK; +} + +/** + * @brief Check whether there is a matching algorithm based on the image file information. + * @param info Image file information + * @retval true or false + */ +static bool HasMatchAlgo(TargetFlashInfo info) +{ + TargetAlgoHandle tmpAlgoList; + TargetLibAlgoListGet(&tmpAlgoList); + for (int i = 0; i < tmpAlgoList.count; i++) { + if (info.regioninfo != tmpAlgoList.libInfo[i].info.regioninfo) { + continue; + } + + if (info.vendorID != tmpAlgoList.libInfo[i].info.vendorID) { + continue; + } + + if (info.modelID != tmpAlgoList.libInfo[i].info.modelID) { + continue; + } + + if (info.flashID != tmpAlgoList.libInfo[i].info.flashID) { + continue; + } + return true; + } + return false; +} + +/** + * @brief The stitching algorithm does not match the file name in factory mode. + * @param list List of files whose algorithms do not match + * @param cnt Indicates the number of files whose algorithms do not match. + * @param index File index with algorithm mismatch + * @retval Failure or Success Result + */ +static int32_t FactorySplicingAlgoName(FactoryAlgoNoMatchList *list, uint32_t cnt, uint32_t index) +{ + errno_t rc = EOK; + switch (g_factoryImageList.libInfo[index].info.vendorID) { + case TARGET_VENDOR_HISILICON: + rc = strcat_s(list->algoInfo[cnt].name, FACTORY_ALGO_NAME_LEN, + g_hiModelName[g_factoryImageList.libInfo[index].info.modelID]); + break; + case TARGET_VENDOR_ST: + rc = strcat_s(list->algoInfo[cnt].name, FACTORY_ALGO_NAME_LEN, + g_stModelName[g_factoryImageList.libInfo[index].info.modelID]); + break; + case TARGET_VENDOR_TI: + rc = strcat_s(list->algoInfo[cnt].name, FACTORY_ALGO_NAME_LEN, + g_tiModelName[g_factoryImageList.libInfo[index].info.modelID]); + break; + case TARGET_VENDOR_RENESAS: + rc = strcat_s(list->algoInfo[cnt].name, FACTORY_ALGO_NAME_LEN, + g_renesasModelName[g_factoryImageList.libInfo[index].info.modelID]); + break; + case TARGET_VENDOR_HM: + rc = strcat_s(list->algoInfo[cnt].name, FACTORY_ALGO_NAME_LEN, + g_vendorHMModelName[g_factoryImageList.libInfo[index].info.modelID]); + break; + case TARGET_VENDOR_AUCU: + rc = strcat_s(list->algoInfo[cnt].name, FACTORY_ALGO_NAME_LEN, + g_aucuModelName[g_factoryImageList.libInfo[index].info.modelID]); + break; + default: + break; + } + if (rc != EOK) { + return FACTORY_STATUS_ERROR; + } + rc = strcat_s(list->algoInfo[cnt].name, FACTORY_ALGO_NAME_LEN, + g_regionInfo[g_factoryImageList.libInfo[index].info.regioninfo & 0xFF]); + if (rc != EOK) { + return FACTORY_STATUS_ERROR; + } + list->algoInfo[cnt].nameLen = strlen(list->algoInfo[cnt].name); + return FACTORY_STATUS_OK; +} + +/** + * @brief Check the algorithm matching in factory mode. + * @param list List of files whose algorithms do not match + * @retval true or false + */ +bool FactoryAlgoMatchCheck(FactoryAlgoNoMatchList *list) +{ + FactoryAlgoNoMatchList tempList; + uint32_t tempCnt = 0; + uint32_t j; + errno_t rc = EOK; + + if (list == NULL) { + return false; + } + rc = memset_s(&tempList, sizeof(tempList), 0, sizeof(tempList)); + if (rc != EOK) { + return false; + } + for (uint32_t i = 0; i < g_factoryImageList.count; i++) { + if (HasMatchAlgo(g_factoryImageList.libInfo[i].info)) { + continue; + } + FactorySplicingAlgoName(&tempList, tempCnt, i); + for (j = 0; j < tempCnt;) { + if (strcmp(tempList.algoInfo[j].name, tempList.algoInfo[tempCnt].name) == 0) { + rc = memset_s(&tempList.algoInfo[tempCnt].name, FACTORY_ALGO_NAME_LEN, + 0, tempList.algoInfo[tempCnt].nameLen); + break; + } + j++; + } + if (rc != EOK) { + return false; + } + if (j >= tempCnt) { + tempCnt++; + } + } + + if (tempCnt > 0) { + tempList.count = tempCnt; + *list = tempList; + return true; + } + return false; +} + +/** + * @brief Check the number of image burning times in factory mode. + * @param list Factory restricted image list + * @retval true or false + */ +bool FactoryImageLoadCntCheck(FactoryRestrictedImageList *list) +{ + FactoryRestrictedImageList tempList; + uint32_t tempCnt = 0; + errno_t rc = EOK; + + if (list == NULL) { + return false; + } + + rc = memset_s(&tempList, sizeof(tempList), 0, sizeof(tempList)); + if (rc != EOK) { + return false; + } + for (int i = 0; i < g_factoryImageList.count; i++) { + if (g_factoryImageLoadCntList.list[i] >= g_factoryImageList.libInfo[i].info.maxLoads && + g_factoryImageList.libInfo[i].info.maxLoads != 0) { + rc = memcpy_s(tempList.imageInfo[tempCnt].name, FACTORY_IMAGE_NAME_LEN, + g_factoryImageList.libInfo[i].name, + g_factoryImageList.libInfo[i].nameLen); + if (rc != EOK) { + return false; + } + tempList.imageInfo[tempCnt].nameLen = g_factoryImageList.libInfo[i].nameLen; + tempCnt++; + } + } + + if (tempCnt > 0) { + tempList.count = tempCnt; + *list = tempList; + return true; + } else { + return false; + } +} + +/** + * @brief Accumulated number of image downloads in factory mode. + * @param index image index + * @retval Success or Failure Result + */ +int32_t FactoryImageLoadCntAdd(uint32_t index) +{ + if (index >= TARGET_LIB_FACTORY_IMAGE_MAX_NUM) { + return TARGET_LIB_ERROR; + } + + g_factoryImageLoadCntList.list[index]++; + ConfigFactoryImageLoadCntSave(&g_factoryImageLoadCntList, sizeof(g_factoryImageLoadCntList)); + return FACTORY_STATUS_OK; +} + +/** + * @brief Obtaining the Number of Burning Times of an Image File in Factory Mode. + * @param index image index + * @retval Number of burnt images + */ +uint32_t FactoryImageLoadCntGet(uint32_t index) +{ + return g_factoryImageLoadCntList.list[index]; +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/factory_manager.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/factory_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..fcf4811705da76431ccd22baed90b0420fa5407a --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/factory_manager.h @@ -0,0 +1,115 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file factory_manager.h + * @author MCU Driver Team + * @brief factory manager driver. + */ +#ifndef FACTORY_MANAGER_H +#define FACTORY_MANAGER_H +#include "target_lib_manager.h" + +#define FACTORY_CRC_CHECK_SPE_VALUE 0x2144DF1C + +#define FACTORY_FLAG_IS_SET 0xFAFBF0AF +#define FACTORY_DEFAULT_COUNT 1 + +#define FACTORY_ALGO_NAME_LEN 48 +#define FACTORY_IMAGE_NAME_LEN 64 + +#define FACTORY_STATUS_OK 0 +#define FACTORY_STATUS_ERROR (-1) +#define FACTORY_STATUS_CRC_ERROR (-2) +#define FACTORY_STATUS_ALGO_NO_MATCH (-3) + +#define FACTORY_CRC_CHECK_RES_SUCCESS USER_CRC_CHECK_SUCCESS +#define FACTORY_CRC_CHECK_RES_FAIL USER_CRC_CHECK_FAIL +#define FACTORY_CRC_CHECK_RES_NOT_CONNECT USER_CRC_CHECK_NOT_CONNECT +#define FACTORY_CRC_CHECK_RES_ERROR USER_CRC_CHECK_ERROR +#define FACTORY_CRC_CHECK_RES_READ_FAIL USER_CRC_CHECK_READ_FAIL +#define FACTORY_CRC_CHECK_RES_BAD_FILE USER_CRC_CHECK_BAD_FILE +#define FACTORY_CRC_CHECK_RES_ALGO_ERROR USER_CRC_CHECK_ALGO_ERROR +#define FACTORY_CRC_CHECK_RES_NO_ALGO USER_CRC_CHECK_NO_ALGO + +typedef struct { + uint32_t preCrc; + uint32_t currentCrc; + int32_t results; + uint32_t checkLen; + uint32_t checkStartAddr; +} FactoryCrcStatus; + +typedef TargetAlgoHandle FactoryAlgoHandle; + +typedef struct { + int32_t count; + TargetImageLibInfo libInfo[TARGET_LIB_FACTORY_IMAGE_MAX_NUM]; +} FactoryImageHandle; + +typedef struct { + uint32_t nameLen; + char name[FACTORY_ALGO_NAME_LEN]; +} FactoryAlgoInfo; + +typedef struct { + uint32_t count; + FactoryAlgoInfo algoInfo[TARGET_LIB_FACTORY_ALGO_MAX_NUM]; +} FactoryAlgoNoMatchList; + +typedef struct { + uint32_t nameLen; + char name[FACTORY_IMAGE_NAME_LEN]; +} FactoryImageInfo; + +typedef struct { + uint32_t count; + FactoryImageInfo imageInfo[TARGET_LIB_FACTORY_IMAGE_MAX_NUM]; +} FactoryRestrictedImageList; + +typedef struct { + uint32_t list[TARGET_LIB_FACTORY_IMAGE_MAX_NUM]; +} FactoryImageLoadCntList; + +int32_t FactoryInit(void); +int32_t FactoryModeEnter(void); +int32_t FactoryModeExit(void); +uint32_t FactoryStatusGet(void); +int32_t FactoryCrcget(FactoryCrcStatus *status, int32_t index); + +int32_t FactoryAlgoListGet(FactoryAlgoHandle *handle); +int32_t FactoryAlgoListGetWithCrcCheck(FactoryAlgoHandle *handle); +int32_t FactoryAlgoChange(TargetFlashInfo info); +int32_t FactoryAlgoFree(int32_t index); +int32_t FactoryAlgoFreeAll(void); + +int32_t FactoryImageListGet(FactoryImageHandle *handle); +int32_t FactoryImageListGetWithCrcCheck(FactoryImageHandle *handle); +int32_t FactoryImageChange(TargetFlashInfo info, uint8_t *imageName, uint32_t nameLen); +int32_t FactoryImageFree(int32_t index); +int32_t FactoryImageFreeAll(void); + +int32_t FactoryLibFileStatusChange(TargetLibType type, int32_t index, uint32_t status); +uint32_t FactoryLibStartAddrGet(TargetLibType type); +int32_t FactoryLibCurrentImageGet(TargetImageLibInfo *info); +int32_t FactoryLibImageIndexGetFormStartAddr(uint32_t startAddr); + +bool FactoryAlgoMatchCheck(FactoryAlgoNoMatchList *list); + +bool FactoryImageLoadCntCheck(FactoryRestrictedImageList *list); +int32_t FactoryImageLoadCntAdd(uint32_t index); +uint32_t FactoryImageLoadCntGet(uint32_t index); +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_download.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_download.c new file mode 100644 index 0000000000000000000000000000000000000000..caa5e37d315291478baaf89937669508b2016d58 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_download.c @@ -0,0 +1,782 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file offline_download.c + * @author MCU Driver Team + * @brief offline download driver. + */ +#include +#include "securec.h" +#include "target_config.h" +#include "flash_manager.h" +#include "FlashPrg.h" +#include "target_board.h" +#include "target_lib_manager.h" +#include "target_algo_parse.h" +#include "status.h" +#include "swd_jtag_config.h" +#include "factory_manager.h" +#include "user_crc.h" +#include "config_storage_update.h" +#include "offline_download.h" + +#define DOWNLOAD_BUFF_SIZE 1024 +#define OFFLINE_ERASE_TYR_TIME 3 + +/* offline state */ +#define OFFLINE_DOWNLOAD_STATE_IDLE 0 +#define OFFLINE_DOWNLOAD_STATE_OPEN 1 +#define OFFLINE_DOWNLOAD_STATE_SELECT_ALGO 2 +#define OFFLINE_DOWNLOAD_STATE_LOADING 3 +#define OFFLINE_DOWNLOAD_VERIFI 4 +#define OFFLINE_DOWNLOAD_STATE_DONE 5 +#define OFFLINE_DOWNLOAD_STATE_ERROR 6 + +typedef struct { + TargetAlgoLibInfo currentLibAlgo; + TargetImageLibInfo currentLibImage; + int32_t currentImageIndex; + uint32_t currentDownloadAdrr; + uint32_t currentDataAdrr; + uint32_t currentDownloadDataEndAddr; + uint32_t currentDownloadSize; + uint32_t currentFactoryFileCnt; +} OfflineDownloadHandle; + +static OfflineDownloadHandle g_offlineDownloadHandle; +volatile static int32_t g_offlineDownloadState; +volatile static bool g_downloadStartFlag; +volatile static bool g_loadingInitialized; +volatile static OfflineDownLoadDisplayState g_offlineDownloadDisplayState; +static uint8_t g_downloadBuf[DOWNLOAD_BUFF_SIZE]; + +/** + * @brief Gets the smaller of two values. + * @param a Input value a + * @param b Input value b + * @retval smaller of two values + */ +static uint32_t Min(uint32_t a, uint32_t b) +{ + return a < b ? a : b; +} + +/** + * @brief Idle processing function. + * @retval None + */ +static void IdleHandler(void) +{ + if (g_downloadStartFlag) { + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_OPEN; + g_offlineDownloadHandle.currentFactoryFileCnt = 0; + } +} + +/** + * @brief Initialization parameter configuration. + * @retval None + */ +static void OpenParameterInit(void) +{ + g_offlineDownloadHandle.currentDataAdrr = 0; + g_offlineDownloadHandle.currentDownloadAdrr = 0; + g_offlineDownloadHandle.currentDownloadSize = 0; + g_loadingInitialized = false; +} + +/** + * @brief Open processing function. + * @retval None + */ +static void OpenHandler(void) +{ + errno_t rc = EOK; + DapLinkStatus status; + uint32_t tempCnt; + FactoryImageHandle tempFactoryImageList; + /* Initialize global parameters. */ + memset_s(g_downloadBuf, sizeof(g_downloadBuf), 0xFF, sizeof(g_downloadBuf)); + + OpenParameterInit(); + /* Check whether the factory mode is used. Perform different processing in factory mode and normal mode. */ + if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { + FactoryImageListGet(&tempFactoryImageList); + /* Check whether the number of download times exceeds the limit. */ + if (tempFactoryImageList.count == 0 || + tempFactoryImageList.count > TARGET_LIB_FACTORY_IMAGE_MAX_NUM) { + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_ERROR; + return; + } + /* In factory mode, firmware is downloaded in the image list sequence. All images stored in factory + mode can be downloaded in one-click mode. */ + if (g_offlineDownloadHandle.currentFactoryFileCnt < tempFactoryImageList.count) { + g_offlineDownloadHandle.currentLibImage = + tempFactoryImageList.libInfo[g_offlineDownloadHandle.currentFactoryFileCnt]; + g_offlineDownloadHandle.currentFactoryFileCnt++; + } + } else { + /* Obtains the information about the image to be downloaded. */ + int ret = TargetLibCurrentImageGet(&g_offlineDownloadHandle.currentLibImage, + &g_offlineDownloadHandle.currentImageIndex); + if (ret != TARGET_LIB_OK) { + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_ERROR; + return; + } + tempCnt = TargetImageLoadCntGet(g_offlineDownloadHandle.currentImageIndex); + /* Check whether the number of download times exceeds the limit. */ + if (tempCnt >= g_offlineDownloadHandle.currentLibImage.info.maxLoads && + g_offlineDownloadHandle.currentLibImage.info.maxLoads != 0) { + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGREADE_MAX_LOAD_ERROR; + DapLinkStatusSet(&status); + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_ERROR; + return; + } + } + /* Check whether the file is damaged. */ + if (g_offlineDownloadHandle.currentLibImage.fileStatus == TARGET_LIB_FILE_STATUS_BAD) { + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_IMAGE_ERROR; + DapLinkStatusSet(&status); + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_ERROR; + return; + } + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_SELECT_ALGO; + /* Turn on On-Demand Erase Configuration */ + flash_manager_set_page_erase(true); +} + +/** + * @brief Select algo processing function. + * @retval None + */ +static void SelectAlgoHandler(void) +{ + int32_t index; + DapLinkStatus status; + /* Obtains the index of the currently selected algorithm. */ + index = TargetLibAlgoIndexGetFormFlashInfo(g_offlineDownloadHandle.currentLibImage.info); + if (index < 0) { + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_ERROR; + g_offlineDownloadDisplayState = OFFLINE_DOWNLOAD_DISPLAY_SELECT_ALGO_FAIL; + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_GET_ALGO_FAIL; + DapLinkStatusSet(&status); + return; + } + /* Flash burning algorithm configuration */ + if (TargetAlgoConfig(index) != TARGET_ALGO_PARSE_OK) { + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_ERROR; + g_offlineDownloadDisplayState = OFFLINE_DOWNLOAD_DISPLAY_SELECT_ALGO_FAIL; + + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_GET_ALGO_FAIL; + DapLinkStatusSet(&status); + return; + } + + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_LOADING; +} + +/** + * @brief Download Processing Initialization. + * @retval true or false + */ +static bool LoadingHandlerInit(void) +{ + DapLinkStatus status; + int32_t clockLevel; + const flash_intf_t *currentIntf = NULL; + + g_offlineDownloadDisplayState = OFFLINE_DOWNLOAD_DISPLAY_LOADLIG; + if (g_board_info.target_cfg) { + region_info_t *region = g_board_info.target_cfg->flash_regions; + for (; region->start != 0 || region->end != 0; ++region) { + /* Version 1 and later versions add the burning start address + of the target board to the file header. */ + if (g_offlineDownloadHandle.currentLibImage.info.version > 0) { + g_offlineDownloadHandle.currentDownloadAdrr = \ + g_offlineDownloadHandle.currentLibImage.info.targetAddr; + } else { + g_offlineDownloadHandle.currentDownloadAdrr = region->start; + } + + if (kRegionIsDefault == region->flags) { + break; + } + } + /* Configure the current flash operation algorithm. */ + currentIntf = flash_intf_target; + } + /* Connect and initialize the target chip. */ + if (flash_manager_init(currentIntf) != ERROR_SUCCESS) { + clockLevel = SwdJtagClockLevelGet(); + /* Speed Down Retry */ + if (clockLevel < SWD_JTAG_CLOCK_LEVEL_9) { + clockLevel++; + SwJtagClockLevelLevelSet(clockLevel); + flash_manager_uninit(); + } else { + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_ERROR; + g_offlineDownloadDisplayState = OFFLINE_DOWNLOAD_DISPLAY_LOAD_FAIL; + + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_TARGET_CONNECT_FAIL; + DapLinkStatusSet(&status); + } + return false; + } + /* Initialize the flash memory for storing firmware on the target chip and configure the + burning start address and end address of the target chip. */ + Init(0, 0, 0); + g_offlineDownloadHandle.currentDataAdrr = g_offlineDownloadHandle.currentLibImage.startAddr; + g_offlineDownloadHandle.currentDownloadDataEndAddr = g_offlineDownloadHandle.currentLibImage.startAddr + + g_offlineDownloadHandle.currentLibImage.info.fileSize; + g_loadingInitialized = true; + return true; +} + +/** + * @brief Speed Down Retry. + * @retval None + */ +static void LoadingSpeedDownRerty(int32_t clockLevel) +{ + DapLinkStatus status; + int32_t level = clockLevel + 1; /* Reduce the rate by 1 level. */ + if (clockLevel < SWD_JTAG_CLOCK_LEVEL_9) { + SwJtagClockLevelLevelSet(level); + flash_manager_uninit(); + UnInit(0); + g_loadingInitialized = false; + } else { + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_ERROR; + g_offlineDownloadDisplayState = OFFLINE_DOWNLOAD_DISPLAY_LOAD_FAIL; + + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_WRITE_FAIL; + DapLinkStatusSet(&status); + } +} + +/** + * @brief Download Processing Function. + * @retval None + */ +static void LoadingHandler(void) +{ + DapLinkStatus status; + int32_t clockLevel; + errno_t rc = EOK; + if ((g_offlineDownloadHandle.currentLibImage.info.regioninfo & 0xFFFF0000) == TARGET_LIB_SEC_REGION) { + SysSoftResetFlagSet(false); + } + if (!g_loadingInitialized) { + /* Download Initial Configuration */ + if (!LoadingHandlerInit()) { + return; + } + } else { + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_WRITE_RUNNING; + DapLinkStatusSet(&status); + rc = memset_s(g_downloadBuf, sizeof(g_downloadBuf), 0xFF, sizeof(g_downloadBuf)); + if (rc != EOK) { + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_ERROR; + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_GET_IMAGE_FAIL; + DapLinkStatusSet(&status); + return; + } + /* Configure the current download size. */ + g_offlineDownloadHandle.currentDownloadSize = Min(sizeof(g_downloadBuf), + (g_offlineDownloadHandle.currentDownloadDataEndAddr - + g_offlineDownloadHandle.currentDataAdrr)); + /* Read the firmware of the target chip from the flash memory. */ + if (FlashRead(g_offlineDownloadHandle.currentDataAdrr, + g_offlineDownloadHandle.currentDownloadSize, g_downloadBuf) != 0) { + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_ERROR; + g_offlineDownloadDisplayState = OFFLINE_DOWNLOAD_DISPLAY_LOAD_FAIL; + + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_GET_IMAGE_FAIL; + DapLinkStatusSet(&status); + return; + } + /* Burn the firmware of the target chip. */ + if (flash_manager_data(g_offlineDownloadHandle.currentDownloadAdrr, g_downloadBuf, + g_offlineDownloadHandle.currentDownloadSize) != ERROR_SUCCESS) { + clockLevel = SwdJtagClockLevelGet(); + /* Burning failed. Reduce the speed and try again. */ + LoadingSpeedDownRerty(clockLevel); + return; + } + /* Segmentation processing */ + g_offlineDownloadHandle.currentDataAdrr += g_offlineDownloadHandle.currentDownloadSize; + g_offlineDownloadHandle.currentDownloadAdrr += g_offlineDownloadHandle.currentDownloadSize; + if (g_offlineDownloadHandle.currentDataAdrr >= g_offlineDownloadHandle.currentDownloadDataEndAddr) { + /* After the download is complete, enter the verification phase. */ + flash_manager_uninit(); + g_offlineDownloadState = OFFLINE_DOWNLOAD_VERIFI; + } + } +} + +/** + * @brief Check the source image file. + * @retval true or false + */ +static bool CheckSoureImage(void) +{ + int32_t currentIndex; + DapLinkStatus status; + /* Initial configuration of CRC check processing */ + UserCrcInit(0, g_offlineDownloadHandle.currentLibImage.info.fileCrc32); + /* Check the CRC value of the source file to determine whether the source file is damaged. */ + if (CheckCrcFromFlash(flash_intf_iap_protected,\ + g_offlineDownloadHandle.currentLibImage.startAddr,\ + g_offlineDownloadHandle.currentLibImage.info.fileSize) !=USER_CRC_CHECK_SUCCESS) { + if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { + currentIndex = \ + FactoryLibImageIndexGetFormStartAddr(g_offlineDownloadHandle.currentLibImage.startAddr); + if (currentIndex < 0) { + return false; + } + /* Flag corrupted file */ + FactoryLibFileStatusChange(TARGET_LIB_TYPE_IMAGE, currentIndex, TARGET_LIB_FILE_STATUS_BAD); + } else { + currentIndex = \ + TargetLibImageIndexGetFormStartAddr(g_offlineDownloadHandle.currentLibImage.startAddr); + if (currentIndex < 0) { + return false; + } + /* Flag corrupted file */ + TargetLibFileStatusChange(TARGET_LIB_TYPE_IMAGE, currentIndex, TARGET_LIB_FILE_STATUS_BAD); + } + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_IMAGE_ERROR; + DapLinkStatusSet(&status); + return false; + } + return true; +} + +/** + * @brief Check the source algo file. + * @retval true or false + */ +static bool CheckSoureAlgo(void) +{ + DapLinkStatus status; + int32_t currentIndex; + + if (TargetLibCurrentAlgoGet(&g_offlineDownloadHandle.currentLibAlgo) != TARGET_LIB_OK) { + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_ALGO_ERROR; + DapLinkStatusSet(&status); + return false; + } + /* Initial configuration of CRC check processing */ + UserCrcInit(0, g_offlineDownloadHandle.currentLibAlgo.info.fileCrc32); + /* Check the CRC value of the source file to determine whether the source file is damaged. */ + if (CheckCrcFromFlash(flash_intf_iap_protected,\ + g_offlineDownloadHandle.currentLibAlgo.startAddr,\ + g_offlineDownloadHandle.currentLibAlgo.info.fileSize) !=USER_CRC_CHECK_SUCCESS) { + currentIndex = TargetLibAlgoIndexGetFormStartAddr(g_offlineDownloadHandle.currentLibAlgo.startAddr); + /* Flag corrupted file */ + TargetLibFileStatusChange(TARGET_LIB_TYPE_ALGO, currentIndex, TARGET_LIB_FILE_STATUS_BAD); + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_ALGO_ERROR; + DapLinkStatusSet(&status); + return false; + } + return true; +} + +/** + * @brief Verification Processing Configuration + * @param verifyStartAddr Check Start Address + * @retval None + */ +static void VerifyHandleConfig(uint32_t *verifyStartAddr) +{ + if (g_board_info.target_cfg) { + region_info_t *region = g_board_info.target_cfg->flash_regions; + for (; region->start != 0 || region->end != 0; ++region) { + /* Version 1 and later versions add the burning start address + of the target board to the file header. */ + if (g_offlineDownloadHandle.currentLibImage.info.version > 0) { + *verifyStartAddr = g_offlineDownloadHandle.currentLibImage.info.targetAddr; + } else { + *verifyStartAddr = region->start; + } + + if (kRegionIsDefault == region->flags) { + break; + } + } + } +} + +/** + * @brief check processing function. + * @retval None + */ +static void VerifyHandler(void) +{ + DapLinkStatus status; + const flash_intf_t *currentIntf = NULL; + uint32_t verifyStartAddr = 0; + uint32_t checkValue; + uint32_t checkLen; + int32_t clockLevel; + + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_VERIFY_RUNNING; + DapLinkStatusSet(&status); + /* Verification Parameter Configuration */ + VerifyHandleConfig(&verifyStartAddr); + /* Configure the current flash operation algorithm. */ + currentIntf = flash_intf_target; + checkLen = g_offlineDownloadHandle.currentLibImage.info.fileSize; + checkValue = g_offlineDownloadHandle.currentLibImage.info.fileCrc32; + + UserCrcInit(0, checkValue); + /* Verify the target file. */ + if (CheckCrcFromFlash(currentIntf, verifyStartAddr, checkLen) != USER_CRC_CHECK_SUCCESS) { + clockLevel = SwdJtagClockLevelGet(); + /* Speed Down Retry */ + if (clockLevel < SWD_JTAG_CLOCK_LEVEL_9) { + clockLevel++; + SwJtagClockLevelLevelSet(clockLevel); + } else { + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_ERROR; + g_offlineDownloadDisplayState = OFFLINE_DOWNLOAD_DISPLAY_VERIFI_FAIL; + + /* Check soruce image */ + if (!CheckSoureImage()) { + return; + } + /* Check soruce algo */ + if (!CheckSoureAlgo()) { + return; + } + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_VERIFY_FAIL; + DapLinkStatusSet(&status); + } + return; + } + + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_DONE; + g_offlineDownloadDisplayState = OFFLINE_DOWNLOAD_DISPLAY_VERIFI_OK; +} + +/** + * @brief Done processing function. + * @retval None + */ +static void DoneHandler(void) +{ + DapLinkStatus status; + FactoryImageHandle tempFactoryImageList; + + UnInit(0); + /* Factory mode and normal mode are handled differently. */ + if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { + if (g_offlineDownloadHandle.currentLibImage.info.maxLoads != 0) { + FactoryImageLoadCntAdd(g_offlineDownloadHandle.currentFactoryFileCnt - 1); + } + FactoryImageListGet(&tempFactoryImageList); + /* Check whether all files are downloaded. */ + if (tempFactoryImageList.count > g_offlineDownloadHandle.currentFactoryFileCnt) { + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_OPEN; + return; + } + } else { + if (g_offlineDownloadHandle.currentLibImage.info.maxLoads != 0) { + TargetImageLoadCntAdd(g_offlineDownloadHandle.currentImageIndex); + } + } + /* Restoring the Default Download Configuration */ + g_downloadStartFlag = false; + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_IDLE; + g_offlineDownloadDisplayState = OFFLINE_DOWNLOAD_DISPLAY_LOAD_OK; + + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_SUCCESS; + DapLinkStatusSet(&status); +} + +/** + * @brief Error processing function. + * @retval None + */ +static void ErrorHandler(void) +{ + flash_manager_uninit(); + UnInit(0); + g_downloadStartFlag = false; + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_IDLE; +} + +/** + * @brief Offline burning initialization. + * @retval Success or Failure Result + */ +int32_t OfflineDownLoadInit(void) +{ + int32_t index; + TargetAlgoHandle temptargetAlgoInfo; + + g_offlineDownloadState = OFFLINE_DOWNLOAD_STATE_IDLE; + g_downloadStartFlag = false; + /* Read the algorithm list. */ + ConfigAlgoListRead(&temptargetAlgoInfo, sizeof(temptargetAlgoInfo)); + if (temptargetAlgoInfo.count == 0 || temptargetAlgoInfo.count > TARGET_LIB_ALGO_MAX_NUM) { + return OFFLINE_DOWNLOAD_ERROR; + } + /* Obtains the index of the currently configured algorithm. */ + index = ConfigCurrentAlgoIndexRead(); + TargetAlgoConfig(index); + return OFFLINE_DOWNLOAD_OK; +} + +/** + * @brief Offline burning deinitialization. + * @retval OFFLINE_DOWNLOAD_OK + */ +int32_t OfflineDownLoadDeinit(void) +{ + return OFFLINE_DOWNLOAD_OK; +} + +/** + * @brief Processing function of the offline burning task. + * @retval None + */ +void OfflineDownLoadHandler(void) +{ + switch (g_offlineDownloadState) { + case OFFLINE_DOWNLOAD_STATE_IDLE: + /* The program is idle most of the time. As long as + there is no download task, the state machine is set back to idle. */ + IdleHandler(); + break; + case OFFLINE_DOWNLOAD_STATE_OPEN: + /* Download Preparation Phase */ + SysSoftResetFlagSet(true); + OpenHandler(); + break; + case OFFLINE_DOWNLOAD_STATE_SELECT_ALGO: + /* Configuration algorithm phase */ + SelectAlgoHandler(); + break; + case OFFLINE_DOWNLOAD_STATE_LOADING: + /* Multipart download processing phase */ + LoadingHandler(); + break; + case OFFLINE_DOWNLOAD_VERIFI: + /* Verification phase */ + VerifyHandler(); + break; + case OFFLINE_DOWNLOAD_STATE_DONE: + DoneHandler(); + SysSoftResetFlagSet(true); + break; + case OFFLINE_DOWNLOAD_STATE_ERROR: + /* Error Handling */ + ErrorHandler(); + SysSoftResetFlagSet(true); + break; + default: + break; + } +} + +/** + * @brief Start Offline Burning. + * @retval Success or Failure Result + */ +int32_t OfflineDownLoadStart(void) +{ + DapLinkStatus status; + if (g_downloadStartFlag) { + return OFFLINE_DOWNLOAD_ERROR; + } + /* Set the start flag. */ + g_downloadStartFlag = true; + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_START; + DapLinkStatusSet(&status); + /* By default, the download starts at the maximum rate. */ + SwJtagClockLevelLevelSet(0); + return OFFLINE_DOWNLOAD_OK; +} + +/** + * @brief Stop Offline Burning. + * @retval OFFLINE_DOWNLOAD_OK + */ +int32_t OfflineDownLoadStop(void) +{ + return OFFLINE_DOWNLOAD_OK; +} + +/** + * @brief Entire erase configuration + * @param startAddr Start address of the erase partition + * @retval None + */ +static void EraseChipConfig(uint32_t *startAddr) +{ + region_info_t *region = g_board_info.target_cfg->flash_regions; + for (; region->start != 0 || region->end != 0; ++region) { + if (kRegionIsDefault == region->flags) { + *startAddr = region->start; + break; + } + } +} + +/** + * @brief Erase chip handle. + * @param startAddr Erase Start Address + * @retval Success or Failure Result + */ +static int32_t OfflineEraseChipHandle(uint32_t startAddr) +{ + int ret; + int32_t clockLevel; + const flash_intf_t *currentIntf = flash_intf_target; + + clockLevel = SwdJtagClockLevelGet(); + while (1) { + if (clockLevel <= SWD_JTAG_CLOCK_LEVEL_9) { + SwJtagClockLevelLevelSet(clockLevel); + clockLevel++; + } else { + break; + } + /* Initialize the target chip. */ + if (ERROR_SUCCESS != currentIntf->init()) { + currentIntf->uninit(); + continue; + } + + /* Configure and load the operation algorithm of the target chip. */ + if (currentIntf->flash_algo_set) { + if (ERROR_SUCCESS != currentIntf->flash_algo_set(startAddr)) { + currentIntf->uninit(); + continue; + } + } + + /* Erases the target chip. If the chip fails to be erased, the system retries + the chip based on the configured retry times. */ + for (uint32_t i = 0; i < OFFLINE_ERASE_TYR_TIME; i++) { + ret = currentIntf->erase_chip(); + if (ret == ERROR_SUCCESS) { + return OFFLINE_DOWNLOAD_OK; + } + } + } + return OFFLINE_DOWNLOAD_ERROR_ERASE_FAIL; +} + +/** + * @brief Erases the entire partition of the target chip based on the algorithm index. + * @param index Algorithm file index + * @retval Success or Failure Result + */ +int32_t OfflineEraseChip(int32_t index) +{ + DapLinkStatus status; + int ret; + uint32_t startAddr = 0; + const flash_intf_t *currentIntf = NULL; + + if (index < 0 || index >= TARGET_LIB_ALGO_MAX_NUM) { + return OFFLINE_DOWNLOAD_ERROR; + } + + if (TargetAlgoConfig(index) != TARGET_ALGO_PARSE_OK) { + /* Display status */ + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_GET_ALGO_FAIL; + DapLinkStatusSet(&status); + return OFFLINE_DOWNLOAD_ERROR_SELECT_ALGO; + } + /* Entire erase configuration */ + if (g_board_info.target_cfg) { + EraseChipConfig(&startAddr); + /* Configure the current flash operation algorithm. */ + currentIntf = flash_intf_target; + } else { + DapLinkStatusGet(&status); + status.imageUpgradeStatus = IMAGE_UPGRADE_GET_ALGO_FAIL; + DapLinkStatusSet(&status); + return OFFLINE_DOWNLOAD_ERROR_SELECT_ALGO; + } + ret = OfflineEraseChipHandle(startAddr); + /* Deinitialize the target chip. */ + currentIntf->uninit(); + return ret; +} + +/** + * @brief Obtaining the Display Status of Offline Download. + * @retval OfflineDownLoadDisplayState + */ +OfflineDownLoadDisplayState OfflineDownLoadDisplayStateGet(void) +{ + return g_offlineDownloadDisplayState; +} + +/** + * @brief Offline Download Display Status Configuration. + * @param state Offline burning status + * @retval OFFLINE_DOWNLOAD_OK + */ +int32_t OfflineDownLoadDisplayStateSet(OfflineDownLoadDisplayState state) +{ + g_offlineDownloadDisplayState = state; + return OFFLINE_DOWNLOAD_OK; +} + +/** + * @brief In OfflineDownLoad. + * @param none + * @retval download flag + */ +bool IsOfflineDownLoad(void) +{ + return g_downloadStartFlag; +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_download.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_download.h new file mode 100644 index 0000000000000000000000000000000000000000..78ea2f5cb4f48155b5a7e3a0ed0fc5eeb0328c9b --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_download.h @@ -0,0 +1,57 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file offline_download.h + * @author MCU Driver Team + * @brief offline download driver. + */ +#ifndef OFFLINE_DOWNLOAD_H +#define OFFLINE_DOWNLOAD_H +#include + +typedef enum { + OFFLINE_DOWNLOAD_DISPLAY_LOADLIG, + OFFLINE_DOWNLOAD_DISPLAY_SELECT_ALGO_FAIL, + OFFLINE_DOWNLOAD_DISPLAY_VERIFI_FAIL, + OFFLINE_DOWNLOAD_DISPLAY_VERIFI_OK, + OFFLINE_DOWNLOAD_DISPLAY_LOAD_FAIL, + OFFLINE_DOWNLOAD_DISPLAY_LOAD_OK, +} OfflineDownLoadDisplayState; + +/* error state */ +#define OFFLINE_DOWNLOAD_OK 0 +#define OFFLINE_DOWNLOAD_ERROR 1 +#define OFFLINE_DOWNLOAD_ERROR_OPEN 2 +#define OFFLINE_DOWNLOAD_ERROR_SELECT_ALGO 3 +#define OFFLINE_DOWNLOAD_VERIFI_ERROR 4 +#define OFFLINE_DOWNLOAD_ERROR_LOADING 5 +#define OFFLINE_DOWNLOAD_ERROR_CLOSE 6 +#define OFFLINE_DOWNLOAD_ERROR_NOT_CONNECT 7 +#define OFFLINE_DOWNLOAD_ERROR_ERASE_FAIL 8 + + +int32_t OfflineDownLoadInit(void); +int32_t OfflineDownLoadDeinit(void); +int32_t OfflineDownLoadStart(void); +int32_t OfflineDownLoadStop(void); +int32_t OfflineEraseChip(int32_t index); +void OfflineDownLoadHandler(void); +OfflineDownLoadDisplayState OfflineDownLoadDisplayStateGet(void); +int32_t OfflineDownLoadDisplayStateSet(OfflineDownLoadDisplayState state); +bool IsOfflineDownLoad(void); + +#endif /* #ifndef OFFLINE_DOWNLOAD_H */ \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_sys_config.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_sys_config.c new file mode 100644 index 0000000000000000000000000000000000000000..f6b209ef42a1034a5567c65917ed4dd05160774a --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_sys_config.c @@ -0,0 +1,412 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file offline_sys_config.c + * @author MCU Driver Team + * @brief offline sys config driver. + */ +#include "DAP.h" +#include "swd_host.h" +#include "jtag_host.h" +#include "swd_jtag_config.h" +#include "debug_cm.h" +#include "target_lib_manager.h" +#include "config_storage_update.h" +#include "factory_manager.h" +#include "IO_Config.h" +#include "offline_download.h" +#include "offline_sys_config.h" + +#define UNLOCK_SECURITY_TIMEOUT 5000 +#define UNLOCK_SECURITY_SUCCESS 0x1 +#define SOFT_RESET_TIME 100 + +static uint32_t g_sysStartFlag = CONFIG_STRAT_FLAG_A; +static uint32_t g_sysLanguage = SYS_LANGUAGE_CN; +static bool g_sysSoftResetFlag = true; + +/** + * @brief Obtains the tick difference.. + * @param curTicks Current tick + * @param preTicks Previous tick + * @retval Tick Delta value + */ +static uint32_t GetTickDelta(uint32_t curTicks, uint32_t preTicks) +{ + if (curTicks >= preTicks) { + return curTicks - preTicks; + } + /* Prevent inversion errors */ + return 0xFFFFFFFF - preTicks + curTicks + 1; +} + +/** + * @brief Jtag reset. + * @retval true or false + */ +static bool JtagReset(void) +{ + uint32_t val; + int timeout = SOFT_RESET_TIME; + uint32_t tmp = 0; + int i = 0; + + /* Switching from the SWD interface to the JTAG interface. */ + if (!SWD2JTAG()) { + return false; + } + /* clear jtag errors. */ + if (!jtag_clear_errors()) { + return false; + } + /* Select AP */ + if (!jtag_write_dp(DP_SELECT, 0)) { + return false; + } + + /* Power up */ + if (!jtag_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ)) { + return false; + } + /* Wait until the power-on is successful. */ + for (i = 0; i < timeout; i++) { + if (!jtag_read_dp(DP_CTRL_STAT, &tmp)) { + return false; + } + + if ((tmp & (CDBGPWRUPACK | CSYSPWRUPACK)) == (CDBGPWRUPACK | CSYSPWRUPACK)) { + /* Break from loop if powerup is complete */ + break; + } + } + + if (i == timeout) { + /* Unable to powerup DP */ + return false; + } + + if (!jtag_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ | TRNNORMAL | MASKLANE)) { + return false; + } + return true; +} + +/** + * @brief Swd reset. + * @retval true or false + */ +static bool SwdReset(void) +{ + uint32_t val; + int timeout = SOFT_RESET_TIME; + uint32_t tmp = 0; + int i = 0; + + /* Switching from the JTAG interface to the SWD interface. */ + if (JTAG2SWD() == 0) { + return false; + } + /* clear swd errors. */ + if (!swd_clear_errors()) { + return false; + } + /* Select AP */ + if (!swd_write_dp(DP_SELECT, 0)) { + return false; + } + + /* Power up */ + if (!swd_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ)) { + return false; + } + /* Wait until the power-on is successful. */ + for (i = 0; i < timeout; i++) { + if (!swd_read_dp(DP_CTRL_STAT, &tmp)) { + return false; + } + if ((tmp & (CDBGPWRUPACK | CSYSPWRUPACK)) == (CDBGPWRUPACK | CSYSPWRUPACK)) { + /* Break from loop if powerup is complete */ + break; + } + } + if ((i == timeout)) { + /* Unable to powerup DP */ + return false; + } + + if (!swd_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ | TRNNORMAL | MASKLANE)) { + return false; + } + return true; +} + +/** + * @brief Initializing the Offline Programming System Configuration. + * @retval 0 success + */ +int32_t OfflineSysConfigInit(void) +{ + uint32_t powerStatus; + + g_sysStartFlag = ConfigStartFlagRead(); + powerStatus = SysExternalPowerStatusGet(); + SysExternalPowerSet(powerStatus); + ConfigFactoryImageLoadCntAddrCalibration(); + ConfigImageLoadCntAddrCalibration(); + return 0; +} + +/** + * @brief Restoring Factory Settings. + * @retval 0 success + */ +int32_t ConfigRestoreFactory(void) +{ + uint32_t startFlag; + + TargetLibImageDeleteAll(); + TargetLibAlgoDeleteAll(); + FactoryImageFreeAll(); + FactoryImageFreeAll(); + ConfigFactoryImageLoadCntClean(); + ConfigImageLoadCntClean(); + + ConfigFactoryFlagSave(0); + + startFlag = ConfigStartFlagRead(); + if (startFlag != CONFIG_STRAT_FLAG_A && startFlag != CONFIG_STRAT_FLAG_B) { + startFlag = CONFIG_STRAT_FLAG_A; + ConfigStartFlagSave(startFlag); + } + SysExternalPowerSet(SYS_EXTERNAL_POWER_OFF); + OfflineDownLoadInit(); + TargetLibInit(); + FactoryInit(); + return 0; +} + +/** + * @brief Startup flag acquisition. + * @retval Startup flag + */ +uint32_t SysStartFlagGet(void) +{ + return g_sysStartFlag; +} + +/** + * @brief Configuration of the External Power Supply Function. + * @param status External power supply configuration status + * @retval None + */ +void SysExternalPowerSet(uint32_t status) +{ + uint32_t currentStatus; + if (status == SYS_EXTERNAL_POWER_ON) { + POWER_SWITCH_PORT->BSRR = POWER_SWITCH_PIN; + } else { + POWER_SWITCH_PORT->BSRR = (POWER_SWITCH_PIN << 16); /* Shift left by 16 bits */ + } + + currentStatus = ConfigPowerStatusFlagRead(); + if (currentStatus != status) { + ConfigPowerStatusFlagSave(status); + } +} + +/** + * @brief Obtaining the Configuration Status of External Power Supply. + * @retval External power supply configuration status + */ +uint32_t SysExternalPowerStatusGet(void) +{ + return ConfigPowerStatusFlagRead(); +} + +/** + * @brief Setting the status of the offline burning indicator + * @param status Indicator status + * @retval None + */ +void OfflineLoadLedSet(uint32_t status) +{ + if ((status & 1) != 0) { + OFFLINE_DOWNLOAD_STATUS_LED_PORT->BSRR = OFFLINE_DOWNLOAD_STATUS_LED_PIN; + } else { + OFFLINE_DOWNLOAD_STATUS_LED_PORT->BSRR = (OFFLINE_DOWNLOAD_STATUS_LED_PIN << 16); /* Shift left by 16 bits */ + } +} + +/** + * @brief Reading the board ID + * @retval board ID + */ +uint32_t SysBoardIdGet(void) +{ + uint32_t boardId = 0; + boardId |= (((BOARD_ID2_PORT->IDR & BOARD_ID2_PIN) ? 1 : 0) << 2); /* Obtains the 2 digit of the ID. */ + boardId |= (((BOARD_ID1_PORT->IDR & BOARD_ID1_PIN) ? 1 : 0) << 1); /* Obtains the 1 digit of the ID. */ + boardId |= ((BOARD_ID0_PORT->IDR & BOARD_ID0_PIN) ? 1 : 0); /* Obtains the 0 digit of the ID. */ + return boardId; +} + +/** + * @brief SWD Unlock the security configuration and roll back the flash protection of the target chip. + * @retval false or true + */ +static bool SwdSysUnlockSecurity(void) +{ + uint32_t val; + uint32_t preTicks; + uint32_t curTicks; + uint32_t delta; + int32_t clockLevel; + + clockLevel = SwdJtagClockLevelGet(); + SwJtagClockLevelLevelSet(clockLevel); + while (!SwdReset()) { + if (clockLevel <= SWD_JTAG_CLOCK_LEVEL_9) { + SwJtagClockLevelLevelSet(clockLevel); + clockLevel++; + } else { + break; + } + } + preTicks = HAL_GetTick(); + swd_write_dp(DP_SELECT, 0x1000000); + swd_write_ap(AP_CSW, 0x0000002, 0x1000000); + swd_write_ap(AP_TAR, 0x14724000, 0x1000000); + swd_write_ap(AP_DRW, 0xABEFCD00, 0x1000000); + while (1) { + curTicks = HAL_GetTick(); + delta = GetTickDelta(curTicks, preTicks); + swd_write_ap(AP_TAR, 0x14724004, 0x1000000); + swd_read_ap(AP_DRW, &val, 0x1000000); + if (val == UNLOCK_SECURITY_SUCCESS) { + return true; + } + + if (delta > UNLOCK_SECURITY_TIMEOUT && val != UNLOCK_SECURITY_SUCCESS) { + return false; + } + } +} + +/** + * @brief JTAG Unlock the security configuration and roll back the flash protection of the target chip. + * @retval false or true + */ +static bool JtagSysUnlockSecurity(void) +{ + uint32_t val; + uint32_t preTicks; + uint32_t curTicks; + uint32_t delta; + int32_t clockLevel; + + clockLevel = SwdJtagClockLevelGet(); + while (!JtagReset()) { + if (clockLevel <= SWD_JTAG_CLOCK_LEVEL_9) { + SwJtagClockLevelLevelSet(clockLevel); + clockLevel++; + } else { + break; + } + } + preTicks = HAL_GetTick(); + jtag_write_dp(DP_SELECT, 0x1000000); + jtag_write_ap(AP_CSW, 0x0000002, 0x1000000); + jtag_write_ap(AP_TAR, 0x14724000, 0x1000000); + jtag_write_ap(AP_DRW, 0xABEFCD00, 0x1000000); + while (1) { + curTicks = HAL_GetTick(); + delta = GetTickDelta(curTicks, preTicks); + jtag_write_ap(AP_TAR, 0x14724004, 0x1000000); + jtag_read_ap(AP_DRW, &val, 0x1000000); + jtag_read_dp(DP_RDBUFF, &val); + if (val == UNLOCK_SECURITY_SUCCESS) { + return true; + } + + if (delta > UNLOCK_SECURITY_TIMEOUT && val != UNLOCK_SECURITY_SUCCESS) { + return false; + } + } +} + +/** + * @brief Unlock the security configuration and roll back the flash protection of the target chip. + * @retval false or true + */ +bool SysUnlockSecurity(void) +{ + uint8_t debugPort; + + debugPort = SwdJtagDebugPortGet(); + if (debugPort == DAP_PORT_JTAG) { + return JtagSysUnlockSecurity(); + } else { + return SwdSysUnlockSecurity(); + } +} + +/** + * @brief Setting the language. + * @param language Language to be set. + * @retval 0 success + */ +int32_t SysLanguageSet(uint32_t language) +{ + g_sysLanguage = language; + return ConfigLanguageFlagSave(g_sysLanguage); +} + +/** + * @brief Setting the language. + * @retval language + */ +uint32_t SysLanguageGet(void) +{ + uint32_t language; + + language = ConfigLanguageFlagRead(); + if (language == SYS_LANGUAGE_EN) { + g_sysLanguage = SYS_LANGUAGE_EN; + } else { + g_sysLanguage = SYS_LANGUAGE_CN; + } + return g_sysLanguage; +} + +/** + * @brief Getting the soft reset flag + * @retval true or false + */ +bool SysSoftResetFlagGet(void) +{ + return g_sysSoftResetFlag; +} + +/** + * @brief Setting the soft reset flag + * @param flag true or false + * @retval None + */ +void SysSoftResetFlagSet(bool flag) +{ + g_sysSoftResetFlag = flag; +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_sys_config.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_sys_config.h new file mode 100644 index 0000000000000000000000000000000000000000..643140922cdc9d6eea8938cd256c398c1c25d8cb --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/offline_sys_config.h @@ -0,0 +1,52 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file offline_sys_config.h + * @author MCU Driver Team + * @brief offline sys config driver. + */ +#ifndef OFFLINE_SYS_CONFIG_H +#define OFFLINE_SYS_CONFIG_H +#include + +#define SYS_EXTERNAL_POWER_ON 0 +#define SYS_EXTERNAL_POWER_OFF 0xFFFFFFFF + +#define SYS_OFFLINE_LED_ON 0 +#define SYS_OFFLINE_LED_OFF 1 + +#define SYS_ALINK_BOARD_VA_10M 0x7 /* 111 */ +#define SYS_ALINK_BOARD_VB_10M 0x6 /* 110 */ +#define SYS_ALINK_BOARD_VB_16M 0x3 /* 011 */ + +#define SYS_LANGUAGE_CN 0x0 +#define SYS_LANGUAGE_EN 0x1 + + +int32_t OfflineSysConfigInit(void); +int32_t ConfigRestoreFactory(void); +uint32_t SysStartFlagGet(void); +void SysExternalPowerSet(uint32_t status); +uint32_t SysExternalPowerStatusGet(void); +bool SysUnlockSecurity(void); +void OfflineLoadLedSet(uint32_t status); +uint32_t SysBoardIdGet(void); +int32_t SysLanguageSet(uint32_t language); +uint32_t SysLanguageGet(void); +bool SysSoftResetFlagGet(void); +void SysSoftResetFlagSet(bool flag); +#endif /* #ifndef OFFLINE_SYS_CONFIG_H */ \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_algo_parse.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_algo_parse.c new file mode 100644 index 0000000000000000000000000000000000000000..0f9d087b76214957d0ccdeb53a1229da1ba23412 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_algo_parse.c @@ -0,0 +1,116 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file target_algo_parse.c + * @author MCU Driver Team + * @brief offline sys config driver. + */ +#include +#include +#include "securec.h" +#include "target_config.h" +#include "flash_blob.h" +#include "FlashPrg.h" +#include "target_lib_manager.h" +#include "factory_manager.h" +#include "debug.h" +#include "target_algo_parse.h" + +static uint8_t g_targetAlgoParseBuff[TARGET_ALGO_PARSE_BUFF_SIZE]; +static program_target_t newFlash; + +/** + * @brief Target algorithm parsing + * @retval None + */ +static void TargetAlgoParse(void) +{ + /* Obtaining the Offset Address of the API Interface of the Target Flash Driver */ + newFlash.init = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_INIT_FUN_OFFSET); + newFlash.uninit = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_UNINIT_FUN_OFFSET); + newFlash.erase_chip = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_ERASE_CHIP_FUN_OFFSET); + newFlash.erase_sector = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_ERASE_SECTOR_FUN_OFFSET); + newFlash.program_page = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_PRG_PAGE_FUN_OFFSET); + newFlash.verify = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_VERIFY_FUN_OFFSET); + newFlash.read = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_READ_FUN_OFFSET); + /* Breakpoint Pointer Offset Address */ + newFlash.sys_call_s.breakpoint = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_BK_ADDR_OFFSET); + /* Stack Pointer Offset Address */ + newFlash.sys_call_s.static_base = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_STATIC_BASE_OFFSET); + newFlash.sys_call_s.stack_pointer = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_STACK_POINTER_OFFSET); + /* Start address of the flash algorithm running data buffer */ + newFlash.program_buffer = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_PRG_BUFF_OFFSET); + /* Start address of the RAM for running the flash algorithm */ + newFlash.algo_start = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_RAM_START_OFFSET); + /* Binary file size of the flash algorithm */ + newFlash.algo_size = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_FLASH_ALGO_LEN_OFFSET); + /* Start address for storing binary files in the flash algorithm */ + newFlash.algo_blob = (uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_ALGO_BLOB_OFFSET); + /* Cache size of the running data of the flash algorithm */ + newFlash.program_buffer_size = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_FLASH_SECTOR_SIZE_OFFSET); + /* Flash information of the target chip */ + target_device.sectors_info->start = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_FLASH_START_OFFSET); + target_device.sectors_info->size = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_FLASH_SIZE_OFFSET); + target_device.sector_info_length = 1; + target_device.flash_regions[0].start = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_FLASH_START_OFFSET); + target_device.flash_regions[0].flags = kRegionIsDefault; + target_device.flash_regions[0].flash_algo = (program_target_t *) &newFlash; + /* Start address of the RAM for running the flash algorithm of the target chip */ + target_device.ram_regions[0].start = *(uint32_t*)(g_targetAlgoParseBuff + TARGET_ALGO_PARSE_RAM_START_OFFSET); +} + +/** + * @brief Configure the target algorithm based on the algorithm index. + * @param algoIndex Index of the algorithm file in the list + * @retval Configuration Result + */ +int32_t TargetAlgoConfig(int32_t algoIndex) +{ + TargetAlgoLibInfo newAlgoInfo; + int32_t ret; + errno_t rc = EOK; + /* Configure the current burning algorithm based on the index. */ + ret = TargetLibAlgoSelect(algoIndex); + if (ret != TARGET_LIB_OK) { + return TARGET_ALGO_PARSE_ERROR; + } + /* Obtains the current programming algorithm information. */ + ret = TargetLibCurrentAlgoGet(&newAlgoInfo); + if (ret != TARGET_LIB_OK || newAlgoInfo.fileStatus == TARGET_LIB_FILE_STATUS_BAD) { + return TARGET_ALGO_PARSE_ERROR; + } + + rc = memset_s(g_targetAlgoParseBuff, sizeof(g_targetAlgoParseBuff), 0xFF, sizeof(g_targetAlgoParseBuff)); + if (rc != EOK) { + return TARGET_ALGO_PARSE_ERROR; + } + Init(0, 0, 0); + /* Read the algorithm file from the debugger and parse it. */ + if (FlashRead(newAlgoInfo.startAddr, newAlgoInfo.info.fileSize, g_targetAlgoParseBuff) != 0) { + return TARGET_ALGO_PARSE_ERROR; + } + + /* Verifying */ + UserCrcInit(0, newAlgoInfo.info.fileCrc32); + UserCrc32(g_targetAlgoParseBuff, newAlgoInfo.info.fileSize); + if (IsCheckSuccess() == 0) { + return TARGET_ALGO_PARSE_ERROR; + } + + TargetAlgoParse(); + return TARGET_ALGO_PARSE_OK; +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_algo_parse.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_algo_parse.h new file mode 100644 index 0000000000000000000000000000000000000000..8ccf7943b384547eeb48a6b71dbd4e10ed722b99 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_algo_parse.h @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file target_algo_parse.h + * @author MCU Driver Team + * @brief target algo parse driver. + */ +#ifndef TARGET_ALGO_PARSE_H +#define TARGET_ALGO_PARSE_H + +#include + +#define TARGET_ALGO_PARSE_OK 0 +#define TARGET_ALGO_PARSE_ERROR 1 + +#define TARGET_ALGO_PARSE_BUFF_SIZE 8192 + +#define TARGET_ALGO_PARSE_MIN_SIZE 0x48 + +#define TARGET_ALGO_PARSE_FLASH_START_OFFSET 0x00 +#define TARGET_ALGO_PARSE_FLASH_SIZE_OFFSET 0x04 +#define TARGET_ALGO_PARSE_FLASH_SECTOR_SIZE_OFFSET 0x08 + +#define TARGET_ALGO_PARSE_RAM_START_OFFSET 0x0C +#define TARGET_ALGO_PARSE_PRG_BUFF_OFFSET 0x10 +#define TARGET_ALGO_PARSE_BK_ADDR_OFFSET 0x14 +#define TARGET_ALGO_PARSE_STATIC_BASE_OFFSET 0x18 +#define TARGET_ALGO_PARSE_STACK_POINTER_OFFSET 0x1C + +#define TARGET_ALGO_PARSE_INIT_FUN_OFFSET 0x20 +#define TARGET_ALGO_PARSE_UNINIT_FUN_OFFSET 0x24 +#define TARGET_ALGO_PARSE_ERASE_CHIP_FUN_OFFSET 0x28 +#define TARGET_ALGO_PARSE_ERASE_SECTOR_FUN_OFFSET 0x2C +#define TARGET_ALGO_PARSE_PRG_PAGE_FUN_OFFSET 0x30 +#define TARGET_ALGO_PARSE_VERIFY_FUN_OFFSET 0x34 +#define TARGET_ALGO_PARSE_READ_FUN_OFFSET 0x38 +#define TARGET_ALGO_PARSE_ALGO_FLAGS_OFFSET 0x3c + +#define TARGET_ALGO_PARSE_RESERVED_OFFSET 0x40 + +#define TARGET_ALGO_PARSE_FLASH_ALGO_LEN_OFFSET 0x44 +#define TARGET_ALGO_PARSE_ALGO_BLOB_OFFSET 0x48 + +int32_t TargetAlgoConfig(int32_t algoIndex); + + +#endif /* #ifndef TARGET_ALGO_PARSE_H */ \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_lib_manager.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_lib_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..bd6dcdb8742dac57efbfbd2a333e79d03932a65b --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_lib_manager.c @@ -0,0 +1,903 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file target_lib_manager.c + * @author MCU Driver Team + * @brief target flash library mamager driver. + */ +#include +#include +#include "securec.h" +#include "FlashPrg.h" +#include "target_vendor_config.h" +#include "config_storage_update.h" +#include "status.h" +#include "debug.h" +#include "target_lib_manager.h" + +static TargetImageHandle g_targetImageInfo; +static TargetAlgoHandle g_targetAlgoInfo; + +static TargetImageLoadCntList g_targetImageLoadCntList; + +static int32_t g_currentAlgoIndex = 0; +static int32_t g_currentImageIndex = 0; +static bool g_freeAlgoFlag[TARGET_LIB_ALGO_MAX_NUM]; +static bool g_freeImageFlag[TARGET_LIB_IMAGE_MAX_NUM]; + +static TargetLibDisplayState g_targetLibDisplayState; + +/** + * @brief Update the image list of the target chip. + * @retval None + */ +static void TargetLibImageUpdateList(void) +{ + TargetImageLibInfo tempInfo; + uint32_t i; + int32_t tempCnt; + uint32_t tempLoadCnt; + if (g_currentImageIndex == (g_targetImageInfo.count - 1) || + g_targetImageInfo.count <= 0) { + return; + } + tempInfo = g_targetImageInfo.libInfo[g_targetImageInfo.count - 1]; + tempLoadCnt = g_targetImageLoadCntList.list[g_targetImageInfo.count - 1]; + g_targetImageInfo.libInfo[g_targetImageInfo.count - 1] = g_targetImageInfo.libInfo[g_currentImageIndex]; + g_targetImageLoadCntList.list[g_targetImageInfo.count - 1] = g_targetImageLoadCntList.list[g_currentImageIndex]; + /* To obtain the number of moves, subtract 2 from the number of moves. */ + tempCnt = g_targetImageInfo.count - g_currentImageIndex - 2; + for (i = 0; i < tempCnt; i++) { + g_targetImageInfo.libInfo[g_currentImageIndex + i] = g_targetImageInfo.libInfo[g_currentImageIndex + 1 + i]; + g_targetImageLoadCntList.list[g_currentImageIndex + i] = \ + g_targetImageLoadCntList.list[g_currentImageIndex + 1 + i]; + } + g_targetImageInfo.libInfo[g_targetImageInfo.count - 2] = tempInfo; /* Last Move Forward 2 */ + g_targetImageLoadCntList.list[g_targetImageInfo.count - 2] = tempLoadCnt; /* Last Move Forward 2 */ + g_currentImageIndex = g_targetImageInfo.count - 1; +} + +/** + * @brief Update the algorithm list of the target chip. + * @retval None + */ +static void TargetLibAlgoUpdateList(void) +{ + TargetAlgoLibInfo tempInfo; + uint32_t i; + int32_t tempCnt; + if (g_currentAlgoIndex == (g_targetAlgoInfo.count - 1) || + g_targetAlgoInfo.count <= 0) { + return; + } + tempInfo = g_targetAlgoInfo.libInfo[g_targetAlgoInfo.count - 1]; + g_targetAlgoInfo.libInfo[g_targetAlgoInfo.count - 1] = g_targetAlgoInfo.libInfo[g_currentAlgoIndex]; + /* To obtain the number of moves, subtract 2 from the number of moves. */ + tempCnt = g_targetAlgoInfo.count - g_currentAlgoIndex - 2; + for (i = 0; i < tempCnt; i++) { + g_targetAlgoInfo.libInfo[g_currentAlgoIndex + i] = g_targetAlgoInfo.libInfo[g_currentAlgoIndex + 1 + i]; + } + g_targetAlgoInfo.libInfo[g_targetAlgoInfo.count - 2] = tempInfo; /* Last Move Forward 2 */ + g_currentAlgoIndex = g_targetAlgoInfo.count - 1; +} + +/** + * @brief Obtaining the address of the idle algorithm space + * @retval Idle algorithm space address + */ +static uint32_t FreeAlgoAddrGet(void) +{ + int i; + for (i = 0; i < TARGET_LIB_ALGO_MAX_NUM; i++) { + if (g_freeAlgoFlag[i]) { + g_freeAlgoFlag[i] = false; + ConfigFreeAlgoFlagSave(g_freeAlgoFlag, sizeof(g_freeAlgoFlag)); + return TARGET_LIB_ALGO_START + i * TARGET_LIB_ONE_ALGO_SIZE; + } + } + return g_targetAlgoInfo.libInfo[0].startAddr; +} + +/** + * @brief Address status configuration of the idle algorithm space. + * @param addr Algorithm space address + * @param state Algorithm space address status + * @retval TARGET_LIB_OK + */ +static int32_t FreeAlgoAddrSet(uint32_t addr, bool state) +{ + uint32_t index; + index = (addr - TARGET_LIB_ALGO_START) / TARGET_LIB_ONE_ALGO_SIZE; + g_freeAlgoFlag[index] = state; + ConfigFreeAlgoFlagSave(g_freeAlgoFlag, sizeof(g_freeAlgoFlag)); + return TARGET_LIB_OK; +} + +/** + * @brief Obtaining the free space address of the image. + * @retval Specifies the free space address of the image + */ +static uint32_t FreeImageAddrGet(void) +{ + int i; + for (i = 0; i < TARGET_LIB_IMAGE_MAX_NUM; i++) { + if (g_freeImageFlag[i]) { + g_freeImageFlag[i] = false; + ConfigFreeImageFlagSave(g_freeImageFlag, sizeof(g_freeImageFlag)); + return TARGET_LIB_IMAGE_START + i * TARGET_LIB_ONE_IMAGE_SIZE; + } + } + return g_targetImageInfo.libInfo[0].startAddr; +} + +/** + * @brief Address status configuration of the idle image space. + * @param addr image space address + * @param state image space address status + * @retval TARGET_LIB_OK + */ +static int32_t FreeImageAddrSet(uint32_t addr, bool state) +{ + uint32_t index; + index = (addr - TARGET_LIB_IMAGE_START) / TARGET_LIB_ONE_IMAGE_SIZE; + g_freeImageFlag[index] = state; + ConfigFreeImageFlagSave(g_freeImageFlag, sizeof(g_freeImageFlag)); + return TARGET_LIB_OK; +} + +/** + * @brief Initialize the target file library. + * @retval Success or Failure Result + */ +int32_t TargetLibInit(void) +{ + ConfigAlgoListRead(&g_targetAlgoInfo, sizeof(g_targetAlgoInfo)); + if (g_targetAlgoInfo.count > TARGET_LIB_ALGO_MAX_NUM) { + g_targetAlgoInfo.count = 0; + } + ConfigImageListRead(&g_targetImageInfo, sizeof(g_targetImageInfo)); + if (g_targetImageInfo.count > TARGET_LIB_IMAGE_MAX_NUM) { + g_targetImageInfo.count = 0; + } + + ConfigImageLoadCntRead(&g_targetImageLoadCntList, sizeof(g_targetImageLoadCntList)); + ConfigFreeAlgoFlagRead(g_freeAlgoFlag, sizeof(g_freeAlgoFlag)); + ConfigFreeImageFlagRead(g_freeImageFlag, sizeof(g_freeImageFlag)); + g_currentAlgoIndex = ConfigCurrentAlgoIndexRead(); + return 0; +} + +/** + * @brief Deinitialize the target file library. + * @retval Success or Failure Result + */ +int32_t TargetLibUninit(void) +{ + return TARGET_LIB_OK; +} + +/** + * @brief Obtaining the Algorithm List of Target Chips. + * @param handle Algorithm list handle + * @retval Success or Failure Result + */ +int32_t TargetLibAlgoListGet(TargetAlgoHandle *handle) +{ + if (handle == NULL) { + return TARGET_LIB_ERROR; + } + + *handle = g_targetAlgoInfo; + return TARGET_LIB_OK; +} + +/** + * @brief Concatenate the algorithm name based on the algorithm list index. + * @param info Target chip information + * @param index Index of the target algorithm list + * @retval Success or Failure Result + */ +static int32_t TargetAlgoNameSplicing(TargetFlashInfo info, int32_t index) +{ + errno_t rc = EOK; + switch (info.vendorID) { + case TARGET_VENDOR_HISILICON: + rc = strcat_s(g_targetAlgoInfo.libInfo[index].name, TARGET_LIB_IMAGE_NAME_MAX_LEN, + g_hiModelName[info.modelID]); + break; + case TARGET_VENDOR_HM: + rc = strcat_s(g_targetAlgoInfo.libInfo[index].name, TARGET_LIB_IMAGE_NAME_MAX_LEN, + g_vendorHMModelName[info.modelID]); + break; + case TARGET_VENDOR_AUCU: + rc = strcat_s(g_targetAlgoInfo.libInfo[index].name, TARGET_LIB_IMAGE_NAME_MAX_LEN, + g_aucuModelName[info.modelID]); + break; + default: + break; + } + if (rc != EOK) { + return TARGET_LIB_ERROR; + } + rc = strcat_s(g_targetAlgoInfo.libInfo[index].name, TARGET_LIB_IMAGE_NAME_MAX_LEN, + g_regionInfo[info.regioninfo & 0xFF]); + if (rc != EOK) { + return TARGET_LIB_ERROR; + } + return TARGET_LIB_OK; +} + +/** + * @brief Check whether indexes exist. + * @param info Target flash information + * @retval index + */ +static int32_t CheckAddIndex(TargetFlashInfo info) +{ + int32_t index = -1; + + for (int i = 0; i < g_targetAlgoInfo.count; i++) { + if (info.regioninfo != g_targetAlgoInfo.libInfo[i].info.regioninfo) { + continue; + } + + if (info.vendorID != g_targetAlgoInfo.libInfo[i].info.vendorID) { + continue; + } + + if (info.modelID != g_targetAlgoInfo.libInfo[i].info.modelID) { + continue; + } + + if (info.flashID != g_targetAlgoInfo.libInfo[i].info.flashID) { + continue; + } + index = i; + break; + } + return index; +} + +/** + * @brief Adding an algorithm file to the target algorithm list + * @param info Target flash information + * @retval Success or Failure Result + */ +int32_t TargetLibAlgoAdd(TargetFlashInfo info) +{ + int32_t index = -1; + errno_t rc = EOK; + + if (g_targetAlgoInfo.count > TARGET_LIB_ALGO_MAX_NUM) { + return TARGET_LIB_ERROR; + } + + index = CheckAddIndex(info); + if (index == -1) { + if (g_targetAlgoInfo.count == TARGET_LIB_ALGO_MAX_NUM || g_targetAlgoInfo.count < 0) { + index = 0; + } else { + index = g_targetAlgoInfo.count; + g_targetAlgoInfo.libInfo[index].startAddr = FreeAlgoAddrGet(); + g_targetAlgoInfo.count++; + } + rc = memset_s(g_targetAlgoInfo.libInfo[index].name, TARGET_LIB_IMAGE_NAME_MAX_LEN, + 0, sizeof(g_targetAlgoInfo.libInfo[index].name)); + if (rc != EOK) { + return TARGET_LIB_ERROR; + } + TargetAlgoNameSplicing(info, index); + g_targetAlgoInfo.libInfo[index].nameLen = strlen(g_targetAlgoInfo.libInfo[index].name); + } + g_targetAlgoInfo.libInfo[index].info = info; + g_targetAlgoInfo.libInfo[index].fileStatus = TARGET_LIB_FILE_STATUS_BAD; + g_currentAlgoIndex = index; + TargetLibAlgoUpdateList(); + ConfigAlgoListSave(&g_targetAlgoInfo, sizeof(g_targetAlgoInfo)); + ConfigCurrentAlgoIndexSave(g_currentAlgoIndex); + return TARGET_LIB_OK; +} + +/** + * @brief Select the target algorithm based on the list index. + * @param index Target algorithm index + * @retval Success or Failure Result + */ +int32_t TargetLibAlgoSelect(int32_t index) +{ + if (index >= g_targetAlgoInfo.count || + index < 0 || + g_targetAlgoInfo.count > TARGET_LIB_ALGO_MAX_NUM) { + return TARGET_LIB_ERROR; + } + if (index != g_currentAlgoIndex) { + g_currentAlgoIndex = index; + ConfigCurrentAlgoIndexSave(g_currentAlgoIndex); + } + return TARGET_LIB_OK; +} + +/** + * @brief Obtains the currently selected target chip algorithm. + * @param info Flash information of the target chip + * @retval Success or Failure Result + */ +int32_t TargetLibCurrentAlgoGet(TargetAlgoLibInfo *info) +{ + if (info == NULL) { + return TARGET_LIB_ERROR; + } + *info = g_targetAlgoInfo.libInfo[g_currentAlgoIndex]; + return TARGET_LIB_OK; +} + +/** + * @brief Obtains the algorithm file index based on the start address. + * @param startAddr Start address of the algorithm file + * @retval Algorithm file index + */ +int32_t TargetLibAlgoIndexGetFormStartAddr(uint32_t startAddr) +{ + int32_t i; + int32_t index = -1; + + for (i = 0; i < g_targetAlgoInfo.count; i++) { + if (startAddr == g_targetAlgoInfo.libInfo[i].startAddr) { + index = i; + break; + } + } + return index; +} + +/** + * @brief Obtain the algorithm file index based on the flash information of the target chip. + * @param info Flash information of the target chip + * @retval Algorithm file index + */ +int32_t TargetLibAlgoIndexGetFormFlashInfo(TargetFlashInfo info) +{ + int32_t i; + int32_t index = -1; + for (i = 0; i < g_targetAlgoInfo.count; i++) { + if (g_targetAlgoInfo.libInfo[i].info.regioninfo != info.regioninfo) { + continue; + } + + if (g_targetAlgoInfo.libInfo[i].info.vendorID != info.vendorID) { + continue; + } + + if (g_targetAlgoInfo.libInfo[i].info.modelID != info.modelID) { + continue; + } + + if (g_targetAlgoInfo.libInfo[i].info.flashID != info.flashID) { + continue; + } + index = i; + } + return index; +} + +/** + * @brief Obtaining the image list of the target chip + * @param handle Image handle of the target chip + * @retval Success or Failure Result + */ +int32_t TargetLibImageListGet(TargetImageHandle *handle) +{ + if (handle == NULL) { + return TARGET_LIB_ERROR; + } + *handle = g_targetImageInfo; + return TARGET_LIB_OK; +} + +/** + * @brief Assemble the image file name based on the target chip information. + * @param info Flash information of the target chip + * @param tempName Specifies the image file name + * @param nameLen Name len + * @retval Success or Failure Result + */ +static int32_t TargetImageNameSplicing(TargetFlashInfo info, char *tempName, uint32_t nameLen) +{ + errno_t rc = EOK; + rc = strcat_s(tempName, nameLen, "("); /* Splice Brackets */ + if (rc != EOK) { + return TARGET_LIB_ERROR; + } + switch (info.vendorID) { /* Splicing Manufacturer */ + case TARGET_VENDOR_HISILICON: + rc = strcat_s(tempName, nameLen, g_hiModelName[info.modelID]); + break; + case TARGET_VENDOR_HM: /* vendor open harmony */ + rc = strcat_s(tempName, nameLen, g_vendorHMModelName[info.modelID]); + break; + case TARGET_VENDOR_AUCU: + rc = strcat_s(tempName, nameLen, g_aucuModelName[info.modelID]); + break; + default: + break; + } + if (rc != EOK) { + return TARGET_LIB_ERROR; + } + rc = strcat_s(tempName, nameLen, g_regionInfo[info.regioninfo & 0xFF]); /* Stitching Partitions */ + if (rc != EOK) { + return TARGET_LIB_ERROR; + } + rc = strcat_s(tempName, nameLen, ")"); /* Splice Brackets */ + if (rc != EOK) { + return TARGET_LIB_ERROR; + } +} + +/** + * @brief Updating the Image Index + * @param info Flash information of the target chip + * @retval Image file index + */ +static int32_t UpdatingImageIndex(TargetFlashInfo info, int32_t index) +{ + int32_t tmpIndex = index; + if (tmpIndex == -1) { + if (g_targetImageInfo.count == TARGET_LIB_IMAGE_MAX_NUM) { + tmpIndex = 0; + } else { + tmpIndex = g_targetImageInfo.count; + g_targetImageInfo.libInfo[tmpIndex].startAddr = FreeImageAddrGet(); + g_targetImageInfo.count++; + } + } + g_targetImageInfo.libInfo[tmpIndex].info = info; + g_targetImageInfo.libInfo[tmpIndex].fileStatus = TARGET_LIB_FILE_STATUS_BAD; + return tmpIndex; +} + +/** + * @brief Adding a File to the Image File List. + * @param info Flash information of the target chip + * @param imageName Image File Name + * @param nameLen Length of the image file name + * @retval Success or Failure Result + */ +int32_t TargetLibImageAdd(TargetFlashInfo info, uint8_t *imageName, uint32_t nameLen) +{ + int32_t i; + int32_t index = -1; + uint32_t templen = 0; + errno_t rc = EOK; + char tempName[TARGET_LIB_IMAGE_NAME_MAX_LEN]; + if (g_targetImageInfo.count > TARGET_LIB_IMAGE_MAX_NUM) { + return TARGET_LIB_ERROR; + } + + if (imageName == NULL || nameLen > TARGET_LIB_IMAGE_IN_NAME_MAX_LEN) { + return TARGET_LIB_ERROR; + } + memset_s(tempName, TARGET_LIB_IMAGE_NAME_MAX_LEN, 0, sizeof(tempName)); + rc = memcpy_s(tempName, TARGET_LIB_IMAGE_NAME_MAX_LEN, imageName, nameLen); + if (rc != EOK) { + return TARGET_LIB_ERROR; + } + TargetImageNameSplicing(info, tempName, TARGET_LIB_IMAGE_NAME_MAX_LEN); + templen = strlen(tempName); + + for (i = 0; i < g_targetImageInfo.count; i++) { + if (g_targetImageInfo.libInfo[i].nameLen != templen) { + continue; + } + + if (strncmp(tempName, g_targetImageInfo.libInfo[i].name, templen) == 0) { + index = i; + break; + } + } + index = UpdatingImageIndex(info, index); + memset_s(g_targetImageInfo.libInfo[index].name, TARGET_LIB_IMAGE_NAME_MAX_LEN, + 0, sizeof(g_targetImageInfo.libInfo[index].name)); + rc = memcpy_s(g_targetImageInfo.libInfo[index].name, TARGET_LIB_IMAGE_NAME_MAX_LEN, + tempName, templen); + if (rc != EOK) { + return TARGET_LIB_ERROR; + } + g_targetImageInfo.libInfo[index].nameLen = templen; + + g_currentImageIndex = index; + g_targetImageLoadCntList.list[index] = 0; + TargetLibImageUpdateList(); + ConfigImageListSave(&g_targetImageInfo, sizeof(g_targetImageInfo)); + ConfigImageLoadCntSave(&g_targetImageLoadCntList, sizeof(g_targetImageLoadCntList)); + return TARGET_LIB_OK; +} + +/** + * @brief Selecting an image file based on the index. + * @param index Image file index + * @retval Success or Failure Result + */ +int32_t TargetLibImageSelect(int32_t index) +{ + if (index >= g_targetImageInfo.count || index < 0) { + return TARGET_LIB_ERROR; + } + g_currentImageIndex = index; + return TARGET_LIB_OK; +} + +/** + * @brief Obtains the information and index of the currently selected file. + * @param info Image file information + * @param index Index of the currently selected file + * @retval Success or Failure Result + */ +int32_t TargetLibCurrentImageGet(TargetImageLibInfo *info, int32_t *index) +{ + if (info == NULL || index == NULL) { + return TARGET_LIB_ERROR; + } + *info = g_targetImageInfo.libInfo[g_currentImageIndex]; + *index = g_currentImageIndex; + return TARGET_LIB_OK; +} + +/** + * @brief Obtains the image index based on the start address. + * @param startAddr Image start address + * @retval Indicates the image index + */ +int32_t TargetLibImageIndexGetFormStartAddr(uint32_t startAddr) +{ + int32_t i; + int32_t index = -1; + + for (i = 0; i < g_targetImageInfo.count; i++) { + if (startAddr == g_targetImageInfo.libInfo[i].startAddr) { + index = i; + break; + } + } + return index; +} + +/** + * @brief Start address configuration of the target chip + * @param type TargetLibType + * @retval TARGET_LIB_OK + */ +int32_t TargetLibStartAddrSet(TargetLibType type) +{ + return TARGET_LIB_OK; +} + +/** + * @brief Obtain the start address of the current image file or algorithm file. + * @param type TargetLibType + * @retval Start address of the current image file or algorithm file + */ +uint32_t TargetLibStartAddrGet(TargetLibType type) +{ + if (type == TARGET_LIB_TYPE_IMAGE) { + return g_targetImageInfo.libInfo[g_currentImageIndex].startAddr; + } else { + return g_targetAlgoInfo.libInfo[g_currentAlgoIndex].startAddr; + } +} + +/** + * @brief Display Status Obtaining + * @retval Display Status + */ +TargetLibDisplayState TargetLibDisplayStateGet(void) +{ + return g_targetLibDisplayState; +} + +/** + * @brief Display Status Obtaining + * @param state Display Status + * @retval TARGET_LIB_OK + */ +int32_t TargetLibDisplayStateSet(TargetLibDisplayState state) +{ + g_targetLibDisplayState = state; + return TARGET_LIB_OK; +} + +/** + * @brief Delete algorithm files based on indexes. + * @param index Algorithm file index + * @retval Success or Failure Result + */ +int32_t TargetLibAlgoDelete(int32_t index) +{ + uint32_t i; + int32_t updataCnt; + DapLinkStatus status; + errno_t rc = EOK; + + DapLinkStatusGet(&status); + status.algoDeleteStatus = ALGORITHM_DELETE_RUNNING; + DapLinkStatusSet(&status); + + if (index >= g_targetAlgoInfo.count || g_targetAlgoInfo.count <= 0 || index < 0) { + DapLinkStatusGet(&status); + status.algoDeleteStatus = ALGORITHM_DELETE_FAIL; + DapLinkStatusSet(&status); + return TARGET_LIB_ERROR; + } + FreeAlgoAddrSet(g_targetAlgoInfo.libInfo[index].startAddr, true); + + if (index < g_targetAlgoInfo.count - 1) { + updataCnt = g_targetAlgoInfo.count - index - 1; + for (i = 0; i < updataCnt; i++) { + g_targetAlgoInfo.libInfo[index + i] = g_targetAlgoInfo.libInfo[index + i + 1]; + } + } + rc = memset_s(&g_targetAlgoInfo.libInfo[g_targetAlgoInfo.count - 1], sizeof(TargetAlgoLibInfo), + 0, sizeof(TargetAlgoLibInfo)); + if (rc != EOK) { + DapLinkStatusGet(&status); + status.algoDeleteStatus = ALGORITHM_DELETE_FAIL; + DapLinkStatusSet(&status); + return TARGET_LIB_ERROR; + } + g_targetAlgoInfo.count--; + ConfigAlgoListSave(&g_targetAlgoInfo, sizeof(g_targetAlgoInfo)); + if (index < g_currentAlgoIndex) { + g_currentAlgoIndex--; + } else if (index == g_currentAlgoIndex) { + g_currentAlgoIndex = g_targetAlgoInfo.count - 1; + } + ConfigCurrentAlgoIndexSave(g_currentAlgoIndex); + + DapLinkStatusGet(&status); + status.algoDeleteStatus = ALGORITHM_DELETE_SUCCESS; + DapLinkStatusSet(&status); + + return TARGET_LIB_OK; +} + +/** + * @brief Delete all algorithm files. + * @retval Success or Failure Result + */ +int32_t TargetLibAlgoDeleteAll(void) +{ + uint32_t i; + DapLinkStatus status; + errno_t rc = EOK; + + DapLinkStatusGet(&status); + status.algoDeleteStatus = ALGORITHM_DELETE_RUNNING; + DapLinkStatusSet(&status); + + for (i = 0; i < TARGET_LIB_ALGO_MAX_NUM; i++) { + g_freeAlgoFlag[i] = true; + rc = memset_s(&g_targetAlgoInfo.libInfo[i], sizeof(g_targetAlgoInfo.libInfo[i]), + 0, sizeof(g_targetAlgoInfo.libInfo[i])); + if (rc != EOK) { + DapLinkStatusGet(&status); + status.algoDeleteStatus = ALGORITHM_DELETE_FAIL; + DapLinkStatusSet(&status); + return TARGET_LIB_ERROR; + } + } + ConfigFreeAlgoFlagSave(g_freeAlgoFlag, sizeof(g_freeAlgoFlag)); + g_targetAlgoInfo.count = 0; + ConfigAlgoListSave(&g_targetAlgoInfo, sizeof(g_targetAlgoInfo)); + g_currentAlgoIndex = 0; + ConfigCurrentAlgoIndexSave(g_currentAlgoIndex); + + DapLinkStatusGet(&status); + status.algoDeleteStatus = ALGORITHM_DELETE_SUCCESS; + DapLinkStatusSet(&status); + return TARGET_LIB_OK; +} + +/** + * @brief Delete image files based on indexes. + * @param index image file index + * @retval Success or Failure Result + */ +int32_t TargetLibImageDelete(uint32_t index) +{ + uint32_t i; + uint32_t updataCnt; + errno_t rc = EOK; + + DapLinkStatus status; + + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_RUNNING; + DapLinkStatusSet(&status); + if (index >= g_targetImageInfo.count) { + return TARGET_LIB_ERROR; + } + FreeImageAddrSet(g_targetImageInfo.libInfo[index].startAddr, true); + + if (index < g_targetImageInfo.count - 1) { + updataCnt = g_targetImageInfo.count - index - 1; + for (i = 0; i < updataCnt; i++) { + g_targetImageInfo.libInfo[index + i] = g_targetImageInfo.libInfo[index + i + 1]; + g_targetImageLoadCntList.list[index + i] = g_targetImageLoadCntList.list[index + i + 1]; + } + } + rc = memset_s(&g_targetImageInfo.libInfo[g_targetImageInfo.count - 1], sizeof(TargetImageLibInfo), + 0, sizeof(TargetImageLibInfo)); + if (rc != EOK) { + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_FAIL; + DapLinkStatusSet(&status); + return TARGET_LIB_ERROR; + } + g_targetImageLoadCntList.list[g_targetImageInfo.count - 1] = TARGET_LIB_LOAD_CNT_INVALIA; + g_targetImageInfo.count--; + ConfigImageListSave(&g_targetImageInfo, sizeof(g_targetImageInfo)); + ConfigImageLoadCntSave(&g_targetImageLoadCntList, sizeof(g_targetImageLoadCntList)); + + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_SUCCESS; + DapLinkStatusSet(&status); + return TARGET_LIB_OK; +} + +/** + * @brief Delete all image files. + * @retval Success or Failure Result + */ +int32_t TargetLibImageDeleteAll(void) +{ + uint32_t i; + DapLinkStatus status; + errno_t rc = EOK; + + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_RUNNING; + DapLinkStatusSet(&status); + + for (i = 0; i < TARGET_LIB_IMAGE_MAX_NUM; i++) { + g_freeImageFlag[i] = true; + rc = memset_s(&g_targetImageInfo.libInfo[i], sizeof(g_targetImageInfo.libInfo[i]), + 0, sizeof(g_targetImageInfo.libInfo[i])); + if (rc != EOK) { + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_FAIL; + DapLinkStatusSet(&status); + return TARGET_LIB_ERROR; + } + g_targetImageLoadCntList.list[i] = TARGET_LIB_LOAD_CNT_INVALIA; + } + ConfigFreeImageFlagSave(g_freeImageFlag, sizeof(g_freeImageFlag)); + g_targetImageInfo.count = 0; + ConfigImageListSave(&g_targetImageInfo, sizeof(g_targetImageInfo)); + ConfigImageLoadCntSave(&g_targetImageLoadCntList, sizeof(g_targetImageLoadCntList)); + + DapLinkStatusGet(&status); + status.imageDeleteStatus = IMAGE_DELETE_SUCCESS; + DapLinkStatusSet(&status); + return TARGET_LIB_OK; +} + +/** + * @brief Modifying the File Status + * @param type Image file or algorithm file + * @param index file index + * @param status File Status + * @retval Success or Failure Result + */ +int32_t TargetLibFileStatusChange(TargetLibType type, int32_t index, uint32_t status) +{ + if (index >= TARGET_LIB_IMAGE_MAX_NUM || index < 0) { + return TARGET_LIB_ERROR; + } + + if (type == TARGET_LIB_TYPE_IMAGE) { + g_targetImageInfo.libInfo[index].fileStatus = status; + ConfigImageListSave(&g_targetImageInfo, sizeof(g_targetImageInfo)); + } else if (type == TARGET_LIB_TYPE_ALGO) { + g_targetAlgoInfo.libInfo[index].fileStatus = status; + ConfigAlgoListSave(&g_targetAlgoInfo, sizeof(g_targetAlgoInfo)); + if (status == TARGET_LIB_FILE_STATUS_BAD) { + g_currentAlgoIndex = 0; + ConfigCurrentAlgoIndexSave(g_currentAlgoIndex); + } + } else { + return TARGET_LIB_ERROR; + } + return TARGET_LIB_OK; +} + +/** + * @brief Obtaining the Chip Erasure List + * @param list Chip Erasure List + * @param listLen List len + * @retval Success or Failure Result + */ +int32_t TargetLibEraseListGet(TargetEraseList *list, uint32_t listLen) +{ + char *tempStr = NULL; + int32_t tempCnt = 0; + uint32_t templen = 0; + errno_t rc = EOK; + if (list == NULL) { + return TARGET_LIB_ERROR; + } + + rc = memset_s(list, listLen, 0, listLen); + if (rc != EOK) { + return TARGET_LIB_ERROR; + } + if (g_targetAlgoInfo.count == 0 || + g_targetAlgoInfo.count > TARGET_LIB_ALGO_MAX_NUM) { + list->count = 0; + return TARGET_LIB_OK; + } + + for (uint32_t i = 0; i < g_targetAlgoInfo.count; i++) { + if ((g_targetAlgoInfo.libInfo[i].info.regioninfo & 0xFFFF0000) != + TARGET_LIB_APP_REGION) { + continue; + } + + if (g_targetAlgoInfo.libInfo[i].fileStatus == TARGET_LIB_FILE_STATUS_BAD) { + continue; + } + tempStr = strchr(g_targetAlgoInfo.libInfo[i].name, '_'); + templen = tempStr - g_targetAlgoInfo.libInfo[i].name; + rc = memcpy_s(list->eraseList[tempCnt].name, TARGET_LIB_IMAGE_NAME_MAX_LEN, + g_targetAlgoInfo.libInfo[i].name, templen); + if (rc != EOK) { + return TARGET_LIB_ERROR; + } + list->eraseList[tempCnt].nameLen = templen; + list->eraseList[tempCnt].index = i; + tempCnt++; + } + list->count = tempCnt; + return TARGET_LIB_OK; +} + +/** + * @brief Obtains the number of times that an image has been downloaded based on the index. + * @param index image index + * @retval Number of times the image has been downloaded + */ +uint32_t TargetImageLoadCntGet(int32_t index) +{ + if (index >= TARGET_LIB_IMAGE_MAX_NUM || index < 0) { + return TARGET_LIB_LOAD_CNT_INVALIA; + } + return g_targetImageLoadCntList.list[index]; +} + +/** + * @brief Accumulate the number of image download times based on the index. + * @param index image index + * @retval Success or Failure Result + */ +int32_t TargetImageLoadCntAdd(int32_t index) +{ + if (index >= TARGET_LIB_IMAGE_MAX_NUM || index < 0) { + return TARGET_LIB_ERROR; + } + g_targetImageLoadCntList.list[index]++; + ConfigImageLoadCntSave(&g_targetImageLoadCntList, sizeof(g_targetImageLoadCntList)); + return TARGET_LIB_OK; +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_lib_manager.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_lib_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..ae45dd77771cf17b44ec23859ffbd84647a35bcf --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_lib_manager.h @@ -0,0 +1,163 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file target_lib_manager.h + * @author MCU Driver Team + * @brief target flash library mamager driver. + */ +#ifndef TARGET_LIB_MANAGER_H +#define TARGET_LIB_MANAGER_H +#include +#include +#include "daplink_addr.h" + +#define TARGET_LIB_OK 0 +#define TARGET_LIB_ERROR 1 + +#define TARGET_LIB_FILE_STATUS_BAD 0 +#define TARGET_LIB_FILE_STATUS_NORMAL 1 +#define TARGET_LIB_FILE_STATUS_SECURITY 2 + +#define TARGET_LIB_SEC_REGION 0x000A0000 +#define TARGET_LIB_APP_REGION 0x00010000 +#define TARGET_LIB_DATA_REGION 0x00020000 + +#define TARGET_LIB_FLASH_BASE_ADDR 0x10048000 +#define TARGET_LIB_FLASH_BLOCK_SIZE 4096 +#define TARGET_LIB_ALGO_OFFSET 0x300000 +#define TARGET_LIB_IMAGE_OFFSET 0x400000 +#define TARGET_LIB_FACTORY_IMAGE_OFFSET 0x900000 + +#define TARGET_LIB_IMAGE_IN_NAME_MAX_LEN 32 +#define TARGET_LIB_IMAGE_NAME_MAX_LEN 64 +#define TARGET_LIB_IMAGE_MAX_NUM 10 +#define TARGET_LIB_ALGO_MAX_NUM 10 +#define TARGET_LIB_FACTORY_ALGO_MAX_NUM TARGET_LIB_ALGO_MAX_NUM +#define TARGET_LIB_FACTORY_IMAGE_MAX_NUM 10 +#define TARGET_LIB_LOAD_CNT_INVALIA 0xFAFAFAFA + +#define TARGET_LIB_IMAGE_START (TARGET_LIB_FLASH_BASE_ADDR + TARGET_LIB_IMAGE_OFFSET) +#define TARGET_LIB_ONE_IMAGE_SIZE (125 * TARGET_LIB_FLASH_BLOCK_SIZE) /* 125*4096 = 500k */ + +#define TARGET_LIB_ALGO_START (TARGET_LIB_FLASH_BASE_ADDR + TARGET_LIB_ALGO_OFFSET) +#define TARGET_LIB_ONE_ALGO_SIZE (2 * TARGET_LIB_FLASH_BLOCK_SIZE) /* 2*4096 = 8K */ + +#define TARGET_LIB_FACTORY_IMAGE_START (TARGET_LIB_FLASH_BASE_ADDR + TARGET_LIB_FACTORY_IMAGE_OFFSET) +#define TARGET_LIB_ONE_FACTORY_IMAGE_SIZE (125 * TARGET_LIB_FLASH_BLOCK_SIZE) /* 125*4096 = 500k */ + +typedef enum { + TARGET_LIB_TYPE_ALGO, + TARGET_LIB_TYPE_IMAGE +} TargetLibType; + +typedef enum { + TARGET_LIB_DISPLAY_LOADING, + TARGET_LIB_DISPLAY_VERIFI_FAIL, + TARGET_LIB_DISPLAY_LOAD_FAIL, + TARGET_LIB_DISPLAY_LOAD_OK, + TARGET_LIB_DISPLAY_DELETE_OK, + TARGET_LIB_DISPLAY_DELETE_FAIL, +}TargetLibDisplayState; + +typedef struct { + uint32_t regioninfo; + uint32_t version; + uint32_t vendorID; + uint32_t modelID; + uint32_t flashID; + uint32_t fileSize; + uint32_t fileCrc32; + uint32_t oldNamelen; + uint32_t targetAddr; + uint32_t maxLoads; +} TargetFlashInfo; + +typedef struct { + uint32_t nameLen; + char name[TARGET_LIB_IMAGE_NAME_MAX_LEN]; + TargetFlashInfo info; + uint32_t fileStatus; + uint32_t startAddr; +} TargetAlgoLibInfo; + +typedef struct { + uint32_t nameLen; + char name[TARGET_LIB_IMAGE_NAME_MAX_LEN]; + TargetFlashInfo info; + uint32_t fileStatus; + uint32_t startAddr; +} TargetImageLibInfo; + +typedef struct { + int32_t count; + TargetAlgoLibInfo libInfo[TARGET_LIB_ALGO_MAX_NUM]; +} TargetAlgoHandle; + +typedef struct { + int32_t count; + TargetImageLibInfo libInfo[TARGET_LIB_IMAGE_MAX_NUM]; +} TargetImageHandle; + +typedef struct { + uint32_t index; + uint32_t nameLen; + char name[TARGET_LIB_IMAGE_NAME_MAX_LEN]; +} TargetEraseInfo; + +typedef struct { + int32_t count; + TargetEraseInfo eraseList[TARGET_LIB_ALGO_MAX_NUM]; +}TargetEraseList; + +typedef struct { + uint32_t list[TARGET_LIB_IMAGE_MAX_NUM]; +} TargetImageLoadCntList; + +int32_t TargetLibInit(void); +int32_t TargetLibUninit(void); + +int32_t TargetLibAlgoListGet(TargetAlgoHandle *handle); +int32_t TargetLibAlgoAdd(TargetFlashInfo info); +int32_t TargetLibAlgoSelect(int32_t index); +int32_t TargetLibAlgoDelete(int32_t index); +int32_t TargetLibAlgoDeleteAll(void); +int32_t TargetLibCurrentAlgoGet(TargetAlgoLibInfo *info); +int32_t TargetLibAlgoIndexGetFormStartAddr(uint32_t startAddr); +int32_t TargetLibAlgoIndexGetFormFlashInfo(TargetFlashInfo info); + +int32_t TargetLibImageListGet(TargetImageHandle *handle); +int32_t TargetLibImageAdd(TargetFlashInfo info, uint8_t *imageName, uint32_t nameLen); +int32_t TargetLibImageSelect(int32_t index); +int32_t TargetLibImageDelete(uint32_t index); +int32_t TargetLibImageDeleteAll(void); +int32_t TargetLibCurrentImageGet(TargetImageLibInfo *info, int32_t *index); +int32_t TargetLibImageIndexGetFormStartAddr(uint32_t startAddr); + +int32_t TargetLibStartAddrSet(TargetLibType type); +uint32_t TargetLibStartAddrGet(TargetLibType type); + +int32_t TargetLibFileStatusChange(TargetLibType type, int32_t index, uint32_t status); + +TargetLibDisplayState TargetLibDisplayStateGet(void); +int32_t TargetLibDisplayStateSet(TargetLibDisplayState state); + +int32_t TargetLibEraseListGet(TargetEraseList *list, uint32_t listLen); + +uint32_t TargetImageLoadCntGet(int32_t index); +int32_t TargetImageLoadCntAdd(int32_t index); + +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_vendor_config.c b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_vendor_config.c new file mode 100644 index 0000000000000000000000000000000000000000..9a8eea3fd199f6be49f12d8c14d547d481ea78d0 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_vendor_config.c @@ -0,0 +1,80 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file target_vendor_config.c + * @author MCU Driver Team + * @brief target vendor config driver. + */ +#include "target_vendor_config.h" + +char g_vendorName[VENDOR_CONFIG_VENDOR_NAME_NUM][VENDOR_CONFIG_NAME_LEN] = { + "Unknow_", + "Hisilicon_", + "Stm32_", + "Ti_", + "Renesas_", + "VendorHM_", + "AUCU_", +}; + +char g_hiModelName[VENDOR_CONFIG_HI_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN] = { + "unknow", + "3065", + "3061", +}; + +char g_stModelName[VENDOR_CONFIG_ST_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN] = { + "unknow", + "f103rb", + "f407", +}; + +char g_tiModelName[VENDOR_CONFIG_TI_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN] = { + "unknow", +}; + +char g_renesasModelName[VENDOR_CONFIG_RENESAS_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN] = { + "unknow", +}; + +char g_vendorHMModelName[VENDOR_CONFIG_HM_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN] = { + "unknow", + "3065HRPIRZ", + "3065HRPICZ", + "3061HRPIKZ", + "3061MRPIKB", + "3061MRPICB", +}; + +char g_aucuModelName[VENDOR_CONFIG_AUCU_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN] = { + "unknow", + "AU301LDF51", + "AU302NDF51", + "AU302PDF51", +}; + +char g_flashTypeName[VENDOR_CONFIG_FLASH_TYPE_NAME_NUM][VENDOR_CONFIG_NAME_LEN] = { + "_inchip", + "_outchip", +}; + +char g_regionInfo[VENDOR_CONFIG_FLASH_REGION_INFO_NUM][VENDOR_CONFIG_NAME_LEN] = { + "_Main_rgn0", + "_Main_rgn1", + "_info_rgn1", + "3", +}; \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_vendor_config.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_vendor_config.h new file mode 100644 index 0000000000000000000000000000000000000000..b3fb366196ee779a3f56eb65528429b383d17733 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/offline_download/target_vendor_config.h @@ -0,0 +1,92 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file target_vendor_config.h + * @author MCU Driver Team + * @brief target vendor config driver. + */ +#ifndef TARGET_VENDOR_CONFIG_H +#define TARGET_VENDOR_CONFIG_H + +#define VENDOR_CONFIG_NAME_LEN 20 +#define VENDOR_CONFIG_VENDOR_NAME_NUM 7 + +#define VENDOR_CONFIG_HI_MODEL_NAME_NUM 3 +#define VENDOR_CONFIG_ST_MODEL_NAME_NUM 3 +#define VENDOR_CONFIG_TI_MODEL_NAME_NUM 1 +#define VENDOR_CONFIG_RENESAS_MODEL_NAME_NUM 1 +#define VENDOR_CONFIG_HM_MODEL_NAME_NUM 6 +#define VENDOR_CONFIG_AUCU_MODEL_NAME_NUM 4 + +#define VENDOR_CONFIG_FLASH_TYPE_NAME_NUM 2 +#define VENDOR_CONFIG_FLASH_REGION_INFO_NUM 4 + +extern char g_vendorName[VENDOR_CONFIG_VENDOR_NAME_NUM][VENDOR_CONFIG_NAME_LEN]; + +extern char g_hiModelName[VENDOR_CONFIG_HI_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN]; + +extern char g_stModelName[VENDOR_CONFIG_ST_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN]; + +extern char g_tiModelName[VENDOR_CONFIG_TI_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN]; + +extern char g_renesasModelName[VENDOR_CONFIG_RENESAS_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN]; + +extern char g_vendorHMModelName[VENDOR_CONFIG_HM_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN]; + +extern char g_aucuModelName[VENDOR_CONFIG_AUCU_MODEL_NAME_NUM][VENDOR_CONFIG_NAME_LEN]; + +extern char g_flashTypeName[VENDOR_CONFIG_FLASH_TYPE_NAME_NUM][VENDOR_CONFIG_NAME_LEN]; +extern char g_regionInfo[VENDOR_CONFIG_FLASH_REGION_INFO_NUM][VENDOR_CONFIG_NAME_LEN]; + +/* vendor ID */ +#define TARGET_VENDOR_HISILICON 0x00000001 +#define TARGET_VENDOR_ST 0x00000002 +#define TARGET_VENDOR_TI 0x00000003 +#define TARGET_VENDOR_RENESAS 0x00000004 +#define TARGET_VENDOR_HM 0x00000005 +#define TARGET_VENDOR_AUCU 0x00000006 + +/* model ID */ + +/* hisilicon */ +#define TARGET_MODEL_HI3065 0x00000001 +#define TARGET_MODEL_HM3061 0x00000002 + +/* ST */ +#define TARGET_MODEL_STM32F103RB 0x00000001 +#define TARGET_MODEL_STM32F407 0x00000002 + +/* TI */ + +/* Renesas */ + +/* vendorHM */ +#define TARGET_MODEL_3065HRPIRZ 0x00000001 +#define TARGET_MODEL_3065HRPICZ 0x00000002 +#define TARGET_MODEL_3061HRPIKZ 0x00000003 + +/* AUCU */ +#define TARGET_MODEL_AG32R2080LF 0x00000001 +#define TARGET_MODEL_AG32R2160NF 0x00000002 +#define TARGET_MODEL_AG32R2160PF 0x00000003 + + +/* flash ID */ +#define TARGET_FLASH_INCHIP 0x00000000 +#define TARGET_FLASH_OUTCHIP 0x00000001 + +#endif /* #ifndef TARGET_VENDOR_CONFIG_H */ \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/remoteproc/inc/remote_proc.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/remoteproc/inc/remote_proc.h new file mode 100644 index 0000000000000000000000000000000000000000..ba71ed9c96c1d5029810e34b014db74aca41b605 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/remoteproc/inc/remote_proc.h @@ -0,0 +1,28 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file remote_proc.h + * @author MCU Driver Team + * @brief Cortex-A Start Cortex-M Header + */ + +#ifndef REMOTE_PROC_H +#define REMOTE_PROC_H + +void RemoteStart(void); + +#endif \ No newline at end of file diff --git a/src/middleware/hisilicon/nostask/kernel/include/nos_task_sched_external.h b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/remoteproc/src/remote_proc.c similarity index 67% rename from src/middleware/hisilicon/nostask/kernel/include/nos_task_sched_external.h rename to src/tools/hispark_trace/hispark/CA7/source/hispark_trace/remoteproc/src/remote_proc.c index 61738c6faeac4a94b8696191fb94827eea060aab..28b1942c725d161fb353894eb36c1f08c563b547 100644 --- a/src/middleware/hisilicon/nostask/kernel/include/nos_task_sched_external.h +++ b/src/tools/hispark_trace/hispark/CA7/source/hispark_trace/remoteproc/src/remote_proc.c @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,26 +15,32 @@ * 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. - * @file nos_task_sched_external.h + * @file remote_proc.c + * @author MCU Driver Team + * @brief Cortex-A Start Cortex-M Process */ -#ifndef NOS_TASK_SCHED_EXTERNAL_H -#define NOS_TASK_SCHED_EXTERNAL_H -#include "nos_buildef.h" -#include "nos_typedef.h" -#include "nos_task_external.h" -#include "nos_cpu_external.h" +#include "stm32mp1xx.h" -INLINE void OsSpinLockTaskRq(struct TagTskCB *taskCB) +/** + * @brief Remote Start CM4 code + * @retval None + */ +static void FirmwareStart(void) { - /* 保留 */ - (void)taskCB; + RCC_TypeDef *rccHandle = (RCC_TypeDef *)RCC_BASE; + rccHandle->MP_GCR &= ~RCC_MP_GCR_BOOT_MCU_Msk; // Hold MCU when the next MCU core reset occurs. + + rccHandle->MP_GRSTCSETR |= RCC_MP_GRSTCSETR_MCURST; // Rest MCU + + rccHandle->MP_GCR |= RCC_MP_GCR_BOOT_MCU_Msk; } -INLINE void OsSpinUnlockTaskRq(struct TagTskCB *taskCB) +/** + * @brief Remote Start CM4 code + * @retval None + */ +void RemoteStart(void) { - /* 保留 */ - (void)taskCB; + FirmwareStart(); } - -#endif /* NOS_TASK_SCHED_EXTERNAL_H */ diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Inc/gpio_config.h b/src/tools/hispark_trace/hispark/CM4/Core/Inc/gpio_config.h new file mode 100644 index 0000000000000000000000000000000000000000..ddbeb4d40dca7a5df6094ee77b0a1e7929ad0e1c --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Inc/gpio_config.h @@ -0,0 +1,100 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file gpio_config.h + * @author MCU Driver Team + * @brief gpio config. + */ +#ifndef GPIO_CONFIG_H +#define GPIO_CONFIG_H + +#define NEW_BOARD + +#ifdef NEW_BOARD + +#define SWCLK_TCK_PIN_PORT GPIOA +#define SWCLK_TCK_PIN GPIO_PIN_9 +#define SWCLK_TCK_PIN_BIT 9 + +#define SWDIO_OUT_TMS_PIN_PORT GPIOA +#define SWDIO_OUT_TMS_PIN GPIO_PIN_8 +#define SWDIO_OUT_TMS_PIN_BIT 8 + +#define SWDIO_IN_PIN_PORT GPIOA +#define SWDIO_IN_PIN GPIO_PIN_0 +#define SWDIO_IN_PIN_BIT 0 + +#define SWDIO_INOUT_OE_PORT GPIOA +#define SWDIO_INOUT_OE_PIN GPIO_PIN_3 +#define SWDIO_INOUT_OE_PIN_BIT 3 + +#define JTAG_TDI_PIN_PORT GPIOA +#define JTAG_TDI_PIN GPIO_PIN_1 +#define JTAG_TDI_PIN_BIT 1 + +#define JTAG_TDO_PIN_PORT GPIOA +#define JTAG_TDO_PIN GPIO_PIN_2 +#define JTAG_TDO_PIN_BIT 2 + +#define JTAG_TRST_PIN_PORT GPIOA +#define JTAG_TRST_PIN GPIO_PIN_14 +#define JTAG_TPST_PIN_BIT 14 + +#define JTAG_TARGET_RST_PIN_PORT GPIOA +#define JTAG_TARGET_RST_PIN GPIO_PIN_13 +#define JTAG_TARGET_RST_PIN_BIT 13 + +#endif + +#ifdef OLD_BOARD + +/* SWD */ +#define SWCLK_TCK_PIN_PORT GPIOA +#define SWCLK_TCK_PIN GPIO_PIN_8 +#define SWCLK_TCK_PIN_BIT 8 + +#define SWDIO_OUT_TMS_PIN_PORT GPIOA +#define SWDIO_OUT_TMS_PIN GPIO_PIN_9 +#define SWDIO_OUT_TMS_PIN_BIT 9 + +#define SWDIO_IN_PIN_PORT GPIOA +#define SWDIO_IN_PIN GPIO_PIN_7 +#define SWDIO_IN_PIN_BIT 7 + +#define SWDIO_INOUT_OE_PORT GPIOA +#define SWDIO_INOUT_OE_PIN GPIO_PIN_6 +#define SWDIO_INOUT_OE_PIN_BIT 6 + +#define JTAG_TDI_PIN_PORT GPIOA +#define JTAG_TDI_PIN GPIO_PIN_10 +#define JTAG_TDI_PIN_BIT 10 + +#define JTAG_TDO_PIN_PORT GPIOA +#define JTAG_TDO_PIN GPIO_PIN_11 +#define JTAG_TDO_PIN_BIT 11 + +#define JTAG_TRST_PIN_PORT GPIOA +#define JTAG_TRST_PIN GPIO_PIN_12 +#define JTAG_TPST_PIN_BIT 12 + +#define JTAG_TARGET_RST_PIN_PORT GPIOA +#define JTAG_TARGET_RST_PIN GPIO_PIN_13 +#define JTAG_TARGET_RST_PIN_BIT 13 + +#endif +void GpioConfigInit(void); +#endif diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Inc/swd_jtag_config.h b/src/tools/hispark_trace/hispark/CM4/Core/Inc/swd_jtag_config.h new file mode 100644 index 0000000000000000000000000000000000000000..2c20b2e9e2d231334795a5d076d32f395d6d94e6 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Inc/swd_jtag_config.h @@ -0,0 +1,56 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file swd_jtag_config.h + * @author MCU Driver Team + * @brief swd and jtag config. + */ +#ifndef SWD_JTAG_CONFIG_H +#define SWD_JTAG_CONFIG_H + +#include +#include "DAP_config.h" +#include "DAP.h" + +#define SWD_JTAG_CLOCK_LEVEL_0 0 +#define SWD_JTAG_CLOCK_LEVEL_1 1 +#define SWD_JTAG_CLOCK_LEVEL_2 2 +#define SWD_JTAG_CLOCK_LEVEL_3 3 +#define SWD_JTAG_CLOCK_LEVEL_4 4 +#define SWD_JTAG_CLOCK_LEVEL_5 5 +#define SWD_JTAG_CLOCK_LEVEL_6 6 +#define SWD_JTAG_CLOCK_LEVEL_7 7 +#define SWD_JTAG_CLOCK_LEVEL_8 8 +#define SWD_JTAG_CLOCK_LEVEL_9 9 +#define SWD_JTAG_CLOCK_LEVEL_LOW 300 + +extern DAP_Data_t g_DAP_Data; + +int SwdTurnaroundSet(uint8_t turnaround); +uint8_t SwdTurnaroundGet(void); +int SwdDataPhaseSet(uint8_t phase); +uint8_t SwdDataPhaseGet(void); + +int SwdJtagIdleCyclesSet(uint8_t cycles); +uint8_t SwdJtagIdleCyclesGet(void); +int SwdJtagClockLevelSet(uint32_t clock); +uint32_t SwdJtagClockLevelGet(void); +int SwdJtagClockDelaySet(uint32_t clock); +uint32_t SwdJtagClockDelayGet(void); +int SwdJtagDebugPortSet(uint8_t port); +uint8_t SwdJtagDebugPortGet(void); +#endif diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Inc/timer.h b/src/tools/hispark_trace/hispark/CM4/Core/Inc/timer.h new file mode 100644 index 0000000000000000000000000000000000000000..f6c61141b368e325933942d000fc5dae46735b16 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Inc/timer.h @@ -0,0 +1,38 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file timer.h + * @author MCU Driver Team + * @brief Header file timer for tick + */ +#ifndef TIMER_H +#define TIMER_H + +#include "stm32mp1xx.h" +#include "stm32mp1xx_hal.h" + +#define GTIM_TIMX TIM2 +static inline void GtimTimxClkEnable(void) +{ + __HAL_RCC_TIM2_CLK_ENABLE(); +} + +void TimerInit(void); +unsigned int GetTimerTickUs(void); +unsigned int GetDelta(unsigned int curTicks, unsigned int preTicks); + +#endif diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Inc/transfer_data_process.h b/src/tools/hispark_trace/hispark/CM4/Core/Inc/transfer_data_process.h new file mode 100644 index 0000000000000000000000000000000000000000..d1b6bbed44e72db492e213d1e289e9a025e31d7b --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Inc/transfer_data_process.h @@ -0,0 +1,30 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file transfer_data_process.h + * @author MCU Driver Team + * @brief Data Processing of Heteronuclear Communication. + */ +#ifndef TRANSFER_DATA_PROCESS_H +#define TRANSFER_DATA_PROCESS_H + +#include + +int32_t TransferDataProcessInit(void); +void TransferDataProcess(void); + +#endif /* #ifndef TRANSFER_DATA_PROCESS_H */ diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Inc/uart.h b/src/tools/hispark_trace/hispark/CM4/Core/Inc/uart.h new file mode 100644 index 0000000000000000000000000000000000000000..ce4d169b8d6f5dcaf0effd3dfe953f9200d5933a --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Inc/uart.h @@ -0,0 +1,51 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file uart.h + * @author MCU Driver Team + * @brief Header file uart4 for printf + */ + +/* Define to prevent recursive inclusion --------------------------------------------*/ +#ifndef UART_H +#define UART_H + +#include "stm32mp1xx.h" + +/*******************************************************************************************************/ +/* 配置UART的GPIO管脚 */ + +#define USART_TX_GPIO_PORT GPIOG +#define USART_TX_GPIO_PIN GPIO_PIN_11 +#define USART_TX_GPIO_AF GPIO_AF6_UART4 + +#define USART_RX_GPIO_PORT GPIOB +#define USART_RX_GPIO_PIN GPIO_PIN_2 +#define USART_RX_GPIO_AF GPIO_AF8_UART4 + +#define USART_UX UART4 +#define USART_UX_IRQ_N UART4_IRQn +#define USART_UX_IRQ_HANDLER UART4_IRQHandler + +/*******************************************************************************************************/ + +#define USART_EN_RX 1 /* USART_EN使能 */ + +void UART_Init(uint32_t baudrate); +int UART_Out(int ch); + +#endif diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Inc/var_monitor_process.h b/src/tools/hispark_trace/hispark/CM4/Core/Inc/var_monitor_process.h new file mode 100644 index 0000000000000000000000000000000000000000..c8c6c2361378abd0f563d1b0b01758947491bc44 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Inc/var_monitor_process.h @@ -0,0 +1,146 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file var_monitor_process.h + * @author MCU Driver Team + * @brief Processes variable monitoring data. The functions are as follows: + * + Variable monitoring. + * + Continuous Address Variable Monitoring Acceleration. + * + Variable monitoring performance test. + * + modifying variable values... + */ +#ifndef VAR_MONITOR_PROCESS_H +#define VAR_MONITOR_PROCESS_H + +#include + +#define MAX_VAR_NUM 300 +#define DISCONNECT_SESSION_TIMEOUT 5000000 +#define FLASH_BOUNDARY 0x400 + +#define BUS_CHANNEL_AHB 0x1000000 + +#define ACCESS_MEMORY_LEN_JTAG 0x0 +#define ACCESS_MEMORY_LEN_SWD 0x1 + +#define ACCESS_MEMORY_ADDR_JTAG 0x4 +#define ACCESS_MEMORY_ADDR_SWD 0x5 + +#define WRITE_MEMORY_JTAG 0xC +#define WRITE_MEMORY_SWD 0xD + +#define READ_MEMORY_PRE_JTAG 0xE +#define READ_MEMORY_PRE_SWD 0xF + +#define READ_MEMORY_END 0xE + +#define ACCESS_DISCONTINUOUS_ONE_BYTE 0x0 +#define ACCESS_DISCONTINUOUS_TWO_BYTE 0x1 +#define ACCESS_DISCONTINUOUS_FOUR_BYTE 0x2 +#define ACCESS_CONTINUOUS_FOUR_BYTE 0x22 + +#define ALIGN_FOUR_BYTE 0x3 + +#define LOW_32_BIT 0x00000000ffffffff +#define HIGH_32_BIT 0xffffffff00000000 + + +#define VARTYPE_CHAR_LEN sizeof(uint8_t) +#define VARTYPE_SHORT_LEN sizeof(uint16_t) +#define VARTYPE_INT_LEN sizeof(uint32_t) +#define VARTYPE_LONG_LEN sizeof(uint64_t) + +#define ADDR_INTERVAL_LEN_ONE 1 +#define ADDR_INTERVAL_LEN_TWO 2 +#define ADDR_INTERVAL_LEN_THREE 3 +#define ADDR_INTERVAL_LEN_FOUR 4 + +#define PARSING_CONTINUOUS 0 +#define PARSING_ENDING 1 + +#define RET_SUCCESS 0 +#define MALLOC_FAIL (-1) +#define RET_FAIL (-2) + + +typedef enum { + TYPE_CHAR = 0x1, + TYPE_SHORT = 0x2, + TYPE_INT = 0x4, + TYPE_LONG = 0x8, + TYPE_MIX = 0xff +} VAR_TYPE; + +typedef struct { + unsigned int address; + unsigned int len; + unsigned long long value; +} DapWriteVar; + +typedef struct { + unsigned int varAddress; + unsigned int varNumBytes; +} DapVarList; + +typedef struct { + unsigned int isSample; + unsigned int periodUs; + unsigned int varNum; + DapVarList *varList; +} DapVarMonitor; + +/* Used to record the address sequence before sorting. */ +typedef struct { + unsigned int map; + unsigned char sampleValue[8]; +} DapAddressMap; + +typedef struct { + unsigned int position[MAX_VAR_NUM]; + unsigned int len[MAX_VAR_NUM]; +} DapPositionInfo; + +/* Used to group incremental addresses */ +typedef struct { + unsigned int startAddress; + unsigned int length; + VAR_TYPE type; + unsigned int mixPosition; +} DapAddressGroup; + +typedef struct { + unsigned int isAddressMapFlag; + unsigned int isAddressIncrementFlag; + unsigned int count; + DapAddressGroup *addressGroup; + unsigned int *addressMap; /* Save the position of the sorted variable. */ +} DapAddressGroupList; + +extern DapVarMonitor g_dapValMonitor; +extern DapWriteVar g_dapWriteVar; +extern uint32_t g_isPerformanceTestFlag; +extern uint32_t g_pauseSampleState; +extern uint8_t JTAG_RESET(void); + +uint8_t WriteOneVal(uint32_t addr, uint32_t length, uint64_t value); +void ReadMemoryToQueue(void); +int StartSampling(void); +void StopSampling(void); +void PauseSampling(uint32_t state); +void FreeMemory(void); + +#endif /* #ifndef VAR_MONITOR_PROCESS_H */ diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Inc/var_monitor_queue.h b/src/tools/hispark_trace/hispark/CM4/Core/Inc/var_monitor_queue.h new file mode 100644 index 0000000000000000000000000000000000000000..5ddecb79b2b309051ade0a1aeeefba2105005752 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Inc/var_monitor_queue.h @@ -0,0 +1,54 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file var_monitor_queue.h + * @author MCU Driver Team + * @brief Shared queue for storing variable monitoring data. + */ +#ifndef VAR_MONITOR_QUEUE_H +#define VAR_MONITOR_QUEUE_H + +#define VARQ_SECTION __attribute__((section(".varq_section"))) +#define VARQ_SIZE (0x1E000 - 18 * sizeof(unsigned int)) /* (120k - 72)bytes */ + +/** + * VarQueue - queue structure + * @read: position of read + * @write: position of write + * @size: buffer size + * @totalReadSize: Read the total size. + * @totalWriteSize: Write the total size. + */ +typedef struct { + unsigned long long read; + unsigned long long write; + unsigned long long size; + unsigned long long totalReadSize; + unsigned long long totalWriteSize; + unsigned long long totalSampleCount; + unsigned long long totalOverflowCount; + unsigned long long totalErrorCount; + unsigned int exceptionExitFlag; + unsigned int errorRate; + char buf[VARQ_SIZE]; +} volatile VarQueue; + +void QueueInit(VarQueue *q); +void QueueDestroy(VarQueue *q); +unsigned int WriteQueue(VarQueue *q, const unsigned char *buf, unsigned int len); + +#endif /* #ifndef VAR_MONITOR_QUEUE_H */ diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Src/gpio_config.c b/src/tools/hispark_trace/hispark/CM4/Core/Src/gpio_config.c new file mode 100644 index 0000000000000000000000000000000000000000..490b055045fad056a789e4c1d8049d97bd548999 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Src/gpio_config.c @@ -0,0 +1,79 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file gpio_config.c + * @author MCU Driver Team + * @brief gpio config. + */ +#include "stm32mp1xx.h" +#include "gpio_config.h" + +void GpioConfigInit(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + /* enable clock to ports */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + + /* config SWD and JTAG */ + GPIO_InitStructure.Pin = SWDIO_INOUT_OE_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_PULLUP; + HAL_GPIO_Init(SWDIO_INOUT_OE_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = SWCLK_TCK_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_PULLDOWN; + HAL_GPIO_Init(SWCLK_TCK_PIN_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = SWDIO_OUT_TMS_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_PULLUP; + HAL_GPIO_Init(SWDIO_OUT_TMS_PIN_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = SWDIO_IN_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_INPUT; + GPIO_InitStructure.Pull = GPIO_PULLUP; + HAL_GPIO_Init(SWDIO_IN_PIN_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = JTAG_TDI_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_PULLUP; + HAL_GPIO_Init(JTAG_TDI_PIN_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = JTAG_TDO_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_INPUT; + GPIO_InitStructure.Pull = GPIO_PULLUP; + HAL_GPIO_Init(JTAG_TDO_PIN_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = JTAG_TRST_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_PULLDOWN; + HAL_GPIO_Init(JTAG_TRST_PIN_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = JTAG_TARGET_RST_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_PULLUP; + HAL_GPIO_Init(JTAG_TARGET_RST_PIN_PORT, &GPIO_InitStructure); +} diff --git a/src/middleware/hisilicon/nostask/kernel/nos_task_del.c b/src/tools/hispark_trace/hispark/CM4/Core/Src/main.c similarity index 58% rename from src/middleware/hisilicon/nostask/kernel/nos_task_del.c rename to src/tools/hispark_trace/hispark/CM4/Core/Src/main.c index ac3d875491b61504fd2c83f87b9130babb5b7bc6..fe11ce57f9b6e3dac2963e16742ecba5c6ef2636 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_task_del.c +++ b/src/tools/hispark_trace/hispark/CM4/Core/Src/main.c @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,53 +15,57 @@ * 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. - * @file nos_task_del.c + * @file main.c + * @author MCU Driver Team + * @brief daplink cortex-m4 main entry */ -#include "nos_task_internal.h" -#include "nos_buildef.h" +#include "timer.h" +#include "gpio_config.h" +#include "msg_queue.h" +#include "var_monitor_process.h" +#include "transfer_data_process.h" -#if defined(OS_OPTION_TASK_DELETE) -/* - * 描述: 删除一个任务线程 - */ -unsigned int OsTaskDelStatusCheck(struct TagTskCB *taskCB) -{ - /* If the task is running and scheduler is locked */ - /* then can not delete it */ - if ((taskCB == RUNNING_TASK) && (OS_TASK_LOCK_DATA != 0)) { - return OS_ERRNO_TSK_DELETE_LOCKED; - } +/* Private includes ----------------------------------------------------------*/ - if (TSK_StatusTst(taskCB, OS_TSK_QUEUE_BUSY)) { - return OS_ERRNO_TSK_QUEUE_DOING; - } - - return NOS_OK; +void _init(void) +{ + ; // do nothing } -#endif -void OsTaskExit(struct TagTskCB *tsk) +void SysTick_Handler(void) { -#if defined(OS_OPTION_TASK_DELETE) - /* delete task */ - (void)NOS_TaskDeleteInner(tsk->taskPid); -#else - uintptr_t intSave = NOS_TaskIntLock(); - - OsTskReadyDel(tsk); - tsk->taskStatus = OS_TSK_UNUSED; - - /* 任务调度 */ - OsTskSchedule(); + HAL_IncTick(); /* Tick Increase */ +} - NOS_TaskIntRestore(intSave); +#ifdef __GNUC__ +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) +#else +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif +PUTCHAR_PROTOTYPE +{ + while ((USART3->ISR & 0X40) == 0) { + ; + } + USART3->TDR = (uint8_t) ch; + return ch; } -/* - * 描述: 删除一个任务线程 - */ -unsigned int NOS_TaskDeleteInner(unsigned int taskPid) +/** + * @brief The application entry point. + * @retval int + */ +int main(void) { - return OsTaskDelete(taskPid); -} \ No newline at end of file + HAL_Init(); + TimerInit(); /* Init timer for tick */ + + GpioConfigInit(); + MSGQ_Init(); /* Init Message Queue */ + + TransferDataProcessInit(); + while (1) { + TransferDataProcess(); + ReadMemoryToQueue(); + } +} diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Src/swd_jtag_config.c b/src/tools/hispark_trace/hispark/CM4/Core/Src/swd_jtag_config.c new file mode 100644 index 0000000000000000000000000000000000000000..631112e5afaa8169b694f32f4339e3a95268a3f7 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Src/swd_jtag_config.c @@ -0,0 +1,205 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file swd_jtag_config.c + * @author MCU Driver Team + * @brief swd and jtag config. + */ +#include "swd_jtag_config.h" +#include "debug.h" + +#define SWD_JTAG_MIN_CLOCK_LEVEL_0 12000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_1 10000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_2 9000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_3 8000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_4 7000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_5 6000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_6 5000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_7 4000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_8 3000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_9 2000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_10 1000000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_11 800000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_12 600000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_13 500000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_14 400000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_15 300000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_16 250000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_17 200000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_18 180000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_19 150000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_20 130000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_21 100000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_22 85000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_23 60000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_24 50000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_25 30000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_26 20000 +#define SWD_JTAG_MIN_CLOCK_LEVEL_27 10000 + +#define SWD_JTAG_MAX_DELAY_LEVEL_CNT 19 +#define SWD_JTAG_CLOCK_NORMAL_LEVEL_CNT 11 + +typedef struct _DelayInfo { + uint32_t delayLevel; + uint32_t baseValue; + uint32_t average; +} DelayInfo; + +typedef struct _ClockLevelInfo { + uint32_t minClock; + uint32_t level; +} ClockLevelInfo; + +/* All data in the following tables are based on actual measurements. */ +const DelayInfo g_delayInfo[SWD_JTAG_MAX_DELAY_LEVEL_CNT] = { + {SWD_JTAG_MIN_CLOCK_LEVEL_10, 7, 200000}, /* base value is 7, average is 200000 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_11, 9, 100000}, /* base value is 9, average is 100000 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_12, 12, 66000}, /* base value is 12, average is 66000 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_13, 15, 33000}, /* base value is 15, average is 33000 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_14, 20, 20000}, /* base value is 20, average is 20000 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_15, 27, 14285}, /* base value is 27, average is 14285 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_16, 33, 8333}, /* base value is 33, average is 8333 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_17, 41, 6250}, /* base value is 41, average is 6250 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_18, 46, 4000}, /* base value is 46, average is 4000 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_19, 55, 3333}, /* base value is 55, average is 3333 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_20, 65, 2200}, /* base value is 65, average is 2200 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_21, 85, 1200}, /* base value is 85, average is 1200 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_22, 100, 1000}, /* base value is 100, average is 1000 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_23, 140, 625}, /* base value is 140, average is 625 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_24, 170, 333}, /* base value is 170, average is 333 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_25, 280, 182}, /* base value is 280, average is 182 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_26, 400, 83}, /* base value is 400, average is 83 */ + {SWD_JTAG_MIN_CLOCK_LEVEL_27, 900, 20}, /* base value is 900, average is 20 */ + {0, 1500, 20} /* base value is 1500, average is 20 */ +}; + +const ClockLevelInfo g_clockLevelInfo[SWD_JTAG_CLOCK_NORMAL_LEVEL_CNT] = { + {SWD_JTAG_MIN_CLOCK_LEVEL_0, SWD_JTAG_CLOCK_LEVEL_1}, + {SWD_JTAG_MIN_CLOCK_LEVEL_1, SWD_JTAG_CLOCK_LEVEL_1}, + {SWD_JTAG_MIN_CLOCK_LEVEL_2, SWD_JTAG_CLOCK_LEVEL_2}, + {SWD_JTAG_MIN_CLOCK_LEVEL_3, SWD_JTAG_CLOCK_LEVEL_3}, + {SWD_JTAG_MIN_CLOCK_LEVEL_4, SWD_JTAG_CLOCK_LEVEL_4}, + {SWD_JTAG_MIN_CLOCK_LEVEL_5, SWD_JTAG_CLOCK_LEVEL_5}, + {SWD_JTAG_MIN_CLOCK_LEVEL_6, SWD_JTAG_CLOCK_LEVEL_6}, + {SWD_JTAG_MIN_CLOCK_LEVEL_7, SWD_JTAG_CLOCK_LEVEL_7}, + {SWD_JTAG_MIN_CLOCK_LEVEL_8, SWD_JTAG_CLOCK_LEVEL_8}, + {SWD_JTAG_MIN_CLOCK_LEVEL_9, SWD_JTAG_CLOCK_LEVEL_9}, + {SWD_JTAG_MIN_CLOCK_LEVEL_10, SWD_JTAG_CLOCK_LEVEL_LOW} +}; + +DAP_Data_t g_DAP_Data = { + .swd_conf.turnaround = 1, + .transfer.idle_cycles = 0, + .swd_conf.data_phase = 0, + .clock_level = SWD_JTAG_CLOCK_LEVEL_6, + .clock_delay = 1, + .jtag_dev.index = 0, + .jtag_dev.count = 1, + .jtag_dev.ir_length[0] = 4, /* ir length is 4 */ + .jtag_dev.ir_before[0] = 0, + .jtag_dev.ir_after[0] = 0, +}; + +static void SwdJtagDelaySet(uint32_t clock) +{ + uint32_t baseValue; + uint32_t offsetValue; + + for (int i = 0; i < SWD_JTAG_MAX_DELAY_LEVEL_CNT; i++) { + if (clock >= g_delayInfo[i].delayLevel) { + baseValue = g_delayInfo[i].baseValue; + offsetValue = (clock - g_delayInfo[i].delayLevel) / g_delayInfo[i].average; + g_DAP_Data.clock_delay = baseValue - offsetValue; + break; + } + } +} + +int SwdTurnaroundSet(uint8_t turnaround) +{ + g_DAP_Data.swd_conf.turnaround = turnaround; + return 0; +} + +uint8_t SwdTurnaroundGet(void) +{ + return g_DAP_Data.swd_conf.turnaround; +} + +int SwdDataPhaseSet(uint8_t phase) +{ + g_DAP_Data.swd_conf.data_phase = phase; + return 0; +} + +uint8_t SwdDataPhaseGet(void) +{ + return g_DAP_Data.swd_conf.data_phase; +} + +int SwdJtagIdleCyclesSet(uint8_t cycles) +{ + g_DAP_Data.transfer.idle_cycles = cycles; + return 0; +} + +uint8_t SwdJtagIdleCyclesGet(void) +{ + return g_DAP_Data.transfer.idle_cycles; +} + +int SwdJtagClockLevelSet(uint32_t clock) +{ + for (int i = 0; i < SWD_JTAG_CLOCK_NORMAL_LEVEL_CNT; i++) { + if (clock >= g_clockLevelInfo[i].minClock) { + g_DAP_Data.clock_level = g_clockLevelInfo[i].level; + break; + } + } + if (g_DAP_Data.clock_level == SWD_JTAG_CLOCK_LEVEL_LOW) { + SwdJtagDelaySet(clock); + } + return 0; +} + +uint32_t SwdJtagClockLevelGet(void) +{ + return g_DAP_Data.clock_level; +} + +int SwdJtagClockDelaySet(uint32_t delay) +{ + g_DAP_Data.clock_delay = delay; + return 0; +} + +uint32_t SwdJtagClockDelayGet(void) +{ + return g_DAP_Data.clock_delay; +} + +int SwdJtagDebugPortSet(uint8_t port) +{ + g_DAP_Data.debug_port = port; + return 0; +} + +uint8_t SwdJtagDebugPortGet(void) +{ + return g_DAP_Data.debug_port; +} diff --git a/src/middleware/hisilicon/nostask/kernel/nos_task_privdata.c b/src/tools/hispark_trace/hispark/CM4/Core/Src/timer.c similarity index 50% rename from src/middleware/hisilicon/nostask/kernel/nos_task_privdata.c rename to src/tools/hispark_trace/hispark/CM4/Core/Src/timer.c index 79356f201cbf329e272d7a1f52d8260bc664162f..058e8021855370dd3be14cb12c0a2b422f73b6df 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_task_privdata.c +++ b/src/tools/hispark_trace/hispark/CM4/Core/Src/timer.c @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,66 +15,51 @@ * 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. - * @file nos_task_privdata.c + * @file timer.c + * @author MCU Driver Team + * @brief Timer Init and start, get tick function */ -#include "nos_task_external.h" +#include "timer.h" +#include "stm32mp1xx_hal_tim.h" -/* - * 描述: 获取当前任务的私有数据。只由本任务操作,不存在竞争,无须关中断。 +/** + * @brief Timer Init + * @retval No */ -uintptr_t NOS_TaskPrivateDataGet(void) +void TimerInit(void) { - struct TagTskCB *taskCB = RUNNING_TASK; + TIM_HandleTypeDef tim; /* 定时器x句柄 */ + GtimTimxClkEnable(); /* 使能TIMx时钟 */ - return taskCB->privateData; -} + tim.Instance = GTIM_TIMX; /* 通用定时器x */ + tim.Init.Prescaler = 199; /* 分频199 */ + tim.Init.CounterMode = TIM_COUNTERMODE_UP; /* 向上计数器 */ + tim.Init.Period = 0xFFFFFFFF; /* 自动装载值 */ + tim.Init.AutoReloadPreload = 1; /* 自动装载值 */ + tim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; /* 时钟分频因子 */ + HAL_TIM_Base_Init(&tim); -/* - * 描述: 设置当前任务的私有数据。只由本任务操作,不存在竞争,无须关中断。 - */ -void NOS_TaskPrivateDataSet(uintptr_t privateData) -{ - struct TagTskCB *taskCB = RUNNING_TASK; - taskCB->privateData = privateData; + HAL_TIM_Base_Start(&tim); /* 使能定时器x和定时器x更新中断 */ } -#if defined(OS_OPTION_306X) -/* - * 描述: 获取指定任务的私有数据。 +/** + * @brief Get current tick + * @retval tick(us) */ -unsigned int OsTaskPrivateDataGetById(unsigned int taskPid, uintptr_t *privateData) +unsigned int GetTimerTickUs(void) { - struct TagTskCB *taskCB; - - if (privateData == NULL) { - return OS_ERRNO_TSK_PTR_NULL; - } - - /* check taskId */ - if (CheckTaskPidOverflow(taskPid)) { - return OS_ERRNO_TSK_ID_INVALID; - } - - taskCB = GetTcbHandle(taskPid); - // 排除大部分不法情况 - if (taskCB->taskStatus == OS_TSK_UNUSED) { - return OS_ERRNO_TSK_NOT_CREATED; - } - - *privateData = taskCB->privateData; - - return NOS_OK; + return (unsigned int)(GTIM_TIMX->CNT); } -/* - * 描述: 获取指定任务的私有数据。 +/** + * @brief Get Delta of two ticks + * @retval delta */ -uintptr_t NOS_TaskPrivateDataGetById(unsigned int taskPid) +unsigned int GetDelta(unsigned int curTicks, unsigned int preTicks) { - uintptr_t privateData = 0; - (void)OsTaskPrivateDataGetById(taskPid, &privateData); - return privateData; + if (curTicks >= preTicks) { + return curTicks - preTicks; + } else { + return 0xFFFFFFFF - preTicks + curTicks + 1; + } } - - -#endif diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Src/transfer_data_process.c b/src/tools/hispark_trace/hispark/CM4/Core/Src/transfer_data_process.c new file mode 100644 index 0000000000000000000000000000000000000000..007067d7350eed6cde867d6e609589ecea9d7306 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Src/transfer_data_process.c @@ -0,0 +1,334 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file transfer_data_process.c + * @author MCU Driver Team + * @brief Data Processing of Heteronuclear Communication. + */ +#include +#include +#include +#include "securec.h" +#include "DAP_config.h" +#include "DAP.h" +#include "msg_queue.h" +#include "debug.h" +#include "gpio_config.h" +#include "swd_jtag_config.h" +#include "var_monitor_process.h" +#include "transfer_data_process.h" + +#define MAX_SWD_RETRY 100 + +#define TRANSFER_DATA_PROCESS_IDLE 0 +#define TRANSFER_DATA_PROCESS_DEBUG 1 +#define TRANSFER_DATA_PROCESS_SAMPLEINIT 2 +#define TRANSFER_DATA_PROCESS_WRITEVAR 3 +#define TRANSFER_DATA_PROCESS_CLOCK_CONFIG 4 +#define TRANSFER_DATA_PROCESS_PERFORMANCE_TEST 5 +#define TRANSFER_DATA_PROCESS_DEBUG_PORT_CONFIG 6 +#define TRANSFER_DATA_PROCESS_PAUSESAMPLEINIT 7 + +typedef struct { + uint32_t request; + uint32_t data; +}TransferDebugInfo; + +static uint32_t g_transferDataProcessState = TRANSFER_DATA_PROCESS_IDLE; +static uint32_t g_transferDataProcessPreState = TRANSFER_DATA_PROCESS_IDLE; +static TransferDebugInfo g_transfetDebugInfo; +static uint32_t g_configClock = 0; +static uint32_t g_debugPortConfig = DAP_PORT_DISABLED; + + +/** + * @brief Saves the variable list information delivered by core A. + * @param data Pointer to the data delivered by core A. + * @param len Length of data delivered by core A. + * @retval None. + */ +static void SaveSamplingMsgData(uint8_t *data, uint32_t len) +{ + uint32_t bufLen1 = sizeof(DapVarMonitor) - sizeof(DapVarList *); + bufLen1 = bufLen1 > len ? len : bufLen1; + memcpy_s(&g_dapValMonitor, sizeof(DapVarMonitor), data, bufLen1); + + if (g_dapValMonitor.isSample != 0) { + if (g_dapValMonitor.varList != NULL) { + free(g_dapValMonitor.varList); + g_dapValMonitor.varList = NULL; + } + g_dapValMonitor.varList = malloc(g_dapValMonitor.varNum * sizeof(DapVarList)); + if (g_dapValMonitor.varList == NULL) { + DBG_PRINTF("g_dapValMonitor.varList malloc fail!!\r\n"); + FreeMemory(); + return; + } + memcpy_s(g_dapValMonitor.varList, (g_dapValMonitor.varNum * sizeof(DapVarList)), + (data + bufLen1), g_dapValMonitor.varNum * sizeof(DapVarList)); + } +} + +/** + * @brief Saves the write variable information delivered by core A. + * @param data Pointer to the data delivered by core A. + * @param len Length of data delivered by core A. + * @retval None. + */ +static void SaveWriteVarMsgData(uint8_t *data, uint32_t len) +{ + memcpy_s(&g_dapWriteVar, sizeof(g_dapWriteVar), data, len); +} + +static bool SaveClockConfig(uint8_t *data, uint32_t len) +{ + errno_t rc = EOK; + rc = memcpy_s(&g_configClock, sizeof(g_configClock), data, len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Saves the performance test information delivered by core A. + * @param data Pointer to the data delivered by core A. + * @param len Length of data delivered by core A. + * @retval true or false. + */ +static bool SavePerformanceTestMsgData(uint8_t *data, uint32_t len) +{ + errno_t rc = EOK; + rc = memcpy_s(&g_isPerformanceTestFlag, sizeof(g_isPerformanceTestFlag), data, len); + if (rc != EOK) { + return false; + } + return true; +} + +static bool SaveDebugPortConfig(uint8_t *data, uint32_t len) +{ + errno_t rc = EOK; + rc = memcpy_s(&g_debugPortConfig, sizeof(g_debugPortConfig), data, len); + if (rc != EOK) { + return false; + } + return true; +} + +/** + * @brief Saves the pause sampling information delivered by core A. + * @param data Pointer to the data delivered by core A. + * @param len Length of data delivered by core A. + * @retval true or false. + */ +static bool SavePauseSamplingMsgData(uint8_t *data, uint32_t len) +{ + errno_t rc = EOK; + rc = memcpy_s(&g_pauseSampleState, sizeof(g_pauseSampleState), data, len); + if (rc != EOK) { + return false; + } + return true; +} + +static void MsgProcess(void) +{ + MsgBuf msg; + if (MSGQ_RxIsEmpty() != true) { + MSGQ_ReceiveMsg(&msg); + switch (msg.type) { + case MSG_TYPE_SAMPLING: + SaveSamplingMsgData(msg.buf, msg.bufLen); + g_transferDataProcessPreState = g_transferDataProcessState; + g_transferDataProcessState = TRANSFER_DATA_PROCESS_SAMPLEINIT; + break; + case MSG_TYPE_WRITEVAR: + SaveWriteVarMsgData(msg.buf, msg.bufLen); + g_transferDataProcessPreState = g_transferDataProcessState; + g_transferDataProcessState = TRANSFER_DATA_PROCESS_WRITEVAR; + break; + case MSG_TYPE_CLK_CFG: + SaveClockConfig(msg.buf, msg.bufLen); + g_transferDataProcessPreState = g_transferDataProcessState; + g_transferDataProcessState = TRANSFER_DATA_PROCESS_CLOCK_CONFIG; + break; + case MSG_TYPE_PERFORMANCE_TEST: + SavePerformanceTestMsgData(msg.buf, msg.bufLen); + g_transferDataProcessPreState = g_transferDataProcessState; + g_transferDataProcessState = TRANSFER_DATA_PROCESS_PERFORMANCE_TEST; + break; + case MSG_TYPE_DEBUG_PORT_SET: + SaveDebugPortConfig(msg.buf, msg.bufLen); + g_transferDataProcessPreState = g_transferDataProcessState; + g_transferDataProcessState = TRANSFER_DATA_PROCESS_DEBUG_PORT_CONFIG; + break; + case MSG_TYPE_PAUSESAMPLING: + SavePauseSamplingMsgData(msg.buf, msg.bufLen); + g_transferDataProcessPreState = g_transferDataProcessState; + g_transferDataProcessState = TRANSFER_DATA_PROCESS_PAUSESAMPLEINIT; + break; + default: + break; + } + } +} + +static void IdleProcess(void) +{ + MsgProcess(); +} + +/** + * @brief Start/Stop sampling processing. + * @param None. + * @retval None. + */ +static void SamplingProcess(void) +{ + MsgBuf msg; + int retValue; + + msg.type = MSG_TYPE_SAMPLING; + msg.bufLen = sizeof(unsigned char); + msg.buf[0] = Q_TRUE; + if (g_dapValMonitor.isSample != 0) { + DBG_PRINTF("M start\r\n"); + retValue = StartSampling(); + if (retValue != RET_SUCCESS) { + StopSampling(); + msg.buf[0] = Q_FALSE; + } + } else { + DBG_PRINTF("M STOP\r\n"); + StopSampling(); + } + MSGQ_SendMsg(&msg); + g_transferDataProcessState = g_transferDataProcessPreState; + MsgProcess(); +} + +/** + * @brief Write variable processing. + * @param None. + * @retval None. + */ +static void WriteVarProcess(void) +{ + uint8_t ret; + MsgBuf msg; + + ret = WriteOneVal(g_dapWriteVar.address, g_dapWriteVar.len, g_dapWriteVar.value); + if (ret == DAP_TRANSFER_OK) { + msg.buf[0] = Q_TRUE; + } else { + msg.buf[0] = Q_FALSE; + } + msg.type = MSG_TYPE_WRITEVAR; + msg.bufLen = sizeof(unsigned char); + MSGQ_SendMsg(&msg); + g_transferDataProcessState = g_transferDataProcessPreState; + MsgProcess(); +} + +/** + * @brief pause sampling processing. + * @param None. + * @retval None. + */ +static void PauseSamplingProcess(void) +{ + MsgBuf msg; + + PauseSampling(g_pauseSampleState); + msg.type = MSG_TYPE_PAUSESAMPLING; + msg.bufLen = sizeof(unsigned char); + msg.buf[0] = Q_TRUE; + MSGQ_SendMsg(&msg); + g_transferDataProcessState = g_transferDataProcessPreState; + MsgProcess(); +} + +static void ClockConfigProcess(void) +{ + SwdJtagClockLevelSet(g_configClock); + g_transferDataProcessState = g_transferDataProcessPreState; + MsgProcess(); +} + +/** + * @brief Performance test processing. + * @param None. + * @retval None. + */ +static void PerformanceTestProcess(void) +{ + MsgBuf msg; + + DBG_PRINTF("g_isPerformanceTestFlag %d\r\n", g_isPerformanceTestFlag); + msg.type = MSG_TYPE_PERFORMANCE_TEST; + msg.bufLen = sizeof(unsigned char); + msg.buf[0] = Q_TRUE; + MSGQ_SendMsg(&msg); + g_transferDataProcessState = g_transferDataProcessPreState; + MsgProcess(); +} + +static void DebugPortConfigProcess(void) +{ + SwdJtagDebugPortSet((uint8_t)g_debugPortConfig); + g_transferDataProcessState = g_transferDataProcessPreState; + MsgProcess(); +} + +int32_t TransferDataProcessInit(void) +{ + g_transferDataProcessState = TRANSFER_DATA_PROCESS_IDLE; + g_transferDataProcessPreState = TRANSFER_DATA_PROCESS_IDLE; + g_transfetDebugInfo.data = 0; + g_transfetDebugInfo.request = 0; + return 0; +} + +void TransferDataProcess(void) +{ + switch (g_transferDataProcessState) { + case TRANSFER_DATA_PROCESS_IDLE: + IdleProcess(); + break; + case TRANSFER_DATA_PROCESS_SAMPLEINIT: + SamplingProcess(); + break; + case TRANSFER_DATA_PROCESS_WRITEVAR: + WriteVarProcess(); + break; + case TRANSFER_DATA_PROCESS_CLOCK_CONFIG: + ClockConfigProcess(); + break; + case TRANSFER_DATA_PROCESS_PERFORMANCE_TEST: + PerformanceTestProcess(); + break; + case TRANSFER_DATA_PROCESS_DEBUG_PORT_CONFIG: + DebugPortConfigProcess(); + break; + case TRANSFER_DATA_PROCESS_PAUSESAMPLEINIT: + PauseSamplingProcess(); + break; + default: + break; + } +} diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Src/uart.c b/src/tools/hispark_trace/hispark/CM4/Core/Src/uart.c new file mode 100644 index 0000000000000000000000000000000000000000..c3f151f214adcaa8fc27ad3bec0d6e3922bd1080 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Src/uart.c @@ -0,0 +1,47 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file uart.c + * @author MCU Driver Team + * @brief file uart4 for printf + */ +#include "uart.h" + +int UART_Out(int ch) +{ + /* 串口4输出 */ + while ((USART_UX->ISR & 0x40) == 0) { + ; // waiting for tx done + } + USART_UX->TDR = (uint8_t)ch; + return ch; +} + +void UART_Init(uint32_t baudrate) +{ + /* 串口4初始化 */ + UART_HandleTypeDef uart4Handle; + uart4Handle.Instance = USART_UX; + uart4Handle.Init.BaudRate = baudrate; + /* Use fixed parameters. */ + uart4Handle.Init.WordLength = UART_WORDLENGTH_8B; + uart4Handle.Init.StopBits = UART_STOPBITS_1; + uart4Handle.Init.Parity = UART_PARITY_NONE; + uart4Handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + uart4Handle.Init.Mode = UART_MODE_TX_RX; + HAL_UART_Init(&uart4Handle); +} diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Src/var_monitor_process.c b/src/tools/hispark_trace/hispark/CM4/Core/Src/var_monitor_process.c new file mode 100644 index 0000000000000000000000000000000000000000..abe1022a3e5d4e18953f9724d7c3f24b93749797 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Src/var_monitor_process.c @@ -0,0 +1,1917 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file var_monitor_process.c + * @author MCU Driver Team + * @brief Processes variable monitoring data. The functions are as follows: + * + Variable monitoring. + * + Continuous Address Variable Monitoring Acceleration. + * + Variable monitoring performance test. + * + modifying variable values... + */ +#include +#include +#include +#include "securec.h" +#include "DAP.h" +#include "var_monitor_queue.h" +#include "swd_jtag_config.h" +#include "debug.h" +#include "timer.h" +#include "var_monitor_process.h" + + +#define MAX_SWD_RETRY 100 +#define ERROR_DETECTION_INTERVAL_US 30000UL +#define ERROR_RATE_1 1 +#define ERROR_MAX_ALLOWED 5 + +// SWD register access +#define SWD_REG_AP (1) +#define SWD_REG_DP (0) +#define SWD_REG_R (1<<1) +#define SWD_REG_W (0<<1) +#define SWD_REG_ADR(a) ((a) & 0x0c) + +#define DP_CTRL_STAT 0x04U // Control & Status + +// Debug Control and Status definitions +#define ORUNDETECT 0x00000001 // Overrun Detect +#define STICKYORUN 0x00000002 // Sticky Overrun +#define TRNMODE 0x0000000C // Transfer Mode Mask +#define TRNNORMAL 0x00000000 // Transfer Mode: Normal +#define TRNVERIFY 0x00000004 // Transfer Mode: Pushed Verify +#define TRNCOMPARE 0x00000008 // Transfer Mode: Pushed Compare +#define STICKYCMP 0x00000010 // Sticky Compare +#define STICKYERR 0x00000020 // Sticky Error +#define READOK 0x00000040 // Read OK (SW Only) +#define WDATAERR 0x00000080 // Write Data Error (SW Only) +#define MASKLANE 0x00000F00 // Mask Lane Mask +#define MASKLANE0 0x00000100 // Mask Lane 0 +#define MASKLANE1 0x00000200 // Mask Lane 1 +#define MASKLANE2 0x00000400 // Mask Lane 2 +#define MASKLANE3 0x00000800 // Mask Lane 3 +#define TRNCNT 0x001FF000 // Transaction Counter Mask +#define CDBGRSTREQ 0x04000000 // Debug Reset Request +#define CDBGRSTACK 0x08000000 // Debug Reset Acknowledge +#define CDBGPWRUPREQ 0x10000000 // Debug Power-up Request +#define CDBGPWRUPACK 0x20000000 // Debug Power-up Acknowledge +#define CSYSPWRUPREQ 0x40000000 // System Power-up Request +#define CSYSPWRUPACK 0x80000000 // System Power-up Acknowledge + +// Abort Register definitions +#define DAPABORT 0x00000001 // DAP Abort +#define STKCMPCLR 0x00000002 // Clear STICKYCMP Flag (SW Only) +#define STKERRCLR 0x00000004 // Clear STICKYERR Flag (SW Only) +#define WDERRCLR 0x00000008 // Clear WDATAERR Flag (SW Only) +#define ORUNERRCLR 0x00000010 // Clear STICKYORUN Flag (SW Only) + +/* Save the initialization information of the variable list. */ +DapVarMonitor g_dapValMonitor; +/* Save the modified variable information. */ +DapWriteVar g_dapWriteVar; +/* flag of enabling the performance test. */ +uint32_t g_isPerformanceTestFlag = 0; +/* Sampling pause status. */ +uint32_t g_pauseSampleState; +extern char g_varQStart; +/* Shared memory queue for storing sampled data */ +static VarQueue *g_varMonitorQueue = (VarQueue *)&g_varQStart; +/* Save the grouping information of the variable list optimization sampling. */ +static DapAddressGroupList g_dapAddressGroupList; +/* Stores the position and length information of the mixed variable list. */ +static DapPositionInfo *g_mixPositionInfo; +/* Virtual variables used in the performance test. */ +static unsigned long long int *g_performanceTestVar; +/* Record the length of the variable list in a frame. */ +static uint32_t g_varMonitorFrameSize = 0; +/* Relative Time. */ +static uint32_t g_preTicks = 0; +/* time stamp. */ +static uint32_t g_timeStamp = 0; +/* Flag for enabling variable sampling. */ +static uint32_t g_isReadMemoryFlag = 0; +/* Flag for enabling the configuration of the sampling sequence. */ +static uint32_t g_isValMonitorSetFlag = 0; +/* Timer for calculating error rate */ +static uint32_t g_errorDetectionTimer = 0; +/* Total number of samples used to calculate the error rate. */ +static uint64_t g_errorDetectionTotalCounter = 0; +/* Number of sampling errors used to calculate the error rate. */ +static uint64_t g_errorDetectionErrorCounter = 0; +/* Alarm value of the error rate. */ +static uint32_t g_errorRate = ERROR_RATE_1; +/* Variable counter for parsing optimized sampled data. */ +static uint32_t g_parsingVarCount = 0; + +/** + * @brief SWD/JTAG Interface Transfer Function. + * @param request Indicates the address of the DP/AP register. + * @param data Data to be written or read back. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t SWDJTAG_Transfer(uint32_t request, uint32_t *data) +{ + if (g_DAP_Data.debug_port == DAP_PORT_SWD) { + return SWD_Transfer(request, data); + } else { + return JTAG_Transfer(request, data); + } +} + +static void Int2Array(uint8_t *res, uint32_t data, uint8_t len) +{ + uint8_t i = 0; + + for (i = 0; i < len; i++) { + res[i] = (data >> (8 * i)) & 0xff; /* 8-bit processing */ + } +} + +static uint8_t SwdWriteDP(uint8_t adr, uint32_t val) +{ + uint32_t req; + uint8_t data[4]; + uint8_t ack; + + req = SWD_REG_DP | SWD_REG_W | SWD_REG_ADR(adr); + Int2Array(data, val, 4); /* 4 byte */ + ack = SWDJTAG_Transfer(req, (uint32_t *)data); + return ack; +} + +static uint8_t SwdReadDP(uint8_t adr, uint32_t *val) +{ + uint32_t tmp_in; + uint8_t tmp_out[4]; + uint8_t ack; + uint32_t tmp; + tmp_in = SWD_REG_DP | SWD_REG_R | SWD_REG_ADR(adr); + ack = SWDJTAG_Transfer(tmp_in, (uint32_t *)tmp_out); + *val = 0; + tmp = tmp_out[3]; /* Byte 3 */ + *val |= (tmp << 24); /* Moved leftwards by 24 bits and placed in the most significant byte. */ + tmp = tmp_out[2]; /* Byte 2 */ + *val |= (tmp << 16); /* Moved leftwards by 16 bits */ + tmp = tmp_out[1]; /* Byte 1 */ + *val |= (tmp << 8); /* Moved leftwards by 8 bits */ + tmp = tmp_out[0]; + *val |= (tmp << 0); + + return ack; +} + +/** + * @brief SWD/JTAG interface reset function. + * @retval None. + */ +static void SwdJtagReset(void) +{ + uint8_t tmp_in[8]; + uint8_t i = 0; + /* Transmitted 8-byte 0xFF */ + for (i = 0; i < 8; i++) { + tmp_in[i] = 0xff; + } + /* Transmit 51 timings */ + SWJ_Sequence(51, tmp_in); + return; +} + +static void SwitchSwdJtag(uint16_t val) +{ + uint8_t tmp_in[2]; + tmp_in[0] = val & 0xff; + tmp_in[1] = (val >> 8) & 0xff; /* Shift left by 8 bits */ + SWJ_Sequence(16, tmp_in); /* Transmit 16 timings */ + return; +} + +static void SwdPowerSet(void) +{ + uint32_t timeout = 200; + uint32_t tmp = 0; + + SwdWriteDP(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ); + for (int i = 0; i < timeout; i++) { + SwdReadDP(DP_CTRL_STAT, &tmp); + if ((tmp & (CDBGPWRUPACK | CSYSPWRUPACK)) == (CDBGPWRUPACK | CSYSPWRUPACK)) { + // Break from loop if powerup is complete + break; + } + } + SwdWriteDP(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ | TRNNORMAL | MASKLANE); +} + +/** + * @brief SWD/JTAG interface read idcode function. + * @param id Idcode value. + * @retval None. + */ +static void SwdJtagReadIdcode(uint32_t *id) +{ + uint32_t request; + uint8_t tmp_in[1]; + uint8_t tmp_out[4]; + tmp_in[0] = 0x00; + SWJ_Sequence(8, tmp_in); /* Transmit 8 timings */ + + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + *id = JTAG_ReadIDCode(); + } else { + request = 0x2; + SWDJTAG_Transfer(request, id); + /* The 3 byte is shifted left by 24 bits, the 2 byte is shifted left by 16 bits, + and the 1byte is shifted left by 8 bits. */ + *id = (tmp_out[3] << 24) | (tmp_out[2] << 16) | (tmp_out[1] << 8) | tmp_out[0]; + } + return; +} + +/** + * @brief SWD/JTAG Interface Transfer Retry Function. + * @param request Indicates the address of the DP/AP register. + * @param data Data to be written or read back. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR. + */ +static uint8_t SWDJTAG_TransferRetry(uint32_t request, uint32_t *data) +{ + uint8_t ack; + + for (uint32_t i = 0; i < MAX_SWD_RETRY; i++) { + ack = SWDJTAG_Transfer(request, data); + if (ack != DAP_TRANSFER_WAIT) { + break; + } + } + return ack; +} + +/** + * @brief SWD/JTAG Interface clean error Function. + * @retval None. + */ +static void SwdJtagCleanError(void) +{ + uint32_t request; + uint32_t data; + + data = STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR; + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + JTAG_WriteAbort(data); + return; + } + + request = DP_ABORT; + SWDJTAG_TransferRetry(request, &data); + return; +} + +/** + * @brief Switching the AHB bus channel. + * @param None. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR. + */ +static uint8_t SwitchBusChannel(void) +{ + uint32_t request; + uint32_t data; + + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + /* WriteDP 2 */ + uint32_t ir = JTAG_DPACC; + JTAG_IR(ir); + } + request = DP_SELECT; + data = BUS_CHANNEL_AHB; + + return SWDJTAG_TransferRetry(request, &data); +} + +/** + * @brief Sets the length of the memory to be accessed. + * @param accessLength length of the memory to be accessed. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t SetAccessMemoryLength(uint32_t accessLength) +{ + uint32_t request; + uint32_t data; + + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + /* WriteAP 0 */ + uint32_t ir = JTAG_APACC; + JTAG_IR(ir); + request = ACCESS_MEMORY_LEN_JTAG; + } else { + request = ACCESS_MEMORY_LEN_SWD; + } + data = accessLength; + + return SWDJTAG_TransferRetry(request, &data); +} + +/** + * @brief Sets the address of the memory to be accessed. + * @param addr address of the memory to be accessed. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t SetAccessMemoryAddr(uint32_t addr) +{ + uint32_t request; + uint32_t data; + + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + /* WriteAP 1 */ + uint32_t ir = JTAG_APACC; + JTAG_IR(ir); + request = ACCESS_MEMORY_ADDR_JTAG; + } else { + request = ACCESS_MEMORY_ADDR_SWD; + } + data = addr; + + return SWDJTAG_TransferRetry(request, &data); +} + +/** + * @brief Modifying the Memory. + * @param value Modified memory value. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t WriteMemory(uint32_t value) +{ + uint32_t request; + uint32_t data; + + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + /* WriteAP 3 */ + uint32_t ir = JTAG_APACC; + JTAG_IR(ir); + request = WRITE_MEMORY_JTAG; + } else { + request = WRITE_MEMORY_SWD; + } + data = value; + + return SWDJTAG_TransferRetry(request, &data); +} + +/** + * @brief Preparation for reading the memory. + * @param None. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t ReadMemoryPrepare(void) +{ + uint32_t request; + + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + /* Read AP3 */ + uint32_t ir = JTAG_APACC; + JTAG_IR(ir); + request = READ_MEMORY_PRE_JTAG; + } else { + request = READ_MEMORY_PRE_SWD; + } + + return SWDJTAG_TransferRetry(request, NULL); +} + +/** + * @brief Read the memory continuously. + * @param outData Read back memory data. + * @param len Data len. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR. + */ +static uint8_t ReadMemoryContinuous(uint8_t *outData, uint32_t len) +{ + uint32_t request; + + if (len > sizeof(uint32_t)) { /* Length verification */ + return DAP_TRANSFER_FAULT; + } + + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + /* Read AP3 */ + uint32_t ir = JTAG_APACC; + JTAG_IR(ir); + request = READ_MEMORY_PRE_JTAG; /* Jtag request */ + } else { + request = READ_MEMORY_PRE_SWD; /* Swd request */ + } + + return SWDJTAG_TransferRetry(request, (uint32_t *)outData); +} + +/** + * @brief Last readback memory. + * @param outData Read back memory data. + * @param len data len + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t ReadMemoryEnd(uint8_t *outData, uint32_t len) +{ + uint32_t request; + + if (len > sizeof(uint32_t)) { + return DAP_TRANSFER_FAULT; + } + + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + /* Read DP3 */ + uint32_t ir = JTAG_DPACC; + JTAG_IR(ir); + } + request = READ_MEMORY_END; + + return SWDJTAG_TransferRetry(request, (uint32_t *)outData); +} + +/** + * @brief Sample a frame of complete data. + * @param addr sample addr. + * @param length sample length. + * @param outData sample data. + * @param maxLen Max data len. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t SamplingOneVal(uint32_t addr, uint32_t length, uint8_t *outData, uint32_t maxLen) +{ + uint32_t data; + uint8_t ack; + int32_t count = length / VARTYPE_INT_LEN; + uint8_t *outDataPtr = outData; + + if (maxLen > VARTYPE_LONG_LEN) { + return DAP_TRANSFER_FAULT; /* Error check */ + } + /* req = 8, data = 1000000 + req = 5, data = 4001800 + req = F, data = EA00000D + req = E, data = 0 */ + if (g_isValMonitorSetFlag == 0) { + g_isValMonitorSetFlag = 1; + + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + JTAG_RESET(); /* reset jtag */ + } + ack = SwitchBusChannel(); /* Switching Channels */ + if (ack != DAP_TRANSFER_OK) { + return ack; + } + /* Sets the length of the memory to be accessed. */ + ack = SetAccessMemoryLength(ACCESS_DISCONTINUOUS_FOUR_BYTE); + if (ack != DAP_TRANSFER_OK) { + return ack; + } + } + + data = addr; + do { + ack = SetAccessMemoryAddr(data); /* Sets the address for accessing the memory. */ + if (ack != DAP_TRANSFER_OK) { + return ack; + } + /* Read four bytes back */ + data += VARTYPE_INT_LEN; + + ack = ReadMemoryPrepare(); /* Read Memory Value. */ + if (ack != DAP_TRANSFER_OK) { + return ack; + } + + ack = ReadMemoryEnd(outDataPtr, sizeof(uint32_t)); /* Read Memory Value. */ + if (ack != DAP_TRANSFER_OK) { + return ack; + } + outDataPtr += VARTYPE_INT_LEN; + count--; + } while (count > 0); + + return ack; +} + +/** + * @brief Parsing of single-byte and double-byte variable data. + * @param addressGroup Variable grouping information. + * @param destAddr Parsed data. + * @param srcAddr Data before parsing. + * @param valLen Val len. + * @param valType variable type. + * @retval true or false. + */ +static bool ShortDataParsing(DapAddressGroup addressGroup, uint8_t *destAddr, uint8_t *srcAddr, + uint32_t valLen, VAR_TYPE valType) +{ + uint8_t *outDataPtr = destAddr; + unsigned int startAddr = addressGroup.startAddress; + unsigned int groupLen = addressGroup.length; + unsigned int varLength = valType; + errno_t rc = EOK; + + if (valLen > sizeof(uint32_t)) { + return false; + } + + do { + /* Parse the content of each variable from the read four bytes of data. */ + rc = memcpy_s(outDataPtr, + varLength, + (char *)&srcAddr[(startAddr + g_parsingVarCount * varLength) & ALIGN_FOUR_BYTE], + varLength); + if (rc != EOK) { + return false; + } + outDataPtr += VARTYPE_LONG_LEN; + g_parsingVarCount++; + if (g_parsingVarCount == groupLen) { + break; + } + } while (((startAddr + g_parsingVarCount * varLength) & ALIGN_FOUR_BYTE) != 0); + return true; +} + +/** + * @brief Parse the sampled data to the value of the corresponding variable. + * @param addressGroup Variable grouping information. + * @param destAddr Parsed data. + * @param valType variable type. + * @param parsingPhase Data Parsing phase. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t DataParsing(DapAddressGroup addressGroup, uint8_t *destAddr, VAR_TYPE valType, uint8_t parsingPhase) +{ + uint8_t ack; + errno_t rc = EOK; + uint8_t value[4]; + uint8_t *outDataPtr = destAddr; + + if (valType == TYPE_LONG) { + ack = ReadMemoryContinuous(outDataPtr, sizeof(uint32_t)); + if (ack != DAP_TRANSFER_OK) { + return ack; + } + outDataPtr += VARTYPE_INT_LEN; + } + if (parsingPhase == PARSING_CONTINUOUS) { + ack = ReadMemoryContinuous(value, sizeof(value)); + } else if (parsingPhase == PARSING_ENDING) { + ack = ReadMemoryEnd(value, sizeof(value)); + } + if (ack != DAP_TRANSFER_OK) { + return ack; + } + if (valType <= TYPE_SHORT) { + ShortDataParsing(addressGroup, outDataPtr, value, sizeof(value), valType); + } else if (valType == TYPE_INT) { + rc = memcpy_s(outDataPtr, VARTYPE_INT_LEN, (char *)value, VARTYPE_INT_LEN); + } else if (valType == TYPE_LONG) { + rc = memcpy_s(outDataPtr, VARTYPE_INT_LEN, (char *)value, VARTYPE_INT_LEN); + } + if (rc != EOK) { + return DAP_TRANSFER_ERROR; + } + + return ack; +} + +/** + * @brief Sampling and parsing data. + * @param addressGroup Variable grouping information. + * @param sampleCount Number of sampling times. + * @param valType variable type. + * @param outData Data Parsing phase. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t SampleAndParsing(DapAddressGroup addressGroup, uint32_t sampleCount, VAR_TYPE valType, uint8_t *outData) +{ + uint8_t ack = DAP_TRANSFER_ERROR; + uint32_t recordVarCount = 0; + uint8_t *outDataPtr = outData; + + g_parsingVarCount = 0; + for (uint32_t i = 0; i < sampleCount; i++) { + if (i == 0) { + ack = ReadMemoryPrepare(); + } else { + ack = DataParsing(addressGroup, outDataPtr, valType, PARSING_CONTINUOUS); + /* Sampling buffer pointer offset. */ + if (valType == TYPE_CHAR || valType == TYPE_SHORT) { + /* 8 bytes in each step */ + outDataPtr += (g_parsingVarCount - recordVarCount) * VARTYPE_LONG_LEN; + recordVarCount = g_parsingVarCount; + } else if (valType == TYPE_INT || valType == TYPE_LONG) { + /* 8 bytes in each step */ + outDataPtr += VARTYPE_LONG_LEN; + } + } + if (ack != DAP_TRANSFER_OK) { + return ack; + } + + if (i == sampleCount - 1) { + ack = DataParsing(addressGroup, outDataPtr, valType, PARSING_ENDING); + } + } + + return ack; +} + +/** + * @brief Pre-sampled for mixed-type variable groups. + * @param mixPositionInfo Variable information of a mixed type variable group. + * @param outData Read back memory data. + * @param parsingPhase Data Parsing phase. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t DataPrepareMix(const DapPositionInfo *mixPositionInfo, uint8_t *outData, uint8_t parsingPhase) +{ + uint8_t ack; + + if (parsingPhase == PARSING_CONTINUOUS) { + ack = ReadMemoryContinuous(outData, sizeof(uint32_t)); + } else if (parsingPhase == PARSING_ENDING) { + if (mixPositionInfo->len[g_parsingVarCount] != VARTYPE_LONG_LEN) { + ack = ReadMemoryEnd(outData, sizeof(uint32_t)); + } else { + ack = ReadMemoryContinuous(outData, sizeof(uint32_t)); + } + } + + return ack; +} + +/** + * @brief Parsing sampled data for mixed-type variable groups. + * @param mixPositionInfo Variable information of a mixed type variable group. + * @param destAddr Parsed data. + * @param groupLen mixed type variable group length. + * @param parsingPhase Data Parsing phase. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t DataParsingMix(DapPositionInfo *mixPositionInfo, uint8_t *destAddr, unsigned int groupLen, + uint8_t parsingPhase) +{ + uint8_t ack; + errno_t rc = EOK; + uint8_t value[4]; + uint8_t *outDataPtr = destAddr; + + ack = DataPrepareMix(mixPositionInfo, value, parsingPhase); + if (ack != DAP_TRANSFER_OK) { + return ack; + } + do { + if (mixPositionInfo->len[g_parsingVarCount] == VARTYPE_LONG_LEN) { + rc = memcpy_s(outDataPtr, VARTYPE_INT_LEN, (char *)value, VARTYPE_INT_LEN); + if (rc != EOK) { + return DAP_TRANSFER_ERROR; + } + outDataPtr += VARTYPE_INT_LEN; + + if (parsingPhase == PARSING_CONTINUOUS) { + ack = ReadMemoryContinuous(outDataPtr, sizeof(uint32_t)); + } else if (parsingPhase == PARSING_ENDING) { + ack = ReadMemoryEnd(outDataPtr, sizeof(uint32_t)); + } + if (ack != DAP_TRANSFER_OK) { + return ack; + } + outDataPtr += VARTYPE_INT_LEN; + g_parsingVarCount++; + } else { + rc = memcpy_s(outDataPtr, mixPositionInfo->len[g_parsingVarCount], + (char *)&value[mixPositionInfo->position[g_parsingVarCount]], + mixPositionInfo->len[g_parsingVarCount]); + if (rc != EOK) { + return DAP_TRANSFER_ERROR; + } + outDataPtr += VARTYPE_LONG_LEN; + g_parsingVarCount++; + } + if (g_parsingVarCount == groupLen) { + break; + } + } while (mixPositionInfo->position[g_parsingVarCount] != 0); + + return ack; +} + +/** + * @brief char data sampling. + * @param addressGroup Variable grouping information. + * @param outData Parsed data. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t GroupChar(DapAddressGroup addressGroup, uint8_t *outData) +{ + uint8_t ack; + uint32_t sampleCount; + + /* Number of sampling times for determining the number of char variables */ + sampleCount = ((addressGroup.startAddress & ALIGN_FOUR_BYTE) + addressGroup.length * TYPE_CHAR) / VARTYPE_INT_LEN; + if ((((addressGroup.startAddress & ALIGN_FOUR_BYTE) + addressGroup.length * TYPE_CHAR) % VARTYPE_INT_LEN) != 0) { + sampleCount++; + } + + ack = SampleAndParsing(addressGroup, sampleCount, TYPE_CHAR, outData); + return ack; +} + +/** + * @brief short data sampling. + * @param addressGroup Variable grouping information. + * @param outData Parsed data. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t GroupShort(DapAddressGroup addressGroup, uint8_t *outData) +{ + uint8_t ack; + uint32_t sampleCount; + + /* Number of sampling times for determining the number of char variables */ + sampleCount = ((addressGroup.startAddress & ALIGN_FOUR_BYTE) + addressGroup.length * TYPE_SHORT) / VARTYPE_INT_LEN; + if ((((addressGroup.startAddress & ALIGN_FOUR_BYTE) + addressGroup.length * TYPE_SHORT) % VARTYPE_INT_LEN) != 0) { + sampleCount++; + } + + ack = SampleAndParsing(addressGroup, sampleCount, TYPE_SHORT, outData); + return ack; +} + +/** + * @brief int data sampling. + * @param addressGroup Variable grouping information. + * @param outData Parsed data. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t GroupInt(DapAddressGroup addressGroup, uint8_t *outData) +{ + uint8_t ack; + + ack = SampleAndParsing(addressGroup, addressGroup.length, TYPE_INT, outData); + return ack; +} + +/** + * @brief long data sampling. + * @param addressGroup Variable grouping information. + * @param outData Parsed data. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t GroupLong(DapAddressGroup addressGroup, uint8_t *outData) +{ + uint8_t ack; + + ack = SampleAndParsing(addressGroup, addressGroup.length, TYPE_LONG, outData); + return ack; +} + +/** + * @brief mix-type data sampling. + * @param addressGroup Variable grouping information. + * @param outData Parsed data. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t GroupMix(DapAddressGroup addressGroup, uint8_t *outData) +{ + uint8_t ack = DAP_TRANSFER_ERROR; + uint32_t sampleCount = 0; + uint32_t recordVarCount = 0; + uint8_t *outDataPtr = outData; + + /* Whether the position of the first variable is 0 or not, a sample sequence is required. */ + for (uint32_t i = 0; i < addressGroup.length; i++) { + if (g_mixPositionInfo[addressGroup.mixPosition].position[i] == 0 && i != 0) { + sampleCount++; + } + } + sampleCount++; + + g_parsingVarCount = 0; + for (uint32_t i = 0; i < sampleCount; i++) { + if (i == 0) { + ack = ReadMemoryPrepare(); + } else { + ack = DataParsingMix(&g_mixPositionInfo[addressGroup.mixPosition], outDataPtr, addressGroup.length, + PARSING_CONTINUOUS); + /* 8 bytes in each step */ + outDataPtr += (g_parsingVarCount - recordVarCount) * VARTYPE_LONG_LEN; + recordVarCount = g_parsingVarCount; + } + if (ack != DAP_TRANSFER_OK) { + return ack; + } + + if (i == sampleCount - 1) { + ack = DataParsingMix(&g_mixPositionInfo[addressGroup.mixPosition], outDataPtr, addressGroup.length, + PARSING_ENDING); + } + } + return ack; +} + +/** + * @brief Selecting a group type. + * @param addressGroup Variable grouping information. + * @param outData Parsed data. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t SelectGroupType(DapAddressGroup addressGroup, uint8_t *outData) +{ + uint8_t ack = DAP_TRANSFER_ERROR; + + switch (addressGroup.type) { + case TYPE_CHAR: + ack = GroupChar(addressGroup, outData); + break; + case TYPE_SHORT: + ack = GroupShort(addressGroup, outData); + break; + case TYPE_INT: + ack = GroupInt(addressGroup, outData); + break; + case TYPE_LONG: + ack = GroupLong(addressGroup, outData); + break; + case TYPE_MIX: + ack = GroupMix(addressGroup, outData); + break; + default: + break; + } + + return ack; +} + +/** + * @brief address incremental continuous sampling. + * @param addressGroup Variable grouping information. + * @param outData Parsed data. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t SampleAddessIncreVal(DapAddressGroup addressGroup, uint8_t *outData) +{ + uint32_t data; + uint8_t ack; + + if (g_isValMonitorSetFlag == 0) { + g_isValMonitorSetFlag = 1; + + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + JTAG_RESET(); + } + ack = SwitchBusChannel(); + if (ack != DAP_TRANSFER_OK) { + return ack; + } + + ack = SetAccessMemoryLength(ACCESS_CONTINUOUS_FOUR_BYTE); + if (ack != DAP_TRANSFER_OK) { + return ack; + } + } + + data = addressGroup.startAddress - addressGroup.startAddress % VARTYPE_INT_LEN; + ack = SetAccessMemoryAddr(data); + if (ack != DAP_TRANSFER_OK) { + return ack; + } + + ack = SelectGroupType(addressGroup, outData); + + return ack; +} + +/** + * @brief address map comparison function. + * @param aa Comparison parameter aa. + * @param bb Comparison parameter bb. + * @retval Compare Results. + */ +static int MapCmp(const void *aa, const void *bb) +{ + DapAddressMap *a = (DapAddressMap *)aa; + DapAddressMap *b = (DapAddressMap *)bb; + + return (a->map - b->map); +} + +/** + * @brief Recovery Address Sequence. + * @param str Sampled data to be restored. + * @param length Length of the variable list to be restored. + * @retval type: MALLOC_FAIL, RET_FAIL, RET_SUCCESS. + */ +static int RestoreAddressSequence(uint8_t *str, uint32_t length) +{ + DapAddressMap *tempAddressMap; + errno_t rc = EOK; + tempAddressMap = (DapAddressMap *)malloc(length * sizeof(DapAddressMap)); + if (tempAddressMap == NULL) { + DBG_PRINTF("tempAddressMap malloc fail!!\r\n"); + StopSampling(); + return MALLOC_FAIL; + } + for (int i = 0; i < length; i++) { + tempAddressMap[i].map = g_dapAddressGroupList.addressMap[i]; + rc = memcpy_s(tempAddressMap[i].sampleValue, VARTYPE_LONG_LEN, &str[i * VARTYPE_LONG_LEN], VARTYPE_LONG_LEN); + if (rc != EOK) { + free(tempAddressMap); + tempAddressMap = NULL; + return RET_FAIL; + } + } + + qsort(tempAddressMap, length, sizeof(tempAddressMap[0]), MapCmp); + + for (int i = 0; i < length; i++) { + rc = memcpy_s(&str[i * VARTYPE_LONG_LEN], VARTYPE_LONG_LEN, tempAddressMap[i].sampleValue, VARTYPE_LONG_LEN); + if (rc != EOK) { + free(tempAddressMap); + tempAddressMap = NULL; + return RET_FAIL; + } + } + if (tempAddressMap != NULL) { + free(tempAddressMap); + tempAddressMap = NULL; + } + + return RET_SUCCESS; +} + +/** + * @brief Check whether the variable list is continuous. + * @param addrA Variable A address. + * @param addrB Variable B address. + * @param lenB Variable B length. + * @retval true or false. + */ +static bool IsCharContinuous(unsigned int addrA, unsigned int addrB, unsigned int lenB) +{ + bool isIncrementalFlag = false; + + if (lenB == VARTYPE_SHORT_LEN && (addrB - addrA) == ADDR_INTERVAL_LEN_TWO) { + /* char-short: If the address difference is 2, it is also continuous. */ + isIncrementalFlag = true; + } else if (((lenB % VARTYPE_INT_LEN) == 0) && + ((addrB - addrA) == ADDR_INTERVAL_LEN_TWO || + (addrB - addrA) == ADDR_INTERVAL_LEN_THREE || + (addrB - addrA) == ADDR_INTERVAL_LEN_FOUR)) { + /* char-int: If the address difference is 2,3,4, it is also continuous. */ + isIncrementalFlag = true; + } +} + +/** + * @brief Check whether the variable list is continuous. + * @param addrA Variable A address. + * @param addrB Variable B address. + * @param lenA Variable A length. + * @param lenB Variable B length. + * @retval continuous or not. + */ +static int JudgeVarContinuous(unsigned int addrA, unsigned int addrB, unsigned int lenA, unsigned int lenB) +{ + int isIncrementalFlag = 0; + + /* Regroup at flash boundary. */ + if ((addrB % FLASH_BOUNDARY) == 0) { + isIncrementalFlag = 0; + } else if ((addrB - addrA) == lenA) { + isIncrementalFlag = 1; + } else if (lenA == VARTYPE_CHAR_LEN) { + if (IsCharContinuous(addrA, addrB, lenB)) { + isIncrementalFlag = 1; + } + } else if (lenA == VARTYPE_SHORT_LEN) { + if (((lenB % VARTYPE_INT_LEN) == 0) && + ((addrB - addrA) == ADDR_INTERVAL_LEN_FOUR)) { + /* short-int/long long: If the address difference is 4, it is also continuous. */ + isIncrementalFlag = 1; + } + } + + return isIncrementalFlag; +} + +/** + * @brief Grouping a list of consecutive variables. + * @param dapValMonitor Variable list information. + * @param dapAddressGroupList Variable grouping information. + * @param address Variable Address list. + * @param varLengthMap Variable length list. + * @retval type: MALLOC_FAIL, RET_SUCCESS. + */ +static int ContinuousVarGroup(const DapVarMonitor *dapValMonitor, DapAddressGroupList *dapAddressGroupList, + const unsigned int *address, const unsigned int *varLengthMap) +{ + int isIncrementalFlag = 0; + + dapAddressGroupList->addressGroup = (DapAddressGroup *)malloc(dapValMonitor->varNum * sizeof(DapAddressGroup)); + if (dapAddressGroupList->addressGroup == NULL) { + DBG_PRINTF("addressGroup malloc fail!!\r\n"); + return MALLOC_FAIL; + } + + /* Incremental Address Group Initialization. */ + dapAddressGroupList->isAddressIncrementFlag = 1; + dapAddressGroupList->count = 1; + dapAddressGroupList->addressGroup[dapAddressGroupList->count - 1].startAddress = address[0]; + dapAddressGroupList->addressGroup[dapAddressGroupList->count - 1].length = 1; + /* Grouping Continuous and Non-Continuous Variables. */ + for (int i = 1; i < dapValMonitor->varNum; i++) { + isIncrementalFlag = JudgeVarContinuous(address[i - 1], address[i], varLengthMap[i - 1], varLengthMap[i]); + if (isIncrementalFlag != 0) { + isIncrementalFlag = 0; + dapAddressGroupList->addressGroup[dapAddressGroupList->count - 1].length++; + continue; + } + dapAddressGroupList->count++; + dapAddressGroupList->addressGroup[dapAddressGroupList->count - 1].startAddress = address[i]; + dapAddressGroupList->addressGroup[dapAddressGroupList->count - 1].length = 1; + } + + return RET_SUCCESS; +} + +/** + * @brief Check whether the type is mixed. + * @param varLengthMap Variable length list. + * @param groupLen Length of the variable group + * @param count Position counter of the variable in the variable length list. + * @retval mix-type or not. + */ +static unsigned int JudgeIsMix(const unsigned int *varLengthMap, unsigned int groupLen, unsigned int count) +{ + unsigned int j; + + for (j = 0; j < groupLen - 1; j++) { + if (varLengthMap[count + j] != varLengthMap[count + j + 1]) { + break; + } + } + if (j == (groupLen - 1)) { + return 0; + } + + return 1; +} + +/** + * @brief Determine the group type. + * @param dapAddressGroupList Variable grouping information. + * @param varLengthMap Variable length list. + * @retval Number of variable groups of mixed types. + */ +static unsigned int JudgeType(DapAddressGroupList *dapAddressGroupList, + const unsigned int *varLengthMap, unsigned int mapLen) +{ + int i; + unsigned int count = 0; + unsigned int mixPosition = 0; + /* Checking Data Validity */ + if (mapLen < dapAddressGroupList->count) { + return 0; + } + /* Traverse the address group list. */ + for (i = 0; i < dapAddressGroupList->count; i++) { + if (dapAddressGroupList->addressGroup[i].length > 1) { + /* if each type of continuous variable is consistent */ + if (JudgeIsMix(varLengthMap, dapAddressGroupList->addressGroup[i].length, count) == 0) { + dapAddressGroupList->addressGroup[i].type = varLengthMap[count]; + } else { + dapAddressGroupList->addressGroup[i].type = TYPE_MIX; + /* Obtains the position and length of each variable in the sampled four bytes of the mixed group. */ + dapAddressGroupList->addressGroup[i].mixPosition = mixPosition; + mixPosition++; + } + } else { + dapAddressGroupList->addressGroup[i].type = varLengthMap[count]; + } + count += dapAddressGroupList->addressGroup[i].length; + } + + return mixPosition; +} + +/** + * @brief Records the postion information of variable groups of mixed types. + * @param dapAddressGroupList Variable grouping information. + * @param address Variable Address list. + * @param varLengthMap Variable length list. + * @param mixGruopNum Number of variable groups of mixed types. + * @retval type: MALLOC_FAIL, RET_FAIL, RET_SUCCESS. + */ +static int RecordMixPosInfo(DapAddressGroupList *dapAddressGroupList, const unsigned int *address, + const unsigned int *varLengthMap, unsigned int mixGruopNum) +{ + int i; + int j; + unsigned int count = 0; + errno_t rc = EOK; + + g_mixPositionInfo = (DapPositionInfo *)malloc(sizeof(DapPositionInfo) * mixGruopNum); + if (g_mixPositionInfo == NULL) { + DBG_PRINTF("mixPositionInfo malloc fail!!\r\n"); + return MALLOC_FAIL; + } + /* clear mix group position infomation. */ + rc = memset_s(g_mixPositionInfo, sizeof(DapPositionInfo) * mixGruopNum, 0, sizeof(DapPositionInfo) * mixGruopNum); + if (rc != EOK) { + return RET_FAIL; + } + + for (i = 0; i < dapAddressGroupList->count; i++) { + if (dapAddressGroupList->addressGroup[i].type == TYPE_MIX) { + unsigned int mixPos = dapAddressGroupList->addressGroup[i].mixPosition; + for (j = 0; j < dapAddressGroupList->addressGroup[i].length; j++) { + g_mixPositionInfo[mixPos].position[j] = address[count + j] & ALIGN_FOUR_BYTE; + g_mixPositionInfo[mixPos].len[j] = varLengthMap[count + j]; + } + } + count += dapAddressGroupList->addressGroup[i].length; + } + + return RET_SUCCESS; +} + +/** + * @brief Categorizing Variable Groups. + * @param dapAddressGroupList Variable grouping information. + * @param address Variable Address list. + * @param varLengthMap Variable length list. + * @param varLengthMapLen var Length Map len. + * @retval type: MALLOC_FAIL, RET_SUCCESS. + */ +static int ClassifyVarGroup(DapAddressGroupList *dapAddressGroupList, const unsigned int *address, + const unsigned int *varLengthMap, unsigned int varLengthMapLen) +{ + unsigned int mixPosition = 0; + int retValue; + + /* Determine whether the type of the address continuous variable is single or mixed. */ + mixPosition = JudgeType(dapAddressGroupList, varLengthMap, varLengthMapLen); + if (mixPosition != 0) { + retValue = RecordMixPosInfo(dapAddressGroupList, address, varLengthMap, mixPosition); + if (retValue != RET_SUCCESS) { + return retValue; + } + } + + return RET_SUCCESS; +} + +/** + * @brief Record variable length mapping. + * @param dapValMonitor Variable list information. + * @param address Variable Address list. + * @param varLenMap Variable length list. + * @retval type: MALLOC_FAIL, RET_SUCCESS. + */ +static int RecordVarLenMap(DapVarMonitor *dapValMonitor, const unsigned int *address, unsigned int *varLenMap) +{ + int i; + int j; + unsigned int *recordVar; + unsigned int *varLengthMap = varLenMap; + + recordVar = (unsigned int *)malloc(dapValMonitor->varNum * sizeof(unsigned int)); + if (recordVar == NULL) { + DBG_PRINTF("recordVar malloc fail!!\r\n"); + return MALLOC_FAIL; + } + + for (i = 0; i < dapValMonitor->varNum; i++) { + recordVar[i] = dapValMonitor->varList[i].varAddress; + } + + for (i = 0; i < dapValMonitor->varNum; i++) { + for (j = 0; j < dapValMonitor->varNum; j++) { + if (address[i] == recordVar[j]) { + recordVar[j] = 0; + /* Save the length of the sorted variable. */ + varLengthMap[i] = dapValMonitor->varList[j].varNumBytes; + break; + } + } + } + if (recordVar != NULL) { + free(recordVar); + recordVar = NULL; + } + return RET_SUCCESS; +} + +/** + * @brief Check whether the variable list is increasing and continuous. + * @param dapValMonitor Variable list information. + * @param dapAddressGroupList Variable grouping information. + * @param address Variable Address list. + * @retval type: MALLOC_FAIL, RET_SUCCESS. + */ +static int IsIncrementalAddress(DapVarMonitor *dapValMonitor, DapAddressGroupList *dapAddressGroupList, + const unsigned int *address) +{ + /* Save the length of the sorted variable. */ + unsigned int *varLengthMap; + int retValue; + + varLengthMap = (unsigned int *)malloc(dapValMonitor->varNum * sizeof(unsigned int)); + if (varLengthMap == NULL) { + DBG_PRINTF("varLengthMap malloc fail!!\r\n"); + return MALLOC_FAIL; + } + retValue = RecordVarLenMap(dapValMonitor, address, varLengthMap); + if (retValue != RET_SUCCESS) { + free(varLengthMap); + varLengthMap = NULL; + return retValue; + } + + /* Grouping Continuity of Variables. */ + retValue = ContinuousVarGroup(dapValMonitor, dapAddressGroupList, address, varLengthMap); + if (retValue != RET_SUCCESS) { + free(varLengthMap); + varLengthMap = NULL; + return retValue; + } + + /* if there is no continuity for each variable. */ + if (dapAddressGroupList->count == dapValMonitor->varNum) { + dapAddressGroupList->isAddressIncrementFlag = 0; + if (dapAddressGroupList->addressGroup != NULL) { + free(dapAddressGroupList->addressGroup); + dapAddressGroupList->addressGroup = NULL; + } + if (varLengthMap != NULL) { + free(varLengthMap); + varLengthMap = NULL; + } + return RET_SUCCESS; + } + + /* Categorizing Continuous Variables. */ + retValue = ClassifyVarGroup(dapAddressGroupList, address, varLengthMap, + dapValMonitor->varNum * sizeof(unsigned int)); + if (retValue != RET_SUCCESS) { + free(varLengthMap); + varLengthMap = NULL; + return retValue; + } + if (varLengthMap != NULL) { + free(varLengthMap); + varLengthMap = NULL; + } + + return RET_SUCCESS; +} + +/** + * @brief address comparison function. + * @param aa Comparison parameter aa. + * @param bb Comparison parameter bb. + * @retval Compare Results. + */ +static int AddressCmp(const void *aa, const void *bb) +{ + long long int difference; + difference = (long long int)(*(unsigned long long *)aa) - (long long int)(*(unsigned long long *)bb); + + if (difference > 0) { + return 1; + } else if (difference == 0) { + return 0; + } else { + return -1; + } +} + +/** + * @brief Record variable address mapping. + * @param dapValMonitor Variable list information. + * @param dapAddressGroupList Variable grouping information. + * @param address Variable Address list. + * @retval type: MALLOC_FAIL, RET_SUCCESS. + */ +static int RecordVarAddrMap(DapVarMonitor *dapValMonitor, DapAddressGroupList *dapAddressGroupList, + const unsigned int *address) +{ + int i; + int j; + unsigned int *recordVar; + + recordVar = (unsigned int *)malloc(dapValMonitor->varNum * sizeof(unsigned int)); + if (recordVar == NULL) { + DBG_PRINTF("recordVar malloc fail!!\r\n"); + return MALLOC_FAIL; + } + dapAddressGroupList->isAddressMapFlag = 1; + for (i = 0; i < dapValMonitor->varNum; i++) { + recordVar[i] = dapValMonitor->varList[i].varAddress; + } + /* Record the address sequence before sorting. */ + for (i = 0; i < dapValMonitor->varNum; i++) { + for (j = 0; j < dapValMonitor->varNum; j++) { + if (address[i] == recordVar[j]) { + recordVar[j] = 0; + /* Save the position of the sorted variable. */ + dapAddressGroupList->addressMap[i] = j; + break; + } + } + } + /* Release resources. */ + if (recordVar != NULL) { + free(recordVar); + recordVar = NULL; + } + return RET_SUCCESS; +} + +/** + * @brief variable grouping algorithm. + * @param dapValMonitor Variable list information. + * @param dapAddressGroupList Variable grouping information. + * @param address Variable Address list. + * @retval type: MALLOC_FAIL, RET_SUCCESS. + */ +static int VarGroupingAlgorithm(DapVarMonitor *dapValMonitor, DapAddressGroupList *dapAddressGroupList, + const unsigned int *address) +{ + int i; + int isAddressMapFlag = 0; + int retValue; + + for (i = 0; i < dapValMonitor->varNum; i++) { + if (address[i] != dapValMonitor->varList[i].varAddress) { + isAddressMapFlag = 1; + break; + } + } + + /* If address mapping required */ + if (isAddressMapFlag != 0) { + retValue = RecordVarAddrMap(dapValMonitor, dapAddressGroupList, address); + if (retValue != RET_SUCCESS) { + return retValue; + } + } else { + dapAddressGroupList->isAddressMapFlag = 0; + if (dapAddressGroupList->addressMap != NULL) { + free(dapAddressGroupList->addressMap); + dapAddressGroupList->addressMap = NULL; + } + } + DBG_PRINTF("isAddressMapFlag %d\r\n", dapAddressGroupList->isAddressMapFlag); + + retValue = IsIncrementalAddress(dapValMonitor, dapAddressGroupList, address); + if (retValue != RET_SUCCESS) { + return retValue; + } + + return RET_SUCCESS; +} + +/** + * @brief Variable incremental sampling initialization. + * @param None. + * @retval type: MALLOC_FAIL, RET_SUCCESS. + */ +static int VarIncrementalInit(void) +{ + int i; + errno_t rc = EOK; + unsigned int *addressList; + int retValue; + + addressList = (unsigned int *)malloc(g_dapValMonitor.varNum * sizeof(unsigned int)); + if (addressList == NULL) { + DBG_PRINTF("addressList malloc fail!!\r\n"); + return MALLOC_FAIL; + } + + for (i = 0; i < g_dapValMonitor.varNum; i++) { + addressList[i] = g_dapValMonitor.varList[i].varAddress; + } + qsort(addressList, g_dapValMonitor.varNum, sizeof(unsigned int), AddressCmp); + + /* Clearing DapAddressGroupList Information. */ + rc = memset_s(&g_dapAddressGroupList, sizeof(DapAddressGroupList), + 0, sizeof(DapAddressGroupList) - sizeof(DapAddressGroup *) - sizeof(unsigned int *)); + if (rc != EOK) { + free(addressList); + addressList = NULL; + return RET_FAIL; + } + g_dapAddressGroupList.addressMap = (unsigned int *)malloc(sizeof(unsigned int) * g_dapValMonitor.varNum); + if (g_dapAddressGroupList.addressMap == NULL) { + DBG_PRINTF("addressMap malloc fail!!\r\n"); + free(addressList); + addressList = NULL; + return MALLOC_FAIL; + } + + retValue = VarGroupingAlgorithm(&g_dapValMonitor, &g_dapAddressGroupList, addressList); + if (retValue != RET_SUCCESS) { + free(addressList); + addressList = NULL; + return retValue; + } + + if (addressList != NULL) { + free(addressList); + addressList = NULL; + } + + return RET_SUCCESS; +} + +/** + * @brief Non-incremental sampling. + * @param dapValMonitor Variable list information. + * @param frameData Sampled data. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t SamplingNonIncremental(DapVarMonitor *dapValMonitor, uint8_t *frameData) +{ + uint8_t *frameDataPtr = frameData; + uint8_t ret; + errno_t rc = EOK; + + for (uint32_t i = 0; i < dapValMonitor->varNum; i++) { + uint8_t value[VARTYPE_LONG_LEN]; + + ret = SamplingOneVal(dapValMonitor->varList[i].varAddress, dapValMonitor->varList[i].varNumBytes, + value, VARTYPE_LONG_LEN); + if (ret != DAP_TRANSFER_OK) { + break; + } + rc = memcpy_s(frameDataPtr, dapValMonitor->varList[i].varNumBytes, + (char *)&value[dapValMonitor->varList[i].varAddress & ALIGN_FOUR_BYTE], + dapValMonitor->varList[i].varNumBytes); + if (rc != EOK) { + return DAP_TRANSFER_ERROR; + } + frameDataPtr += dapValMonitor->varList[i].varNumBytes; + } + + return ret; +} + +/** + * @brief incremental sampling. + * @param dapValMonitor Variable list information. + * @param frameData Sampled data. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t SamplingIncremental(DapVarMonitor *dapValMonitor, uint8_t *frameData) +{ + uint8_t *frameDataPtr = frameData; + uint8_t ret = DAP_TRANSFER_ERROR; + uint8_t *sampleValue; + int retValue; + errno_t rc = EOK; + + sampleValue = (uint8_t *)malloc(dapValMonitor->varNum * VARTYPE_LONG_LEN * sizeof(uint8_t)); + if (sampleValue == NULL) { + DBG_PRINTF("sampleValue malloc fail!!\r\n"); + StopSampling(); + return DAP_TRANSFER_ERROR; + } + uint8_t *valuePtr = sampleValue; + + for (uint32_t i = 0; i < g_dapAddressGroupList.count; i++) { + ret = SampleAddessIncreVal(g_dapAddressGroupList.addressGroup[i], valuePtr); + if (ret != DAP_TRANSFER_OK) { + break; + } + valuePtr += g_dapAddressGroupList.addressGroup[i].length * VARTYPE_LONG_LEN; + } + + if (ret == DAP_TRANSFER_OK) { + if (g_dapAddressGroupList.isAddressMapFlag != 0) { + retValue = RestoreAddressSequence(sampleValue, dapValMonitor->varNum); + if (retValue != RET_SUCCESS) { + free(sampleValue); + sampleValue = NULL; + StopSampling(); + return DAP_TRANSFER_ERROR; + } + } + + for (uint32_t i = 0; i < dapValMonitor->varNum; i++) { + rc = memcpy_s(frameDataPtr, dapValMonitor->varList[i].varNumBytes, + &sampleValue[i * VARTYPE_LONG_LEN], dapValMonitor->varList[i].varNumBytes); + if (rc != EOK) { + free(sampleValue); + sampleValue = NULL; + StopSampling(); + return DAP_TRANSFER_ERROR; + } + frameDataPtr += dapValMonitor->varList[i].varNumBytes; + } + } + if (sampleValue != NULL) { + free(sampleValue); + sampleValue = NULL; + } + + return ret; +} + +/** + * @brief Performance test sampling. + * @param dapValMonitor Variable list information. + * @param frameData Sampled data. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t SamplingPerformance(DapVarMonitor *dapValMonitor, uint8_t *frameData) +{ + uint8_t *frameDataPtr = frameData; + errno_t rc = EOK; + + for (uint32_t i = 0; i < dapValMonitor->varNum; i++) { + /* The initialization step is 100 when the number of virtual variables exceeds 1000. */ + if (g_performanceTestVar[i]++ >= (i * 100 + 1000)) { + /* Dummy variable steps every 100. */ + g_performanceTestVar[i] = i * 100; + } + rc = memcpy_s(frameDataPtr, dapValMonitor->varList[i].varNumBytes, + (char *)&g_performanceTestVar[i], dapValMonitor->varList[i].varNumBytes); + if (rc != EOK) { + return DAP_TRANSFER_ERROR; + } + frameDataPtr += dapValMonitor->varList[i].varNumBytes; + } + + return DAP_TRANSFER_OK; +} + +/** + * @brief sampling. + * @param dapValMonitor Variable list information. + * @param frameData Sampled data. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t Sampling(DapVarMonitor *dapValMonitor, uint8_t *frameData) +{ + uint8_t ret = DAP_TRANSFER_OK; + + if (g_isPerformanceTestFlag == 0) { + if (g_dapAddressGroupList.isAddressIncrementFlag != 0) { + ret = SamplingIncremental(dapValMonitor, frameData); + } else { + ret = SamplingNonIncremental(dapValMonitor, frameData); + } + } else { + ret = SamplingPerformance(dapValMonitor, frameData); + } + + return ret; +} + +/** + * @brief Sample a complete frame once. + * @param varMonitorQueue Sampling shared memory queue. + * @param time time stamp. + * @retval type: MALLOC_FAIL, RET_SUCCESS. + */ +static int SampleOneFrame(VarQueue *varMonitorQueue, uint32_t time) +{ + uint32_t retLen; + uint8_t ret; + uint8_t *outData; + uint32_t outDataLen; + errno_t rc = EOK; + /* (timeStamp)4-byte */ + outDataLen = g_dapValMonitor.varNum * VARTYPE_LONG_LEN + VARTYPE_INT_LEN; + outData = (uint8_t *)malloc(outDataLen * sizeof(uint8_t)); + if (outData == NULL) { + StopSampling(); + return MALLOC_FAIL; + } + uint8_t *frameDataPtr = outData; + + /* The livewatch function uses the full sequence for slow sampling(>100000us). */ + if (g_dapValMonitor.periodUs >= 100000) { + g_isValMonitorSetFlag = 0; + } + /* Total sampling times. */ + varMonitorQueue->totalSampleCount++; + /* Record timestamp. */ + g_timeStamp += time; + rc = memcpy_s(frameDataPtr, VARTYPE_INT_LEN, (char *)&g_timeStamp, VARTYPE_INT_LEN); + if (rc != EOK) { + free(outData); + outData = NULL; + return RET_FAIL; + } + frameDataPtr += VARTYPE_INT_LEN; + + ret = Sampling(&g_dapValMonitor, frameDataPtr); + if (ret != DAP_TRANSFER_OK) { + /* Number of error samples for calculating the error rate. */ + g_errorDetectionErrorCounter++; + /* Total number of sampling errors. */ + varMonitorQueue->totalErrorCount++; + } else { + retLen = WriteQueue(varMonitorQueue, outData, g_varMonitorFrameSize); + if (retLen != g_varMonitorFrameSize) { + /* Total number of sampling overflows. */ + varMonitorQueue->totalOverflowCount++; + } + } + if (outData != NULL) { + free(outData); + outData = NULL; + } + + return RET_SUCCESS; +} + +/** + * @brief Checking the sampling error rate. + * @param varMonitorQueue Sampling shared memory queue. + * @param currentTime current time. + * @retval None. + */ +static void CheckErrorRate(VarQueue *varMonitorQueue, uint32_t currentTime) +{ + uint32_t idCode = 0; + /* Total number of sampling times for calculating the error rate. */ + g_errorDetectionTotalCounter++; + if (GetDelta(currentTime, g_errorDetectionTimer) >= ERROR_DETECTION_INTERVAL_US) { + /* Multiply the error rate by 100. */ + varMonitorQueue->errorRate = g_errorDetectionErrorCounter * 100 / g_errorDetectionTotalCounter; + if (varMonitorQueue->errorRate >= g_errorRate) { + SwdJtagReset(); + SwitchSwdJtag(0xE79E); + SwdJtagReset(); + SwdJtagReadIdcode(&idCode); + SwdJtagCleanError(); + SwdPowerSet(); + g_isReadMemoryFlag = 1; + g_isValMonitorSetFlag = 0; + } + g_errorDetectionErrorCounter = 0; + g_errorDetectionTotalCounter = 0; + g_errorDetectionTimer = currentTime; + } else { + if (g_errorDetectionErrorCounter >= ERROR_MAX_ALLOWED) { + SwdJtagReset(); + SwitchSwdJtag(0xE79E); + SwdJtagReset(); + SwdJtagReadIdcode(&idCode); + SwdJtagCleanError(); + SwdPowerSet(); + g_isReadMemoryFlag = 1; + g_isValMonitorSetFlag = 0; + g_errorDetectionErrorCounter = 0; + g_errorDetectionTotalCounter = 0; + } + } +} + +/** + * @brief Preprocessing Before Modifying Variables. + * @param addr sample addr. + * @param length sample length. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +static uint8_t WriteValPrepare(uint32_t addr, uint32_t length) +{ + uint8_t ack; + + /* Switching Bus Channels. */ + ack = SwitchBusChannel(); + if (ack != DAP_TRANSFER_OK) { + return ack; + } + + /* Sets the length of the variable to be modified. */ + if (length == VARTYPE_CHAR_LEN) { + ack = SetAccessMemoryLength(ACCESS_DISCONTINUOUS_ONE_BYTE); + } else if (length == VARTYPE_SHORT_LEN) { + ack = SetAccessMemoryLength(ACCESS_DISCONTINUOUS_TWO_BYTE); + } else if (length >= VARTYPE_INT_LEN) { + ack = SetAccessMemoryLength(ACCESS_CONTINUOUS_FOUR_BYTE); + } + if (ack != DAP_TRANSFER_OK) { + return ack; + } + + /* Sets the address of a variable. */ + ack = SetAccessMemoryAddr(addr); + + return ack; +} + +/** + * @brief Write a single variable. + * @param addr sample addr. + * @param length sample length. + * @param value write value. + * @retval type: DAP_TRANSFER_OK, DAP_TRANSFER_WAIT, DAP_TRANSFER_FAULT, DAP_TRANSFER_ERROR.. + */ +uint8_t WriteOneVal(uint32_t addr, uint32_t length, uint64_t value) +{ + uint8_t ack; + uint32_t lowValue; + uint32_t highValue; + + lowValue = (value & LOW_32_BIT); + /* Obtains the value of the upper 32 bits. */ + highValue = (value & HIGH_32_BIT) >> 32; + + /* WriteDP 2 0x1000000 + WriteAP 0 0x000002 + WriteAP 1 0x040018B0 + WriteAP 3 0x12345678 + */ + ack = WriteValPrepare(addr, length); + if (ack != DAP_TRANSFER_OK) { + return ack; + } + + /* left shifting ((addr % VARTYPE_INT_LEN) * 8)-bit. */ + lowValue <<= ((addr % VARTYPE_INT_LEN) * 8); + ack = WriteMemory(lowValue); + if (ack != DAP_TRANSFER_OK) { + return ack; + } + if (length == VARTYPE_LONG_LEN) { + ack = WriteMemory(highValue); + if (ack != DAP_TRANSFER_OK) { + return ack; + } + } + + /* Restore the read variable length. */ + if (g_dapAddressGroupList.isAddressIncrementFlag != 0) { + ack = SetAccessMemoryLength(ACCESS_CONTINUOUS_FOUR_BYTE); + } else { + ack = SetAccessMemoryLength(ACCESS_DISCONTINUOUS_FOUR_BYTE); + } + if (ack != DAP_TRANSFER_OK) { + return ack; + } + + return ack; +} + +/** + * @brief Store sampled variable values in the queue. + * @param None. + * @retval None. + */ +void ReadMemoryToQueue(void) +{ + uint32_t curTicks; + uint32_t delta; + + if (g_isReadMemoryFlag != 0) { + curTicks = GetTimerTickUs(); + delta = GetDelta(curTicks, g_preTicks); + /* Sampling frequency */ + if (delta > g_dapValMonitor.periodUs) { + SampleOneFrame(g_varMonitorQueue, delta); + CheckErrorRate(g_varMonitorQueue, curTicks); + g_preTicks = curTicks; + } + } +} + +/** + * @brief Preparation to start sampling. + * @param None. + * @retval type: MALLOC_FAIL, RET_SUCCESS. + */ +int StartSampling(void) +{ + int retValue; + + QueueInit(g_varMonitorQueue); + /* Timestamp 4-byte. */ + g_varMonitorFrameSize = 4; + for (unsigned int i = 0; i < g_dapValMonitor.varNum; i++) { + g_varMonitorFrameSize += g_dapValMonitor.varList[i].varNumBytes; + } + + if (g_isPerformanceTestFlag != 0) { + g_performanceTestVar = (unsigned long long int *)malloc(sizeof(unsigned long long int) * + g_dapValMonitor.varNum); + if (g_performanceTestVar == NULL) { + return MALLOC_FAIL; + } + for (unsigned int i = 0; i < g_dapValMonitor.varNum; i++) { + /* Dummy variable steps every 100. */ + g_performanceTestVar[i] = i * 100; + } + } else { + /* When sampling, the address increment needs to be determined. */ + retValue = VarIncrementalInit(); + if (retValue != RET_SUCCESS) { + return retValue; + } + } + /* Clear the timestamp. */ + g_timeStamp = 0; + /* set the read memory flag */ + g_isReadMemoryFlag = 1; + g_isValMonitorSetFlag = 0; + g_preTicks = GetTimerTickUs(); + /* Error detection initialization. */ + g_errorDetectionTimer = g_preTicks; + g_errorDetectionTotalCounter = 0; + g_errorDetectionErrorCounter = 0; + + return RET_SUCCESS; +} + +/** + * @brief Release all memory requested for sampling. + * @param None. + * @retval None. + */ +void FreeMemory(void) +{ + if ((g_isPerformanceTestFlag != 0) && (g_performanceTestVar != NULL)) { + free(g_performanceTestVar); + g_performanceTestVar = NULL; + } + + /* Clearing Sampling Information. */ + memset_s(&g_dapValMonitor, sizeof(DapVarMonitor) - sizeof(DapVarList *), + 0, sizeof(DapVarMonitor) - sizeof(DapVarList *)); + if (g_dapValMonitor.varList != NULL) { + free(g_dapValMonitor.varList); + g_dapValMonitor.varList = NULL; + } + + if ((g_dapAddressGroupList.isAddressIncrementFlag != 0) && (g_mixPositionInfo != NULL)) { + free(g_mixPositionInfo); + g_mixPositionInfo = NULL; + } + + if ((g_dapAddressGroupList.isAddressMapFlag != 0) && (g_dapAddressGroupList.addressMap != NULL)) { + free(g_dapAddressGroupList.addressMap); + g_dapAddressGroupList.addressMap = NULL; + } + if ((g_dapAddressGroupList.isAddressIncrementFlag != 0) && (g_dapAddressGroupList.addressGroup != NULL)) { + free(g_dapAddressGroupList.addressGroup); + g_dapAddressGroupList.addressGroup = NULL; + } + /* Clearing DapAddressGroupList Information. */ + memset_s(&g_dapAddressGroupList, sizeof(DapAddressGroupList) - sizeof(DapAddressGroup *) - sizeof(unsigned int *), + 0, sizeof(DapAddressGroupList) - sizeof(DapAddressGroup *) - sizeof(unsigned int *)); +} + +/** + * @brief Stop sampling processing. + * @param None. + * @retval None. + */ +void StopSampling(void) +{ + QueueDestroy(g_varMonitorQueue); + FreeMemory(); + + /* Clear the timestamp. */ + g_timeStamp = 0; + /* clear the read memory flag */ + g_isReadMemoryFlag = 0; + /* clear Error detection counter */ + g_errorDetectionTotalCounter = 0; + g_errorDetectionErrorCounter = 0; + + if (g_DAP_Data.debug_port == DAP_PORT_JTAG) { + JTAG_RESET(); + } +} + +/** + * @brief Pause sampling processing. + * @param state Pause or resume. + * @retval None. + */ +void PauseSampling(uint32_t state) +{ + g_isReadMemoryFlag = state; +} diff --git a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/common/mcs_fault_detection.c b/src/tools/hispark_trace/hispark/CM4/Core/Src/var_monitor_queue.c similarity index 40% rename from src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/common/mcs_fault_detection.c rename to src/tools/hispark_trace/hispark/CM4/Core/Src/var_monitor_queue.c index 2a320db65fd7a5b89475443a89a9fc5b0af99162..e6cbb53d0acc417de69ad9040ebae1e6c1bd7c29 100644 --- a/src/application/middleware_sample/mcs_hall_bldc_1shunt/user_protect/common/mcs_fault_detection.c +++ b/src/tools/hispark_trace/hispark/CM4/Core/Src/var_monitor_queue.c @@ -1,5 +1,5 @@ /** - * @ Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,62 +15,97 @@ * 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. - * @file mcs_fault_detection.h - * @author MCU Algorithm Team - * @brief This file contains fault dection struct and api declaration. + * @file var_monitor_queue.c + * @author MCU Driver Team + * @brief Shared queue for storing variable monitoring data. */ - -#include "mcs_fault_detection.h" -#include "mcs_assert.h" +#include +#include +#include "securec.h" +#include "debug.h" +#include "var_monitor_queue.h" /** - * @brief Motor fault detection initialization. - * @param faultDet Fault detection handle. + * @brief init a queue. + * @param q pointer of queue. * @retval None. */ -void FaultDetect_Init(FAULT_DET_Handle *faultDet) +void QueueInit(VarQueue *q) { - MCS_ASSERT_PARAM(faultDet != NULL); - /* Clear the fault status. */ - faultDet->faultStatus.all = 0; - /* Initialize the fault detection structure. */ - OCD_Init(&faultDet->ocd, OVER_CURR_AMP_THRESHOLD, OVER_CURR_TIME_THRESHOLD, CTRL_CURR_PERIOD); - OTD_Init(&faultDet->otd, OVER_TEMP_AMP_THRESHOLD, OVER_TEMP_TIME_THRESHOLD, CTRL_CURR_PERIOD); - OVD_Init(&faultDet->ovd, OVER_VOLT_AMP_THRESHOLD, OVER_VOLT_TIME_THRESHOLD, CTRL_CURR_PERIOD); - LVD_Init(&faultDet->lvd, LOWER_VOLT_AMP_THRESHOLD, LOWER_VOLT_TIME_THRESHOLD, CTRL_CURR_PERIOD); - STD_Init(&faultDet->std, STALL_CURR_THRESHOLD, STALL_SPEED_THRESHOLD, STALL_TIME_THRESHOLD, CTRL_CURR_PERIOD); + q->read = 0; + q->write = 0; + q->size = VARQ_SIZE; + q->totalReadSize = 0; + q->totalWriteSize = 0; + q->totalSampleCount = 0; + q->totalOverflowCount = 0; + q->totalErrorCount = 0; + q->exceptionExitFlag = 0; + q->errorRate = 0; } /** - * @brief Motor fault detection. - * @param faultDet Fault detection handle. - * @param currAmp Motor current amplitude. - * @param tempAmp Motor temperature amplitude. - * @param voltAmp Motor voltage amplitude. - * @retval Whether the motor happen faults. + * @brief destroy a queue. + * @param q pointer of queue. + * @retval None. */ -bool FaultDetect_Exec(FAULT_DET_Handle *faultDet, float currAmp, float tempAmp, float voltAmp, float spdFbk) +void QueueDestroy(VarQueue *q) { - MCS_ASSERT_PARAM(faultDet != NULL); - /* Executing Fault Detection */ - faultDet->faultStatus.Bit.overCurrErr = OCD_Exec(&faultDet->ocd, currAmp); - faultDet->faultStatus.Bit.overTempErr = OTD_Exec(&faultDet->otd, tempAmp); - faultDet->faultStatus.Bit.overVoltErr = OVD_Exec(&faultDet->ovd, voltAmp); - faultDet->faultStatus.Bit.lowerVoltErr = LVD_Exec(&faultDet->lvd, voltAmp); - faultDet->faultStatus.Bit.motorStallErr = STD_Exec_ByCurrSpd(&faultDet->std, spdFbk, currAmp); + QueueInit(q); +} - /* Return to Fault Status */ - return faultDet->faultStatus.all; +/** + * @brief whether a queue is full. + * @param q pointer of queue. + * @retval Whether the value is full. + */ +static bool QueueFull(VarQueue *q) +{ + return ((q->totalWriteSize - q->totalReadSize) == q->size); } /** - * @brief Clear Motor fault detection history value. - * @param faultDet Fault detection handle. - * @retval None. + * @brief write buffers to queue. + * @param q pointer of queue. + * @param buf pointer of write buffer. + * @param len length of write buffer. + * @retval Length of a successful write. */ -void FaultDetect_Clear(FAULT_DET_Handle *faultDet) +unsigned int WriteQueue(VarQueue *q, const unsigned char *buf, unsigned int len) { - MCS_ASSERT_PARAM(faultDet != NULL); - /* Clear the fault status. */ - faultDet->faultStatus.all = 0; -} \ No newline at end of file + unsigned int ret = 0; + errno_t rc = EOK; + unsigned long long rest = q->size - q->write; + unsigned long long space = q->size - (q->totalWriteSize - q->totalReadSize); + + if ((q->totalWriteSize - q->totalReadSize) >= q->size) { + return ret; + } + if (QueueFull(q)) { + return ret; + } + if (space >= len) { + ret = len; + if (rest >= len) { + rc = memcpy_s((void *)(q->buf + q->write), rest, (void *)buf, len); + if (rc != EOK) { + return 0; + } + q->write = (q->write + len) % q->size; + q->totalWriteSize += len; + } else { + rc = memcpy_s((void *)(q->buf + q->write), rest, (void *)buf, rest); + if (rc != EOK) { + return 0; + } + q->write = 0; + rc = memcpy_s((void *)q->buf, q->size, (void *)(buf + rest), len - rest); + if (rc != EOK) { + return 0; + } + q->write = len - rest; + q->totalWriteSize += len; + } + } + return ret; +} diff --git a/src/tools/hispark_trace/hispark/CM4/Core/Startup/startup_stm32mp157daax.s b/src/tools/hispark_trace/hispark/CM4/Core/Startup/startup_stm32mp157daax.s new file mode 100644 index 0000000000000000000000000000000000000000..3b0634e9f9c95ba77dd2fe20f64cae4414fbda6d --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Core/Startup/startup_stm32mp157daax.s @@ -0,0 +1,792 @@ +/** + ****************************************************************************** + * @file startup_stm32mp15xx.s + * @author MCD Application Team + * @brief STM32MP15xx Devices vector table for GCC based 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 Cortex-M processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * 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 + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + + .section .startup_copro_fw.Reset_Handler,"ax" + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr sp, =_estack /* set stack pointer */ + +/* Loop to copy data from read only memory to RAM. The ranges + * of copy from/to are specified by following symbols evaluated in + * linker script. + * _sidata: End of code section, i.e., begin of data sections to copy from. + * _sdata/_edata: RAM address range that data should be + * copied to. Both must be aligned to 4 bytes boundary. */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =_sbss + b LoopFillZerobss + +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = _ebss + cmp r2, r3 + bcc FillZerobss + +/* Call the clock system intitialization function.*/ + + bl SystemInit + // ldr r0, =SystemInit + // blx r0 +/* Call static constructors */ + bl __libc_init_array + // ldr r0, =__libc_init_array + // blx r0 +/* Call the application's entry point.*/ + bl main + //ldr r0, =main + //blx r0 + +LoopForever: + b LoopForever + + +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M4. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack // Top of Stack + .word Reset_Handler // Reset Handler + .word NMI_Handler // NMI Handler + .word HardFault_Handler // Hard Fault Handler + .word MemManage_Handler // MPU Fault Handler + .word BusFault_Handler // Bus Fault Handler + .word UsageFault_Handler // Usage Fault Handler + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word SVC_Handler // SVCall Handler + .word DebugMon_Handler // Debug Monitor Handler + .word 0 // Reserved + .word PendSV_Handler // PendSV Handler + .word SysTick_Handler // SysTick Handler + + // External Interrupts + .word WWDG1_IRQHandler // Window WatchDog 1 + .word PVD_AVD_IRQHandler // PVD and AVD through EXTI Line detection + .word TAMP_IRQHandler // Tamper and TimeStamps through the EXTI line + .word RTC_WKUP_ALARM_IRQHandler // RTC Wakeup and Alarm through the EXTI line + .word RESERVED4_IRQHandler // Reserved + .word RCC_IRQHandler // RCC + .word EXTI0_IRQHandler // EXTI Line0 + .word EXTI1_IRQHandler // EXTI Line1 + .word EXTI2_IRQHandler // EXTI Line2 + .word EXTI3_IRQHandler // EXTI Line3 + .word EXTI4_IRQHandler // EXTI Line4 + .word DMA1_Stream0_IRQHandler // DMA1 Stream 0 + .word DMA1_Stream1_IRQHandler // DMA1 Stream 1 + .word DMA1_Stream2_IRQHandler // DMA1 Stream 2 + .word DMA1_Stream3_IRQHandler // DMA1 Stream 3 + .word DMA1_Stream4_IRQHandler // DMA1 Stream 4 + .word DMA1_Stream5_IRQHandler // DMA1 Stream 5 + .word DMA1_Stream6_IRQHandler // DMA1 Stream 6 + .word ADC1_IRQHandler // ADC1 + .word FDCAN1_IT0_IRQHandler // FDCAN1 Interrupt line 0 + .word FDCAN2_IT0_IRQHandler // FDCAN2 Interrupt line 0 + .word FDCAN1_IT1_IRQHandler // FDCAN1 Interrupt line 1 + .word FDCAN2_IT1_IRQHandler // FDCAN2 Interrupt line 1 + .word EXTI5_IRQHandler // External Line5 interrupts through AIEC + .word TIM1_BRK_IRQHandler // TIM1 Break interrupt + .word TIM1_UP_IRQHandler // TIM1 Update Interrupt + .word TIM1_TRG_COM_IRQHandler // TIM1 Trigger and Commutation Interrupt + .word TIM1_CC_IRQHandler // TIM1 Capture Compare + .word TIM2_IRQHandler // TIM2 + .word TIM3_IRQHandler // TIM3 + .word TIM4_IRQHandler // TIM4 + .word I2C1_EV_IRQHandler // I2C1 Event + .word I2C1_ER_IRQHandler // I2C1 Error + .word I2C2_EV_IRQHandler // I2C2 Event + .word I2C2_ER_IRQHandler // I2C2 Error + .word SPI1_IRQHandler // SPI1 + .word SPI2_IRQHandler // SPI2 + .word USART1_IRQHandler // USART1 + .word USART2_IRQHandler // USART2 + .word USART3_IRQHandler // USART3 + .word EXTI10_IRQHandler // External Line10 interrupts through AIEC + .word RTC_TIMESTAMP_IRQHandler // RTC TimeStamp through EXTI Line + .word EXTI11_IRQHandler // External Line11 interrupts through AIEC + .word TIM8_BRK_IRQHandler // TIM8 Break Interrupt + .word TIM8_UP_IRQHandler // TIM8 Update Interrupt + .word TIM8_TRG_COM_IRQHandler // TIM8 Trigger and Commutation Interrupt + .word TIM8_CC_IRQHandler // TIM8 Capture Compare Interrupt + .word DMA1_Stream7_IRQHandler // DMA1 Stream7 + .word FMC_IRQHandler // FMC + .word SDMMC1_IRQHandler // SDMMC1 + .word TIM5_IRQHandler // TIM5 + .word SPI3_IRQHandler // SPI3 + .word UART4_IRQHandler // UART4 + .word UART5_IRQHandler // UART5 + .word TIM6_IRQHandler // TIM6 + .word TIM7_IRQHandler // TIM7 + .word DMA2_Stream0_IRQHandler // DMA2 Stream 0 + .word DMA2_Stream1_IRQHandler // DMA2 Stream 1 + .word DMA2_Stream2_IRQHandler // DMA2 Stream 2 + .word DMA2_Stream3_IRQHandler // DMA2 Stream 3 + .word DMA2_Stream4_IRQHandler // DMA2 Stream 4 + .word ETH1_IRQHandler // Ethernet + .word ETH1_WKUP_IRQHandler // Ethernet Wakeup through EXTI line + .word FDCAN_CAL_IRQHandler // FDCAN Calibration + .word EXTI6_IRQHandler // EXTI Line6 interrupts through AIEC + .word EXTI7_IRQHandler // EXTI Line7 interrupts through AIEC + .word EXTI8_IRQHandler // EXTI Line8 interrupts through AIEC + .word EXTI9_IRQHandler // EXTI Line9 interrupts through AIEC + .word DMA2_Stream5_IRQHandler // DMA2 Stream 5 + .word DMA2_Stream6_IRQHandler // DMA2 Stream 6 + .word DMA2_Stream7_IRQHandler // DMA2 Stream 7 + .word USART6_IRQHandler // USART6 + .word I2C3_EV_IRQHandler // I2C3 event + .word I2C3_ER_IRQHandler // I2C3 error + .word USBH_OHCI_IRQHandler // USB Host OHCI + .word USBH_EHCI_IRQHandler // USB Host EHCI + .word EXTI12_IRQHandler // EXTI Line12 interrupts through AIEC + .word EXTI13_IRQHandler // EXTI Line13 interrupts through AIEC + .word DCMI_IRQHandler // DCMI + .word CRYP1_IRQHandler // Crypto1 global interrupt + .word HASH1_IRQHandler // Crypto Hash1 interrupt + .word FPU_IRQHandler // FPU + .word UART7_IRQHandler // UART7 + .word UART8_IRQHandler // UART8 + .word SPI4_IRQHandler // SPI4 + .word SPI5_IRQHandler // SPI5 + .word SPI6_IRQHandler // SPI6 + .word SAI1_IRQHandler // SAI1 + .word LTDC_IRQHandler // LTDC + .word LTDC_ER_IRQHandler // LTDC error + .word ADC2_IRQHandler // ADC2 + .word SAI2_IRQHandler // SAI2 + .word QUADSPI_IRQHandler // QUADSPI + .word LPTIM1_IRQHandler // LPTIM1 global interrupt + .word CEC_IRQHandler // HDMI_CEC + .word I2C4_EV_IRQHandler // I2C4 Event + .word I2C4_ER_IRQHandler // I2C4 Error + .word SPDIF_RX_IRQHandler // SPDIF_RX + .word OTG_IRQHandler // USB On The Go HS global interrupt + .word RESERVED99_IRQHandler // Reserved + .word IPCC_RX0_IRQHandler // Mailbox RX0 Free interrupt + .word IPCC_TX0_IRQHandler // Mailbox TX0 Free interrupt + .word DMAMUX1_OVR_IRQHandler // DMAMUX1 Overrun interrupt + .word IPCC_RX1_IRQHandler // Mailbox RX1 Free interrupt + .word IPCC_TX1_IRQHandler // Mailbox TX1 Free interrupt + .word CRYP2_IRQHandler // Crypto2 global interrupt + .word HASH2_IRQHandler // Crypto Hash2 interrupt + .word I2C5_EV_IRQHandler // I2C5 Event Interrupt + .word I2C5_ER_IRQHandler // I2C5 Error Interrupt + .word GPU_IRQHandler // GPU Global Interrupt + .word DFSDM1_FLT0_IRQHandler // DFSDM Filter0 Interrupt + .word DFSDM1_FLT1_IRQHandler // DFSDM Filter1 Interrupt + .word DFSDM1_FLT2_IRQHandler // DFSDM Filter2 Interrupt + .word DFSDM1_FLT3_IRQHandler // DFSDM Filter3 Interrupt + .word SAI3_IRQHandler // SAI3 global Interrupt + .word DFSDM1_FLT4_IRQHandler // DFSDM Filter4 Interrupt + .word TIM15_IRQHandler // TIM15 global Interrupt + .word TIM16_IRQHandler // TIM16 global Interrupt + .word TIM17_IRQHandler // TIM17 global Interrupt + .word TIM12_IRQHandler // TIM12 global Interrupt + .word MDIOS_IRQHandler // MDIOS global Interrupt + .word EXTI14_IRQHandler // EXTI Line14 interrupts through AIEC + .word MDMA_IRQHandler // MDMA global Interrupt + .word DSI_IRQHandler // DSI global Interrupt + .word SDMMC2_IRQHandler // SDMMC2 global Interrupt + .word HSEM_IT2_IRQHandler // HSEM global Interrupt + .word DFSDM1_FLT5_IRQHandler // DFSDM Filter5 Interrupt + .word EXTI15_IRQHandler // EXTI Line15 interrupts through AIEC + .word nCTIIRQ1_IRQHandler // Cortex-M4 CTI interrupt 1 + .word nCTIIRQ2_IRQHandler // Cortex-M4 CTI interrupt 2 + .word TIM13_IRQHandler // TIM13 global interrupt + .word TIM14_IRQHandler // TIM14 global interrupt + .word DAC_IRQHandler // DAC1 and DAC2 underrun error interrupts + .word RNG1_IRQHandler // RNG1 interrupt + .word RNG2_IRQHandler // RNG2 interrupt + .word I2C6_EV_IRQHandler // I2C6 Event Interrupt + .word I2C6_ER_IRQHandler // I2C6 Error Interrupt + .word SDMMC3_IRQHandler // SDMMC3 global Interrupt + .word LPTIM2_IRQHandler // LPTIM2 global interrupt + .word LPTIM3_IRQHandler // LPTIM3 global interrupt + .word LPTIM4_IRQHandler // LPTIM4 global interrupt + .word LPTIM5_IRQHandler // LPTIM5 global interrupt + .word ETH1_LPI_IRQHandler // ETH1_LPI interrupt + .word RESERVED143_IRQHandler // Reserved + .word MPU_SEV_IRQHandler // MPU Send Event through AIEC + .word RCC_WAKEUP_IRQHandler // RCC Wake up interrupt + .word SAI4_IRQHandler // SAI4 global interrupt + .word DTS_IRQHandler // Temperature sensor interrupt + .word RESERVED148_IRQHandler // Reserved + .word WAKEUP_PIN_IRQHandler // Interrupt for all 6 wake-up pins + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak RESERVED4_IRQHandler + .thumb_set RESERVED4_IRQHandler,Default_Handler + + .weak RESERVED99_IRQHandler + .thumb_set RESERVED99_IRQHandler,Default_Handler + + .weak ETH1_LPI_IRQHandler + .thumb_set ETH1_LPI_IRQHandler,Default_Handler + + .weak RESERVED143_IRQHandler + .thumb_set RESERVED143_IRQHandler,Default_Handler + + .weak WWDG1_IRQHandler + .thumb_set WWDG1_IRQHandler,Default_Handler + + .weak PVD_AVD_IRQHandler + .thumb_set PVD_AVD_IRQHandler,Default_Handler + + .weak TAMP_IRQHandler + .thumb_set TAMP_IRQHandler,Default_Handler + + .weak RTC_WKUP_ALARM_IRQHandler + .thumb_set RTC_WKUP_ALARM_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Stream0_IRQHandler + .thumb_set DMA1_Stream0_IRQHandler,Default_Handler + + .weak DMA1_Stream1_IRQHandler + .thumb_set DMA1_Stream1_IRQHandler,Default_Handler + + .weak DMA1_Stream2_IRQHandler + .thumb_set DMA1_Stream2_IRQHandler,Default_Handler + + .weak DMA1_Stream3_IRQHandler + .thumb_set DMA1_Stream3_IRQHandler,Default_Handler + + .weak DMA1_Stream4_IRQHandler + .thumb_set DMA1_Stream4_IRQHandler,Default_Handler + + .weak DMA1_Stream5_IRQHandler + .thumb_set DMA1_Stream5_IRQHandler,Default_Handler + + .weak DMA1_Stream6_IRQHandler + .thumb_set DMA1_Stream6_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak ADC2_IRQHandler + .thumb_set ADC2_IRQHandler,Default_Handler + + .weak FDCAN1_IT0_IRQHandler + .thumb_set FDCAN1_IT0_IRQHandler,Default_Handler + + .weak FDCAN2_IT0_IRQHandler + .thumb_set FDCAN2_IT0_IRQHandler,Default_Handler + + .weak FDCAN1_IT1_IRQHandler + .thumb_set FDCAN1_IT1_IRQHandler,Default_Handler + + .weak FDCAN2_IT1_IRQHandler + .thumb_set FDCAN2_IT1_IRQHandler,Default_Handler + + .weak FDCAN_CAL_IRQHandler + .thumb_set FDCAN_CAL_IRQHandler,Default_Handler + + .weak EXTI5_IRQHandler + .thumb_set EXTI5_IRQHandler,Default_Handler + + .weak TIM1_BRK_IRQHandler + .thumb_set TIM1_BRK_IRQHandler,Default_Handler + + .weak TIM1_UP_IRQHandler + .thumb_set TIM1_UP_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_IRQHandler + .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM4_IRQHandler + .thumb_set TIM4_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_IRQHandler + .thumb_set USART3_IRQHandler,Default_Handler + + .weak EXTI10_IRQHandler + .thumb_set EXTI10_IRQHandler,Default_Handler + + .weak RTC_TIMESTAMP_IRQHandler + .thumb_set RTC_TIMESTAMP_IRQHandler,Default_Handler + + .weak EXTI11_IRQHandler + .thumb_set EXTI11_IRQHandler,Default_Handler + + .weak TIM8_BRK_IRQHandler + .thumb_set TIM8_BRK_IRQHandler,Default_Handler + + .weak TIM8_UP_IRQHandler + .thumb_set TIM8_UP_IRQHandler,Default_Handler + + .weak TIM8_TRG_COM_IRQHandler + .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler + + .weak TIM8_CC_IRQHandler + .thumb_set TIM8_CC_IRQHandler,Default_Handler + + .weak DMA1_Stream7_IRQHandler + .thumb_set DMA1_Stream7_IRQHandler,Default_Handler + + .weak FMC_IRQHandler + .thumb_set FMC_IRQHandler,Default_Handler + + .weak SDMMC1_IRQHandler + .thumb_set SDMMC1_IRQHandler,Default_Handler + + .weak TIM5_IRQHandler + .thumb_set TIM5_IRQHandler,Default_Handler + + .weak SPI3_IRQHandler + .thumb_set SPI3_IRQHandler,Default_Handler + + .weak UART4_IRQHandler + .thumb_set UART4_IRQHandler,Default_Handler + + .weak UART5_IRQHandler + .thumb_set UART5_IRQHandler,Default_Handler + + .weak TIM6_IRQHandler + .thumb_set TIM6_IRQHandler,Default_Handler + + .weak TIM7_IRQHandler + .thumb_set TIM7_IRQHandler,Default_Handler + + .weak DMA2_Stream0_IRQHandler + .thumb_set DMA2_Stream0_IRQHandler,Default_Handler + + .weak DMA2_Stream1_IRQHandler + .thumb_set DMA2_Stream1_IRQHandler,Default_Handler + + .weak DMA2_Stream2_IRQHandler + .thumb_set DMA2_Stream2_IRQHandler,Default_Handler + + .weak DMA2_Stream3_IRQHandler + .thumb_set DMA2_Stream3_IRQHandler,Default_Handler + + .weak DMA2_Stream4_IRQHandler + .thumb_set DMA2_Stream4_IRQHandler,Default_Handler + + .weak ETH1_IRQHandler + .thumb_set ETH1_IRQHandler,Default_Handler + + .weak ETH1_WKUP_IRQHandler + .thumb_set ETH1_WKUP_IRQHandler,Default_Handler + + .weak ETH1_LPI_IRQHandler + .thumb_set ETH1_LPI_IRQHandler,Default_Handler + + .weak EXTI6_IRQHandler + .thumb_set EXTI6_IRQHandler,Default_Handler + + .weak EXTI7_IRQHandler + .thumb_set EXTI7_IRQHandler,Default_Handler + + .weak EXTI8_IRQHandler + .thumb_set EXTI8_IRQHandler,Default_Handler + + .weak EXTI9_IRQHandler + .thumb_set EXTI9_IRQHandler,Default_Handler + + .weak DMA2_Stream5_IRQHandler + .thumb_set DMA2_Stream5_IRQHandler,Default_Handler + + .weak DMA2_Stream6_IRQHandler + .thumb_set DMA2_Stream6_IRQHandler,Default_Handler + + .weak DMA2_Stream7_IRQHandler + .thumb_set DMA2_Stream7_IRQHandler,Default_Handler + + .weak USART6_IRQHandler + .thumb_set USART6_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak USBH_OHCI_IRQHandler + .thumb_set USBH_OHCI_IRQHandler,Default_Handler + + .weak USBH_EHCI_IRQHandler + .thumb_set USBH_EHCI_IRQHandler,Default_Handler + + .weak EXTI12_IRQHandler + .thumb_set EXTI12_IRQHandler,Default_Handler + + .weak EXTI13_IRQHandler + .thumb_set EXTI13_IRQHandler,Default_Handler + + .weak DCMI_IRQHandler + .thumb_set DCMI_IRQHandler,Default_Handler + + .weak CRYP1_IRQHandler + .thumb_set CRYP1_IRQHandler,Default_Handler + + .weak HASH1_IRQHandler + .thumb_set HASH1_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak UART7_IRQHandler + .thumb_set UART7_IRQHandler,Default_Handler + + .weak UART8_IRQHandler + .thumb_set UART8_IRQHandler,Default_Handler + + .weak SPI4_IRQHandler + .thumb_set SPI4_IRQHandler,Default_Handler + + .weak SPI5_IRQHandler + .thumb_set SPI5_IRQHandler,Default_Handler + + .weak SPI6_IRQHandler + .thumb_set SPI6_IRQHandler,Default_Handler + + .weak SAI1_IRQHandler + .thumb_set SAI1_IRQHandler,Default_Handler + + .weak LTDC_IRQHandler + .thumb_set LTDC_IRQHandler,Default_Handler + + .weak LTDC_ER_IRQHandler + .thumb_set LTDC_ER_IRQHandler,Default_Handler + + .weak SAI2_IRQHandler + .thumb_set SAI2_IRQHandler,Default_Handler + + .weak QUADSPI_IRQHandler + .thumb_set QUADSPI_IRQHandler,Default_Handler + + .weak LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak CEC_IRQHandler + .thumb_set CEC_IRQHandler,Default_Handler + + .weak I2C4_EV_IRQHandler + .thumb_set I2C4_EV_IRQHandler,Default_Handler + + .weak I2C4_ER_IRQHandler + .thumb_set I2C4_ER_IRQHandler,Default_Handler + + .weak SPDIF_RX_IRQHandler + .thumb_set SPDIF_RX_IRQHandler,Default_Handler + + .weak OTG_IRQHandler + .thumb_set OTG_IRQHandler,Default_Handler + + .weak IPCC_RX0_IRQHandler + .thumb_set IPCC_RX0_IRQHandler,Default_Handler + + .weak IPCC_TX0_IRQHandler + .thumb_set IPCC_TX0_IRQHandler,Default_Handler + + .weak DMAMUX1_OVR_IRQHandler + .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler + + .weak IPCC_RX1_IRQHandler + .thumb_set IPCC_RX1_IRQHandler,Default_Handler + + .weak IPCC_TX1_IRQHandler + .thumb_set IPCC_TX1_IRQHandler,Default_Handler + + .weak CRYP2_IRQHandler + .thumb_set CRYP2_IRQHandler,Default_Handler + + .weak HASH2_IRQHandler + .thumb_set HASH2_IRQHandler,Default_Handler + + .weak I2C5_EV_IRQHandler + .thumb_set I2C5_EV_IRQHandler,Default_Handler + + .weak I2C5_ER_IRQHandler + .thumb_set I2C5_ER_IRQHandler,Default_Handler + + .weak GPU_IRQHandler + .thumb_set GPU_IRQHandler,Default_Handler + + .weak DFSDM1_FLT0_IRQHandler + .thumb_set DFSDM1_FLT0_IRQHandler,Default_Handler + + .weak DFSDM1_FLT1_IRQHandler + .thumb_set DFSDM1_FLT1_IRQHandler,Default_Handler + + .weak DFSDM1_FLT2_IRQHandler + .thumb_set DFSDM1_FLT2_IRQHandler,Default_Handler + + .weak DFSDM1_FLT3_IRQHandler + .thumb_set DFSDM1_FLT3_IRQHandler,Default_Handler + + .weak SAI3_IRQHandler + .thumb_set SAI3_IRQHandler,Default_Handler + + .weak DFSDM1_FLT4_IRQHandler + .thumb_set DFSDM1_FLT4_IRQHandler,Default_Handler + + .weak TIM15_IRQHandler + .thumb_set TIM15_IRQHandler,Default_Handler + + .weak TIM16_IRQHandler + .thumb_set TIM16_IRQHandler,Default_Handler + + .weak TIM17_IRQHandler + .thumb_set TIM17_IRQHandler,Default_Handler + + .weak TIM12_IRQHandler + .thumb_set TIM12_IRQHandler,Default_Handler + + .weak MDIOS_IRQHandler + .thumb_set MDIOS_IRQHandler,Default_Handler + + .weak EXTI14_IRQHandler + .thumb_set EXTI14_IRQHandler,Default_Handler + + .weak MDMA_IRQHandler + .thumb_set MDMA_IRQHandler,Default_Handler + + .weak DSI_IRQHandler + .thumb_set DSI_IRQHandler,Default_Handler + + .weak SDMMC2_IRQHandler + .thumb_set SDMMC2_IRQHandler,Default_Handler + + .weak HSEM_IT2_IRQHandler + .thumb_set HSEM_IT2_IRQHandler,Default_Handler + + .weak DFSDM1_FLT5_IRQHandler + .thumb_set DFSDM1_FLT5_IRQHandler,Default_Handler + + .weak EXTI15_IRQHandler + .thumb_set EXTI15_IRQHandler,Default_Handler + + .weak nCTIIRQ1_IRQHandler + .thumb_set nCTIIRQ1_IRQHandler,Default_Handler + + .weak nCTIIRQ2_IRQHandler + .thumb_set nCTIIRQ2_IRQHandler,Default_Handler + + .weak TIM13_IRQHandler + .thumb_set TIM13_IRQHandler,Default_Handler + + .weak TIM14_IRQHandler + .thumb_set TIM14_IRQHandler,Default_Handler + + .weak DAC_IRQHandler + .thumb_set DAC_IRQHandler,Default_Handler + + .weak RNG1_IRQHandler + .thumb_set RNG1_IRQHandler,Default_Handler + + .weak RNG2_IRQHandler + .thumb_set RNG2_IRQHandler,Default_Handler + + .weak I2C6_EV_IRQHandler + .thumb_set I2C6_EV_IRQHandler,Default_Handler + + .weak I2C6_ER_IRQHandler + .thumb_set I2C6_ER_IRQHandler,Default_Handler + + .weak SDMMC3_IRQHandler + .thumb_set SDMMC3_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_IRQHandler,Default_Handler + + .weak LPTIM3_IRQHandler + .thumb_set LPTIM3_IRQHandler,Default_Handler + + .weak LPTIM4_IRQHandler + .thumb_set LPTIM4_IRQHandler,Default_Handler + + .weak LPTIM5_IRQHandler + .thumb_set LPTIM5_IRQHandler,Default_Handler + + .weak MPU_SEV_IRQHandler + .thumb_set MPU_SEV_IRQHandler,Default_Handler + + .weak RCC_WAKEUP_IRQHandler + .thumb_set RCC_WAKEUP_IRQHandler,Default_Handler + + .weak SAI4_IRQHandler + .thumb_set SAI4_IRQHandler,Default_Handler + + .weak DTS_IRQHandler + .thumb_set DTS_IRQHandler,Default_Handler + + .weak RESERVED148_IRQHandler + .thumb_set RESERVED148_IRQHandler,Default_Handler + + .weak WAKEUP_PIN_IRQHandler + .thumb_set WAKEUP_PIN_IRQHandler,Default_Handler + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/src/tools/hispark_trace/hispark/CM4/Makefile b/src/tools/hispark_trace/hispark/CM4/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..822c842b58b6fc5d3805f19b9dbf1c55bb9eeda6 --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/Makefile @@ -0,0 +1,126 @@ +# 配置编译工具链 +TOOLCHAIN = arm-none-eabi- +CC = $(TOOLCHAIN)gcc +AS = $(TOOLCHAIN)as +LD = $(TOOLCHAIN)ld +AR = $(TOOLCHAIN)ar +OBJCP = $(TOOLCHAIN)objcopy +OBJDUMP = $(TOOLCHAIN)objdump + +# 生成的文件名<项目名> +PROJECT := daplink_M4 + +TOP_DIR = . +OUT_DIR = $(TOP_DIR)/out + +# 定义文件格式和文件名 +TARGET := $(PROJECT) +TARGET_ELF := $(OUT_DIR)/$(TARGET).elf +TARGET_BIN := $(OUT_DIR)/$(TARGET).bin +TARGET_HEX := $(OUT_DIR)/$(TARGET).hex +TARGET_MAP := $(OUT_DIR)/$(TARGET).map +TARGET_ASM := $(OUT_DIR)/$(TARGET).asm + +OBJCPFLAGS_ELF_TO_BIN = -Obinary +OBJCPFLAGS_ELF_TO_ASM = -S +OBJCPFLAGS_ELF_TO_HEX = -Oihex +OBJCPFLAGS_BIN_TO_HEX = -Ibinary -Oihex + +# 定义路径 +SCRIPT_DIR := $(TOP_DIR)/ +STARTUP_DIR := $(TOP_DIR)/Core/Startup +INC_DIR := -I $(TOP_DIR)/Drivers/CMSIS/Device/ST/STM32MP1xx/Include +INC_DIR += -I $(TOP_DIR)/Drivers/CMSIS/Include +INC_DIR += -I $(TOP_DIR)/Drivers/STM32MP1xx_HAL_Driver/Inc/Legacy +INC_DIR += -I $(TOP_DIR)/Drivers/STM32MP1xx_HAL_Driver/Inc +INC_DIR += -I $(TOP_DIR)/Core/Src +INC_DIR += -I $(TOP_DIR)/Core/Inc +INC_DIR += -I $(TOP_DIR)/securec/include + +SOURCE := $(wildcard $(TOP_DIR)/Core/Src/*.c) +SOURCE += $(wildcard $(TOP_DIR)/Drivers/STM32MP1xx_HAL_Driver/Src/*.c) +SOURCE += $(wildcard $(TOP_DIR)/securec/src/*.c) + + +# 设置LD链接脚本文件 +LDSCRIPT := $(SCRIPT_DIR)/STM32MP157DAAX_RAM.ld + +#需要链接的静态库 +#Set the TOOLCHAIN_DIR in ~/.bashrc or in build.sh (the tool chain is gcc-arm-10.3-2021.07-x86_64-arm-none-eabi). +#TOOLCHAIN_DIR=CI_ENV +LDLIBS_DIR += -L$(TOOLCHAIN_DIR)/lib/gcc/arm-none-eabi/10.3.1/thumb/v7e-m+fp/hard +LDLIBS_DIR += -L$(TOOLCHAIN_DIR)/arm-none-eabi/lib/thumb/v7e-m+fp/hard + +#定义编译标志 +CCFLAGS += -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Os -ffunction-sections -fdata-sections -Wall -fstack-usage +CCFLAGS += '-DMETAL_MAX_DEVICE_REGIONS=2' -DSTM32MP157Dxx -DUSE_HAL_DRIVER -DCORE_CM4 -DNO_ATOMIC_64_SUPPORT -DMETAL_INTERNAL -DVIRTIO_SLAVE_ONLY +CCFLAGS += -DNEED_UART_INIT +CCFLAGS += -static --specs=nano.specs --specs=nosys.specs +CCFLAGS += $(INC_DIR) +CCFLAGS += -DSECUREC_HAVE_ERRNO_H=0 +ASFLAGS += -mcpu=cortex-m4 -x assembler-with-cpp -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard --specs=nano.specs --specs=nosys.specs +LDFLAGS += $(LDLIBS_DIR) +LDFLAGS += -T $(LDSCRIPT) -Map="$(TARGET_MAP)" --gc-sections -static --no-wchar-size-warning --start-group -lc -lm --end-group +# 添加启动文件 +SOURCE_ASM += $(STARTUP_DIR)/startup_stm32mp157daax.s + +# 替换文件后缀 +C_OBJS := $(SOURCE:%.c=%.o) +ASM_OBJS := $(SOURCE_ASM:%.s=%.o) + +# 编译命令的定义 +COMPILE = $(CC) $(CCFLAGS) -c $< -o $@ +ASSEMBLE = $(CC) $(ASFLAGS) -c $< -o $@ +LINK = $(LD) $+ $(LDFLAGS) -o $@ +ELF_TO_BIN = $(OBJCP) $(OBJCPFLAGS_ELF_TO_BIN) $< $@ +BIN_TO_HEX = $(OBJCP) $(OBJCPFLAGS_BIN_TO_HEX) $< $@ +ELF_TO_ASM = $(OBJDUMP) $(OBJCPFLAGS_ELF_TO_ASM) $< $@ + +# 定义伪目标 +.PHONY :all clean printf + +# 定义规则 +all: $(TARGET_HEX) + @echo "build done" + +$(TARGET_HEX): $(TARGET_BIN) + $(BIN_TO_HEX) + +$(TARGET_BIN): $(TARGET_ELF) + $(ELF_TO_BIN) + +$(TARGET_ELF): $(C_OBJS) $(ASM_OBJS) + $(LINK) + +$(C_OBJS):%.o:%.c + $(shell if [ ! -e $(OUT_DIR) ]; then mkdir -p $(OUT_DIR); fi) + $(COMPILE) + +$(ASM_OBJS):%.o:%.s + $(ASSEMBLE) + +printf: + @echo $(ASM_OBJS) + @echo $(ASSEMBLE) + +ifeq ($(OS), Windows_NT) +RM := del /s/q +clean: +# $(RM) $(C_OBJS) $(ASM_OBJS) + $(RM) .\*.o + $(RM) .\*.su + $(RM) .\*.bin + $(RM) .\*.hex + $(RM) .\*.map + $(RM) .\*.elf + @echo "clean done" +else +clean: + find . -name "*.o" | xargs rm -f + find . -name "*.su" | xargs rm -f + rm -f $(TARGET_HEX) + rm -f $(TARGET_BIN) + rm -f $(TARGET_ELF) + rm -f $(TARGET_MAP) + @echo "clean done" +endif diff --git a/src/tools/hispark_trace/hispark/CM4/STM32MP157DAAX_RAM.ld b/src/tools/hispark_trace/hispark/CM4/STM32MP157DAAX_RAM.ld new file mode 100644 index 0000000000000000000000000000000000000000..9e2ffa297faa57c3f29cb3215e3713e3939b660d --- /dev/null +++ b/src/tools/hispark_trace/hispark/CM4/STM32MP157DAAX_RAM.ld @@ -0,0 +1,199 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Abstract : Linker script for STM32MP1 series +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +**

© Copyright (c) 2019 STMicroelectronics. +** All rights reserved.

+** +** 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 +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x10040000; /* end of RAM */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000300 + m_text (RX) : ORIGIN = 0x00000300, LENGTH = 0x0000FD00 + m_tbl_shm (RW) : ORIGIN = 0x10000000, LENGTH = 0x00001000 + m_data (RW) : ORIGIN = 0x10001000, LENGTH = 0x0001F000 + m_ipc_shm (RW) : ORIGIN = 0x10040000, LENGTH = 0x00008000 + MSGQ_SHM(RW) : ORIGIN = 0x10050000, LENGTH = 20K + VARQ_SHM(RW) : ORIGIN = 0x10020000, LENGTH = 120K +} + + /* Symbols needed for OpenAMP to enable rpmsg */ +__OPENAMP_region_start__ = ORIGIN(m_ipc_shm); +__OPENAMP_region_end__ = ORIGIN(m_ipc_shm)+LENGTH(m_ipc_shm); +g_msgQStart = ORIGIN(MSGQ_SHM); +g_varQStart = ORIGIN(VARQ_SHM); + +/* Sections */ +SECTIONS +{ + /* The startup code into ROM memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > m_interrupts + + + /* The program code and other data into ROM memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } > m_text + + /* Constant data into ROM memory*/ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } > m_text + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > m_text + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } > m_text + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } > m_text + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } > m_text + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } > m_text + + /* Used by the startup to initialize data */ + __DATA_ROM = .; + _sidata = LOADADDR(.data); + + /* Initialized data sections */ + .data : AT(__DATA_ROM) + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } > m_data + + __DATA_END = __DATA_ROM + (_edata - _sdata); + text_end = ORIGIN(m_text) + LENGTH(m_text); + ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") + + /* Uninitialized data section into RAM memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } > m_data + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } > m_data + + + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } + +} diff --git a/src/tools/hispark_trace/hispark/boot/Makefile b/src/tools/hispark_trace/hispark/boot/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..bf31863c08da21fdb7d3cab8145a935b558f8d6c --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/Makefile @@ -0,0 +1,139 @@ +ARCH := arm +CROSS_COMPILE := arm-none-eabi- +ifeq ($(OS), Windows_NT) +PLATFORM="Windows" +COMPILE_TIME = $(shell echo %date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%) +else +PLATFORM="Unix-Like" +COMPILE_TIME = $(date + "%Y-%M-%d %H:%M:%s") +endif + + +AR := $(CROSS_COMPILE)ar +CC := $(CROSS_COMPILE)gcc +NM := $(CROSS_COMPILE)nm +CPP := $(CROSS_COMPILE)cpp +LD := $(CROSS_COMPILE)ld +OBJCOPY := $(CROSS_COMPILE)objcopy +OBJDUMP := $(CROSS_COMPILE)objdump + +TOP_DIR := . + +OUT = $(TOP_DIR)/out +TARGET := daplink_boot +TARGET_ELF := $(OUT)/$(TARGET).elf +TARGET_BIN := $(OUT)/$(TARGET).bin +TARGET_HEX := $(OUT)/$(TARGET).hex +TARGET_ASM := $(OUT)/$(TARGET).asm +TARGET_MAP := $(OUT)/$(TARGET).map + +OBJCPFLAGS_ELF_TO_BIN = -Obinary +OBJCPFLAGS_ELF_TO_HEX = -Ibinary -Oihex +OBJCPFLAGS_ELF_TO_LIST = -S + +CFLAGS = -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -std=gnu11 -fno-strict-aliasing -fno-PIE -Os -fno-stack-protector -fno-delete-null-pointer-checks -fmacro-prefix-map=./= -g -fstack-usage -Wno-format-nonliteral -Werror=date-time -D__ARM__ -Wa,-mimplicit-it=always -mthumb -mthumb-interwork -mabi=aapcs-linux -mword-relocations -fPIE -fPIC -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -pipe -march=armv7-a -mtune=generic-armv7-a +CFLAGS += -fno-short-wchar -fno-strict-aliasing +CFLAGS += -mfloat-abi=soft +CFLAGS += -fshort-enums +CFLAGS += -DCORE_CA7 -DSTM32MP153Dxx -D__NO_USB_LIB_C -DDAPLINK_HIC_ID=0x97969949 -DUSE_HAL_DRIVER -DINTERFACE_STM32MP153 -DUSE_LEGACY_CMSIS_RTOS -DOS_CLOCK=25000000 +CFLAGS += -DDAPLINK_VERSION=10002000 +CFLAGS += -DHISPARK_TRACE -DHISPARK_BOOT +CFLAGS += -DWINUSB_INTERFACE +CFLAGS += -DCONFIG_HAS_VBAR +CFLAGS += -DDAPLINK_BASEADDR=0x2FFCA500 +CFLAGS += -DM4BIN_SIZE_ADDR=0xC004 -DM4_TEXT_BASEADDR=0xBB000 +ASFLAGS = -Wall -march=armv7-a -mtune=cortex-a7 -nostidinc -fno-PIE -g -D__ARM__ -D__ASSEMBLY__ -Wa,-mimplicit-it=always -mthumb -mthumb-interwork -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -pipe -D__LINUX_ARM_ARCH__=7 -mtune=generic-armv7-a +ASFLAGS += -DHISPARK_BOOT + + +LDSCRIPT = $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/$(TARGET).lds + +SRC = $(wildcard $(TOP_DIR)/source/*.c) +SRC += $(wildcard $(TOP_DIR)/source/crc/*.c) +SRC += $(wildcard $(TOP_DIR)/source/boot/*.c) +SRC += $(wildcard $(TOP_DIR)/source/flash/*.c) +SRC += $(wildcard $(TOP_DIR)/source/config/*.c) +SRC += $(wildcard $(TOP_DIR)/source/mmi/key/*.c) +SRC += $(wildcard $(TOP_DIR)/source/mmi/oled/*.c) +SRC += $(wildcard $(TOP_DIR)/source/mmi/display/src/*.c) +SRC += $(wildcard $(TOP_DIR)/source/mmi/*.c) +SRC += $(wildcard $(TOP_DIR)/source/securec/src/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/cmsis/*.c) +SRC += $(wildcard $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/Src/*.c) + +ASM_SRC = ${wildcard $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/gcc/*.S} + +INC = -I $(TOP_DIR)/include +INC += -I $(TOP_DIR)/source +INC += -I $(TOP_DIR)/source/crc +INC += -I $(TOP_DIR)/source/flash +INC += -I $(TOP_DIR)/source/config +INC += -I $(TOP_DIR)/source/mmi +INC += -I $(TOP_DIR)/source/mmi/key +INC += -I $(TOP_DIR)/source/mmi/oled +INC += -I $(TOP_DIR)/source/mmi/display/inc +INC += -I $(TOP_DIR)/source/daplink +INC += -I $(TOP_DIR)/source/hic_hal +INC += -I $(TOP_DIR)/source/hic_hal/stm32 +INC += -I $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx +INC += -I $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/cmsis +INC += -I $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver +INC += -I $(TOP_DIR)/source/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/Inc +INC += -I $(TOP_DIR)/source/securec/include + +INC += -I $(TOP_DIR)/source/cmsis-core +INC += -I $(TOP_DIR)/Drivers/CMSIS/Device/ST/STM32MP1xx/Include + +NORMOM_CFLAGS :=$(CFLAGS) $(INC) +NORMOM_ASFLAGS :=$(CFLAGS) -I $(TOP_DIR)/include +LDFLAGS = -nostdlib -T $(LDSCRIPT) -nostartfiles -Wl,--gc-sections -pie -lc -static -Wl,--no-wchar-size-warning +#Set the TOOLCHAIN_DIR in ~/.bashrc or in build.sh (the tool chain is gcc-arm-10.3-2021.07-x86_64-arm-none-eabi). +#TOOLCHAIN_DIR=CI_ENV +LIBS = $(TOOLCHAIN_DIR)/lib/gcc/arm-none-eabi/10.3.1/libgcc.a +LIBS += $(TOOLCHAIN_DIR)/arm-none-eabi/lib/libc.a + + +OBJ := $(SRC:%.c=%.o) +ASMOBJ := $(ASM_SRC:%.S=%.o) + +DEF += + +STARTUP_RAW = $(wildcard $(STARTUP)) +STARTUP_OBJ = $(STARTUP_RAW:%.c=%.o) + +daplink_OBJ = ./out/*.o + +all: $(OUT) $(TARGET_BIN) +$(TARGET_BIN): $(TARGET_ELF) + $(Q)$(OBJCOPY) $(OBJCPFLAGS_ELF_TO_BIN) $(TARGET_ELF) $(TARGET_BIN) + $(Q)$(OBJDUMP) -d $(TARGET_ELF) > $(TARGET_ASM) + $(Q)$(OBJDUMP) -stD $(TARGET_ELF) > $(TARGET_MAP) + +$(TARGET_ELF):$(OBJ) $(ASMOBJ) + $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ + +$(OBJ):%.o:%.c + @echo Compile $< + $(CC) $(NORMOM_CFLAGS) -c $< -o $@ + +$(ASMOBJ):%.o:%.S + @echo Compile $< + $(CC) $(NORMOM_ASFLAGS) -c $< -o $@ + +$(OUT): + mkdir -p $(OUT) + +.PHONY: clean +ifeq ($(OS), Windows_NT) +RM := del /s/q +clean: + $(RM) ..\boot\*.o + $(RM) ..\boot\*.su + $(RM) out +else +clean : + find . -name "*.o" | xargs rm -f + find . -name "*.su" | xargs rm -f + -rm -rf $(OUT)/* +endif diff --git a/src/tools/hispark_trace/hispark/boot/source/boot.c b/src/tools/hispark_trace/hispark/boot/source/boot.c new file mode 100644 index 0000000000000000000000000000000000000000..b14953e7bc2dfd7d1e2efa5fde5adfa5110753a9 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/boot.c @@ -0,0 +1,452 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file boot.c + * @author MCU Driver Team + * @brief daplink boot code + */ + +#include +#include +#include +#include +#include "securec.h" +#include "stm32mp1xx.h" +#include "daplink_addr.h" +#include "crc32.h" +#include "display.h" +#include "menu_tbl.h" +#include "key.h" +#include "sdk.h" +#include "FlashPrg.h" +#include "config_storage_update.h" +#include "boot.h" + +#ifndef NULLPTR +#define NULLPTR (void *)0 +#endif + +#define SUCCESS 0 +#define FAIL 0xFFFFFFFF +#define BOOT_SIZE K_BYTE(32) +#define PARAM_SIZE K_BYTE(16) +#define IMAGE_BASE_ADDR (DAPLINK_ROM_BL_START + BOOT_SIZE + PARAM_SIZE) + +#define BOOT_KEY_WAIT_TIMES 2000 +#define BOOT_KEY_PRESS_TH 1000 +#define BOOT_NO_PRESS_TIMEOUT 100 + +#define BOOK_KEY_PRESS_DETECTION_INTERVAL 50 + +#if (defined(DAPLINK_BASEADDR) && (DAPLINK_BASEADDR != 0)) +#define DAPLINK_A7_CODE_START DAPLINK_BASEADDR +#else +#error "Please set a7 code start" +#endif +#define DAPLINK_M4_CODE_START 0x38000000 + +/* DaplinK Image Information */ +static ImageInfoST g_imageInfo = { + .blockIdAddr = DAPLINK_ROM_BL_START + BOOT_SIZE, + .a7Addr = DAPLINK_A7_CODE_START, + .m4Addr = DAPLINK_M4_CODE_START, /* 内存镜像,实际会写到RETRAM(0x0000000) */ + .readPageSize = FLASH_READ_SIZE, + .load[0] = { + .a7Start = IMAGE_BASE_ADDR, + .a7Size = IMAGE_BASE_ADDR + K_BYTE(700) - 4, + .m4Start = IMAGE_BASE_ADDR + K_BYTE(700), + .m4Size = IMAGE_BASE_ADDR + K_BYTE(1024) - 4, + }, + .load[1] = { + .a7Start = IMAGE_BASE_ADDR + K_BYTE(1024), + .a7Size = IMAGE_BASE_ADDR + K_BYTE(700 + 1024) - 4, + .m4Start = IMAGE_BASE_ADDR + K_BYTE(700 + 1024), + .m4Size = IMAGE_BASE_ADDR + K_BYTE(2048) - 4, + } +}; + +typedef void (*PHookFunc)(void); + +/** + * @brief Get Block Index. + * @param blockId [OUTPUT] + * @retval success + */ +static uint32_t GetBlockIndex(IMAGE_BLOCK_ID *blockId) +{ + *blockId = (ConfigStartFlagRead() == CONFIG_STRAT_FLAG_A) ? IMAGE_BLOCK_A : IMAGE_BLOCK_B; + return LOAD_SUCCESS; +} + +/** + * @brief Get DAPLink CA7 image size + * @param blockId [INPUT] + * @retval success/fail + */ +static uint32_t GetCA7ImageSize(IMAGE_BLOCK_ID blockId) +{ + uint32_t imageSize; + if (FlashRead(g_imageInfo.load[blockId].a7Size, sizeof(uint32_t), (uint8_t *)&imageSize) != 0) { + /* read image fail, return fail */ + return LOAD_FAIL; + } + if (imageSize == 0) { + /* empty image, return fail */ + return LOAD_FAIL; + } + g_imageInfo.ca7ImageSize = imageSize; + return LOAD_SUCCESS; +} + +/** + * @brief Get DAPLink CM4 image size + * @param blockId [INPUT] + * @retval success/fail + */ +static uint32_t GetCM4ImageSize(IMAGE_BLOCK_ID blockId) +{ + uint32_t imageSize; + if (FlashRead(g_imageInfo.load[blockId].m4Size, sizeof(uint32_t), (uint8_t *)&imageSize) != 0) { + /* read image fail, return fail */ + return LOAD_FAIL; + } + if (imageSize == 0) { + /* empty image, return fail */ + return LOAD_FAIL; + } + g_imageInfo.cm4ImageSize = imageSize; + return LOAD_SUCCESS; +} + +/** + * @brief Write Image from src to dest + * @param dst destination address + * @param src source address + * @param len image length + * @retval success/fail + */ +static uint32_t WriteImage(uint32_t dst, uint32_t src, uint32_t len) +{ + errno_t rc = EOK; + uint32_t imageSize = len - 4; + uint32_t a7LoadAddr = src; + uint32_t dest = dst; + uint8_t buf[FLASH_READ_SIZE]; + uint32_t ckSum = 0; + uint32_t crc; + + if (FlashRead(a7LoadAddr + imageSize, sizeof(int), buf) != SUCCESS) { + /* If get image size fail, uninit flash and return fail */ + UnInit(0); + return FAIL; + } + /* Get expect crc */ + crc = *(unsigned int *)buf; + while (imageSize > 0) { + /* Copy Image from src to dest */ + uint32_t readLen = (imageSize >= g_imageInfo.readPageSize) ? g_imageInfo.readPageSize : imageSize; + if (FlashRead(a7LoadAddr, readLen, buf) != SUCCESS) { + UnInit(0); + return FAIL; + } + /* calc crc checksum */ + ckSum = Crc32Continue(ckSum, buf, readLen); + rc = memcpy_s((void *)dest, readLen, (void *)buf, readLen); + if (rc != EOK) { + UnInit(0); + return FAIL; + } + imageSize -= readLen; + a7LoadAddr += readLen; + dest += readLen; + } + /* return success if calc crc equl expect crc, or return error */ + return (ckSum == crc) ? LOAD_SUCCESS : LOAD_CRC_ERROR; +} + +/** + * @brief Write DAPLink CA7 image + * @param blockId [INPUT] + * @retval success/fail + */ +static inline uint32_t WriteCA7Image(IMAGE_BLOCK_ID blockId) +{ + return WriteImage(g_imageInfo.a7Addr, g_imageInfo.load[blockId].a7Start, g_imageInfo.ca7ImageSize); +} + +/** + * @brief Write DAPLink CM4 image + * @param blockId [INPUT] + * @retval success/fail + */ +static inline uint32_t WriteCM4Image(IMAGE_BLOCK_ID blockId) +{ + return WriteImage(g_imageInfo.m4Addr, g_imageInfo.load[blockId].m4Start, g_imageInfo.cm4ImageSize); +} + +/** + * @brief Load Firmware + * @param blockId [INPUT] + * @retval success/fail + */ +static uint32_t FirmwareLoad(IMAGE_BLOCK_ID blockId) +{ + uint32_t ret; + + /* Get CA7 Image size */ + if (GetCA7ImageSize(blockId) != LOAD_SUCCESS) { + return LOAD_FAIL; + } + + /* Write CA7 Image */ + ret = WriteCA7Image(blockId); + if (ret != LOAD_SUCCESS) { + return ret; + } + + /* Get CM4 Image size */ + if (GetCM4ImageSize(blockId) != LOAD_SUCCESS) { + return LOAD_FAIL; + } + + /* Write CM4 Image */ + ret = WriteCM4Image(blockId); + if (ret != LOAD_SUCCESS) { + return ret; + } + return SUCCESS; +} + +/** + * @brief Jump to address and run + * @param addr next pc address + * @retval None + */ +static void Jump(unsigned int addr) +{ + (*(void(*)(void))addr)(); +} + +/** + * @brief Select a Startup block + * @param None + * @retval bool 0: no block selectd, 1: select a block + */ +static bool BlockSelect(void) +{ + unsigned int preTick = (unsigned int)HAL_GetTick(); + unsigned int curTick; + unsigned char keyVal; + unsigned int keyCnt = 0; + + for (unsigned int i = 0; i < BOOT_KEY_WAIT_TIMES;) { + curTick = (unsigned int)HAL_GetTick(); + if (curTick == preTick) { + /* The key event is counted only once at a fixed interval. */ + continue; + } + preTick = curTick; + keyVal = KeyScan(LONG_KEY); + if (keyVal == KEY_CONFIRM) { + /* Only the confirmation key is counted. */ + keyCnt++; + } + ++i; + if (i == BOOT_NO_PRESS_TIMEOUT) { + /* Key not detected. */ + if (keyCnt == 0) { + return 0; + } + } + } + /* If the number of key presses in a specified period exceeds the + threshold, the confirm key is pressed. */ + return keyCnt >= BOOT_KEY_PRESS_TH; +} + +/** + * @brief Key processing + * @param None + * @retval None + */ +static void KeyProcess(void) +{ + uint8_t keyValue = 0; + keyValue = KeyScan(SHORT_KEY); + switch (keyValue) { + case KEY_DOWN: + FrameMoveDown(); /* Move Down */ + break; + case KEY_UP: + FrameMoveUp(); /* Move Up */ + break; + case KEY_CONFIRM: + FrameItemSelect(); /* Selected block */ + break; + default: + break; + } +} + +/** + * @brief Menu processing + * @param None + * @retval None + */ +static void BootMenuProcess(void) +{ + Frame *frame = GetDefaultFrame(); /* Get Boot Frame */ + unsigned int curTick = 0; + unsigned int preTick = 0; + + FrameShow(frame); + + /* Wait Key Press */ + while (1) { + curTick = (unsigned int)HAL_GetTick() / BOOK_KEY_PRESS_DETECTION_INTERVAL; + if (curTick != preTick) { + preTick = curTick; + KeyProcess(); /* If startup block is selected, don't return here */ + } + } +} + +/** + * @brief Get Start Image Block Id + * @param None + * @retval None + */ +static inline unsigned int GetStartBlock(void) +{ + return (ConfigStartFlagRead() == CONFIG_STRAT_FLAG_A) ? IMAGE_BLOCK_A : IMAGE_BLOCK_B; +} + +/** + * @brief Set Start Image Block Id + * @param None + * @retval None + */ +static inline void SetStartBlock(unsigned int blockId) +{ + ConfigStartFlagSave(blockId == IMAGE_BLOCK_A ? CONFIG_STRAT_FLAG_A : CONFIG_STRAT_FLAG_B); +} + +/** + * @brief Start frome specified Image Block + * @param blockId Image block index + * @param pfunc Image Load fail hook function + * @retval None + */ +static void StartupWithBlockId(unsigned int blockId, PHookFunc pfunc) +{ + unsigned int index = blockId; + + Init(0, 0, 0); /* Flash Init */ + + if (FirmwareLoad(index) != LOAD_SUCCESS) { /* Load Image from specified block */ + if (pfunc) { + pfunc(); /* try hook process when load fail */ + } + /* if load fail, try start from another block */ + index = (index == IMAGE_BLOCK_A) ? IMAGE_BLOCK_B : IMAGE_BLOCK_A; + if (FirmwareLoad(index) != LOAD_SUCCESS) { + return; + } + } + /* If the startup block is not the same as the specified block (starting from the + specified block fails), update the block */ + if (GetStartBlock() != index) { + SetStartBlock(index); + } + UnInit(0); /* Flash DeInit */ + Jump(g_imageInfo.a7Addr); /* Jump to DAPLINK CA7 code first instruction */ +} + +/** + * @brief Wait Confirm an popup fail message + * @param void + * @retval None + */ +static void WaitConfirm(void) +{ + unsigned int curTick = 0; + unsigned int preTick = 0; + + while (1) { + curTick = (unsigned int)HAL_GetTick() / BOOK_KEY_PRESS_DETECTION_INTERVAL; + if (curTick != preTick) { + preTick = curTick; + if (KeyScan(SHORT_KEY) == KEY_CONFIRM) { /* Confirmed, End the infinite loop */ + break; + } + } + } +} + +/** + * @brief Load Fail process, popup a messeage and wait + * @param void + * @retval None + */ +static void StartUpFailProc(void) +{ + PopupMsgStartupFail(); + WaitConfirm(); +} + +/** + * @brief Select BlockA, a function connect frame items + * @param void + * @retval None + */ +void SelectedBlockA(void) +{ + StartupWithBlockId(IMAGE_BLOCK_A, StartUpFailProc); +} + +/** + * @brief Select BlockB, a function connect frame items + * @param void + * @retval None + */ +void SelectedBlockB(void) +{ + StartupWithBlockId(IMAGE_BLOCK_B, StartUpFailProc); +} + +/** + * @brief boot main function + * @param void + * @retval None + */ +int BootMain(void) +{ + IMAGE_BLOCK_ID blockId; + + if (BlockSelect()) { + /* If you press and hold the OK key during startup, the boot menu + is displayed. May Changed startup block id */ + BootMenuProcess(); + } + /* Get startup block id */ + if (GetBlockIndex(&blockId) != LOAD_SUCCESS) { + return LOAD_FAIL; + } + /* Start From block id */ + StartupWithBlockId(blockId, NULLPTR); + return 0; +} diff --git a/src/tools/hispark_trace/hispark/boot/source/boot.h b/src/tools/hispark_trace/hispark/boot/source/boot.h new file mode 100644 index 0000000000000000000000000000000000000000..97317b761317b45e5f4e94a1f30e73d99167b732 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/boot.h @@ -0,0 +1,76 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file boot.h + * @author MCU Driver Team + * @brief daplink boot header + */ +#ifndef BOOT_H +#define BOOT_H + +#include + +#define K_BYTE(size) ((size)*1024) +#define M_BYTE(size) (size) * 1024 * 1024) + +#define FLASH_WRITE_SIZE 256 +#define FLASH_READ_SIZE 4096 +typedef enum { + IMAGE_BLOCK_A = 0, + IMAGE_BLOCK_B, + IMAGE_BLOCK_NUM, +} IMAGE_BLOCK_ID; + +typedef enum { + IMAGE_CA7 = 0, + IMAGE_CM4, +} IMAGE_TYPE; + +typedef enum { + LOAD_SUCCESS = 0, + LOAD_FAIL = -1, + LOAD_CRC_ERROR = -2, +} LOAD_RET_TYPE; + +typedef struct { + unsigned int a7Start; + unsigned int a7Size; /* image后为image size */ + unsigned int m4Start; + unsigned int m4Size; +} ImageLoadST; + +typedef struct { + ImageLoadST load[IMAGE_BLOCK_NUM]; + unsigned int blockIdAddr; + unsigned int a7Addr; + unsigned int m4Addr; + + IMAGE_BLOCK_ID blockId; + unsigned int readPageSize; + unsigned int ca7ImageSize; + unsigned int cm4ImageSize; +} ImageInfoST; + +int BootMain(void); + +void SelectedBlockA(void); + +void SelectedBlockB(void); + +extern uint32_t FlashRead(uint32_t adr, uint32_t sz, uint8_t *buf); + +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/boot/source/config/config_storage_update.c b/src/tools/hispark_trace/hispark/boot/source/config/config_storage_update.c new file mode 100644 index 0000000000000000000000000000000000000000..3eee19b5e339ebfcecc0971752245189ea7fd178 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/config/config_storage_update.c @@ -0,0 +1,105 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file config_storage_update.c + * @author MCU Driver Team + * @brief config storage update driver. + */ +#include +#include +#include "FlashPrg.h" +#include "config_storage_update.h" + +#define ONE_PAGE_SIZE 256 + +/** + * @brief Save Startup Flag. + * @param flag Startup Flag + * @retval Success or Failure Result + */ +int32_t ConfigStartFlagSave(uint32_t flag) +{ + bool algoFreeFlag[TARGET_LIB_ALGO_MAX_NUM]; + bool imageFreeFlag[TARGET_LIB_IMAGE_MAX_NUM]; + bool factoryImageFreeFlag[TARGET_LIB_FACTORY_IMAGE_MAX_NUM]; + uint32_t algoIndex; + uint32_t addr; + uint32_t factoryFlag; + uint32_t powerStatus; + + UnInit(0); + Init(0, 0, 0); + /* Backing Up Data */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_CURRENT_ALGO_INDEX_OFFSET; + FlashRead(addr, sizeof(algoIndex), (uint8_t *)&algoIndex); + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FREE_ALGO_FLAG_ARRY_OFFSET; + FlashRead(addr, sizeof(algoFreeFlag), (uint8_t *)algoFreeFlag); + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FREE_IMAGE_FLAG_ARRY_OFFSET; + FlashRead(addr, sizeof(imageFreeFlag), (uint8_t *)imageFreeFlag); + + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FACTORY_FLAG_OFFSET; + FlashRead(addr, sizeof(factoryFlag), (uint8_t *)&factoryFlag); + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FREE_FACTORY_IMAGE_FLAG_ARRY_OFFSET; + FlashRead(addr, sizeof(factoryImageFreeFlag), (uint8_t *)factoryImageFreeFlag); + + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_POWER_STATUS_FLAG_OFFSET; + FlashRead(addr, sizeof(powerStatus), (uint8_t *)&powerStatus); + /* Erasing the flash memory of the old data storage area */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_STARTUP_FLAG_OFFSET; + EraseSector(addr); + /* Restoring Data */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_CURRENT_ALGO_INDEX_OFFSET; + ProgramPage(addr, sizeof(algoIndex), (uint32_t *)&algoIndex); + + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FREE_ALGO_FLAG_ARRY_OFFSET; + ProgramPage(addr, sizeof(algoFreeFlag), (uint32_t *)algoFreeFlag); + + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FREE_FACTORY_IMAGE_FLAG_ARRY_OFFSET; + ProgramPage(addr, sizeof(factoryImageFreeFlag), (uint32_t *)factoryImageFreeFlag); + + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FREE_IMAGE_FLAG_ARRY_OFFSET; + ProgramPage(addr, sizeof(imageFreeFlag), (uint32_t *)imageFreeFlag); + + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_FACTORY_FLAG_OFFSET; + ProgramPage(addr, sizeof(factoryFlag), (uint32_t *)&factoryFlag); + + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_POWER_STATUS_FLAG_OFFSET; + ProgramPage(addr, sizeof(powerStatus), (uint32_t *)&powerStatus); + /* Update data */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_STARTUP_FLAG_OFFSET; + ProgramPage(addr, sizeof(flag), (uint32_t *)&flag); + UnInit(0); + return 0; +} + +/** + * @brief Read Startup Flag. + * @retval Startup Flag + */ +uint32_t ConfigStartFlagRead(void) +{ + uint32_t addr; + uint32_t startFlag; + + UnInit(0); + Init(0, 0, 0); + /* Read start flag */ + addr = CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_UPDATE_STARTUP_FLAG_OFFSET; + FlashRead(addr, sizeof(startFlag), (uint8_t *)&startFlag); + UnInit(0); + return startFlag; +} diff --git a/src/tools/hispark_trace/hispark/boot/source/config/config_storage_update.h b/src/tools/hispark_trace/hispark/boot/source/config/config_storage_update.h new file mode 100644 index 0000000000000000000000000000000000000000..9bad47a0f25d713d9443a1bc191b4f2bbf55f5be --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/config/config_storage_update.h @@ -0,0 +1,91 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file config_storage_update.h + * @author MCU Driver Team + * @brief config storage update driver. + */ +#ifndef CONFIG_STORAGE_UPDATE_H +#define CONFIG_STORAGE_UPDATE_H + +#include +#include "target_lib_manager.h" + +#define CONFIG_LOAD_TYPE_UNKNOW 0 +#define CONFIG_LOAD_TYPE_INTERFACE 1 +#define CONFIG_LOAD_TYPE_BOOT 2 +#define CONFIG_LOAD_TYPE_IMAGE 3 +#define CONFIG_LOAD_TYPE_ALGO 4 +#define CONFIG_LOAD_TYPE_TARGET 5 + +#define CONFIG_FLASH_BASS_ADDR 0x10048000 + +#define CONFIG_STRAT_FLAG_A 0xFFFFFFFF +#define CONFIG_STRAT_FLAG_B 0 +#define CONFIG_STORAGE_MAX_BOOT_SIZE 0x8000 +#define CONFIG_STORAGE_MAX_INFACR_SIZE 0x100000 +#define CONFIG_STORAGE_ONE_IMAGE_MAX_SIZE TARGET_LIB_ONE_IMAGE_SIZE +#define CONFIG_STORAGE_ONE_ALGO_MAX_SIZE TARGET_LIB_ONE_ALGO_SIZE + +#define CONFIG_STORAGE_MAX_SIZE 0x2000 +#define CONFIG_STORAGE_UPDATE_BASE_ADDR (0x10048000 + 0x8000) +#define CONFIG_STORAGE_UPDATE_BACKUP_BASE_ADDR (CONFIG_STORAGE_UPDATE_BASE_ADDR + CONFIG_STORAGE_MAX_SIZE) + +#define CONFIG_STORAGE_UPDATE_ALGO_LIST_OFFSET 0x0 +#define CONFIG_STORAGE_UPDATE_ALGO_LIST_SIZE 0x800 + +#define CONFIG_STORAGE_UPDATE_IMAGE_LIST_OFFSET 0x800 +#define CONFIG_STORAGE_UPDATE_IMAGE_LIST_SIZE 0x800 + +#define CONFIG_STORAGE_UPDATE_STARTUP_FLAG_OFFSET 0x1000 +#define CONFIG_STORAGE_UPDATE_STARTUP_FLAG_SIZE 0x4 + +#define CONFIG_STORAGE_UPDATE_FREE_ALGO_FLAG_ARRY_OFFSET 0x1004 +#define CONFIG_STORAGE_UPDATE_FREE_ALGO_FLAG_ARRY_SIZE 0x50 + +#define CONFIG_STORAGE_UPDATE_FREE_IMAGE_FLAG_ARRY_OFFSET 0x1054 /* 4 * 20 byte */ +#define CONFIG_STORAGE_UPDATE_FREE_IMAGE_FLAG_ARRY_SIZE 0x28 + +#define CONFIG_STORAGE_UPDATE_FREE_FACTORY_IMAGE_FLAG_ARRY_OFFSET 0x107C /* 4 * 10 byte */ +#define CONFIG_STORAGE_UPDATE_FREE_FACTORY_IMAGE_FLAG_ARRY_SIZE 0x28 + +#define CONFIG_STORAGE_UPDATE_CURRENT_ALGO_INDEX_OFFSET 0x10A4 +#define CONFIG_STORAGE_UPDATE_CURRENT_ALGO_INDEX_SIZE 0x4 + +#define CONFIG_STORAGE_UPDATE_FACTORY_ALGO_LIST_OFFSET 0x1100 +#define CONFIG_STORAGE_UPDATE_FACTORY_ALGO_LIST_SIZE 0xD0 + +#define CONFIG_STORAGE_UPDATE_FACTORY_FLAG_OFFSET 0x12D0 +#define CONFIG_STORAGE_UPDATE_FACTORY_FLAG_SIZE 0x4 + +#define CONFIG_STORAGE_UPDATE_POWER_STATUS_FLAG_OFFSET 0x12D4 +#define CONFIG_STORAGE_UPDATE_POWER_STATUS_FLAG_SIZE 0x4 + + +/* No add base config addr */ +#define CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LIST_OFFSET 0x210000 +#define CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LIST_SIZE 0x800 + +#define CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_OFFSET 0x20C000 +#define CONFIG_STORAGE_UPDATE_IMAGE_LOAD_CNT_LIST_SIZE 0x1000 + +#define CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_OFFSET 0x20E000 +#define CONFIG_STORAGE_UPDATE_FACTORY_IMAGE_LOAD_CNT_LIST_SIZE 0x1000 +int32_t ConfigStartFlagSave(uint32_t flag); +uint32_t ConfigStartFlagRead(void); + +#endif /* #ifndef CONFIG_STORAGE_UPDATE_H */ diff --git a/src/tools/hispark_trace/hispark/boot/source/config/target_lib_manager.h b/src/tools/hispark_trace/hispark/boot/source/config/target_lib_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..3d80de8a3fb10227e1752aa2c31ef9e8d7156217 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/config/target_lib_manager.h @@ -0,0 +1,59 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file target_lib_manager.h + * @author MCU Driver Team + * @brief target flash library mamager driver. + */ +#ifndef TARGET_LIB_MANAGER_H +#define TARGET_LIB_MANAGER_H + +#define TARGET_LIB_OK 0 +#define TARGET_LIB_ERROR 1 + +#define TARGET_LIB_FILE_STATUS_BAD 0 +#define TARGET_LIB_FILE_STATUS_NORMAL 1 +#define TARGET_LIB_FILE_STATUS_SECURITY 2 + +#define TARGET_LIB_SEC_REGION 0x000A0000 +#define TARGET_LIB_APP_REGION 0x00010000 +#define TARGET_LIB_DATA_REGION 0x00020000 + +#define TARGET_LIB_FLASH_BASE_ADDR 0x10048000 +#define TARGET_LIB_FLASH_BLOCK_SIZE 4096 +#define TARGET_LIB_ALGO_OFFSET 0x300000 +#define TARGET_LIB_IMAGE_OFFSET 0x400000 +#define TARGET_LIB_FACTORY_IMAGE_OFFSET 0x900000 + +#define TARGET_LIB_IMAGE_IN_NAME_MAX_LEN 32 +#define TARGET_LIB_IMAGE_NAME_MAX_LEN 64 +#define TARGET_LIB_IMAGE_MAX_NUM 10 +#define TARGET_LIB_ALGO_MAX_NUM 10 +#define TARGET_LIB_FACTORY_ALGO_MAX_NUM TARGET_LIB_ALGO_MAX_NUM +#define TARGET_LIB_FACTORY_IMAGE_MAX_NUM 10 +#define TARGET_LIB_LOAD_CNT_INVALIA 0xFAFAFAFA + +#define TARGET_LIB_IMAGE_START (TARGET_LIB_FLASH_BASE_ADDR + TARGET_LIB_IMAGE_OFFSET) +#define TARGET_LIB_ONE_IMAGE_SIZE (125 * TARGET_LIB_FLASH_BLOCK_SIZE) /* 125*4096 = 500k */ + +#define TARGET_LIB_ALGO_START (TARGET_LIB_FLASH_BASE_ADDR + TARGET_LIB_ALGO_OFFSET) +#define TARGET_LIB_ONE_ALGO_SIZE (2 * TARGET_LIB_FLASH_BLOCK_SIZE) /* 2*4096 = 8K */ + +#define TARGET_LIB_FACTORY_IMAGE_START (TARGET_LIB_FLASH_BASE_ADDR + TARGET_LIB_FACTORY_IMAGE_OFFSET) +#define TARGET_LIB_ONE_FACTORY_IMAGE_SIZE (125 * TARGET_LIB_FLASH_BLOCK_SIZE) /* 125*4096 = 500k */ + +#endif diff --git a/src/tools/hispark_trace/hispark/boot/source/hic_hal/stm32/stm32mp1xx/daplink_boot.lds b/src/tools/hispark_trace/hispark/boot/source/hic_hal/stm32/stm32mp1xx/daplink_boot.lds new file mode 100644 index 0000000000000000000000000000000000000000..e16a4f2780419a64b1bbbc954185df1ae942f182 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/hic_hal/stm32/stm32mp1xx/daplink_boot.lds @@ -0,0 +1,65 @@ +/* create for stmp32mp157, A7_CODE run in sysram */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH("arm") +ENTRY(_start) + +TEXT_START = 0x2FFC2500; +RAM_START = 0x10000000; + +MEMORY +{ + A7_CODE(RX) : ORIGIN = TEXT_START, LENGTH = 16K + A7_SRAM(RW) : ORIGIN = RAM_START, LENGTH = 4K + STACK(RW) : ORIGIN = RAM_START + 4K, LENGTH = 16K +} + +SECTIONS +{ + . = ALIGN(4); + .text.entry : + { + KEEP(*(.text.entry)) + } > A7_CODE + + .text : + { + *(.text*) + *(.ram.text*) + } > A7_CODE + + .rodata : + { + . = ALIGN(4); + *(SORT_BY_ALIGNMENT(.rodata*)) + *(.got*) + } > A7_CODE + + .data : + { + . = ALIGN(4); + __data_load = LOADADDR(.data); + __data_start = .; + *(SORT_BY_ALIGNMENT(.data*)) + . = ALIGN(4); + __data_end = .; + } > A7_SRAM AT > A7_CODE + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } > A7_SRAM + + .stack (NOLOAD) : + { + . = ALIGN(4); + __SYSTEM_STACK_BEGIN__ = ORIGIN(STACK); + KEEP(*(.stacks)) + __SYSTEM_STACK_END__ = ORIGIN(STACK) + LENGTH(STACK); + } > STACK + STACK_TOP = __SYSTEM_STACK_END__; +} diff --git a/src/tools/hispark_trace/hispark/boot/source/hic_hal/stm32/stm32mp1xx/gcc/startup_stm32mp1xx.S b/src/tools/hispark_trace/hispark/boot/source/hic_hal/stm32/stm32mp1xx/gcc/startup_stm32mp1xx.S new file mode 100644 index 0000000000000000000000000000000000000000..3767104f6c665d628011a57e7dec22bf1564d568 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/hic_hal/stm32/stm32mp1xx/gcc/startup_stm32mp1xx.S @@ -0,0 +1,212 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * armboot - Startup Code for STM32MP1xx of HiSparkTrace + */ +#define ASM_NL ; +#define SYMBOL_NAME_STR(X) #X +#define SYMBOL_NAME(X) X +#ifdef __STDC__ +#define SYMBOL_NAME_LABEL(X) X##: +#else +#define SYMBOL_NAME_LABEL(X) X: +#endif +#define ALIGN .align 2 + +#define LENTRY(name) \ + ALIGN ASM_NL \ + SYMBOL_NAME_LABEL(name) + +#define ENTRY(name) \ + .globl SYMBOL_NAME(name) ASM_NL \ + LENTRY(name) + +#define END(name) \ + .size name, .-name + +#define ENDPROC(name) \ + .type name STT_FUNC ASM_NL \ + END(name) + +/************************************************************************* + * + * Startup Code (reset vector) + * + * Do important init only if we don't start from memory! + * Setup memory and board specific bits prior to relocation. + * Relocate armboot to ram. Setup stack. + * + *************************************************************************/ + .section .text.entry + + .globl _start + .globl save_boot_params_ret + .extern InterruptEntry + .type save_boot_params_ret,%function + .global raise + +_start: + /* 创建中断向量表 */ + ldr pc, =Reset_Handler /* 复位中断 */ + ldr pc, =Undefined_Handler /* 未定义指令中断 */ + ldr pc, =SVC_Handler /* Supervisor中断 */ + ldr pc, =PrefAbort_Handler /* 预取终止中断 */ + ldr pc, =DataAbort_Handler /* 数据终止中断 */ + ldr pc, =NotUsed_Handler /* 未使用中断 */ + ldr pc, =IRQ_Handler /* IRQ中断 */ + ldr pc, =FIQ_Handler /* FIQ中断 */ + +Reset_Handler: + /* Allow the board to save important registers */ + b save_boot_params + +/* 未定义指令中断函数 */ +Undefined_Handler: + b . + +/* Supervisor中断服务函数 */ +SVC_Handler: + b . + +/* 预取终止中断服务函数 */ +PrefAbort_Handler: + b . + +/* 数据终止中断服务函数 */ +DataAbort_Handler: + b . + +/* 未使用的中断服务函数 */ +NotUsed_Handler: + b . + +/* FIQ中断服务函数 */ +FIQ_Handler: + b . + +/* IRQ中断服务函数 */ +IRQ_Handler: + b . + +save_boot_params_ret: + /* + * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, + * except if in HYP mode already + */ + mrs r0, cpsr + and r1, r0, #0x1f @ mask mode bits + teq r1, #0x1a @ test for HYP mode + bicne r0, r0, #0x1f @ clear all mode bits + orrne r0, r0, #0x13 @ set SVC mode + orr r0, r0, #0xc0 @ disable FIQ and IRQ + msr cpsr,r0 + +/* + * Setup vector: + */ + /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ + mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register + bic r0, #(1<<13) @ V = 0 + mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register + + /* Set vector address in CP15 VBAR register */ + ldr r0, =_start + mcr p15, 0, r0, c12, c0, 0 @Set VBAR + + /* the mask ROM code should have PLL and others stable */ + bl cpu_init_cp15 + + bl _main + +raise: + b . + + +/************************************************************************* + * + * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) + * __attribute__((weak)); + * + * Stack pointer is not yet initialized at this moment + * Don't save anything to stack even if compiled with -O0 + * + *************************************************************************/ +ENTRY(save_boot_params) + b save_boot_params_ret @ back to my caller +ENDPROC(save_boot_params) + +/************************************************************************* + * + * cpu_init_cp15 + * + * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless + * CONFIG_SYS_ICACHE_OFF is defined. + * + *************************************************************************/ +ENTRY(cpu_init_cp15) + /* + * Invalidate L1 I/D + */ + mov r0, #0 @ set up for MCR + mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs + mcr p15, 0, r0, c7, c5, 0 @ invalidate icache + mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array + mcr p15, 0, r0, c7, c10, 4 @ DSB + mcr p15, 0, r0, c7, c5, 4 @ ISB + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002000 @ clear bits 13 (--V-) + bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) + orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align + orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB + orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache + mcr p15, 0, r0, c1, c0, 0 + + mov r5, lr @ Store my Caller + mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR) + mov r3, r1, lsr #20 @ get variant field + and r3, r3, #0xf @ r3 has CPU variant + and r4, r1, #0xf @ r4 has CPU revision + mov r2, r3, lsl #4 @ shift variant field for combined value + orr r2, r4, r2 @ r2 has combined CPU variant + revision + + ldr r0, =(STACK_TOP) + bic r0, r0, #7 /* 8-byte alignment for ABI compliance */ + mov sp, r0 + mov pc, r5 @ back to my caller +ENDPROC(cpu_init_cp15) + +ENTRY(data_copy) + ldr r4, =(__data_load) + ldr r5, =(__data_start) + ldr r6, =(__data_end) +copy_loop: + ldr r7, [r4] + str r7, [r5] + add r4, r4, #4 + add r5, r5, #4 + cmp r5, r6 + blt copy_loop + mov pc, lr +ENDPROC(data_copy) + +ENTRY(bss_clear) + ldr r4, =(__bss_start) + ldr r5, =(__bss_end) + mov r6, #0 +clear_loop: + str r6, [r4] + add r4, r4, #4 + cmp r4, r5 + blt clear_loop + mov pc, lr +ENDPROC(bss_clear) + +ENTRY(_main) + bl data_copy + bl bss_clear + bl main + +ENDPROC(_main) diff --git a/src/tools/hispark_trace/hispark/boot/source/main.c b/src/tools/hispark_trace/hispark/boot/source/main.c new file mode 100644 index 0000000000000000000000000000000000000000..ac834a66361e86cea1bec9501d8299af92ed58f8 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/main.c @@ -0,0 +1,46 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file main.h + * @author MCU Driver Team + * @brief daplink boot main file + */ + +#include +#include +#include "sdk.h" +#include "boot.h" + +#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) +#ifndef __MICROLIB +/* Avoids early implicit call to osKernelInitialize() */ +void _platform_post_stackheap_init (void) {} +#endif +#if (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) +/* Avoids the semihosting issue */ +__asm(" .global __ARM_use_no_argv\n"); +#endif +#endif + +int main(void) +{ + sdk_init(); + BootMain(); + for (;;) { + } + return 0; +} diff --git a/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/display.h b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/display.h new file mode 100644 index 0000000000000000000000000000000000000000..c2ec2c614588a3ade908b4d5ee7faef6158550a0 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/display.h @@ -0,0 +1,89 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file display.h + * @author MCU Driver Team + * @brief daplink boot display header + */ + +#ifndef DISPLAY_H +#define DISPLAY_H + +#include +#include "display_common.h" + +#define SOFTWARE_VERSION DAPLINK_COMPILE_TIME +#define HARDWARE_VERSION "V1.00" + +#define ITEM_LIST_MAX_LEN 128 +#define EXT_INFO_MAX_LEN 72 + +typedef struct ItemST Item; +typedef struct FrameST Frame; + +typedef void (*SelectedProc)(void); +typedef unsigned int (*GetExtText)(char *buf, unsigned int len); + +typedef enum { + FRAME_STATIC = 0, + FRAME_SHOW_MSG, + FRAME_DYN_ITEMS, +} FrameType; + +typedef struct { + unsigned int width; + unsigned int high; +} WinSize; + +struct ItemST { + char *text[LANGUAGE_NUM]; + SelectedProc itemSelectedProc; + GetExtText getInfo; +}; + +struct FrameST { + unsigned int pointer; + unsigned int begin; + unsigned int winSize; + size_t lineNumber; + size_t staticItemNum; + unsigned int rollEn; + Item *pItem; + char *name; +}; + +typedef struct { + unsigned char name[FILENAME_MAX_LEN]; +} FileName; + +typedef struct { + unsigned int width; + unsigned int high; + unsigned int showLineMask; + Language language; + Frame *frame; +} WinInfo; + +void FrameShow(const Frame *frame); +Frame *GetCurFrame(void); +Language GetWinLanguage(void); +void FrameMoveUp(void); +void FrameMoveDown(void); +void FrameItemSelect(void); +void PopupMsgStartupFail(void); + +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/display_common.h b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/display_common.h new file mode 100644 index 0000000000000000000000000000000000000000..42181562986cd32b17c1a31cd0d20448fbb71459 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/display_common.h @@ -0,0 +1,42 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file display_common.h + * @author MCU Driver Team + * @brief daplink boot display common header + */ + +#ifndef DISPLAY_COMMON_H +#define DISPLAY_COMMON_H + +#define MULTI_LANGUAGE(x) {x##_EN, x##_ZH} +#define GET_MULTILANGE_STR(x, language) ((language) == LANGUAGE_EN ? x##_EN : x##_ZH) + +#define WIN_HEIGHT (16 * 6) +#define WIN_WIDTH (24 * 8) +#define FONT_SIZE 16 +#define WIN_MAX_LINE (WIN_HEIGHT / FONT_SIZE) +#define ITEM_CONTEXT_MAX_LEN 48 +#define FILENAME_MAX_LEN 128 + +typedef enum { + LANGUAGE_EN = 0, + LANGUAGE_CN = 1, + LANGUAGE_NUM = 2, +} Language; + +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/menu_tbl.h b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/menu_tbl.h new file mode 100644 index 0000000000000000000000000000000000000000..b9807ee1cf82dca5d0057aa0dab6568bdc4e3401 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/menu_tbl.h @@ -0,0 +1,30 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file menu_tbl.h + * @author MCU Driver Team + * @brief daplink boot menu table header + */ + +#ifndef MENU_TBL_H +#define MENU_TBL_H + +#include "display.h" + +Frame *GetDefaultFrame(void); + +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/proc.h b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/proc.h new file mode 100644 index 0000000000000000000000000000000000000000..f3440a1245ea9b5bcaa7887a4c2331d87b9cdcca --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/proc.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file proc.h + * @author MCU Driver Team + * @brief daplink boot mmi process header + */ + +#ifndef PROC_H +#define PROC_H + +#define MSG_MAX_LEN 128 +#define SN_MAX_LEN 24 +#define VER_MAX_LEN 12 + +unsigned int GetBlockASelected(char *buf, unsigned int len); + +unsigned int GetBlockBSelected(char *buf, unsigned int len); + +#endif \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/res_en.h b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/res_en.h new file mode 100644 index 0000000000000000000000000000000000000000..9ab99d29318624e33fae7d86b55e74a9da837f97 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/res_en.h @@ -0,0 +1,34 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file res_en.h + * @author MCU Driver Team + * @brief daplink boot display resource string of english + */ + +#ifndef RES_EN_H +#define RES_EN_H + +#define STARTUP_SELECT_EN "Please Select From:" +#define STARTUP_FROM_BLOCK_A_EN "1.Startup from A Block" +#define STARTUP_FROM_BLOCK_B_EN "2.Startup from B Block" +#define SELECTED_EN "(boot partition)" +#define START_FAIL_TITLE_EN " Warning " +#define START_FAIL_MSG_EN "The boot partition file you selected does not exist or is damaged,"\ + "and it has been changed to another partition to boot" +#define BOOT_VERSION_EN "BootVersion V1.0.1" +#endif diff --git a/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/res_zh.h b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/res_zh.h new file mode 100644 index 0000000000000000000000000000000000000000..382d8e8a304b9820337735d154f90f14c6b9eae8 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/mmi/display/inc/res_zh.h @@ -0,0 +1,36 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file res_zh.h + * @author MCU Driver Team + * @brief daplink boot display resource string of chinese + */ + +#ifndef RES_ZH_H +#define RES_ZH_H + +#define STARTUP_SELECT_ZH "ѡĸϵͳ:" +#define STARTUP_FROM_BLOCK_A_ZH "1.A" +#define STARTUP_FROM_BLOCK_B_ZH "2.B" + +#define SELECTED_ZH "()" + +#define START_FAIL_TITLE_ZH " 澯 " +#define START_FAIL_MSG_ZH "ѡļڻ,ѸΪ" + +#define BOOT_VERSION_ZH "BootVersion V1.0.1" +#endif diff --git a/src/tools/hispark_trace/hispark/boot/source/mmi/display/src/display.c b/src/tools/hispark_trace/hispark/boot/source/mmi/display/src/display.c new file mode 100644 index 0000000000000000000000000000000000000000..bede80c5ac9397cb3466f02b4cb5913c7e6e6397 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/mmi/display/src/display.c @@ -0,0 +1,174 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file display.c + * @author MCU Driver Team + * @brief daplink boot display process + */ + +#include +#include +#include "securec.h" +#include "oled.h" +#include "menu_tbl.h" +#include "proc.h" +#include "res_en.h" +#include "res_zh.h" +#include "display.h" + +static WinInfo g_WinInfo = { + .width = WIN_WIDTH / (FONT_SIZE / 2), /* 默认为显示英文字符 */ + .high = WIN_HEIGHT / FONT_SIZE, + .showLineMask = 0, + .language = LANGUAGE_CN, +}; + +/** + * @brief Merge Two String to buffer. + */ +static char *MergeStr(char *const buf, unsigned int bufLen, char *part1, const char *part2) +{ + char *p = buf; + errno_t rc = EOK; + if (part2 == NULL) { /* if part2 is empty, don't merge */ + return part1; + } + + rc = strcpy_s(p, bufLen, part1); + if (rc != EOK) { + return part1; + } + rc = strncat_s(p, bufLen, part2, bufLen - strlen(p)); + if (rc != EOK) { + return part1; + } + return p; +} + +/** + * @brief Get Language + */ +Language GetWinLanguage(void) +{ + return g_WinInfo.language; +} + +/** + * @brief Frame Move Up + */ +void FrameMoveUp(void) +{ + Frame *frame = GetDefaultFrame(); + + if (frame->pointer > 0) { + frame->pointer--; + if (frame->pointer >= g_WinInfo.high - 1) { + frame->begin--; /* if pointer move out of window, frame move up one line */ + } + } else { + if (frame->rollEn) { /* roll process */ + unsigned int end = frame->lineNumber; + frame->pointer = end - 1; + if (end >= g_WinInfo.high) { + frame->begin = end - g_WinInfo.high; + } else { + frame->begin = 0; + } + } + } + FrameShow(frame); /* show frame */ +} + +/** + * @brief Frame Move Down + */ +void FrameMoveDown(void) +{ + Frame *frame = GetDefaultFrame(); + + if (frame->pointer < frame->lineNumber - 1) { + frame->pointer++; /* make pointer-- */ + if (frame->pointer >= g_WinInfo.high) { + frame->begin++; /* if pointer move out of window, frame move down one line */ + } + } else { + if (frame->rollEn) { /* roll process */ + frame->pointer = 0; + frame->begin = 0; + } + } + FrameShow(frame); /* show frame */ +} + +/** + * @brief Frame Selected process + */ +void FrameItemSelect(void) +{ + Frame *frame = GetDefaultFrame(); + Item *item = &frame->pItem[frame->pointer]; + if (!item) { /* item without connect frame, return */ + return; + } + if (item->itemSelectedProc) { /* item with selected process, do process */ + item->itemSelectedProc(); + } + return; +} + +/** + * @brief Frame Show + */ +void FrameShow(const Frame *frame) +{ + char itemText[ITEM_LIST_MAX_LEN] = {0}; + for (unsigned int i = frame->begin; i < frame->lineNumber; ++i) { + uint8_t reversed = (i == frame->pointer) ? 0 : 1; + char *p = (char *)frame->pItem[i].text[g_WinInfo.language]; + char *dynStr; + if (frame->pItem[i].getInfo) { /* Get items ext info */ + char extInfo[EXT_INFO_MAX_LEN]; + memset_s(extInfo, sizeof(extInfo), 0, sizeof(extInfo)); + if (frame->pItem[i].getInfo(extInfo, sizeof(extInfo))) { + /* Add extended information after items. */ + dynStr = extInfo; + p = MergeStr(itemText, sizeof(itemText), p, dynStr); + } + } + OledShowMenuItem(i, p, FONT_SIZE, reversed); + } + if (frame == GetDefaultFrame()) { + /* Show boot version in boot main frame */ + OledShowMsg(g_WinInfo.high - 1, BOOT_VERSION_EN, strlen(BOOT_VERSION_EN)); + } +} + +/** + * @brief Popup Message if startup fail + */ +void PopupMsgStartupFail(void) +{ + for (int line = 0; line < g_WinInfo.high; ++line) { + OledClearLine(line, 0, g_WinInfo.width); + } + char *title[] = MULTI_LANGUAGE(START_FAIL_TITLE); + int i = 0; + OledShowMsg(i++, title[GetWinLanguage()], FONT_SIZE); + char *msg[] = MULTI_LANGUAGE(START_FAIL_MSG); + i++; /* Insert a blank line between title and message. */ + OledShowMsg(i, msg[GetWinLanguage()], FONT_SIZE); +} diff --git a/src/tools/hispark_trace/hispark/boot/source/mmi/display/src/menu_tbl.c b/src/tools/hispark_trace/hispark/boot/source/mmi/display/src/menu_tbl.c new file mode 100644 index 0000000000000000000000000000000000000000..223d23a57c7a97836cd1344d87dcd2964ade4ea9 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/mmi/display/src/menu_tbl.c @@ -0,0 +1,59 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file menu_tbl.c + * @author MCU Driver Team + * @brief daplink boot menu display process + */ +#include +#include "display_common.h" +#include "display.h" +#include "res_en.h" +#include "res_zh.h" +#include "boot.h" +#include "util.h" +#include "proc.h" + +static Frame mainMenuFrame; + +#define FRAME_INIT(x, NAME, rollEnable) \ + .pointer = 0, \ + .lineNumber = ARRAY_SIZE(x), \ + .staticItemNum = ARRAY_SIZE(x), \ + .begin = 0, \ + .pItem = (x), \ + .name = (NAME), \ + .rollEn = (rollEnable) + +/* 菜单显示元素 */ +/* TOP Menu */ +static Item mainItems[] = { + {MULTI_LANGUAGE(STARTUP_SELECT), 0, 0}, + {MULTI_LANGUAGE(STARTUP_FROM_BLOCK_A), SelectedBlockA, GetBlockASelected}, + {MULTI_LANGUAGE(STARTUP_FROM_BLOCK_B), SelectedBlockB, GetBlockBSelected}, +}; + +/* 描述菜单链接关系和动作 */ +static Frame mainMenuFrame = { + FRAME_INIT(mainItems, "mainMenu", true), +}; + +/* Get Boot Main Frame */ +Frame *GetDefaultFrame(void) +{ + return &mainMenuFrame; +} diff --git a/src/middleware/hisilicon/nostask/kernel/nos_tick.c b/src/tools/hispark_trace/hispark/boot/source/mmi/display/src/proc.c similarity index 55% rename from src/middleware/hisilicon/nostask/kernel/nos_tick.c rename to src/tools/hispark_trace/hispark/boot/source/mmi/display/src/proc.c index 61872050301b3f55e54d4046faf6dd53f024cbce..27a5346e9c248dcdf25f9642e2db0d5e6d85a304 100644 --- a/src/middleware/hisilicon/nostask/kernel/nos_tick.c +++ b/src/tools/hispark_trace/hispark/boot/source/mmi/display/src/proc.c @@ -1,5 +1,5 @@ /** - * @copyright Copyright (c) 2023, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the * following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following @@ -15,48 +15,57 @@ * 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. - * @file nos_tick.c + * @file proc.c + * @author MCU Driver Team + * @brief daplink boot menu item selectd connect process */ -#include "nos_task_external.h" -/* - * 描述: Tick中断的处理函数。扫描任务超时链表、扫描超时软件定时器、扫描TSKMON等。 - */ -static void OsTickDispatcher(void) -{ - uintptr_t intSave; - intSave = NOS_IntLock(); +#include +#include +#include "securec.h" +#include "res_en.h" +#include "res_zh.h" +#include "display.h" +#include "oled.h" +#include "config_storage_update.h" +#include "proc.h" - g_uniTicks++; +/** + * @brief Boot Block A selected. + */ +unsigned int GetBlockASelected(char *buf, unsigned int len) +{ + errno_t rc = EOK; + char *msg[] = MULTI_LANGUAGE(SELECTED); - // 任务超时扫描 - if (g_taskScanHook != NULL) { - g_taskScanHook(); + if (ConfigStartFlagRead() != CONFIG_STRAT_FLAG_A) { + /* Block A isn't selected */ + return false; } - NOS_IntRestore(intSave); + rc = strncpy_s(buf, len, msg[GetWinLanguage()], len); + if (rc != EOK) { + return false; + } + return true; } -/* - * 描述: tick尾部处理 - */ -void OsHwiDispatchTick(void); -void OsHwiDispatchTick(void) +/** + * @brief Boot Block B selected process + */ +unsigned int GetBlockBSelected(char *buf, unsigned int len) { - TICK_NO_RESPOND_CNT++; + errno_t rc = EOK; + char *msg[] = MULTI_LANGUAGE(SELECTED); - if ((UNI_FLAG & OS_FLG_TICK_ACTIVE) != 0) { - // OsTskContextLoad, 回到被打断的tick处理现场 - return; + if (ConfigStartFlagRead() != CONFIG_STRAT_FLAG_B) { + /* Block B isn't selected */ + return false; } - UNI_FLAG |= OS_FLG_TICK_ACTIVE; - - do { - /* 暂不开中断(否则中断处理流程切栈代码需要修改) */ - OsTickDispatcher(); - TICK_NO_RESPOND_CNT--; - } while (TICK_NO_RESPOND_CNT > 0); - - UNI_FLAG &= ~OS_FLG_TICK_ACTIVE; -} + rc = strncpy_s(buf, len, msg[GetWinLanguage()], len); + if (rc != EOK) { + return false; + } + return true; +} \ No newline at end of file diff --git a/src/tools/hispark_trace/hispark/boot/source/util.h b/src/tools/hispark_trace/hispark/boot/source/util.h new file mode 100644 index 0000000000000000000000000000000000000000..a6534032d531c675249b3648f7c9e095f46a4c44 --- /dev/null +++ b/src/tools/hispark_trace/hispark/boot/source/util.h @@ -0,0 +1,37 @@ +/** + * @copyright Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file util.h + * @author MCU Driver Team + * @brief useful function + */ + +#ifndef UTIL_H +#define UTIL_H + +//! @brief Get number of elements in the array. +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/tools/hispark_trace/hispark/patchs/CA7/000-hisparktrace.patch b/src/tools/hispark_trace/hispark/patchs/CA7/000-hisparktrace.patch new file mode 100644 index 0000000000000000000000000000000000000000..78b610f3a21160e7b6ba88b794f780dac0c74fbe --- /dev/null +++ b/src/tools/hispark_trace/hispark/patchs/CA7/000-hisparktrace.patch @@ -0,0 +1,10932 @@ +diff -uNr old/CA7/source/cmsis-core/cmsis_cp15.h new/CA7/source/cmsis-core/cmsis_cp15.h +--- old/CA7/source/cmsis-core/cmsis_cp15.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/cmsis-core/cmsis_cp15.h 2023-05-25 15:09:49.000000000 +0800 +@@ -31,6 +31,12 @@ + #ifndef __CMSIS_CP15_H + #define __CMSIS_CP15_H + ++#ifdef HISPARK_TRACE ++#ifndef __STATIC_FORCEINLINE ++ #define __STATIC_FORCEINLINE static inline __attribute__((always_inline)) ++#endif ++#endif ++ + /** \brief Get ACTLR + \return Auxiliary Control register value + */ +@@ -273,7 +279,7 @@ + + #if (defined(__CORTEX_A) && (__CORTEX_A == 7U) && \ + defined(__TIM_PRESENT) && (__TIM_PRESENT == 1U)) || \ +- defined(DOXYGEN) ++ defined(DOXYGEN) || defined(HISPARK_TRACE) + + /** \brief Set CNTFRQ + +@@ -459,7 +465,9 @@ + /** \brief Set CCSIDR + \deprecated CCSIDR itself is read-only. Use __set_CSSELR to select cache level instead. + */ ++#ifndef HISPARK_TRACE + CMSIS_DEPRECATED ++#endif + __STATIC_FORCEINLINE void __set_CCSIDR(uint32_t value) + { + __set_CSSELR(value); +diff -uNr old/CA7/source/cmsis-core/cmsis_gcc.h new/CA7/source/cmsis-core/cmsis_gcc.h +--- old/CA7/source/cmsis-core/cmsis_gcc.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/cmsis-core/cmsis_gcc.h 2023-05-25 15:09:49.000000000 +0800 +@@ -301,7 +301,12 @@ + { + uint32_t result; + ++#ifdef CORE_CA7 ++ result = 0; /* Cortex-A doesn't support xpsr register */ ++#else + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); ++#endif ++ + return(result); + } + +@@ -2167,7 +2172,34 @@ + #endif /* (__ARM_FEATURE_DSP == 1) */ + /*@} end of group CMSIS_SIMD_intrinsics */ + +- ++#ifdef HISPARK_TRACE ++#define __STRINGIFY(x) #x ++#define __set_CP(coproc, opcode_1, src, CRn, CRm, opcode_2) \ ++ __ASM volatile ("MCR " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \ ++ "%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " \ ++ __STRINGIFY(opcode_2) \ ++ : : "r" (src) ) ++ ++/* C语言实现MRC指令 */ ++#define __get_CP(coproc, opcode_1, dst, CRn, CRm, opcode_2) \ ++ ({ \ ++ __ASM volatile ("MRC " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \ ++ "%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " \ ++ __STRINGIFY(opcode_2) \ ++ : "=r" (dst) ); \ ++ }) ++ ++#define __get_CP64(cp, op1, Rt, CRm) \ ++({\ ++ __ASM volatile("MRRC " __STRINGIFY(p##cp) ", " __STRINGIFY(op1) ", %Q0, %R0," __STRINGIFY(c##CRm) : "=r" (Rt) : : "memory" );\ ++}) ++ ++#define __set_CP64(cp, op1, Rt, CRm) \ ++({\ ++ __ASM volatile("MCRR "__STRINGIFY(p##cp) ", " __STRINGIFY(op1) ", %Q0, %R0, " __STRINGIFY(c##CRm) : : "r" (Rt) : "memory" );\ ++}) ++#include "cmsis_cp15.h" ++#endif + #pragma GCC diagnostic pop + + #endif /* __CMSIS_GCC_H */ +diff -uNr old/CA7/source/cmsis-core/core_ca.h new/CA7/source/cmsis-core/core_ca.h +--- old/CA7/source/cmsis-core/core_ca.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/cmsis-core/core_ca.h 2023-05-25 15:09:49.000000000 +0800 +@@ -35,6 +35,12 @@ + #ifndef __CORE_CA_H_GENERIC + #define __CORE_CA_H_GENERIC + ++#ifdef HISPARK_TRACE ++#include ++ ++#define NVIC_DisableIRQ(x) (void)0 ++#define NVIC_EnableIRQ(x) (void)0 ++#endif + + /******************************************************************************* + * CMSIS definitions +@@ -739,6 +745,13 @@ + #define L2C_310 ((L2C_310_TypeDef *)L2C_310_BASE) /*!< \brief L2C_310 register set access pointer */ + #endif + ++#ifdef HISPARK_TRACE ++__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) ++{ ++ return (0UL); /* Function successful */ ++} ++#endif ++ + #if (__GIC_PRESENT == 1U) || defined(DOXYGEN) + + /** \brief Structure type to access the Generic Interrupt Controller Distributor (GICD) +@@ -950,6 +963,7 @@ + */ + __STATIC_FORCEINLINE void __L1C_MaintainDCacheSetWay(uint32_t level, uint32_t maint) + { ++#ifndef HISPARK_TRACE + uint32_t Dummy; + uint32_t ccsidr; + uint32_t num_sets; +@@ -985,6 +999,7 @@ + } + } + __DMB(); ++#endif + } + + /** \brief Clean and Invalidate the entire data or unified cache +@@ -992,6 +1007,7 @@ + * \param [in] op 0 - invalidate, 1 - clean, otherwise - invalidate and clean + */ + __STATIC_FORCEINLINE void L1C_CleanInvalidateCache(uint32_t op) { ++#ifndef HISPARK_TRACE + uint32_t clidr; + uint32_t cache_type; + clidr = __get_CLIDR(); +@@ -1003,6 +1019,7 @@ + __L1C_MaintainDCacheSetWay(i, op); + } + } ++#endif + } + + /** \brief Clean and Invalidate the entire data or unified cache +@@ -1010,7 +1027,9 @@ + * \param [in] op 0 - invalidate, 1 - clean, otherwise - invalidate and clean + * \deprecated Use generic L1C_CleanInvalidateCache instead. + */ ++#ifndef HISPARK_TRACE + CMSIS_DEPRECATED ++#endif + __STATIC_FORCEINLINE void __L1C_CleanInvalidateCache(uint32_t op) { + L1C_CleanInvalidateCache(op); + } +@@ -1473,7 +1492,7 @@ + //Set priority + GIC_SetPriority((IRQn_Type)i, priority_field/2U); + //Set target list to CPU0 +- GIC_SetTarget((IRQn_Type)i, 1U); ++ GIC_SetTarget((IRQn_Type)i, 0xFFFFU); + } + //Enable distributor + GIC_EnableDistributor(); +@@ -2578,20 +2597,26 @@ + */ + __STATIC_INLINE void MMU_Enable(void) + { ++ #if defined(HISPARK_TRACE) ++ #else + // Set M bit 0 to enable the MMU + // Set AFE bit to enable simplified access permissions model + // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking + __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29)); + __ISB(); ++ #endif + } + + /** \brief Disable MMU + */ + __STATIC_INLINE void MMU_Disable(void) + { ++ #if defined(HISPARK_TRACE) ++ #else + // Clear M bit 0 to disable the MMU + __set_SCTLR( __get_SCTLR() & ~1); + __ISB(); ++ #endif + } + + /** \brief Invalidate entire unified TLB +@@ -2599,9 +2624,12 @@ + + __STATIC_INLINE void MMU_InvalidateTLB(void) + { ++ #if defined(HISPARK_TRACE) ++ #else + __set_TLBIALL(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new state ++ #endif + } + + +diff -uNr old/CA7/source/daplink/cmsis-dap/DAP.c new/CA7/source/daplink/cmsis-dap/DAP.c +--- old/CA7/source/daplink/cmsis-dap/DAP.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/cmsis-dap/DAP.c 2023-06-09 15:33:13.058970800 +0800 +@@ -35,7 +35,12 @@ + #include "DAP.h" + #include "info.h" + #include "dap_strings.h" +- ++#if defined(HISPARK_TRACE) ++#include "DAP_vendor_ex.h" ++#include "debug.h" ++#include "msg_queue.h" ++#include "swd_jtag_config.h" ++#endif + + #if (DAP_PACKET_SIZE < 64U) + #error "Minimum Packet Size is 64!" +@@ -56,6 +61,10 @@ + #define MAX_SWJ_CLOCK(delay_cycles) \ + ((CPU_CLOCK/2U) / (IO_PORT_WRITE_CYCLES + delay_cycles)) + ++#if defined (HISPARK_TRACE) ++#define CLOCK_DELAY(swj_clock) \ ++ (((CPU_CLOCK/2U) / swj_clock) - IO_PORT_WRITE_CYCLES) ++#endif + + DAP_Data_t DAP_Data; // DAP Data + volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag +@@ -63,6 +72,12 @@ + + static const char DAP_FW_Ver [] = DAP_FW_VER; + ++#if defined (HISPARK_TRACE) ++#if TARGET_DEVICE_FIXED ++static const char TargetDeviceVendor [] = TARGET_DEVICE_VENDOR; ++static const char TargetDeviceName [] = TARGET_DEVICE_NAME; ++#endif ++#endif + + + // Get DAP Information +@@ -87,10 +102,24 @@ + memcpy(info, DAP_FW_Ver, length); + break; + case DAP_ID_DEVICE_VENDOR: +- length = DAP_GetTargetDeviceVendorString((char *)info); ++#if defined(HISPARK_TRACE) ++#if TARGET_DEVICE_FIXED ++ length = (uint8_t)sizeof(TargetDeviceVendor); ++ memcpy(info, TargetDeviceVendor, length); ++#endif ++#else ++ length = DAP_GetTargetDeviceVendorString((char *)info); ++#endif + break; + case DAP_ID_DEVICE_NAME: ++#if defined(HISPARK_TRACE) ++#if TARGET_DEVICE_FIXED ++ length = (uint8_t)sizeof(TargetDeviceName); ++ memcpy(info, TargetDeviceName, length); ++#endif ++#else + length = DAP_GetTargetDeviceNameString((char *)info); ++#endif + break; + case DAP_ID_BOARD_VENDOR: + length = DAP_GetTargetBoardVendorString((char *)info); +@@ -253,6 +282,14 @@ + break; + } + ++#ifdef HISPARK_TRACE ++ MsgBuf msg; ++ msg.type = MSG_TYPE_DEBUG_PORT_SET; ++ msg.bufLen = sizeof(DAP_Data.debug_port); ++ memcpy(msg.buf, &DAP_Data.debug_port, sizeof(DAP_Data.debug_port)); ++ MSGQ_SendMsg(&msg); ++#endif ++ + *response = (uint8_t)port; + return ((1U << 16) | 1U); + } +@@ -418,7 +455,6 @@ + static uint32_t DAP_SWJ_Clock(const uint8_t *request, uint8_t *response) { + #if ((DAP_SWD != 0) || (DAP_JTAG != 0)) + uint32_t clock; +- uint32_t delay; + + clock = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8) | +@@ -432,6 +468,16 @@ + + DAP_Data.nominal_clock = clock; + ++#ifdef HISPARK_TRACE ++ MsgBuf msg; ++ msg.type = MSG_TYPE_CLK_CFG; ++ msg.bufLen = sizeof(clock); ++ memcpy(msg.buf, &clock, sizeof(clock)); ++ MSGQ_SendMsg(&msg); ++ ++ SwdJtagClockLevelSet(clock); ++#endif ++ + Set_DAP_Clock_Delay(clock); + + *response = DAP_OK; +@@ -1821,7 +1867,6 @@ + void DAP_Setup(void) { + + // Default settings +- DAP_Data.debug_port = 0U; + DAP_Data.nominal_clock = DAP_DEFAULT_SWJ_CLOCK; + DAP_Data.transfer.idle_cycles = 0U; + DAP_Data.transfer.retry_count = 100U; +@@ -1832,7 +1877,8 @@ + DAP_Data.swd_conf.data_phase = 0U; + #endif + #if (DAP_JTAG != 0) +- DAP_Data.jtag_dev.count = 0U; ++ DAP_Data.jtag_dev.count = 1U; ++ DAP_Data.jtag_dev.ir_length[0] = 4, /* ir length is 4 */ + #endif + + // Sets DAP_Data.fast_clock and DAP_Data.clock_delay. +diff -uNr old/CA7/source/daplink/cmsis-dap/DAP.h new/CA7/source/daplink/cmsis-dap/DAP.h +--- old/CA7/source/daplink/cmsis-dap/DAP.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/cmsis-dap/DAP.h 2023-06-09 15:33:33.462015400 +0800 +@@ -113,6 +113,17 @@ + #define ID_DAP_VendorExFirst 0xA0U + #define ID_DAP_VendorExLast 0xFEU + ++#ifdef HISPARK_TRACE ++#define ID_DAP_VENDOR_VAR_MONITOR 0xAAU ++#define ID_DAP_VENDOR_READ_VAR 0xABU ++#define ID_DAP_VENDOR_WRITE_VAR 0xACU ++#define ID_DAP_VENDOR_STOP_VARMONITOR 0xADU ++#define ID_DAP_VENDOR_PAUSE_VARMONITOR 0xAEU ++ ++#define VARMONITOR_PAUCE 0x0 ++#define VARMONITOR_RESUME 0x1 ++#endif /* #ifdef HISPARK_TRACE */ ++ + #define ID_DAP_Invalid 0xFFU + + // DAP Status Code +@@ -235,12 +246,18 @@ + + #include + #include ++#ifdef STM32MP153Dxx ++#include "stm32mp153dxx_ca7.h" ++#endif + #include "cmsis_compiler.h" + + // DAP Data structure + typedef struct { + uint8_t debug_port; // Debug Port + uint8_t fast_clock; // Fast Clock Flag ++#ifdef HISPARK_TRACE ++ uint32_t clock_level; // clock_level ++#endif /* #ifdef HISPARK_TRACE */ + uint8_t padding[2]; + uint32_t clock_delay; // Clock Delay + uint32_t nominal_clock; // Nominal requested clock frequency in Hertz. +@@ -285,6 +302,7 @@ + extern void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi); + extern void JTAG_Sequence (uint32_t info, const uint8_t *tdi, uint8_t *tdo); + extern void JTAG_IR (uint32_t ir); ++extern uint8_t JTAG_RESET (void); + extern uint32_t JTAG_ReadIDCode (void); + extern void JTAG_WriteAbort (uint32_t data); + extern uint8_t JTAG_Transfer (uint32_t request, uint32_t *data); +diff -uNr old/CA7/source/daplink/cmsis-dap/debug_cm.h new/CA7/source/daplink/cmsis-dap/debug_cm.h +--- old/CA7/source/daplink/cmsis-dap/debug_cm.h 2022-02-05 13:12:28.000000000 +0800 ++++ new/CA7/source/daplink/cmsis-dap/debug_cm.h 2023-06-09 15:46:20.991985600 +0800 +@@ -31,6 +31,11 @@ + #define SWD_REG_W (0<<1) + #define SWD_REG_ADR(a) (a & 0x0c) + ++// JTAG register access ++#define JTAG_REG_R (1<<1) ++#define JTAG_REG_W (0<<1) ++#define JTAG_REG_ADR(a) (a & 0x0c) ++ + // Abort Register definitions + #define DAPABORT 0x00000001 // DAP Abort + #define STKCMPCLR 0x00000002 // Clear STICKYCMP Flag (SW Only) +@@ -165,4 +170,14 @@ + // Data Watchpoint and Trace unit + #define DWT_PCSR 0xe000101c // DWT PC Sampling Register + ++typedef enum { ++ CONNECT_NORMAL, ++ CONNECT_UNDER_RESET, ++} JTAG_SWD_CONNECT_TYPE; ++ ++typedef enum { ++ FLASHALGO_RETURN_BOOL, ++ FLASHALGO_RETURN_POINTER ++} flash_algo_return_t; ++ + #endif +diff -uNr old/CA7/source/daplink/cmsis-dap/JTAG_DP.c new/CA7/source/daplink/cmsis-dap/JTAG_DP.c +--- old/CA7/source/daplink/cmsis-dap/JTAG_DP.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/cmsis-dap/JTAG_DP.c 2023-06-09 15:33:49.711543900 +0800 +@@ -27,7 +27,9 @@ + + #include "DAP_config.h" + #include "DAP.h" +- ++#ifdef HISPARK_TRACE ++#include "swd_jtag_config.h" ++#endif /* #ifdef HISPARK_TRACE */ + + // JTAG Macros + +@@ -36,45 +38,262 @@ + #define PIN_TMS_SET PIN_SWDIO_TMS_SET + #define PIN_TMS_CLR PIN_SWDIO_TMS_CLR + +-#define JTAG_CYCLE_TCK() \ +- PIN_TCK_CLR(); \ +- PIN_DELAY(); \ +- PIN_TCK_SET(); \ +- PIN_DELAY() +- +-#define JTAG_CYCLE_TDI(tdi) \ +- PIN_TDI_OUT(tdi); \ +- PIN_TCK_CLR(); \ +- PIN_DELAY(); \ +- PIN_TCK_SET(); \ +- PIN_DELAY() +- +-#define JTAG_CYCLE_TDO(tdo) \ +- PIN_TCK_CLR(); \ +- PIN_DELAY(); \ +- tdo = PIN_TDO_IN(); \ +- PIN_TCK_SET(); \ +- PIN_DELAY() +- +-#define JTAG_CYCLE_TDIO(tdi,tdo) \ +- PIN_TDI_OUT(tdi); \ +- PIN_TCK_CLR(); \ +- PIN_DELAY(); \ +- tdo = PIN_TDO_IN(); \ +- PIN_TCK_SET(); \ +- PIN_DELAY() ++#ifdef HISPARK_TRACE ++inline static void JTAGDP_DELAY_LEVEL_0(void) ++{ ++ __NOP(); __NOP(); ++} + +-#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) ++inline static void JTAGDP_DELAY_LEVEL_1(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP(); ++} + ++inline static void JTAGDP_DELAY_LEVEL_2(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} + +-#if (DAP_JTAG != 0) ++inline static void JTAGDP_DELAY_LEVEL_3(void) ++{ ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_4(void) ++{ ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_5(void) ++{ ++ volatile uint32_t cnt = 1; ++ while(cnt) { ++ cnt--; ++ } ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_6(void) ++{ ++ volatile uint32_t cnt = 2; ++ while(cnt) { ++ cnt--; ++ } ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_7(void) ++{ ++ volatile uint32_t cnt = 3; ++ while(cnt) { ++ cnt--; ++ } ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_8(void) ++{ ++ volatile uint32_t cnt = 5; ++ while(cnt) { ++ cnt--; ++ } ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_9(void) ++{ ++ volatile uint32_t cnt = 15; ++ while(cnt) { ++ cnt--; ++ } ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_LOW(uint32_t delay) ++{ ++ volatile uint32_t cnt = delay; ++ while(cnt) { ++ cnt--; ++ } ++} ++#endif /* #ifdef HISPARK_TRACE */ + ++#define JTAG_CYCLE_TCK() \ ++ PIN_TCK_CLR(); \ ++ PIN_DELAY(); \ ++ PIN_TCK_SET(); \ ++ PIN_DELAY() ++ ++#define JTAG_CYCLE_TDI(tdi) \ ++ PIN_TDI_OUT(tdi); \ ++ PIN_TCK_CLR(); \ ++ PIN_DELAY(); \ ++ PIN_TCK_SET(); \ ++ PIN_DELAY() ++ ++#define JTAG_CYCLE_TDO(tdo) \ ++ PIN_TCK_CLR(); \ ++ PIN_DELAY(); \ ++ tdo = PIN_TDO_IN(); \ ++ PIN_TCK_SET(); \ ++ PIN_DELAY() ++ ++#define JTAG_CYCLE_TDIO(tdi,tdo) \ ++ PIN_TDI_OUT(tdi); \ ++ PIN_TCK_CLR(); \ ++ PIN_DELAY(); \ ++ tdo = PIN_TDO_IN(); \ ++ PIN_TCK_SET(); \ ++ PIN_DELAY() ++ ++#ifdef HISPARK_TRACE ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_6() ++#else ++#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) ++#endif /* #ifdef HISPARK_TRACE */ ++ ++#if (DAP_JTAG != 0) + + // Generate JTAG Sequence + // info: sequence information + // tdi: pointer to TDI generated data + // tdo: pointer to TDO captured data + // return: none ++#ifdef HISPARK_TRACE ++#define JTAG_SequenceFunction(speed) \ ++static void JTAG_Sequence_##speed (uint32_t info, const uint8_t *tdi, uint8_t *tdo) \ ++{ \ ++ uint32_t i_val; \ ++ uint32_t o_val; \ ++ uint32_t bit; \ ++ uint32_t n, k; \ ++ \ ++ n = info & JTAG_SEQUENCE_TCK; \ ++ if (n == 0U) { \ ++ n = 64U; \ ++ } \ ++ \ ++ if (info & JTAG_SEQUENCE_TMS) { \ ++ PIN_TMS_SET(); \ ++ } else { \ ++ PIN_TMS_CLR(); \ ++ } \ ++ \ ++ while (n) { \ ++ i_val = *tdi++; \ ++ o_val = 0U; \ ++ for (k = 8U; k && n; k--, n--) { \ ++ JTAG_CYCLE_TDIO(i_val, bit); \ ++ i_val >>= 1; \ ++ o_val >>= 1; \ ++ o_val |= bit << 7; \ ++ } \ ++ o_val >>= k; \ ++ if (info & JTAG_SEQUENCE_TDO) { \ ++ *tdo++ = (uint8_t)o_val; \ ++ } \ ++ } \ ++} ++#else /* #ifdef HISPARK_TRACE */ + void JTAG_Sequence (uint32_t info, const uint8_t *tdi, uint8_t *tdo) { + uint32_t i_val; + uint32_t o_val; +@@ -107,151 +326,220 @@ + } + } + } +- ++#endif /* #ifdef HISPARK_TRACE */ + + // JTAG Set IR + // ir: IR value + // return: none +-#define JTAG_IR_Function(speed) /**/ \ +-static void JTAG_IR_##speed (uint32_t ir) { \ +- uint32_t n; \ +- \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \ +- JTAG_CYCLE_TCK(); /* Select-IR-Scan */ \ +- PIN_TMS_CLR(); \ +- JTAG_CYCLE_TCK(); /* Capture-IR */ \ +- JTAG_CYCLE_TCK(); /* Shift-IR */ \ +- \ +- PIN_TDI_OUT(1U); \ +- for (n = DAP_Data.jtag_dev.ir_before[DAP_Data.jtag_dev.index]; n; n--) { \ +- JTAG_CYCLE_TCK(); /* Bypass before data */ \ +- } \ +- for (n = DAP_Data.jtag_dev.ir_length[DAP_Data.jtag_dev.index] - 1U; n; n--) { \ +- JTAG_CYCLE_TDI(ir); /* Set IR bits (except last) */ \ +- ir >>= 1; \ +- } \ +- n = DAP_Data.jtag_dev.ir_after[DAP_Data.jtag_dev.index]; \ +- if (n) { \ +- JTAG_CYCLE_TDI(ir); /* Set last IR bit */ \ +- PIN_TDI_OUT(1U); \ +- for (--n; n; n--) { \ +- JTAG_CYCLE_TCK(); /* Bypass after data */ \ +- } \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Bypass & Exit1-IR */ \ +- } else { \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TDI(ir); /* Set last IR bit & Exit1-IR */ \ +- } \ +- \ +- JTAG_CYCLE_TCK(); /* Update-IR */ \ +- PIN_TMS_CLR(); \ +- JTAG_CYCLE_TCK(); /* Idle */ \ +- PIN_TDI_OUT(1U); \ ++#define JTAG_IR_Function(speed) \ ++static void JTAG_IR_##speed (uint32_t ir) \ ++{ \ ++ uint32_t n; \ ++ \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \ ++ JTAG_CYCLE_TCK(); /* Select-IR-Scan */ \ ++ PIN_TMS_CLR(); \ ++ JTAG_CYCLE_TCK(); /* Capture-IR */ \ ++ JTAG_CYCLE_TCK(); /* Shift-IR */ \ ++ \ ++ PIN_TDI_OUT(1U); \ ++ for (n = DAP_Data.jtag_dev.ir_before[DAP_Data.jtag_dev.index]; n; n--) { \ ++ JTAG_CYCLE_TCK(); /* Bypass before data */ \ ++ } \ ++ for (n = DAP_Data.jtag_dev.ir_length[DAP_Data.jtag_dev.index] - 1U; n; n--) { \ ++ JTAG_CYCLE_TDI(ir); /* Set IR bits (except last) */ \ ++ ir >>= 1; \ ++ } \ ++ n = DAP_Data.jtag_dev.ir_after[DAP_Data.jtag_dev.index]; \ ++ if (n) { \ ++ JTAG_CYCLE_TDI(ir); /* Set last IR bit */ \ ++ PIN_TDI_OUT(1U); \ ++ for (--n; n; n--) { \ ++ JTAG_CYCLE_TCK(); /* Bypass after data */ \ ++ } \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Bypass & Exit1-IR */ \ ++ } else { \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TDI(ir); /* Set last IR bit & Exit1-IR */ \ ++ } \ ++ \ ++ JTAG_CYCLE_TCK(); /* Update-IR */ \ ++ PIN_TMS_CLR(); \ ++ JTAG_CYCLE_TCK(); /* Idle */ \ ++ PIN_TDI_OUT(1U); \ + } + +- + // JTAG Transfer I/O + // request: A[3:2] RnW APnDP + // data: DATA[31:0] + // return: ACK[2:0] +-#define JTAG_TransferFunction(speed) /**/ \ +-static uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) { \ +- uint32_t ack; \ +- uint32_t bit; \ +- uint32_t val; \ +- uint32_t n; \ +- \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \ +- PIN_TMS_CLR(); \ +- JTAG_CYCLE_TCK(); /* Capture-DR */ \ +- JTAG_CYCLE_TCK(); /* Shift-DR */ \ +- \ +- for (n = DAP_Data.jtag_dev.index; n; n--) { \ +- JTAG_CYCLE_TCK(); /* Bypass before data */ \ +- } \ +- \ +- JTAG_CYCLE_TDIO(request >> 1, bit); /* Set RnW, Get ACK.0 */ \ +- ack = bit << 1; \ +- JTAG_CYCLE_TDIO(request >> 2, bit); /* Set A2, Get ACK.1 */ \ +- ack |= bit << 0; \ +- JTAG_CYCLE_TDIO(request >> 3, bit); /* Set A3, Get ACK.2 */ \ +- ack |= bit << 2; \ +- \ +- if (ack != DAP_TRANSFER_OK) { \ +- /* Exit on error */ \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Exit1-DR */ \ +- goto exit; \ +- } \ +- \ +- if (request & DAP_TRANSFER_RnW) { \ +- /* Read Transfer */ \ +- val = 0U; \ +- for (n = 31U; n; n--) { \ +- JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ \ +- val |= bit << 31; \ +- val >>= 1; \ +- } \ +- n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \ +- if (n) { \ +- JTAG_CYCLE_TDO(bit); /* Get D31 */ \ +- for (--n; n; n--) { \ +- JTAG_CYCLE_TCK(); /* Bypass after data */ \ +- } \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \ +- } else { \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ \ +- } \ +- val |= bit << 31; \ +- if (data) { *data = val; } \ +- } else { \ +- /* Write Transfer */ \ +- val = *data; \ +- for (n = 31U; n; n--) { \ +- JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \ +- val >>= 1; \ +- } \ +- n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \ +- if (n) { \ +- JTAG_CYCLE_TDI(val); /* Set D31 */ \ +- for (--n; n; n--) { \ +- JTAG_CYCLE_TCK(); /* Bypass after data */ \ +- } \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \ +- } else { \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TDI(val); /* Set D31 & Exit1-DR */ \ +- } \ +- } \ +- \ +-exit: \ +- JTAG_CYCLE_TCK(); /* Update-DR */ \ +- PIN_TMS_CLR(); \ +- JTAG_CYCLE_TCK(); /* Idle */ \ +- PIN_TDI_OUT(1U); \ +- \ +- /* Capture Timestamp */ \ +- if (request & DAP_TRANSFER_TIMESTAMP) { \ +- DAP_Data.timestamp = TIMESTAMP_GET(); \ +- } \ +- \ +- /* Idle cycles */ \ +- n = DAP_Data.transfer.idle_cycles; \ +- while (n--) { \ +- JTAG_CYCLE_TCK(); /* Idle */ \ +- } \ +- \ +- return ((uint8_t)ack); \ ++#define JTAG_TransferFunction(speed) \ ++static uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) \ ++{ \ ++ uint32_t ack; \ ++ uint32_t bit; \ ++ uint32_t val; \ ++ uint32_t n; \ ++ \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \ ++ PIN_TMS_CLR(); \ ++ JTAG_CYCLE_TCK(); /* Capture-DR */ \ ++ JTAG_CYCLE_TCK(); /* Shift-DR */ \ ++ \ ++ for (n = DAP_Data.jtag_dev.index; n; n--) { \ ++ JTAG_CYCLE_TCK(); /* Bypass before data */ \ ++ } \ ++ \ ++ JTAG_CYCLE_TDIO(request >> 1, bit); /* Set RnW, Get ACK.0 */ \ ++ ack = bit << 1; \ ++ JTAG_CYCLE_TDIO(request >> 2, bit); /* Set A2, Get ACK.1 */ \ ++ ack |= bit << 0; \ ++ JTAG_CYCLE_TDIO(request >> 3, bit); /* Set A3, Get ACK.2 */ \ ++ ack |= bit << 2; \ ++ \ ++ if (ack != DAP_TRANSFER_OK) { \ ++ /* Exit on error */ \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Exit1-DR */ \ ++ goto exit; \ ++ } \ ++ \ ++ if (request & DAP_TRANSFER_RnW) { \ ++ /* Read Transfer */ \ ++ val = 0U; \ ++ for (n = 31U; n; n--) { \ ++ JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ \ ++ val |= bit << 31; \ ++ val >>= 1; \ ++ } \ ++ n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \ ++ if (n) { \ ++ JTAG_CYCLE_TDO(bit); /* Get D31 */ \ ++ for (--n; n; n--) { \ ++ JTAG_CYCLE_TCK(); /* Bypass after data */ \ ++ } \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \ ++ } else { \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ \ ++ } \ ++ val |= bit << 31; \ ++ if (data) { \ ++ *data = val; \ ++ } \ ++ } else { \ ++ /* Write Transfer */ \ ++ val = *data; \ ++ for (n = 31U; n; n--) { \ ++ JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \ ++ val >>= 1; \ ++ } \ ++ n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \ ++ if (n) { \ ++ JTAG_CYCLE_TDI(val); /* Set D31 */ \ ++ for (--n; n; n--) { \ ++ JTAG_CYCLE_TCK(); /* Bypass after data */ \ ++ } \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \ ++ } else { \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TDI(val); /* Set D31 & Exit1-DR */ \ ++ } \ ++ } \ ++ \ ++exit: \ ++ JTAG_CYCLE_TCK(); /* Update-DR */ \ ++ PIN_TMS_CLR(); \ ++ JTAG_CYCLE_TCK(); /* Idle */ \ ++ PIN_TDI_OUT(1U); \ ++ \ ++ /* Capture Timestamp */ \ ++ if (request & DAP_TRANSFER_TIMESTAMP) { \ ++ DAP_Data.timestamp = TIMESTAMP_GET(); \ ++ } \ ++ \ ++ /* Idle cycles */ \ ++ n = DAP_Data.transfer.idle_cycles; \ ++ while (n--) { \ ++ JTAG_CYCLE_TCK(); /* Idle */ \ ++ } \ ++ \ ++ return ((uint8_t)ack); \ + } + ++#ifdef HISPARK_TRACE ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_0() ++JTAG_SequenceFunction(Level0) ++JTAG_IR_Function(Level0) ++JTAG_TransferFunction(Level0) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_1() ++JTAG_SequenceFunction(Level1) ++JTAG_IR_Function(Level1) ++JTAG_TransferFunction(Level1) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_2() ++JTAG_SequenceFunction(Level2) ++JTAG_IR_Function(Level2) ++JTAG_TransferFunction(Level2) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_3() ++JTAG_SequenceFunction(Level3) ++JTAG_IR_Function(Level3) ++JTAG_TransferFunction(Level3) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_4() ++JTAG_SequenceFunction(Level4) ++JTAG_IR_Function(Level4) ++JTAG_TransferFunction(Level4) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_5() ++JTAG_SequenceFunction(Level5) ++JTAG_IR_Function(Level5) ++JTAG_TransferFunction(Level5) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_6() ++JTAG_SequenceFunction(Level6) ++JTAG_IR_Function(Level6) ++JTAG_TransferFunction(Level6) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_7() ++JTAG_SequenceFunction(Level7) ++JTAG_IR_Function(Level7) ++JTAG_TransferFunction(Level7) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_8() ++JTAG_SequenceFunction(Level8) ++JTAG_IR_Function(Level8) ++JTAG_TransferFunction(Level8) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_9() ++JTAG_SequenceFunction(Level9) ++JTAG_IR_Function(Level9) ++JTAG_TransferFunction(Level9) + + #undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_LOW(DAP_Data.clock_delay) ++JTAG_SequenceFunction(LevelLow) ++JTAG_IR_Function(LevelLow) ++JTAG_TransferFunction(LevelLow) ++#else /* #ifdef HISPARK_TRACE */ ++#undef PIN_DELAY + #define PIN_DELAY() PIN_DELAY_FAST() + JTAG_IR_Function(Fast) + JTAG_TransferFunction(Fast) +@@ -260,40 +548,41 @@ + #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) + JTAG_IR_Function(Slow) + JTAG_TransferFunction(Slow) +- ++#endif /* #ifdef HISPARK_TRACE */ + + // JTAG Read IDCODE register + // return: value read +-uint32_t JTAG_ReadIDCode (void) { +- uint32_t bit; +- uint32_t val; +- uint32_t n; ++uint32_t JTAG_ReadIDCode (void) ++{ ++ uint32_t bit; ++ uint32_t val; ++ uint32_t n; + +- PIN_TMS_SET(); +- JTAG_CYCLE_TCK(); /* Select-DR-Scan */ +- PIN_TMS_CLR(); +- JTAG_CYCLE_TCK(); /* Capture-DR */ +- JTAG_CYCLE_TCK(); /* Shift-DR */ ++ PIN_TMS_SET(); ++ JTAG_CYCLE_TCK(); /* Select-DR-Scan */ ++ PIN_TMS_CLR(); ++ JTAG_CYCLE_TCK(); /* Capture-DR */ ++ JTAG_CYCLE_TCK(); /* Shift-DR */ + +- for (n = DAP_Data.jtag_dev.index; n; n--) { +- JTAG_CYCLE_TCK(); /* Bypass before data */ +- } ++ for (n = DAP_Data.jtag_dev.index; n; n--) { ++ JTAG_CYCLE_TCK(); /* Bypass before data */ ++ } + +- val = 0U; +- for (n = 31U; n; n--) { +- JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ +- val |= bit << 31; +- val >>= 1; +- } +- PIN_TMS_SET(); +- JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ +- val |= bit << 31; +- +- JTAG_CYCLE_TCK(); /* Update-DR */ +- PIN_TMS_CLR(); +- JTAG_CYCLE_TCK(); /* Idle */ ++ val = 0U; ++ for (n = 31U; n; n--) { ++ JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ ++ val |= bit << 31; ++ val >>= 1; ++ } ++ PIN_TMS_SET(); ++ JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ ++ val |= bit << 31; + +- return (val); ++ JTAG_CYCLE_TCK(); /* Update-DR */ ++ PIN_TMS_CLR(); ++ JTAG_CYCLE_TCK(); /* Idle */ ++ ++ return (val); + } + + +@@ -301,70 +590,199 @@ + // data: value to write + // return: none + void JTAG_WriteAbort (uint32_t data) { +- uint32_t n; ++ uint32_t n; + +- PIN_TMS_SET(); +- JTAG_CYCLE_TCK(); /* Select-DR-Scan */ +- PIN_TMS_CLR(); +- JTAG_CYCLE_TCK(); /* Capture-DR */ +- JTAG_CYCLE_TCK(); /* Shift-DR */ ++ PIN_TMS_SET(); ++ JTAG_CYCLE_TCK(); /* Select-DR-Scan */ ++ PIN_TMS_CLR(); ++ JTAG_CYCLE_TCK(); /* Capture-DR */ ++ JTAG_CYCLE_TCK(); /* Shift-DR */ + +- for (n = DAP_Data.jtag_dev.index; n; n--) { +- JTAG_CYCLE_TCK(); /* Bypass before data */ +- } ++ for (n = DAP_Data.jtag_dev.index; n; n--) { ++ JTAG_CYCLE_TCK(); /* Bypass before data */ ++ } + +- PIN_TDI_OUT(0U); +- JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */ +- JTAG_CYCLE_TCK(); /* Set A2=0 */ +- JTAG_CYCLE_TCK(); /* Set A3=0 */ +- +- for (n = 31U; n; n--) { +- JTAG_CYCLE_TDI(data); /* Set D0..D30 */ +- data >>= 1; +- } +- n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; +- if (n) { +- JTAG_CYCLE_TDI(data); /* Set D31 */ +- for (--n; n; n--) { +- JTAG_CYCLE_TCK(); /* Bypass after data */ ++ PIN_TDI_OUT(0U); ++ JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */ ++ JTAG_CYCLE_TCK(); /* Set A2=0 */ ++ JTAG_CYCLE_TCK(); /* Set A3=0 */ ++ ++ for (n = 31U; n; n--) { ++ JTAG_CYCLE_TDI(data); /* Set D0..D30 */ ++ data >>= 1; ++ } ++ n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; ++ if (n) { ++ JTAG_CYCLE_TDI(data); /* Set D31 */ ++ for (--n; n; n--) { ++ JTAG_CYCLE_TCK(); /* Bypass after data */ ++ } ++ PIN_TMS_SET(); ++ JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ ++ } else { ++ PIN_TMS_SET(); ++ JTAG_CYCLE_TDI(data); /* Set D31 & Exit1-DR */ + } +- PIN_TMS_SET(); +- JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ +- } else { +- PIN_TMS_SET(); +- JTAG_CYCLE_TDI(data); /* Set D31 & Exit1-DR */ +- } + +- JTAG_CYCLE_TCK(); /* Update-DR */ +- PIN_TMS_CLR(); +- JTAG_CYCLE_TCK(); /* Idle */ +- PIN_TDI_OUT(1U); ++ JTAG_CYCLE_TCK(); /* Update-DR */ ++ PIN_TMS_CLR(); ++ JTAG_CYCLE_TCK(); /* Idle */ ++ PIN_TDI_OUT(1U); + } + ++#ifdef HISPARK_TRACE ++// Generate JTAG Sequence ++// info: sequence information ++// tdi: pointer to TDI generated data ++// tdo: pointer to TDO captured data ++// return: none ++void JTAG_Sequence(uint32_t info, const uint8_t *tdi, uint8_t *tdo) ++{ ++ switch (DAP_Data.clock_level) { ++ case SWD_JTAG_CLOCK_LEVEL_0: ++ JTAG_Sequence_Level0(info, tdi, tdo); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_1: ++ JTAG_Sequence_Level1(info, tdi, tdo); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_2: ++ JTAG_Sequence_Level2(info, tdi, tdo); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_3: ++ JTAG_Sequence_Level3(info, tdi, tdo); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_4: ++ JTAG_Sequence_Level4(info, tdi, tdo); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_5: ++ JTAG_Sequence_Level5(info, tdi, tdo); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_6: ++ JTAG_Sequence_Level6(info, tdi, tdo); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_7: ++ JTAG_Sequence_Level7(info, tdi, tdo); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_8: ++ JTAG_Sequence_Level8(info, tdi, tdo); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_9: ++ JTAG_Sequence_Level9(info, tdi, tdo); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_LOW: ++ JTAG_Sequence_LevelLow(info, tdi, tdo); ++ break; ++ default: ++ JTAG_Sequence_Level5(info, tdi, tdo); ++ break; ++ } ++} ++#endif /* #ifdef HISPARK_TRACE */ ++ ++uint8_t JTAG_RESET (void) ++{ ++ PIN_TMS_SET(); ++ for (int i = 0; i < 8; i++) { ++ JTAG_CYCLE_TCK(); ++ } ++ PIN_TMS_CLR(); ++ JTAG_CYCLE_TCK(); ++ PIN_TDI_OUT(1U); ++ return 0; ++} + + // JTAG Set IR + // ir: IR value + // return: none +-void JTAG_IR (uint32_t ir) { +- if (DAP_Data.fast_clock) { +- JTAG_IR_Fast(ir); +- } else { +- JTAG_IR_Slow(ir); +- } ++void JTAG_IR (uint32_t ir) ++{ ++#ifdef HISPARK_TRACE ++ switch (DAP_Data.clock_level) { ++ case SWD_JTAG_CLOCK_LEVEL_0: ++ JTAG_IR_Level0(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_1: ++ JTAG_IR_Level1(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_2: ++ JTAG_IR_Level2(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_3: ++ JTAG_IR_Level3(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_4: ++ JTAG_IR_Level4(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_5: ++ JTAG_IR_Level5(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_6: ++ JTAG_IR_Level6(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_7: ++ JTAG_IR_Level7(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_8: ++ JTAG_IR_Level8(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_9: ++ JTAG_IR_Level9(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_LOW: ++ JTAG_IR_LevelLow(ir); ++ break; ++ default: ++ JTAG_IR_Level5(ir); ++ break; ++ } ++#else /* #ifdef HISPARK_TRACE */ ++ if (DAP_Data.fast_clock) { ++ JTAG_IR_Fast(ir); ++ } else { ++ JTAG_IR_Slow(ir); ++ } ++#endif /* #ifdef HISPARK_TRACE */ + } + +- + // JTAG Transfer I/O + // request: A[3:2] RnW APnDP + // data: DATA[31:0] + // return: ACK[2:0] +-uint8_t JTAG_Transfer(uint32_t request, uint32_t *data) { +- if (DAP_Data.fast_clock) { +- return JTAG_TransferFast(request, data); +- } else { +- return JTAG_TransferSlow(request, data); +- } ++uint8_t JTAG_Transfer(uint32_t request, uint32_t *data) ++{ ++#ifdef HISPARK_TRACE ++ switch (DAP_Data.clock_level) { ++ case SWD_JTAG_CLOCK_LEVEL_0: ++ return JTAG_TransferLevel0(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_1: ++ return JTAG_TransferLevel1(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_2: ++ return JTAG_TransferLevel2(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_3: ++ return JTAG_TransferLevel3(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_4: ++ return JTAG_TransferLevel4(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_5: ++ return JTAG_TransferLevel5(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_6: ++ return JTAG_TransferLevel6(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_7: ++ return JTAG_TransferLevel7(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_8: ++ return JTAG_TransferLevel8(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_9: ++ return JTAG_TransferLevel9(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_LOW: ++ return JTAG_TransferLevelLow(request, data); ++ default: ++ return JTAG_TransferLevel5(request, data); ++ } ++#else /* #ifdef HISPARK_TRACE */ ++ if (DAP_Data.fast_clock) { ++ return JTAG_TransferFast(request, data); ++ } else { ++ return JTAG_TransferSlow(request, data); ++ } ++#endif /* #ifdef HISPARK_TRACE */ + } +- +- +-#endif /* (DAP_JTAG != 0) */ ++#endif /* (DAP_JTAG != 0) */ +\ No newline at end of file +diff -uNr old/CA7/source/daplink/cmsis-dap/SW_DP.c new/CA7/source/daplink/cmsis-dap/SW_DP.c +--- old/CA7/source/daplink/cmsis-dap/SW_DP.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/cmsis-dap/SW_DP.c 2023-05-25 15:09:49.000000000 +0800 +@@ -27,6 +27,9 @@ + + #include "DAP_config.h" + #include "DAP.h" ++#ifdef HISPARK_TRACE ++#include "swd_jtag_config.h" ++#endif /* #ifdef HISPARK_TRACE */ + + #if defined(__CC_ARM) + #pragma push +@@ -38,16 +41,216 @@ + #endif + + // SW Macros +- + #define PIN_SWCLK_SET PIN_SWCLK_TCK_SET + #define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR + +-#define SW_CLOCK_CYCLE() \ +- PIN_SWCLK_CLR(); \ +- PIN_DELAY(); \ +- PIN_SWCLK_SET(); \ +- PIN_DELAY() ++#ifdef HISPARK_TRACE ++inline static void SWDP_DELAY_LEVEL_0(void) ++{ ++ __NOP(); __NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_1(void) ++{ ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_2(void) ++{ ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_3(void) ++{ ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_4(void) ++{ ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_5(void) ++{ ++ volatile uint32_t cnt = 1; ++ while(cnt) { ++ cnt--; ++ } ++} ++ ++inline static void SWDP_DELAY_LEVEL_6(void) ++{ ++ volatile uint32_t cnt = 2; ++ while(cnt) { ++ cnt--; ++ } ++} ++ ++inline static void SWDP_DELAY_LEVEL_7(void) ++{ ++ volatile uint32_t cnt = 3; ++ while(cnt) { ++ cnt--; ++ } ++} ++ ++inline static void SWDP_DELAY_LEVEL_8(void) ++{ ++ volatile uint32_t cnt = 5; ++ while(cnt) { ++ cnt--; ++ } ++} ++ ++inline static void SWDP_DELAY_LEVEL_9(void) ++{ ++ volatile uint32_t cnt = 11; ++ while(cnt) { ++ cnt--; ++ }; ++} ++ ++inline static void SWDP_DELAY_LEVEL_LOW(uint32_t delay) ++{ ++ volatile uint32_t cnt = 15; ++ while(cnt) { ++ cnt--; ++ } ++} ++#endif /* #ifdef HISPARK_TRACE */ ++ ++#define SW_CLOCK_CYCLE() \ ++ PIN_SWCLK_CLR(); \ ++ \ ++ PIN_DELAY(); \ ++ PIN_SWCLK_SET(); \ ++ \ ++ PIN_DELAY() ++ ++#ifdef HISPARK_TRACE ++#define SW_WRITE_BIT(bit) \ ++ PIN_SWDIO_OUT(bit); \ ++ PIN_SWCLK_CLR(); \ ++ __NOP(); \ ++ PIN_DELAY(); \ ++ PIN_SWCLK_SET(); \ ++ __NOP(); \ ++ PIN_DELAY() ++ ++#define SW_READ_BIT(bit) \ ++ PIN_SWCLK_CLR(); \ ++ \ ++ PIN_DELAY(); \ ++ bit = PIN_SWDIO_IN(); \ ++ PIN_SWCLK_SET(); \ ++ PIN_DELAY() + ++#define PIN_DELAY() SWDP_DELAY_LEVEL_6() ++#else /* #ifdef HISPARK_TRACE */ + #define SW_WRITE_BIT(bit) \ + PIN_SWDIO_OUT(bit); \ + PIN_SWCLK_CLR(); \ +@@ -63,6 +266,7 @@ + PIN_DELAY() + + #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) ++#endif /* #ifdef HISPARK_TRACE */ + + + // Generate SWJ Sequence +@@ -70,26 +274,27 @@ + // data: pointer to sequence bit data + // return: none + #if ((DAP_SWD != 0) || (DAP_JTAG != 0)) +-__WEAK void SWJ_Sequence (uint32_t count, const uint8_t *data) { +- uint32_t val; +- uint32_t n; +- +- val = 0U; +- n = 0U; +- while (count--) { +- if (n == 0U) { +- val = *data++; +- n = 8U; +- } +- if (val & 1U) { +- PIN_SWDIO_TMS_SET(); +- } else { +- PIN_SWDIO_TMS_CLR(); ++__WEAK void SWJ_Sequence (uint32_t count, const uint8_t *data) ++{ ++ uint32_t val; ++ uint32_t n; ++ ++ val = 0U; ++ n = 0U; ++ while (count--) { ++ if (n == 0U) { ++ val = *data++; ++ n = 8U; ++ } ++ if (val & 1U) { ++ PIN_SWDIO_TMS_SET(); ++ } else { ++ PIN_SWDIO_TMS_CLR(); ++ } ++ SW_CLOCK_CYCLE(); ++ val >>= 1; ++ n--; + } +- SW_CLOCK_CYCLE(); +- val >>= 1; +- n--; +- } + } + #endif + +@@ -100,47 +305,181 @@ + // swdi: pointer to SWDIO captured data + // return: none + #if (DAP_SWD != 0) +-__WEAK void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) { +- uint32_t val; +- uint32_t bit; +- uint32_t n, k; +- +- n = info & SWD_SEQUENCE_CLK; +- if (n == 0U) { +- n = 64U; +- } ++__WEAK void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) ++{ ++ uint32_t val; ++ uint32_t bit; ++ uint32_t n, k; + +- if (info & SWD_SEQUENCE_DIN) { +- while (n) { +- val = 0U; +- for (k = 8U; k && n; k--, n--) { +- SW_READ_BIT(bit); +- val >>= 1; +- val |= bit << 7; +- } +- val >>= k; +- *swdi++ = (uint8_t)val; ++ n = info & SWD_SEQUENCE_CLK; ++ if (n == 0U) { ++ n = 64U; + } +- } else { +- while (n) { +- val = *swdo++; +- for (k = 8U; k && n; k--, n--) { +- SW_WRITE_BIT(val); +- val >>= 1; +- } ++ ++ if (info & SWD_SEQUENCE_DIN) { ++ while (n) { ++ val = 0U; ++ for (k = 8U; k && n; k--, n--) { ++ SW_READ_BIT(bit); ++ val >>= 1; ++ val |= bit << 7; ++ } ++ val >>= k; ++ *swdi++ = (uint8_t)val; ++ } ++ } else { ++ while (n) { ++ val = *swdo++; ++ for (k = 8U; k && n; k--, n--) { ++ SW_WRITE_BIT(val); ++ val >>= 1; ++ } ++ } + } +- } + } + #endif + +- + #if (DAP_SWD != 0) + +- + // SWD Transfer I/O + // request: A[3:2] RnW APnDP + // data: DATA[31:0] + // return: ACK[2:0] ++#ifdef HISPARK_TRACE ++#define SWD_TransferFunction(speed) \ ++static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) \ ++{ \ ++ uint32_t ack; \ ++ uint32_t bit; \ ++ uint32_t val; \ ++ uint32_t parity; \ ++ \ ++ uint32_t n; \ ++ PIN_SWDIO_OUT_ENABLE(); \ ++ \ ++ /* Packet Request */ \ ++ parity = 0U; \ ++ SW_WRITE_BIT(1U); /* Start Bit */ \ ++ bit = request >> 0; \ ++ SW_WRITE_BIT(bit); /* APnDP Bit */ \ ++ parity += bit; \ ++ bit = request >> 1; \ ++ SW_WRITE_BIT(bit); /* RnW Bit */ \ ++ parity += bit; \ ++ bit = request >> 2; \ ++ SW_WRITE_BIT(bit); /* A2 Bit */ \ ++ parity += bit; \ ++ bit = request >> 3; \ ++ SW_WRITE_BIT(bit); /* A3 Bit */ \ ++ parity += bit; \ ++ SW_WRITE_BIT(parity); /* Parity Bit */ \ ++ __NOP();__NOP(); \ ++ SW_WRITE_BIT(0U); /* Stop Bit */ \ ++ __NOP();__NOP(); \ ++ SW_WRITE_BIT(1U); /* Park Bit */ \ ++ __NOP();__NOP(); \ ++ \ ++ PIN_SWDIO_OUT_DISABLE(); \ ++ /* Turnaround */ \ ++ for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ ++ SW_CLOCK_CYCLE(); \ ++ } \ ++ \ ++ /* Acknowledge response */ \ ++ SW_READ_BIT(bit); \ ++ __NOP(); \ ++ ack = bit << 0; \ ++ SW_READ_BIT(bit); \ ++ ack |= bit << 1; \ ++ SW_READ_BIT(bit); \ ++ ack |= bit << 2; \ ++ if (ack == DAP_TRANSFER_OK) { /* OK response */ \ ++ /* Data transfer */ \ ++ if (request & DAP_TRANSFER_RnW) { \ ++ /* Read data */ \ ++ val = 0U; \ ++ parity = 0U; \ ++ for (n = 32U; n; n--) { \ ++ SW_READ_BIT(bit); /* Read RDATA[0:31] */ \ ++ parity += bit; \ ++ val >>= 1; \ ++ val |= bit << 31; \ ++ } \ ++ SW_READ_BIT(bit); /* Read Parity */ \ ++ __NOP();__NOP();__NOP(); \ ++ if ((parity ^ bit) & 1U) { \ ++ ack = DAP_TRANSFER_ERROR; \ ++ } \ ++ if (data) { *data = val; } \ ++ /* Turnaround */ \ ++ for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ ++ SW_CLOCK_CYCLE(); \ ++ __NOP();__NOP(); \ ++ } \ ++ PIN_SWDIO_OUT_ENABLE(); \ ++ } else { \ ++ /* Turnaround */ \ ++ for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ ++ SW_CLOCK_CYCLE(); \ ++ __NOP();__NOP(); \ ++ } \ ++ PIN_SWDIO_OUT_ENABLE(); \ ++ /* Write data */ \ ++ val = *data; \ ++ parity = 0U; \ ++ for (n = 32U; n; n--) { \ ++ SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \ ++ parity += val; \ ++ val >>= 1; \ ++ } \ ++ SW_WRITE_BIT(parity); /* Write Parity Bit */ \ ++ } \ ++ /* Capture Timestamp */ \ ++ if (request & DAP_TRANSFER_TIMESTAMP) { \ ++ DAP_Data.timestamp = TIMESTAMP_GET(); \ ++ } \ ++ /* Idle cycles */ \ ++ n = DAP_Data.transfer.idle_cycles; \ ++ if (n) { \ ++ PIN_SWDIO_OUT(0U); \ ++ for (; n; n--) { \ ++ SW_CLOCK_CYCLE(); \ ++ } \ ++ } \ ++ PIN_SWDIO_OUT(1U); \ ++ return ((uint8_t)ack); \ ++ } \ ++ \ ++ if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \ ++ /* WAIT or FAULT response */ \ ++ if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \ ++ for (n = 32U+1U; n; n--) { \ ++ SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \ ++ } \ ++ } \ ++ /* Turnaround */ \ ++ for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ ++ SW_CLOCK_CYCLE(); \ ++ } \ ++ PIN_SWDIO_OUT_ENABLE(); \ ++ if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \ ++ PIN_SWDIO_OUT(0U); \ ++ for (n = 32U+1U; n; n--) { \ ++ SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \ ++ } \ ++ } \ ++ PIN_SWDIO_OUT(1U); \ ++ return ((uint8_t)ack); \ ++ } \ ++ /* Protocol error */ \ ++ for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \ ++ SW_CLOCK_CYCLE(); /* Back off data phase */ \ ++ } \ ++ PIN_SWDIO_OUT_ENABLE(); \ ++ PIN_SWDIO_OUT(1U); \ ++ return ((uint8_t)ack); \ ++} ++#else /* #ifdef HISPARK_TRACE */ + #define SWD_TransferFunction(speed) /**/ \ + static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \ + uint32_t ack; \ +@@ -267,7 +606,54 @@ + PIN_SWDIO_OUT(1U); \ + return ((uint8_t)ack); \ + } ++#endif /* #ifdef HISPARK_TRACE */ ++ ++#ifdef HISPARK_TRACE ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_0() ++SWD_TransferFunction(Level0) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_1() ++SWD_TransferFunction(Level1) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_2() ++SWD_TransferFunction(Level2) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_3() ++SWD_TransferFunction(Level3) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_4() ++SWD_TransferFunction(Level4) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_5() ++SWD_TransferFunction(Level5) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_6() ++SWD_TransferFunction(Level6) + ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_7() ++SWD_TransferFunction(Level7) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_8() ++SWD_TransferFunction(Level8) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_9() ++SWD_TransferFunction(Level9) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_LOW(DAP_Data.clock_delay) ++SWD_TransferFunction(LevelLow) ++#else /* #ifdef HISPARK_TRACE */ + + #undef PIN_DELAY + #define PIN_DELAY() PIN_DELAY_FAST() +@@ -277,23 +663,51 @@ + #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) + SWD_TransferFunction(Slow) + ++#endif /* #ifdef HISPARK_TRACE */ + + // SWD Transfer I/O + // request: A[3:2] RnW APnDP + // data: DATA[31:0] + // return: ACK[2:0] + __WEAK uint8_t SWD_Transfer(uint32_t request, uint32_t *data) { ++#ifdef HISPARK_TRACE ++ switch (DAP_Data.clock_level) { ++ case SWD_JTAG_CLOCK_LEVEL_0: ++ return SWD_TransferLevel0(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_1: ++ return SWD_TransferLevel1(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_2: ++ return SWD_TransferLevel2(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_3: ++ return SWD_TransferLevel3(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_4: ++ return SWD_TransferLevel4(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_5: ++ return SWD_TransferLevel5(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_6: ++ return SWD_TransferLevel6(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_7: ++ return SWD_TransferLevel7(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_8: ++ return SWD_TransferLevel8(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_9: ++ return SWD_TransferLevel9(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_LOW: ++ return SWD_TransferLevelLow(request, data); ++ default: ++ return SWD_TransferLevel6(request, data); ++ } ++#else /* #ifdef HISPARK_TRACE */ + if (DAP_Data.fast_clock) { + return SWD_TransferFast(request, data); + } else { + return SWD_TransferSlow(request, data); + } ++#endif /* #ifdef HISPARK_TRACE */ + } + +- + #endif /* (DAP_SWD != 0) */ + +- + #if defined(__CC_ARM) + #pragma pop + #elif defined(__GNUC__) && !defined(__ARMCC_VERSION) +diff -uNr old/CA7/source/daplink/cmsis-dap/SWO.c new/CA7/source/daplink/cmsis-dap/SWO.c +--- old/CA7/source/daplink/cmsis-dap/SWO.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/cmsis-dap/SWO.c 2023-05-25 15:09:49.000000000 +0800 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2013-2021 ARM Limited. All rights reserved. ++ * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * +@@ -17,8 +17,8 @@ + * + * ---------------------------------------------------------------------- + * +- * $Date: 29. March 2021 +- * $Revision: V2.0.1 ++ * $Date: 1. December 2017 ++ * $Revision: V2.0.0 + * + * Project: CMSIS-DAP Source + * Title: SWO.c CMSIS-DAP SWO I/O +@@ -32,8 +32,6 @@ + #endif + #if (SWO_STREAM != 0) + #include "cmsis_os2.h" +-#define osObjectsExternal +-#include "osObjects.h" + #endif + + #if (SWO_STREAM != 0) +@@ -44,11 +42,15 @@ + + #if (SWO_UART != 0) + ++#ifndef SWO_USART_PORT ++#define SWO_USART_PORT 0 /* USART Port Number */ ++#endif ++ + // USART Driver + #define _USART_Driver_(n) Driver_USART##n + #define USART_Driver_(n) _USART_Driver_(n) +-extern ARM_DRIVER_USART USART_Driver_(SWO_UART_DRIVER); +-#define pUSART (&USART_Driver_(SWO_UART_DRIVER)) ++extern ARM_DRIVER_USART USART_Driver_(SWO_USART_PORT); ++#define pUSART (&USART_Driver_(SWO_USART_PORT)) + + static uint8_t USART_Ready = 0U; + +@@ -148,10 +150,10 @@ + } + } + +-// Enable or disable SWO Mode (UART) ++// Enable or disable UART SWO Mode + // enable: enable flag + // return: 1 - Success, 0 - Error +-__WEAK uint32_t SWO_Mode_UART (uint32_t enable) { ++__WEAK uint32_t SWO_MODE_UART (uint32_t enable) { + int32_t status; + + USART_Ready = 0U; +@@ -175,7 +177,7 @@ + return (1U); + } + +-// Configure SWO Baudrate (UART) ++// Configure UART SWO Baudrate + // baudrate: requested baudrate + // return: actual baudrate or 0 when not configured + __WEAK uint32_t SWO_Baudrate_UART (uint32_t baudrate) { +@@ -221,10 +223,10 @@ + return (baudrate); + } + +-// Control SWO Capture (UART) ++// Control UART SWO Capture + // active: active flag + // return: 1 - Success, 0 - Error +-__WEAK uint32_t SWO_Control_UART (uint32_t active) { ++__WEAK uint32_t SWO_CONTROL_UART (uint32_t active) { + int32_t status; + + if (active) { +@@ -250,7 +252,7 @@ + return (1U); + } + +-// Start SWO Capture (UART) ++// Start UART SWO Capture + // buf: pointer to buffer for capturing + // num: number of bytes to capture + __WEAK void SWO_Capture_UART (uint8_t *buf, uint32_t num) { +@@ -258,7 +260,7 @@ + pUSART->Receive(buf, num); + } + +-// Get SWO Pending Trace Count (UART) ++// Get UART SWO Pending Trace Count + // return: number of pending trace data bytes + __WEAK uint32_t SWO_GetCount_UART (void) { + uint32_t count; +@@ -276,36 +278,36 @@ + + #if (SWO_MANCHESTER != 0) + +-// Enable or disable SWO Mode (Manchester) ++// Enable or disable Manchester SWO Mode + // enable: enable flag + // return: 1 - Success, 0 - Error +-__WEAK uint32_t SWO_Mode_Manchester (uint32_t enable) { ++__WEAK uint32_t Manchester_SWO_Mode (uint32_t enable) { + return (0U); + } + +-// Configure SWO Baudrate (Manchester) ++// Configure Manchester SWO Baudrate + // baudrate: requested baudrate + // return: actual baudrate or 0 when not configured + __WEAK uint32_t SWO_Baudrate_Manchester (uint32_t baudrate) { + return (0U); + } + +-// Control SWO Capture (Manchester) ++// Control Manchester SWO Capture + // active: active flag + // return: 1 - Success, 0 - Error +-__WEAK uint32_t SWO_Control_Manchester (uint32_t active) { ++__WEAK uint32_t Manchester_SWO_Control (uint32_t active) { + return (0U); + } + +-// Start SWO Capture (Manchester) ++// Start Manchester SWO Capture + // buf: pointer to buffer for capturing + // num: number of bytes to capture +-__WEAK void SWO_Capture_Manchester (uint8_t *buf, uint32_t num) { ++__WEAK void Manchester_SWO_Capture (uint8_t *buf, uint32_t num) { + } + +-// Get SWO Pending Trace Count (Manchester) ++// Get Manchester SWO Pending Trace Count + // return: number of pending trace data bytes +-__WEAK uint32_t SWO_GetCount_Manchester (void) { ++__WEAK uint32_t Manchester_SWO_GetCount (void) { + } + + #endif /* (SWO_MANCHESTER != 0) */ +@@ -349,13 +351,13 @@ + #if (SWO_UART != 0) + case DAP_SWO_UART: + TraceStatus = DAP_SWO_CAPTURE_ACTIVE; +- SWO_Capture_UART(&TraceBuf[index_i], 1U); ++ UART_SWO_Capture(&TraceBuf[index_i], 1U); + break; + #endif + #if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + TraceStatus = DAP_SWO_CAPTURE_ACTIVE; +- SWO_Capture_Manchester(&TraceBuf[index_i], 1U); ++ Manchester_SWO_Capture(&TraceBuf[index_i], 1U); + break; + #endif + default: +@@ -377,12 +379,12 @@ + switch (TraceMode) { + #if (SWO_UART != 0) + case DAP_SWO_UART: +- count += SWO_GetCount_UART(); ++ count += UART_SWO_GetCount(); + break; + #endif + #if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: +- count += SWO_GetCount_Manchester(); ++ count += Manchester_SWO_GetCount(); + break; + #endif + default: +@@ -469,12 +471,12 @@ + switch (TraceMode) { + #if (SWO_UART != 0) + case DAP_SWO_UART: +- SWO_Mode_UART(0U); ++ SWO_MODE_UART(0U); + break; + #endif + #if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: +- SWO_Mode_Manchester(0U); ++ Manchester_SWO_Mode(0U); + break; + #endif + default: +@@ -487,12 +489,12 @@ + break; + #if (SWO_UART != 0) + case DAP_SWO_UART: +- result = SWO_Mode_UART(1U); ++ result = SWO_MODE_UART(1U); + break; + #endif + #if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: +- result = SWO_Mode_Manchester(1U); ++ result = Manchester_SWO_Mode(1U); + break; + #endif + default: +@@ -533,12 +535,12 @@ + switch (TraceMode) { + #if (SWO_UART != 0) + case DAP_SWO_UART: +- baudrate = SWO_Baudrate_UART(baudrate); ++ baudrate = SWO_BAUDRATE_UART(baudrate); + break; + #endif + #if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: +- baudrate = SWO_Baudrate_Manchester(baudrate); ++ baudrate = Manchester_SWO_Baudrate(baudrate); + break; + #endif + default: +@@ -577,12 +579,12 @@ + switch (TraceMode) { + #if (SWO_UART != 0) + case DAP_SWO_UART: +- result = SWO_Control_UART(active); ++ result = SWO_CONTROL_UART(active); + break; + #endif + #if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: +- result = SWO_Control_Manchester(active); ++ result = Manchester_SWO_Control(active); + break; + #endif + default: +diff -uNr old/CA7/source/daplink/compiler.h new/CA7/source/daplink/compiler.h +--- old/CA7/source/daplink/compiler.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/compiler.h 2023-05-25 15:09:49.000000000 +0800 +@@ -37,7 +37,11 @@ + // The special value '__COUNTER__' is used to create a unique value to + // append to 'compiler_assert_' to create a unique token. This prevents + // conflicts resulting from the same enum being declared multiple times. ++#if defined(HISPARK_TRACE) ++#define COMPILER_ASSERT(e) ++#else + #define COMPILER_ASSERT(e) enum { COMPILER_CONCAT(compiler_assert_, __COUNTER__) = 1/((e) ? 1 : 0) } ++#endif + + // Macros to disable optimisation of a function. + #if (defined(__ICCARM__)) +diff -uNr old/CA7/source/daplink/cortex_m.c new/CA7/source/daplink/cortex_m.c +--- old/CA7/source/daplink/cortex_m.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/cortex_m.c 2023-05-25 15:09:49.000000000 +0800 +@@ -23,5 +23,7 @@ + + __WEAK void SystemReset(void) + { +- NVIC_SystemReset(); ++#ifndef HISPARK_TRACE ++ NVIC_SystemReset(); ++#endif + } +diff -uNr old/CA7/source/daplink/cortex_m.h new/CA7/source/daplink/cortex_m.h +--- old/CA7/source/daplink/cortex_m.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/cortex_m.h 2023-05-25 15:09:49.000000000 +0800 +@@ -34,15 +34,21 @@ + + __STATIC_FORCEINLINE cortex_int_state_t cortex_int_get_and_disable(void) + { ++#ifdef HISPARK_TRACE ++ cortex_int_state_t state = 0; ++#else + cortex_int_state_t state; + state = __get_PRIMASK(); ++#endif + __disable_irq(); + return state; + } + + __STATIC_FORCEINLINE void cortex_int_restore(cortex_int_state_t state) + { ++#ifndef HISPARK_TRACE + __set_PRIMASK(state); ++#endif + } + + __STATIC_FORCEINLINE bool cortex_in_isr(void) +diff -uNr old/CA7/source/daplink/daplink_debug.h new/CA7/source/daplink/daplink_debug.h +--- old/CA7/source/daplink/daplink_debug.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/daplink_debug.h 2023-05-25 15:09:49.000000000 +0800 +@@ -26,6 +26,11 @@ + #include + #include + #include ++#if defined (HISPARK_TRACE) ++#include "cmsis_os2.h" ++#include "rl_usb.h" ++#include "util.h" ++#endif + + #ifdef __cplusplus + extern "C" { +@@ -37,9 +42,56 @@ + + #if defined (DAPLINK_DEBUG) + ++#if defined (HISPARK_TRACE) ++static const char error_msg[] = "\r\n\r\n"; ++ ++static inline uint32_t daplink_debug(uint8_t *buf, uint32_t size) ++{ ++ uint32_t total_free; ++ uint32_t write_free; ++ uint32_t error_len = strlen(error_msg); ++ total_free = USBD_CDC_ACM_DataFree(); ++ ++ if (total_free < error_len) { ++ // No space ++ return 0; ++ } ++ ++ // Size available for writing ++ write_free = total_free - error_len; ++ size = MIN(write_free, size); ++ USBD_CDC_ACM_DataSend(buf, size); ++ ++ if (write_free == size) { ++ USBD_CDC_ACM_DataSend((uint8_t *)error_msg, error_len); ++ } ++ ++ return size; ++} ++ ++static char daplink_debug_buf[128] = {0}; ++static inline uint32_t daplink_debug_print(const char *format, ...) ++{ ++ uint32_t ret; ++ int32_t r = 0; ++ va_list arg; ++ ret = 1; ++ va_start(arg, format); ++ r = vsnprintf(daplink_debug_buf, sizeof(daplink_debug_buf), format, arg); ++ ++ if (r >= sizeof(daplink_debug_buf)) { ++ r = snprintf(daplink_debug_buf, sizeof(daplink_debug_buf), "\r\n", r); ++ ret = 0; ++ } ++ ++ va_end(arg); ++ daplink_debug((uint8_t *)daplink_debug_buf, r); ++ return ret; ++} ++#else + uint32_t daplink_debug_print(const char *format, ...); + uint32_t daplink_debug(uint8_t *data, uint32_t size); +- ++#endif + #else + + static inline uint32_t daplink_debug_print(const char *format, ...) +@@ -57,8 +109,8 @@ + #define debug_msg(fmt, args...) daplink_debug_print(fmt, ## args); + #define debug_data(buf, size) daplink_debug(buf, size); + +-#endif +- + #ifdef __cplusplus + } + #endif ++ ++#endif +diff -uNr old/CA7/source/daplink/daplink.h new/CA7/source/daplink/daplink.h +--- old/CA7/source/daplink/daplink.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/daplink.h 2023-05-25 15:09:49.000000000 +0800 +@@ -66,6 +66,9 @@ + #define DAPLINK_HIC_ID_STM32F723IE 0x9796990D // reserving for future use + #define DAPLINK_HIC_ID_LPC55XX 0x4C504355 // 'LPC\x55' + #define DAPLINK_HIC_ID_M48SSIDAE 0x97969921 ++#ifdef HISPARK_TRACE ++#define DAPLINK_HIC_ID_STM32MP153 0x97969949 ++#endif + #define DAPLINK_HIC_ID_PSOC5 0x2E127069 + #define DAPLINK_HIC_ID_NRF52820 0x6E052820 // 'n\x05\x28\x20' + //@} +diff -uNr old/CA7/source/daplink/drag-n-drop/file_stream.c new/CA7/source/daplink/drag-n-drop/file_stream.c +--- old/CA7/source/daplink/drag-n-drop/file_stream.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/drag-n-drop/file_stream.c 2023-05-25 15:09:49.000000000 +0800 +@@ -30,6 +30,12 @@ + #include "compiler.h" + #include "validation.h" + ++#ifdef HISPARK_TRACE ++#include "target_lib_manager.h" ++#include "factory_manager.h" ++#include "config_storage_update.h" ++#endif /* #ifdef HISPARK_TRACE */ ++ + typedef enum { + STREAM_STATE_CLOSED, + STREAM_STATE_OPEN, +@@ -53,6 +59,12 @@ + uint8_t vector_buf[FLASH_DECODER_MIN_SIZE]; + uint8_t buf_pos; + uint32_t flash_addr; ++#ifdef HISPARK_TRACE ++ uint8_t name_buf[TARGET_LIB_IMAGE_NAME_MAX_LEN]; ++ uint8_t name_len; ++ uint8_t name_buf_pos; ++ uint8_t image_flag; ++#endif /* #ifdef HISPARK_TRACE */ + } bin_state_t; + + typedef struct { +@@ -151,7 +163,6 @@ + if (ERROR_SUCCESS != status) { + state = STREAM_STATE_ERROR; + } +- + return status; + } + +@@ -218,6 +229,20 @@ + + static error_t write_bin(void *state, const uint8_t *data, uint32_t size) + { ++#ifdef HISPARK_TRACE ++ error_t status; ++ bin_state_t *bin_state = (bin_state_t *)state; ++ flash_decoder_type_t flash_type; ++ uint32_t size_left; ++ uint32_t copy_size; ++ uint32_t start_addr; ++ const flash_intf_t *flash_intf; ++ int32_t end_addr = 0; ++ flash_decoder_head_t info; ++ TargetFlashInfo targetFlashInfo; ++ ++ if (bin_state->buf_pos < FLASH_DECODER_MIN_SIZE || bin_state->image_flag == 1) { ++#else + error_t status; + bin_state_t *bin_state = (bin_state_t *)state; + +@@ -227,6 +252,7 @@ + uint32_t copy_size; + uint32_t start_addr; + const flash_intf_t *flash_intf; ++#endif /* #ifdef HISPARK_TRACE */ + // Buffer Data + size_left = FLASH_DECODER_MIN_SIZE - bin_state->buf_pos; + copy_size = MIN(size_left, size); +@@ -247,6 +273,47 @@ + return ERROR_FD_UNSUPPORTED_UPDATE; + } + ++#ifdef HISPARK_TRACE ++ if (FLASH_DECODER_TYPE_TARGET_ALGO == flash_type || ++ FLASH_DECODER_TYPE_TARGET_IMAGE == flash_type) { ++ memcpy(&info, bin_state->vector_buf, sizeof(info)); ++ targetFlashInfo.regioninfo = info.region_info; ++ targetFlashInfo.flashID = info.vendor_flash_algo; ++ targetFlashInfo.fileSize = info.size; ++ targetFlashInfo.modelID = info.vendor_model; ++ targetFlashInfo.vendorID = info.vendor; ++ targetFlashInfo.version = info.version; ++ targetFlashInfo.fileCrc32 = info.crc_value; ++ targetFlashInfo.oldNamelen = info.nameLen; ++ targetFlashInfo.targetAddr = info.targetAddr; ++ targetFlashInfo.maxLoads = info.maxLoads; ++ ++ if (FLASH_DECODER_TYPE_TARGET_ALGO == flash_type) { ++ if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { ++ FactoryAlgoChange(targetFlashInfo); ++ } else { ++ TargetLibAlgoAdd(targetFlashInfo); ++ } ++ } else { ++ bin_state->image_flag = 1; ++ size_left = info.nameLen - bin_state->name_buf_pos; ++ copy_size = MIN(size_left, size); ++ memcpy(bin_state->name_buf + bin_state->name_buf_pos, data, copy_size); ++ bin_state->name_buf_pos += copy_size; ++ if (bin_state->name_buf_pos < info.nameLen) { ++ return ERROR_SUCCESS; ++ } ++ if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { ++ FactoryImageChange(targetFlashInfo, bin_state->name_buf, info.nameLen); ++ } else { ++ TargetLibImageAdd(targetFlashInfo, bin_state->name_buf, info.nameLen); ++ } ++ bin_state->image_flag = 0; ++ data += copy_size; ++ size -= copy_size; ++ } ++ } ++#endif /* #ifdef HISPARK_TRACE */ + // Determine flash addresss + status = flash_decoder_get_flash(flash_type, 0, false, &start_addr, &flash_intf); + +@@ -261,17 +328,25 @@ + if (ERROR_SUCCESS != status) { + return status; + } +- ++#ifdef HISPARK_TRACE ++ if (flash_type == FLASH_DECODER_TYPE_TARGET) { ++ bin_state->flash_addr += bin_state->buf_pos; ++ } ++#else /* #ifdef HISPARK_TRACE */ + bin_state->flash_addr += bin_state->buf_pos; ++#endif /* #ifdef HISPARK_TRACE */ + } + + // Write data ++#ifdef HISPARK_TRACE ++ end_addr = ConfigLoadEndAddrGet(); ++ size = (end_addr - bin_state->flash_addr) > size ? size : (end_addr - bin_state->flash_addr); ++#endif /* #ifdef HISPARK_TRACE */ + status = flash_decoder_write(bin_state->flash_addr, data, size); + + if (ERROR_SUCCESS != status) { + return status; + } +- + bin_state->flash_addr += size; + // There is no way to determine the end of a binary + // file so any point could be the end +diff -uNr old/CA7/source/daplink/drag-n-drop/flash_decoder.c new/CA7/source/daplink/drag-n-drop/flash_decoder.c +--- old/CA7/source/daplink/drag-n-drop/flash_decoder.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/drag-n-drop/flash_decoder.c 2023-05-25 15:09:49.000000000 +0800 +@@ -31,6 +31,14 @@ + #include "target_board.h" + #include "cmsis_compiler.h" + ++#ifdef HISPARK_TRACE ++#include "target_lib_manager.h" ++#include "config_storage_update.h" ++#include "factory_manager.h" ++#include "offline_sys_config.h" ++#include "status.h" ++#endif /* #ifdef HISPARK_TRACE */ ++ + // Set to 1 to enable debugging + #define DEBUG_FLASH_DECODER 0 + +@@ -65,6 +73,57 @@ + return 0; // Return 0 if image is compatible + } + ++#ifdef HISPARK_TRACE ++flash_decoder_type_t flash_decoder_detect_type(const uint8_t *data, uint32_t size, uint32_t addr, bool addr_valid) ++{ ++ flash_decoder_head_t info; ++ util_assert(size >= FLASH_DECODER_MIN_SIZE); ++ ++ // Check if this is a daplink image ++ memcpy(&info, data, sizeof(info)); ++ if(!addr_valid){ //reset until we know the binary type ++ flash_type_target_bin = false; ++ } ++ ++ if (info.magic_head == FLASH_DECODER_MAGIC_HEAD) { ++ ConfigLoadCurrentFileSizeSet(info.size); ++ if (FLASH_DECODER_FILE_TYPE_IF == info.file_type) { ++ // Interface update ++ return FLASH_DECODER_TYPE_INTERFACE; ++ } else if (FLASH_DECODER_FILE_TYPE_BL == info.file_type) { ++ // Bootloader update ++ return FLASH_DECODER_TYPE_BOOTLOADER; ++ } else if (FLASH_DECODER_FILE_TYPE_TARGET_ALGO == info.file_type){ ++ return FLASH_DECODER_TYPE_TARGET_ALGO; ++ } else if (FLASH_DECODER_FILE_TYPE_TARGET_IMAGE == info.file_type){ ++ return FLASH_DECODER_TYPE_TARGET_IMAGE; ++ } else if (FLASH_DECODER_FILE_TYPE_TARGET == info.file_type){ ++ if(!addr_valid){ //binary is a bin type ++ flash_type_target_bin = true; ++ } ++ return FLASH_DECODER_TYPE_TARGET; ++ } else { ++ return FLASH_DECODER_TYPE_UNKNOWN; ++ } ++ } ++ ++ // Check if a valid vector table for the target can be found ++ if (validate_bin_nvic(data)) { ++ if(!addr_valid){ //binary is a bin type ++ flash_type_target_bin = true; ++ } ++ return FLASH_DECODER_TYPE_TARGET; ++ } ++ ++ // If an address is specified then the data can be decoded ++ if (addr_valid) { ++ // TODO - future improvement - make sure address is within target's flash ++ return FLASH_DECODER_TYPE_TARGET; ++ } ++ ++ return FLASH_DECODER_TYPE_UNKNOWN; ++} ++#else /* #ifdef HISPARK_TRACE */ + flash_decoder_type_t flash_decoder_detect_type(const uint8_t *data, uint32_t size, uint32_t addr, bool addr_valid) + { + daplink_info_t info; +@@ -102,7 +161,158 @@ + + return FLASH_DECODER_TYPE_UNKNOWN; + } ++#endif /* #ifdef HISPARK_TRACE */ + ++#ifdef HISPARK_TRACE ++error_t flash_decoder_get_flash(flash_decoder_type_t type, uint32_t addr, bool addr_valid, uint32_t *start_addr, const flash_intf_t **flash_intf) ++{ ++ error_t status = ERROR_SUCCESS; ++ uint32_t flash_start_local; ++ const flash_intf_t *flash_intf_local = 0; ++ int endAddr = 0; ++ uint32_t file_len = 0; ++ DapLinkStatus daplinkStatus; ++ ++ if ((0 == start_addr) || (0 == flash_intf)) { ++ util_assert(0); ++ return ERROR_INTERNAL; ++ } ++ ++ *start_addr = 0; ++ *flash_intf = 0; ++ flash_start_local = 0; ++ flash_intf_local = 0; ++ ++ if (daplink_is_bootloader()) { ++ if (FLASH_DECODER_TYPE_INTERFACE == type) { ++ if (addr_valid && (DAPLINK_ROM_IF_START != addr)) { ++ // Address is wrong so display error message ++ status = ERROR_FD_INTF_UPDT_ADDR_WRONG; ++ } else { ++ // Setup for update ++ flash_start_local = DAPLINK_ROM_IF_START; ++ flash_intf_local = flash_intf_iap_protected; ++ } ++ } else if (FLASH_DECODER_TYPE_TARGET == type) { ++ if (addr_valid && (DAPLINK_ROM_IF_START != addr)) { ++ // Address is wrong so display error message ++ status = ERROR_FD_INTF_UPDT_ADDR_WRONG; ++ } else { ++ // "Target" update in this case would be a 3rd party interface application ++ flash_start_local = DAPLINK_ROM_IF_START; ++ flash_intf_local = flash_intf_iap_protected; ++ } ++ } else { ++ status = ERROR_FD_UNSUPPORTED_UPDATE; ++ } ++ } else if (daplink_is_interface()) { ++ file_len = ConfigLoadCurrentFileSizeGet(); ++ if (FLASH_DECODER_TYPE_BOOTLOADER == type) { ++ ConfigLoadTypeSet(CONFIG_LOAD_TYPE_BOOT); ++ if (addr_valid && (DAPLINK_ROM_BL_START != addr)) { ++ // Address is wrong so display error message ++ status = ERROR_FD_BL_UPDT_ADDR_WRONG; ++ } else { ++ // Setup for update ++ flash_start_local = DAPLINK_ROM_BL_START; ++ flash_intf_local = flash_intf_iap_protected; ++ endAddr = flash_start_local + (CONFIG_STORAGE_MAX_BOOT_SIZE > file_len ? file_len : CONFIG_STORAGE_MAX_BOOT_SIZE); ++ ConfigLoadEndAddrSet(endAddr); ++ } ++ } else if (FLASH_DECODER_TYPE_TARGET == type) { ++ ConfigLoadTypeSet(CONFIG_LOAD_TYPE_TARGET); ++ if (g_board_info.target_cfg) { ++ region_info_t * region = g_board_info.target_cfg->flash_regions; ++ for (; region->start != 0 || region->end != 0; ++region) { ++ if (kRegionIsDefault == region->flags) { ++ flash_start_local = region->start; ++ endAddr = region->end; ++ ConfigLoadEndAddrSet(endAddr); ++ break; ++ } ++ } ++ flash_intf_local = flash_intf_target; ++ } else { ++ status = ERROR_FD_UNSUPPORTED_UPDATE; ++ } ++ } else if (FLASH_DECODER_TYPE_TARGET_IMAGE == type) { ++ DapLinkStatusGet(&daplinkStatus); ++ daplinkStatus.imageStoreStatus = IMAGE_STORE_IDLE; ++ DapLinkStatusSet(&daplinkStatus); ++ ConfigLoadTypeSet(CONFIG_LOAD_TYPE_IMAGE); ++ if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { ++ flash_start_local = FactoryLibStartAddrGet(TARGET_LIB_TYPE_IMAGE); ++ } else { ++ flash_start_local = TargetLibStartAddrGet(TARGET_LIB_TYPE_IMAGE); ++ } ++ endAddr = flash_start_local + (CONFIG_STORAGE_ONE_IMAGE_MAX_SIZE > file_len ? file_len : CONFIG_STORAGE_ONE_IMAGE_MAX_SIZE); ++ ConfigLoadEndAddrSet(endAddr); ++ if (addr_valid && (flash_start_local != addr)) { ++ flash_start_local = 0; ++ status = ERROR_FD_BL_UPDT_ADDR_WRONG; ++ } else { ++ flash_intf_local = flash_intf_iap_protected; ++ } ++ }else if (FLASH_DECODER_TYPE_TARGET_ALGO == type) { ++ DapLinkStatusGet(&daplinkStatus); ++ daplinkStatus.algoStoreStatus = ALGORITHM_STORE_IDLE; ++ DapLinkStatusSet(&daplinkStatus); ++ ConfigLoadTypeSet(CONFIG_LOAD_TYPE_ALGO); ++ flash_start_local = TargetLibStartAddrGet(TARGET_LIB_TYPE_ALGO); ++ endAddr = flash_start_local + (CONFIG_STORAGE_ONE_ALGO_MAX_SIZE > file_len ? file_len : CONFIG_STORAGE_ONE_ALGO_MAX_SIZE); ++ ConfigLoadEndAddrSet(endAddr); ++ if (addr_valid && (flash_start_local != addr)) { ++ flash_start_local = 0; ++ status = ERROR_FD_BL_UPDT_ADDR_WRONG; ++ } else { ++ flash_intf_local = flash_intf_iap_protected; ++ } ++ } else if (FLASH_DECODER_TYPE_INTERFACE == type) { ++ DapLinkStatusGet(&daplinkStatus); ++ daplinkStatus.fwUpgradeStatus = FIRMWARE_UPGRADE_IDLE; ++ DapLinkStatusSet(&daplinkStatus); ++ ConfigLoadTypeSet(CONFIG_LOAD_TYPE_INTERFACE); ++ if (addr_valid && (DAPLINK_ROM_IF_START_A != addr) && (DAPLINK_ROM_IF_START_B != addr)) { ++ // Address is wrong so display error message ++ status = ERROR_FD_INTF_UPDT_ADDR_WRONG; ++ } else { ++ // Setup for update ++ if (SysStartFlagGet() == CONFIG_STRAT_FLAG_A) { ++ flash_start_local = DAPLINK_ROM_IF_START_B; ++ } else { ++ flash_start_local = DAPLINK_ROM_IF_START_A; ++ } ++ endAddr = flash_start_local + (CONFIG_STORAGE_MAX_INFACR_SIZE > file_len ? file_len : CONFIG_STORAGE_MAX_INFACR_SIZE); ++ ConfigLoadEndAddrSet(endAddr); ++ flash_intf_local = flash_intf_iap_protected; ++ } ++ }else { ++ ConfigLoadTypeSet(CONFIG_LOAD_TYPE_UNKNOW); ++ status = ERROR_FD_UNSUPPORTED_UPDATE; ++ } ++ } else { ++ status = ERROR_FD_UNSUPPORTED_UPDATE; ++ } ++ ++ // Don't allow bootloader updates unless automation is allowed ++ if (!config_get_automation_allowed() && (FLASH_DECODER_TYPE_BOOTLOADER == type)) { ++ status = ERROR_FD_UNSUPPORTED_UPDATE; ++ } ++ ++ if (ERROR_SUCCESS != status) { ++ return status; ++ } ++ ++ if (0 == flash_intf_local) { ++ util_assert(0); ++ return ERROR_INTERNAL; ++ } ++ ++ *start_addr = flash_start_local; ++ *flash_intf = flash_intf_local; ++ return status; ++} ++#else /* #ifdef HISPARK_TRACE */ + error_t flash_decoder_get_flash(flash_decoder_type_t type, uint32_t addr, bool addr_valid, uint32_t *start_addr, const flash_intf_t **flash_intf) + { + error_t status = ERROR_SUCCESS; +@@ -189,6 +399,7 @@ + *flash_intf = flash_intf_local; + return status; + } ++#endif /* #ifdef HISPARK_TRACE */ + + error_t flash_decoder_validate_target_image(flash_decoder_type_t type, const uint8_t *data, uint32_t size) + { +@@ -286,6 +497,9 @@ + if (flash_type_known) { + const flash_intf_t *flash_intf; + uint32_t flash_start_addr; ++#ifdef HISPARK_TRACE ++ TargetAlgoLibInfo tempAlgoInfo; ++#endif + status = flash_decoder_get_flash(flash_type, initial_addr, true, &flash_start_addr, &flash_intf); + + if (ERROR_SUCCESS != status) { +@@ -306,6 +520,14 @@ + flash_decoder_printf(" flash_start_addr=0x%x\r\n", flash_start_addr); + // Initialize flash manager + util_assert(!flash_initialized); ++#ifdef HISPARK_TRACE ++ TargetLibCurrentAlgoGet(&tempAlgoInfo); ++ if (flash_type == FLASH_DECODER_TYPE_TARGET && ++ tempAlgoInfo.fileStatus != TARGET_LIB_FILE_STATUS_NORMAL) { ++ state = DECODER_STATE_ERROR; ++ return ERROR_INTERNAL; ++ } ++#endif + status = flash_manager_init(flash_intf); + flash_decoder_printf(" flash_manager_init ret %i\r\n", status); + +@@ -318,6 +540,24 @@ + } + + // If flash has been initalized then write out buffered data ++#ifdef HISPARK_TRACE ++ if (flash_initialized) { ++ if (flash_type == FLASH_DECODER_TYPE_TARGET) { ++ ++ status = flash_manager_data(initial_addr, flash_buf, flash_buf_pos); ++ flash_decoder_printf(" Flushing buffer initial_addr=0x%x, flash_buf_pos=%i, flash_manager_data ret=%i\r\n", ++ initial_addr, flash_buf_pos, status); ++ ++ if (ERROR_SUCCESS != status) { ++ state = DECODER_STATE_ERROR; ++ return status; ++ } ++ } ++ } ++ if (size == 0) { ++ return status; ++ } ++#else /* #ifdef HISPARK_TRACE */ + if (flash_initialized) { + status = flash_manager_data(initial_addr, flash_buf, flash_buf_pos); + flash_decoder_printf(" Flushing buffer initial_addr=0x%x, flash_buf_pos=%i, flash_manager_data ret=%i\r\n", +@@ -328,6 +568,7 @@ + return status; + } + } ++#endif /* #ifdef HISPARK_TRACE */ + } + + // Write data as normal if flash has been initialized +@@ -356,7 +597,11 @@ + error_t flash_decoder_close(void) + { + error_t status = ERROR_SUCCESS; ++#ifdef HISPARK_TRACE ++ ++#else /* #ifdef HISPARK_TRACE */ + decoder_state_t prev_state = state; ++#endif /* #ifdef HISPARK_TRACE */ + flash_decoder_printf("flash_decoder_close()\r\n"); + + if (DECODER_STATE_CLOSED == state) { +@@ -370,12 +615,15 @@ + status = flash_manager_uninit(); + flash_decoder_printf(" flash_manager_uninit ret %i\r\n", status); + } ++#ifdef HISPARK_TRACE + ++#else /* #ifdef HISPARK_TRACE */ + if ((DECODER_STATE_DONE != prev_state) && + (flash_type != FLASH_DECODER_TYPE_TARGET) && + (status == ERROR_SUCCESS)) { + status = ERROR_IAP_UPDT_INCOMPLETE; + } ++#endif /* #ifdef HISPARK_TRACE */ + + return status; + } +@@ -385,6 +633,14 @@ + uint32_t end_addr=0; + + switch (flash_type) { ++#ifdef HISPARK_TRACE ++ case FLASH_DECODER_TYPE_BOOTLOADER: ++ case FLASH_DECODER_TYPE_INTERFACE: ++ case FLASH_DECODER_TYPE_TARGET_IMAGE: ++ case FLASH_DECODER_TYPE_TARGET_ALGO: ++ end_addr = ConfigLoadEndAddrGet(); ++ break; ++#else /* #ifdef HISPARK_TRACE */ + case FLASH_DECODER_TYPE_BOOTLOADER: + end_addr = DAPLINK_ROM_BL_START + DAPLINK_ROM_BL_SIZE; + break; +@@ -392,7 +648,7 @@ + case FLASH_DECODER_TYPE_INTERFACE: + end_addr = DAPLINK_ROM_IF_START + DAPLINK_ROM_IF_SIZE; + break; +- ++#endif /* #ifdef HISPARK_TRACE */ + case FLASH_DECODER_TYPE_TARGET: + //only if we are sure it is a bin for the target; without check unordered hex files will cause to terminate flashing + if (flash_type_target_bin && g_board_info.target_cfg) { +diff -uNr old/CA7/source/daplink/drag-n-drop/flash_decoder.h new/CA7/source/daplink/drag-n-drop/flash_decoder.h +--- old/CA7/source/daplink/drag-n-drop/flash_decoder.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/drag-n-drop/flash_decoder.h 2023-05-25 15:09:49.000000000 +0800 +@@ -35,13 +35,44 @@ + // Enough space for 12 vectors + #define FLASH_DECODER_MIN_SIZE 0x30 + ++#ifdef HISPARK_TRACE ++#define FLASH_DECODER_MAGIC_HEAD 0xAA55A55A ++ ++#define FLASH_DECODER_FILE_TYPE_BL 0x9B939D93 ++#define FLASH_DECODER_FILE_TYPE_IF 0x9B939E8F ++#define FLASH_DECODER_FILE_TYPE_TARGET_ALGO 0x9B939F00 ++#define FLASH_DECODER_FILE_TYPE_TARGET_IMAGE 0x9B939F01 ++#define FLASH_DECODER_FILE_TYPE_TARGET 0x9B939F02 ++#endif /* #ifdef HISPARK_TRACE */ ++ + typedef enum { + FLASH_DECODER_TYPE_UNKNOWN, + FLASH_DECODER_TYPE_BOOTLOADER, + FLASH_DECODER_TYPE_INTERFACE, ++#ifdef HISPARK_TRACE ++ FLASH_DECODER_TYPE_TARGET_IMAGE, ++ FLASH_DECODER_TYPE_TARGET_ALGO, ++#endif /* #ifdef HISPARK_TRACE */ + FLASH_DECODER_TYPE_TARGET, + } flash_decoder_type_t; + ++#ifdef HISPARK_TRACE ++typedef struct { ++ uint32_t magic_head; ++ uint32_t region_info; ++ uint32_t file_type; ++ uint32_t version; ++ uint32_t vendor; ++ uint32_t vendor_model; ++ uint32_t vendor_flash_algo; ++ uint32_t size; ++ uint32_t crc_value; ++ uint32_t nameLen; ++ uint32_t targetAddr; ++ uint32_t maxLoads; ++} flash_decoder_head_t; ++#endif /* #ifdef HISPARK_TRACE */ ++ + flash_decoder_type_t flash_decoder_detect_type(const uint8_t *data, uint32_t size, uint32_t addr, bool addr_valid); + error_t flash_decoder_get_flash(flash_decoder_type_t type, uint32_t addr, bool addr_valid, uint32_t *start_addr, const flash_intf_t **flash_intf); + +diff -uNr old/CA7/source/daplink/drag-n-drop/flash_intf.h new/CA7/source/daplink/drag-n-drop/flash_intf.h +--- old/CA7/source/daplink/drag-n-drop/flash_intf.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/drag-n-drop/flash_intf.h 2023-05-25 15:09:49.000000000 +0800 +@@ -34,12 +34,18 @@ + FLASH_FUNC_NOP, + FLASH_FUNC_ERASE, + FLASH_FUNC_PROGRAM, ++#ifdef HISPARK_TRACE ++ FLASH_FUNC_READ, ++#endif + FLASH_FUNC_VERIFY + } flash_func_t; + + typedef error_t (*flash_intf_init_cb_t)(void); + typedef error_t (*flash_intf_uninit_cb_t)(void); + typedef error_t (*flash_intf_program_page_cb_t)(uint32_t addr, const uint8_t *buf, uint32_t size); ++#ifdef HISPARK_TRACE ++typedef error_t (*flash_intf_read_cb_t)(uint32_t addr, uint8_t *buf, uint32_t size); ++#endif + typedef error_t (*flash_intf_erase_sector_cb_t)(uint32_t sector); + typedef error_t (*flash_intf_erase_chip_cb_t)(void); + typedef uint32_t (*flash_program_page_min_size_cb_t)(uint32_t addr); +@@ -57,6 +63,9 @@ + flash_erase_sector_size_cb_t erase_sector_size; + flash_busy_cb_t flash_busy; + flash_algo_set_cb_t flash_algo_set; ++#ifdef HISPARK_TRACE ++ flash_intf_read_cb_t read; ++#endif + } flash_intf_t; + + // All flash interfaces. Unsupported interfaces are NULL. +diff -uNr old/CA7/source/daplink/drag-n-drop/flash_manager.c new/CA7/source/daplink/drag-n-drop/flash_manager.c +--- old/CA7/source/daplink/drag-n-drop/flash_manager.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/drag-n-drop/flash_manager.c 2023-05-25 15:09:49.000000000 +0800 +@@ -4,7 +4,7 @@ + * + * DAPLink Interface Firmware + * Copyright (c) 2009-2019, ARM Limited, All Rights Reserved +- * Copyright 2019, Cypress Semiconductor Corporation ++ * Copyright 2019, Cypress Semiconductor Corporation + * or a subsidiary of Cypress Semiconductor Corporation. + * SPDX-License-Identifier: Apache-2.0 + * +@@ -25,6 +25,9 @@ + #include "util.h" + #include "error.h" + #include "settings.h" ++#ifdef HISPARK_TRACE ++#include "target_lib_manager.h" ++#endif + + // Set to 1 to enable debugging + #define DEBUG_FLASH_MANAGER 0 +@@ -48,7 +51,11 @@ + static uint8_t buf[1024]; + static bool buf_empty; + static bool current_sector_valid; ++#ifdef HISPARK_TRACE ++static bool page_erase_enabled = true; ++#else + static bool page_erase_enabled = false; ++#endif + static uint32_t current_write_block_addr; + static uint32_t current_write_block_size; + static uint32_t current_sector_addr; +diff -uNr old/CA7/source/daplink/drag-n-drop/iap_flash_intf.c new/CA7/source/daplink/drag-n-drop/iap_flash_intf.c +--- old/CA7/source/daplink/drag-n-drop/iap_flash_intf.c 2023-06-09 16:19:20.547962084 +0800 ++++ new/CA7/source/daplink/drag-n-drop/iap_flash_intf.c 2023-06-09 15:37:12.812038800 +0800 +@@ -52,6 +52,9 @@ + static error_t init(void); + static error_t uninit(void); + static error_t program_page(uint32_t addr, const uint8_t *buf, uint32_t size); ++#ifdef HISPARK_TRACE ++static error_t iap_flash_read(uint32_t addr, uint8_t *buf, uint32_t size); ++#endif + static error_t erase_sector(uint32_t addr); + static error_t erase_chip(void); + static uint32_t program_page_min_size(uint32_t addr); +@@ -73,6 +76,10 @@ + program_page_min_size, + erase_sector_size, + target_flash_busy, ++#ifdef HISPARK_TRACE ++ 0, ++ iap_flash_read, ++#endif + }; + + const flash_intf_t *const flash_intf_iap_protected = &flash_intf; +@@ -144,7 +151,11 @@ + // Bootloader - For 3rd party applications the end of the update + // is unknown so it is not an error if the transfer + // ends early. ++#ifdef HISPARK_TRACE ++ ++#else + return ERROR_IAP_UPDT_INCOMPLETE; ++#endif + } + + return ERROR_SUCCESS; +@@ -368,7 +379,11 @@ + + static error_t intercept_page_write(uint32_t addr, const uint8_t *buf, uint32_t size) + { ++#ifdef HISPARK_TRACE ++ error_t status = ERROR_IAP_NO_INTERCEPT; ++#else + error_t status; ++#endif + uint32_t crc_size; + uint32_t updt_start = DAPLINK_ROM_UPDATE_START; + uint32_t updt_end = DAPLINK_ROM_UPDATE_START + DAPLINK_ROM_UPDATE_SIZE; +@@ -377,7 +392,6 @@ + util_assert(0); + return ERROR_INTERNAL; + } +- + if ((addr < updt_start) || (addr >= updt_end)) { + return ERROR_IAP_OUT_OF_BOUNDS; + } +@@ -391,12 +405,16 @@ + crc = crc32_continue(crc, buf, crc_size); + + // Intercept the data if it is in the first sector +- if ((addr >= updt_start) && (addr < updt_start + DAPLINK_SECTOR_SIZE)) { +- uint32_t buf_offset = addr - updt_start; +- memcpy(sector_buf + buf_offset, buf, size); +- // Intercept was successful ++#ifdef HISPARK_TRACE ++ ++#else ++ if ((addr >= updt_start) && (addr < updt_start + DAPLINK_SECTOR_SIZE)) { ++ uint32_t buf_offset = addr - updt_start; ++ memcpy(sector_buf + buf_offset, buf, size); ++ // Intercept was successful + return ERROR_SUCCESS; +- } ++ } ++#endif /* #ifdef HISPARK_TRACE */ + + // Finalize update if this is the last sector + if (updt_end == addr + size) { +@@ -427,15 +445,19 @@ + // The bootloader has been updated so recompute the crc + info_crc_compute(); + update_complete = true; ++#ifdef HISPARK_TRACE ++ } ++ return status; ++#else + return status; + } + + return ERROR_IAP_NO_INTERCEPT; ++#endif + } + + static error_t intercept_sector_erase(uint32_t addr) + { +- error_t status; + uint32_t updt_start = DAPLINK_ROM_UPDATE_START; + uint32_t updt_end = DAPLINK_ROM_UPDATE_START + DAPLINK_ROM_UPDATE_SIZE; + +@@ -443,7 +465,6 @@ + util_assert(0); + return ERROR_INTERNAL; + } +- + if ((addr < updt_start) || (addr >= updt_end)) { + return ERROR_IAP_OUT_OF_BOUNDS; + } +@@ -453,18 +474,21 @@ + } + + /* Everything below here is interface specific */ ++#ifdef HISPARK_TRACE + +- if (DAPLINK_ROM_UPDATE_START == addr) { +- uint32_t addr = DAPLINK_ROM_UPDATE_START; +- status = critical_erase_and_program(addr, (uint8_t *)DAPLINK_ROM_IF_START, DAPLINK_MIN_WRITE_SIZE); +- +- if (ERROR_SUCCESS == status) { +- // Intercept was successful +- status = ERROR_SUCCESS; +- } +- +- return status; +- } ++#else /* #ifdef HISPARK_TRACE */ ++ if (DAPLINK_ROM_UPDATE_START == addr) { ++ uint32_t addr = DAPLINK_ROM_UPDATE_START; ++ status = critical_erase_and_program(addr, (uint8_t *)DAPLINK_ROM_IF_START, DAPLINK_MIN_WRITE_SIZE); ++ ++ if (ERROR_SUCCESS == status) { ++ // Intercept was successful ++ status = ERROR_SUCCESS; ++ } ++ ++ return status; ++ } ++#endif /* #ifdef HISPARK_TRACE */ + + return ERROR_IAP_NO_INTERCEPT; + } +@@ -499,6 +523,13 @@ + return ERROR_SUCCESS; + } + +-static uint8_t target_flash_busy(void){ ++static uint8_t target_flash_busy(void) { + return (state == STATE_OPEN); + } ++ ++#ifdef HISPARK_TRACE ++static error_t iap_flash_read(uint32_t addr, uint8_t *buf, uint32_t size) ++{ ++ return FlashRead(addr, size, buf); ++} ++#endif +diff -uNr old/CA7/source/daplink/drag-n-drop/intelhex.c new/CA7/source/daplink/drag-n-drop/intelhex.c +--- old/CA7/source/daplink/drag-n-drop/intelhex.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/drag-n-drop/intelhex.c 2023-05-25 15:09:49.000000000 +0800 +@@ -37,9 +37,9 @@ + }; + + typedef union hex_line_t hex_line_t; +-__PACKED_UNION hex_line_t { ++union __attribute__((packed)) hex_line_t { + uint8_t buf[0x25]; +- __PACKED_STRUCT { ++ struct __attribute__((packed)) { + uint8_t byte_count; + uint16_t address; + uint8_t record_type; +@@ -87,7 +87,7 @@ + static uint8_t low_nibble = 0, idx = 0, record_processed = 0, load_unaligned_record = 0, skip_until_aligned = 0; + static uint16_t binary_version = 0; + uint16_t board_id_hex __WEAK; +-uint16_t board_id_hex_default __WEAK; ++uint16_t board_id_hex_min __WEAK; + + void reset_hex_parser(void) + { +@@ -170,15 +170,12 @@ + + case DATA_RECORD: + case CUSTOM_DATA_RECORD: +- if (binary_version == 0 || binary_version == board_id_hex_default || binary_version == board_id_hex) { ++ if (binary_version == 0 || (binary_version >= board_id_hex_min && binary_version <= board_id_hex)){ + // Only save data from the correct binary + // verify this is a continous block of memory or need to exit and dump + if (((next_address_to_write & 0xffff0000) | line.address) != next_address_to_write) { + load_unaligned_record = 1; + status = HEX_PARSE_UNALIGNED; +- // Function will be executed again and will start by finishing to process this record by +- // adding the this line into bin_buf, so the 1st loop iteration should be the next blob byte +- hex_blob++; + goto hex_parser_exit; + } else { + // This should be superfluous but it is necessary for GCC +diff -uNr old/CA7/source/daplink/drag-n-drop/vfs_manager.c new/CA7/source/daplink/drag-n-drop/vfs_manager.c +--- old/CA7/source/daplink/drag-n-drop/vfs_manager.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/drag-n-drop/vfs_manager.c 2023-05-25 15:09:49.000000000 +0800 +@@ -36,6 +36,15 @@ + #include "file_stream.h" + #include "error.h" + ++#ifdef HISPARK_TRACE ++#include "flash_intf.h" ++#include "config_storage_update.h" ++#include "target_lib_manager.h" ++#include "offline_sys_config.h" ++#include "user_crc.h" ++#include "status.h" ++#endif ++ + // Set to 1 to enable debugging + #define DEBUG_VFS_MANAGER 0 + +@@ -389,7 +398,6 @@ + USBD_MSC_BlockCount = USBD_MSC_MemorySize / USBD_MSC_BlockSize; + USBD_MSC_BlockBuf = (uint8_t *)usb_buffer; + } +- + // Callback to handle changes to the root directory. Should be used with vfs_set_file_change_callback + static void file_change_handler(const vfs_filename_t filename, vfs_file_change_t change, vfs_file_t file, vfs_file_t new_file_data) + { +@@ -556,6 +564,85 @@ + sync_unlock(); + } + ++#ifdef HISPARK_TRACE ++static void transfer_update_done_handle(void) ++{ ++ int loadType; ++ int currentIndex; ++ uint32_t fileStatus; ++ DapLinkStatus daplinkStatus; ++ TargetAlgoLibInfo currentLibAlgo; ++ TargetImageLibInfo currentLibImage; ++ const flash_intf_t *currentIntf; ++ loadType = ConfigLoadTypeGet(); ++ switch (loadType) { ++ case CONFIG_LOAD_TYPE_INTERFACE: ++ if (SysStartFlagGet() == CONFIG_STRAT_FLAG_A) { ++ ConfigStartFlagSave(CONFIG_STRAT_FLAG_B); ++ } else { ++ ConfigStartFlagSave(CONFIG_STRAT_FLAG_A); ++ } ++ DapLinkStatusGet(&daplinkStatus); ++ daplinkStatus.fwUpgradeStatus = FIMRWARE_UPGRADE_SUCCESS; ++ DapLinkStatusSet(&daplinkStatus); ++ break; ++ case CONFIG_LOAD_TYPE_IMAGE: ++ if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { ++ FactoryLibCurrentImageGet(¤tLibImage); ++ } else { ++ TargetLibCurrentImageGet(¤tLibImage, (int32_t *)¤tIndex); ++ } ++ UserCrcInit(0, currentLibImage.info.fileCrc32); ++ currentIntf = flash_intf_iap_protected; ++ if (CheckCrcFromFlash(currentIntf, currentLibImage.startAddr, currentLibImage.info.fileSize) ++ != USER_CRC_CHECK_SUCCESS) { ++ DapLinkStatusGet(&daplinkStatus); ++ daplinkStatus.imageStoreStatus = IMAGE_STORE_CRC_ERROR; ++ DapLinkStatusSet(&daplinkStatus); ++ } else { ++ if (FactoryStatusGet() == FACTORY_FLAG_IS_SET) { ++ currentIndex = FactoryLibImageIndexGetFormStartAddr(currentLibImage.startAddr); ++ FactoryLibFileStatusChange(TARGET_LIB_TYPE_IMAGE, currentIndex, TARGET_LIB_FILE_STATUS_NORMAL); ++ } else { ++ currentIndex = TargetLibImageIndexGetFormStartAddr(currentLibImage.startAddr); ++ TargetLibFileStatusChange(TARGET_LIB_TYPE_IMAGE, currentIndex, TARGET_LIB_FILE_STATUS_NORMAL); ++ } ++ DapLinkStatusGet(&daplinkStatus); ++ daplinkStatus.imageStoreStatus = IMAGE_STORE_SUCCESS; ++ DapLinkStatusSet(&daplinkStatus); ++ } ++ break; ++ case CONFIG_LOAD_TYPE_ALGO: ++ TargetLibCurrentAlgoGet(¤tLibAlgo); ++ UserCrcInit(0, currentLibAlgo.info.fileCrc32); ++ currentIntf = flash_intf_iap_protected; ++ if (CheckCrcFromFlash(currentIntf, currentLibAlgo.startAddr, currentLibAlgo.info.fileSize) ++ != USER_CRC_CHECK_SUCCESS) { ++ DapLinkStatusGet(&daplinkStatus); ++ daplinkStatus.algoStoreStatus = ALGORITHM_STORE_CRC_ERROR; ++ DapLinkStatusSet(&daplinkStatus); ++ } else { ++ if ((currentLibAlgo.info.regioninfo & 0xFFFF0000) == TARGET_LIB_SEC_REGION) { ++ fileStatus = TARGET_LIB_FILE_STATUS_SECURITY; ++ } else { ++ fileStatus = TARGET_LIB_FILE_STATUS_NORMAL; ++ } ++ ++ currentIndex = TargetLibAlgoIndexGetFormStartAddr(currentLibAlgo.startAddr); ++ TargetLibFileStatusChange(TARGET_LIB_TYPE_ALGO, currentIndex, fileStatus); ++ DapLinkStatusGet(&daplinkStatus); ++ daplinkStatus.algoStoreStatus = ALGORITHM_STORE_SUCCESS; ++ DapLinkStatusSet(&daplinkStatus); ++ } ++ break; ++ case CONFIG_LOAD_TYPE_TARGET: ++ break; ++ default: ++ break; ++ } ++} ++#endif /* #ifdef HISPARK_TRACE */ ++ + // Update the tranfer state with file information + static void transfer_update_file_info(vfs_file_t file, uint32_t start_sector, uint32_t size, stream_type_t stream) + { +@@ -714,6 +801,9 @@ + // Override status so ERROR_SUCCESS_DONE + // does not get passed into transfer_update_state + status = stream_close(); ++#ifdef HISPARK_TRACE ++ transfer_update_done_handle(); ++#endif + vfs_mngr_printf(" stream_close ret=%i\r\n", status); + file_transfer_state.stream_open = false; + file_transfer_state.stream_finished = true; +diff -uNr old/CA7/source/daplink/drag-n-drop/vfs_user.c new/CA7/source/daplink/drag-n-drop/vfs_user.c +--- old/CA7/source/daplink/drag-n-drop/vfs_user.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/drag-n-drop/vfs_user.c 2023-05-25 15:09:49.000000000 +0800 +@@ -45,6 +45,13 @@ + //! device. This is to accomodate for hex file programming. + #define VFS_DISK_SIZE (MB(64)) + ++#ifdef HISPARK_TRACE ++// Additional buffer space to display more than 512 bytes in DETAILS.TXT ++#if !defined(BOARD_EXTRA_BUFFER) ++#define BOARD_EXTRA_BUFFER 0 ++#endif ++#endif /* #ifdef HISPARK_TRACE */ ++ + //! @brief Constants for magic action or config files. + //! + //! The "magic files" are files with a special name that if created on the USB MSC volume, will +@@ -118,8 +125,7 @@ + + static uint32_t expand_info(uint8_t *buf, uint32_t bufsize); + +-__WEAK void vfs_user_build_filesystem_hook(){} +- ++__WEAK void vfs_user_build_filesystem_hook(void){} + void vfs_user_build_filesystem() + { + uint32_t file_size; +@@ -137,6 +143,10 @@ + if (vfs_mngr_get_transfer_status() != ERROR_SUCCESS) { + file_size = get_file_size(read_file_fail_txt); + vfs_create_file("FAIL TXT", read_file_fail_txt, 0, file_size); ++#ifdef HISPARK_TRACE ++ } else { ++ vfs_create_file("SUCCESS TXT", 0, 0, 0); ++#endif + } + + // ASSERT.TXT +@@ -517,12 +527,21 @@ + #define LOCAL_MODS "" + #endif + ++#ifdef HISPARK_TRACE ++#ifndef GIT_DESCRIPTION ++#define GIT_DESCRIPTION "001" ++#endif ++#endif /* #ifdef HISPARK_TRACE */ + static uint32_t update_details_txt_file(uint8_t *buf, uint32_t size, uint32_t start) + { + uint32_t pos = 0; + + pos += util_write_string_in_region(buf, size, start, pos, ++#ifdef HISPARK_TRACE ++ "# DAPLink Firmware - see https://mbed.com/daplink\r\n" ++#else + "# DAPLink Firmware - see https://daplink.io\r\n" ++#endif + // Build ID + "Build ID: " GIT_DESCRIPTION " (" COMPILER_DESCRIPTION LOCAL_MODS ")\r\n"); + // Unique ID +@@ -671,7 +690,11 @@ + uint32_t buf_len = strlen((const char *)buf); + uint32_t str_len = strlen((const char *)insert_string); + //buffer overflow check on insert ++#ifdef HISPARK_TRACE ++ if (((buf + str_len + buf_len - 2) < (orig_buf+bufsize)) && (str_len > 0)){ ++#else + if( (buf + str_len + buf_len - 2) < (orig_buf+bufsize)){ ++#endif + // push out string + memmove(buf + str_len, buf + 2, buf_len - 2); + // insert +diff -uNr old/CA7/source/daplink/error.c new/CA7/source/daplink/error.c +--- old/CA7/source/daplink/error.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/error.c 2023-05-25 15:09:49.000000000 +0800 +@@ -71,6 +71,8 @@ + "Flash algorithm erase all command FAILURE", + // ERROR_WRITE + "Flash algorithm write command FAILURE", ++ // ERROR_READ ++ "Flash algorithm read command FAILURE", + // ERROR_WRITE_VERIFY + "Flash algorithm write verify command FAILURE", + +@@ -177,6 +179,8 @@ + ERROR_TYPE_TARGET, + // ERROR_WRITE + ERROR_TYPE_TARGET, ++ // ERROR_READ ++ ERROR_TYPE_TARGET, + // ERROR_WRITE_VERIFY + ERROR_TYPE_TARGET, + +diff -uNr old/CA7/source/daplink/error.h new/CA7/source/daplink/error.h +--- old/CA7/source/daplink/error.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/error.h 2023-05-25 15:09:49.000000000 +0800 +@@ -52,6 +52,7 @@ + ERROR_ERASE_SECTOR, + ERROR_ERASE_ALL, + ERROR_WRITE, ++ ERROR_READ, + ERROR_WRITE_VERIFY, + + /* File stream errors */ +diff -uNr old/CA7/source/daplink/flash_hal.c new/CA7/source/daplink/flash_hal.c +--- old/CA7/source/daplink/flash_hal.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/flash_hal.c 2023-05-25 15:09:49.000000000 +0800 +@@ -23,6 +23,10 @@ + #include "cortex_m.h" + #include "daplink_addr.h" + ++#ifdef HISPARK_TRACE ++#define ONE_PAGE_SIZE 256 ++#endif ++ + uint32_t flash_erase_sector(uint32_t addr) + { + cortex_int_state_t state; +@@ -35,11 +39,31 @@ + + uint32_t flash_program_page(uint32_t adr, uint32_t sz, uint8_t *buf) + { ++ + int retval = -1; + cortex_int_state_t state; + state = cortex_int_get_and_disable(); ++#ifdef HISPARK_TRACE ++ int i = 0; ++ uint32_t page_cnt = 0; ++ page_cnt = sz / ONE_PAGE_SIZE; ++ ++ for (i = 0; i < page_cnt; i++) { ++ retval = ProgramPage(adr, ONE_PAGE_SIZE, (uint32_t *)buf); ++ cortex_int_restore(state); ++ adr += ONE_PAGE_SIZE; ++ sz -= ONE_PAGE_SIZE; ++ buf += ONE_PAGE_SIZE; ++ } ++ ++ if (sz > 0) { ++ retval = ProgramPage(adr, sz, (uint32_t *)buf); ++ } ++#else + retval = ProgramPage(adr, sz, (uint32_t *)buf); + cortex_int_restore(state); ++#endif ++ + return retval; + } + +diff -uNr old/CA7/source/daplink/HardFault_Handler.c new/CA7/source/daplink/HardFault_Handler.c +--- old/CA7/source/daplink/HardFault_Handler.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/HardFault_Handler.c 2023-05-25 15:09:49.000000000 +0800 +@@ -28,6 +28,7 @@ + //hexdump logic on hardfault + __USED __NO_RETURN void _fault_handler(uint32_t _lr) + { ++#ifndef HISPARK_TRACE + uint32_t stk_ptr; + uint32_t * stack = (uint32_t *)__get_MSP(); + +@@ -63,7 +64,7 @@ + config_ram_add_hexdump(SCB->MMFAR); + config_ram_add_hexdump(SCB->BFAR); + #endif // __CORTEX_M +- ++#endif + util_assert(0); + SystemReset(); + +@@ -77,7 +78,7 @@ + _fault_handler(_lr); + } + #else // gcc and armclang +-void HardFault_Handler() ++void HardFault_Handler(void) + { + __ASM volatile ( + " mov r0, lr \n\t" +diff -uNr old/CA7/source/daplink/info.c new/CA7/source/daplink/info.c +--- old/CA7/source/daplink/info.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/info.c 2023-05-25 15:09:49.000000000 +0800 +@@ -60,7 +60,6 @@ + + static char usb_desc_unique_id[2 + sizeof(string_unique_id) * 2]; + +- + const char *info_get_unique_id(void) + { + return string_unique_id; +@@ -160,7 +159,7 @@ + string_version[idx++] = 0; + } + +-static void setup_unique_id() ++static void setup_unique_id(void) + { + memset(string_unique_id, 0, sizeof(string_unique_id)); + strcat(string_unique_id, string_board_id); +@@ -169,7 +168,7 @@ + strcat(string_unique_id, string_hic_id); + } + +-static void setup_string_descriptor() ++static void setup_string_descriptor(void) + { + uint8_t i = 0, idx = 0, len = 0; + len = strlen((const char *)string_unique_id); +@@ -187,7 +186,9 @@ + + void info_init(void) + { ++#ifndef HISPARK_TRACE + info_crc_compute(); ++#endif + read_unique_id(host_id); + setup_basics(); + setup_unique_id(); +@@ -321,4 +322,3 @@ + + return info_if->version; + } +- +diff -uNr old/CA7/source/daplink/interface/bootloader_update.c new/CA7/source/daplink/interface/bootloader_update.c +--- old/CA7/source/daplink/interface/bootloader_update.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/interface/bootloader_update.c 2023-05-25 15:09:49.000000000 +0800 +@@ -49,7 +49,7 @@ + static const char image_data[1]; + #endif //DAPLINK_BOOTLOADER_UPDATE + +-static bool interface_image_valid() ++static bool interface_image_valid(void) + { + uint32_t stored_crc = 0; + uint32_t computed_crc; +diff -uNr old/CA7/source/daplink/interface/daplink.c new/CA7/source/daplink/interface/daplink.c +--- old/CA7/source/daplink/interface/daplink.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/interface/daplink.c 2023-05-25 15:09:49.000000000 +0800 +@@ -25,9 +25,11 @@ + + #include "virtual_fs.h" + #include "compiler.h" ++#ifdef HISPARK_TRACE + ++#else + COMPILER_ASSERT(DAPLINK_BUILD_KEY == DAPLINK_BUILD_KEY_IF); +- ++#endif + const vfs_filename_t daplink_mode_file_name = "START_BLACT"; + + #endif //DRAG_N_DROP_SUPPORT +diff -uNr old/CA7/source/daplink/interface/jtag_host.c new/CA7/source/daplink/interface/jtag_host.c +--- old/CA7/source/daplink/interface/jtag_host.c 1970-01-01 08:00:00.000000000 +0800 ++++ new/CA7/source/daplink/interface/jtag_host.c 2023-06-09 08:51:53.645623700 +0800 +@@ -0,0 +1,1467 @@ ++/** ++ * @file jtag_host.c ++ * @brief Implementation of jtag_host.h ++ * ++ * DAPLink Interface Firmware ++ * Copyright (c) 2009-2019, ARM Limited, All Rights Reserved ++ * Copyright 2019, Cypress Semiconductor Corporation ++ * or a subsidiary of Cypress Semiconductor Corporation. ++ * SPDX-License-Identifier: Apache-2.0 ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); you may ++ * not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#ifndef TARGET_MCU_CORTEX_A ++#include "device.h" ++#include "cmsis_os2.h" ++#include "target_config.h" ++#include "jtag_host.h" ++#include "debug_cm.h" ++ ++#include "DAP_config.h" ++#include "DAP.h" ++#include "target_family.h" ++#include "jtag_host.h" ++ ++// riscv DM register ++/* RISC_V Debug 模块相关的寄存器定义, ++ 详细的寄存器说明请查阅RISC-V官方文档《RISC-V Debug Specification》 */ ++#define RISCV_DM_ADDRESS_SHIFT 0x2 /* TAR [2,31]bit */ ++#define MATCH_CSRRW 0x1073 ++#define MATCH_CSRRS 0x2073 ++#define MATCH_CSRRC 0x3073 ++ ++#define RISCV_DM_GPRS_BASE_ADDR 0x1000 ++ ++#define RISCV_DM_DATA0 0x04 ++#define RISCV_DM_DATA11 0x0f ++#define RISCV_DM_HARTINFO 0x12 ++#define RISCV_DM_PROGBUF0 0x20 ++#define RISCV_DM_PROGBUF1 0x21 ++ ++#define RISCV_DM_DMCONTROL 0x10 ++#define RISCV_DM_DMCONTROL_HALTREQ_SHIFT 31 ++#define RISCV_DM_DMCONTROL_RESUMEREQ_SHIFT 30 ++ ++#define RISCV_DM_DMSTATUS 0x11 ++#define RISCV_DM_DMSTATUS_ALLHALTED_SHIFT 9 ++ ++#define RISCV_DM_ABSTRACTCS 0x16 ++#define RISCV_DM_ABSTRACTCS_BUSY_SHIFT 12 ++#define RISCV_DM_ABSTRACTCS_CMDERR_SHIFT 8 ++ ++#define RISCV_DM_COMMAND 0x17 ++#define RISCV_DM_COMMAND_CMDTYPE_SHIFT 24 ++#define RISCV_DM_COMMAND_AARSIZE_SHIFT 20 ++#define RISCV_DM_COMMAND_POSTEXEC_SHIFT 18 ++#define RISCV_DM_COMMAND_TRANSFER_SHIFT 17 ++#define RISCV_DM_COMMAND_WRITE_SHIFT 16 ++ ++#define RISCV_DM_DCSR 0x7B0 ++#define RISCV_DM_DCSR_EBREAK_SHIFT 15 ++ ++#define RISCV_DM_DPC 0x7B1 ++#define RISCV_DM_EBREAK_CMD 0x100073 ++ ++// Default NVIC and Core debug base addresses ++// TODO: Read these addresses from ROM. ++#define NVIC_Addr (0xe000e000) ++#define DBG_Addr (0xe000edf0) ++ ++// AP CSW register, base value ++#define CSW_VALUE (CSW_RESERVED | CSW_MSTRDBG | CSW_HPROT | CSW_DBGSTAT | CSW_SADDRINC) ++ ++#define DCRDR 0xE000EDF8 ++#define DCRSR 0xE000EDF4 ++#define DHCSR 0xE000EDF0 ++#define REGWnR (1 << 16) ++ ++#define MAX_JTAG_RETRY 10//10 ++#define MAX_TIMEOUT 5000 // Timeout for syscalls on target ++ ++// Use the CMSIS-Core definition if available. ++#if !defined(SCB_AIRCR_PRIGROUP_Pos) ++#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ ++#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ ++#endif ++ ++typedef struct { ++ uint32_t select; ++ uint32_t csw; ++} DAP_STATE; ++ ++typedef struct { ++ uint32_t r[33]; ++} DEBUG_STATE; ++ ++static JTAG_SWD_CONNECT_TYPE reset_connect = CONNECT_NORMAL; ++ ++static DAP_STATE dap_state; ++static uint32_t soft_reset = SYSRESETREQ; ++ ++static uint8_t jtag_halted(void); ++static uint8_t jtag_wait_until_halted(void); ++static uint32_t jtag_csrrw(unsigned int rd, unsigned int rs, unsigned int csr); ++static uint32_t jtag_csrrs(unsigned int rd, unsigned int rs, unsigned int csr); ++static uint32_t jtag_csrrc(unsigned int rd, unsigned int rs, unsigned int csr); ++static uint8_t jtag_set_pc(uint32_t pc_addr); ++static uint8_t jtag_set_ebreak_mode(uint8_t mode); ++ ++void jtag_set_reset_connect(JTAG_SWD_CONNECT_TYPE type) ++{ ++ reset_connect = type; ++} ++ ++static void int2array(uint8_t *res, uint32_t data, uint8_t len) ++{ ++ uint8_t i = 0; ++ ++ for (i = 0; i < len; i++) { ++ res[i] = (data >> 8 * i) & 0xff; ++ } ++} ++ ++uint8_t jtag_transfer_retry(uint32_t req, uint32_t *data) ++{ ++ uint8_t i, ack; ++ ++ for (i = 0; i < MAX_JTAG_RETRY; i++) { ++ ack = JTAG_Transfer(req, data); ++ ++ // if ack != WAIT ++ if (ack != DAP_TRANSFER_WAIT) { ++ return ack; ++ } ++ } ++ ++ return ack; ++} ++ ++void jtag_set_soft_reset(uint32_t soft_reset_type) ++{ ++ soft_reset = soft_reset_type; ++} ++ ++uint8_t jtag_init(void) ++{ ++ //TODO - DAP_Setup puts GPIO pins in a hi-z state which can ++ // cause problems on re-init. This needs to be investigated ++ // and fixed. ++ DAP_Setup(); ++ PORT_JTAG_SETUP(); ++ return 1; ++} ++ ++uint8_t jtag_off(void) ++{ ++ PORT_OFF(); ++ return 1; ++} ++ ++uint8_t jtag_clear_errors(void) ++{ ++ JTAG_WriteAbort(STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR); ++ return 1; ++} ++ ++// Read debug port register. ++uint8_t jtag_read_dp(uint8_t adr, uint32_t *val) ++{ ++ uint32_t tmp_in; ++ uint8_t tmp_out[4]; ++ uint8_t ack; ++ uint32_t tmp; ++ uint32_t ir = JTAG_DPACC; ++ ++ tmp_in = JTAG_REG_R | JTAG_REG_ADR(adr); ++ JTAG_IR(ir); ++ ack = jtag_transfer_retry(tmp_in, (uint32_t *)tmp_out); ++ *val = 0; ++ tmp = tmp_out[3]; ++ *val |= (tmp << 24); ++ tmp = tmp_out[2]; ++ *val |= (tmp << 16); ++ tmp = tmp_out[1]; ++ *val |= (tmp << 8); ++ tmp = tmp_out[0]; ++ *val |= (tmp << 0); ++ return ((ack == 0x1) ? 0x1 : 0x0); ++} ++ ++// Write debug port register ++uint8_t jtag_write_dp(uint8_t adr, uint32_t val) ++{ ++ uint32_t req; ++ uint8_t data[4]; ++ uint8_t ack; ++ uint32_t ir = JTAG_DPACC; ++ ++ //check if the right bank is already selected ++ if ((adr == DP_SELECT) && (dap_state.select == val)) { ++ return 1; ++ } ++ req = JTAG_REG_W | JTAG_REG_ADR(adr); ++ int2array(data, val, 4); ++ JTAG_IR(ir); ++ ack = jtag_transfer_retry(req, (uint32_t *)data); ++ if ((ack == DAP_TRANSFER_OK) && (adr == DP_SELECT)) { ++ dap_state.select = val; ++ } ++ return ((ack == 0x1) ? 0x1 : 0x0); ++} ++ ++// Read access port register. ++uint8_t jtag_read_ap(uint32_t adr, uint32_t *val, uint32_t apsel) ++{ ++ uint8_t tmp_in, ack; ++ uint8_t tmp_out[4]; ++ uint32_t tmp; ++ uint32_t bank_sel = adr & APBANKSEL; ++ uint32_t ir = JTAG_APACC; ++ ++ if (!jtag_write_dp(DP_SELECT, apsel | bank_sel)) { ++ return 0; ++ } ++ ++ tmp_in = JTAG_REG_R | JTAG_REG_ADR(adr); ++ // first dummy read ++ JTAG_IR(ir); ++ ack = jtag_transfer_retry(tmp_in, (uint32_t *)tmp_out); ++ *val = 0; ++ tmp = tmp_out[3]; ++ *val |= (tmp << 24); ++ tmp = tmp_out[2]; ++ *val |= (tmp << 16); ++ tmp = tmp_out[1]; ++ *val |= (tmp << 8); ++ tmp = tmp_out[0]; ++ *val |= (tmp << 0); ++ return ((ack == 0x1) ? 0x1 : 0x0); ++} ++ ++// Write access port register ++uint8_t jtag_write_ap(uint32_t adr, uint32_t val,uint32_t apsel) ++{ ++ uint8_t data[4]; ++ uint8_t req, ack; ++ uint32_t bank_sel = adr & APBANKSEL; ++ uint32_t ir = JTAG_APACC; ++ ++ if (!jtag_write_dp(DP_SELECT, apsel | bank_sel)) { ++ //if (!jtag_write_dp(DP_SELECT, 0x1000000)) { ++ return 0; ++ } ++ ++ switch (adr) { ++ case AP_CSW: ++ if (dap_state.csw == val) { ++ return 1; ++ } ++ ++ dap_state.csw = val; ++ break; ++ ++ default: ++ break; ++ } ++ ++ req = JTAG_REG_W | JTAG_REG_ADR(adr); ++ int2array(data, val, 4); ++ JTAG_IR(ir); ++ if (jtag_transfer_retry(req, (uint32_t *)data) != 0x01) { ++ return 0; ++ } ++ ++ req = JTAG_REG_R | JTAG_REG_ADR(DP_RDBUFF); ++ ir = JTAG_DPACC; ++ JTAG_IR(ir); ++ ack = jtag_transfer_retry(req, NULL); ++ ++ return ((ack == 0x1) ? 0x1 : 0x0); ++} ++ ++ ++// Write 32-bit word aligned values to target memory using address auto-increment. ++// size is in bytes. ++static uint8_t jtag_write_block(uint32_t address, uint8_t *data, uint32_t size) ++{ ++ uint8_t tmp_in[4], req; ++ uint32_t size_in_words; ++ uint32_t i, ack; ++ uint32_t ir = JTAG_DPACC; ++ ++ if (size == 0) { ++ return 0; ++ } ++ ++ size_in_words = size / 4; ++ ++ //AHB 地址递增写 ++ if (!jtag_write_ap(AP_CSW, 0x12, 0x1000000)) { ++ return 0; ++ } ++ ++ // TAR write ++ req = JTAG_REG_W | (1 << 2); ++ int2array(tmp_in, address, 4); ++ ir = JTAG_APACC; ++ JTAG_IR(ir); ++ if (jtag_transfer_retry(req, (uint32_t *)tmp_in) != 0x01) { ++ return 0; ++ } ++ ++ // DRW write ++ req = JTAG_REG_W | (3 << 2); ++ ++ for (i = 0; i < size_in_words; i++) { ++ if (jtag_transfer_retry(req, (uint32_t *)data) != 0x01) { ++ return 0; ++ } ++ ++ data += 4; ++ } ++ ir = JTAG_DPACC; ++ // dummy read ++ req = JTAG_REG_R | SWD_REG_ADR(DP_RDBUFF); ++ JTAG_IR(ir); ++ ack = jtag_transfer_retry(req, NULL); ++ return ((ack == 0x1) ? 0x1 : 0x0); ++} ++ ++// Read 32-bit word aligned values from target memory using address auto-increment. ++// size is in bytes. ++static uint8_t jtag_read_block(uint32_t address, uint8_t *data, uint32_t size) ++{ ++ uint8_t tmp_in[4], req, ack; ++ uint32_t size_in_words; ++ uint32_t i; ++ uint32_t ir; ++ ++ if (size == 0) { ++ return 0; ++ } ++ ++ size_in_words = size / 4; ++ //AHB地址递增读 ++ if (!jtag_write_ap(AP_CSW, 0x12, 0x1000000)) { ++ return 0; ++ } ++ ++ // TAR write ++ req = JTAG_REG_W | AP_TAR; ++ int2array(tmp_in, address, 4); ++ ir = JTAG_APACC; ++ JTAG_IR(ir); ++ if (jtag_transfer_retry(req, (uint32_t *)tmp_in) != DAP_TRANSFER_OK) { ++ return 0; ++ } ++ ++ // read data ++ req = JTAG_REG_R | AP_DRW; ++ JTAG_IR(ir); ++ // initiate first read, data comes back in next read ++ if (jtag_transfer_retry(req, NULL) != 0x01) { ++ return 0; ++ } ++ ++ for (i = 0; i < (size_in_words - 1); i++) { ++ if (jtag_transfer_retry(req, (uint32_t *)data) != DAP_TRANSFER_OK) { ++ return 0; ++ } ++ ++ data += 4; ++ } ++ ++ // read last word ++ ir = JTAG_DPACC; ++ req = JTAG_REG_R | JTAG_REG_ADR(DP_RDBUFF); ++ JTAG_IR(ir); ++ ack = jtag_transfer_retry(req, (uint32_t *)data); ++ return ((ack == 0x1) ? 0x1 : 0x0); ++} ++ ++// Read target memory. ++static uint8_t jtag_read_data(uint32_t addr, uint32_t *val) ++{ ++ uint8_t tmp_in[4]; ++ uint8_t tmp_out[4]; ++ uint8_t req, ack; ++ uint32_t tmp; ++ uint32_t ir; ++ // put addr in TAR register ++ int2array(tmp_in, addr, 4); ++ ir = JTAG_APACC; ++ req = JTAG_REG_W | (1 << 2); ++ JTAG_IR(ir); ++ if (jtag_transfer_retry(req, (uint32_t *)tmp_in) != 0x01) { ++ return 0; ++ } ++ ++ // read data ++ req = JTAG_REG_R | (3 << 2); ++ if (jtag_transfer_retry(req, (uint32_t *)tmp_out) != 0x01) { ++ return 0; ++ } ++ ++ // dummy read ++ ir = JTAG_DPACC; ++ req = JTAG_REG_R | JTAG_REG_ADR(DP_RDBUFF); ++ JTAG_IR(ir); ++ ack = jtag_transfer_retry(req, (uint32_t *)tmp_out); ++ *val = 0; ++ tmp = tmp_out[3]; ++ *val |= (tmp << 24); ++ tmp = tmp_out[2]; ++ *val |= (tmp << 16); ++ tmp = tmp_out[1]; ++ *val |= (tmp << 8); ++ tmp = tmp_out[0]; ++ *val |= (tmp << 0); ++ return ((ack == 0x1) ? 0x1 : 0x0); ++} ++ ++// Write target memory. ++static uint8_t jtag_write_data(uint32_t address, uint32_t data) ++{ ++ uint8_t tmp_in[4]; ++ uint8_t req, ack; ++ uint32_t ir; ++ // put addr in TAR register ++ int2array(tmp_in, address, 4); ++ req = JTAG_REG_W | (1 << 2); ++ ir = JTAG_APACC; ++ JTAG_IR(ir); ++ if (jtag_transfer_retry(req, (uint32_t *)tmp_in) != 0x01) { ++ return 0; ++ } ++ ++ // write data ++ int2array(tmp_in, data, 4); ++ req = JTAG_REG_W | (3 << 2); ++ if (jtag_transfer_retry(req, (uint32_t *)tmp_in) != 0x01) { ++ return 0; ++ } ++ ++ // dummy read ++ req = JTAG_REG_R | JTAG_REG_ADR(DP_RDBUFF); ++ ir = JTAG_DPACC; ++ JTAG_IR(ir); ++ ack = jtag_transfer_retry(req, NULL); ++ return ((ack == 0x01) ? 1 : 0); ++} ++ ++// Read 32-bit word from target memory. ++uint8_t jtag_read_word(uint32_t addr, uint32_t *val) ++{ ++ if (!jtag_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE32, 0x000000)) { ++ return 0; ++ } ++ ++ if (!jtag_read_data(addr, val)) { ++ return 0; ++ } ++ ++ return 1; ++} ++ ++// Write 32-bit word to target memory. ++uint8_t jtag_write_word(uint32_t addr, uint32_t val, uint32_t apsel) ++{ ++ if (!jtag_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE32, apsel)) { ++ return 0; ++ } ++ ++ if (!jtag_write_data(addr, val)) { ++ return 0; ++ } ++ ++ return 1; ++} ++ ++// Read 8-bit byte from target memory. ++uint8_t jtag_read_byte(uint32_t addr, uint8_t *val) ++{ ++ uint32_t tmp; ++ ++ if (!jtag_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE8, 0x1000000)) { ++ return 0; ++ } ++ ++ if (!jtag_read_data(addr, &tmp)) { ++ return 0; ++ } ++ ++ *val = (uint8_t)(tmp >> ((addr & 0x03) << 3)); ++ return 1; ++} ++ ++// Write 8-bit byte to target memory. ++uint8_t jtag_write_byte(uint32_t addr, uint8_t val) ++{ ++ uint32_t tmp; ++ ++ if (!jtag_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE8, 0x1000000)) { ++ return 0; ++ } ++ ++ tmp = val << ((addr & 0x03) << 3); ++ ++ if (!jtag_write_data(addr, tmp)) { ++ return 0; ++ } ++ ++ return 1; ++} ++ ++// Read unaligned data from target memory. ++// size is in bytes. ++uint8_t jtag_read_memory(uint32_t address, uint8_t *data, uint32_t size) ++{ ++ uint32_t n; ++ ++ // Read bytes until word aligned ++ while ((size > 0) && (address & 0x3)) { ++ if (!jtag_read_byte(address, data)) { ++ return 0; ++ } ++ ++ address++; ++ data++; ++ size--; ++ } ++ ++ // Read word aligned blocks ++ while (size > 3) { ++ // Limit to auto increment page size ++ n = TARGET_AUTO_INCREMENT_PAGE_SIZE - (address & (TARGET_AUTO_INCREMENT_PAGE_SIZE - 1)); ++ ++ if (size < n) { ++ n = size & 0xFFFFFFFC; // Only count complete words remaining ++ } ++ ++ if (!jtag_read_block(address, data, n)) { ++ return 0; ++ } ++ ++ address += n; ++ data += n; ++ size -= n; ++ } ++ ++ // Read remaining bytes ++ while (size > 0) { ++ if (!jtag_read_byte(address, data)) { ++ return 0; ++ } ++ ++ address++; ++ data++; ++ size--; ++ } ++ ++ return 1; ++} ++ ++// Write unaligned data to target memory. ++// size is in bytes. ++uint8_t jtag_write_memory(uint32_t address, uint8_t *data, uint32_t size) ++{ ++ uint32_t n = 0; ++ ++ // Write bytes until word aligned ++ while ((size > 0) && (address & 0x3)) { ++ if (!jtag_write_byte(address, *data)) { ++ return 0; ++ } ++ ++ address++; ++ data++; ++ size--; ++ } ++ ++ // Write word aligned blocks ++ while (size > 3) { ++ // Limit to auto increment page size ++ n = TARGET_AUTO_INCREMENT_PAGE_SIZE - (address & (TARGET_AUTO_INCREMENT_PAGE_SIZE - 1)); ++ ++ if (size < n) { ++ n = size & 0xFFFFFFFC; // Only count complete words remaining ++ } ++ ++ if (!jtag_write_block(address, data, n)) { ++ return 0; ++ } ++ ++ address += n; ++ data += n; ++ size -= n; ++ } ++ ++ // Write remaining bytes ++ while (size > 0) { ++ if (!jtag_write_byte(address, *data)) { ++ return 0; ++ } ++ ++ address++; ++ data++; ++ size--; ++ } ++ ++ return 1; ++} ++ ++// Execute system call. ++static uint8_t jtag_write_debug_state(DEBUG_STATE *state) ++{ ++ uint32_t i, status; ++ uint32_t temReg; ++ uint32_t try = 5; ++ ++ if (!jtag_write_dp(DP_SELECT, 0)) { ++ return 0; ++ } ++ ++ /* halt hart */ ++ for (i = 0; i < try;) { ++ i++; ++ if (jtag_halted()) { ++ break; ++ } ++ if (i == try) { ++ return 0; ++ } ++ } ++ ++ if (!jtag_set_pc(state->r[32])) { ++ return 0; ++ } ++ ++ // R10, R11, R12, R13 ++ for (i = 10; i < 14; i++) { ++ temReg = i + RISCV_DM_GPRS_BASE_ADDR; ++ if (!jtag_write_core_register(temReg, state->r[i])) { ++ return 0; ++ } ++ } ++ // x1, x2, x3 ++ for (i = 1; i < 4; i++) { ++ temReg = i + RISCV_DM_GPRS_BASE_ADDR; ++ if (!jtag_write_core_register(temReg, state->r[i])) { ++ return 0; ++ } ++ } ++ ++ /* resume hart */ ++ if (!jtag_write_word(RISCV_DM_DMCONTROL << RISCV_DM_ADDRESS_SHIFT, 1 << RISCV_DM_DMCONTROL_RESUMEREQ_SHIFT | 0x1, 0x0)) { ++ return 0; ++ } ++ ++ // check status ++ if (!jtag_read_dp(DP_CTRL_STAT, &status)) { ++ return 0; ++ } ++ ++ if (status & (STICKYERR | WDATAERR)) { ++ return 0; ++ } ++ ++ return 1; ++} ++ ++uint8_t jtag_read_core_register(uint32_t n, uint32_t *val) ++{ ++ int i = 0, timeout = 100; ++ uint32_t tempCommand = 0; ++ if (!jtag_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8, 0x0)) { ++ return 0; ++ } ++ tempCommand = (0x2 << RISCV_DM_COMMAND_AARSIZE_SHIFT) | ++ (0x1 << RISCV_DM_COMMAND_TRANSFER_SHIFT) | n; ++ if (!jtag_write_word(RISCV_DM_COMMAND << RISCV_DM_ADDRESS_SHIFT, tempCommand, 0x0)) { ++ return 0; ++ } ++ ++ // wait for abstractcs busy is 0 ++ for (i = 0; i < timeout; i++) { ++ if (!jtag_read_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT, val)) { ++ return 0; ++ } ++ ++ if ((*val >> RISCV_DM_ABSTRACTCS_BUSY_SHIFT & 0x1) == 0) { ++ if ((*val >> RISCV_DM_ABSTRACTCS_CMDERR_SHIFT & 0x7) == 0) { ++ break; ++ } else { ++ jtag_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8, 0x0); ++ return 0; ++ } ++ } ++ } ++ ++ if (i == timeout) { ++ return 0; ++ } ++ ++ if (!jtag_read_word(RISCV_DM_DATA0 << RISCV_DM_ADDRESS_SHIFT, val)) { ++ return 0; ++ } ++ ++ return 1; ++} ++ ++uint8_t jtag_write_core_register(uint32_t n, uint32_t val) ++{ ++ int i = 0, timeout = 100; ++ uint32_t tempCommand = 0; ++ if (!jtag_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8, 0x0)) { ++ return 0; ++ } ++ if (!jtag_write_word(RISCV_DM_DATA0 << RISCV_DM_ADDRESS_SHIFT, val, 0x0)) { ++ return 0; ++ } ++ tempCommand = (0x2 << RISCV_DM_COMMAND_AARSIZE_SHIFT) | ++ (0x1 << RISCV_DM_COMMAND_TRANSFER_SHIFT) | ++ (0x1 << RISCV_DM_COMMAND_WRITE_SHIFT) | n; ++ ++ if (!jtag_write_word(RISCV_DM_COMMAND << RISCV_DM_ADDRESS_SHIFT, tempCommand, 0x0)) { ++ return 0; ++ } ++ ++ // wait for abstractcs busy is 0 ++ for (i = 0; i < timeout; i++) { ++ if (!jtag_read_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT, &val)) { ++ return 0; ++ } ++ ++ if ((val >> RISCV_DM_ABSTRACTCS_BUSY_SHIFT & 0x1) == 0) { ++ if ((val >> RISCV_DM_ABSTRACTCS_CMDERR_SHIFT & 0x7) == 0) { ++ return 1; ++ } else { ++ jtag_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8, 0x0); ++ return 0; ++ } ++ } ++ } ++ return 0; ++} ++ ++static uint8_t jtag_wait_until_halted(void) ++{ ++ // Wait for target to stop ++ uint32_t val, i, timeout = MAX_TIMEOUT; ++ ++ for (i = 0; i < timeout; i++) { ++ if (!jtag_read_word(RISCV_DM_DMSTATUS << RISCV_DM_ADDRESS_SHIFT, &val)) { ++ return 0; ++ } ++ ++ if (val & (0x1 << RISCV_DM_DMSTATUS_ALLHALTED_SHIFT)) { ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++static uint32_t jtag_csrrw(unsigned int rd, unsigned int rs, unsigned int csr) ++{ ++ return (csr << 20) | (rs << 15) | (rd << 7) | MATCH_CSRRW; ++} ++ ++static uint32_t jtag_csrrs(unsigned int rd, unsigned int rs, unsigned int csr) ++{ ++ return (csr << 20) | (rs << 15) | (rd << 7) | MATCH_CSRRS; ++} ++ ++static uint32_t jtag_csrrc(unsigned int rd, unsigned int rs, unsigned int csr) ++{ ++ return (csr << 20) | (rs << 15) | (rd << 7) | MATCH_CSRRC; ++} ++ ++static uint8_t jtag_halted(void) ++{ ++ /* halt hart */ ++ if (!jtag_write_word(RISCV_DM_DMCONTROL << RISCV_DM_ADDRESS_SHIFT, 1 << RISCV_DM_DMCONTROL_HALTREQ_SHIFT | 0x1, 0x0)) { ++ return 0; ++ } ++ if (!jtag_wait_until_halted()) { ++ return 0; ++ } ++ return 1; ++} ++ ++static uint8_t jtag_set_pc(uint32_t pc_addr) ++{ ++ uint32_t tempCommand; ++ uint32_t i; ++ uint32_t val; ++ uint32_t timeout = 100; ++ uint32_t temReg; ++ uint32_t s0; ++ ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!jtag_read_core_register(temReg, &s0)) { ++ return 0; ++ } ++ ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!jtag_write_core_register(temReg, pc_addr)) { ++ goto SET_PC_ERR; ++ } ++ ++ if (!jtag_write_word(RISCV_DM_PROGBUF0 << RISCV_DM_ADDRESS_SHIFT, jtag_csrrw(0,8,RISCV_DM_DPC), 0x0)) { ++ goto SET_PC_ERR; ++ } ++ ++ if (!jtag_write_word(RISCV_DM_PROGBUF1 << RISCV_DM_ADDRESS_SHIFT,RISCV_DM_EBREAK_CMD, 0x0)) { ++ goto SET_PC_ERR; ++ } ++ ++ if (!jtag_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8, 0x0)) { ++ goto SET_PC_ERR; ++ } ++ tempCommand = (0x2 << RISCV_DM_COMMAND_AARSIZE_SHIFT) | ++ (0x1 << RISCV_DM_COMMAND_POSTEXEC_SHIFT)| 0x1000; ++ ++ if (!jtag_write_word(RISCV_DM_COMMAND << RISCV_DM_ADDRESS_SHIFT, tempCommand, 0x0)) { ++ goto SET_PC_ERR; ++ } ++ ++ // wait for abstractcs busy is 0 ++ for (i = 0; i < timeout; i++) { ++ if (!jtag_read_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT, &val)) { ++ goto SET_PC_ERR; ++ } ++ ++ if ((val >> RISCV_DM_ABSTRACTCS_BUSY_SHIFT & 0x1) == 0) { ++ if ((val >> RISCV_DM_ABSTRACTCS_CMDERR_SHIFT & 0x7) == 0) { ++ goto SET_PC_SUCCESS; ++ } else { ++ jtag_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8, 0x0); ++ goto SET_PC_ERR; ++ } ++ } ++ } ++ ++SET_PC_ERR: ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ jtag_write_core_register(temReg, s0); ++ return 0; ++ ++SET_PC_SUCCESS: ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!jtag_write_core_register(temReg, s0)) { ++ return 0; ++ } else { ++ return 1; ++ } ++} ++ ++static uint8_t jtag_set_ebreak_mode(uint8_t mode) ++{ ++ uint32_t tempCommand; ++ uint32_t i; ++ uint32_t val; ++ uint32_t timeout = 100; ++ uint32_t temReg; ++ uint32_t s0; ++ uint32_t try = 5; ++ ++ /* halt hart */ ++ for (i = 0; i < try;) { ++ i++; ++ if (jtag_halted()) { ++ break; ++ } ++ if (i == try) { ++ return 0; ++ } ++ } ++ ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!jtag_read_core_register(temReg, &s0)) { ++ return 0; ++ } ++ if (mode == 0) { ++ val = ~(0x1 << RISCV_DM_DCSR_EBREAK_SHIFT); ++ } else { ++ val = (0x1 << RISCV_DM_DCSR_EBREAK_SHIFT); ++ } ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!jtag_write_core_register(temReg, val)) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ ++ if (mode == 0) { ++ if (!jtag_write_word(RISCV_DM_PROGBUF0 << RISCV_DM_ADDRESS_SHIFT, jtag_csrrc(0,8,RISCV_DM_DCSR), 0x0)) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ } else { ++ if (!jtag_write_word(RISCV_DM_PROGBUF0 << RISCV_DM_ADDRESS_SHIFT, jtag_csrrs(0,8,RISCV_DM_DCSR), 0x0)) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ } ++ ++ if (!jtag_write_word(RISCV_DM_PROGBUF1 << RISCV_DM_ADDRESS_SHIFT, RISCV_DM_EBREAK_CMD, 0x0)) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ ++ if (!jtag_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8, 0x0)) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ tempCommand = (0x2 << RISCV_DM_COMMAND_AARSIZE_SHIFT) | ++ (0x1 << RISCV_DM_COMMAND_POSTEXEC_SHIFT)| 0x1000; ++ ++ if (!jtag_write_word(RISCV_DM_COMMAND << RISCV_DM_ADDRESS_SHIFT, tempCommand, 0x0)) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ ++ // wait for abstractcs busy is 0 ++ for (i = 0; i < timeout; i++) { ++ if (!jtag_read_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT, &val)) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ ++ if ((val >> RISCV_DM_ABSTRACTCS_BUSY_SHIFT & 0x1) == 0) { ++ if ((val >> RISCV_DM_ABSTRACTCS_CMDERR_SHIFT & 0x7) == 0) { ++ goto SET_EBREAK_MODE_SUCCESS; ++ } else { ++ jtag_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8, 0x0); ++ goto SET_EBREAK_MODE_ERR; ++ } ++ } ++ } ++ ++SET_EBREAK_MODE_ERR: ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ jtag_write_core_register(temReg, s0); ++ return 0; ++ ++SET_EBREAK_MODE_SUCCESS: ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!jtag_write_core_register(temReg, s0)) { ++ return 0; ++ } else { ++ return 1; ++ } ++} ++ ++uint8_t jtag_flash_syscall_exec(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, flash_algo_return_t return_type) ++{ ++ uint32_t temReg; ++ volatile DEBUG_STATE state = {{0}}; ++ // Call flash algorithm function on target and wait for result. ++ state.r[10] = arg1; // R10: Argument 1 ++ state.r[11] = arg2; // R11: Argument 2 ++ state.r[12] = arg3; // R12: Argument 3 ++ state.r[13] = arg4; // R13: Argument 4 ++ state.r[3] = sysCallParam->static_base; // SB: Static Base ++ state.r[2] = sysCallParam->stack_pointer; // SP: Stack Pointer ++ state.r[1] = sysCallParam->breakpoint; // LR: Exit Point ++ state.r[32] = entry; // PC: Entry Point ++ ++ if (!jtag_write_debug_state((DEBUG_STATE *)&state)) { ++ return 0; ++ } ++ if (!jtag_wait_until_halted()) { ++ return 0; ++ } ++ temReg = 10 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!jtag_read_core_register(temReg, (uint32_t *)&state.r[10])) { ++ return 0; ++ } ++ ++ if ( return_type == FLASHALGO_RETURN_POINTER ) { ++ // Flash verify functions return pointer to byte following the buffer if successful. ++ if (state.r[10] != (arg1 + arg2)) { ++ return 0; ++ } ++ } else { ++ // Flash functions return 0 if successful. ++ if (state.r[10] != 0) { ++ return 0; ++ } ++ } ++ ++ return 1; ++} ++ ++// JTAG Reset ++static uint8_t jtag_reset(void) ++{ ++ uint8_t tmp_in[8]; ++ uint8_t i = 0; ++ ++ for (i = 0; i < 8; i++) { ++ tmp_in[i] = 0xff; ++ } ++ ++ SWJ_Sequence(51, tmp_in); ++ return 1; ++} ++ ++// JTAG Switch ++static uint8_t jtag_switch(uint16_t val) ++{ ++ uint8_t tmp_in[2]; ++ tmp_in[0] = val & 0xff; ++ tmp_in[1] = (val >> 8) & 0xff; ++ SWJ_Sequence(16, tmp_in); ++ return 1; ++} ++ ++// JTAG Read ID ++static uint8_t jtag_read_idcode(uint32_t *id) ++{ ++ *id = JTAG_ReadIDCode(); ++ // uint8_t tmp_out[4]; ++ // if (jtag_read_dp(0, (uint32_t *)tmp_out) != 0x01) { ++ // return 0; ++ // } ++ ++ // *id = (tmp_out[3] << 24) | (tmp_out[2] << 16) | (tmp_out[1] << 8) | tmp_out[0]; ++ return 1; ++} ++ ++ ++uint8_t SWD2JTAG() ++{ ++ uint32_t tmp = 0; ++ ++ if (!jtag_reset()) { ++ return 0; ++ } ++ ++ if (!jtag_switch(0xE73C)) { ++ return 0; ++ } ++ ++ JTAG_RESET(); ++ jtag_read_idcode(&tmp); ++ if (tmp == 0 || tmp == 0xFFFFFFFF) { ++ return 0; ++ } ++ ++ return 1; ++} ++ ++uint8_t jtag_init_debug(void) ++{ ++ uint32_t tmp = 0; ++ int i = 0; ++ int timeout = 100; ++ // init dap state with fake values ++ dap_state.select = 0xffffffff; ++ dap_state.csw = 0xffffffff; ++ ++ int8_t retries = 4; ++ int8_t do_abort = 0; ++ do { ++ if (do_abort) { ++ //do an abort on stale target, then reset the device ++ JTAG_WriteAbort(DAPABORT); ++ //jtag_write_dp(DP_ABORT, DAPABORT); ++ jtag_set_target_reset(1); ++ osDelay(2); ++ jtag_set_target_reset(0); ++ osDelay(2); ++ do_abort = 0; ++ } ++ jtag_init(); ++ // call a target dependant function ++ // this function can do several stuff before really ++ // initing the debug ++ if (g_target_family && g_target_family->target_before_init_debug) { ++ g_target_family->target_before_init_debug(); ++ } ++ ++ if (!SWD2JTAG()) { ++ do_abort = 1; ++ continue; ++ } ++ ++ if (!jtag_clear_errors()) { ++ do_abort = 1; ++ continue; ++ } ++ ++ if (!jtag_write_dp(DP_SELECT, 0)) { ++ do_abort = 1; ++ continue; ++ ++ } ++ ++ // Power up ++ if (!jtag_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ)) { ++ do_abort = 1; ++ continue; ++ } ++ ++ for (i = 0; i < timeout; i++) { ++ ++ if (!jtag_read_dp(DP_CTRL_STAT, &tmp)) { ++ do_abort = 1; ++ break; ++ } ++ ++ if ((tmp & (CDBGPWRUPACK | CSYSPWRUPACK)) == (CDBGPWRUPACK | CSYSPWRUPACK)) { ++ //Break from loop if powerup is complete ++ break; ++ } ++ } ++ if ((i == timeout) || (do_abort == 1)) { ++ // Unable to powerup DP ++ do_abort = 1; ++ continue; ++ } ++ ++ if (!jtag_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ | TRNNORMAL | MASKLANE)) { ++ do_abort = 1; ++ continue; ++ } ++ ++ // call a target dependant function: ++ // some target can enter in a lock state ++ // this function can unlock these targets ++ if (g_target_family && g_target_family->target_unlock_sequence) { ++ g_target_family->target_unlock_sequence(); ++ } ++ ++ if (!jtag_write_dp(DP_SELECT, 0)) { ++ do_abort = 1; ++ continue; ++ } ++ ++ if (!jtag_set_ebreak_mode(1)) { ++ do_abort = 1; ++ continue; ++ } ++ return 1; ++ ++ } while (--retries > 0); ++ ++ return 0; ++} ++ ++uint8_t jtag_set_target_state_hw(target_state_t state) ++{ ++ uint32_t val; ++ int8_t ap_retries = 2; ++ /* Calling jtag_init prior to entering RUN state causes operations to fail. */ ++ if (state != RUN) { ++ jtag_init(); ++ } ++ ++ switch (state) { ++ case RESET_HOLD: ++ jtag_set_target_reset(1); ++ break; ++ ++ case RESET_RUN: ++ jtag_set_target_reset(1); ++ osDelay(2); ++ jtag_set_target_reset(0); ++ osDelay(2); ++ jtag_off(); ++ break; ++ ++ case RESET_PROGRAM: ++ if (!jtag_init_debug()) { ++ return 0; ++ } ++ ++ if (reset_connect == CONNECT_UNDER_RESET) { ++ // Assert reset ++ jtag_set_target_reset(1); ++ osDelay(2); ++ } ++ ++ // Enable debug ++ while(jtag_write_word(DBG_HCSR, DBGKEY | C_DEBUGEN, 0x0) == 0) { ++ if( --ap_retries <=0 ) ++ return 0; ++ // Target is in invalid state? ++ jtag_set_target_reset(1); ++ osDelay(2); ++ jtag_set_target_reset(0); ++ osDelay(2); ++ } ++ ++ // Enable halt on reset ++ if (!jtag_write_word(DBG_EMCR, VC_CORERESET, 0x0)) { ++ return 0; ++ } ++ ++ if (reset_connect == CONNECT_NORMAL) { ++ // Assert reset ++ jtag_set_target_reset(1); ++ osDelay(2); ++ } ++ ++ // Deassert reset ++ jtag_set_target_reset(0); ++ osDelay(2); ++ ++ do { ++ if (!jtag_read_word(DBG_HCSR, &val)) { ++ return 0; ++ } ++ } while ((val & S_HALT) == 0); ++ ++ // Disable halt on reset ++ if (!jtag_write_word(DBG_EMCR, 0, 0x0)) { ++ return 0; ++ } ++ ++ break; ++ ++ case NO_DEBUG: ++ if (!jtag_write_word(DBG_HCSR, DBGKEY, 0x0)) { ++ return 0; ++ } ++ ++ break; ++ ++ case DEBUG: ++ if (!SWD2JTAG()) { ++ return 0; ++ } ++ ++ if (!jtag_clear_errors()) { ++ return 0; ++ } ++ ++ // Ensure CTRL/STAT register selected in DPBANKSEL ++ if (!jtag_write_dp(DP_SELECT, 0)) { ++ return 0; ++ } ++ ++ // Power up ++ if (!jtag_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ)) { ++ return 0; ++ } ++ ++ // Enable debug ++ if (!jtag_write_word(DBG_HCSR, DBGKEY | C_DEBUGEN, 0x0)) { ++ return 0; ++ } ++ ++ break; ++ ++ case HALT: ++ if (!jtag_init_debug()) { ++ return 0; ++ } ++ ++ // Enable debug and halt the core (DHCSR <- 0xA05F0003) ++ if (!jtag_write_word(DBG_HCSR, DBGKEY | C_DEBUGEN | C_HALT, 0x0)) { ++ return 0; ++ } ++ ++ // Wait until core is halted ++ do { ++ if (!jtag_read_word(DBG_HCSR, &val)) { ++ return 0; ++ } ++ } while ((val & S_HALT) == 0); ++ break; ++ ++ case RUN: ++ if (!jtag_write_word(DBG_HCSR, DBGKEY, 0x0)) { ++ return 0; ++ } ++ jtag_off(); ++ break; ++ ++ case POST_FLASH_RESET: ++ // This state should be handled in target_reset.c, nothing needs to be done here. ++ break; ++ ++ default: ++ return 0; ++ } ++ ++ return 1; ++} ++ ++uint8_t jtag_set_target_state_sw(target_state_t state) ++{ ++ uint32_t val; ++ /* Calling jtag_init prior to enterring RUN state causes operations to fail. */ ++ if (state != RUN) { ++ jtag_init(); ++ } ++ ++ switch (state) { ++ case RESET_HOLD: ++ jtag_set_target_reset(1); ++ break; ++ ++ case RESET_RUN: ++ jtag_set_target_reset(1); ++ osDelay(2); ++ jtag_set_target_reset(0); ++ osDelay(2); ++ ++ // Power down ++ // Per ADIv6 spec. Clear first CSYSPWRUPREQ followed by CDBGPWRUPREQ ++ if (!jtag_read_dp(DP_CTRL_STAT, &val)) { ++ return 0; ++ } ++ ++ if (!jtag_write_dp(DP_CTRL_STAT, val & ~CSYSPWRUPREQ)) { ++ return 0; ++ } ++ ++ // Wait until ACK is deasserted ++ do { ++ if (!jtag_read_dp(DP_CTRL_STAT, &val)) { ++ return 0; ++ } ++ } while ((val & (CSYSPWRUPACK)) != 0); ++ ++ if (!jtag_write_dp(DP_CTRL_STAT, val & ~CDBGPWRUPREQ)) { ++ return 0; ++ } ++ ++ // Wait until ACK is deasserted ++ do { ++ if (!jtag_read_dp(DP_CTRL_STAT, &val)) { ++ return 0; ++ } ++ } while ((val & (CDBGPWRUPACK)) != 0); ++ ++ jtag_off(); ++ break; ++ ++ case RESET_PROGRAM: ++ if (!jtag_init_debug()) { ++ return 0; ++ } ++ ++ jtag_exec_soft_reset(); ++ if (!jtag_init_debug()) { ++ return 0; ++ } ++ break; ++ ++ case NO_DEBUG: ++ if (!jtag_write_word(DBG_HCSR, DBGKEY, 0x0)) { ++ return 0; ++ } ++ ++ break; ++ ++ case DEBUG: ++ if (!SWD2JTAG()) { ++ return 0; ++ } ++ ++ if (!jtag_clear_errors()) { ++ return 0; ++ } ++ ++ // Ensure CTRL/STAT register selected in DPBANKSEL ++ if (!jtag_write_dp(DP_SELECT, 0)) { ++ return 0; ++ } ++ ++ // Power up ++ if (!jtag_write_dp(DP_CTRL_STAT, CSYSPWRUPREQ | CDBGPWRUPREQ)) { ++ return 0; ++ } ++ ++ // Enable debug ++ if (!jtag_write_word(DBG_HCSR, DBGKEY | C_DEBUGEN, 0x0)) { ++ return 0; ++ } ++ ++ break; ++ ++ case HALT: ++ if (!jtag_init_debug()) { ++ return 0; ++ } ++ ++ // Enable debug and halt the core (DHCSR <- 0xA05F0003) ++ if (!jtag_write_word(DBG_HCSR, DBGKEY | C_DEBUGEN | C_HALT, 0x0)) { ++ return 0; ++ } ++ ++ // Wait until core is halted ++ do { ++ if (!jtag_read_word(DBG_HCSR, &val)) { ++ return 0; ++ } ++ } while ((val & S_HALT) == 0); ++ break; ++ ++ case RUN: ++ if (!jtag_write_word(DBG_HCSR, DBGKEY, 0x0)) { ++ return 0; ++ } ++ jtag_off(); ++ break; ++ ++ case POST_FLASH_RESET: ++ // This state should be handled in target_reset.c, nothing needs to be done here. ++ break; ++ ++ default: ++ return 0; ++ } ++ ++ return 1; ++} ++ ++void jtag_exec_soft_reset(void) ++{ ++ uint32_t val; ++ jtag_init_debug(); ++ /* Set (0x10100200) debug flag register */ ++ jtag_write_dp(DP_SELECT, 0x1000000); ++ jtag_write_ap(AP_CSW, 0x0000002, 0x1000000); ++ jtag_read_dp(DP_RDBUFF,&val); ++ jtag_write_dp(DP_SELECT, 0x1000000); ++ jtag_write_ap(AP_TAR, 0x10100200, 0x1000000); ++ jtag_write_ap(AP_DRW, 0xA5A5A5A5, 0x1000000); ++ ++ /* Unlock (0x10100044) configuration lock register */ ++ jtag_write_dp(DP_SELECT, 0x1000000); ++ jtag_write_ap(AP_CSW, 0x0000002, 0x1000000); ++ jtag_read_dp(DP_RDBUFF,&val); ++ jtag_write_dp(DP_SELECT, 0x1000000); ++ jtag_write_ap(AP_TAR, 0x10100044, 0x1000000); ++ jtag_write_ap(AP_DRW, 0xEA510000, 0x1000000); ++ ++ /* Set (0x1000001C) to HOSC (0x1000001C = 0x8) -- bit1~0: 0-HOSC, 1-XTAL, 2-PLL */ ++ jtag_write_dp(DP_SELECT, 0x1000000); ++ jtag_write_ap(AP_CSW, 0x0000002, 0x1000000); ++ jtag_read_dp(DP_RDBUFF,&val); ++ jtag_write_dp(DP_SELECT, 0x1000000); ++ jtag_write_ap(AP_TAR, 0x1000001C, 0x1000000); ++ jtag_write_ap(AP_DRW, 0x00000008, 0x1000000); ++ ++ /* Set (0x10100004) system reset register to reset system */ ++ jtag_write_dp(DP_SELECT, 0x1000000); ++ jtag_write_ap(AP_CSW, 0x0000002, 0x1000000); ++ jtag_read_dp(DP_RDBUFF,&val); ++ jtag_write_dp(DP_SELECT, 0x1000000); ++ jtag_write_ap(AP_TAR, 0x10100004, 0x1000000); ++ jtag_write_ap(AP_DRW, 0x00000001, 0x1000000); ++ ++ /* Add some clocks to ensure the last write operations takes effect with jlink */ ++ jtag_read_dp(DP_RDBUFF,&val); ++ /* Wait until the reset is complete. */ ++ osDelay(300); ++} ++#endif +diff -uNr old/CA7/source/daplink/interface/jtag_host.h new/CA7/source/daplink/interface/jtag_host.h +--- old/CA7/source/daplink/interface/jtag_host.h 1970-01-01 08:00:00.000000000 +0800 ++++ new/CA7/source/daplink/interface/jtag_host.h 2023-06-08 11:47:56.470578000 +0800 +@@ -0,0 +1,68 @@ ++/** ++ * @file jtag_host.h ++ * @brief Host driver for accessing the DAP ++ * ++ * DAPLink Interface Firmware ++ * Copyright (c) 2009-2019, ARM Limited, All Rights Reserved ++ * Copyright 2019, Cypress Semiconductor Corporation ++ * or a subsidiary of Cypress Semiconductor Corporation. ++ * SPDX-License-Identifier: Apache-2.0 ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); you may ++ * not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#ifndef JTAGHOST_CM_H ++#define JTAGHOST_CM_H ++ ++#include "flash_blob.h" ++#include "target_family.h" ++#ifdef TARGET_MCU_CORTEX_A ++#include "debug_ca.h" ++#else ++#include "debug_cm.h" ++#endif ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++uint8_t jtag_init(void); ++uint8_t jtag_off(void); ++uint8_t jtag_init_debug(void); ++uint8_t jtag_clear_errors(void); ++uint8_t jtag_read_dp(uint8_t adr, uint32_t *val); ++uint8_t jtag_write_dp(uint8_t adr, uint32_t val); ++uint8_t jtag_read_ap(uint32_t adr, uint32_t *val,uint32_t apsel); ++uint8_t jtag_write_ap(uint32_t adr, uint32_t val,uint32_t apsel); ++uint8_t jtag_read_word(uint32_t addr, uint32_t *val); ++uint8_t jtag_write_word(uint32_t addr, uint32_t val, uint32_t apsel); ++uint8_t jtag_read_byte(uint32_t addr, uint8_t *val); ++uint8_t jtag_write_byte(uint32_t addr, uint8_t val); ++uint8_t jtag_read_memory(uint32_t address, uint8_t *data, uint32_t size); ++uint8_t jtag_write_memory(uint32_t address, uint8_t *data, uint32_t size); ++uint8_t jtag_read_core_register(uint32_t n, uint32_t *val); ++uint8_t jtag_write_core_register(uint32_t n, uint32_t val); ++uint8_t jtag_flash_syscall_exec(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, flash_algo_return_t return_type); ++uint8_t jtag_set_target_state_hw(target_state_t state); ++uint8_t jtag_set_target_state_sw(target_state_t state); ++uint8_t jtag_transfer_retry(uint32_t req, uint32_t *data); ++void jtag_set_reset_connect(JTAG_SWD_CONNECT_TYPE type); ++void jtag_set_soft_reset(uint32_t soft_reset_type); ++void jtag_exec_soft_reset(void); ++uint8_t SWD2JTAG(void); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +diff -uNr old/CA7/source/daplink/interface/main_interface.c new/CA7/source/daplink/interface/main_interface.c +--- old/CA7/source/daplink/interface/main_interface.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/interface/main_interface.c 2023-12-27 14:14:08.214716956 +0800 +@@ -29,6 +29,7 @@ + #include "uart.h" + #include "tasks.h" + #include "swd_host.h" ++#include "jtag_host.h" + #include "info.h" + #include "settings.h" + #include "daplink.h" +@@ -50,6 +51,21 @@ + #include "rtx_os.h" + #endif + ++#ifdef HISPARK_TRACE ++#include "debug.h" ++#include "key.h" ++#include "oled.h" ++#include "target_lib_manager.h" ++#include "offline_download.h" ++#include "offline_sys_config.h" ++#include "var_monitor_process.h" ++#include "display.h" ++#include "remote_proc.h" ++#include "msg_queue.h" ++#include "factory_manager.h" ++#include "gpio.h" ++#endif ++ + #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + #ifndef __MICROLIB + /* Avoids early implicit call to osKernelInitialize() */ +@@ -81,6 +97,12 @@ + #define FLAGS_MAIN_CDC_EVENT (1 << 11) + // Used by msd when flashing a new binary + #define FLAGS_LED_BLINK_30MS (1 << 6) ++#ifdef HISPARK_TRACE ++#define FLAGS_MAIN_450MS (1 << 7) ++#define FLAGS_MAIN_1200MS (1 << 8) ++#define FLAGS_MAIN_LOOP (1 << 31) ++#define FLAGS_MAIN_60MS (1 << 12) ++#endif + + // Timing constants (in 90mS ticks) + // USB busy time (~3 sec) +@@ -110,26 +132,34 @@ + #define MSC_LED_DEF GPIO_LED_OFF + #endif + ++#ifdef HISPARK_TRACE ++#define TICK_30MS (30) ++#define TICK_60MS (60) ++#define TICK_90MS (90) ++#define TICK_450MS (450) ++#define TICK_1200MS (1200) ++#endif ++ + // Reference to our main task + osThreadId_t main_task_id; + #ifndef USE_LEGACY_CMSIS_RTOS + static uint32_t s_main_thread_cb[WORDS(sizeof(osRtxThread_t))]; + static uint64_t s_main_task_stack[MAIN_TASK_STACK / sizeof(uint64_t)]; + static const osThreadAttr_t k_main_thread_attr = { +- .name = "main", +- .cb_mem = s_main_thread_cb, +- .cb_size = sizeof(s_main_thread_cb), +- .stack_mem = s_main_task_stack, +- .stack_size = sizeof(s_main_task_stack), +- .priority = MAIN_TASK_PRIORITY, +- }; ++ .name = "main", ++ .cb_mem = s_main_thread_cb, ++ .cb_size = sizeof(s_main_thread_cb), ++ .stack_mem = s_main_task_stack, ++ .stack_size = sizeof(s_main_task_stack), ++ .priority = MAIN_TASK_PRIORITY, ++}; + + static uint32_t s_timer_30ms_cb[WORDS(sizeof(osRtxTimer_t))]; + static const osTimerAttr_t k_timer_30ms_attr = { +- .name = "30ms", +- .cb_mem = s_timer_30ms_cb, +- .cb_size = sizeof(s_timer_30ms_cb), +- }; ++ .name = "30ms", ++ .cb_mem = s_timer_30ms_cb, ++ .cb_size = sizeof(s_timer_30ms_cb), ++}; + #endif + + // USB busy LED state; when TRUE the LED will flash once using 30mS clock tick +@@ -149,6 +179,12 @@ + + } + ++#ifdef HISPARK_TRACE ++__WEAK void DisplayPeriodProcHook(void) ++{ ++} ++#endif ++ + __WEAK void handle_reset_button(void) + { + // button state +@@ -171,12 +207,12 @@ + } + } + +-__WEAK void board_handle_powerdown() ++__WEAK void board_handle_powerdown(void) + { + // TODO: put the interface chip in sleep mode + } + +-__WEAK void board_custom_event() ++__WEAK void board_custom_event(void) + { + + } +@@ -263,10 +299,152 @@ + + extern void cdc_process_event(void); + ++#ifdef HISPARK_TRACE ++uint32_t GetTickDelta(uint32_t curTicks, uint32_t preTicks) ++{ ++ if (curTicks >= preTicks) { ++ return curTicks - preTicks; ++ } else { ++ return 0xFFFFFFFF - preTicks + curTicks + 1; ++ } ++} ++ ++void M4_Startup(void) ++{ ++ MSGQ_Init(); /* 消息队列初始化 */ ++ RemoteStart(); ++} ++ ++void KeyProcess(void) ++{ ++ uint8_t key_value = 0; ++ key_value = KeyScan(SHORT_KEY); ++ switch (key_value) { ++ case KEY_DOWN: ++ FrameMoveDown(); ++ break; ++ case KEY_UP: ++ FrameMoveUp(); ++ break; ++ case KEY_CONFIRM: ++ FrameItemSelect(); ++ break; ++ default: ++ break; ++ } ++} ++extern void DaplinkStatusSetTest(void); ++UART_Configuration my_UART_Config; ++ ++void my_uart_init(void) ++{ ++ my_UART_Config.Baudrate = 115200; /* Default baudrate = 115200 */ ++ my_UART_Config.DataBits = 0; ++ my_UART_Config.Parity = 0; ++ my_UART_Config.StopBits = 8; /* stop bits = 8 */ ++ my_UART_Config.FlowControl = UART_FLOW_CONTROL_NONE; ++ ++ uart_set_configuration(&my_UART_Config); ++} ++ ++static void UpdateUsbStatus(uint32_t *usbStateCnt, uint32_t *usbNoCfgCnt) ++{ ++ uint32_t usb_state_count = *usbStateCnt; ++ uint32_t usb_no_config_count = *usbNoCfgCnt; ++ // Update USB busy status ++#ifdef DRAG_N_DROP_SUPPORT ++ vfs_mngr_periodic(90); // FLAGS_MAIN_90MS ++#endif ++ DAP_StatusDetection(); ++ // Update USB connect status ++ switch (usb_state) { ++ case USB_DISCONNECTING: ++ usb_state = USB_DISCONNECTED; ++ // Disable board power before USB is disconnected. ++ gpio_set_board_power(false); ++ usbd_connect(0); ++ break; ++ ++ case USB_CONNECTING: ++ // Wait before connecting ++ if (DECZERO(usb_state_count) == 0) { ++ usbd_connect(1); ++ usb_state = USB_CHECK_CONNECTED; ++ // Reset connect timeout ++ usb_no_config_count = USB_CONFIGURE_TIMEOUT; ++ } ++ break; ++ ++ case USB_CHECK_CONNECTED: ++ if (usbd_configured()) { ++ // Let the HIC enable power to the target now that high power has been negotiated. ++ gpio_set_board_power(true); ++ ++ usb_state = USB_CONNECTED; ++ } else if (DECZERO(usb_no_config_count) == 0) { ++ // USB configuration timed out, which most likely indicates that the HIC is ++ // powered by a USB wall wart or similar power source. Go ahead and enable ++ // board power. ++ gpio_set_board_power(true); ++ usb_state = USB_DISCONNECTED; ++ } ++ ++ break; ++ ++ case USB_CONNECTED: ++ case USB_DISCONNECTED: ++ if (usbd_configured()) { ++ usb_state = USB_CONNECTED; ++ } else { ++ usb_state = USB_DISCONNECTED; ++ usb_state_count = USB_CONNECT_DELAY; ++ usb_no_config_count = USB_CONFIGURE_TIMEOUT; ++ } ++ default: ++ break; ++ } ++ ++ *usbStateCnt = usb_state_count; ++ *usbNoCfgCnt = usb_no_config_count; ++} ++ ++#ifdef PBON_BUTTON ++static void PbonPressProcess(uint8_t *powerOn) ++{ ++ // handle PBON pressed ++ if (gpio_get_pbon_btn()) { ++ if (*powerOn) { ++ // Loop till PBON is pressed ++ while (gpio_get_pbon_btn()) { ++ ; ++ } ++ // Power button released when target was running ++ target_set_state(SHUTDOWN); ++ *powerOn = 0; ++ } else { ++ // Loop till PBON is pressed ++ while (gpio_get_pbon_btn()) { ++ ; ++ } ++ // Power button released when target was already powered off ++ target_set_state(POWER_ON); ++ *powerOn = 1; ++ } ++ } ++} ++#endif ++#endif ++ + void main_task(void * arg) + { + // State processing + uint16_t flags = 0; ++#ifdef HISPARK_TRACE ++ uint32_t preTicks; ++ uint32_t curTicks; ++ uint32_t delta; ++ uint32_t times = 0; ++#endif + // LED + gpio_led_state_t hid_led_value = HID_LED_DEF; + gpio_led_state_t cdc_led_value = CDC_LED_DEF; +@@ -287,6 +465,18 @@ + #endif + // leds + gpio_init(); ++ ++#ifdef HISPARK_TRACE ++// NOTE!!!!! if use debug, CDC can't be used! ++#if (DBG_PRINTF_USE == DBG_USE_CUSTOM_PRINTF) ++ uart_initialize(); ++ my_uart_init(); ++#endif ++ ++ DBG_PRINTF("\r\nDaplink\r\n"); ++ M4_Startup(); ++ gpio_set_daplink_run(GPIO_LED_ON); ++#endif + // Turn to LED default settings + gpio_set_hid_led(hid_led_value); + gpio_set_cdc_led(cdc_led_value); +@@ -302,16 +492,17 @@ + g_board_info.prerun_board_config(); + } + +- //initialize the family ++ // initialize the family + init_family(); + + if (g_target_family && g_target_family->prerun_target_config) { + g_target_family->prerun_target_config(); + } + +- //setup some flags ++ // setup some flags + if (g_board_info.flags & kEnableUnderResetConnect) { + swd_set_reset_connect(CONNECT_UNDER_RESET); ++ jtag_set_reset_connect(CONNECT_UNDER_RESET); + } + if (g_board_info.flags & kEnablePageErase) { + #ifdef DRAG_N_DROP_SUPPORT +@@ -333,24 +524,53 @@ + usb_state_count = USB_CONNECT_DELAY; + + // Start timer tasks +-#ifndef USE_LEGACY_CMSIS_RTOS +- osTimerId_t tmr_id = osTimerNew(timer_task_30mS, osTimerPeriodic, NULL, &k_timer_30ms_attr); +-#else +- osTimerId_t tmr_id = osTimerNew(timer_task_30mS, osTimerPeriodic, NULL, NULL); +-#endif +- osTimerStart(tmr_id, 3); ++ preTicks = HAL_GetTick(); ++ OfflineSysConfigInit(); ++ OfflineDownLoadInit(); ++ TargetLibInit(); ++ FactoryInit(); ++ DisplayInit(); ++ + while (1) { +- flags = osThreadFlagsWait(FLAGS_MAIN_RESET // Put target in reset state +- | FLAGS_MAIN_90MS // 90mS tick +- | FLAGS_MAIN_30MS // 30mS tick +- | FLAGS_MAIN_POWERDOWN // Power down interface +- | FLAGS_MAIN_DISABLEDEBUG // Disable target debug +- | FLAGS_MAIN_PROC_USB // process usb events +- | FLAGS_MAIN_CDC_EVENT // cdc event +- | FLAGS_BOARD_EVENT // custom board event +- , osFlagsWaitAny +- , osWaitForever); ++ osThreadFlagsSet(main_task_id, FLAGS_MAIN_LOOP); ++ flags = osThreadFlagsWait(FLAGS_MAIN_RESET // Put target in reset state ++ | FLAGS_MAIN_90MS // 90mS tick ++ | FLAGS_MAIN_60MS // 60mS tick ++ | FLAGS_MAIN_1200MS ++ | FLAGS_MAIN_450MS ++ | FLAGS_MAIN_30MS // 30mS tick ++ | FLAGS_MAIN_POWERDOWN // Power down interface ++ | FLAGS_MAIN_DISABLEDEBUG // Disable target debug ++ | FLAGS_MAIN_PROC_USB // process usb events ++ | FLAGS_MAIN_CDC_EVENT // cdc event ++ | FLAGS_BOARD_EVENT // custom board event ++ | FLAGS_MAIN_LOOP, ++ osFlagsWaitAny, ++ osWaitForever); ++ ++ curTicks = HAL_GetTick(); ++ delta = GetTickDelta(curTicks, preTicks); ++ if (delta >= TICK_30MS) { ++ osThreadFlagsSet(main_task_id, FLAGS_MAIN_30MS); ++ times++; ++ if ((times % (TICK_60MS / TICK_30MS)) == 0) { ++ osThreadFlagsSet(main_task_id, FLAGS_MAIN_60MS); ++ } ++ if ((times & (TICK_90MS / TICK_30MS)) == 0) { ++ osThreadFlagsSet(main_task_id, FLAGS_MAIN_90MS); ++ } ++ if ((times % (TICK_450MS / TICK_30MS)) == 0) { ++ osThreadFlagsSet(main_task_id, FLAGS_MAIN_450MS); ++ } ++ if ((times % (TICK_1200MS / TICK_30MS)) == 0) { ++ osThreadFlagsSet(main_task_id, FLAGS_MAIN_1200MS); ++ } ++ preTicks = curTicks; ++ } + ++ if (flags == FLAGS_MAIN_LOOP) { ++ continue; ++ } + if (flags & FLAGS_MAIN_PROC_USB) { + if (usb_test_mode) { + // When in USB test mode Insert a delay to +@@ -379,109 +599,44 @@ + board_handle_powerdown(); + } + +- if (flags & FLAGS_MAIN_DISABLEDEBUG) { +- // Disable debug +- target_set_state(NO_DEBUG); +- } +- ++#if (DBG_PRINTF_USE == DBG_USE_NO_PRINTF) + if (flags & FLAGS_MAIN_CDC_EVENT) { + cdc_process_event(); + } +- ++#endif + if (flags & FLAGS_BOARD_EVENT) { + board_custom_event(); + } + +- if (flags & FLAGS_MAIN_90MS) { +- // Update USB busy status +-#ifdef DRAG_N_DROP_SUPPORT +- vfs_mngr_periodic(90); // FLAGS_MAIN_90MS +-#endif +- // Update USB connect status +- switch (usb_state) { +- case USB_DISCONNECTING: +- usb_state = USB_DISCONNECTED; +- // Disable board power before USB is disconnected. +- gpio_set_board_power(false); +- usbd_connect(0); +- break; +- +- case USB_CONNECTING: +- // Wait before connecting +- if (DECZERO(usb_state_count) == 0) { +- usbd_connect(1); +- usb_state = USB_CHECK_CONNECTED; +- // Reset connect timeout +- usb_no_config_count = USB_CONFIGURE_TIMEOUT; +- } +- +- break; +- +- case USB_CHECK_CONNECTED: +- if (usbd_configured()) { +- // Let the HIC enable power to the target now that high power has been negotiated. +- gpio_set_board_power(true); +- +- usb_state = USB_CONNECTED; +- } +- else if (DECZERO(usb_no_config_count) == 0) { +- // USB configuration timed out, which most likely indicates that the HIC is +- // powered by a USB wall wart or similar power source. Go ahead and enable +- // board power. +- gpio_set_board_power(true); +- usb_state = USB_DISCONNECTED; +- } +- +- break; +- +- case USB_CONNECTED: +- case USB_DISCONNECTED: +- if (usbd_configured()) { +- usb_state = USB_CONNECTED; +- } +- else { +- usb_state = USB_DISCONNECTED; +- usb_state_count = USB_CONNECT_DELAY; +- usb_no_config_count = USB_CONFIGURE_TIMEOUT; +- } +- default: +- break; +- } ++ if (flags & FLAGS_MAIN_450MS) { ++ DisplayPeriodProcHook(); + } + ++ if (flags & FLAGS_MAIN_1200MS) { ++ UpdateDapStatistics(); ++ } ++ if (flags & FLAGS_MAIN_90MS) { ++ UpdateUsbStatus(&usb_state_count, &usb_no_config_count); ++ } ++ if (flags & FLAGS_MAIN_60MS) { ++ OfflineDownLoadHandler(); ++ } + // 30mS tick used for flashing LED when USB is busy + if (flags & FLAGS_MAIN_30MS) { +- ++ if (!IsOfflineDownLoad()) { ++ KeyProcess(); ++ } + handle_reset_button(); + + #ifdef PBON_BUTTON + // handle PBON pressed +- if(gpio_get_pbon_btn()) +- { +- if(power_on) +- { +- // Loop till PBON is pressed +- while (gpio_get_pbon_btn()) {;} +- // Power button released when target was running +- target_set_state(SHUTDOWN); +- power_on = 0; +- } +- else +- { +- // Loop till PBON is pressed +- while (gpio_get_pbon_btn()) {;} +- // Power button released when target was already powered off +- target_set_state(POWER_ON); +- power_on = 1; +- } +- } ++ PbonPressProcess(&power_on); + #endif + // 30ms event hook function + board_30ms_hook(); + + // DAP LED + if (hid_led_usb_activity) { +- + if ((hid_led_state == MAIN_LED_FLASH) || (hid_led_state == MAIN_LED_FLASH_PERMANENT)) { + // Toggle LED value + hid_led_value = GPIO_LED_ON == hid_led_value ? GPIO_LED_OFF : GPIO_LED_ON; +@@ -492,7 +647,7 @@ + hid_led_state = MAIN_LED_DEF; + } + } else { +- //LED next state is MAIN_LED_DEF ++ // LED next state is MAIN_LED_DEF + hid_led_value = HID_LED_DEF; + hid_led_usb_activity = 0; + } +@@ -503,7 +658,6 @@ + + // MSD LED + if (msc_led_usb_activity) { +- + if ((msc_led_state == MAIN_LED_FLASH) || (msc_led_state == MAIN_LED_FLASH_PERMANENT)) { + // Toggle LED value + msc_led_value = GPIO_LED_ON == msc_led_value ? GPIO_LED_OFF : GPIO_LED_ON; +@@ -514,7 +668,7 @@ + msc_led_state = MAIN_LED_DEF; + } + } else { +- //LED next state is MAIN_LED_DEF ++ // LED next state is MAIN_LED_DEF + msc_led_value = MSC_LED_DEF; + msc_led_usb_activity = 0; + } +@@ -525,8 +679,7 @@ + + // CDC LED + if (cdc_led_usb_activity) { +- +- if ((cdc_led_state == MAIN_LED_FLASH) || (cdc_led_state == MAIN_LED_FLASH_PERMANENT)){ ++ if ((cdc_led_state == MAIN_LED_FLASH) || (cdc_led_state == MAIN_LED_FLASH_PERMANENT)) { + // Toggle LED value + cdc_led_value = GPIO_LED_ON == cdc_led_value ? GPIO_LED_OFF : GPIO_LED_ON; + +@@ -535,8 +688,8 @@ + cdc_led_usb_activity = 0; + cdc_led_state = MAIN_LED_DEF; + } +- }else{ +- //LED next state is MAIN_LED_DEF ++ } else { ++ // LED next state is MAIN_LED_DEF + cdc_led_value = CDC_LED_DEF; + cdc_led_usb_activity = 0; + } +@@ -553,7 +706,9 @@ + // Explicitly set the vector table since the bootloader might not set + // it to what we expect. + #if DAPLINK_ROM_BL_SIZE > 0 +- SCB->VTOR = SCB_VTOR_TBLOFF_Msk & DAPLINK_ROM_IF_START; ++ // remove start by xuyong, SCB not found ++ // SCB->VTOR = SCB_VTOR_TBLOFF_Msk & DAPLINK_ROM_IF_START; ++ // remove end + #endif + // initialize vendor sdk + sdk_init(); +@@ -572,5 +727,7 @@ + osKernelStart(); + + // Should never reach here! +- for (;;) {} ++ for (;;) { ++ ; ++ } + } +diff -uNr old/CA7/source/daplink/interface/swd_host.c new/CA7/source/daplink/interface/swd_host.c +--- old/CA7/source/daplink/interface/swd_host.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/interface/swd_host.c 2024-12-30 10:11:39.390510672 +0800 +@@ -25,11 +25,58 @@ + #include "device.h" + #include "cmsis_os2.h" + #include "target_config.h" ++#if defined(HISPARK_TRACE) ++#include "swd_host.h" ++#include "debug_cm.h" ++#include "offline_sys_config.h" ++#endif + #include "DAP_config.h" + #include "DAP.h" + #include "target_family.h" + #include "swd_host.h" + ++#if defined(HISPARK_TRACE) ++// riscv DM register ++/* RISC_V Debug 模块相关的寄存器定义, ++ 详细的寄存器说明请查阅RISC-V官方文档《RISC-V Debug Specification》 */ ++#define RISCV_DM_ADDRESS_SHIFT 0x2 ++#define MATCH_CSRRW 0x1073 ++#define MATCH_CSRRS 0x2073 ++#define MATCH_CSRRC 0x3073 ++ ++#define RISCV_DM_GPRS_BASE_ADDR 0x1000 ++ ++#define RISCV_DM_DATA0 0x04 ++#define RISCV_DM_DATA11 0x0f ++#define RISCV_DM_HARTINFO 0x12 ++#define RISCV_DM_PROGBUF0 0x20 ++#define RISCV_DM_PROGBUF1 0x21 ++ ++#define RISCV_DM_DMCONTROL 0x10 ++#define RISCV_DM_DMCONTROL_HALTREQ_SHIFT 31 ++#define RISCV_DM_DMCONTROL_RESUMEREQ_SHIFT 30 ++ ++#define RISCV_DM_DMSTATUS 0x11 ++#define RISCV_DM_DMSTATUS_ALLHALTED_SHIFT 9 ++ ++#define RISCV_DM_ABSTRACTCS 0x16 ++#define RISCV_DM_ABSTRACTCS_BUSY_SHIFT 12 ++#define RISCV_DM_ABSTRACTCS_CMDERR_SHIFT 8 ++ ++#define RISCV_DM_COMMAND 0x17 ++#define RISCV_DM_COMMAND_CMDTYPE_SHIFT 24 ++#define RISCV_DM_COMMAND_AARSIZE_SHIFT 20 ++#define RISCV_DM_COMMAND_POSTEXEC_SHIFT 18 ++#define RISCV_DM_COMMAND_TRANSFER_SHIFT 17 ++#define RISCV_DM_COMMAND_WRITE_SHIFT 16 ++ ++#define RISCV_DM_DCSR 0x7B0 ++#define RISCV_DM_DCSR_EBREAK_SHIFT 15 ++ ++#define RISCV_DM_DPC 0x7B1 ++#define RISCV_DM_EBREAK_CMD 0x100073 ++#endif ++ + // Default NVIC and Core debug base addresses + // TODO: Read these addresses from ROM. + #define NVIC_Addr (0xe000e000) +@@ -43,8 +90,13 @@ + #define DHCSR 0xE000EDF0 + #define REGWnR (1 << 16) + ++#if defined(HISPARK_TRACE) ++#define MAX_SWD_RETRY 10//10 ++#define MAX_TIMEOUT 10000 // Timeout for syscalls on target ++#else + #define MAX_SWD_RETRY 100//10 + #define MAX_TIMEOUT 1000000 // Timeout for syscalls on target ++#endif + + // Use the CMSIS-Core definition if available. + #if !defined(SCB_AIRCR_PRIGROUP_Pos) +@@ -58,15 +110,32 @@ + } DAP_STATE; + + typedef struct { ++#if defined(HISPARK_TRACE) ++ uint32_t r[33]; ++#else + uint32_t r[16]; + uint32_t xpsr; ++#endif + } DEBUG_STATE; + +-static SWD_CONNECT_TYPE reset_connect = CONNECT_NORMAL; ++static JTAG_SWD_CONNECT_TYPE reset_connect = CONNECT_NORMAL; + + static DAP_STATE dap_state; + static uint32_t soft_reset = SYSRESETREQ; + ++#if defined(HISPARK_TRACE) ++static uint8_t swd_halted(void); ++static uint8_t swd_wait_until_halted(void); ++static uint32_t swd_csrrw(unsigned int rd, unsigned int rs, unsigned int csr); ++static uint32_t swd_csrrs(unsigned int rd, unsigned int rs, unsigned int csr); ++static uint32_t swd_csrrc(unsigned int rd, unsigned int rs, unsigned int csr); ++static uint8_t swd_set_pc(uint32_t pc_addr); ++static uint8_t swd_set_ebreak_mode(uint8_t mode); ++#endif ++ ++#if defined(HISPARK_TRACE) ++ ++#else + static uint32_t swd_get_apsel(uint32_t adr) + { + uint32_t apsel = target_get_apsel(); +@@ -75,8 +144,8 @@ + else + return apsel; + } +- +-void swd_set_reset_connect(SWD_CONNECT_TYPE type) ++#endif /* #if defined(HISPARK_TRACE) */ ++void swd_set_reset_connect(JTAG_SWD_CONNECT_TYPE type) + { + reset_connect = type; + } +@@ -153,7 +222,11 @@ + *val |= (tmp << 8); + tmp = tmp_out[0]; + *val |= (tmp << 0); ++#if defined(HISPARK_TRACE) ++ return ack; ++#else + return (ack == 0x01); ++#endif + } + + // Write debug port register +@@ -164,26 +237,39 @@ + uint8_t ack; + + //check if the right bank is already selected ++#ifndef HISPARK_TRACE + if ((adr == DP_SELECT) && (dap_state.select == val)) { + return 1; + } +- ++#endif + req = SWD_REG_DP | SWD_REG_W | SWD_REG_ADR(adr); + int2array(data, val, 4); + ack = swd_transfer_retry(req, (uint32_t *)data); + if ((ack == DAP_TRANSFER_OK) && (adr == DP_SELECT)) { + dap_state.select = val; + } ++#if defined(HISPARK_TRACE) ++ return ack; ++#else + return (ack == 0x01); ++#endif + } + + // Read access port register. ++#ifdef HISPARK_TRACE ++uint8_t swd_read_ap(uint32_t adr, uint32_t *val, uint32_t apsel) ++#else + uint8_t swd_read_ap(uint32_t adr, uint32_t *val) ++#endif + { + uint8_t tmp_in, ack; + uint8_t tmp_out[4]; + uint32_t tmp; ++#ifdef HISPARK_TRACE ++ ++#else + uint32_t apsel = swd_get_apsel(adr); ++#endif + uint32_t bank_sel = adr & APBANKSEL; + + if (!swd_write_dp(DP_SELECT, apsel | bank_sel)) { +@@ -192,7 +278,6 @@ + + tmp_in = SWD_REG_AP | SWD_REG_R | SWD_REG_ADR(adr); + // first dummy read +- swd_transfer_retry(tmp_in, (uint32_t *)tmp_out); + ack = swd_transfer_retry(tmp_in, (uint32_t *)tmp_out); + *val = 0; + tmp = tmp_out[3]; +@@ -203,17 +288,28 @@ + *val |= (tmp << 8); + tmp = tmp_out[0]; + *val |= (tmp << 0); ++#ifdef HISPARK_TRACE ++ return ack; ++#else + return (ack == 0x01); ++#endif + } + + // Write access port register ++#ifdef HISPARK_TRACE ++uint8_t swd_write_ap(uint32_t adr, uint32_t val,uint32_t apsel) ++#else + uint8_t swd_write_ap(uint32_t adr, uint32_t val) ++#endif + { + uint8_t data[4]; + uint8_t req, ack; ++#ifdef HISPARK_TRACE ++ ++#else + uint32_t apsel = swd_get_apsel(adr); ++#endif + uint32_t bank_sel = adr & APBANKSEL; +- + if (!swd_write_dp(DP_SELECT, apsel | bank_sel)) { + return 0; + } +@@ -240,7 +336,11 @@ + + req = SWD_REG_DP | SWD_REG_R | SWD_REG_ADR(DP_RDBUFF); + ack = swd_transfer_retry(req, NULL); ++#ifdef HISPARK_TRACE ++ return ack; ++#else + return (ack == 0x01); ++#endif + } + + +@@ -259,7 +359,12 @@ + size_in_words = size / 4; + + // CSW register ++ //AHB 地址递增写 ++#ifdef HISPARK_TRACE ++ if (!swd_write_ap(AP_CSW, 0x12, 0x1000000)) { ++#else + if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE32)) { ++#endif + return 0; + } + +@@ -285,7 +390,11 @@ + // dummy read + req = SWD_REG_DP | SWD_REG_R | SWD_REG_ADR(DP_RDBUFF); + ack = swd_transfer_retry(req, NULL); ++#ifdef HISPARK_TRACE ++ return ack; ++#else + return (ack == 0x01); ++#endif + } + + // Read 32-bit word aligned values from target memory using address auto-increment. +@@ -301,8 +410,12 @@ + } + + size_in_words = size / 4; +- ++#ifdef HISPARK_TRACE ++ //AHB地址递增读 ++ if (!swd_write_ap(AP_CSW, 0x12, 0x1000000)) { ++#else + if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE32)) { ++#endif + return 0; + } + +@@ -333,7 +446,11 @@ + // read last word + req = SWD_REG_DP | SWD_REG_R | SWD_REG_ADR(DP_RDBUFF); + ack = swd_transfer_retry(req, (uint32_t *)data); ++#ifdef HISPARK_TRACE ++ return ack; ++#else + return (ack == 0x01); ++#endif + } + + // Read target memory. +@@ -370,7 +487,11 @@ + *val |= (tmp << 8); + tmp = tmp_out[0]; + *val |= (tmp << 0); ++#ifdef HISPARK_TRACE ++ return ack; ++#else + return (ack == 0x01); ++#endif + } + + // Write target memory. +@@ -403,7 +524,11 @@ + // Read 32-bit word from target memory. + uint8_t swd_read_word(uint32_t addr, uint32_t *val) + { ++#ifdef HISPARK_TRACE ++ if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE32, 0x000000)) { ++#else + if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE32)) { ++#endif + return 0; + } + +@@ -417,7 +542,11 @@ + // Write 32-bit word to target memory. + uint8_t swd_write_word(uint32_t addr, uint32_t val) + { ++#ifdef HISPARK_TRACE ++ if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE32, 0x000000)) { ++#else + if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE32)) { ++#endif + return 0; + } + +@@ -432,8 +561,11 @@ + uint8_t swd_read_byte(uint32_t addr, uint8_t *val) + { + uint32_t tmp; +- ++#ifdef HISPARK_TRACE ++ if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE8, 0x1000000)) { ++#else + if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE8)) { ++#endif + return 0; + } + +@@ -449,8 +581,11 @@ + uint8_t swd_write_byte(uint32_t addr, uint8_t val) + { + uint32_t tmp; +- ++#ifdef HISPARK_TRACE ++ if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE8, 0x1000000)) { ++#else + if (!swd_write_ap(AP_CSW, CSW_VALUE | CSW_SIZE8)) { ++#endif + return 0; + } + +@@ -562,6 +697,66 @@ + } + + // Execute system call. ++#ifdef HISPARK_TRACE ++/* RISC-V */ ++static uint8_t swd_write_debug_state(DEBUG_STATE *state) ++{ ++ uint32_t i, status; ++ uint32_t temReg; ++ uint32_t try = 5; ++ ++ if (!swd_write_dp(DP_SELECT, 0)) { ++ return 0; ++ } ++ ++ /* halt hart */ ++ for (i = 0; i < try;) { ++ i++; ++ if (swd_halted()) { ++ break; ++ } ++ if (i == try) { ++ return 0; ++ } ++ } ++ ++ if (!swd_set_pc(state->r[32])) { ++ return 0; ++ } ++ ++ // R10, R11, R12, R13 ++ for (i = 10; i < 14; i++) { ++ temReg = i + RISCV_DM_GPRS_BASE_ADDR; ++ if (!swd_write_core_register(temReg, state->r[i])) { ++ return 0; ++ } ++ } ++ // x1, x2, x3 ++ for (i = 1; i < 4; i++) { ++ temReg = i + RISCV_DM_GPRS_BASE_ADDR; ++ if (!swd_write_core_register(temReg, state->r[i])) { ++ return 0; ++ } ++ } ++ ++ /* resume hart */ ++ if (!swd_write_word(RISCV_DM_DMCONTROL << RISCV_DM_ADDRESS_SHIFT, 1 << RISCV_DM_DMCONTROL_RESUMEREQ_SHIFT | 0x1)) { ++ return 0; ++ } ++ ++ // check status ++ if (!swd_read_dp(DP_CTRL_STAT, &status)) { ++ return 0; ++ } ++ ++ if (status & (STICKYERR | WDATAERR)) { ++ return 0; ++ } ++ ++ return 1; ++} ++#else /* #ifdef HISPARK_TRACE */ ++/* ARM */ + static uint8_t swd_write_debug_state(DEBUG_STATE *state) + { + uint32_t i, status; +@@ -613,7 +808,49 @@ + + return 1; + } ++#endif /* #ifdef HISPARK_TRACE */ + ++#ifdef HISPARK_TRACE ++uint8_t swd_read_core_register(uint32_t n, uint32_t *val) ++{ ++ int i = 0, timeout = 100; ++ uint32_t tempCommand = 0; ++ if (!swd_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8)) { ++ return 0; ++ } ++ tempCommand = (0x2 << RISCV_DM_COMMAND_AARSIZE_SHIFT) | ++ (0x1 << RISCV_DM_COMMAND_TRANSFER_SHIFT) | n; ++ if (!swd_write_word(RISCV_DM_COMMAND << RISCV_DM_ADDRESS_SHIFT, tempCommand)) { ++ return 0; ++ } ++ ++ // wait for abstractcs busy is 0 ++ for (i = 0; i < timeout; i++) { ++ if (!swd_read_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT, val)) { ++ return 0; ++ } ++ ++ if ((*val >> RISCV_DM_ABSTRACTCS_BUSY_SHIFT & 0x1) == 0) { ++ if ((*val >> RISCV_DM_ABSTRACTCS_CMDERR_SHIFT & 0x7) == 0) { ++ break; ++ } else { ++ swd_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8); ++ return 0; ++ } ++ } ++ } ++ ++ if (i == timeout) { ++ return 0; ++ } ++ ++ if (!swd_read_word(RISCV_DM_DATA0 << RISCV_DM_ADDRESS_SHIFT, val)) { ++ return 0; ++ } ++ ++ return 1; ++} ++#else /* #ifdef HISPARK_TRACE */ + uint8_t swd_read_core_register(uint32_t n, uint32_t *val) + { + int i = 0, timeout = 100; +@@ -643,7 +880,45 @@ + + return 1; + } ++#endif /* #ifdef HISPARK_TRACE */ + ++#ifdef HISPARK_TRACE ++uint8_t swd_write_core_register(uint32_t n, uint32_t val) ++{ ++ int i = 0, timeout = 100; ++ uint32_t tempCommand = 0; ++ if (!swd_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8)) { ++ return 0; ++ } ++ if (!swd_write_word(RISCV_DM_DATA0 << RISCV_DM_ADDRESS_SHIFT, val)) { ++ return 0; ++ } ++ tempCommand = (0x2 << RISCV_DM_COMMAND_AARSIZE_SHIFT) | ++ (0x1 << RISCV_DM_COMMAND_TRANSFER_SHIFT) | ++ (0x1 << RISCV_DM_COMMAND_WRITE_SHIFT) | n; ++ ++ if (!swd_write_word(RISCV_DM_COMMAND << RISCV_DM_ADDRESS_SHIFT, tempCommand)) { ++ return 0; ++ } ++ ++ // wait for abstractcs busy is 0 ++ for (i = 0; i < timeout; i++) { ++ if (!swd_read_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT, &val)) { ++ return 0; ++ } ++ ++ if ((val >> RISCV_DM_ABSTRACTCS_BUSY_SHIFT & 0x1) == 0) { ++ if ((val >> RISCV_DM_ABSTRACTCS_CMDERR_SHIFT & 0x7) == 0) { ++ return 1; ++ } else { ++ swd_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8); ++ return 0; ++ } ++ } ++ } ++ return 0; ++} ++#else /* #ifdef HISPARK_TRACE */ + uint8_t swd_write_core_register(uint32_t n, uint32_t val) + { + int i = 0, timeout = 100; +@@ -669,6 +944,7 @@ + + return 0; + } ++#endif /* #ifdef HISPARK_TRACE */ + + static uint8_t swd_wait_until_halted(void) + { +@@ -676,6 +952,15 @@ + uint32_t val, i, timeout = MAX_TIMEOUT; + + for (i = 0; i < timeout; i++) { ++#ifdef HISPARK_TRACE ++ if (!swd_read_word(RISCV_DM_DMSTATUS << RISCV_DM_ADDRESS_SHIFT, &val)) { ++ return 0; ++ } ++ ++ if (val & (0x1 << RISCV_DM_DMSTATUS_ALLHALTED_SHIFT)) { ++ return 1; ++ } ++#else + if (!swd_read_word(DBG_HCSR, &val)) { + return 0; + } +@@ -683,11 +968,240 @@ + if (val & S_HALT) { + return 1; + } ++#endif ++ } ++ ++ return 0; ++} ++ ++#ifdef HISPARK_TRACE ++static uint32_t swd_csrrw(unsigned int rd, unsigned int rs, unsigned int csr) ++{ ++ return (csr << 20) | (rs << 15) | (rd << 7) | MATCH_CSRRW; ++} ++ ++static uint32_t swd_csrrs(unsigned int rd, unsigned int rs, unsigned int csr) ++{ ++ return (csr << 20) | (rs << 15) | (rd << 7) | MATCH_CSRRS; ++} ++ ++static uint32_t swd_csrrc(unsigned int rd, unsigned int rs, unsigned int csr) ++{ ++ return (csr << 20) | (rs << 15) | (rd << 7) | MATCH_CSRRC; ++} ++ ++static uint8_t swd_halted(void) ++{ ++ /* halt hart */ ++ if (!swd_write_word(RISCV_DM_DMCONTROL << RISCV_DM_ADDRESS_SHIFT, 1 << RISCV_DM_DMCONTROL_HALTREQ_SHIFT | 0x1)) { ++ return 0; ++ } ++ if (!swd_wait_until_halted()) { ++ return 0; ++ } ++ return 1; ++} ++ ++static uint8_t swd_set_pc(uint32_t pc_addr) ++{ ++ uint32_t tempCommand; ++ uint32_t i; ++ uint32_t val; ++ uint32_t timeout = 100; ++ uint32_t temReg; ++ uint32_t s0; ++ ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!swd_read_core_register(temReg, &s0)) { ++ return 0; ++ } ++ ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!swd_write_core_register(temReg, pc_addr)) { ++ goto SET_PC_ERR; ++ } ++ ++ if (!swd_write_word(RISCV_DM_PROGBUF0 << RISCV_DM_ADDRESS_SHIFT, swd_csrrw(0,8,RISCV_DM_DPC))) { ++ goto SET_PC_ERR; ++ } ++ ++ if (!swd_write_word(RISCV_DM_PROGBUF1 << RISCV_DM_ADDRESS_SHIFT,RISCV_DM_EBREAK_CMD)) { ++ goto SET_PC_ERR; ++ } ++ ++ if (!swd_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8)) { ++ goto SET_PC_ERR; ++ } ++ tempCommand = (0x2 << RISCV_DM_COMMAND_AARSIZE_SHIFT) | ++ (0x1 << RISCV_DM_COMMAND_POSTEXEC_SHIFT)| 0x1000; ++ ++ if (!swd_write_word(RISCV_DM_COMMAND << RISCV_DM_ADDRESS_SHIFT, tempCommand)) { ++ goto SET_PC_ERR; ++ } ++ ++ // wait for abstractcs busy is 0 ++ for (i = 0; i < timeout; i++) { ++ if (!swd_read_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT, &val)) { ++ goto SET_PC_ERR; ++ } ++ ++ if ((val >> RISCV_DM_ABSTRACTCS_BUSY_SHIFT & 0x1) == 0) { ++ if ((val >> RISCV_DM_ABSTRACTCS_CMDERR_SHIFT & 0x7) == 0) { ++ goto SET_PC_SUCCESS; ++ } else { ++ swd_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8); ++ goto SET_PC_ERR; ++ } ++ } ++ } ++ ++SET_PC_ERR: ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ swd_write_core_register(temReg, s0); ++ return 0; ++ ++SET_PC_SUCCESS: ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!swd_write_core_register(temReg, s0)) { ++ return 0; ++ } else { ++ return 1; ++ } ++} ++ ++static uint8_t swd_set_ebreak_mode(uint8_t mode) ++{ ++ uint32_t tempCommand; ++ uint32_t i; ++ uint32_t val; ++ uint32_t timeout = 100; ++ uint32_t temReg; ++ uint32_t s0; ++ uint32_t try = 5; ++ ++ /* halt hart */ ++ for (i = 0; i < try;) { ++ i++; ++ if (swd_halted()) { ++ break; ++ } ++ if (i == try) { ++ return 0; ++ } ++ } ++ ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!swd_read_core_register(temReg, &s0)) { ++ return 0; ++ } ++ if (mode == 0) { ++ val = ~(0x1 << RISCV_DM_DCSR_EBREAK_SHIFT); ++ } else { ++ val = (0x1 << RISCV_DM_DCSR_EBREAK_SHIFT); ++ } ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!swd_write_core_register(temReg, val)) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ ++ if (mode == 0) { ++ if (!swd_write_word(RISCV_DM_PROGBUF0 << RISCV_DM_ADDRESS_SHIFT, swd_csrrc(0,8,RISCV_DM_DCSR))) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ } else { ++ if (!swd_write_word(RISCV_DM_PROGBUF0 << RISCV_DM_ADDRESS_SHIFT, swd_csrrs(0,8,RISCV_DM_DCSR))) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ } ++ ++ if (!swd_write_word(RISCV_DM_PROGBUF1 << RISCV_DM_ADDRESS_SHIFT, RISCV_DM_EBREAK_CMD)) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ ++ if (!swd_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8)) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ tempCommand = (0x2 << RISCV_DM_COMMAND_AARSIZE_SHIFT) | ++ (0x1 << RISCV_DM_COMMAND_POSTEXEC_SHIFT)| 0x1000; ++ ++ if (!swd_write_word(RISCV_DM_COMMAND << RISCV_DM_ADDRESS_SHIFT, tempCommand)) { ++ goto SET_EBREAK_MODE_ERR; ++ } ++ ++ // wait for abstractcs busy is 0 ++ for (i = 0; i < timeout; i++) { ++ if (!swd_read_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT, &val)) { ++ goto SET_EBREAK_MODE_ERR;; ++ } ++ ++ if ((val >> RISCV_DM_ABSTRACTCS_BUSY_SHIFT & 0x1) == 0) { ++ if ((val >> RISCV_DM_ABSTRACTCS_CMDERR_SHIFT & 0x7) == 0) { ++ goto SET_EBREAK_MODE_SUCCESS; ++ } else { ++ swd_write_word(RISCV_DM_ABSTRACTCS << RISCV_DM_ADDRESS_SHIFT,0x7 << 8); ++ goto SET_EBREAK_MODE_ERR; ++ } ++ } + } + ++SET_EBREAK_MODE_ERR: ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ swd_write_core_register(temReg, s0); + return 0; ++ ++SET_EBREAK_MODE_SUCCESS: ++ temReg = 8 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!swd_write_core_register(temReg, s0)) { ++ return 0; ++ } else { ++ return 1; ++ } + } ++#endif /* #ifdef HISPARK_TRACE */ + ++#ifdef HISPARK_TRACE ++/* RISC-V */ ++uint8_t swd_flash_syscall_exec(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, flash_algo_return_t return_type) ++{ ++ uint32_t temReg; ++ volatile DEBUG_STATE state = {{0}}; ++ // Call flash algorithm function on target and wait for result. ++ state.r[10] = arg1; // R10: Argument 1 ++ state.r[11] = arg2; // R11: Argument 2 ++ state.r[12] = arg3; // R12: Argument 3 ++ state.r[13] = arg4; // R13: Argument 4 ++ state.r[3] = sysCallParam->static_base; // SB: Static Base ++ state.r[2] = sysCallParam->stack_pointer; // SP: Stack Pointer ++ state.r[1] = sysCallParam->breakpoint; // LR: Exit Point ++ state.r[32] = entry; // PC: Entry Point ++ ++ if (!swd_write_debug_state((DEBUG_STATE *)&state)) { ++ return 0; ++ } ++ if (!swd_wait_until_halted()) { ++ return 0; ++ } ++ temReg = 10 + RISCV_DM_GPRS_BASE_ADDR; ++ if (!swd_read_core_register(temReg, (uint32_t *)&state.r[10])) { ++ return 0; ++ } ++ ++ if ( return_type == FLASHALGO_RETURN_POINTER ) { ++ // Flash verify functions return pointer to byte following the buffer if successful. ++ if (state.r[10] != (arg1 + arg2)) { ++ return 0; ++ } ++ } else { ++ // Flash functions return 0 if successful. ++ if (state.r[10] != 0) { ++ return 0; ++ } ++ } ++ ++ return 1; ++} ++#else /* #ifdef HISPARK_TRACE */ ++/* ARM */ + uint8_t swd_flash_syscall_exec(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, flash_algo_return_t return_type) + { + DEBUG_STATE state = {{0}, 0}; +@@ -734,6 +1248,7 @@ + + return 1; + } ++#endif + + // SWD Reset + static uint8_t swd_reset(void) +@@ -802,6 +1317,7 @@ + uint8_t swd_init_debug(void) + { + uint32_t tmp = 0; ++ + int i = 0; + int timeout = 100; + // init dap state with fake values +@@ -882,7 +1398,12 @@ + do_abort = 1; + continue; + } +- ++#ifdef HISPARK_TRACE ++ if (!swd_set_ebreak_mode(1)) { ++ do_abort = 1; ++ continue; ++ } ++#endif + return 1; + + } while (--retries > 0); +@@ -1034,7 +1555,11 @@ + uint8_t swd_set_target_state_sw(target_state_t state) + { + uint32_t val; ++#ifdef HISPARK_TRACE ++ ++#else + int8_t ap_retries = 2; ++#endif + /* Calling swd_init prior to enterring RUN state causes operations to fail. */ + if (state != RUN) { + swd_init(); +@@ -1050,10 +1575,13 @@ + osDelay(2); + swd_set_target_reset(0); + osDelay(2); ++#ifdef HISPARK_TRACE + ++#else + if (!swd_init_debug()) { + return 0; + } ++#endif + + // Power down + // Per ADIv6 spec. Clear first CSYSPWRUPREQ followed by CDBGPWRUPREQ +@@ -1087,6 +1615,16 @@ + break; + + case RESET_PROGRAM: ++#ifdef HISPARK_TRACE ++ if (!swd_init_debug()) { ++ return 0; ++ } ++ swd_exec_soft_reset(); ++ if (!swd_init_debug()) { ++ return 0; ++ } ++ break; ++#else /* #ifdef HISPARK_TRACE */ + if (!swd_init_debug()) { + return 0; + } +@@ -1138,7 +1676,7 @@ + } + + break; +- ++#endif /* #ifdef HISPARK_TRACE */ + case NO_DEBUG: + if (!swd_write_word(DBG_HCSR, DBGKEY)) { + return 0; +@@ -1207,4 +1745,51 @@ + + return 1; + } ++ ++#ifdef HISPARK_TRACE ++void swd_exec_soft_reset(void) ++{ ++ uint32_t val; ++ if (!SysSoftResetFlagGet()) { ++ return; ++ } ++ swd_init_debug(); ++ /* Set (0x10100200) debug flag register */ ++ swd_write_dp(DP_SELECT, 0x1000000); ++ swd_write_ap(AP_CSW, 0x0000002, 0x1000000); ++ swd_read_dp(DP_RDBUFF,&val); ++ swd_write_dp(DP_SELECT, 0x1000000); ++ swd_write_ap(AP_TAR, 0x10100200, 0x1000000); ++ swd_write_ap(AP_DRW, 0xA5A5A5A5, 0x1000000); ++ ++ /* Unlock (0x10100044) configuration lock register */ ++ swd_write_dp(DP_SELECT, 0x1000000); ++ swd_write_ap(AP_CSW, 0x0000002, 0x1000000); ++ swd_read_dp(DP_RDBUFF,&val); ++ swd_write_dp(DP_SELECT, 0x1000000); ++ swd_write_ap(AP_TAR, 0x10100044, 0x1000000); ++ swd_write_ap(AP_DRW, 0xEA510000, 0x1000000); ++ ++ /* Set (0x1000001C) to HOSC (0x1000001C = 0x8) -- bit1~0: 0-HOSC, 1-XTAL, 2-PLL */ ++ swd_write_dp(DP_SELECT, 0x1000000); ++ swd_write_ap(AP_CSW, 0x0000002, 0x1000000); ++ swd_read_dp(DP_RDBUFF,&val); ++ swd_write_dp(DP_SELECT, 0x1000000); ++ swd_write_ap(AP_TAR, 0x1000001C, 0x1000000); ++ swd_write_ap(AP_DRW, 0x00000008, 0x1000000); ++ ++ /* Set (0x10100004) system reset register to reset system */ ++ swd_write_dp(DP_SELECT, 0x1000000); ++ swd_write_ap(AP_CSW, 0x0000002, 0x1000000); ++ swd_read_dp(DP_RDBUFF,&val); ++ swd_write_dp(DP_SELECT, 0x1000000); ++ swd_write_ap(AP_TAR, 0x10100004, 0x1000000); ++ swd_write_ap(AP_DRW, 0x00000001, 0x1000000); ++ ++ /* Add some clocks to ensure the last write operations takes effect with jlink */ ++ swd_read_dp(DP_RDBUFF,&val); ++ /* Wait until the reset is complete. */ ++ osDelay(300); ++} ++#endif /* #ifdef HISPARK_TRACE */ + #endif +diff -uNr old/CA7/source/daplink/interface/swd_host.h new/CA7/source/daplink/interface/swd_host.h +--- old/CA7/source/daplink/interface/swd_host.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/interface/swd_host.h 2023-06-09 15:38:35.689535300 +0800 +@@ -36,24 +36,19 @@ + extern "C" { + #endif + +-typedef enum { +- CONNECT_NORMAL, +- CONNECT_UNDER_RESET, +-} SWD_CONNECT_TYPE; +- +-typedef enum { +- FLASHALGO_RETURN_BOOL, +- FLASHALGO_RETURN_POINTER +-} flash_algo_return_t; +- + uint8_t swd_init(void); + uint8_t swd_off(void); + uint8_t swd_init_debug(void); + uint8_t swd_clear_errors(void); + uint8_t swd_read_dp(uint8_t adr, uint32_t *val); + uint8_t swd_write_dp(uint8_t adr, uint32_t val); ++#if defined(HISPARK_TRACE) ++uint8_t swd_read_ap(uint32_t adr, uint32_t *val,uint32_t apsel); ++uint8_t swd_write_ap(uint32_t adr, uint32_t val,uint32_t apsel); ++#else + uint8_t swd_read_ap(uint32_t adr, uint32_t *val); + uint8_t swd_write_ap(uint32_t adr, uint32_t val); ++#endif + uint8_t swd_read_word(uint32_t addr, uint32_t *val); + uint8_t swd_write_word(uint32_t addr, uint32_t val); + uint8_t swd_read_byte(uint32_t addr, uint8_t *val); +@@ -67,8 +62,11 @@ + uint8_t swd_set_target_state_sw(target_state_t state); + uint8_t swd_transfer_retry(uint32_t req, uint32_t *data); + void int2array(uint8_t *res, uint32_t data, uint8_t len); +-void swd_set_reset_connect(SWD_CONNECT_TYPE type); ++void swd_set_reset_connect(JTAG_SWD_CONNECT_TYPE type); + void swd_set_soft_reset(uint32_t soft_reset_type); ++#if defined(HISPARK_TRACE) ++void swd_exec_soft_reset(void); ++#endif + uint8_t JTAG2SWD(void); + + #ifdef __cplusplus +diff -uNr old/CA7/source/daplink/interface/target_flash.c new/CA7/source/daplink/interface/target_flash.c +--- old/CA7/source/daplink/interface/target_flash.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/interface/target_flash.c 2023-06-09 15:39:54.224644800 +0800 +@@ -28,6 +28,8 @@ + #include "target_config.h" + #include "intelhex.h" + #include "swd_host.h" ++#include "jtag_host.h" ++#include "swd_jtag_config.h" + #include "flash_intf.h" + #include "util.h" + #include "settings.h" +@@ -51,6 +53,9 @@ + static uint32_t target_flash_erase_sector_size(uint32_t addr); + static uint8_t target_flash_busy(void); + static error_t target_flash_set(uint32_t addr); ++#if defined(HISPARK_TRACE) ++static error_t target_flash_read(uint32_t addr, uint8_t *buf, uint32_t size); ++#endif + + static const flash_intf_t flash_intf = { + target_flash_init, +@@ -62,6 +67,9 @@ + target_flash_erase_sector_size, + target_flash_busy, + target_flash_set, ++#if defined(HISPARK_TRACE) ++ target_flash_read, ++#endif + }; + + static state_t state = STATE_CLOSED; +@@ -79,6 +87,46 @@ + //saved flash start from flash algo + static uint32_t flash_start = 0; + ++#ifdef HISPARK_TRACE ++static uint8_t swd_jtag_read_memory(uint32_t address, uint8_t *data, uint32_t size) ++{ ++ uint8_t debugPort; ++ ++ debugPort = SwdJtagDebugPortGet(); ++ if (debugPort == DAP_PORT_JTAG) { ++ return jtag_read_memory(address, data, size); ++ } else { ++ return swd_read_memory(address, data, size); ++ } ++} ++ ++static uint8_t swd_jtag_write_memory(uint32_t address, uint8_t *data, uint32_t size) ++{ ++ uint8_t debugPort; ++ ++ debugPort = SwdJtagDebugPortGet(); ++ if (debugPort == DAP_PORT_JTAG) { ++ return jtag_write_memory(address, data, size); ++ } else { ++ return swd_write_memory(address, data, size); ++ } ++} ++ ++static uint8_t swd_jtag_flash_syscall_exec(const program_syscall_t *sysCallParam, ++ uint32_t entry, uint32_t arg1, uint32_t arg2, ++ uint32_t arg3, uint32_t arg4, flash_algo_return_t return_type) ++{ ++ uint8_t debugPort; ++ ++ debugPort = SwdJtagDebugPortGet(); ++ if (debugPort == DAP_PORT_JTAG) { ++ return jtag_flash_syscall_exec(sysCallParam, entry, arg1, arg2, arg3, arg4, return_type); ++ } else { ++ return swd_flash_syscall_exec(sysCallParam, entry, arg1, arg2, arg3, arg4, return_type); ++ } ++} ++#endif /* HISPARK_TRACE */ ++ + static program_target_t * get_flash_algo(uint32_t addr) + { + region_info_t * flash_region = g_board_info.target_cfg->flash_regions; +@@ -112,14 +160,22 @@ + // Finish the currently active function. + if (FLASH_FUNC_NOP != last_flash_func && + ((flash->algo_flags & kAlgoSingleInitType) == 0 || FLASH_FUNC_NOP == func ) && ++#ifdef HISPARK_TRACE ++ 0 == swd_jtag_flash_syscall_exec(&flash->sys_call_s, flash->uninit, last_flash_func, 0, 0, 0, FLASHALGO_RETURN_BOOL)) { ++#else + 0 == swd_flash_syscall_exec(&flash->sys_call_s, flash->uninit, last_flash_func, 0, 0, 0, FLASHALGO_RETURN_BOOL)) { ++#endif /* #ifdef HISPARK_TRACE */ + return ERROR_UNINIT; + } + + // Start a new function. + if (FLASH_FUNC_NOP != func && + ((flash->algo_flags & kAlgoSingleInitType) == 0 || FLASH_FUNC_NOP == last_flash_func ) && ++#ifdef HISPARK_TRACE ++ 0 == swd_jtag_flash_syscall_exec(&flash->sys_call_s, flash->init, flash_start, 0, func, 0, FLASHALGO_RETURN_BOOL)) { ++#else + 0 == swd_flash_syscall_exec(&flash->sys_call_s, flash->init, flash_start, 0, func, 0, FLASHALGO_RETURN_BOOL)) { ++#endif /* #ifdef HISPARK_TRACE */ + return ERROR_INIT; + } + +@@ -142,7 +198,11 @@ + return status; + } + // Download flash programming algorithm to target ++#ifdef HISPARK_TRACE ++ if (0 == swd_jtag_write_memory(new_flash_algo->algo_start, (uint8_t *)new_flash_algo->algo_blob, new_flash_algo->algo_size)) { ++#else + if (0 == swd_write_memory(new_flash_algo->algo_start, (uint8_t *)new_flash_algo->algo_blob, new_flash_algo->algo_size)) { ++#endif /* #ifdef HISPARK_TRACE */ + return ERROR_ALGO_DL; + } + +@@ -199,7 +259,11 @@ + target_set_state(POST_FLASH_RESET); + + state = STATE_CLOSED; +- swd_off(); ++ if (SwdJtagDebugPortGet() == DAP_PORT_JTAG) { ++ jtag_off(); ++ } else { ++ swd_off(); ++ } + return ERROR_SUCCESS; + } else { + return ERROR_FAILURE; +@@ -233,11 +297,24 @@ + uint32_t write_size = MIN(size, flash->program_buffer_size); + + // Write page to buffer ++#ifdef HISPARK_TRACE ++ if (!swd_jtag_write_memory(flash->program_buffer, (uint8_t *)buf, write_size)) { ++#else + if (!swd_write_memory(flash->program_buffer, (uint8_t *)buf, write_size)) { ++#endif /* #ifdef HISPARK_TRACE */ + return ERROR_ALGO_DATA_SEQ; + } + + // Run flash programming ++#ifdef HISPARK_TRACE ++ if (!swd_jtag_flash_syscall_exec(&flash->sys_call_s, ++ flash->program_page, ++ addr, ++ write_size, ++ flash->program_buffer, ++ 0, ++ FLASHALGO_RETURN_BOOL)) { ++#else + if (!swd_flash_syscall_exec(&flash->sys_call_s, + flash->program_page, + addr, +@@ -245,6 +322,7 @@ + flash->program_buffer, + 0, + FLASHALGO_RETURN_BOOL)) { ++#endif /* #ifdef HISPARK_TRACE */ + return ERROR_WRITE; + } + +@@ -261,6 +339,15 @@ + } else { + return_type = FLASHALGO_RETURN_BOOL; + } ++#ifdef HISPARK_TRACE ++ if (!swd_jtag_flash_syscall_exec(&flash->sys_call_s, ++ flash->verify, ++ addr, ++ write_size, ++ flash->program_buffer, ++ 0, ++ return_type)) { ++#else + if (!swd_flash_syscall_exec(&flash->sys_call_s, + flash->verify, + addr, +@@ -268,13 +355,18 @@ + flash->program_buffer, + 0, + return_type)) { ++#endif /* #ifdef HISPARK_TRACE */ + return ERROR_WRITE_VERIFY; + } + } else { + while (write_size > 0) { + uint8_t rb_buf[16]; + uint32_t verify_size = MIN(write_size, sizeof(rb_buf)); ++#ifdef HISPARK_TRACE ++ if (!swd_jtag_read_memory(addr, rb_buf, verify_size)) { ++#else + if (!swd_read_memory(addr, rb_buf, verify_size)) { ++#endif /* #ifdef HISPARK_TRACE */ + return ERROR_ALGO_DATA_SEQ; + } + if (memcmp(buf, rb_buf, verify_size) != 0) { +@@ -322,7 +414,11 @@ + return status; + } + ++#ifdef HISPARK_TRACE ++ if (0 == swd_jtag_flash_syscall_exec(&flash->sys_call_s, flash->erase_sector, addr, 0, 0, 0, FLASHALGO_RETURN_BOOL)) { ++#else + if (0 == swd_flash_syscall_exec(&flash->sys_call_s, flash->erase_sector, addr, 0, 0, 0, FLASHALGO_RETURN_BOOL)) { ++#endif /* #ifdef HISPARK_TRACE */ + return ERROR_ERASE_SECTOR; + } + +@@ -352,7 +448,11 @@ + if (status != ERROR_SUCCESS) { + return status; + } ++#ifdef HISPARK_TRACE ++ if (0 == swd_jtag_flash_syscall_exec(¤t_flash_algo->sys_call_s, current_flash_algo->erase_chip, 0, 0, 0, 0, FLASHALGO_RETURN_BOOL)) { ++#else + if (0 == swd_flash_syscall_exec(¤t_flash_algo->sys_call_s, current_flash_algo->erase_chip, 0, 0, 0, 0, FLASHALGO_RETURN_BOOL)) { ++#endif /* #ifdef HISPARK_TRACE */ + return ERROR_ERASE_ALL; + } + } +@@ -399,7 +499,61 @@ + return 0; + } + } ++#if defined(HISPARK_TRACE) ++static error_t target_flash_read(uint32_t addr, uint8_t *buf, uint32_t size) ++{ ++ if (g_board_info.target_cfg) { ++ error_t status = ERROR_SUCCESS; ++ program_target_t * flash = current_flash_algo; ++ ++ if (!flash) { ++ return ERROR_INTERNAL; ++ } ++ ++ status = flash_func_start(FLASH_FUNC_READ); ++ if (status != ERROR_SUCCESS) { ++ return status; ++ } ++ ++ while (size > 0) { ++ uint32_t read_size = MIN(size, flash->program_buffer_size); + ++ // Read page to buffer ++#ifdef HISPARK_TRACE ++ if (!swd_jtag_flash_syscall_exec(&flash->sys_call_s, ++ flash->read, ++ addr, ++ read_size, ++ flash->program_buffer, ++ 0, ++ FLASHALGO_RETURN_BOOL)) { ++#else ++ if (!swd_flash_syscall_exec(&flash->sys_call_s, ++ flash->read, ++ addr, ++ read_size, ++ flash->program_buffer, ++ 0, ++ FLASHALGO_RETURN_BOOL)) { ++#endif /* #ifdef HISPARK_TRACE */ ++ return ERROR_READ; ++ } ++#ifdef HISPARK_TRACE ++ if (!swd_jtag_read_memory(flash->program_buffer, buf, read_size)) { ++#else ++ if (!swd_read_memory(flash->program_buffer, buf, read_size)) { ++#endif /* #ifdef HISPARK_TRACE */ ++ return ERROR_READ; ++ } ++ addr += read_size; ++ buf += read_size; ++ size -= read_size; ++ } ++ return ERROR_SUCCESS; ++ } ++ return ERROR_FAILURE; ++} ++#endif + static uint8_t target_flash_busy(void){ + return (state == STATE_OPEN); + } +diff -uNr old/CA7/source/daplink/settings/settings_rom.c new/CA7/source/daplink/settings/settings_rom.c +--- old/CA7/source/daplink/settings/settings_rom.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/settings/settings_rom.c 2023-05-25 15:09:49.000000000 +0800 +@@ -18,7 +18,7 @@ + * See the License for the specific language governing permissions and + * limitations under the License. + */ +- ++#ifndef HISPARK_TRACE + #include + + #include "settings.h" +@@ -196,3 +196,4 @@ + { + return config_rom_copy.detect_incompatible_target; + } ++#endif +diff -uNr old/CA7/source/daplink/usb2uart/usbd_user_cdc_acm.c new/CA7/source/daplink/usb2uart/usbd_user_cdc_acm.c +--- old/CA7/source/daplink/usb2uart/usbd_user_cdc_acm.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/usb2uart/usbd_user_cdc_acm.c 2023-05-25 15:39:01.000000000 +0800 +@@ -149,11 +149,17 @@ + */ + int32_t USBD_CDC_ACM_PortSetControlLineState(uint16_t ctrl_bmp) + { +- uart_set_control_line_state(ctrl_bmp); +- return (1); ++#ifndef HISPARK_TRACE ++ uart_set_control_line_state(ctrl_bmp); ++#endif ++ return (1); + } + ++#ifdef HISPARK_TRACE ++void cdc_process_event(void) ++#else + void cdc_process_event() ++#endif + { + int32_t len_data = 0; + uint8_t data[64]; +diff -uNr old/CA7/source/daplink/util.c new/CA7/source/daplink/util.c +--- old/CA7/source/daplink/util.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/util.c 2023-05-25 15:09:49.000000000 +0800 +@@ -28,6 +28,76 @@ + //remove dependency from vfs_manager + __WEAK void vfs_mngr_fs_remount(void) {} + ++#if defined(HISPARK_TRACE) ++void int2str(char *str, int num) ++{ ++ char buf[12] = {0}; ++ int i = 0; ++ int len; ++ if (num == 0) { ++ *str = '0'; ++ return; ++ } ++ if (num < 0) { ++ *str++ = '-'; ++ num = -num; ++ } ++ while (num) { ++ buf[i++] = '0' + num % 10; ++ num /= 10; ++ } ++ ++ len = i; ++ for (i = len - 1; i >= 0; --i) { ++ *str++ = buf[i]; ++ } ++ *str = 0; ++} ++ ++uint32_t util_write_uint64_with_delimiter(char *str, uint64_t value) ++{ ++ uint64_t temp_val; ++ uint32_t digits; ++ uint32_t i; ++ uint32_t delimiter = 0; ++ uint32_t len; ++ char buf[30] = {0}; ++ char *p = buf; ++ ++ // Count the number of digits ++ digits = 0; ++ temp_val = value; ++ ++ while (temp_val > 0) { ++ temp_val /= 10; ++ digits += 1; ++ } ++ ++ if (digits <= 0) { ++ digits = 1; ++ } ++ ++ // Write the number ++ for (i = 0; i < digits; i++) { ++ if (delimiter) { ++ *p++ = ','; ++ delimiter = 0; ++ } ++ *p++ = '0' + (value % 10); ++ if ((i % 4) == 3) { ++ delimiter = 1; ++ } ++ value /= 10; ++ } ++ len = strlen(buf); ++ for (i = 0; i < len; ++i) { ++ str[i] = buf[len - i - 1]; ++ } ++ ++ return digits; ++} ++#endif ++ + uint32_t util_write_hex8(char *str, uint8_t value) + { + static const char nybble_chars[] = "0123456789abcdef"; +diff -uNr old/CA7/source/daplink/util.h new/CA7/source/daplink/util.h +--- old/CA7/source/daplink/util.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/daplink/util.h 2023-05-25 15:09:49.000000000 +0800 +@@ -63,6 +63,7 @@ + uint32_t util_write_hex32(char *str, uint32_t value); + uint32_t util_write_uint32(char *str, uint32_t value); + uint32_t util_write_uint32(char *str, uint32_t value); ++uint32_t util_write_uint64_with_delimiter(char *str, uint64_t value); + uint32_t util_write_uint32_zp(char *str, uint32_t value, uint16_t total_size); + uint32_t util_write_string(char *str, const char *data); + +@@ -71,6 +72,10 @@ + uint32_t util_write_string_in_region(uint8_t *buf, uint32_t size, uint32_t start, + uint32_t pos, const char *input); + ++#if defined(HISPARK_TRACE) ++void int2str(char *str, int num); ++#endif ++ + __STATIC_INLINE uint32_t util_div_round_up(uint32_t dividen, uint32_t divisor) + { + return (dividen + divisor - 1) / divisor; +diff -uNr old/CA7/source/family/vendorHM/306x/flash_blob.c new/CA7/source/family/vendorHM/306x/flash_blob.c +--- old/CA7/source/family/vendorHM/306x/flash_blob.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/family/vendorHM/306x/flash_blob.c 2023-06-09 15:40:27.424082900 +0800 +@@ -1,5 +1,5 @@ + /* Flash OS Routines (Automagically Generated) +- * Copyright (c) 2009-2019 ARM Limited ++ * Copyright (c) 2009-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. +@@ -13,52 +13,86 @@ + * See the License for the specific language governing permissions and + * limitations under the License. + */ ++#include "flash_blob.h" + +-static const uint32_t STM32F103RB_flash_prog_blob[] = { +- 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, +- 0x4603b510, 0x4c442000, 0x48446020, 0x48446060, 0x46206060, 0xf01069c0, 0xd1080f04, 0x5055f245, +- 0x60204c40, 0x60602006, 0x70fff640, 0x200060a0, 0x4601bd10, 0x69004838, 0x0080f040, 0x61104a36, +- 0x47702000, 0x69004834, 0x0004f040, 0x61084932, 0x69004608, 0x0040f040, 0xe0036108, 0x20aaf64a, +- 0x60084930, 0x68c0482c, 0x0f01f010, 0x482ad1f6, 0xf0206900, 0x49280004, 0x20006108, 0x46014770, +- 0x69004825, 0x0002f040, 0x61104a23, 0x61414610, 0xf0406900, 0x61100040, 0xf64ae003, 0x4a2120aa, +- 0x481d6010, 0xf01068c0, 0xd1f60f01, 0x6900481a, 0x0002f020, 0x61104a18, 0x47702000, 0x4603b510, +- 0xf0201c48, 0xe0220101, 0x69004813, 0x0001f040, 0x61204c11, 0x80188810, 0x480fbf00, 0xf01068c0, +- 0xd1fa0f01, 0x6900480c, 0x0001f020, 0x61204c0a, 0x68c04620, 0x0f14f010, 0x4620d006, 0xf04068c0, +- 0x60e00014, 0xbd102001, 0x1c921c9b, 0x29001e89, 0x2000d1da, 0x0000e7f7, 0x40022000, 0x45670123, +- 0xcdef89ab, 0x40003000, 0x00000000 ++ ++static uint32_t h306x_flash_prog_blob[] = { ++ 0x00100073, ++ 0xd6227179, 0x2e231800, 0x2c23fca4, 0x2a23fcb4, 0x2623fcc4, 0x2783fe04, 0x8b8dfd44, 0x2783cb81, ++ 0x8389fd44, 0x22230785, 0xa031fef4, 0xfd442783, 0x22238389, 0x07b7fef4, 0x20231471, 0x2783fef4, ++ 0x2623fdc4, 0x2703fef4, 0x07b7fd84, 0x17fd0040, 0x00f776b3, 0xfe042783, 0x00400737, 0x8f75177d, ++ 0x43d0070a, 0xff0006b7, 0x8ef1068d, 0xc3d88f55, 0xfe042423, 0x2783a015, 0x4398fec4, 0xfe042783, ++ 0x40e7a023, 0xfec42783, 0x26230791, 0x2783fef4, 0x0785fe84, 0xfef42423, 0xfe842703, 0xfd442783, ++ 0xfcf76be3, 0xfe442783, 0x03f7f793, 0x0ff7f713, 0xfe042783, 0x03f77713, 0x43900752, 0xfc1006b7, ++ 0x8ef116fd, 0xc3988f55, 0xfe042783, 0x77134398, 0x67138ff7, 0xc3982007, 0xfe042783, 0x67134398, ++ 0xc3980017, 0x27830001, 0x439cfe04, 0xf7938b85, 0xfbf50ff7, 0x54320001, 0x80826145, 0xd6227179, ++ 0x2e231800, 0x2c23fca4, 0x2a23fcb4, 0x07b7fcc4, 0x26231471, 0x2783fef4, 0xc737fec4, 0x0713fedc, ++ 0xa023a987, 0x278320e7, 0xa703fec4, 0x9b750807, 0x08e7a023, 0xfec42783, 0x0807a703, 0xa0239b79, ++ 0x478108e7, 0x5432853e, 0x80826145, 0xce221101, 0x26231000, 0x4781fea4, 0x4472853e, 0x80826105, ++ 0xd6227179, 0x2e231800, 0x2c23fca4, 0x87b2fcb4, 0xfcf40ba3, 0xfdc42783, 0xfef42623, 0xfec42783, ++ 0x00178713, 0xfee42623, 0x0007c783, 0x0ff7f793, 0xfd744703, 0x00f70463, 0xa8114785, 0xfd842783, ++ 0x2c2317fd, 0x2783fcf4, 0xfbe9fd84, 0x853e4781, 0x61455432, 0x11018082, 0x1000ce22, 0x147107b7, ++ 0xfef42623, 0xfec42783, 0x073743d4, 0x070dff00, 0xc3d88f75, 0xfec42783, 0x77134398, 0x67138ff7, ++ 0xc3986007, 0xfec42783, 0x67134398, 0xc3980017, 0x27830001, 0x439cfec4, 0xf7938b85, 0xfbf50ff7, ++ 0x853e4781, 0x61054472, 0x71798082, 0x1800d622, 0xfca42e23, 0xfe042623, 0x147107b7, 0xfef42423, ++ 0xfdc42703, 0x030007b7, 0x00f76e63, 0xfdc42703, 0xfd0007b7, 0x262397ba, 0x2783fef4, 0x8389fec4, ++ 0xfef42623, 0xfec42703, 0x004007b7, 0x76b317fd, 0x278300f7, 0x0737fe84, 0x177d0040, 0x070a8f75, ++ 0x06b743d0, 0x068dff00, 0x8f558ef1, 0x2783c3d8, 0x4398fe84, 0x8ff77713, 0x40076713, 0x2783c398, ++ 0x4398fe84, 0x00176713, 0x0001c398, 0xfe842783, 0x8b85439c, 0x0ff7f793, 0x4781fbf5, 0x5432853e, ++ 0x80826145, 0xd6067179, 0x1800d422, 0xfca42e23, 0xfcb42c23, 0xfcc42a23, 0xfe042423, 0xfd442783, ++ 0xfef42023, 0xfd842783, 0x22238389, 0x2783fef4, 0x839dfe44, 0xfef42623, 0xfdc42703, 0x030007b7, ++ 0x00f76e63, 0xfdc42703, 0xfd0007b7, 0x242397ba, 0x2783fef4, 0x8389fe84, 0xfef42423, 0xfe042783, ++ 0x08000613, 0xfe842583, 0x39dd853e, 0xfe042783, 0x20078793, 0xfef42023, 0xfe842783, 0x08078793, ++ 0xfef42423, 0xfec42783, 0x262317fd, 0x2783fef4, 0xf7e9fec4, 0xfe442783, 0x07f7f793, 0x2703cf81, ++ 0x2783fe04, 0xf793fe44, 0x863e07f7, 0xfe842583, 0x317d853a, 0x853e4781, 0x542250b2, 0x80826145, ++ 0xce221101, 0x26231000, 0x2423fea4, 0x2223feb4, 0x4781fec4, 0x4472853e, 0x80826105, 0xd6227179, ++ 0x2e231800, 0x2c23fca4, 0x2a23fcb4, 0x2623fcc4, 0x2783fe04, 0x2423fd84, 0x2783fef4, 0xe399fd44, ++ 0xa83d4785, 0xfdc42783, 0xfef42623, 0x2783a035, 0x17fdfe84, 0xfef42423, 0xfec42703, 0x00170793, ++ 0xfef42623, 0xfd442783, 0x00178693, 0xfcd42a23, 0x00074703, 0x00e78023, 0xfe842783, 0x4781fbe9, ++ 0x5432853e, 0x80826145, 0x00000000, 0x00000000 + }; + ++// Start address of flash ++static const uint32_t flash_start = 0x03000000; ++// Size of flash ++static const uint32_t flash_size = 0x00028000; ++ + /** +-* List of start and size for each size of flash sector ++* List of start and size for each size of flash sector - even indexes are start, odd are size + * The size will apply to all sectors between the listed address and the next address + * in the list. + * The last pair in the list will have sectors starting at that address and ending +-* at address start + size. ++* at address flash_start + flash_size. + */ +-static const sector_info_t sectors_info[] = { +- {0x08000000, 0x400}, ++static uint32_t sectors_info[] = { ++ 0x03000000, 0x00002000, + }; + + static const program_target_t flash = { +- 0x20000021, // Init +- 0x20000053, // UnInit +- 0x20000065, // EraseChip +- 0x2000009f, // EraseSector +- 0x200000dd, // ProgramPage +- 0x0, // Verify ++ 0x02000100, // Init ++ 0x02000150, // UnInit ++ 0x020001ba, // EraseChip ++ 0x0200020e, // EraseSector ++ 0x020002a8, // ProgramPage ++ 0x02000364, // Verify ++ 0x02000380, // Read + + // BKPT : start of blob + 1 + // RSB : blob start + header + rw data offset + // RSP : stack pointer ++ // state.r[1] = sysCallParam->breakpoint; // LR: Exit Point ++ //state.r[3] = sysCallParam->static_base; // SB: Static Base ++ //state.r[2] = sysCallParam->stack_pointer; // SP: Stack Pointer ++ + { +- 0x20000001, +- 0x20000148, +- 0x20000800 ++ 0x02000001, ++ 0x020003f4, ++ 0x02000800 + }, + +- 0x20000000 + 0x00000A00, // mem buffer location +- 0x20000000, // location to write prog_blob in target RAM +- sizeof(STM32F103RB_flash_prog_blob), // prog_blob size +- STM32F103RB_flash_prog_blob, // address of prog_blob +- 0x00000400 // ram_to_flash_bytes_to_be_written +-}; ++ 0x02000000 + 0x00000A00, // mem buffer location ++ 0x02000000, // location to write prog_blob in target RAM ++ sizeof(h306x_flash_prog_blob), // prog_blob size ++ h306x_flash_prog_blob, // address of prog_blob ++ 0x00000200 // ram_to_flash_bytes_to_be_written ++}; +\ No newline at end of file +diff -uNr old/CA7/source/family/vendorHM/306x/target.c new/CA7/source/family/vendorHM/306x/target.c +--- old/CA7/source/family/vendorHM/306x/target.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/family/vendorHM/306x/target.c 2023-06-09 15:40:36.953182300 +0800 +@@ -1,6 +1,6 @@ + /** + * @file target.c +- * @brief Target information for the STM32F103RB ++ * @brief Target information for the 306x + * + * DAPLink Interface Firmware + * Copyright (c) 2017-2019, ARM Limited, All Rights Reserved +@@ -20,21 +20,47 @@ + */ + + #include "target_config.h" ++#include "target_family.h" + + // The file flash_blob.c must only be included in target.c + #include "flash_blob.c" + + // target information + target_cfg_t target_device = { +- .version = kTargetConfigVersion, +- .sectors_info = sectors_info, ++ .sectors_info = (sector_info_t *)sectors_info, + .sector_info_length = (sizeof(sectors_info))/(sizeof(sector_info_t)), +- .flash_regions[0].start = 0x08000000, +- .flash_regions[0].end = 0x08020000, ++ .flash_regions[0].start = 0x03000000, ++ .flash_regions[0].end = 0x03028000, + .flash_regions[0].flags = kRegionIsDefault, + .flash_regions[0].flash_algo = (program_target_t *) &flash, + .ram_regions[0].start = 0x20000000, +- .ram_regions[0].end = 0x20005000, +- .target_vendor = "STMicroelectronics", +- .target_part_number = "STM32F103RB", ++ .ram_regions[0].end = 0x20004000, + }; ++ ++#define H306x_BIN_HEAD1 0xBD ++#define H306x_BIN_HEAD2 0x95 ++#define H306x_BIN_HEAD3 0x7E ++#define H306x_BIN_HEAD4 0xA3 ++uint8_t H306xBinParse(const uint8_t *buf) ++{ ++ uint8_t temp[] = { ++ H306x_BIN_HEAD1, ++ H306x_BIN_HEAD2, ++ H306x_BIN_HEAD3, ++ H306x_BIN_HEAD4 ++ }; ++ for (int i = 0; i < 4; i++) { ++ if (temp[i] != buf[i]) { ++ return 0; ++ } ++ } ++ return 1; ++} ++const target_family_descriptor_t g_target_family_306x = { ++ .validate_bin_nvic = &H306xBinParse, ++ .default_reset_type = kSoftwareReset, ++ //.apsel = 0x1000000, ++ .apsel = 0x0000000, ++}; ++ ++const target_family_descriptor_t *g_target_family = &g_target_family_306x; +diff -uNr old/CA7/source/hic_hal/device.h new/CA7/source/hic_hal/device.h +--- old/CA7/source/hic_hal/device.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/device.h 2023-05-25 15:09:49.000000000 +0800 +@@ -42,6 +42,8 @@ + #include "stm32f1xx.h" + #elif defined (INTERFACE_M48SSIDAE) + #include "M480.h" ++#elif defined (INTERFACE_STM32MP153) ++#include "stm32mp1xx.h" + #elif defined (INTERFACE_NRF52820) + #include "nrf52820.h" + #else +diff -uNr old/CA7/source/hic_hal/flash_blob.h new/CA7/source/hic_hal/flash_blob.h +--- old/CA7/source/hic_hal/flash_blob.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/flash_blob.h 2023-05-25 15:09:49.000000000 +0800 +@@ -44,6 +44,22 @@ + } program_syscall_t; + + typedef struct __attribute__((__packed__)) { ++#ifdef HISPARK_TRACE ++ uint32_t init; ++ uint32_t uninit; ++ uint32_t erase_chip; ++ uint32_t erase_sector; ++ uint32_t program_page; ++ uint32_t verify; ++ uint32_t read; ++ program_syscall_t sys_call_s; ++ uint32_t program_buffer; ++ uint32_t algo_start; ++ uint32_t algo_size; ++ uint32_t *algo_blob; ++ uint32_t program_buffer_size; ++ uint32_t algo_flags; /*!< Combination of kAlgoVerifyReturnsAddress, kAlgoSingleInitType and kAlgoSkipChipErase*/ ++#else /* #ifdef HISPARK_TRACE */ + const uint32_t init; + const uint32_t uninit; + const uint32_t erase_chip; +@@ -57,11 +73,17 @@ + const uint32_t *algo_blob; + const uint32_t program_buffer_size; + const uint32_t algo_flags; /*!< Combination of kAlgoVerifyReturnsAddress, kAlgoSingleInitType and kAlgoSkipChipErase*/ ++#endif /* #ifdef HISPARK_TRACE */ + } program_target_t; + + typedef struct __attribute__((__packed__)) { ++#ifdef HISPARK_TRACE ++ uint32_t start; ++ uint32_t size; ++#else + const uint32_t start; + const uint32_t size; ++#endif + } sector_info_t; + + #ifdef __cplusplus +diff -uNr old/CA7/source/hic_hal/FlashPrg.h new/CA7/source/hic_hal/FlashPrg.h +--- old/CA7/source/hic_hal/FlashPrg.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/FlashPrg.h 2023-05-25 15:09:49.000000000 +0800 +@@ -77,6 +77,8 @@ + */ + uint32_t Verify(uint32_t adr, uint32_t sz, uint32_t *buf); + ++uint32_t FlashRead(uint32_t adr, uint32_t sz, uint8_t *buf); ++ + #ifdef __cplusplus + } + #endif +diff -uNr old/CA7/source/hic_hal/gpio.h new/CA7/source/hic_hal/gpio.h +--- old/CA7/source/hic_hal/gpio.h 2022-02-05 13:12:28.000000000 +0800 ++++ new/CA7/source/hic_hal/gpio.h 2023-05-25 15:36:28.000000000 +0800 +@@ -51,6 +51,10 @@ + return gpio_get_reset_btn_no_fwrd() || gpio_get_reset_btn_fwrd(); + } + ++#ifdef HISPARK_TRACE ++void gpio_set_daplink_run(gpio_led_state_t state); ++#endif ++ + #ifdef __cplusplus + } + #endif +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/cmsis/stm32mp1xx_hal_msp.c new/CA7/source/hic_hal/stm32/stm32mp1xx/cmsis/stm32mp1xx_hal_msp.c +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/cmsis/stm32mp1xx_hal_msp.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/cmsis/stm32mp1xx_hal_msp.c 2023-05-25 15:09:49.000000000 +0800 +@@ -18,7 +18,14 @@ + ****************************************************************************** + */ + /* Includes ------------------------------------------------------------------*/ ++#ifdef HISPARK_TRACE ++#include "stm32mp1xx.h" ++ ++#define PERIPH_LOCK(x) ++#define PERIPH_UNLOCK(x) ++#else + #include "main.h" ++#endif + + /* USER CODE BEGIN 0 */ + +@@ -48,8 +55,14 @@ + /* USER CODE END QUADSPI_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_QSPI_CLK_ENABLE(); +- +- /**QUADSPI GPIO Configuration ++#ifdef HISPARK_TRACE ++ __HAL_RCC_GPIOE_CLK_ENABLE(); ++ __HAL_RCC_GPIOB_CLK_ENABLE(); ++ __HAL_RCC_GPIOC_CLK_ENABLE(); ++ __HAL_RCC_GPIOF_CLK_ENABLE(); ++#endif ++ ++ /**QUADSPI GPIO Configuration + PC0 ------> QUADSPI_BK2_NCS + PF10 ------> QUADSPI_CLK + PB6 ------> QUADSPI_BK1_NCS +@@ -91,9 +104,11 @@ + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + PERIPH_UNLOCK(GPIOF); + ++#ifndef HISPARK_TRACE + /* QUADSPI interrupt Init */ + HAL_NVIC_SetPriority(QUADSPI_IRQn, DEFAULT_IRQ_PRIO, 0); + HAL_NVIC_EnableIRQ(QUADSPI_IRQn); ++#endif + /* USER CODE BEGIN QUADSPI_MspInit 1 */ + /* Reset the QuadSPI memory interface */ + __HAL_RCC_QSPI_FORCE_RESET(); +@@ -113,12 +128,12 @@ + /* Reset the QuadSPI memory interface */ + __HAL_RCC_QSPI_FORCE_RESET(); + __HAL_RCC_QSPI_RELEASE_RESET(); +- ++ + /* USER CODE END QUADSPI_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_QSPI_CLK_DISABLE(); +- +- /**QUADSPI GPIO Configuration ++ ++ /**QUADSPI GPIO Configuration + PC0 ------> QUADSPI_BK2_NCS + PF10 ------> QUADSPI_CLK + PB6 ------> QUADSPI_BK1_NCS +@@ -129,7 +144,7 @@ + PF6 ------> QUADSPI_BK1_IO3 + PH2 ------> QUADSPI_BK2_IO0 + PF8 ------> QUADSPI_BK1_IO0 +- PF9 ------> QUADSPI_BK1_IO1 ++ PF9 ------> QUADSPI_BK1_IO1 + */ + + PERIPH_LOCK(GPIOF); +@@ -141,9 +156,10 @@ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10); + PERIPH_UNLOCK(GPIOB); + +- ++#ifndef HISPARK_TRACE + /* QUADSPI interrupt DeInit */ + HAL_NVIC_DisableIRQ(QUADSPI_IRQn); ++#endif + /* USER CODE BEGIN QUADSPI_MspDeInit 1 */ + + /* USER CODE END QUADSPI_MspDeInit 1 */ +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/cmsis/system_stm32mp1xx.c new/CA7/source/hic_hal/stm32/stm32mp1xx/cmsis/system_stm32mp1xx.c +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/cmsis/system_stm32mp1xx.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/cmsis/system_stm32mp1xx.c 2023-05-25 15:09:49.000000000 +0800 +@@ -14,7 +14,7 @@ + * be used by the user application to setup + * the SysTick timer or configure other + * parameters. +- * ++ * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. +@@ -76,7 +76,7 @@ + /*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ + /* #define VECT_TAB_SRAM */ +-#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. ++#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. + This value must be a multiple of 0x400. */ + /******************************************************************************/ + +@@ -103,7 +103,11 @@ + then there is no need to call the first functions listed above, + since SystemCoreClock variable is updated automatically. + */ ++#ifdef HISPARK_TRACE ++ unsigned int SystemCoreClock = HSI_VALUE; ++#else + uint32_t SystemCoreClock = HSI_VALUE; ++#endif + /** + * @} + */ +@@ -112,8 +116,8 @@ + * @{ + */ + +-#if defined (DATA_IN_ExtSRAM) +- static void SystemInit_ExtMemCtl(void); ++#if defined (DATA_IN_ExtSRAM) ++ static void SystemInit_ExtMemCtl(void); + #endif /* DATA_IN_ExtSRAM */ + + /** +@@ -126,7 +130,7 @@ + + /** + * @brief Setup the microcontroller system +- * Initialize the FPU setting, vector table location and External memory ++ * Initialize the FPU setting, vector table location and External memory + * configuration. + * @param None + * @retval None +@@ -151,8 +155,10 @@ + CLEAR_REG(EXTI_C2->EMR2); + CLEAR_REG(EXTI_C2->EMR3); + #else ++#ifndef HISPARK_TRACE + #error Please #define CORE_CM4 +-#endif ++#endif ++#endif + } + + /** +@@ -166,7 +172,7 @@ + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real +- * frequency in the chip. It is calculated based on the predefined ++ * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the +@@ -272,10 +278,10 @@ + */ + void SystemInit_ExtMemCtl(void) + { +- ++ + } + #endif /* DATA_IN_ExtSRAM */ +- ++ + /** + * @} + */ +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/DAP_config.h new/CA7/source/hic_hal/stm32/stm32mp1xx/DAP_config.h +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/DAP_config.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/DAP_config.h 2023-12-27 14:14:40.636039904 +0800 +@@ -57,11 +57,11 @@ + + /// Indicate that JTAG communication mode is available at the Debug Port. + /// This information is returned by the command \ref DAP_Info as part of Capabilities. +-#define DAP_JTAG 0 ///< JTAG Mode: 1 = available, 0 = not available. ++#define DAP_JTAG 1 ///< JTAG Mode: 1 = available, 0 = not available. + + /// Configure maximum number of JTAG devices on the scan chain connected to the Debug Access Port. + /// This setting impacts the RAM requirements of the Debug Unit. Valid range is 1 .. 255. +-#define DAP_JTAG_DEV_CNT 0 ///< Maximum number of JTAG devices on scan chain ++#define DAP_JTAG_DEV_CNT 4 ///< Maximum number of JTAG devices on scan chain + + /// Default communication mode on the Debug Access Port. + /// Used for the command \ref DAP_Connect when Port Default mode is selected. +@@ -83,27 +83,24 @@ + #endif + + /// Maximum Package Buffers for Command and Response data. +-/// This configuration settings is used to optimize the communication performance with the ++/// This configuration settings is used to optimized the communication performance with the + /// debugger and depends on the USB peripheral. For devices with limited RAM or USB buffer the + /// setting can be reduced (valid range is 1 .. 255). Change setting to 4 for High-Speed USB. +-#define DAP_PACKET_COUNT 4 ///< Buffers: 64 = Full-Speed, 4 = High-Speed. ++#define DAP_PACKET_COUNT 8 ///< Buffers: 64 = Full-Speed, 4 = High-Speed. + + /// Indicate that UART Serial Wire Output (SWO) trace is available. + /// This information is returned by the command \ref DAP_Info as part of Capabilities. + #define SWO_UART 0 ///< SWO UART: 1 = available, 0 = not available + +-/// USART Driver instance number for the UART SWO. +-#define SWO_UART_DRIVER 0 ///< USART Driver instance number (Driver_USART#). +- + /// Maximum SWO UART Baudrate + #define SWO_UART_MAX_BAUDRATE 10000000U ///< SWO UART Maximum Baudrate in Hz + + /// Indicate that Manchester Serial Wire Output (SWO) trace is available. + /// This information is returned by the command \ref DAP_Info as part of Capabilities. +-#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available. ++#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available + + /// SWO Trace Buffer Size. +-#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n). ++#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n) + + /// SWO Streaming Trace. + #define SWO_STREAM 0 ///< SWO Streaming Trace: 1 = available, 0 = not available. +@@ -115,84 +112,30 @@ + /// This information is returned by the command \ref DAP_Info as part of Capabilities. + #define DAP_UART 0 ///< DAP UART: 1 = available, 0 = not available. + +-/// USART Driver instance number for the UART Communication Port. +-#define DAP_UART_DRIVER 1 ///< USART Driver instance number (Driver_USART#). +- +-/// UART Receive Buffer Size. +-#define DAP_UART_RX_BUFFER_SIZE 1024U ///< Uart Receive Buffer Size in bytes (must be 2^n). +- +-/// UART Transmit Buffer Size. +-#define DAP_UART_TX_BUFFER_SIZE 1024U ///< Uart Transmit Buffer Size in bytes (must be 2^n). +- +-/// Indicate that UART Communication via USB COM Port is available. +-/// This information is returned by the command \ref DAP_Info as part of Capabilities. +-#define DAP_UART_USB_COM_PORT 1 ///< USB COM Port: 1 = available, 0 = not available. +- + /// Debug Unit is connected to fixed Target Device. + /// The Debug Unit may be part of an evaluation board and always connected to a fixed +-/// known device. In this case a Device Vendor, Device Name, Board Vendor and Board Name strings +-/// are stored and may be used by the debugger or IDE to configure device parameters. +-#define TARGET_FIXED 0 ///< Target: 1 = known, 0 = unknown; ++/// known device. In this case a Device Vendor and Device Name string is stored which ++/// may be used by the debugger or IDE to configure device parameters. ++#define TARGET_DEVICE_FIXED 0 ///< Target Device: 1 = known, 0 = unknown; ++ ++#if TARGET_DEVICE_FIXED ++#define TARGET_DEVICE_VENDOR "" ///< String indicating the Silicon Vendor ++#define TARGET_DEVICE_NAME "" ///< String indicating the Target Device ++#endif + + ///@} + + + __STATIC_INLINE void pin_out_init(GPIO_TypeDef* GPIOx, uint8_t pin_bit) + { +- if(pin_bit >= 8) +- { +- GPIOx->CRH &= ~(0x0000000F << ((pin_bit-8) << 2)); +- GPIOx->CRH |= ( ((uint32_t)(0x00|0x03) & 0x0F) << ((pin_bit-8) << 2) ); +- } +- else +- { +- GPIOx->CRL &= ~(0x0000000F << ((pin_bit) << 2)); +- GPIOx->CRL |= ( ((uint32_t)(0x00|0x03) & 0x0F) << ((pin_bit) << 2) ); +- } + } + + __STATIC_INLINE void pin_out_od_init(GPIO_TypeDef* GPIOx, uint8_t pin_bit) + { +- if(pin_bit >= 8) +- { +- GPIOx->CRH &= ~(0x0000000F << ((pin_bit-8) << 2)); +- GPIOx->CRH |= ( ((uint32_t)(0x04|0x03) & 0x0F) << ((pin_bit-8) << 2) ); +- } +- else +- { +- GPIOx->CRL &= ~(0x0000000F << ((pin_bit) << 2)); +- GPIOx->CRL |= ( ((uint32_t)(0x04|0x03) & 0x0F) << ((pin_bit) << 2) ); +- } + } + + __STATIC_INLINE void pin_in_init(GPIO_TypeDef* GPIOx, uint8_t pin_bit, uint8_t mode) + { +- uint8_t config; +- if(mode == 1) +- config = 0x08; //Up +- else if(mode == 2) +- config = 0x08; //down +- else +- config = 0x00; //GPIO_Mode_AIN +- +- if(pin_bit >= 8) +- { +- GPIOx->CRH &= ~(0x0000000F << ((pin_bit-8) << 2)); +- GPIOx->CRH |= ( ((uint32_t)(config) & 0x0F) << ((pin_bit-8) << 2) ); +- if(mode == 1) +- GPIOx->BSRR = (((uint32_t)0x01) << pin_bit); +- else if(mode == 2) +- GPIOx->BRR = (((uint32_t)0x01) << pin_bit); +- } +- else +- { +- GPIOx->CRL &= ~(0x0000000F << ((pin_bit) << 2)); +- GPIOx->CRL |= ( ((uint32_t)(config) & 0x0F) << ((pin_bit) << 2) ); +- if(mode == 1) +- GPIOx->BSRR = (((uint32_t)0x01) << pin_bit); +- else if(mode == 2) +- GPIOx->BRR = (((uint32_t)0x01) << pin_bit); +- } + } + //************************************************************************************************** + /** +@@ -240,7 +183,12 @@ + __STATIC_INLINE void PORT_JTAG_SETUP(void) + { + #if (DAP_JTAG != 0) +- ++ SWDIO_INOUT_OE_PORT->BSRR = (SWDIO_INOUT_OE_PIN << 16); ++ JTAG_TDI_PIN_PORT->BSRR = JTAG_TDI_PIN; ++ SWCLK_TCK_PIN_PORT->BSRR = SWCLK_TCK_PIN; ++ JTAG_TRST_PIN_PORT->BSRR = JTAG_TRST_PIN; ++ JTAG_TARGET_RST_PIN_PORT->BSRR = JTAG_TARGET_RST_PIN; ++ SWDIO_OUT_TMS_PIN_PORT->BSRR = SWDIO_OUT_TMS_PIN; + #endif + } + +@@ -251,17 +199,7 @@ + */ + __STATIC_INLINE void PORT_SWD_SETUP(void) + { +- // Set SWCLK HIGH +- pin_out_init(SWCLK_TCK_PIN_PORT, SWCLK_TCK_PIN_Bit); +- SWCLK_TCK_PIN_PORT->BSRR = SWCLK_TCK_PIN; +- // Set SWDIO HIGH +- pin_out_init(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN_Bit); +- SWDIO_OUT_PIN_PORT->BSRR = SWDIO_OUT_PIN; +- +- pin_in_init(SWDIO_IN_PIN_PORT, SWDIO_IN_PIN_Bit, 1); +- // Set RESET HIGH +- pin_out_od_init(nRESET_PIN_PORT, nRESET_PIN_Bit);//TODO - fix reset logic +- nRESET_PIN_PORT->BSRR = nRESET_PIN; ++ ; // Not available + } + + /** Disable JTAG/SWD I/O Pins. +@@ -270,9 +208,7 @@ + */ + __STATIC_INLINE void PORT_OFF(void) + { +- pin_in_init(SWCLK_TCK_PIN_PORT, SWCLK_TCK_PIN_Bit, 0); +- pin_in_init(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN_Bit, 0); +- pin_in_init(SWDIO_IN_PIN_PORT, SWDIO_IN_PIN_Bit, 0); ++ ; // Not available + } + + // SWCLK/TCK I/O pin ------------------------------------- +@@ -298,7 +234,7 @@ + */ + __STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void) + { +- SWCLK_TCK_PIN_PORT->BRR = SWCLK_TCK_PIN; ++ SWCLK_TCK_PIN_PORT->BSRR = (SWCLK_TCK_PIN << 16); + } + + // SWDIO/TMS Pin I/O -------------------------------------- +@@ -308,7 +244,7 @@ + */ + __STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void) + { +- return ((SWDIO_IN_PIN_PORT->IDR & SWDIO_IN_PIN) ? 1 : 0); ++ return ((SWDIO_OUT_TMS_PIN_PORT->IDR & SWDIO_OUT_TMS_PIN) ? 1 : 0); + } + + /** SWDIO/TMS I/O pin: Set Output to High. +@@ -316,7 +252,7 @@ + */ + __STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void) + { +- SWDIO_OUT_PIN_PORT->BSRR = SWDIO_OUT_PIN; ++ SWDIO_OUT_TMS_PIN_PORT->BSRR = SWDIO_OUT_TMS_PIN; + } + + /** SWDIO/TMS I/O pin: Set Output to Low. +@@ -324,7 +260,7 @@ + */ + __STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void) + { +- SWDIO_OUT_PIN_PORT->BRR = SWDIO_OUT_PIN; ++ SWDIO_OUT_TMS_PIN_PORT->BSRR = (SWDIO_OUT_TMS_PIN << 16); + } + + /** SWDIO I/O pin: Get Input (used in SWD mode only). +@@ -340,10 +276,11 @@ + */ + __STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit) + { ++ + if (bit & 1) +- SWDIO_OUT_PIN_PORT->BSRR = SWDIO_OUT_PIN; ++ SWDIO_OUT_TMS_PIN_PORT->BSRR = SWDIO_OUT_TMS_PIN; + else +- SWDIO_OUT_PIN_PORT->BRR = SWDIO_OUT_PIN; ++ SWDIO_OUT_TMS_PIN_PORT->BSRR = (SWDIO_OUT_TMS_PIN << 16); + } + + /** SWDIO I/O pin: Switch to Output mode (used in SWD mode only). +@@ -352,8 +289,7 @@ + */ + __STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE(void) + { +- pin_out_init(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN_Bit); +- SWDIO_OUT_PIN_PORT->BRR = SWDIO_OUT_PIN; ++ SWDIO_INOUT_OE_PORT->BSRR = (SWDIO_INOUT_OE_PIN << 16); + } + + /** SWDIO I/O pin: Switch to Input mode (used in SWD mode only). +@@ -362,8 +298,8 @@ + */ + __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void) + { +- pin_in_init(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN_Bit, 0); +- SWDIO_OUT_PIN_PORT->BSRR = SWDIO_OUT_PIN; ++ SWDIO_OUT_TMS_PIN_PORT->BSRR = (SWDIO_OUT_TMS_PIN<< 16); ++ SWDIO_INOUT_OE_PORT->BSRR = SWDIO_INOUT_OE_PIN; + } + + +@@ -374,7 +310,7 @@ + */ + __STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void) + { +- return (0); // Not available ++ return ((JTAG_TDI_PIN_PORT->IDR & JTAG_TDI_PIN) ? 1 : 0); + } + + /** TDI I/O pin: Set Output. +@@ -382,7 +318,10 @@ + */ + __STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit) + { +- ; // Not available ++ if (bit & 1) ++ JTAG_TDI_PIN_PORT->BSRR = JTAG_TDI_PIN; ++ else ++ JTAG_TDI_PIN_PORT->BSRR = (JTAG_TDI_PIN << 16); + } + + +@@ -393,7 +332,7 @@ + */ + __STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) + { +- return (0); // Not available ++ return ((JTAG_TDO_PIN_PORT->IDR & JTAG_TDO_PIN) ? 1 : 0); + } + + +@@ -404,7 +343,7 @@ + */ + __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void) + { +- return (0); // Not available ++ return ((JTAG_TRST_PIN_PORT->IDR & JTAG_TRST_PIN) ? 1 : 0); + } + + /** nTRST I/O pin: Set Output. +@@ -414,7 +353,10 @@ + */ + __STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) + { +- ; // Not available ++ if (bit & 1) ++ JTAG_TRST_PIN_PORT->BSRR = JTAG_TRST_PIN; ++ else ++ JTAG_TRST_PIN_PORT->BSRR = (JTAG_TRST_PIN << 16); + } + + // nRESET Pin I/O------------------------------------------ +@@ -424,7 +366,7 @@ + */ + __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void) + { +- return ((nRESET_PIN_PORT->IDR >> nRESET_PIN_Bit) & 1); ++ return ((JTAG_TARGET_RST_PIN_PORT->IDR >> JTAG_TARGET_RST_PIN_BIT) & 1); + } + + /** nRESET I/O pin: Set Output. +@@ -432,14 +374,13 @@ + - 0: issue a device hardware reset. + - 1: release device hardware reset. + */ +-// TODO - sw specific implementation should be created +- +-__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) ++__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) + { +- if (bit & 1) +- nRESET_PIN_PORT->BSRR = nRESET_PIN; +- else +- nRESET_PIN_PORT->BRR = nRESET_PIN; ++ if (bit & 1) { ++ JTAG_TARGET_RST_PIN_PORT->BSRR = (JTAG_TARGET_RST_PIN << 16); // DIR pin low -> nRST goes high ++ } else { ++ JTAG_TARGET_RST_PIN_PORT->BSRR = JTAG_TARGET_RST_PIN; // DIR pin high -> nRST goes low ++ } + } + + //************************************************************************************************** +@@ -462,10 +403,7 @@ + */ + __STATIC_INLINE void LED_CONNECTED_OUT(uint32_t bit) + { +- if (bit & 1) +- CONNECTED_LED_PORT->BRR = CONNECTED_LED_PIN; // LED on +- else +- CONNECTED_LED_PORT->BSRR = CONNECTED_LED_PIN;// LED off ++ ; // Not available + } + + /** Debug Unit: Set status Target Running LED. +@@ -497,7 +435,11 @@ + \return Current timestamp value. + */ + __STATIC_INLINE uint32_t TIMESTAMP_GET (void) { +- return (DWT->CYCCNT) / (CPU_CLOCK / TIMESTAMP_CLOCK); ++#if defined(HISPARK_TRACE) ++ return 100; // delete by xuyong, 只有M核才有DWT,A核需要其他的寄存器 ++#else ++ return (DWT->CYCCNT) / (CPU_CLOCK / TIMESTAMP_CLOCK); ++#endif + } + + ///@} +@@ -522,25 +464,19 @@ + */ + __STATIC_INLINE void DAP_SETUP(void) + { +- /* Enable port clock */ +- __HAL_RCC_GPIOA_CLK_ENABLE(); +- __HAL_RCC_GPIOB_CLK_ENABLE(); +- __HAL_RCC_GPIOC_CLK_ENABLE(); +- __HAL_RCC_GPIOD_CLK_ENABLE(); +- /* Configure I/O pin SWCLK */ +- pin_out_init(SWCLK_TCK_PIN_PORT, SWCLK_TCK_PIN_Bit); +- SWCLK_TCK_PIN_PORT->BSRR = SWCLK_TCK_PIN; +- +- pin_out_init(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN_Bit); +- SWDIO_OUT_PIN_PORT->BSRR = SWDIO_OUT_PIN; +- +- pin_in_init(SWDIO_IN_PIN_PORT, SWDIO_IN_PIN_Bit, 1); ++#ifndef HISPARK_TRACE ++ GPIO_InitTypeDef gpio_init = ++ { ++ .Pin = CONNECTED_LED_PIN, ++ .Mode = GPIO_MODE_OUTPUT_PP, ++ .Speed = GPIO_SPEED_FREQ_VERY_HIGH, ++ }; + +- pin_out_od_init(nRESET_PIN_PORT, nRESET_PIN_Bit); +- nRESET_PIN_PORT->BSRR = nRESET_PIN; ++ PORT_SWD_SETUP(); + +- pin_out_init(CONNECTED_LED_PORT, CONNECTED_LED_PIN_Bit); +- CONNECTED_LED_PORT->BSRR = CONNECTED_LED_PIN; ++ HAL_GPIO_Init(CONNECTED_LED_PORT, &gpio_init); ++ HAL_GPIO_WritePin(CONNECTED_LED_PORT, CONNECTED_LED_PIN, GPIO_PIN_SET); ++#endif + } + + /** Reset Target Device with custom specific I/O pin or command sequence. +@@ -557,5 +493,4 @@ + + ///@} + +- + #endif /* __DAP_CONFIG_H__ */ +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/daplink_addr.h new/CA7/source/hic_hal/stm32/stm32mp1xx/daplink_addr.h +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/daplink_addr.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/daplink_addr.h 2023-05-25 15:09:49.000000000 +0800 +@@ -23,39 +23,70 @@ + #define DAPLINK_ADDR_H + + /* Device sizes */ ++#define UPGRADE_LOADERBOOT 0 + +-#define DAPLINK_ROM_START 0x08000000 +-#define DAPLINK_ROM_SIZE 0x00020000 ++#define DAPLINK_ROM_START 0x10048000 ++#define DAPLINK_ROM_SIZE 0x001000000 // has to be a multiple of the sector size, only bank 1 is used, the datasheet says under table 7 in the notes section that the memory boundary is limited to this on each bank + +-#define DAPLINK_RAM_START 0x20000000 +-#define DAPLINK_RAM_SIZE 0x00005000 ++#define DAPLINK_RAM_START 0x2FFF8500 // Execute from AXI SRAM, because it's powered on by default and the app is quite large due to the sector_buf static variable that is used to hold one sector (128Kb) ++#define DAPLINK_RAM_SIZE 0x0002000 // divisible by DAPLINK_MIN_WRITE_SIZE ++ ++/* Flash Programming Info */ ++ ++#define DAPLINK_SECTOR_SIZE 0x0001000 // this chip has a large 128Kb sector erase ++#define DAPLINK_MIN_WRITE_SIZE 0x00000100 + + /* ROM sizes */ + +-#define DAPLINK_ROM_BL_START 0x08000000 +-#define DAPLINK_ROM_BL_SIZE 0x0000BC00 ++#define DAPLINK_ROM_BL_START 0x10048000 ++#define DAPLINK_ROM_BL_SIZE 0x10000000 // 0x00020000 // 128 kB bootloader -- 1 sector modified by xuyong, 临时不支持bootloader + +-#define DAPLINK_ROM_IF_START 0x0800C000 +-#define DAPLINK_ROM_IF_SIZE 0x00013C00 ++#define DAPLINK_ROM_CONFIG_ADMIN_START 0x08020000 ++#define DAPLINK_ROM_CONFIG_ADMIN_SIZE 0x00020000 // 1 sector + +-#define DAPLINK_ROM_CONFIG_USER_START 0x0801FC00 +-#define DAPLINK_ROM_CONFIG_USER_SIZE 0x00000400 ++#if defined(DAPLINK_BASEADDR) && (DAPLINK_BASEADDR != 0) ++#define DAPLINK_ROM_IF_START DAPLINK_BASEADDR ++#else ++#error "Please set daplink base address" ++#endif ++#define DAPLINK_ROM_IF_SIZE 0x00010000 // 5 sectors + +-/* RAM sizes */ + +-#define DAPLINK_RAM_APP_START 0x20000000 +-#define DAPLINK_RAM_APP_SIZE 0x00004F00 ++#if defined(UPGRADE_LOADERBOOT) && (UPGRADE_LOADERBOOT == 1) ++#define DAPLINK_ROM_IF_OFFSET_A 0x0000 ++#else ++#define DAPLINK_ROM_IF_OFFSET_A 0xc000 ++#endif + +-#define DAPLINK_RAM_SHARED_START 0x20004F00 +-#define DAPLINK_RAM_SHARED_SIZE 0x00000100 ++#define DAPLINK_ROM_IF_START_A (0x10048000 + DAPLINK_ROM_IF_OFFSET_A) ++#define DAPLINK_ROM_IF_SIZE_A 0x1000000 + +-/* Flash Programming Info */ ++#define DAPLINK_ROM_IF_OFFSET_B 0x10c000 ++#define DAPLINK_ROM_IF_START_B (0x10048000 + DAPLINK_ROM_IF_OFFSET_B) ++#define DAPLINK_ROM_IF_SIZE_B 0x1000000 + +-#define DAPLINK_SECTOR_SIZE 0x00000400 +-#define DAPLINK_MIN_WRITE_SIZE 0x00000400 + +-/* Current build */ ++#define DAPLINK_ROM_TARGET_IMAGE_START 0x70000000 ++#define DAPLINK_ROM_TARGET_IMAGE_SIZE 0x00010000 ++ ++#define DAPLINK_ROM_TARGET_ALGO_START 0x70010000 ++#define DAPLINK_ROM_TARGET_ALGO_SIZE 0x00010000 + ++#define DAPLINK_ROM_CONFIG_USER_START 0x080E0000 ++#define DAPLINK_ROM_CONFIG_USER_SIZE 0x00020000 // 1 sector ++ ++/* RAM sizes */ ++ ++#define DAPLINK_RAM_APP_START DAPLINK_RAM_START ++#define DAPLINK_RAM_APP_SIZE (DAPLINK_RAM_SIZE - DAPLINK_MIN_WRITE_SIZE) // leave space for RAM_SHARED ++ ++#define DAPLINK_RAM_SHARED_START (DAPLINK_RAM_APP_START + DAPLINK_RAM_APP_SIZE) ++#define DAPLINK_RAM_SHARED_SIZE (DAPLINK_RAM_SIZE - DAPLINK_RAM_APP_SIZE) // fill the rest of RAM ++ ++#ifndef DAPLINK_IF ++#define DAPLINK_IF ++#endif ++/* Current build */ + #if defined(DAPLINK_BL) + + #define DAPLINK_ROM_APP_START DAPLINK_ROM_BL_START +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/flash.c new/CA7/source/hic_hal/stm32/stm32mp1xx/flash.c +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/flash.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/flash.c 2023-05-25 15:09:49.000000000 +0800 +@@ -1,5 +1,5 @@ + /** +- * @file flash_hal_stm32f103xb.c ++ * @file flash_hal_stm32h743ii.c + * @brief + * + * DAPLink Interface Firmware +@@ -19,12 +19,72 @@ + * limitations under the License. + */ + ++#ifdef HISPARK_BOOT ++#include "flash_hal.h" // FlashOS Structures ++#include "stm32mp1xx.h" ++#include "util.h" ++#include "string.h" ++#include "daplink_addr.h" ++#else + #include "flash_hal.h" // FlashOS Structures + #include "target_config.h" // target_device +-#include "stm32f1xx.h" ++#include "stm32mp1xx.h" + #include "util.h" + #include "string.h" + #include "target_board.h" ++#include "daplink_addr.h" ++#include "debug.h" ++#endif ++ ++#define FLASH_BASE_SHIFT DAPLINK_ROM_BL_START ++ ++#define PRG_PAGE_SIZE_SHIFT 4 ++#define QSPI_DUMMY_CYCLES 0 ++#define DUMMY_CLOCK_CYCLES_READ_QUAD 10 ++#define DUMMY_CLOCK_CYCLES_READ_MAP 10 ++ ++#define QSPI_OK 0 ++#define QSPI_ERROR 1 ++ ++#define FLASH_STATUS_NO_READY 0 ++#define FLASH_STATUS_IS_READY 1 ++ ++/* Read/Write/erase Array Commands */ ++#define NORMAL_READ_CMD 0x03 ++#define FAST_READ_CMD 0x0B ++#define TWO_READ_READ_CMD 0xBB ++#define DREAD_READ_CMD 0x3B ++#define FOUR_READ_READ_CMD 0xEB ++#define QUAD_OUT_FAST_READ_CMD 0x6B ++#define PAGE_PROGRAM_CMD 0x02 ++#define QUAD_PAGE_PROGRAM_CMD 0x38 ++#define SECTOR_ERASE_CMD 0x20 ++#define BLOCK_ERASE_32K_CMD 0x52 ++#define BLOCK_ERASE_64K_CMD 0xD8 ++#define CHIP_ERASE_CMD 0x60 /*0x60 or 0xC7*/ ++ ++/* Reagister/Setting Commands */ ++#define WRITE_ENABLE_CMD 0x06 ++#define WRITE_DISABLE_CMD 0x04 ++#define READ_STATUS_REG_CMD 0x05 ++#define READ_CFG_REG_CMD 0x15 ++#define WRITE_STATUS_REG_CMD 0x01 ++#define WRITE_PROTECT_SEL_CMD 0x68 ++#define ENABLE_QPI_CMD 0x35 ++#define RESET_QPI_CMD 0xF5 ++#define PE_SUSPEND_CMD 0xB0 ++#define PE_RESUME_CMD 0x30 ++#define DEEP_POWER_DOWN_CMD 0xB9 ++#define RELEASE_DEEP_POWER_DOWN_CMD 0xAB ++#define SET_BURST_LENGTH_CMD 0xC0 ++#define READ_FAST_BOOT_REG_CMD 0x16 ++#define WRITE_FAST_BOOT_REG_CMD 0x17 ++#define ERASE_FAST_BOOT_REG_CMD 0x18 ++ ++/* Reset Commands */ ++#define NOP_OP_CMD 0x00 ++#define RESET_ENABLE_CMD 0x66 ++#define RESET_MEMORY_CMD 0x99 + + /********************************************************************* + * +@@ -32,6 +92,209 @@ + * + ********************************************************************** + */ ++static QSPI_HandleTypeDef g_flashQspiHandle; ++static uint32_t g_flashReadyStatus = FLASH_STATUS_NO_READY; ++ ++static uint32_t QSPI_ResetChip(void) ++{ ++ QSPI_CommandTypeDef sCommand; ++ uint32_t temp = 0; ++ /* Erasing Sequence ---------------------------------*/ ++ sCommand.InstructionMode= QSPI_INSTRUCTION_1_LINE; ++ sCommand.AddressSize= QSPI_ADDRESS_24_BITS; ++ sCommand.AlternateByteMode= QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DdrMode= QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode= QSPI_SIOO_INST_EVERY_CMD; ++ sCommand.Instruction= RESET_ENABLE_CMD; ++ sCommand.AddressMode= QSPI_ADDRESS_NONE; ++ sCommand.Address= 0; ++ sCommand.DataMode= QSPI_DATA_NONE; ++ sCommand.DummyCycles= QSPI_DUMMY_CYCLES; ++ if(HAL_QSPI_Command(&g_flashQspiHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) ++ { ++ return 1; ++ } ++ for(temp = 0; temp < 0x2f; temp++) ++ { ++ __NOP(); ++ } ++ sCommand.InstructionMode= QSPI_INSTRUCTION_1_LINE; ++ sCommand.AddressSize= QSPI_ADDRESS_24_BITS; ++ sCommand.AlternateByteMode= QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DdrMode= QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode= QSPI_SIOO_INST_EVERY_CMD; ++ sCommand.Instruction= RESET_MEMORY_CMD; ++ sCommand.AddressMode= QSPI_ADDRESS_NONE; ++ sCommand.Address= 0; ++ sCommand.DataMode= QSPI_DATA_NONE; ++ sCommand.DummyCycles= QSPI_DUMMY_CYCLES; ++ if(HAL_QSPI_Command(&g_flashQspiHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK) ++ { ++ return 1; ++ } ++ return 0; ++} ++ ++static uint32_t QSPI_AutoPollingMemReady(uint32_t timeout) ++{ ++ QSPI_CommandTypeDef sCommand; ++ QSPI_AutoPollingTypeDef sConfig; ++ memset(&sCommand, 0, sizeof(sCommand)); ++ memset(&sConfig, 0, sizeof(sConfig)); ++ /* Configure automatic polling mode to wait for memory ready ------*/ ++ sCommand.InstructionMode= QSPI_INSTRUCTION_1_LINE; ++ sCommand.Instruction= READ_STATUS_REG_CMD; ++ sCommand.AddressMode= QSPI_ADDRESS_NONE; ++ sCommand.AlternateByteMode= QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DataMode= QSPI_DATA_1_LINE; ++ sCommand.DummyCycles= QSPI_DUMMY_CYCLES; ++ sCommand.DdrMode= QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode= QSPI_SIOO_INST_EVERY_CMD; ++ sConfig.Match= 0x00; ++ sConfig.Mask= 0x01; ++ sConfig.MatchMode= QSPI_MATCH_MODE_AND; ++ sConfig.StatusBytesSize= 1; ++ sConfig.Interval= 0x10; ++ sConfig.AutomaticStop= QSPI_AUTOMATIC_STOP_ENABLE; ++ if(HAL_QSPI_AutoPolling(&g_flashQspiHandle, &sCommand, &sConfig, timeout) != HAL_OK) ++ { ++ return 1; ++ } ++ return 0; ++} ++ ++static uint32_t QSPI_Configuration(void) ++{ ++ QSPI_CommandTypeDef sCommand; ++ uint8_t test_buffer[4] = { 0 }; ++ /*read status register*/ ++ sCommand.InstructionMode= QSPI_INSTRUCTION_1_LINE; ++ sCommand.Instruction= READ_STATUS_REG_CMD; ++ sCommand.AddressMode= QSPI_ADDRESS_NONE; ++ sCommand.AlternateByteMode= QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DataMode= QSPI_DATA_1_LINE; ++ sCommand.DummyCycles= QSPI_DUMMY_CYCLES; ++ sCommand.DdrMode= QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode= QSPI_SIOO_INST_EVERY_CMD; ++ sCommand.NbData= 1; ++ if(HAL_QSPI_Command(&g_flashQspiHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) ++ { ++ return 1; ++ } ++ if(HAL_QSPI_Receive(&g_flashQspiHandle, test_buffer, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) ++ { ++ return 1; ++ } ++ /*read configuration register*/ ++ sCommand.InstructionMode= QSPI_INSTRUCTION_1_LINE; ++ sCommand.Instruction= READ_CFG_REG_CMD; ++ sCommand.AddressMode= QSPI_ADDRESS_NONE; ++ sCommand.AlternateByteMode= QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DataMode= QSPI_DATA_1_LINE; ++ sCommand.DummyCycles= QSPI_DUMMY_CYCLES; ++ sCommand.DdrMode= QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode= QSPI_SIOO_INST_EVERY_CMD; ++ sCommand.NbData= 1; ++ if(HAL_QSPI_Command(&g_flashQspiHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) ++ { ++ return 1; ++ } ++ ++ if(HAL_QSPI_Receive(&g_flashQspiHandle, &(test_buffer[1]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) ++ { ++ return 1; ++ } ++ ++ /*modify buffer to enable quad mode*/ ++ test_buffer[0] |= 0x40; ++ /*set dummy cycles*/ ++ test_buffer[1] |= 0xC0; ++ sCommand.InstructionMode= QSPI_INSTRUCTION_1_LINE; ++ sCommand.AddressSize= QSPI_ADDRESS_24_BITS; ++ sCommand.AlternateByteMode= QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DdrMode= QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode= QSPI_SIOO_INST_EVERY_CMD; ++ sCommand.Instruction= WRITE_STATUS_REG_CMD; ++ sCommand.AddressMode= QSPI_ADDRESS_NONE; ++ sCommand.DataMode= QSPI_DATA_1_LINE; ++ sCommand.DummyCycles= QSPI_DUMMY_CYCLES; ++ sCommand.NbData= 2; ++ if(HAL_QSPI_Command(&g_flashQspiHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) ++ { ++ return 1; ++ } ++ if(HAL_QSPI_Transmit(&g_flashQspiHandle, test_buffer, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { ++ return 1; ++ } ++ return 0; ++} ++ ++uint32_t QSPI_EnableMemoryMappedMode(void) ++{ ++ QSPI_CommandTypeDef sCommand; ++ QSPI_MemoryMappedTypeDef sMemMappedCfg; ++ /* Enable Memory-Mapped mode------------------------------------------*/ ++ sCommand.InstructionMode= QSPI_INSTRUCTION_1_LINE; ++ sCommand.AddressSize= QSPI_ADDRESS_24_BITS; ++ sCommand.AlternateByteMode= QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DdrMode= QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode= QSPI_SIOO_INST_EVERY_CMD; ++ sCommand.AddressMode= QSPI_ADDRESS_1_LINE; ++ sCommand.DataMode= QSPI_DATA_4_LINES; ++ sCommand.NbData= 0; ++ sCommand.Address= 0; ++ sCommand.Instruction= QUAD_OUT_FAST_READ_CMD; ++ sCommand.DummyCycles= DUMMY_CLOCK_CYCLES_READ_MAP; ++ sMemMappedCfg.TimeOutActivation= QSPI_TIMEOUT_COUNTER_DISABLE; ++ if(HAL_QSPI_MemoryMapped(&g_flashQspiHandle, &sCommand, &sMemMappedCfg) != HAL_OK) ++ { ++ return 1; ++ } ++ return 0; ++} ++ ++static uint32_t QSPI_WriteEnable(void) ++{ ++ QSPI_CommandTypeDef sCommand; ++ QSPI_AutoPollingTypeDef sConfig; ++ memset(&sCommand, 0, sizeof(sCommand)); ++ memset(&sConfig, 0, sizeof(sConfig)); ++ /* Enable write operations ------------------------------------------*/ ++ sCommand.InstructionMode= QSPI_INSTRUCTION_1_LINE; ++ sCommand.Instruction= WRITE_ENABLE_CMD; ++ sCommand.AddressMode= QSPI_ADDRESS_NONE; ++ sCommand.AlternateByteMode= QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DataMode= QSPI_DATA_NONE; ++ sCommand.DummyCycles= QSPI_DUMMY_CYCLES; ++ sCommand.DdrMode= QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode= QSPI_SIOO_INST_EVERY_CMD; ++ if(HAL_QSPI_Command(&g_flashQspiHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK) ++ { ++ return QSPI_ERROR; ++ } ++ /* Configure automatic polling mode to wait for write enabling ----*/ ++ sConfig.Match = 0x02; ++ sConfig.Mask = 0x02; ++ sConfig.MatchMode = QSPI_MATCH_MODE_AND; ++ sConfig.StatusBytesSize = 1; ++ sConfig.Interval = 0x10; ++ sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; ++ sCommand.Instruction = READ_STATUS_REG_CMD; ++ sCommand.DataMode = QSPI_DATA_1_LINE; ++ if(HAL_QSPI_AutoPolling(&g_flashQspiHandle, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) ++ { ++ return QSPI_ERROR; ++ } ++ return QSPI_OK; ++} + + /********************************************************************* + * +@@ -39,11 +302,43 @@ + * + ********************************************************************** + */ ++ + uint32_t Init(uint32_t adr, uint32_t clk, uint32_t fnc) + { +- // +- // No special init required +- // ++ uint32_t ret; ++ g_flashQspiHandle.Instance = QUADSPI; ++ g_flashQspiHandle.Init.ClockPrescaler = 1; ++ g_flashQspiHandle.Init.FifoThreshold = 4; ++ g_flashQspiHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE; ++ g_flashQspiHandle.Init.FlashSize = 23; ++ g_flashQspiHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE; ++ g_flashQspiHandle.Init.ClockMode = QSPI_CLOCK_MODE_0; ++ g_flashQspiHandle.Init.FlashID = QSPI_FLASH_ID_1; ++ g_flashQspiHandle.Init.DualFlash = QSPI_DUALFLASH_DISABLE; ++ if (HAL_QSPI_Init(&g_flashQspiHandle) != HAL_OK){ ++ return 1; ++ } ++ ++ ret = QSPI_ResetChip(); ++ if (ret != 0) { ++ return 1; ++ } ++ ++ ret = QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE); ++ if (ret != 0) { ++ return 1; ++ } ++ ++ ret = QSPI_WriteEnable(); ++ if (ret != 0) { ++ return 1; ++ } ++ ++ ret = QSPI_Configuration(); ++ if (ret != 0) { ++ return 1; ++ } ++ g_flashReadyStatus = FLASH_STATUS_IS_READY; + return (0); + } + +@@ -52,69 +347,193 @@ + // + // No special uninit required + // ++ HAL_QSPI_DeInit(&g_flashQspiHandle); ++ g_flashReadyStatus = FLASH_STATUS_NO_READY; + return (0); + } + + uint32_t EraseChip(void) + { +- FLASH_EraseInitTypeDef erase_init; +- uint32_t error; +- uint32_t ret = 0; // O.K. +- if (g_board_info.target_cfg) { +- HAL_FLASH_Unlock(); +- //bootloader, interface flashing only concerns 1 flash region +- util_assert((g_board_info.target_cfg->flash_regions[0].end - g_board_info.target_cfg->flash_regions[0].start) % +- FLASH_PAGE_SIZE == 0); +- memset(&erase_init, 0, sizeof(erase_init)); +- erase_init.TypeErase = FLASH_TYPEERASE_PAGES; +- erase_init.PageAddress = g_board_info.target_cfg->flash_regions[0].start; +- erase_init.NbPages = (g_board_info.target_cfg->flash_regions[0].end - g_board_info.target_cfg->flash_regions[0].start) % FLASH_PAGE_SIZE; +- if (HAL_FLASHEx_Erase(&erase_init, &error) != HAL_OK) { +- ret = 1; ++ QSPI_CommandTypeDef sCommand; ++ ++ if (g_flashReadyStatus != FLASH_STATUS_IS_READY) { ++ if (Init(0,0,0) != QSPI_OK) { ++ return QSPI_ERROR; + } +- +- HAL_FLASH_Lock(); +- }else{ +- ret = 1; + } +- return ret; ++ ++ if (QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { ++ return QSPI_ERROR; ++ } ++ ++ if (QSPI_WriteEnable() != HAL_OK) { ++ return QSPI_ERROR; ++ } ++ ++ sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE; ++ sCommand.AddressMode = QSPI_ADDRESS_NONE; ++ sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DataMode = QSPI_DATA_NONE; ++ sCommand.DummyCycles = QSPI_DUMMY_CYCLES; ++ sCommand.DdrMode = QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; ++ ++ sCommand.Instruction = CHIP_ERASE_CMD; ++ ++ if (HAL_QSPI_Command(&g_flashQspiHandle, &sCommand,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { ++ return 1; ++ } ++ ++ ++ if (QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE * 16) != QSPI_OK) { ++ return QSPI_ERROR; ++ } ++ return 0; + } + + uint32_t EraseSector(uint32_t adr) + { +- FLASH_EraseInitTypeDef erase_init; +- uint32_t error; +- uint32_t ret = 0; // O.K. ++ QSPI_CommandTypeDef sCommand; ++ uint32_t tmpAddr = 0; + +- HAL_FLASH_Unlock(); +- +- memset(&erase_init, 0, sizeof(erase_init)); +- erase_init.TypeErase = FLASH_TYPEERASE_PAGES; +- erase_init.PageAddress = adr; +- erase_init.NbPages = 1; +- if (HAL_FLASHEx_Erase(&erase_init, &error) != HAL_OK) { +- ret = 1; ++ if (g_flashReadyStatus != FLASH_STATUS_IS_READY) { ++ if (Init(0,0,0) != QSPI_OK) { ++ return QSPI_ERROR; ++ } + } + +- HAL_FLASH_Lock(); +- return ret; ++ if (adr >= FLASH_BASE_SHIFT) { ++ tmpAddr = adr - FLASH_BASE_SHIFT; ++ } ++ ++ if (QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { ++ return QSPI_ERROR; ++ } ++ ++ if (QSPI_WriteEnable() != HAL_OK) { ++ return QSPI_ERROR; ++ } ++ ++ sCommand.InstructionMode= QSPI_INSTRUCTION_1_LINE; ++ sCommand.AddressSize= QSPI_ADDRESS_24_BITS; ++ sCommand.AlternateByteMode= QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DdrMode= QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode= QSPI_SIOO_INST_EVERY_CMD; ++ sCommand.Instruction= SECTOR_ERASE_CMD; ++ sCommand.AddressMode= QSPI_ADDRESS_1_LINE; ++ sCommand.DataMode= QSPI_DATA_NONE; ++ sCommand.DummyCycles= QSPI_DUMMY_CYCLES; ++ ++ sCommand.Address = tmpAddr; ++ ++ if (HAL_QSPI_Command(&g_flashQspiHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { ++ return QSPI_ERROR; ++ } ++ ++ if (QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { ++ return QSPI_ERROR; ++ } ++ return 0; + } + + uint32_t ProgramPage(uint32_t adr, uint32_t sz, uint32_t *buf) + { +- uint32_t i; +- uint32_t ret = 0; // O.K. +- +- HAL_FLASH_Unlock(); ++ QSPI_CommandTypeDef sCommand; ++ uint32_t tmpAddr = 0; + +- util_assert(sz % 4 == 0); +- for (i = 0; i < sz / 4; i++) { +- if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, adr + i * 4, buf[i]) != HAL_OK) { +- ret = 1; +- break; ++ if (g_flashReadyStatus != FLASH_STATUS_IS_READY) { ++ if (Init(0,0,0) != QSPI_OK) { ++ return QSPI_ERROR; + } + } + +- HAL_FLASH_Lock(); +- return ret; ++ if (adr >= FLASH_BASE_SHIFT) { ++ tmpAddr = adr - FLASH_BASE_SHIFT; ++ } ++#ifndef HISPARK_BOOT ++ util_assert(sz % PRG_PAGE_SIZE_SHIFT == 0); ++#endif ++ if (QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { ++ return QSPI_ERROR; ++ } ++ ++ if (QSPI_WriteEnable() != HAL_OK) { ++ return QSPI_ERROR; ++ } ++ ++ sCommand.InstructionMode= QSPI_INSTRUCTION_1_LINE; ++ sCommand.AddressSize= QSPI_ADDRESS_24_BITS; ++ sCommand.AlternateByteMode= QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DdrMode= QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode= QSPI_SIOO_INST_EVERY_CMD; ++ sCommand.Instruction= QUAD_PAGE_PROGRAM_CMD; ++ sCommand.AddressMode= QSPI_ADDRESS_4_LINES; ++ sCommand.DataMode= QSPI_DATA_4_LINES; ++ sCommand.NbData = sz; ++ sCommand.Address = tmpAddr; ++ sCommand.DummyCycles= QSPI_DUMMY_CYCLES; ++ if (HAL_QSPI_Command(&g_flashQspiHandle, &sCommand,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { ++ return 1; ++ } ++ ++ if (HAL_QSPI_Transmit(&g_flashQspiHandle, (uint8_t *)buf, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { ++ return 1; ++ } ++ ++ if (QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { ++ return QSPI_ERROR; ++ } ++ ++ return 0; + } ++ ++uint32_t FlashRead(uint32_t adr, uint32_t sz, uint8_t *buf) ++{ ++ QSPI_CommandTypeDef sCommand; ++ uint32_t tmpAddr = 0; ++ ++ if (g_flashReadyStatus != FLASH_STATUS_IS_READY) { ++ if (Init(0,0,0) != QSPI_OK) { ++ return QSPI_ERROR; ++ } ++ } ++ ++ if (adr >= FLASH_BASE_SHIFT) { ++ tmpAddr = adr - FLASH_BASE_SHIFT; ++ } ++ ++ if (QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { ++ return QSPI_ERROR; ++ } ++ ++ if (QSPI_WriteEnable() != HAL_OK) { ++ return QSPI_ERROR; ++ } ++ sCommand.InstructionMode= QSPI_INSTRUCTION_1_LINE; ++ sCommand.AddressSize= QSPI_ADDRESS_24_BITS; ++ sCommand.AlternateByteMode= QSPI_ALTERNATE_BYTES_NONE; ++ sCommand.DdrMode= QSPI_DDR_MODE_DISABLE; ++ sCommand.DdrHoldHalfCycle= QSPI_DDR_HHC_ANALOG_DELAY; ++ sCommand.SIOOMode= QSPI_SIOO_INST_EVERY_CMD; ++ sCommand.Instruction= FOUR_READ_READ_CMD; ++ sCommand.AddressMode= QSPI_ADDRESS_4_LINES; ++ sCommand.DataMode= QSPI_DATA_4_LINES; ++ sCommand.NbData = sz; ++ sCommand.Address = tmpAddr; ++ sCommand.DummyCycles= DUMMY_CLOCK_CYCLES_READ_QUAD; ++ if (HAL_QSPI_Command(&g_flashQspiHandle, &sCommand,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { ++ return 1; ++ } ++ ++ if (HAL_QSPI_Receive(&g_flashQspiHandle, (uint8_t *)buf, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) { ++ return 1; ++ } ++ ++ if (QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) { ++ return QSPI_ERROR; ++ } ++ return 0; ++} +\ No newline at end of file +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/gpio.c new/CA7/source/hic_hal/stm32/stm32mp1xx/gpio.c +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/gpio.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/gpio.c 2023-06-09 15:41:16.791334600 +0800 +@@ -19,7 +19,7 @@ + * limitations under the License. + */ + +-#include "stm32f1xx.h" ++#include "stm32mp1xx.h" + #include "DAP_config.h" + #include "gpio.h" + #include "daplink.h" +@@ -40,11 +40,11 @@ + static uint32_t tim1_clk_div(uint32_t apb2clkdiv) + { + switch (apb2clkdiv) { +- case RCC_CFGR_PPRE2_DIV2: ++ case RCC_APB2_DIV1: + return 1; +- case RCC_CFGR_PPRE2_DIV4: ++ case RCC_APB2_DIV4: + return 2; +- case RCC_CFGR_PPRE2_DIV8: ++ case RCC_APB2_DIV8: + return 4; + default: // RCC_CFGR_PPRE2_DIV1 + return 1; +@@ -63,7 +63,7 @@ + HAL_RCC_GetClockConfig(&clk_init, &unused); + + /* Compute the period value to have TIMx counter clock equal to 8000000 Hz */ +- source_clock = SystemCoreClock / tim1_clk_div(clk_init.APB2CLKDivider); ++ source_clock = SystemCoreClock / tim1_clk_div(clk_init.APB2_Div); + period = (uint32_t)(source_clock / 8000000) - 1; + + /* Set TIMx instance */ +@@ -112,6 +112,35 @@ + return; + } + ++void gpio_init_buffered_dut_pin(GPIO_TypeDef *dir_port, uint16_t dir_pin, GPIO_TypeDef *input_port, uint16_t input_pin, bool activeHigh) ++{ ++ // Initialize GPIO signals to DUT ++ // ++ // These are "open drain/open collector" signals, with an external buffer (with a direction pin for each line). ++ // The buffer direction is normally an input (to the MCU) so the DUT can pull high/low as needed and a butten can ++ // also pull hi/low manually. ++ // To "activate" the signal the MCU pin has a weak IO pullup/down so when the buffer becomes an output (from the MCU) ++ // the DUT line is driven high/low as needed. ++ ++ GPIO_InitTypeDef GPIO_InitStructure; ++ ++ HAL_GPIO_WritePin(dir_port, dir_pin, GPIO_PIN_RESET); //input to MCU ++ ++ GPIO_InitStructure.Pin = dir_pin; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; ++ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ HAL_GPIO_Init(dir_port, &GPIO_InitStructure); ++ ++ //MCU pin is initialized as an input with pulldown (active low) or pullup (active high) ++ GPIO_InitStructure.Pin = input_pin; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; ++ GPIO_InitStructure.Mode = GPIO_MODE_INPUT; ++ GPIO_InitStructure.Pull = activeHigh ? GPIO_PULLUP : GPIO_PULLDOWN; ++ HAL_GPIO_Init(input_port, &GPIO_InitStructure); ++ GPIO_InitStructure.Pull = GPIO_NOPULL; ++} ++ ++ + void gpio_init(void) + { + GPIO_InitTypeDef GPIO_InitStructure; +@@ -120,24 +149,124 @@ + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); ++ __HAL_RCC_GPIOE_CLK_ENABLE(); //gpio, spi, etc ++ __HAL_RCC_GPIOF_CLK_ENABLE(); //gpio direction, etc. ++ __HAL_RCC_GPIOG_CLK_ENABLE(); //elee: udb led's ++ __HAL_RCC_GPIOH_CLK_ENABLE(); //elee: usb hub signals, SPI, I2C ++ __HAL_RCC_GPIOI_CLK_ENABLE(); //udb usb ulpi dir, spi, jtag + // Enable USB connect pin +- __HAL_RCC_AFIO_CLK_ENABLE(); +- // Disable JTAG to free pins for other uses ++ __HAL_RCC_SYSCFG_CLK_ENABLE(); //elee: this macro maps to the same as __HAL_RCC_AFIO_CLK_ENABLE(); (in the F1) and still exists. Try it... ++ ++ // Disable JTAG to free pins for other uses + // Note - SWD is still enabled +- __HAL_AFIO_REMAP_SWJ_NOJTAG(); ++ //ToDo: elee: this doesn't exist in the H7 hal. Can it be skipped, or need to find a replacement? Skip it for now... ++ //__HAL_AFIO_REMAP_SWJ_NOJTAG(); + + USB_CONNECT_PORT_ENABLE(); + USB_CONNECT_OFF(); +- GPIO_InitStructure.Pin = USB_CONNECT_PIN; ++ GPIO_InitStructure.Pin = USB_CONNECT_PIN; //elee: WHAT does this pin do? PA15? what board is it from? stm429? discovery? MB1075.pdf doesn't have it. I guess USB power (to detect if connected?). Or LED to show USB connected? + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + HAL_GPIO_Init(USB_CONNECT_PORT, &GPIO_InitStructure); +- // configure LEDs +- HAL_GPIO_WritePin(RUNNING_LED_PORT, RUNNING_LED_PIN, GPIO_PIN_SET); +- GPIO_InitStructure.Pin = RUNNING_LED_PIN; +- GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; ++ ++ //config SWD ++ GPIO_InitStructure.Pin = SWDIO_INOUT_OE_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ GPIO_InitStructure.Pull = GPIO_PULLUP; ++ HAL_GPIO_Init(SWDIO_INOUT_OE_PORT, &GPIO_InitStructure); ++ ++ GPIO_InitStructure.Pin = SWCLK_TCK_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ GPIO_InitStructure.Pull = GPIO_PULLDOWN; ++ HAL_GPIO_Init(SWCLK_TCK_PIN_PORT, &GPIO_InitStructure); ++ HAL_GPIO_WritePin(SWCLK_TCK_PIN_PORT, SWCLK_TCK_PIN, GPIO_PIN_SET); ++ ++ GPIO_InitStructure.Pin = SWDIO_OUT_TMS_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ GPIO_InitStructure.Pull = GPIO_PULLUP; ++ HAL_GPIO_Init(SWDIO_OUT_TMS_PIN_PORT, &GPIO_InitStructure); ++ HAL_GPIO_WritePin(SWDIO_OUT_TMS_PIN_PORT, SWDIO_OUT_TMS_PIN, GPIO_PIN_SET); ++ ++ GPIO_InitStructure.Pin = SWDIO_IN_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_INPUT; ++ GPIO_InitStructure.Pull = GPIO_PULLUP; ++ HAL_GPIO_Init(SWDIO_IN_PIN_PORT, &GPIO_InitStructure); ++ ++ ++ GPIO_InitStructure.Pin = JTAG_TDI_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ GPIO_InitStructure.Pull = GPIO_PULLUP; ++ HAL_GPIO_Init(JTAG_TDI_PIN_PORT, &GPIO_InitStructure); ++ HAL_GPIO_WritePin(JTAG_TDI_PIN_PORT, JTAG_TDI_PIN, GPIO_PIN_SET); ++ ++ GPIO_InitStructure.Pin = JTAG_TDO_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_INPUT; ++ GPIO_InitStructure.Pull = GPIO_PULLUP; ++ HAL_GPIO_Init(JTAG_TDO_PIN_PORT, &GPIO_InitStructure); ++ ++ GPIO_InitStructure.Pin = JTAG_TRST_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ GPIO_InitStructure.Pull = GPIO_PULLDOWN; ++ HAL_GPIO_Init(JTAG_TRST_PIN_PORT, &GPIO_InitStructure); ++ HAL_GPIO_WritePin(JTAG_TRST_PIN_PORT, JTAG_TRST_PIN, GPIO_PIN_SET); ++ ++ GPIO_InitStructure.Pin = JTAG_TARGET_RST_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ GPIO_InitStructure.Pull = GPIO_PULLUP; ++ HAL_GPIO_Init(JTAG_TARGET_RST_PIN_PORT, &GPIO_InitStructure); ++ HAL_GPIO_WritePin(JTAG_TARGET_RST_PIN_PORT, JTAG_TARGET_RST_PIN, GPIO_PIN_SET); ++ ++ //config LED ++ GPIO_InitStructure.Pin = OFFLINE_DOWNLOAD_STATUS_LED_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; +- HAL_GPIO_Init(RUNNING_LED_PORT, &GPIO_InitStructure); ++ GPIO_InitStructure.Pull = GPIO_PULLUP; ++ HAL_GPIO_Init(OFFLINE_DOWNLOAD_STATUS_LED_PORT, &GPIO_InitStructure); ++ HAL_GPIO_WritePin(OFFLINE_DOWNLOAD_STATUS_LED_PORT, OFFLINE_DOWNLOAD_STATUS_LED_PIN, GPIO_PIN_SET); ++ ++ //config power switch ++ GPIO_InitStructure.Pin = POWER_SWITCH_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ GPIO_InitStructure.Pull = GPIO_PULLDOWN; ++ HAL_GPIO_Init(POWER_SWITCH_PORT, &GPIO_InitStructure); ++ HAL_GPIO_WritePin(POWER_SWITCH_PORT, POWER_SWITCH_PIN, GPIO_PIN_RESET); ++ ++ //config board ID ++ GPIO_InitStructure.Pin = BOARD_ID0_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_INPUT; ++ GPIO_InitStructure.Pull = GPIO_PULLUP; ++ HAL_GPIO_Init(BOARD_ID0_PORT, &GPIO_InitStructure); ++ ++ GPIO_InitStructure.Pin = BOARD_ID1_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_INPUT; ++ GPIO_InitStructure.Pull = GPIO_PULLUP; ++ HAL_GPIO_Init(BOARD_ID1_PORT, &GPIO_InitStructure); ++ ++ GPIO_InitStructure.Pin = BOARD_ID2_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ GPIO_InitStructure.Mode = GPIO_MODE_INPUT; ++ GPIO_InitStructure.Pull = GPIO_PULLUP; ++ HAL_GPIO_Init(BOARD_ID2_PORT, &GPIO_InitStructure); ++ ++ // configure LEDs ++ // HAL_GPIO_WritePin(RUNNING_LED_PORT, RUNNING_LED_PIN, GPIO_PIN_SET); ++ // GPIO_InitStructure.Pin = RUNNING_LED_PIN; ++ // GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; ++ // GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ // HAL_GPIO_Init(RUNNING_LED_PORT, &GPIO_InitStructure); ++ // // HAL_GPIO_WritePin(RUNNING_LED_PORT, RUNNING_LED_PIN, GPIO_PIN_RESET); ++ // // while(1); + + HAL_GPIO_WritePin(CONNECTED_LED_PORT, CONNECTED_LED_PIN, GPIO_PIN_SET); + GPIO_InitStructure.Pin = CONNECTED_LED_PIN; +@@ -145,39 +274,73 @@ + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + HAL_GPIO_Init(CONNECTED_LED_PORT, &GPIO_InitStructure); + +- HAL_GPIO_WritePin(PIN_CDC_LED_PORT, PIN_CDC_LED, GPIO_PIN_SET); +- GPIO_InitStructure.Pin = PIN_CDC_LED; +- GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; +- GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; +- HAL_GPIO_Init(PIN_CDC_LED_PORT, &GPIO_InitStructure); ++ // HAL_GPIO_WritePin(PIN_CDC_LED_PORT, PIN_CDC_LED, GPIO_PIN_SET); ++ // GPIO_InitStructure.Pin = PIN_CDC_LED; ++ // GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; ++ // GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ // HAL_GPIO_Init(PIN_CDC_LED_PORT, &GPIO_InitStructure); ++ ++ // HAL_GPIO_WritePin(PIN_MSC_LED_PORT, PIN_MSC_LED, GPIO_PIN_SET); ++ // GPIO_InitStructure.Pin = PIN_MSC_LED; ++ // GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; ++ // GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ // HAL_GPIO_Init(PIN_MSC_LED_PORT, &GPIO_InitStructure); ++ ++ // Reset (to DUT): ++ gpio_init_buffered_dut_pin(nRESET_DIR_PIN_PORT, nRESET_DIR_PIN, nRESET_PIN_PORT, nRESET_PIN, false); ++ ++ // Setup the MCO. MCO2 for UDB ++ // GPIO_InitStructure.Pin = GPIO_PIN_9; ++ // GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ++ // GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; ++ // HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); ++ output_clock_enable(); + +- HAL_GPIO_WritePin(PIN_MSC_LED_PORT, PIN_MSC_LED, GPIO_PIN_SET); +- GPIO_InitStructure.Pin = PIN_MSC_LED; +- GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; ++ // Setup the USB Hub to be "self powered" (very common setting, even if not strictly compliant). ++ GPIO_InitStructure.Pin = USBHUB_SELFPWR_PIN; ++ GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; +- HAL_GPIO_Init(PIN_MSC_LED_PORT, &GPIO_InitStructure); ++ HAL_GPIO_Init(USBHUB_SELFPWR_PORT, &GPIO_InitStructure); ++ //HAL_GPIO_WritePin(USBHUB_SELFPWR_PORT, USBHUB_SELFPWR_PIN, GPIO_PIN_RESET); + +- // reset button configured as gpio open drain output with a pullup +- HAL_GPIO_WritePin(nRESET_PIN_PORT, nRESET_PIN, GPIO_PIN_SET); +- GPIO_InitStructure.Pin = nRESET_PIN; +- GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD; +- GPIO_InitStructure.Pull = GPIO_PULLUP; +- HAL_GPIO_Init(nRESET_PIN_PORT, &GPIO_InitStructure); ++ //Initialize bidir buffer control signals ++ // GPIO_InitStructure.Pin = SWD_BUFFER_EN_PIN; ++ // GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; ++ // GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ // HAL_GPIO_WritePin(SWD_BUFFER_EN_PORT, SWD_BUFFER_EN_PIN, GPIO_PIN_RESET); ++ //HAL_GPIO_Init(SWD_BUFFER_EN_PORT, &GPIO_InitStructure); ++ ++ //These are "open drain/open collector" style, with an external buffer. ++ //UDC0_RST_L is configured by the nRESET section above... ++ //UDC0_BOOT_L ++ gpio_init_buffered_dut_pin(UDC0_BOOT_L_DIR_PORT, UDC0_BOOT_L_DIR_PIN, UDC0_BOOT_L_PORT, UDC0_BOOT_L_PIN, false); ++ //UDC0_BUTTON_L ++ gpio_init_buffered_dut_pin(UDC0_BUTTON_L_DIR_PORT, UDC0_BUTTON_L_DIR_PIN, UDC0_BUTTON_L_PORT, UDC0_BUTTON_L_PIN, false); ++ //UDC1_RST ++ gpio_init_buffered_dut_pin(UDC1_RST_DIR_PORT, UDC1_RST_DIR_PIN, UDC1_RST_PORT, UDC1_RST_PIN, true); ++ //UDC1_BOOT ++ gpio_init_buffered_dut_pin(UDC1_BOOT_DIR_PORT, UDC1_BOOT_DIR_PIN, UDC1_BOOT_PORT, UDC1_BOOT_PIN, true); ++ //UDC1_BUTTON ++ gpio_init_buffered_dut_pin(UDC1_BUTTON_DIR_PORT, UDC1_BUTTON_DIR_PIN, UDC1_BUTTON_PORT, UDC1_BUTTON_PIN, true); + + // Turn on power to the board. When the target is unpowered + // it holds the reset line low. ++ // This switched the DUT USB port, using UDC_DUT_USB_EN_L_PIN + HAL_GPIO_WritePin(POWER_EN_PIN_PORT, POWER_EN_PIN, GPIO_PIN_RESET); + GPIO_InitStructure.Pin = POWER_EN_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + HAL_GPIO_Init(POWER_EN_PIN_PORT, &GPIO_InitStructure); + +- // Setup the 8MHz MCO +- GPIO_InitStructure.Pin = GPIO_PIN_8; ++ //Initialize external relay (turned on) ++ HAL_GPIO_WritePin(UDC_EXT_RELAY_PORT, UDC_EXT_RELAY_PIN, GPIO_PIN_SET); ++ GPIO_InitStructure.Pin = UDC_EXT_RELAY_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; +- GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; +- HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); +- output_clock_enable(); ++ GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++ HAL_GPIO_Init(UDC_EXT_RELAY_PORT, &GPIO_InitStructure); ++ ++ ++ //ToDo(elee): Update delay as needed for core clk speed. This is the value from the stm32f1. + + // Let the voltage rails stabilize. This is especailly important + // during software resets, since the target's 3.3v rail can take +@@ -188,22 +351,23 @@ + busy_wait(1000000); + } + ++void gpio_set_daplink_run(gpio_led_state_t state) ++{ ++} ++ + void gpio_set_hid_led(gpio_led_state_t state) + { +- // LED is active low +- HAL_GPIO_WritePin(PIN_HID_LED_PORT, PIN_HID_LED, state ? GPIO_PIN_RESET : GPIO_PIN_SET); ++ // LED is active low + } + + void gpio_set_cdc_led(gpio_led_state_t state) + { + // LED is active low +- HAL_GPIO_WritePin(PIN_CDC_LED_PORT, PIN_CDC_LED, state ? GPIO_PIN_RESET : GPIO_PIN_SET); + } + + void gpio_set_msc_led(gpio_led_state_t state) + { + // LED is active low +- HAL_GPIO_WritePin(PIN_MSC_LED_PORT, PIN_MSC_LED, state ? GPIO_PIN_RESET : GPIO_PIN_SET); + } + + uint8_t gpio_get_reset_btn_no_fwrd(void) +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/IO_Config.h new/CA7/source/hic_hal/stm32/stm32mp1xx/IO_Config.h +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/IO_Config.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/IO_Config.h 2023-12-27 14:15:07.543397210 +0800 +@@ -22,11 +22,49 @@ + #ifndef __IO_CONFIG_H__ + #define __IO_CONFIG_H__ + +-#include "stm32f1xx.h" ++#include "stm32mp1xx.h" + #include "compiler.h" + #include "daplink.h" + +-COMPILER_ASSERT(DAPLINK_HIC_ID == DAPLINK_HIC_ID_STM32F103XB); ++COMPILER_ASSERT(DAPLINK_HIC_ID == DAPLINK_HIC_ID_STM32MP153); ++ ++//OLED SPI & button Pin ++#define SPI4_CLK_PORT GPIOE ++#define SPI4_CLK_PIN GPIO_PIN_2 ++#define SPI4_MOSI_PORT GPIOE ++#define SPI4_MOSI_PIN GPIO_PIN_6 ++#define RESET_OLED_PORT GPIOE ++#define RESET_OLED_PIN GPIO_PIN_3 ++#define SPI4_MISO_DC_PORT GPIOE ++#define SPI4_MISO_DC_PIN GPIO_PIN_5 ++#define SPI4_CS_PORT GPIOE ++#define SPI4_CS_PIN GPIO_PIN_4 ++#define BUTTON_BACK_PORT GPIOB ++#define BUTTON_BACK_PIN GPIO_PIN_9 ++#define BUTTON_NEXT_PORT GPIOC ++#define BUTTON_NEXT_PIN GPIO_PIN_8 ++#define BUTTON_VIEW_PORT GPIOC ++#define BUTTON_VIEW_PIN GPIO_PIN_9 ++ ++//SPI NOR Flash PIN ++#define QUAAD_BK1_NCS_PORT GPIOB ++#define QUAAD_BK1_NCS_PIN GPIO_PIN_6 ++#define QUAAD_CLK_PORT GPIOF ++#define QUAAD_CLK_PIN GPIO_PIN_10 ++#define QUAAD_BK1_IO0_PORT GPIOF ++#define QUAAD_BK1_IO0_PIN GPIO_PIN_8 ++#define QUAAD_BK1_IO1_PORT GPIOF ++#define QUAAD_BK1_IO1_PIN GPIO_PIN_9 ++#define QUAAD_BK1_IO2_PORT GPIOF ++#define QUAAD_BK1_IO2_PIN GPIO_PIN_7 ++#define QUAAD_BK1_IO3_PORT GPIOF ++#define QUAAD_BK1_IO3_PIN GPIO_PIN_6 ++ ++//UART(hiburn) PIN ++#define UART4_TX_PORT GPIOG ++#define UART4_TX_PIN GPIO_PIN_11 ++#define UART4_RX_PORT GPIOB ++#define UART4_RX_PIN GPIO_PIN_2 + + //USB control pin + #define USB_CONNECT_PORT_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +@@ -34,53 +72,235 @@ + #define USB_CONNECT_PORT GPIOA + #define USB_CONNECT_PIN GPIO_PIN_15 + #define USB_CONNECT_ON() (USB_CONNECT_PORT->BSRR = USB_CONNECT_PIN) +-#define USB_CONNECT_OFF() (USB_CONNECT_PORT->BRR = USB_CONNECT_PIN) ++#define USB_CONNECT_OFF() (USB_CONNECT_PORT->BSRR = ((uint32_t)USB_CONNECT_PIN << 16)) + + //Connected LED +-#define CONNECTED_LED_PORT GPIOB +-#define CONNECTED_LED_PIN GPIO_PIN_6 +-#define CONNECTED_LED_PIN_Bit 6 + ++// #define CONNECTED_LED_PORT GPIOA //elee: LED1 on eval board ++// #define CONNECTED_LED_PIN GPIO_PIN_4 //elee: LED1 on eval board ++// #define CONNECTED_LED_PIN_Bit 4 ++ ++#define CONNECTED_LED_PORT GPIOG //elee: LED0 on UDB board ++#define CONNECTED_LED_PIN GPIO_PIN_0 //elee: LED0 on UDB board ++#define CONNECTED_LED_PIN_Bit 0 ++ ++// ToDo(elee): + //When bootloader, disable the target port(not used) +-#define POWER_EN_PIN_PORT GPIOB +-#define POWER_EN_PIN GPIO_PIN_15 +-#define POWER_EN_Bit 15 ++#define POWER_EN_PIN_PORT UDC_DUT_USB_EN_L_PORT ++#define POWER_EN_PIN UDC_DUT_USB_EN_L_PIN ++#define POWER_EN_Bit UDC_DUT_USB_EN_L_PIN_Bit + + // nRESET OUT Pin +-#define nRESET_PIN_PORT GPIOB +-#define nRESET_PIN GPIO_PIN_0 +-#define nRESET_PIN_Bit 0 +- +-//SWD +-#define SWCLK_TCK_PIN_PORT GPIOB +-#define SWCLK_TCK_PIN GPIO_PIN_13 +-#define SWCLK_TCK_PIN_Bit 13 +- +-#define SWDIO_OUT_PIN_PORT GPIOB +-#define SWDIO_OUT_PIN GPIO_PIN_14 +-#define SWDIO_OUT_PIN_Bit 14 +- +-#define SWDIO_IN_PIN_PORT GPIOB +-#define SWDIO_IN_PIN GPIO_PIN_12 +-#define SWDIO_IN_PIN_Bit 12 ++// JTAG0_MCU_UDC_RESET_L, UDC0_RST_L ++#define nRESET_PIN_PORT GPIOI ++#define nRESET_PIN GPIO_PIN_4 ++#define nRESET_PIN_Bit 4 ++ ++// nRESET DIR Pin ++// JTAG0_NRESET_DIR ++#define nRESET_DIR_PIN_PORT GPIOF ++#define nRESET_DIR_PIN GPIO_PIN_8 ++#define nRESET_DIR_PIN_Bit 8 ++ ++//SWD/JTAG ++// JTAG0_MCU_UDC_TCK_SWDCLK ++#define SWCLK_TCK_PIN_PORT GPIOA ++#define SWCLK_TCK_PIN GPIO_PIN_9 ++#define SWCLK_TCK_PIN_BIT 9 ++ ++#define SWDIO_OUT_TMS_PIN_PORT GPIOA ++#define SWDIO_OUT_TMS_PIN GPIO_PIN_8 ++#define SWDIO_OUT_TMS_PIN_BIT 8 ++ ++#define SWDIO_IN_PIN_PORT GPIOA ++#define SWDIO_IN_PIN GPIO_PIN_0 ++#define SWDIO_IN_PIN_BIT 0 ++ ++#define SWDIO_INOUT_OE_PORT GPIOA ++#define SWDIO_INOUT_OE_PIN GPIO_PIN_3 ++#define SWDIO_INOUT_OE_PIN_BIT 3 ++ ++#define JTAG_TDI_PIN_PORT GPIOA ++#define JTAG_TDI_PIN GPIO_PIN_1 ++#define JTAG_TDI_PIN_BIT 1 ++ ++#define JTAG_TDO_PIN_PORT GPIOA ++#define JTAG_TDO_PIN GPIO_PIN_2 ++#define JTAG_TDO_PIN_BIT 2 ++ ++#define JTAG_TRST_PIN_PORT GPIOA ++#define JTAG_TRST_PIN GPIO_PIN_14 ++#define JTAG_TPST_PIN_BIT 14 ++ ++#define JTAG_TARGET_RST_PIN_PORT GPIOA ++#define JTAG_TARGET_RST_PIN GPIO_PIN_13 ++#define JTAG_TARGET_RST_PIN_BIT 13 + + //LEDs +-//USB status LED +-#define RUNNING_LED_PORT GPIOA +-#define RUNNING_LED_PIN GPIO_PIN_9 +-#define RUNNING_LED_Bit 9 +- +-#define PIN_HID_LED_PORT GPIOA +-#define PIN_HID_LED GPIO_PIN_9 +-#define PIN_HID_LED_Bit 9 +- +-#define PIN_CDC_LED_PORT GPIOA +-#define PIN_CDC_LED GPIO_PIN_9 +-#define PIN_CDC_LED_Bit 9 +- +-#define PIN_MSC_LED_PORT GPIOA +-#define PIN_MSC_LED GPIO_PIN_9 +-#define PIN_MSC_LED_Bit 9 ++#define OFFLINE_DOWNLOAD_STATUS_LED_PORT GPIOA ++#define OFFLINE_DOWNLOAD_STATUS_LED_PIN GPIO_PIN_6 ++#define OFFLINE_DOWNLOAD_STATUS_LED_Bit 6 ++ ++#define POWER_SWITCH_PORT GPIOA ++#define POWER_SWITCH_PIN GPIO_PIN_7 ++#define POWER_SWITCH_Bit 7 ++ ++//Board ID ++#define BOARD_ID0_PORT GPIOB ++#define BOARD_ID0_PIN GPIO_PIN_0 ++#define BOARD_ID0_Bit 0 ++ ++#define BOARD_ID1_PORT GPIOB ++#define BOARD_ID1_PIN GPIO_PIN_1 ++#define BOARD_ID1_Bit 1 ++ ++#define BOARD_ID2_PORT GPIOC ++#define BOARD_ID2_PIN GPIO_PIN_5 ++#define BOARD_ID2_Bit 5 ++ ++//UDB specific signals ++#define USBHUB_SELFPWR_PORT GPIOH ++#define USBHUB_SELFPWR_PIN GPIO_PIN_14 ++#define USBHUB_SELFPWR_PIN_Bit 14 ++ ++ ++//DUT USB port power switch ++//VBUS_DUT_EN_L ++#define UDC_DUT_USB_EN_L_PORT GPIOH ++#define UDC_DUT_USB_EN_L_PIN GPIO_PIN_10 ++#define UDC_DUT_USB_EN_L_PIN_Bit 10 ++ ++//External power relay control ++//EXT_RELAY_EN ++#define UDC_EXT_RELAY_PORT GPIOE ++#define UDC_EXT_RELAY_PIN GPIO_PIN_11 ++#define UDC_EXT_RELAY_PIN_Bit 11 ++ ++ ++//GPIO LINES ++//Open Drain/Collector usage: MCU IO has pulldown/up enabled. ++//External buffer set to OUT to pull low/high, and IN to be high-z ++//JTAG0_MCU_UDC_RESET_L, JTAG0_NRESET_DIR ++#define UDC0_RST_L_PORT nRESET_PIN_PORT ++#define UDC0_RST_L_PIN nRESET_PIN ++#define UDC0_RST_L_PIN_Bit nRESET_PIN_Bit ++#define UDC0_RST_L_DIR_PORT nRESET_DIR_PIN_PORT ++#define UDC0_RST_L_DIR_PIN nRESET_DIR_PIN ++#define UDC0_RST_L_DIR_PIN_Bit nRESET_DIR_PIN_Bit ++ ++//MCU_BOOT0_UDC_L, BOOT0_DIR ++#define UDC0_BOOT_L_PORT GPIOE ++#define UDC0_BOOT_L_PIN GPIO_PIN_7 ++#define UDC0_BOOT_L_PIN_Bit 7 ++#define UDC0_BOOT_L_DIR_PORT GPIOE ++#define UDC0_BOOT_L_DIR_PIN GPIO_PIN_15 ++#define UDC0_BOOT_L_DIR_PIN_Bit 15 ++ ++//MCU_BUT_USR0_UDC_L, BUT_USR0_DIR ++#define UDC0_BUTTON_L_PORT GPIOE ++#define UDC0_BUTTON_L_PIN GPIO_PIN_8 ++#define UDC0_BUTTON_L_PIN_Bit 8 ++#define UDC0_BUTTON_L_DIR_PORT GPIOF ++#define UDC0_BUTTON_L_DIR_PIN GPIO_PIN_2 ++#define UDC0_BUTTON_L_DIR_PIN_Bit 2 ++ ++//JTAG1_MCU_UDC_RESET, JTAG1_RESET_DIR ++#define UDC1_RST_PORT GPIOI ++#define UDC1_RST_PIN GPIO_PIN_9 ++#define UDC1_RST_PIN_Bit 9 ++#define UDC1_RST_DIR_PORT GPIOB ++#define UDC1_RST_DIR_PIN GPIO_PIN_4 ++#define UDC1_RST_DIR_PIN_Bit 4 ++ ++//MCU_BOOT1_UDC, BOOT1_DIR ++#define UDC1_BOOT_PORT GPIOE ++#define UDC1_BOOT_PIN GPIO_PIN_1 ++#define UDC1_BOOT_PIN_Bit 1 ++#define UDC1_BOOT_DIR_PORT GPIOE ++#define UDC1_BOOT_DIR_PIN GPIO_PIN_13 ++#define UDC1_BOOT_DIR_PIN_Bit 13 ++ ++//MCU_BUT_USR1_UDC, BUT_USR1_DIR ++#define UDC1_BUTTON_PORT GPIOE ++#define UDC1_BUTTON_PIN GPIO_PIN_3 ++#define UDC1_BUTTON_PIN_Bit 3 ++#define UDC1_BUTTON_DIR_PORT GPIOE ++#define UDC1_BUTTON_DIR_PIN GPIO_PIN_14 ++#define UDC1_BUTTON_DIR_PIN_Bit 14 ++ ++// ehassman ++// From MX_Device.h ++/*-------------------------------- I2C1 --------------------------------*/ ++// I2C1 ++// #define MX_I2C1 1 ++/* Pin PB6 */ ++#define MX_I2C1_SCL_GPIO_Speed GPIO_SPEED_FREQ_LOW ++#define MX_I2C1_SCL_GPIO_FM6 __NULL ++#define MX_I2C1_SCL_Pin PB6 ++#define MX_I2C1_SCL_GPIOx GPIOB ++#define MX_I2C1_SCL_GPIO_PuPd GPIO_NOPULL ++#define MX_I2C1_SCL_GPIO_Pin GPIO_PIN_6 ++#define MX_I2C1_SCL_GPIO_AF GPIO_AF4_I2C1 ++#define MX_I2C1_SCL_GPIO_Mode GPIO_MODE_AF_OD ++ ++/* Pin PB7 */ ++#define MX_I2C1_SDA_GPIO_Speed GPIO_SPEED_FREQ_LOW ++#define MX_I2C1_SDA_Pin PB7 ++#define MX_I2C1_SDA_GPIOx GPIOB ++#define MX_I2C1_SDA_GPIO_PuPd GPIO_NOPULL ++#define MX_I2C1_SDA_GPIO_Pin GPIO_PIN_7 ++#define MX_I2C1_SDA_GPIO_AF GPIO_AF4_I2C1 ++#define MX_I2C1_SDA_GPIO_FM7 __NULL ++#define MX_I2C1_SDA_GPIO_Mode GPIO_MODE_AF_OD ++ ++ ++// I2C2 ++#define MX_I2C2 1 ++ ++/* Pin PF1 */ ++#define MX_I2C2_SCL_GPIO_Speed GPIO_SPEED_FREQ_LOW ++#define MX_I2C2_SCL_GPIO_FM6 __NULL ++#define MX_I2C2_SCL_Pin PF1 ++#define MX_I2C2_SCL_GPIOx GPIOF ++#define MX_I2C2_SCL_GPIO_PuPd GPIO_NOPULL ++#define MX_I2C2_SCL_GPIO_Pin GPIO_PIN_1 ++#define MX_I2C2_SCL_GPIO_AF GPIO_AF4_I2C2 ++#define MX_I2C2_SCL_GPIO_Mode GPIO_MODE_AF_OD ++ ++/* Pin PF0 */ ++#define MX_I2C2_SDA_GPIO_Speed GPIO_SPEED_FREQ_LOW ++#define MX_I2C2_SDA_Pin PF0 ++#define MX_I2C2_SDA_GPIOx GPIOF ++#define MX_I2C2_SDA_GPIO_PuPd GPIO_NOPULL ++#define MX_I2C2_SDA_GPIO_Pin GPIO_PIN_0 ++#define MX_I2C2_SDA_GPIO_AF GPIO_AF4_I2C2 ++#define MX_I2C2_SDA_GPIO_FM7 __NULL ++#define MX_I2C2_SDA_GPIO_Mode GPIO_MODE_AF_OD ++ ++ ++/*---------------------------- Clock Configuration ---------------------------*/ ++ ++#define MX_LSI_VALUE 32000 ++#define MX_LSE_VALUE 32768 ++#define MX_HSI_VALUE 64000000 ++#define MX_HSE_VALUE 25000000 ++#define MX_EXTERNAL_CLOCK_VALUE 12288000 ++#define MX_PLLDSIFreq_Value 500000000 ++#define MX_SYSCLKFreq_VALUE 400000000 ++#define MX_HCLKFreq_Value 100000000 ++#define MX_CortexFreq_Value 400000000 ++#define MX_APB1Freq_Value 25000000 ++#define MX_APB2Freq_Value 25000000 ++#define MX_CECFreq_Value 32000 ++#define MX_RTCFreq_Value 32000 ++#define MX_USBFreq_Value 400000000 ++#define MX_WatchDogFreq_Value 32000 ++#define MX_DSIFreq_Value 96000000 ++#define MX_DSIPHYCLKFreq_Value 96000000 ++#define MX_DSITXEscFreq_Value 20000000 ++#define MX_SPDIFRXFreq_Value 400000000 ++#define MX_MCO1PinFreq_Value 64000000 ++#define MX_MCO2PinFreq_Value 400000000 + + + #endif +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/read_uid.c new/CA7/source/hic_hal/stm32/stm32mp1xx/read_uid.c +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/read_uid.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/read_uid.c 2023-05-25 15:09:49.000000000 +0800 +@@ -18,18 +18,18 @@ + * See the License for the specific language governing permissions and + * limitations under the License. + */ +- +-#include "stm32f1xx.h" ++ ++#include "stm32mp1xx.h" + #include "read_uid.h" + + void read_unique_id(uint32_t *id) + { +- uint32_t Device_Serial0, Device_Serial1, Device_Serial2; +- +- Device_Serial0 = *(uint32_t*)(0x1FFFF7E8); +- Device_Serial1 = *(uint32_t*)(0x1FFFF7EC); +- Device_Serial2 = *(uint32_t*)(0x1FFFF7F0); +- ++ uint32_t Device_Serial0, Device_Serial1, Device_Serial2; ++ ++ Device_Serial0 = *(uint32_t*)(0x5C005234); ++ Device_Serial1 = *(uint32_t*)(0x5C005238); ++ Device_Serial2 = *(uint32_t*)(0x5C00523C); ++ + id[0] = Device_Serial0; + id[1] = Device_Serial1; + id[2] = Device_Serial2; +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/sdk.c new/CA7/source/hic_hal/stm32/stm32mp1xx/sdk.c +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/sdk.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/sdk.c 2023-05-25 15:09:49.000000000 +0800 +@@ -19,17 +19,36 @@ + * limitations under the License. + */ + +-#include "stm32f1xx.h" ++#include "stm32mp1xx.h" ++#include "stm32mp1xx_hal.h" ++#ifndef HISPARK_BOOT + #include "DAP_config.h" + #include "gpio.h" + #include "daplink.h" ++#endif + #include "util.h" +-#include "cortex_m.h" ++#include "sdk.h" ++#ifndef HISPARK_BOOT ++#include "interrupt.h" ++#endif ++#include "oled.h" ++#include "display.h" ++#include "key.h" ++ ++ ++extern void SystemCoreClockUpdate(void); ++extern void MX_USB_OTG_FS_PCD_Init(void); ++extern void MX_USB_OTG_HS_PCD_Init(void); ++void SystemClock_Config(void); ++void Error_Handler(void); + + TIM_HandleTypeDef timer; + uint32_t time_count; + +-static uint32_t tim2_clk_div(uint32_t apb1clkdiv); ++void MX_GPIO_Init(void) ++{ ++} ++ + + /** + * @brief Switch the PLL source from HSI to HSE bypass, and select the PLL as SYSCLK +@@ -50,84 +69,42 @@ + */ + void sdk_init() + { +- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; +- RCC_OscInitTypeDef RCC_OscInitStruct = {0}; +- +- SystemCoreClockUpdate(); ++ //todo: elee: Review this some more. For now just call the stm32cube startup files (from the cube generated main). + HAL_Init(); ++ /* USER CODE BEGIN Init */ ++ /* USER CODE END Init */ ++ /* Configure the system clock */ ++#ifndef HISPARK_BOOT ++ SystemClock_Config(); ++ SystemCoreClockUpdate(); + +- /* Select HSI as system clock source to allow modification of the PLL configuration */ +- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK; +- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; +- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { +- /* Initialization Error */ +- util_assert(0); +- } +- +- /* Enable HSE bypass Oscillator, select it as PLL source and finally activate the PLL */ +- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; +- RCC_OscInitStruct.HSEState = RCC_CR_HSEON; +- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; +- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; +- RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; +- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; +- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { +- /* Initialization Error */ +- util_assert(0); +- } +- +- /* Select the PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ +- RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); +- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; +- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; +- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; +- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; +- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { +- /* Initialization Error */ +- util_assert(0); +- } ++ IRQ_Init(); ++#endif ++ /* USER CODE BEGIN SysInit */ ++ /* USER CODE END SysInit */ ++ /* Initialize all configured peripherals */ ++ MX_GPIO_Init(); ++ ++ OledInit(); ++ KeyInit(); ++ ++#ifndef HISPARK_BOOT ++ pin_out_init(CONNECTED_LED_PORT, CONNECTED_LED_PIN_Bit); ++ CONNECTED_LED_PORT->BSRR = CONNECTED_LED_PIN; ++ ++ //elee: toggle the pin, see the LED do something. ++ HAL_Delay(100); ++ CONNECTED_LED_PORT->BSRR = (CONNECTED_LED_PIN << 16); ++#endif + } + + HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) + { +- HAL_StatusTypeDef ret; +- RCC_ClkInitTypeDef clk_init; +- uint32_t unused; +- uint32_t prescaler; +- uint32_t source_clock; +- +- HAL_RCC_GetClockConfig(&clk_init, &unused); +- +- /* Compute the prescaler value to have TIMx counter clock equal to 4000 Hz */ +- source_clock = SystemCoreClock / tim2_clk_div(clk_init.APB1CLKDivider); +- prescaler = (uint32_t)(source_clock / 4000) - 1; +- +- /* Set TIMx instance */ +- timer.Instance = TIM2; +- +- timer.Init.Period = 0xFFFF; +- timer.Init.Prescaler = prescaler; +- timer.Init.ClockDivision = 0; +- timer.Init.CounterMode = TIM_COUNTERMODE_UP; +- timer.Init.RepetitionCounter = 0; +- +- __HAL_RCC_TIM2_CLK_ENABLE(); +- +- ret = HAL_TIM_Base_DeInit(&timer); +- if (ret != HAL_OK) { +- return ret; +- } +- +- time_count = 0; +- ret = HAL_TIM_Base_Init(&timer); +- if (ret != HAL_OK) { +- return ret; +- } +- +- ret = HAL_TIM_Base_Start(&timer); +- if (ret != HAL_OK) { +- return ret; +- } ++ STGENC_TypeDef *stgenc = (STGENC_TypeDef *)STGENC; ++ stgenc->CNTCR = 0; ++ stgenc->CNTCVL = 0; ++ stgenc->CNTCVU = 0; ++ stgenc->CNTCR = 1; + + return HAL_OK; + } +@@ -140,11 +117,29 @@ + + uint32_t HAL_GetTick(void) + { +- cortex_int_state_t state; +- state = cortex_int_get_and_disable(); +- const uint32_t ticks = __HAL_TIM_GET_COUNTER(&timer) / 4; +- time_count += (ticks - time_count) & 0x3FFF; +- cortex_int_restore(state); ++ //HAL_InitTick在系统HSE起来前就被调用,因此使用了HSI的时钟 ++ STGENC_TypeDef *stgenc = (STGENC_TypeDef *)STGENC; ++ const uint32_t ticks = HSI_VALUE / 1000; ++ uint64_t ts = stgenc->CNTCVU; ++ ts <<= 32; ++ ts += stgenc->CNTCVL; ++ ts /= ticks; ++ time_count = (uint32_t)(ts & 0xFFFFFFFF); ++ ++ return time_count; ++} ++ ++uint32_t HAL_GetTickUs(void) ++{ ++ //HAL_InitTick在系统HSE起来前就被调用,因此使用了HSI的时钟 ++ STGENC_TypeDef *stgenc = (STGENC_TypeDef *)STGENC; ++ const uint32_t ticks = HSI_VALUE / 1000000; ++ uint64_t ts = stgenc->CNTCVU; ++ ts <<= 32; ++ ts += stgenc->CNTCVL; ++ ts /= ticks; ++ time_count = (uint32_t)(ts & 0xFFFFFFFF); ++ + return time_count; + } + +@@ -158,18 +153,122 @@ + HAL_TIM_Base_Stop(&timer); + } + +-static uint32_t tim2_clk_div(uint32_t apb1clkdiv) ++/** ++ * @brief System Clock Configuration ++ * @retval None ++ */ ++void SystemClock_Config(void) + { +- switch (apb1clkdiv) { +- case RCC_CFGR_PPRE1_DIV2: +- return 1; +- case RCC_CFGR_PPRE1_DIV4: +- return 2; +- case RCC_CFGR_PPRE1_DIV8: +- return 4; +- case RCC_CFGR_PPRE1_DIV16: +- return 8; +- default: +- return 1; +- } ++ RCC_OscInitTypeDef RCC_OscInitStruct = {0}; ++ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; ++ ++ HAL_RCC_DeInit(); ++ /**Configure LSE Drive Capability ++ */ ++ HAL_PWR_EnableBkUpAccess(); ++ __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_MEDIUMHIGH); ++ ++ /**Initializes the CPU, AHB and APB busses clocks ++ */ ++ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE; ++ RCC_OscInitStruct.HSEState = RCC_HSE_ON; ++ RCC_OscInitStruct.HSIState = RCC_HSI_ON; ++ RCC_OscInitStruct.HSICalibrationValue = 16; ++ RCC_OscInitStruct.HSIDivValue = RCC_HSI_DIV1; ++ ++ /**PLL1 Config ++ */ ++ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; ++ RCC_OscInitStruct.PLL.PLLSource = RCC_PLL12SOURCE_HSE; ++ RCC_OscInitStruct.PLL.PLLM = 3; ++ RCC_OscInitStruct.PLL.PLLN = 100; ++ RCC_OscInitStruct.PLL.PLLP = 1; ++ RCC_OscInitStruct.PLL.PLLQ = 1; ++ RCC_OscInitStruct.PLL.PLLR = 1; ++ RCC_OscInitStruct.PLL.PLLFRACV = 0; ++ RCC_OscInitStruct.PLL.PLLMODE = RCC_PLL_FRACTIONAL; ++ RCC_OscInitStruct.PLL.RPDFN_DIS = RCC_RPDFN_DIS_DISABLED; ++ RCC_OscInitStruct.PLL.TPDFN_DIS = RCC_TPDFN_DIS_DISABLED; ++ ++ /**PLL2 Config ++ */ ++ RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_ON; ++ RCC_OscInitStruct.PLL2.PLLSource = RCC_PLL12SOURCE_HSE; ++ RCC_OscInitStruct.PLL2.PLLM = 3; ++ RCC_OscInitStruct.PLL2.PLLN = 66; ++ RCC_OscInitStruct.PLL2.PLLP = 2; ++ RCC_OscInitStruct.PLL2.PLLQ = 1; ++ RCC_OscInitStruct.PLL2.PLLR = 1; ++ RCC_OscInitStruct.PLL2.PLLFRACV = 5120; ++ RCC_OscInitStruct.PLL2.PLLMODE = RCC_PLL_FRACTIONAL; ++ RCC_OscInitStruct.PLL2.RPDFN_DIS = RCC_RPDFN_DIS_DISABLED; ++ RCC_OscInitStruct.PLL2.TPDFN_DIS = RCC_TPDFN_DIS_DISABLED; ++ ++ /**PLL3 Config ++ */ ++ RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_ON; ++ RCC_OscInitStruct.PLL3.PLLSource = RCC_PLL3SOURCE_HSE; ++ RCC_OscInitStruct.PLL3.PLLM = 2; ++ RCC_OscInitStruct.PLL3.PLLN = 34; ++ RCC_OscInitStruct.PLL3.PLLP = 2; ++ RCC_OscInitStruct.PLL3.PLLQ = 17; ++ RCC_OscInitStruct.PLL3.PLLR = 37; ++ RCC_OscInitStruct.PLL3.PLLRGE = RCC_PLL3IFRANGE_1; ++ RCC_OscInitStruct.PLL3.PLLFRACV = 0x1A04; ++ RCC_OscInitStruct.PLL3.PLLMODE = RCC_PLL_FRACTIONAL; ++ RCC_OscInitStruct.PLL3.RPDFN_DIS = RCC_RPDFN_DIS_DISABLED; ++ RCC_OscInitStruct.PLL3.TPDFN_DIS = RCC_TPDFN_DIS_DISABLED; ++ ++ /**PLL4 Config ++ */ ++ RCC_OscInitStruct.PLL4.PLLState = RCC_PLL_ON; ++ RCC_OscInitStruct.PLL4.PLLSource = RCC_PLL4SOURCE_HSE; ++ RCC_OscInitStruct.PLL4.PLLM = 4; ++ RCC_OscInitStruct.PLL4.PLLN = 99; ++ RCC_OscInitStruct.PLL4.PLLP = 6; ++ RCC_OscInitStruct.PLL4.PLLQ = 8; ++ RCC_OscInitStruct.PLL4.PLLR = 8; ++ RCC_OscInitStruct.PLL4.PLLRGE = RCC_PLL4IFRANGE_0; ++ RCC_OscInitStruct.PLL4.PLLFRACV = 0; ++ RCC_OscInitStruct.PLL4.PLLMODE = RCC_PLL_INTEGER; ++ RCC_OscInitStruct.PLL4.RPDFN_DIS = RCC_RPDFN_DIS_DISABLED; ++ RCC_OscInitStruct.PLL4.TPDFN_DIS = RCC_TPDFN_DIS_DISABLED; ++ ++ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) ++ { ++ Error_Handler(); ++ } ++ /**RCC Clock Config ++ */ ++ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_ACLK ++ |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 ++ |RCC_CLOCKTYPE_PCLK3|RCC_CLOCKTYPE_PCLK4 ++ |RCC_CLOCKTYPE_PCLK5|RCC_CLOCKTYPE_MPU; ++ RCC_ClkInitStruct.MPUInit.MPU_Clock = RCC_MPUSOURCE_PLL1; ++ RCC_ClkInitStruct.MPUInit.MPU_Div = RCC_MPU_DIV2; ++ RCC_ClkInitStruct.AXISSInit.AXI_Clock = RCC_AXISSOURCE_PLL2; ++ RCC_ClkInitStruct.AXISSInit.AXI_Div = RCC_AXI_DIV1; ++ RCC_ClkInitStruct.MCUInit.MCU_Clock = RCC_MCUSSOURCE_PLL3; ++ RCC_ClkInitStruct.MCUInit.MCU_Div = RCC_MCU_DIV1; ++ RCC_ClkInitStruct.APB4_Div = RCC_APB4_DIV2; ++ RCC_ClkInitStruct.APB5_Div = RCC_APB5_DIV4; ++ RCC_ClkInitStruct.APB1_Div = RCC_APB1_DIV2; ++ RCC_ClkInitStruct.APB2_Div = RCC_APB2_DIV2; ++ RCC_ClkInitStruct.APB3_Div = RCC_APB3_DIV2; ++ ++ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != HAL_OK) ++ { ++ Error_Handler(); ++ } ++ ++ /**Set the HSE division factor for RTC clock ++ */ ++ // __HAL_RCC_RTC_HSEDIV(24); + } ++ ++ ++void Error_Handler(void) ++{ ++ /* USER CODE BEGIN Error_Handler_Debug */ ++ /* USER CODE END Error_Handler_Debug */ ++} +\ No newline at end of file +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/stm32mp153dxx_ca7.h new/CA7/source/hic_hal/stm32/stm32mp1xx/stm32mp153dxx_ca7.h +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/stm32mp153dxx_ca7.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/stm32mp153dxx_ca7.h 2023-05-25 15:09:49.000000000 +0800 +@@ -269,8 +269,13 @@ + #define GIC_DISTRIBUTOR_BASE GIC_BASE + #define GIC_INTERFACE_BASE (GIC_BASE+0x1000) + ++#ifdef HISPARK_TRACE ++#include "cmsis_compiler.h" ++#endif + #include "core_ca.h" ++#ifndef HISPARK_TRACE + #include "system_stm32mp1xx_A7.h" ++#endif + + + +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/stm32mp1xx.h new/CA7/source/hic_hal/stm32/stm32mp1xx/stm32mp1xx.h +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/stm32mp1xx.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/stm32mp1xx.h 2023-05-25 15:09:49.000000000 +0800 +@@ -42,6 +42,10 @@ + extern "C" { + #endif /* __cplusplus */ + ++#ifdef HISPARK_TRACE ++extern unsigned int SystemCoreClock; ++#endif ++ + /** @addtogroup Library_configuration_section + * @{ + */ +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/stm32mp1xx_hal_conf.h new/CA7/source/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/stm32mp1xx_hal_conf.h +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/stm32mp1xx_hal_conf.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/STM32MP1xx_HAL_Driver/stm32mp1xx_hal_conf.h 2023-05-25 15:09:49.000000000 +0800 +@@ -46,31 +46,47 @@ + /*#define HAL_DFSDM_MODULE_ENABLED */ + /*#define HAL_FDCAN_MODULE_ENABLED */ + /*#define HAL_HASH_MODULE_ENABLED */ ++#define HAL_HSEM_MODULE_ENABLED + /*#define HAL_I2C_MODULE_ENABLED */ ++/*#define HAL_I2S_MODULE_ENABLED */ + /*#define HAL_IPCC_MODULE_ENABLED */ + /*#define HAL_LPTIM_MODULE_ENABLED */ +-/*#define HAL_QSPI_MODULE_ENABLED */ ++#define HAL_QSPI_MODULE_ENABLED + /*#define HAL_RNG_MODULE_ENABLED */ + /*#define HAL_SAI_MODULE_ENABLED */ + /*#define HAL_SD_MODULE_ENABLED */ +-/*#define HAL_MMC_MODULE_ENABLED */ ++/*#define HAL_SMARTCARD_MODULE_ENABLED */ + /*#define HAL_RTC_MODULE_ENABLED */ + /*#define HAL_SMBUS_MODULE_ENABLED */ + /*#define HAL_SPDIFRX_MODULE_ENABLED */ + /*#define HAL_SPI_MODULE_ENABLED */ +-/*#define HAL_TIM_MODULE_ENABLED */ +-/*#define HAL_UART_MODULE_ENABLED */ +-/*#define HAL_USART_MODULE_ENABLED */ ++/*#define HAL_SRAM_MODULE_ENABLED */ ++#define HAL_TIM_MODULE_ENABLED ++ #define HAL_UART_MODULE_ENABLED ++#define HAL_USART_MODULE_ENABLED + /*#define HAL_WWDG_MODULE_ENABLED */ +-#define HAL_EXTI_MODULE_ENABLED +-#define HAL_HSEM_MODULE_ENABLED + #define HAL_GPIO_MODULE_ENABLED ++#define HAL_EXTI_MODULE_ENABLED + #define HAL_DMA_MODULE_ENABLED +-/*#define HAL_MDMA_MODULE_ENABLED */ ++#define HAL_MDMA_MODULE_ENABLED + #define HAL_RCC_MODULE_ENABLED + #define HAL_PWR_MODULE_ENABLED + #define HAL_CORTEX_MODULE_ENABLED + ++/* ########################## Register Callbacks selection ############################## */ ++/** ++ * @brief This is the list of modules where register callback can be used ++ */ ++#define USE_HAL_ADC_REGISTER_CALLBACKS 0u ++#define USE_HAL_CEC_REGISTER_CALLBACKS 0u ++#define USE_HAL_DAC_REGISTER_CALLBACKS 0u ++#define USE_HAL_I2C_REGISTER_CALLBACKS 0u ++#define USE_HAL_RNG_REGISTER_CALLBACKS 0u ++#define USE_HAL_SPI_REGISTER_CALLBACKS 0u ++#define USE_HAL_UART_REGISTER_CALLBACKS 0u ++#define USE_HAL_USART_REGISTER_CALLBACKS 0u ++#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u ++ + /* ########################## Oscillator Values adaptation ####################*/ + /** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. +@@ -95,6 +111,14 @@ + #endif /* HSI_VALUE */ + + /** ++ * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup ++ * Timeout value ++ */ ++#if !defined (HSI_STARTUP_TIMEOUT) ++ #define HSI_STARTUP_TIMEOUT 5000U /*!< Time out for HSI start up */ ++#endif /* HSI_STARTUP_TIMEOUT */ ++ ++/** + * @brief Internal Low Speed oscillator (LSI) value. + */ + #if !defined (LSI_VALUE) +@@ -124,6 +148,9 @@ + #endif /* CSI_VALUE */ + + /** ++ * @brief External clock source for I2S peripheral ++ * This value is used by the I2S HAL module to compute the I2S clock source ++ * frequency, this source is inserted directly through I2S_CKIN pad. + */ + #if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the External clock in Hz*/ +@@ -212,10 +239,6 @@ + #include "stm32mp1xx_hal_dfsdm.h" + #endif /* HAL_DFSDM_MODULE_ENABLED */ + +-#ifdef HAL_EXTI_MODULE_ENABLED +- #include "stm32mp1xx_hal_exti.h" +-#endif /* HAL_EXTI_MODULE_ENABLED */ +- + #ifdef HAL_FDCAN_MODULE_ENABLED + #include "stm32mp1xx_hal_fdcan.h" + #endif /* HAL_FDCAN_MODULE_ENABLED */ +@@ -248,6 +271,10 @@ + #include "stm32mp1xx_hal_rng.h" + #endif /* HAL_RNG_MODULE_ENABLED */ + ++#ifdef HAL_RTC_MODULE_ENABLED ++ #include "stm32mp1xx_hal_rtc.h" ++#endif /* HAL_RTC_MODULE_ENABLED */ ++ + #ifdef HAL_SAI_MODULE_ENABLED + #include "stm32mp1xx_hal_sai.h" + #endif /* HAL_SAI_MODULE_ENABLED */ +@@ -256,9 +283,9 @@ + #include "stm32mp1xx_hal_sd.h" + #endif /* HAL_SD_MODULE_ENABLED */ + +-#ifdef HAL_MMC_MODULE_ENABLED +- #include "stm32mp1xx_hal_mmc.h" +-#endif /* HAL_MMC_MODULE_ENABLED */ ++#ifdef HAL_SMARTCARD_MODULE_ENABLED ++ #include "stm32mp1xx_hal_smartcard.h" ++#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + + #ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32mp1xx_hal_smbus.h" +@@ -272,9 +299,9 @@ + #include "stm32mp1xx_hal_spi.h" + #endif /* HAL_SPI_MODULE_ENABLED */ + +-#ifdef HAL_RTC_MODULE_ENABLED +- #include "stm32mp1xx_hal_rtc.h" +-#endif /* HAL_RTC_MODULE_ENABLED */ ++#ifdef HAL_SRAM_MODULE_ENABLED ++ #include "stm32mp1xx_hal_sram.h" ++#endif /* HAL_SRAM_MODULE_ENABLED */ + + #ifdef HAL_TIM_MODULE_ENABLED + #include "stm32mp1xx_hal_tim.h" +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/uart.c new/CA7/source/hic_hal/stm32/stm32mp1xx/uart.c +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/uart.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/uart.c 2023-12-27 14:15:37.337658991 +0800 +@@ -21,70 +21,113 @@ + + #include "string.h" + +-#include "stm32f1xx.h" ++#include "stm32mp1xx.h" + #include "uart.h" + #include "gpio.h" + #include "util.h" + #include "circ_buf.h" ++#ifdef HISPARK_TRACE ++#include "interrupt.h" ++#include "settings.h" ++#endif + #include "IO_Config.h" + +-// For usart +-#define CDC_UART USART2 +-#define CDC_UART_ENABLE() __HAL_RCC_USART2_CLK_ENABLE() +-#define CDC_UART_DISABLE() __HAL_RCC_USART2_CLK_DISABLE() +-#define CDC_UART_IRQn USART2_IRQn +-#define CDC_UART_IRQn_Handler USART2_IRQHandler +- +-#define UART_PINS_PORT_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +-#define UART_PINS_PORT_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() +- +-#define UART_TX_PORT GPIOA +-#define UART_TX_PIN GPIO_PIN_2 +- +-#define UART_RX_PORT GPIOA +-#define UART_RX_PIN GPIO_PIN_3 +- +-#define UART_CTS_PORT GPIOA +-#define UART_CTS_PIN GPIO_PIN_0 +- +-#define UART_RTS_PORT GPIOA +-#define UART_RTS_PIN GPIO_PIN_1 ++// UDB: USART3, UART0_MCU_UDC_TXD or UART0_UDC_TXD ++// pd8=USART3_TX pd9=USART3_RX + ++#define CDC_UART UART4 ++#define CDC_UART_ENABLE() __HAL_RCC_UART4_CLK_ENABLE() ++#define CDC_UART_DISABLE() __HAL_RCC_UART4_CLK_DISABLE() ++#define CDC_UART_IRQn UART4_IRQn ++//#define CDC_UART_IRQn_Handler UART4_IRQHandler ++ ++#define CDC_UART_RXFIFO_THRESHOLD UART_RXFIFO_THRESHOLD_3_4 ++#define UART_PINS_PORT_ENABLE() do{__HAL_RCC_GPIOG_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();}while(0) ++#define UART_PINS_PORT_DISABLE() do{__HAL_RCC_GPIOG_CLK_DISABLE();__HAL_RCC_GPIOB_CLK_DISABLE();}while(0) ++ ++#define UART_TX_PORT GPIOG ++#define UART_TX_PIN GPIO_PIN_11 ++#define UART_TX_ALTFUNC GPIO_AF6_UART4 //Select the correct alt func ++ ++#define UART_RX_PORT GPIOB ++#define UART_RX_PIN GPIO_PIN_2 ++#define UART_RX_ALTFUNC GPIO_AF8_UART4 //Select the correct alt func ++ ++//ToDo(elee): CTS/RTS not used on main UDC uarts. How to ensure they are not used? Just don't set the Alternate function? ++// Just choose one of the possible pins for CTS/RTS for usart3 for now. ++//#define UART_CTS_PORT GPIOD ++//#define UART_CTS_PIN GPIO_PIN_11 ++// ++//#define UART_RTS_PORT GPIOD ++//#define UART_RTS_PIN GPIO_PIN_12 ++#define CDC_UART_BAUDRATE_DEFAULT (115200) + + #define RX_OVRF_MSG "\n" + #define RX_OVRF_MSG_SIZE (sizeof(RX_OVRF_MSG) - 1) + #define BUFFER_SIZE (512) + +-circ_buf_t write_buffer; +-uint8_t write_buffer_data[BUFFER_SIZE]; +-circ_buf_t read_buffer; +-uint8_t read_buffer_data[BUFFER_SIZE]; ++static circ_buf_t s_write_buffer; ++static uint8_t s_write_buffer_data[BUFFER_SIZE]; ++static circ_buf_t s_read_buffer; ++static uint8_t s_read_buffer_data[BUFFER_SIZE]; + +-static UART_Configuration configuration = { +- .Baudrate = 9600, ++static UART_Configuration s_configuration = ++{ ++ .Baudrate = CDC_UART_BAUDRATE_DEFAULT, + .DataBits = UART_DATA_BITS_8, + .Parity = UART_PARITY_NONE, + .StopBits = UART_STOP_BITS_1, + .FlowControl = UART_FLOW_CONTROL_NONE, + }; + +-extern uint32_t SystemCoreClock; +- ++static UART_HandleTypeDef s_uart_handle; + ++void CDC_UART_IRQn_Handler(void); + + static void clear_buffers(void) + { +- circ_buf_init(&write_buffer, write_buffer_data, sizeof(write_buffer_data)); +- circ_buf_init(&read_buffer, read_buffer_data, sizeof(read_buffer_data)); ++ circ_buf_init(&s_write_buffer, s_write_buffer_data, sizeof(s_write_buffer_data)); ++ circ_buf_init(&s_read_buffer, s_read_buffer_data, sizeof(s_read_buffer_data)); ++} ++ ++static void uart_read_from_fifo_in_isr(void) ++{ ++ uint16_t size = circ_buf_count_free(&s_read_buffer); ++ uint8_t data; ++ while (CDC_UART->ISR & USART_ISR_RXNE_RXFNE) ++ { ++ data = CDC_UART->RDR; ++ if (size > RX_OVRF_MSG_SIZE) ++ { ++ circ_buf_push(&s_read_buffer, data); ++ } ++ else if (config_get_overflow_detect()) ++ { ++ if (RX_OVRF_MSG_SIZE == size) ++ { ++ circ_buf_write(&s_read_buffer, (uint8_t*)RX_OVRF_MSG, RX_OVRF_MSG_SIZE); ++ } ++ else ++ { ++ // drop characters ++ } ++ break; ++ } ++ else ++ { ++ // drop characters ++ break; ++ } ++ --size; ++ } ++ ++ main_cdc_send_event(); + } + + int32_t uart_initialize(void) + { + GPIO_InitTypeDef GPIO_InitStructure; + +- CDC_UART->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE); +- clear_buffers(); +- + CDC_UART_ENABLE(); + UART_PINS_PORT_ENABLE(); + +@@ -92,171 +135,213 @@ + GPIO_InitStructure.Pin = UART_TX_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; ++ GPIO_InitStructure.Pull = GPIO_NOPULL; ++ GPIO_InitStructure.Alternate = UART_TX_ALTFUNC; + HAL_GPIO_Init(UART_TX_PORT, &GPIO_InitStructure); + //RX pin + GPIO_InitStructure.Pin = UART_RX_PIN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; +- GPIO_InitStructure.Mode = GPIO_MODE_INPUT; ++ GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Pull = GPIO_PULLUP; ++ GPIO_InitStructure.Alternate = UART_RX_ALTFUNC; + HAL_GPIO_Init(UART_RX_PORT, &GPIO_InitStructure); +- //CTS pin, input +- GPIO_InitStructure.Pin = UART_CTS_PIN; +- GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; +- GPIO_InitStructure.Mode = GPIO_MODE_INPUT; +- GPIO_InitStructure.Pull = GPIO_PULLUP; +- HAL_GPIO_Init(UART_CTS_PORT, &GPIO_InitStructure); +- //RTS pin, output low +- HAL_GPIO_WritePin(UART_RTS_PORT, UART_RTS_PIN, GPIO_PIN_RESET); +- GPIO_InitStructure.Pin = UART_RTS_PIN; +- GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; +- GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; +- HAL_GPIO_Init(UART_RTS_PORT, &GPIO_InitStructure); ++// //CTS pin, input ++// GPIO_InitStructure.Pin = UART_CTS_PIN; ++// GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; ++// GPIO_InitStructure.Mode = GPIO_MODE_INPUT; ++// GPIO_InitStructure.Pull = GPIO_PULLUP; ++// //GPIO_InitStructure.Alternate = UART_ALTFUNC; //cts is not used? ++// HAL_GPIO_Init(UART_CTS_PORT, &GPIO_InitStructure); ++// //RTS pin, output low ++// HAL_GPIO_WritePin(UART_RTS_PORT, UART_RTS_PIN, GPIO_PIN_RESET); ++// GPIO_InitStructure.Pin = UART_RTS_PIN; ++// GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; ++// GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; ++// GPIO_InitStructure.Pull = GPIO_NOPULL; ++// //GPIO_InitStructure.Alternate = UART_ALTFUNC; //rts is not used? ++// HAL_GPIO_Init(UART_RTS_PORT, &GPIO_InitStructure); + +- NVIC_EnableIRQ(CDC_UART_IRQn); ++// NVIC_EnableIRQ(CDC_UART_IRQn); ++ IRQ_Enable(UART4_IRQn, 6, CDC_UART_IRQn_Handler); + + return 1; + } + + int32_t uart_uninitialize(void) + { +- CDC_UART->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE); ++ NVIC_DisableIRQ(CDC_UART_IRQn); + clear_buffers(); ++ ++ HAL_GPIO_DeInit(UART_RX_PORT, UART_RX_PIN); ++ HAL_GPIO_DeInit(UART_TX_PORT, UART_TX_PIN); ++ ++ CDC_UART_DISABLE(); ++ + return 1; + } + + int32_t uart_reset(void) + { + const uint32_t cr1 = CDC_UART->CR1; +- CDC_UART->CR1 = cr1 & ~(USART_IT_TXE | USART_IT_RXNE); ++ CDC_UART->CR1 = cr1 & ~(USART_ISR_TXE_TXFNF | USART_ISR_RXNE_RXFNE); + clear_buffers(); +- CDC_UART->CR1 = cr1 & ~USART_IT_TXE; ++ CDC_UART->CR1 = cr1 & ~USART_ISR_TXE_TXFNF; + return 1; + } + + int32_t uart_set_configuration(UART_Configuration *config) + { +- UART_HandleTypeDef uart_handle; + HAL_StatusTypeDef status; + +- memset(&uart_handle, 0, sizeof(uart_handle)); +- uart_handle.Instance = CDC_UART; ++ s_uart_handle.Instance = CDC_UART; ++ status = HAL_UART_DeInit(&s_uart_handle); + ++ util_assert(status != HAL_ERROR); + // parity +- configuration.Parity = config->Parity; +- if(config->Parity == UART_PARITY_ODD) { +- uart_handle.Init.Parity = HAL_UART_PARITY_ODD; +- } else if(config->Parity == UART_PARITY_EVEN) { +- uart_handle.Init.Parity = HAL_UART_PARITY_EVEN; +- } else if(config->Parity == UART_PARITY_NONE) { +- uart_handle.Init.Parity = HAL_UART_PARITY_NONE; ++ s_configuration.Parity = config->Parity; ++ if(config->Parity == UART_PARITY_ODD_DAPLINK) { ++ s_uart_handle.Init.Parity = UART_PARITY_ODD; ++ } else if(config->Parity == UART_PARITY_EVEN_DAPLINK) { ++ s_uart_handle.Init.Parity = UART_PARITY_EVEN; ++ } else if(config->Parity == UART_PARITY_NONE_DAPLINK) { ++ s_uart_handle.Init.Parity = UART_PARITY_NONE; + } else { //Other not support +- uart_handle.Init.Parity = HAL_UART_PARITY_NONE; +- configuration.Parity = UART_PARITY_NONE; ++ // not support other parity ++ util_assert(false); + } + + // stop bits +- configuration.StopBits = config->StopBits; ++ s_configuration.StopBits = config->StopBits; + if(config->StopBits == UART_STOP_BITS_2) { +- uart_handle.Init.StopBits = UART_STOPBITS_2; ++ s_uart_handle.Init.StopBits = UART_STOPBITS_2; + } else if(config->StopBits == UART_STOP_BITS_1_5) { +- uart_handle.Init.StopBits = UART_STOPBITS_2; +- configuration.StopBits = UART_STOP_BITS_2; ++ s_uart_handle.Init.StopBits = UART_STOPBITS_2; ++ s_configuration.StopBits = UART_STOP_BITS_2; + } else if(config->StopBits == UART_STOP_BITS_1) { +- uart_handle.Init.StopBits = UART_STOPBITS_1; ++ s_uart_handle.Init.StopBits = UART_STOPBITS_1; + } else { +- uart_handle.Init.StopBits = UART_STOPBITS_1; +- configuration.StopBits = UART_STOP_BITS_1; ++ s_uart_handle.Init.StopBits = UART_STOPBITS_1; ++ s_configuration.StopBits = UART_STOP_BITS_1; + } + + //Only 8 bit support +- configuration.DataBits = UART_DATA_BITS_8; +- if (uart_handle.Init.Parity == HAL_UART_PARITY_ODD || uart_handle.Init.Parity == HAL_UART_PARITY_EVEN) { +- uart_handle.Init.WordLength = UART_WORDLENGTH_9B; ++ util_assert(config->DataBits == UART_DATA_BITS_8); ++ s_configuration.DataBits = config->DataBits; ++ if (s_uart_handle.Init.Parity == UART_PARITY_ODD || s_uart_handle.Init.Parity == UART_PARITY_EVEN) { ++ s_uart_handle.Init.WordLength = UART_WORDLENGTH_9B; + } else { +- uart_handle.Init.WordLength = UART_WORDLENGTH_8B; ++ s_uart_handle.Init.WordLength = UART_WORDLENGTH_8B; + } + + // No flow control +- configuration.FlowControl = UART_FLOW_CONTROL_NONE; +- uart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; +- ++ s_configuration.FlowControl = UART_FLOW_CONTROL_NONE; ++ s_uart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; ++ + // Specified baudrate +- configuration.Baudrate = config->Baudrate; +- uart_handle.Init.BaudRate = config->Baudrate; ++ s_configuration.Baudrate = config->Baudrate; ++ s_uart_handle.Init.BaudRate = config->Baudrate; + + // TX and RX +- uart_handle.Init.Mode = UART_MODE_TX_RX; +- +- // Disable uart and tx/rx interrupt +- CDC_UART->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE); ++ s_uart_handle.Init.Mode = UART_MODE_TX_RX; + +- clear_buffers(); ++ status = HAL_UART_Init(&s_uart_handle); ++ util_assert(status != HAL_ERROR); ++ ++ status = HAL_UARTEx_EnableFifoMode(&s_uart_handle); ++ util_assert(status != HAL_ERROR); + +- status = HAL_UART_DeInit(&uart_handle); +- util_assert(HAL_OK == status); +- status = HAL_UART_Init(&uart_handle); +- util_assert(HAL_OK == status); +- (void)status; ++ status = HAL_UARTEx_SetRxFifoThreshold(&s_uart_handle, CDC_UART_RXFIFO_THRESHOLD); ++ util_assert(status != HAL_ERROR); ++ ++ clear_buffers(); + +- CDC_UART->CR1 |= USART_IT_RXNE; ++ CDC_UART->CR1 |= USART_CR1_IDLEIE; ++ CDC_UART->CR3 |= USART_CR3_RXFTIE; + + return 1; + } + + int32_t uart_get_configuration(UART_Configuration *config) + { +- config->Baudrate = configuration.Baudrate; +- config->DataBits = configuration.DataBits; +- config->Parity = configuration.Parity; +- config->StopBits = configuration.StopBits; ++ config->Baudrate = s_configuration.Baudrate; ++ config->DataBits = s_configuration.DataBits; ++ config->Parity = s_configuration.Parity; ++ config->StopBits = s_configuration.StopBits; + config->FlowControl = UART_FLOW_CONTROL_NONE; + + return 1; + } + +-void uart_set_control_line_state(uint16_t ctrl_bmp) ++int UART_Out(int ch) + { ++ while ((CDC_UART->ISR & 0X40) == 0); /* ȴһַ */ ++ ++ CDC_UART->TDR = (uint8_t)ch; /* Ҫ͵ַ ch д뵽DRĴ */ ++ return ch; + } + ++ + int32_t uart_write_free(void) + { +- return circ_buf_count_free(&write_buffer); ++ return circ_buf_count_free(&s_write_buffer); + } + + int32_t uart_write_data(uint8_t *data, uint16_t size) + { +- uint32_t cnt = circ_buf_write(&write_buffer, data, size); +- CDC_UART->CR1 |= USART_IT_TXE; +- ++ uint32_t cnt = circ_buf_write(&s_write_buffer, data, size); ++ if (cnt > 0) ++ { ++ CDC_UART->CR1 |= USART_CR1_TXEIE_TXFNFIE; ++ } + return cnt; + } + + int32_t uart_read_data(uint8_t *data, uint16_t size) + { +- return circ_buf_read(&read_buffer, data, size); ++ return circ_buf_read(&s_read_buffer, data, size); + } + + void CDC_UART_IRQn_Handler(void) + { +- const uint32_t sr = CDC_UART->SR; ++ const uint32_t isr_reg = CDC_UART->ISR; ++ const uint32_t cr1 = CDC_UART->CR1; ++ const uint32_t cr3 = CDC_UART->CR3; + +- if (sr & USART_SR_RXNE) { +- uint8_t dat = CDC_UART->DR; +- uint32_t free = circ_buf_count_free(&read_buffer); +- if (free > RX_OVRF_MSG_SIZE) { +- circ_buf_push(&read_buffer, dat); +- } else if (RX_OVRF_MSG_SIZE == free) { +- circ_buf_write(&read_buffer, (uint8_t*)RX_OVRF_MSG, RX_OVRF_MSG_SIZE); +- } else { +- // Drop character +- } ++ // UART Rx ++ if ((isr_reg & USART_ISR_RXFT) && (cr3 & USART_CR3_RXFTIE)) ++ { ++ uart_read_from_fifo_in_isr(); ++ } ++ else if((cr1 & USART_CR1_IDLEIE) && (isr_reg & USART_ISR_IDLE)) ++ { ++ // Handle IDLE interrupt to deal with the data left in FIFO, ++ // which is less than CDC_UART_FIFO_SIZE and cannot trigger ++ // USART_ISR_RXFT ++ CDC_UART->ICR |= USART_ICR_IDLECF; ++ uart_read_from_fifo_in_isr(); + } + +- if (sr & USART_SR_TXE) { +- if (circ_buf_count_used(&write_buffer) > 0) { +- CDC_UART->DR = circ_buf_pop(&write_buffer); +- } else { +- CDC_UART->CR1 &= ~USART_IT_TXE; ++ // UART Tx ++ if ((isr_reg & USART_ISR_TXE_TXFNF) && (cr1 & USART_CR1_TXEIE_TXFNFIE)) ++ { ++ uint16_t size = circ_buf_count_used(&s_write_buffer); ++ if (size > 0) ++ { ++ while (size && (CDC_UART->ISR & USART_ISR_TXE_TXFNF)) ++ { ++ CDC_UART->TDR = circ_buf_pop(&s_write_buffer); ++ --size; ++ } ++ ++ if (size == 0) ++ { ++ CDC_UART->CR1 &= ~USART_CR1_TXEIE_TXFNFIE; ++ } ++ } ++ else ++ { ++ // transmission is done ++ CDC_UART->CR1 &= ~USART_CR1_TXEIE_TXFNFIE; + } + } + } +diff -uNr old/CA7/source/hic_hal/stm32/stm32mp1xx/usb_config.c new/CA7/source/hic_hal/stm32/stm32mp1xx/usb_config.c +--- old/CA7/source/hic_hal/stm32/stm32mp1xx/usb_config.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/stm32/stm32mp1xx/usb_config.c 2023-05-25 15:16:40.000000000 +0800 +@@ -23,14 +23,16 @@ + + // USB Device + // Enable the USB Device functionality ++#ifndef USBD_ENABLE + #define USBD_ENABLE 1 ++#endif + #define USBD_RTX_CORE_STACK 0 + #define USBD_RTX_DEVICE_STACK 0 + #define USBD_RTX_ENDPOINT0_STACK 0 + + // High-speed + // Enable high-speed functionality (if device supports it) +-#define USBD_HS_ENABLE 0 ++#define USBD_HS_ENABLE 1 //elee: Beagle analyzer shows HS traffic, maybe set this to match? + #if (defined(WEBUSB_INTERFACE) || defined(WINUSB_INTERFACE) || defined(BULK_ENDPOINT)) + #define USBD_BOS_ENABLE 1 + #else +@@ -54,9 +56,12 @@ + // + #define USBD_POWER 0 + #define USBD_MAX_PACKET0 64 +-#define USBD_DEVDESC_IDVENDOR 0x0D28 +-#define USBD_DEVDESC_IDPRODUCT 0x0204 +-#define USBD_DEVDESC_BCDDEVICE 0x0100 ++// #define USBD_DEVDESC_IDVENDOR 0x0483 ++// #define USBD_DEVDESC_IDPRODUCT 0x5720 ++// #define USBD_DEVDESC_BCDDEVICE 0x0200 ++#define USBD_DEVDESC_IDVENDOR 0x4701 ++#define USBD_DEVDESC_IDPRODUCT 0x0290 ++#define USBD_DEVDESC_BCDDEVICE 0x0200 //was 0x0100 + + // Configuration Settings + // These settings affect Configuration Descriptor +@@ -91,13 +96,7 @@ + // + #define USBD_STRDESC_LANGID 0x0409 + #define USBD_STRDESC_MAN L"Arm" +-#ifndef USB_PROD_STR + #define USBD_STRDESC_PROD L"DAPLink CMSIS-DAP" +-#else +-#define _TOWIDE(x) L ## #x +-#define TOWIDE(x) _TOWIDE(x) +-#define USBD_STRDESC_PROD TOWIDE(USB_PROD_STR) +-#endif + #define USBD_STRDESC_SER_ENABLE 1 + #define USBD_STRDESC_SER L"0001A0000000" + +@@ -153,12 +152,6 @@ + #define WEBUSB_INTERFACE 1 + #endif + +-#ifndef WINUSB_INTERFACE +-#define WINUSB_INTERFACE 0 +-#else +-#define WINUSB_INTERFACE 1 +-#endif +- + #define USBD_HID_ENABLE HID_ENDPOINT + #ifndef BULK_ENDPOINT //check if bulk endpoint is not enabled + #define USBD_HID_EP_INTIN 1 +@@ -170,7 +163,7 @@ + #define USBD_HID_EP_INTIN_STACK 0 + #define USBD_HID_WMAXPACKETSIZE 64 + #define USBD_HID_BINTERVAL 1 +-#define USBD_HID_HS_ENABLE 0 ++#define USBD_HID_HS_ENABLE 1 //elee: enable + #define USBD_HID_HS_WMAXPACKETSIZE 64 + #define USBD_HID_HS_BINTERVAL 6 + #define USBD_HID_STRDESC L"CMSIS-DAP v1" +@@ -221,7 +214,7 @@ + #define USBD_MSC_EP_BULKOUT 2 + #define USBD_MSC_EP_BULKIN_STACK 0 + #define USBD_MSC_WMAXPACKETSIZE 64 +-#define USBD_MSC_HS_ENABLE 0 ++#define USBD_MSC_HS_ENABLE 1 //elee: enable + #define USBD_MSC_HS_WMAXPACKETSIZE 512 + #define USBD_MSC_HS_BINTERVAL 0 + #define USBD_MSC_STRDESC L"USB_MSC" +@@ -341,20 +334,20 @@ + #define USBD_CDC_ACM_EP_INTIN_STACK 0 + #define USBD_CDC_ACM_WMAXPACKETSIZE 16 + #define USBD_CDC_ACM_BINTERVAL 32 +-#define USBD_CDC_ACM_HS_ENABLE 0 ++#define USBD_CDC_ACM_HS_ENABLE 1 //elee: enable + #define USBD_CDC_ACM_HS_WMAXPACKETSIZE 16 + #define USBD_CDC_ACM_HS_BINTERVAL 2 + #define USBD_CDC_ACM_EP_BULKIN 4 + #define USBD_CDC_ACM_EP_BULKOUT 4 + #define USBD_CDC_ACM_EP_BULKIN_STACK 0 + #define USBD_CDC_ACM_WMAXPACKETSIZE1 16 +-#define USBD_CDC_ACM_HS_ENABLE1 0 +-#define USBD_CDC_ACM_HS_WMAXPACKETSIZE1 16 +-#define USBD_CDC_ACM_HS_BINTERVAL1 0 ++#define USBD_CDC_ACM_HS_ENABLE1 1 //elee: enable ++#define USBD_CDC_ACM_HS_WMAXPACKETSIZE1 512 ++#define USBD_CDC_ACM_HS_BINTERVAL1 3 + #define USBD_CDC_ACM_CIF_STRDESC L"mbed Serial Port" + #define USBD_CDC_ACM_DIF_STRDESC L"mbed Serial Port" +-#define USBD_CDC_ACM_SENDBUF_SIZE 64 +-#define USBD_CDC_ACM_RECEIVEBUF_SIZE 64 ++#define USBD_CDC_ACM_SENDBUF_SIZE 512 ++#define USBD_CDC_ACM_RECEIVEBUF_SIZE 1024 + #if (((USBD_CDC_ACM_HS_ENABLE1) && (USBD_CDC_ACM_SENDBUF_SIZE < USBD_CDC_ACM_HS_WMAXPACKETSIZE1)) || (USBD_CDC_ACM_SENDBUF_SIZE < USBD_CDC_ACM_WMAXPACKETSIZE1)) + #error "Send Buffer size must be larger or equal to Bulk In maximum packet size!" + #endif +@@ -362,6 +355,37 @@ + #error "Receive Buffer size must be larger or equal to Bulk Out maximum packet size!" + #endif + ++#ifndef CDCB_ENDPOINT ++#define CDCB_ENDPOINT 0 ++#else ++#define CDCB_ENDPOINT 1 ++#endif ++#define USBD_CDCB_ACM_ENABLE CDCB_ENDPOINT ++#define USBD_CDCB_ACM_EP_INTIN 1 // Mutually exclusive with non-bulk HID ++#define USBD_CDCB_ACM_EP_INTIN_STACK 0 ++#define USBD_CDCB_ACM_WMAXPACKETSIZE 16 ++#define USBD_CDCB_ACM_BINTERVAL 32 ++#define USBD_CDCB_ACM_HS_ENABLE 1 //elee: enable ++#define USBD_CDCB_ACM_HS_WMAXPACKETSIZE 16 ++#define USBD_CDCB_ACM_HS_BINTERVAL 2 ++#define USBD_CDCB_ACM_EP_BULKIN 2 // Mutually exclusive with MSC ++#define USBD_CDCB_ACM_EP_BULKOUT 2 // Mutually exclusive with MSC ++#define USBD_CDCB_ACM_EP_BULKIN_STACK 0 ++#define USBD_CDCB_ACM_WMAXPACKETSIZE1 16 ++#define USBD_CDCB_ACM_HS_ENABLE1 1 //elee: enable ++#define USBD_CDCB_ACM_HS_WMAXPACKETSIZE1 16 ++#define USBD_CDCB_ACM_HS_BINTERVAL1 0 ++#define USBD_CDCB_ACM_CIF_STRDESC L"mbed Serial Port" ++#define USBD_CDCB_ACM_DIF_STRDESC L"mbed Serial Port" ++#define USBD_CDCB_ACM_SENDBUF_SIZE 64 ++#define USBD_CDCB_ACM_RECEIVEBUF_SIZE 64 ++#if (((USBD_CDCB_ACM_HS_ENABLE1) && (USBD_CDCB_ACM_SENDBUF_SIZE < USBD_CDCB_ACM_HS_WMAXPACKETSIZE1)) || (USBD_CDCB_ACM_SENDBUF_SIZE < USBD_CDCB_ACM_WMAXPACKETSIZE1)) ++#error "Send Buffer size must be larger or equal to Bulk In maximum packet size!" ++#endif ++#if (((USBD_CDCB_ACM_HS_ENABLE1) && (USBD_CDCB_ACM_RECEIVEBUF_SIZE < USBD_CDCB_ACM_HS_WMAXPACKETSIZE1)) || (USBD_CDCB_ACM_RECEIVEBUF_SIZE < USBD_CDCB_ACM_WMAXPACKETSIZE1)) ++#error "Receive Buffer size must be larger or equal to Bulk Out maximum packet size!" ++#endif ++ + // Custom Class Device + // Enables USB Custom Class Requests + // Class IDs: +@@ -387,6 +411,12 @@ + #define USBD_WEBUSB_ORIGIN_URL "os.mbed.com/" + + // Microsoft OS Descriptors 2.0 (WinUSB) support ++#ifndef WINUSB_INTERFACE ++#define WINUSB_INTERFACE 0 ++#else ++#define WINUSB_INTERFACE 1 ++#endif ++ + #define USBD_WINUSB_ENABLE WINUSB_INTERFACE + #define USBD_WINUSB_VENDOR_CODE 0x20 + // +@@ -402,15 +432,14 @@ + #define USBD_BULK_EP_BULKOUT 1 + #define USBD_BULK_EP_BULKIN_SWO 6 + #define USBD_BULK_WMAXPACKETSIZE 64 +-#define USBD_BULK_HS_ENABLE 0 ++#define USBD_BULK_HS_ENABLE 1 //elee: enable + #define USBD_BULK_HS_WMAXPACKETSIZE 512 + #define USBD_BULK_STRDESC L"CMSIS-DAP v2" + +- + /* USB Device Calculations ---------------------------------------------------*/ + +-#define USBD_IF_NUM_MAX (USBD_BULK_ENABLE+USBD_WEBUSB_ENABLE+USBD_HID_ENABLE+USBD_MSC_ENABLE+(USBD_ADC_ENABLE*2)+(USBD_CDC_ACM_ENABLE*2)+USBD_CLS_ENABLE) +-#define USBD_MULTI_IF (USBD_CDC_ACM_ENABLE*(USBD_HID_ENABLE|USBD_MSC_ENABLE|USBD_ADC_ENABLE|USBD_CLS_ENABLE|USBD_WEBUSB_ENABLE|USBD_BULK_ENABLE)) ++#define USBD_IF_NUM_MAX (USBD_BULK_ENABLE+USBD_WEBUSB_ENABLE+USBD_HID_ENABLE+USBD_MSC_ENABLE+(USBD_ADC_ENABLE*2)+(USBD_CDC_ACM_ENABLE*2)+(USBD_CDCB_ACM_ENABLE*2)+USBD_CLS_ENABLE) ++#define USBD_MULTI_IF (USBD_CDC_ACM_ENABLE*(USBD_CDCB_ACM_ENABLE|USBD_HID_ENABLE|USBD_MSC_ENABLE|USBD_ADC_ENABLE|USBD_CLS_ENABLE|USBD_WEBUSB_ENABLE|USBD_BULK_ENABLE)) + // #define MAX(x, y) (((x) < (y)) ? (y) : (x)) + #define USBD_EP_NUM_CALC0 MAX((USBD_HID_ENABLE *(USBD_HID_EP_INTIN )), (USBD_HID_ENABLE *(USBD_HID_EP_INTOUT))) + #define USBD_EP_NUM_CALC1 MAX((USBD_MSC_ENABLE *(USBD_MSC_EP_BULKIN )), (USBD_MSC_ENABLE *(USBD_MSC_EP_BULKOUT))) +@@ -420,14 +449,18 @@ + #define USBD_EP_NUM_CALC5 MAX(USBD_EP_NUM_CALC2, USBD_EP_NUM_CALC3) + #define USBD_EP_NUM_CALC6 MAX(USBD_EP_NUM_CALC4, USBD_EP_NUM_CALC5) + #define USBD_EP_NUM_CALC7 MAX((USBD_BULK_ENABLE*(USBD_BULK_EP_BULKIN)), (USBD_BULK_ENABLE*(USBD_BULK_EP_BULKOUT))) +-#define USBD_EP_NUM MAX(USBD_EP_NUM_CALC6, USBD_EP_NUM_CALC7) ++#define USBD_EP_NUM_CALC8 MAX(USBD_EP_NUM_CALC6, USBD_EP_NUM_CALC7) ++#define USBD_EP_NUM_CALC9 MAX(USBD_EP_NUM_CALC8, (USBD_CDCB_ACM_ENABLE*(USBD_CDCB_ACM_EP_INTIN))) ++#define USBD_EP_NUM_CALC10 MAX((USBD_CDCB_ACM_ENABLE*(USBD_CDCB_ACM_EP_BULKIN)), (USBD_CDCB_ACM_ENABLE*(USBD_CDCB_ACM_EP_BULKOUT))) ++#define USBD_EP_NUM MAX(USBD_EP_NUM_CALC9, USBD_EP_NUM_CALC10) ++ + + #if (USBD_HID_ENABLE) + #if (USBD_MSC_ENABLE) +-#if ((((USBD_HID_EP_INTIN == USBD_MSC_EP_BULKIN) || \ +- (USBD_HID_EP_INTIN == USBD_MSC_EP_BULKOUT))) || \ +- ((USBD_HID_EP_INTOUT != 0) && \ +- (USBD_HID_EP_INTOUT == USBD_MSC_EP_BULKIN) || \ ++#if ((((USBD_HID_EP_INTIN == USBD_MSC_EP_BULKIN) || \ ++ (USBD_HID_EP_INTIN == USBD_MSC_EP_BULKIN)))|| \ ++ ((USBD_HID_EP_INTOUT != 0) && \ ++ (USBD_HID_EP_INTOUT == USBD_MSC_EP_BULKIN) || \ + (USBD_HID_EP_INTOUT == USBD_MSC_EP_BULKOUT))) + #error "HID and Mass Storage Device Interface can not use same Endpoints!" + #endif +@@ -450,7 +483,18 @@ + #error "HID and Communication Device Interface can not use same Endpoints!" + #endif + #endif ++#if (USBD_CDCB_ACM_ENABLE) ++#if (((USBD_HID_EP_INTIN == USBD_CDCB_ACM_EP_INTIN) || \ ++ (USBD_HID_EP_INTIN == USBD_CDCB_ACM_EP_BULKIN) || \ ++ (USBD_HID_EP_INTIN == USBD_CDCB_ACM_EP_BULKOUT))|| \ ++ ((USBD_HID_EP_INTOUT != 0) && \ ++ ((USBD_HID_EP_INTOUT == USBD_CDCB_ACM_EP_INTIN) || \ ++ (USBD_HID_EP_INTOUT == USBD_CDCB_ACM_EP_BULKIN) || \ ++ (USBD_HID_EP_INTOUT == USBD_CDCB_ACM_EP_BULKOUT)))) ++#error "HID and Communication Device B Interface can not use same Endpoints!" ++#endif + #endif ++#endif // USBD_HID_ENABLE + + #if (USBD_MSC_ENABLE) + #if (USBD_ADC_ENABLE) +@@ -469,7 +513,17 @@ + #error "Mass Storage Device and Communication Device Interface can not use same Endpoints!" + #endif + #endif ++#if (USBD_CDCB_ACM_ENABLE) ++#if ((USBD_MSC_EP_BULKIN == USBD_CDCB_ACM_EP_INTIN) || \ ++ (USBD_MSC_EP_BULKIN == USBD_CDCB_ACM_EP_BULKIN) || \ ++ (USBD_MSC_EP_BULKIN == USBD_CDCB_ACM_EP_BULKOUT) || \ ++ (USBD_MSC_EP_BULKOUT == USBD_CDCB_ACM_EP_INTIN) || \ ++ (USBD_MSC_EP_BULKOUT == USBD_CDCB_ACM_EP_BULKIN) || \ ++ (USBD_MSC_EP_BULKOUT == USBD_CDCB_ACM_EP_BULKOUT)) ++#error "Mass Storage Device and Communication Device B Interface can not use same Endpoints!" + #endif ++#endif ++#endif // USBD_MSC_ENABLE + + #if (USBD_ADC_ENABLE) + #if (USBD_CDC_ACM_ENABLE) +@@ -479,21 +533,49 @@ + #error "Audio Device and Communication Device Interface can not use same Endpoints!" + #endif + #endif ++#if (USBD_CDCB_ACM_ENABLE) ++#if ((USBD_ADC_EP_ISOOUT == USBD_CDCB_ACM_EP_INTIN) || \ ++ (USBD_ADC_EP_ISOOUT == USBD_CDCB_ACM_EP_BULKIN) || \ ++ (USBD_ADC_EP_ISOOUT == USBD_CDCB_ACM_EP_BULKOUT)) ++#error "Audio Device and Communication Device B Interface can not use same Endpoints!" ++#endif ++#endif ++#endif // USBD_ADC_ENABLE ++ ++#if (USBD_CDC_ACM_ENABLE) ++#if (USBD_CDCB_ACM_ENABLE) ++#if ((USBD_CDC_ACM_EP_INTIN == USBD_CDCB_ACM_EP_INTIN) || \ ++ (USBD_CDC_ACM_EP_INTIN == USBD_CDCB_ACM_EP_BULKIN) || \ ++ (USBD_CDC_ACM_EP_INTIN == USBD_CDCB_ACM_EP_BULKOUT) || \ ++ (USBD_CDC_ACM_EP_BULKIN == USBD_CDCB_ACM_EP_INTIN) || \ ++ (USBD_CDC_ACM_EP_BULKIN == USBD_CDCB_ACM_EP_BULKIN) || \ ++ (USBD_CDC_ACM_EP_BULKIN == USBD_CDCB_ACM_EP_BULKOUT) || \ ++ (USBD_CDC_ACM_EP_BULKOUT == USBD_CDCB_ACM_EP_INTIN) || \ ++ (USBD_CDC_ACM_EP_BULKOUT == USBD_CDCB_ACM_EP_BULKIN) || \ ++ (USBD_CDC_ACM_EP_BULKOUT == USBD_CDCB_ACM_EP_BULKOUT)) ++#error "Communication Device and Communication Device B Interface can not use same Endpoints!" ++#endif + #endif ++#endif // USBD_CDC_ACM_ENABLE ++ + + #define USBD_ADC_CIF_NUM (0) + #define USBD_ADC_SIF1_NUM (1) + #define USBD_ADC_SIF2_NUM (2) + ++// Index of each interface string + #define USBD_ADC_CIF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+0) + #define USBD_ADC_SIF1_STR_NUM (3+USBD_STRDESC_SER_ENABLE+1) + #define USBD_ADC_SIF2_STR_NUM (3+USBD_STRDESC_SER_ENABLE+2) + #define USBD_CDC_ACM_CIF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+0) + #define USBD_CDC_ACM_DIF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+1) +-#define USBD_HID_IF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+USBD_CDC_ACM_ENABLE*2) +-#define USBD_WEBUSB_IF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+USBD_CDC_ACM_ENABLE*2+USBD_HID_ENABLE) +-#define USBD_MSC_IF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+USBD_CDC_ACM_ENABLE*2+USBD_HID_ENABLE+USBD_WEBUSB_ENABLE) +-#define USBD_BULK_IF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+USBD_CDC_ACM_ENABLE*2+USBD_HID_ENABLE+USBD_WEBUSB_ENABLE+USBD_MSC_ENABLE) ++#define USBD_CDCB_ACM_CIF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+USBD_CDC_ACM_ENABLE*2+0) ++#define USBD_CDCB_ACM_DIF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+USBD_CDC_ACM_ENABLE*2+1) ++#define USBD_HID_IF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+USBD_CDC_ACM_ENABLE*2+USBD_CDCB_ACM_ENABLE*2) ++#define USBD_WEBUSB_IF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+USBD_CDC_ACM_ENABLE*2+USBD_CDCB_ACM_ENABLE*2+USBD_HID_ENABLE) ++#define USBD_MSC_IF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+USBD_CDC_ACM_ENABLE*2+USBD_CDCB_ACM_ENABLE*2+USBD_HID_ENABLE+USBD_WEBUSB_ENABLE) ++#define USBD_BULK_IF_STR_NUM (3+USBD_STRDESC_SER_ENABLE+USBD_ADC_ENABLE*3+USBD_CDC_ACM_ENABLE*2+USBD_CDCB_ACM_ENABLE*2+USBD_HID_ENABLE+USBD_WEBUSB_ENABLE+USBD_MSC_ENABLE) ++ + + #if (USBD_HID_ENABLE) + #if (USBD_HID_HS_ENABLE) +@@ -537,6 +619,21 @@ + #define USBD_CDC_ACM_MAX_PACKET (0) + #define USBD_CDC_ACM_MAX_PACKET1 (0) + #endif ++#if (USBD_CDCB_ACM_ENABLE) ++#if (USBD_CDCB_ACM_HS_ENABLE) ++#define USBD_CDCB_ACM_MAX_PACKET ((USBD_CDCB_ACM_HS_WMAXPACKETSIZE > USBD_CDCB_ACM_WMAXPACKETSIZE) ? USBD_CDCB_ACM_HS_WMAXPACKETSIZE : USBD_CDCB_ACM_WMAXPACKETSIZE) ++#else ++#define USBD_CDCB_ACM_MAX_PACKET (USBD_CDCB_ACM_WMAXPACKETSIZE) ++#endif ++#if (USBD_CDCB_ACM_HS_ENABLE1) ++#define USBD_CDCB_ACM_MAX_PACKET1 ((USBD_CDCB_ACM_HS_WMAXPACKETSIZE1 > USBD_CDCB_ACM_WMAXPACKETSIZE1) ? USBD_CDCB_ACM_HS_WMAXPACKETSIZE1 : USBD_CDCB_ACM_WMAXPACKETSIZE1) ++#else ++#define USBD_CDCB_ACM_MAX_PACKET1 (USBD_CDCB_ACM_WMAXPACKETSIZE1) ++#endif ++#else ++#define USBD_CDCB_ACM_MAX_PACKET (0) ++#define USBD_CDCB_ACM_MAX_PACKET1 (0) ++#endif + #if (USBD_BULK_ENABLE) + #if (USBD_BULK_HS_ENABLE) + #define USBD_BULK_MAX_PACKET ((USBD_BULK_HS_WMAXPACKETSIZE > USBD_BULK_WMAXPACKETSIZE) ? USBD_BULK_HS_WMAXPACKETSIZE : USBD_BULK_WMAXPACKETSIZE) +@@ -546,18 +643,23 @@ + #else + #define USBD_BULK_MAX_PACKET (0) + #endif +-#define USBD_MAX_PACKET_CALC0 ((USBD_HID_MAX_PACKET > USBD_HID_MAX_PACKET ) ? (USBD_HID_MAX_PACKET ) : (USBD_HID_MAX_PACKET )) ++ ++// TODO(aiw): Simplify (and maybe reorder) for easier maintenance ++#define USBD_MAX_PACKET_CALC0 ((USBD_HID_MAX_PACKET > USBD_CDCB_ACM_MAX_PACKET ) ? (USBD_HID_MAX_PACKET ) : (USBD_CDCB_ACM_MAX_PACKET )) + #define USBD_MAX_PACKET_CALC1 ((USBD_ADC_MAX_PACKET > USBD_CDC_ACM_MAX_PACKET ) ? (USBD_ADC_MAX_PACKET ) : (USBD_CDC_ACM_MAX_PACKET )) + #define USBD_MAX_PACKET_CALC2 ((USBD_MAX_PACKET_CALC0 > USBD_MAX_PACKET_CALC1 ) ? (USBD_MAX_PACKET_CALC0) : (USBD_MAX_PACKET_CALC1 )) +-#define USBD_MAX_PACKET_CALC3 ((USBD_BULK_MAX_PACKET > USBD_CDC_ACM_MAX_PACKET1 ) ? (USBD_BULK_MAX_PACKET) : (USBD_CDC_ACM_MAX_PACKET1 )) +-#define USBD_MAX_PACKET ((USBD_MAX_PACKET_CALC3 > USBD_MAX_PACKET_CALC2 ) ? (USBD_MAX_PACKET_CALC3) : (USBD_MAX_PACKET_CALC2 )) + ++#define USBD_MAX_PACKET_CALC3 ((USBD_BULK_MAX_PACKET > USBD_CDC_ACM_MAX_PACKET1 ) ? (USBD_BULK_MAX_PACKET ) : (USBD_CDC_ACM_MAX_PACKET1 )) ++#define USBD_MAX_PACKET_CALC4 ((USBD_CDCB_ACM_MAX_PACKET1 > USBD_MSC_MAX_PACKET ) ? (USBD_CDCB_ACM_MAX_PACKET1) : (USBD_MSC_MAX_PACKET )) ++#define USBD_MAX_PACKET_CALC5 ((USBD_MAX_PACKET_CALC3 > USBD_MAX_PACKET_CALC4 ) ? (USBD_MAX_PACKET_CALC3 ) : (USBD_MAX_PACKET_CALC4 )) ++ ++#define USBD_MAX_PACKET ((USBD_MAX_PACKET_CALC5 > USBD_MAX_PACKET_CALC2 ) ? (USBD_MAX_PACKET_CALC5) : (USBD_MAX_PACKET_CALC2 )) + + /*------------------------------------------------------------------------------ + * USB Config Functions + *----------------------------------------------------------------------------*/ + +-#ifndef __USB_CONFIG___ ++#ifndef __USB_CONFIG__ + #define __USB_CONFIG__ + + #ifndef __NO_USB_LIB_C +diff -uNr old/CA7/source/hic_hal/uart.h new/CA7/source/hic_hal/uart.h +--- old/CA7/source/hic_hal/uart.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/hic_hal/uart.h 2023-12-27 14:17:42.910784472 +0800 +@@ -31,11 +31,19 @@ + + /* Parity enumerator */ + typedef enum { ++#ifdef DAPLINK_UART ++ UART_PARITY_NONE_DAPLINK = 0, ++ UART_PARITY_ODD_DAPLINK = 1, ++ UART_PARITY_EVEN_DAPLINK = 2, ++ UART_PARITY_MARK_DAPLINK = 3, ++ UART_PARITY_SPACE_DAPLINK = 4 ++#else + UART_PARITY_NONE = 0, + UART_PARITY_ODD = 1, + UART_PARITY_EVEN = 2, + UART_PARITY_MARK = 3, +- UART_PARITY_SPACE = 4 ++ UART_PARITY_SPACE = 4 ++#endif + } UART_Parity; + + /* Stop Bits enumerator */ +@@ -87,6 +95,10 @@ + extern void uart_software_flow_control(void); + extern void uart_enable_flow_control(bool enabled); + ++#ifdef HISPARK_TRACE ++extern void main_cdc_send_event(void); ++extern int UART_Out(int ch); ++#endif + #ifdef __cplusplus + } + #endif +diff -uNr old/CA7/source/rtos_none/cmsis_os2_port.c new/CA7/source/rtos_none/cmsis_os2_port.c +--- old/CA7/source/rtos_none/cmsis_os2_port.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/rtos_none/cmsis_os2_port.c 2023-05-25 15:09:49.000000000 +0800 +@@ -20,6 +20,9 @@ + */ + #include "cmsis_os2.h" + #include "SysTick_Handler.h" ++#if defined(USE_HAL_TICK) && defined(HISPARK_TRACE) ++#include "stm32mp1xx_hal.h" ++#endif + + osStatus_t osKernelInitialize(void) + { +@@ -47,8 +50,21 @@ + + osStatus_t osDelay(uint32_t ticks) + { ++#if defined(USE_HAL_TICK) && defined(HISPARK_TRACE) ++ uint32_t temp; ++ uint32_t pre_tick = 0; ++ uint32_t current_tick = 0; ++ pre_tick = HAL_GetTick(); ++ while (1) { ++ current_tick = HAL_GetTick(); ++ temp = current_tick - pre_tick; ++ if (temp > ticks) { ++ return osOK; ++ } ++ } ++#else + sysTickWait(ticks); +- return osOK; ++#endif + } + + osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) +@@ -87,3 +103,10 @@ + { + return (osThreadId_t)1; + } ++ ++#if defined(USE_HAL_TICK) && defined(HISPARK_TRACE) ++uint32_t osKernelGetSysTimerCount(void) ++{ ++ return HAL_GetTick(); ++} ++#endif +\ No newline at end of file +diff -uNr old/CA7/source/rtos_none/SysTick_Handler.c new/CA7/source/rtos_none/SysTick_Handler.c +--- old/CA7/source/rtos_none/SysTick_Handler.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/rtos_none/SysTick_Handler.c 2023-05-25 15:09:49.000000000 +0800 +@@ -28,9 +28,15 @@ + #endif + + //Set the timer tick value for selected timer. ++#ifdef HISPARK_TRACE ++#ifdef NO_RTOS ++#define OS_TICK 10000 ++#endif ++#else + #ifndef OS_TICK + #error "OS_TICK should be defined by RTOS configuration" + #endif ++#endif + + #define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) + +diff -uNr old/CA7/source/target/target_config.h new/CA7/source/target/target_config.h +--- old/CA7/source/target/target_config.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/target/target_config.h 2023-05-25 15:09:49.000000000 +0800 +@@ -63,11 +63,19 @@ + */ + typedef struct __attribute__((__packed__)) target_cfg { + uint32_t version; /*!< Target configuration version */ ++#ifdef HISPARK_TRACE ++ sector_info_t* sectors_info; /*!< Sector start and length list */ ++#else + const sector_info_t* sectors_info; /*!< Sector start and length list */ ++#endif + uint32_t sector_info_length; /*!< Number of entries in the sectors_info array */ + region_info_t flash_regions[MAX_REGIONS]; /*!< Flash regions */ + region_info_t ram_regions[MAX_REGIONS]; /*!< RAM regions */ ++#ifdef HISPARK_TRACE ++ char *rt_board_id; /*!< If assigned, this is a flexible board ID */ ++#else + const char *rt_board_id; /*!< If assigned, this is a flexible board ID */ ++#endif + uint16_t rt_family_id; /*!< If assigned, this is a flexible family ID */ + uint8_t erase_reset; /*!< Reset after performing an erase */ + uint8_t pad; +diff -uNr old/CA7/source/target/target_family.c new/CA7/source/target/target_family.c +--- old/CA7/source/target/target_family.c 2022-02-05 13:12:28.000000000 +0800 ++++ new/CA7/source/target/target_family.c 2023-06-09 15:09:34.710441100 +0800 +@@ -21,7 +21,9 @@ + + #include "daplink.h" + #include "DAP_config.h" ++#include "swd_jtag_config.h" + #include "swd_host.h" ++#include "jtag_host.h" + #include "target_family.h" + #include "target_board.h" + +@@ -133,14 +135,30 @@ + return g_target_family->target_set_state(state); + } else { + if (g_target_family->default_reset_type == kHardwareReset) { +- return swd_set_target_state_hw(state); ++ if (SwdJtagDebugPortGet() == DAP_PORT_JTAG) { ++ return jtag_set_target_state_hw(state); ++ } else { ++ return swd_set_target_state_hw(state); ++ } + } else if (g_target_family->default_reset_type == kSoftwareReset) { + if (g_board_info.soft_reset_type) { //board has precedence +- swd_set_soft_reset(g_board_info.soft_reset_type); ++ if (SwdJtagDebugPortGet() == DAP_PORT_JTAG) { ++ jtag_set_soft_reset(g_board_info.soft_reset_type); ++ } else { ++ swd_set_soft_reset(g_board_info.soft_reset_type); ++ } + } else if (g_target_family->soft_reset_type) { +- swd_set_soft_reset(g_target_family->soft_reset_type); ++ if (SwdJtagDebugPortGet() == DAP_PORT_JTAG) { ++ jtag_set_soft_reset(g_target_family->soft_reset_type); ++ } else { ++ swd_set_soft_reset(g_target_family->soft_reset_type); ++ } ++ } ++ if (SwdJtagDebugPortGet() == DAP_PORT_JTAG) { ++ return jtag_set_target_state_sw(state); ++ } else { ++ return swd_set_target_state_sw(state); + } +- return swd_set_target_state_sw(state); + } else { + return 1; + } +@@ -157,6 +175,15 @@ + } else { + (asserted) ? PIN_nRESET_OUT(0) : PIN_nRESET_OUT(1); + } ++} ++ ++void jtag_set_target_reset(uint8_t asserted) ++{ ++ if (g_target_family && g_target_family->jtag_set_target_reset) { ++ g_target_family->jtag_set_target_reset(asserted); ++ } else { ++ (asserted) ? PIN_nRESET_OUT(0) : PIN_nRESET_OUT(1); ++ } + } + + uint32_t target_get_apsel() +diff -uNr old/CA7/source/target/target_family.h new/CA7/source/target/target_family.h +--- old/CA7/source/target/target_family.h 2022-02-05 13:12:28.000000000 +0800 ++++ new/CA7/source/target/target_family.h 2023-06-09 15:09:54.922080300 +0800 +@@ -122,6 +122,7 @@ + uint8_t (*validate_bin_nvic)(const uint8_t *buf); /*!< Validate a bin file to be flash by drag and drop */ + uint8_t (*validate_hexfile)(const uint8_t *buf); /*!< Validate a hex file to be flash by drag and drop */ + uint32_t apsel; /*!< APSEL for the family */ ++ void (*jtag_set_target_reset)(uint8_t asserted); + } target_family_descriptor_t; + + //! @brief The active family used by the board. +@@ -145,6 +146,9 @@ + //! @brief Controls reset of the target. + void swd_set_target_reset(uint8_t asserted); + ++//! @brief Controls reset of the target. ++void jtag_set_target_reset(uint8_t asserted); ++ + //! @brief Get the APSEL for the AHB-AP to use for controlling the target. + uint32_t target_get_apsel(void); + +diff -uNr old/CA7/source/usb/hid/usbd_core_hid.c new/CA7/source/usb/hid/usbd_core_hid.c +--- old/CA7/source/usb/hid/usbd_core_hid.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/usb/hid/usbd_core_hid.c 2023-05-25 15:09:49.000000000 +0800 +@@ -35,8 +35,12 @@ + { + switch (USBD_SetupPacket.wValueH) { + case HID_HID_DESCRIPTOR_TYPE: ++ #ifdef HISPARK_TRACE ++ if (USBD_SetupPacket.wIndexL != usbd_hid_if_num) { ++ #else + if (USBD_SetupPacket.wIndexL != usbd_hid_if_num && + USBD_SetupPacket.wIndexL != usbd_webusb_if_num) { ++ #endif + return (__FALSE); + } + +@@ -55,8 +59,12 @@ + break; + + case HID_REPORT_DESCRIPTOR_TYPE: ++ #ifdef HISPARK_TRACE ++ if (USBD_SetupPacket.wIndexL != usbd_hid_if_num) { ++ #else + if (USBD_SetupPacket.wIndexL != usbd_hid_if_num && + USBD_SetupPacket.wIndexL != usbd_webusb_if_num) { ++ #endif + return (__FALSE); + } + +@@ -83,8 +91,12 @@ + + __WEAK BOOL USBD_EndPoint0_Setup_HID_ReqToIF(void) + { ++#ifdef HISPARK_TRACE ++ if (USBD_SetupPacket.wIndexL == usbd_hid_if_num) { ++#else + if (USBD_SetupPacket.wIndexL == usbd_hid_if_num || + USBD_SetupPacket.wIndexL == usbd_webusb_if_num) { ++#endif + switch (USBD_SetupPacket.bRequest) { + case HID_REQUEST_GET_REPORT: + if (USBD_HID_GetReport()) { +@@ -157,8 +169,12 @@ + + __WEAK BOOL USBD_EndPoint0_Out_HID_ReqToIF(void) + { ++#ifdef HISPARK_TRACE ++ if (USBD_SetupPacket.wIndexL == usbd_hid_if_num) { ++#else + if (USBD_SetupPacket.wIndexL == usbd_hid_if_num || + USBD_SetupPacket.wIndexL == usbd_webusb_if_num) { ++#endif + switch (USBD_SetupPacket.bRequest) { + case HID_REQUEST_SET_REPORT: + if (USBD_HID_SetReport()) { +diff -uNr old/CA7/source/usb/hid/usbd_user_hid.c new/CA7/source/usb/hid/usbd_user_hid.c +--- old/CA7/source/usb/hid/usbd_user_hid.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/usb/hid/usbd_user_hid.c 2023-05-25 15:24:26.000000000 +0800 +@@ -22,7 +22,9 @@ + #include + #include "rl_usb.h" + #include "usb.h" ++#ifndef HISPARK_TRACE + #define __NO_USB_LIB_C ++#endif + #include "usb_config.c" + #include "DAP_config.h" + #include "DAP.h" +@@ -42,7 +44,11 @@ + static volatile uint8_t USB_ResponseIdle; + static DAP_queue DAP_Cmd_queue; + ++#ifdef HISPARK_TRACE ++void hid_send_packet(void) ++#else + void hid_send_packet() ++#endif + { + uint8_t * sbuf; + int slen; +diff -uNr old/CA7/source/usb/usbd_core.c new/CA7/source/usb/usbd_core.c +--- old/CA7/source/usb/usbd_core.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/usb/usbd_core.c 2023-05-25 15:23:34.000000000 +0800 +@@ -23,6 +23,9 @@ + #include "rl_usb.h" + #include "usb_for_lib.h" + #include "info.h" ++#ifdef HISPARK_TRACE ++#include "interrupt.h" ++#endif + + U16 USBD_DeviceStatus; + U8 USBD_DeviceAddress; +@@ -374,6 +377,11 @@ + + USBD_EP0Data.pData = pD; + len = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; ++ #ifdef HISPARK_TRACE ++ if (len > USBD_SetupPacket.wLength) { ++ len = USBD_SetupPacket.wLength; ++ } ++ #endif + break; + + case USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE: +@@ -927,10 +935,11 @@ + case REQUEST_VENDOR: + switch (USBD_SetupPacket.bmRequestType.Recipient) { + case REQUEST_TO_DEVICE: ++ #ifndef HISPARK_TRACE + if (USBD_EndPoint0_Setup_WebUSB_ReqToDevice()) { + goto setup_vendor_ok; + } +- ++ #endif + if (USBD_EndPoint0_Setup_WinUSB_ReqToDevice()) { + goto setup_vendor_ok; + } +diff -uNr old/CA7/source/usb/usbd_hw.h new/CA7/source/usb/usbd_hw.h +--- old/CA7/source/usb/usbd_hw.h 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/usb/usbd_hw.h 2023-05-25 15:09:49.000000000 +0800 +@@ -47,5 +47,8 @@ + extern U32 USBD_GetError(void); + extern void USBD_SignalHandler(void); + extern void USBD_Handler(void); ++#ifdef HISPARK_TRACE ++extern void OTG_HS_IRQHandler(void); ++#endif + + #endif /* __USBD_HW_H__ */ +diff -uNr old/CA7/source/usb/usb_lib.c new/CA7/source/usb/usb_lib.c +--- old/CA7/source/usb/usb_lib.c 2023-05-25 15:09:49.000000000 +0800 ++++ new/CA7/source/usb/usb_lib.c 2023-05-25 15:20:09.000000000 +0800 +@@ -24,6 +24,9 @@ + #include "usb.h" + #include "settings.h" + #include "compiler.h" ++#ifdef HISPARK_TRACE ++#include "usb_config.c" ++#endif + + #if defined(__CC_ARM) + #pragma thumb +@@ -93,7 +96,11 @@ + const U8 usbd_msc_ep_bulkin = USBD_MSC_EP_BULKIN; + const U8 usbd_msc_ep_bulkout = USBD_MSC_EP_BULKOUT; + const U16 usbd_msc_maxpacketsize[2] = {USBD_MSC_WMAXPACKETSIZE, USBD_MSC_HS_WMAXPACKETSIZE}; ++#ifdef HISPARK_TRACE ++const U8 *usbd_msc_inquiry_data = (U8 *)USBD_MSC_INQUIRY_DATA; ++#else + const U8 *usbd_msc_inquiry_data = USBD_MSC_INQUIRY_DATA; ++#endif + const U16 USBD_MSC_BulkBufSize = USBD_MSC_MAX_PACKET; + U8 USBD_MSC_BulkBuf[USBD_MSC_MAX_PACKET]; + #endif +@@ -2503,6 +2510,7 @@ + return sizeof(start_desc); + } + ++#ifndef HISPARK_TRACE + static U16 hid_desc_fill(U8 * config_desc, U8 * config_desc_hs, U8 if_num) { + U8 * pD = 0; + const U8 hid_desc[] = { +@@ -2535,6 +2543,7 @@ + #endif + return sizeof(hid_desc); + } ++#endif + + static U16 acm_cdc_desc_fill(U8 * config_desc, U8 * config_desc_hs, U8 if_num) { + U8 * pD = 0; diff --git a/src/tools/hispark_trace/hispark/patchs/CM4/000-hisparktrace_cm4.patch b/src/tools/hispark_trace/hispark/patchs/CM4/000-hisparktrace_cm4.patch new file mode 100644 index 0000000000000000000000000000000000000000..728847da30e996f0503946f94c1504c2f187bdce --- /dev/null +++ b/src/tools/hispark_trace/hispark/patchs/CM4/000-hisparktrace_cm4.patch @@ -0,0 +1,2208 @@ +diff -uNr old/CM4/Core/Inc/DAP_config.h new/CM4/Core/Inc/DAP_config.h +--- old/CM4/Core/Inc/DAP_config.h 2023-05-29 09:46:06.000000000 +0800 ++++ new/CM4/Core/Inc/DAP_config.h 2023-12-27 14:21:36.267212139 +0800 +@@ -3,7 +3,7 @@ + * @brief + * + * DAPLink Interface Firmware +- * Copyright (c) 2009-2021, ARM Limited, All Rights Reserved ++ * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may +@@ -22,20 +22,19 @@ + #ifndef __DAP_CONFIG_H__ + #define __DAP_CONFIG_H__ + +-#include "IO_Config.h" ++#include "stdint.h" ++#include "stm32mp1xx.h" ++#include "gpio_config.h" + + //************************************************************************************************** + /** + \defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information + \ingroup DAP_ConfigIO_gr + @{ +-Provides definitions about the hardware and configuration of the Debug Unit. +- +-This information includes: ++Provides definitions about: + - Definition of Cortex-M processor parameters used in CMSIS-DAP Debug Unit. +- - Debug Unit Identification strings (Vendor, Product, Serial Number). + - Debug Unit communication packet size. +- - Debug Access Port supported modes and settings (JTAG/SWD and SWO). ++ - Debug Access Port communication mode (JTAG or SWD). + - Optional information about a connected Target Device (for Evaluation Boards). + */ + +@@ -43,13 +42,18 @@ + /// This value is used to calculate the SWD/JTAG clock speed. + #define CPU_CLOCK SystemCoreClock ///< Specifies the CPU Clock in Hz + ++ ++// ToDo(elee): Review, is this 6 for H743? ++// https://stackoverflow.com/questions/51736591/stm32h7xx-toggle-io-as-fast-as-possible ++ + /// Number of processor cycles for I/O Port write operations. + /// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O + /// Port write operations in the Debug Unit by a Cortex-M MCU. Most Cortex-M processors +-/// require 2 processor cycles for a I/O Port Write operation. If the Debug Unit uses ++/// requrie 2 processor cycles for a I/O Port Write operation. If the Debug Unit uses + /// a Cortex-M0+ processor with high-speed peripheral I/O only 1 processor cycle might be +-/// required. +-#define IO_PORT_WRITE_CYCLES 2U ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0 ++/// requrired. ++#define IO_PORT_WRITE_CYCLES 2 ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0 ++ + + /// Indicate that Serial Wire Debug (SWD) communication mode is available at the Debug Access Port. + /// This information is returned by the command \ref DAP_Info as part of Capabilities. +@@ -57,11 +61,11 @@ + + /// Indicate that JTAG communication mode is available at the Debug Port. + /// This information is returned by the command \ref DAP_Info as part of Capabilities. +-#define DAP_JTAG 0 ///< JTAG Mode: 1 = available, 0 = not available. ++#define DAP_JTAG 1 ///< JTAG Mode: 1 = available, 0 = not available. + + /// Configure maximum number of JTAG devices on the scan chain connected to the Debug Access Port. + /// This setting impacts the RAM requirements of the Debug Unit. Valid range is 1 .. 255. +-#define DAP_JTAG_DEV_CNT 0 ///< Maximum number of JTAG devices on scan chain ++#define DAP_JTAG_DEV_CNT 4 ///< Maximum number of JTAG devices on scan chain + + /// Default communication mode on the Debug Access Port. + /// Used for the command \ref DAP_Connect when Port Default mode is selected. +@@ -72,38 +76,41 @@ + /// The command \ref DAP_SWJ_Clock can be used to overwrite this default setting. + #define DAP_DEFAULT_SWJ_CLOCK 5000000 ///< Default SWD/JTAG clock frequency in Hz. + ++//ToDo(elee): 512 for WinUSB? https://arm-software.github.io/CMSIS_5/DAP/html/group__DAP__Config__Debug__gr.html#gaa28bb1da2661291634c4a8fb3e227404 ++ + /// Maximum Package Size for Command and Response data. +-/// This configuration settings is used to optimize the communication performance with the +-/// debugger and depends on the USB peripheral. Typical vales are 64 for Full-speed USB HID or WinUSB, +-/// 1024 for High-speed USB HID and 512 for High-speed USB WinUSB. +-#ifndef HID_ENDPOINT //HID end points currently set limits to 64 +-#define DAP_PACKET_SIZE 512 ///< Specifies Packet Size in bytes. +-#else +-#define DAP_PACKET_SIZE 64 ///< Specifies Packet Size in bytes. +-#endif ++/// This configuration settings is used to optimized the communication performance with the ++/// debugger and depends on the USB peripheral. Change setting to 1024 for High-Speed USB. ++#define DAP_PACKET_SIZE 64 ///< USB: 64 = Full-Speed, 1024 = High-Speed. + + /// Maximum Package Buffers for Command and Response data. +-/// This configuration settings is used to optimize the communication performance with the ++/// This configuration settings is used to optimized the communication performance with the + /// debugger and depends on the USB peripheral. For devices with limited RAM or USB buffer the + /// setting can be reduced (valid range is 1 .. 255). Change setting to 4 for High-Speed USB. +-#define DAP_PACKET_COUNT 4 ///< Buffers: 64 = Full-Speed, 4 = High-Speed. ++#define DAP_PACKET_COUNT 64 ///< Buffers: 64 = Full-Speed, 4 = High-Speed. ++ ++ ++// ToDo(elee): enable SWO_UART + + /// Indicate that UART Serial Wire Output (SWO) trace is available. + /// This information is returned by the command \ref DAP_Info as part of Capabilities. + #define SWO_UART 0 ///< SWO UART: 1 = available, 0 = not available + +-/// USART Driver instance number for the UART SWO. +-#define SWO_UART_DRIVER 0 ///< USART Driver instance number (Driver_USART#). +- + /// Maximum SWO UART Baudrate + #define SWO_UART_MAX_BAUDRATE 10000000U ///< SWO UART Maximum Baudrate in Hz + ++ ++// ToDo(elee): Supported? How common? ++ + /// Indicate that Manchester Serial Wire Output (SWO) trace is available. + /// This information is returned by the command \ref DAP_Info as part of Capabilities. +-#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available. ++#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available + + /// SWO Trace Buffer Size. +-#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n). ++#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n) ++ ++ ++// Todo(elee): Looks like is 0 for all DAPLink probes. + + /// SWO Streaming Trace. + #define SWO_STREAM 0 ///< SWO Streaming Trace: 1 = available, 0 = not available. +@@ -111,88 +118,50 @@ + /// Clock frequency of the Test Domain Timer. Timer value is returned with \ref TIMESTAMP_GET. + #define TIMESTAMP_CLOCK 1000000U ///< Timestamp clock in Hz (0 = timestamps not supported). + +-/// Indicate that UART Communication Port is available. +-/// This information is returned by the command \ref DAP_Info as part of Capabilities. +-#define DAP_UART 0 ///< DAP UART: 1 = available, 0 = not available. +- +-/// USART Driver instance number for the UART Communication Port. +-#define DAP_UART_DRIVER 1 ///< USART Driver instance number (Driver_USART#). +- +-/// UART Receive Buffer Size. +-#define DAP_UART_RX_BUFFER_SIZE 1024U ///< Uart Receive Buffer Size in bytes (must be 2^n). +- +-/// UART Transmit Buffer Size. +-#define DAP_UART_TX_BUFFER_SIZE 1024U ///< Uart Transmit Buffer Size in bytes (must be 2^n). +- +-/// Indicate that UART Communication via USB COM Port is available. +-/// This information is returned by the command \ref DAP_Info as part of Capabilities. +-#define DAP_UART_USB_COM_PORT 1 ///< USB COM Port: 1 = available, 0 = not available. + + /// Debug Unit is connected to fixed Target Device. + /// The Debug Unit may be part of an evaluation board and always connected to a fixed +-/// known device. In this case a Device Vendor, Device Name, Board Vendor and Board Name strings +-/// are stored and may be used by the debugger or IDE to configure device parameters. +-#define TARGET_FIXED 0 ///< Target: 1 = known, 0 = unknown; +- ++/// known device. In this case a Device Vendor and Device Name string is stored which ++/// may be used by the debugger or IDE to configure device parameters. ++#define TARGET_DEVICE_FIXED 0 ///< Target Device: 1 = known, 0 = unknown; ++ ++#if TARGET_DEVICE_FIXED ++#define TARGET_DEVICE_VENDOR "" ///< String indicating the Silicon Vendor ++#define TARGET_DEVICE_NAME "" ///< String indicating the Target Device ++#endif + ///@} +- +- + __STATIC_INLINE void pin_out_init(GPIO_TypeDef* GPIOx, uint8_t pin_bit) + { +- if(pin_bit >= 8) +- { +- GPIOx->CRH &= ~(0x0000000F << ((pin_bit-8) << 2)); +- GPIOx->CRH |= ( ((uint32_t)(0x00|0x03) & 0x0F) << ((pin_bit-8) << 2) ); +- } +- else +- { +- GPIOx->CRL &= ~(0x0000000F << ((pin_bit) << 2)); +- GPIOx->CRL |= ( ((uint32_t)(0x00|0x03) & 0x0F) << ((pin_bit) << 2) ); +- } ++ GPIOx->MODER &= ~(0x00000003 << ((pin_bit) << 1)); //shift in 2 bit increments. ++ GPIOx->MODER |= ( 0x00000001 << ((pin_bit) << 1) ); // 0b01 = gpio out ++ GPIOx->OTYPER &= ~(0x00000001 << (pin_bit)); // 0b0 = push-pull mode ++ GPIOx->OSPEEDR |= (0x0000003 << ((pin_bit) << 1)); // set "very high speed" + } + + __STATIC_INLINE void pin_out_od_init(GPIO_TypeDef* GPIOx, uint8_t pin_bit) + { +- if(pin_bit >= 8) +- { +- GPIOx->CRH &= ~(0x0000000F << ((pin_bit-8) << 2)); +- GPIOx->CRH |= ( ((uint32_t)(0x04|0x03) & 0x0F) << ((pin_bit-8) << 2) ); +- } +- else +- { +- GPIOx->CRL &= ~(0x0000000F << ((pin_bit) << 2)); +- GPIOx->CRL |= ( ((uint32_t)(0x04|0x03) & 0x0F) << ((pin_bit) << 2) ); +- } ++ GPIOx->MODER &= ~(0x00000003 << ((pin_bit) << 1)); ++ GPIOx->MODER |= ( 0x00000001 << ((pin_bit) << 1) ); // 0b01 = gpio out ++ GPIOx->OTYPER |= (0x00000001 << (pin_bit)); // 0b1 = open drain mode ++ GPIOx->OSPEEDR |= (0x0000003 << ((pin_bit) << 1)); // set "very high speed" + } + + __STATIC_INLINE void pin_in_init(GPIO_TypeDef* GPIOx, uint8_t pin_bit, uint8_t mode) + { +- uint8_t config; +- if(mode == 1) +- config = 0x08; //Up +- else if(mode == 2) +- config = 0x08; //down +- else +- config = 0x00; //GPIO_Mode_AIN +- +- if(pin_bit >= 8) +- { +- GPIOx->CRH &= ~(0x0000000F << ((pin_bit-8) << 2)); +- GPIOx->CRH |= ( ((uint32_t)(config) & 0x0F) << ((pin_bit-8) << 2) ); +- if(mode == 1) +- GPIOx->BSRR = (((uint32_t)0x01) << pin_bit); +- else if(mode == 2) +- GPIOx->BRR = (((uint32_t)0x01) << pin_bit); ++ // mode = 0 -> analog input, 1->pullup, 2->pulldown, 3->input-no-pullups ++ uint8_t config = 0; ++ if(mode == 1) { ++ config = 0x01; //pull-up ++ } else if(mode == 2) { ++ config = 0x02; //pull-down + } +- else +- { +- GPIOx->CRL &= ~(0x0000000F << ((pin_bit) << 2)); +- GPIOx->CRL |= ( ((uint32_t)(config) & 0x0F) << ((pin_bit) << 2) ); +- if(mode == 1) +- GPIOx->BSRR = (((uint32_t)0x01) << pin_bit); +- else if(mode == 2) +- GPIOx->BRR = (((uint32_t)0x01) << pin_bit); ++ if( mode == 0) { //analog input ++ GPIOx->MODER |= ( 0x00000003 << ((pin_bit) << 1) ); // 0b11 = analog mode ++ } else { // gpio in (mode >0) ++ GPIOx->MODER &= ~(0x00000003 << ((pin_bit) << 1)); // clear (input mode) + } ++ GPIOx->PUPDR &= ~(0x00000003 << ((pin_bit) << 1)); // clear ++ GPIOx->PUPDR |= ( ((uint32_t)(config) & 0x03) << ((pin_bit) << 1)); // set pullup/down + } + //************************************************************************************************** + /** +@@ -251,17 +220,6 @@ + */ + __STATIC_INLINE void PORT_SWD_SETUP(void) + { +- // Set SWCLK HIGH +- pin_out_init(SWCLK_TCK_PIN_PORT, SWCLK_TCK_PIN_Bit); +- SWCLK_TCK_PIN_PORT->BSRR = SWCLK_TCK_PIN; +- // Set SWDIO HIGH +- pin_out_init(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN_Bit); +- SWDIO_OUT_PIN_PORT->BSRR = SWDIO_OUT_PIN; +- +- pin_in_init(SWDIO_IN_PIN_PORT, SWDIO_IN_PIN_Bit, 1); +- // Set RESET HIGH +- pin_out_od_init(nRESET_PIN_PORT, nRESET_PIN_Bit);//TODO - fix reset logic +- nRESET_PIN_PORT->BSRR = nRESET_PIN; + } + + /** Disable JTAG/SWD I/O Pins. +@@ -269,10 +227,7 @@ + - TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode. + */ + __STATIC_INLINE void PORT_OFF(void) +-{ +- pin_in_init(SWCLK_TCK_PIN_PORT, SWCLK_TCK_PIN_Bit, 0); +- pin_in_init(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN_Bit, 0); +- pin_in_init(SWDIO_IN_PIN_PORT, SWDIO_IN_PIN_Bit, 0); ++{ + } + + // SWCLK/TCK I/O pin ------------------------------------- +@@ -298,7 +253,7 @@ + */ + __STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void) + { +- SWCLK_TCK_PIN_PORT->BRR = SWCLK_TCK_PIN; ++ SWCLK_TCK_PIN_PORT->BSRR = (SWCLK_TCK_PIN << 16); + } + + // SWDIO/TMS Pin I/O -------------------------------------- +@@ -308,7 +263,7 @@ + */ + __STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void) + { +- return ((SWDIO_IN_PIN_PORT->IDR & SWDIO_IN_PIN) ? 1 : 0); ++ return ((SWDIO_OUT_TMS_PIN_PORT->IDR & SWDIO_OUT_TMS_PIN) ? 1 : 0); + } + + /** SWDIO/TMS I/O pin: Set Output to High. +@@ -316,7 +271,7 @@ + */ + __STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void) + { +- SWDIO_OUT_PIN_PORT->BSRR = SWDIO_OUT_PIN; ++ SWDIO_OUT_TMS_PIN_PORT->BSRR = SWDIO_OUT_TMS_PIN; + } + + /** SWDIO/TMS I/O pin: Set Output to Low. +@@ -324,7 +279,7 @@ + */ + __STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void) + { +- SWDIO_OUT_PIN_PORT->BRR = SWDIO_OUT_PIN; ++ SWDIO_OUT_TMS_PIN_PORT->BSRR = (SWDIO_OUT_TMS_PIN << 16); + } + + /** SWDIO I/O pin: Get Input (used in SWD mode only). +@@ -339,11 +294,12 @@ + \param bit Output value for the SWDIO DAP hardware I/O pin. + */ + __STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit) ++//extern void PIN_SWDIO_OUT(uint32_t bit); + { + if (bit & 1) +- SWDIO_OUT_PIN_PORT->BSRR = SWDIO_OUT_PIN; ++ SWDIO_OUT_TMS_PIN_PORT->BSRR = SWDIO_OUT_TMS_PIN; + else +- SWDIO_OUT_PIN_PORT->BRR = SWDIO_OUT_PIN; ++ SWDIO_OUT_TMS_PIN_PORT->BSRR = (SWDIO_OUT_TMS_PIN << 16); + } + + /** SWDIO I/O pin: Switch to Output mode (used in SWD mode only). +@@ -352,8 +308,8 @@ + */ + __STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE(void) + { +- pin_out_init(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN_Bit); +- SWDIO_OUT_PIN_PORT->BRR = SWDIO_OUT_PIN; ++ SWDIO_INOUT_OE_PORT->BSRR = (SWDIO_INOUT_OE_PIN << 16); ++ __NOP(); + } + + /** SWDIO I/O pin: Switch to Input mode (used in SWD mode only). +@@ -362,8 +318,8 @@ + */ + __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void) + { +- pin_in_init(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN_Bit, 0); +- SWDIO_OUT_PIN_PORT->BSRR = SWDIO_OUT_PIN; ++ SWDIO_INOUT_OE_PORT->BSRR = SWDIO_INOUT_OE_PIN; ++ __NOP(); + } + + +@@ -374,7 +330,7 @@ + */ + __STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void) + { +- return (0); // Not available ++ return ((JTAG_TDI_PIN_PORT->IDR & JTAG_TDI_PIN) ? 1 : 0); + } + + /** TDI I/O pin: Set Output. +@@ -382,7 +338,10 @@ + */ + __STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit) + { +- ; // Not available ++ if (bit & 1) ++ JTAG_TDI_PIN_PORT->BSRR = JTAG_TDI_PIN; ++ else ++ JTAG_TDI_PIN_PORT->BSRR = (JTAG_TDI_PIN << 16); + } + + +@@ -393,7 +352,7 @@ + */ + __STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) + { +- return (0); // Not available ++ return ((JTAG_TDO_PIN_PORT->IDR & JTAG_TDO_PIN) ? 1 : 0); + } + + +@@ -404,7 +363,7 @@ + */ + __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void) + { +- return (0); // Not available ++ return ((JTAG_TRST_PIN_PORT->IDR & JTAG_TRST_PIN) ? 1 : 0); + } + + /** nTRST I/O pin: Set Output. +@@ -414,7 +373,10 @@ + */ + __STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) + { +- ; // Not available ++ if (bit & 1) ++ JTAG_TRST_PIN_PORT->BSRR = JTAG_TRST_PIN; ++ else ++ JTAG_TRST_PIN_PORT->BSRR = (JTAG_TRST_PIN << 16); + } + + // nRESET Pin I/O------------------------------------------ +@@ -424,7 +386,7 @@ + */ + __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void) + { +- return ((nRESET_PIN_PORT->IDR >> nRESET_PIN_Bit) & 1); ++ return ((JTAG_TARGET_RST_PIN_PORT->IDR >> JTAG_TARGET_RST_PIN_BIT) & 1); + } + + /** nRESET I/O pin: Set Output. +@@ -437,9 +399,9 @@ + __STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) + { + if (bit & 1) +- nRESET_PIN_PORT->BSRR = nRESET_PIN; ++ JTAG_TARGET_RST_PIN_PORT->BSRR = (JTAG_TARGET_RST_PIN << 16); // DIR pin low -> nRST goes high + else +- nRESET_PIN_PORT->BRR = nRESET_PIN; ++ JTAG_TARGET_RST_PIN_PORT->BSRR = JTAG_TARGET_RST_PIN; // DIR pin high -> nRST goes low + } + + //************************************************************************************************** +@@ -462,10 +424,6 @@ + */ + __STATIC_INLINE void LED_CONNECTED_OUT(uint32_t bit) + { +- if (bit & 1) +- CONNECTED_LED_PORT->BRR = CONNECTED_LED_PIN; // LED on +- else +- CONNECTED_LED_PORT->BSRR = CONNECTED_LED_PIN;// LED off + } + + /** Debug Unit: Set status Target Running LED. +@@ -475,7 +433,6 @@ + */ + __STATIC_INLINE void LED_RUNNING_OUT(uint32_t bit) + { +- ; // Not available + } + + ///@} +@@ -496,8 +453,9 @@ + /** Get timestamp of Test Domain Timer. + \return Current timestamp value. + */ +-__STATIC_INLINE uint32_t TIMESTAMP_GET (void) { +- return (DWT->CYCCNT) / (CPU_CLOCK / TIMESTAMP_CLOCK); ++__STATIC_INLINE uint32_t TIMESTAMP_GET (void) ++{ ++ return 100; + } + + ///@} +@@ -522,25 +480,7 @@ + */ + __STATIC_INLINE void DAP_SETUP(void) + { +- /* Enable port clock */ +- __HAL_RCC_GPIOA_CLK_ENABLE(); +- __HAL_RCC_GPIOB_CLK_ENABLE(); +- __HAL_RCC_GPIOC_CLK_ENABLE(); +- __HAL_RCC_GPIOD_CLK_ENABLE(); +- /* Configure I/O pin SWCLK */ +- pin_out_init(SWCLK_TCK_PIN_PORT, SWCLK_TCK_PIN_Bit); +- SWCLK_TCK_PIN_PORT->BSRR = SWCLK_TCK_PIN; +- +- pin_out_init(SWDIO_OUT_PIN_PORT, SWDIO_OUT_PIN_Bit); +- SWDIO_OUT_PIN_PORT->BSRR = SWDIO_OUT_PIN; +- +- pin_in_init(SWDIO_IN_PIN_PORT, SWDIO_IN_PIN_Bit, 1); +- +- pin_out_od_init(nRESET_PIN_PORT, nRESET_PIN_Bit); +- nRESET_PIN_PORT->BSRR = nRESET_PIN; +- +- pin_out_init(CONNECTED_LED_PORT, CONNECTED_LED_PIN_Bit); +- CONNECTED_LED_PORT->BSRR = CONNECTED_LED_PIN; ++ //ToDo(elee): Can it just call PORT_SWD_SETUP() instead? + } + + /** Reset Target Device with custom specific I/O pin or command sequence. +@@ -556,6 +496,4 @@ + } + + ///@} +- +- +-#endif /* __DAP_CONFIG_H__ */ ++#endif /* __DAP_CONFIG_H__ */ +\ No newline at end of file +diff -uNr old/CM4/Core/Inc/DAP.h new/CM4/Core/Inc/DAP.h +--- old/CM4/Core/Inc/DAP.h 2023-05-29 09:46:06.000000000 +0800 ++++ new/CM4/Core/Inc/DAP.h 2023-12-27 14:21:19.308466152 +0800 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2013-2021 ARM Limited. All rights reserved. ++ * Copyright (c) 2013-2020 ARM Limited. All rights reserved. + * Copyright 2019, Cypress Semiconductor Corporation + * or a subsidiary of Cypress Semiconductor Corporation. + * +@@ -19,8 +19,8 @@ + * + * ---------------------------------------------------------------------- + * +- * $Date: 26. May 2021 +- * $Revision: V2.1.0 ++ * $Date: 26. November 2019 ++ * $Revision: V2.0.0 + * + * Project: CMSIS-DAP Include + * Title: DAP.h Definitions +@@ -33,9 +33,9 @@ + + // DAP Firmware Version + #ifdef DAP_FW_V1 +-#define DAP_FW_VER "1.3.0" ++#define DAP_FW_VER "1.2.0" + #else +-#define DAP_FW_VER "2.1.0" ++#define DAP_FW_VER "2.0.0" + #endif + + // DAP Command IDs +@@ -65,11 +65,6 @@ + #define ID_DAP_SWO_Status 0x1BU + #define ID_DAP_SWO_ExtendedStatus 0x1EU + #define ID_DAP_SWO_Data 0x1CU +-#define ID_DAP_UART_Transport 0x1FU +-#define ID_DAP_UART_Configure 0x20U +-#define ID_DAP_UART_Control 0x22U +-#define ID_DAP_UART_Status 0x23U +-#define ID_DAP_UART_Transfer 0x21U + + #define ID_DAP_QueueCommands 0x7EU + #define ID_DAP_ExecuteCommands 0x7FU +@@ -123,16 +118,13 @@ + #define DAP_ID_VENDOR 1U + #define DAP_ID_PRODUCT 2U + #define DAP_ID_SER_NUM 3U +-#define DAP_ID_DAP_FW_VER 4U ++#define DAP_ID_CMSIS_DAP_VER 4U ++#define DAP_ID_FW_VER 4U // Deprecated alias of DAP_ID_CMSIS_DAP_VER for backwards compatibility. + #define DAP_ID_DEVICE_VENDOR 5U + #define DAP_ID_DEVICE_NAME 6U +-#define DAP_ID_BOARD_VENDOR 7U +-#define DAP_ID_BOARD_NAME 8U +-#define DAP_ID_PRODUCT_FW_VER 9U ++#define DAP_ID_PRODUCT_FW_VER 7U + #define DAP_ID_CAPABILITIES 0xF0U + #define DAP_ID_TIMESTAMP_CLOCK 0xF1U +-#define DAP_ID_UART_RX_BUFFER_SIZE 0xFBU +-#define DAP_ID_UART_TX_BUFFER_SIZE 0xFCU + #define DAP_ID_SWO_BUFFER_SIZE 0xFDU + #define DAP_ID_PACKET_COUNT 0xFEU + #define DAP_ID_PACKET_SIZE 0xFFU +@@ -182,30 +174,6 @@ + #define DAP_SWO_STREAM_ERROR (1U<<6) + #define DAP_SWO_BUFFER_OVERRUN (1U<<7) + +-// DAP UART Transport +-#define DAP_UART_TRANSPORT_NONE 0U +-#define DAP_UART_TRANSPORT_USB_COM_PORT 1U +-#define DAP_UART_TRANSPORT_DAP_COMMAND 2U +- +-// DAP UART Control +-#define DAP_UART_CONTROL_RX_ENABLE (1U<<0) +-#define DAP_UART_CONTROL_RX_DISABLE (1U<<1) +-#define DAP_UART_CONTROL_RX_BUF_FLUSH (1U<<2) +-#define DAP_UART_CONTROL_TX_ENABLE (1U<<4) +-#define DAP_UART_CONTROL_TX_DISABLE (1U<<5) +-#define DAP_UART_CONTROL_TX_BUF_FLUSH (1U<<6) +- +-// DAP UART Status +-#define DAP_UART_STATUS_RX_ENABLED (1U<<0) +-#define DAP_UART_STATUS_RX_DATA_LOST (1U<<1) +-#define DAP_UART_STATUS_FRAMING_ERROR (1U<<2) +-#define DAP_UART_STATUS_PARITY_ERROR (1U<<3) +-#define DAP_UART_STATUS_TX_ENABLED (1U<<4) +- +-// DAP UART Configure Error +-#define DAP_UART_CFG_ERROR_DATA_BITS (1U<<0) +-#define DAP_UART_CFG_ERROR_PARITY (1U<<1) +-#define DAP_UART_CFG_ERROR_STOP_BITS (1U<<2) + + // Debug Port Register Addresses + #define DP_IDCODE 0x00U // IDCODE Register (SW Read only) +@@ -239,39 +207,40 @@ + + // DAP Data structure + typedef struct { +- uint8_t debug_port; // Debug Port +- uint8_t fast_clock; // Fast Clock Flag +- uint8_t padding[2]; +- uint32_t clock_delay; // Clock Delay +- uint32_t nominal_clock; // Nominal requested clock frequency in Hertz. +- uint32_t timestamp; // Last captured Timestamp +- struct { // Transfer Configuration +- uint8_t idle_cycles; // Idle cycles after transfer +- uint8_t padding[3]; +- uint16_t retry_count; // Number of retries after WAIT response +- uint16_t match_retry; // Number of retries if read value does not match +- uint32_t match_mask; // Match Mask +- } transfer; ++ uint8_t debug_port; // Debug Port ++ uint8_t fast_clock; // Fast Clock Flag ++ uint32_t clock_level; // clock_level ++ uint8_t padding[2]; ++ uint32_t clock_delay; // Clock Delay ++ uint32_t nominal_clock; // Nominal requested clock frequency in Hertz. ++ uint32_t timestamp; // Last captured Timestamp ++ struct { // Transfer Configuration ++ uint8_t idle_cycles; // Idle cycles after transfer ++ uint8_t padding[3]; ++ uint16_t retry_count; // Number of retries after WAIT response ++ uint16_t match_retry; // Number of retries if read value does not match ++ uint32_t match_mask; // Match Mask ++ } transfer; + #if (DAP_SWD != 0) +- struct { // SWD Configuration +- uint8_t turnaround; // Turnaround period +- uint8_t data_phase; // Always generate Data Phase +- } swd_conf; ++ struct { // SWD Configuration ++ uint8_t turnaround; // Turnaround period ++ uint8_t data_phase; // Always generate Data Phase ++ } swd_conf; + #endif + #if (DAP_JTAG != 0) +- struct { // JTAG Device Chain +- uint8_t count; // Number of devices +- uint8_t index; // Device index (device at TDO has index 0) ++ struct { // JTAG Device Chain ++ uint8_t count; // Number of devices ++ uint8_t index; // Device index (device at TDO has index 0) + #if (DAP_JTAG_DEV_CNT != 0) +- uint8_t ir_length[DAP_JTAG_DEV_CNT]; // IR Length in bits +- uint16_t ir_before[DAP_JTAG_DEV_CNT]; // Bits before IR +- uint16_t ir_after [DAP_JTAG_DEV_CNT]; // Bits after IR ++ uint8_t ir_length[DAP_JTAG_DEV_CNT]; // IR Length in bits ++ uint16_t ir_before[DAP_JTAG_DEV_CNT]; // Bits before IR ++ uint16_t ir_after [DAP_JTAG_DEV_CNT]; // Bits after IR + #endif +- } jtag_dev; ++ } jtag_dev; + #endif + } DAP_Data_t; + +-extern DAP_Data_t DAP_Data; // DAP Data ++//extern DAP_Data_t DAP_Data; // DAP Data + extern volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag + + +@@ -304,25 +273,17 @@ + extern void SWO_AbortTransfer (void); + extern void SWO_TransferComplete (void); + +-extern uint32_t SWO_Mode_UART (uint32_t enable); +-extern uint32_t SWO_Baudrate_UART (uint32_t baudrate); +-extern uint32_t SWO_Control_UART (uint32_t active); +-extern void SWO_Capture_UART (uint8_t *buf, uint32_t num); +-extern uint32_t SWO_GetCount_UART (void); +- +-extern uint32_t SWO_Mode_Manchester (uint32_t enable); +-extern uint32_t SWO_Baudrate_Manchester (uint32_t baudrate); +-extern uint32_t SWO_Control_Manchester (uint32_t active); +-extern void SWO_Capture_Manchester (uint8_t *buf, uint32_t num); +-extern uint32_t SWO_GetCount_Manchester (void); +- +-extern uint32_t UART_Transport (const uint8_t *request, uint8_t *response); +-extern uint32_t UART_Configure (const uint8_t *request, uint8_t *response); +-extern uint32_t UART_Control (const uint8_t *request, uint8_t *response); +-extern uint32_t UART_Status (uint8_t *response); +-extern uint32_t UART_Transfer (const uint8_t *request, uint8_t *response); +- +-extern uint8_t USB_COM_PORT_Activate (uint32_t cmd); ++extern uint32_t UART_SWO_Mode (uint32_t enable); ++extern uint32_t UART_SWO_Baudrate (uint32_t baudrate); ++extern uint32_t UART_SWO_Control (uint32_t active); ++extern void UART_SWO_Capture (uint8_t *buf, uint32_t num); ++extern uint32_t UART_SWO_GetCount (void); ++ ++extern uint32_t Manchester_SWO_Mode (uint32_t enable); ++extern uint32_t Manchester_SWO_Baudrate (uint32_t baudrate); ++extern uint32_t Manchester_SWO_Control (uint32_t active); ++extern void Manchester_SWO_Capture (uint8_t *buf, uint32_t num); ++extern uint32_t Manchester_SWO_GetCount (void); + + extern uint32_t DAP_ProcessVendorCommand (const uint8_t *request, uint8_t *response); + extern uint32_t DAP_ProcessCommand (const uint8_t *request, uint8_t *response); +@@ -371,5 +332,4 @@ + } + #endif + +- +-#endif /* __DAP_H__ */ ++#endif /* __DAP_H__ */ +\ No newline at end of file +diff -uNr old/CM4/Core/Src/JTAG_DP.c new/CM4/Core/Src/JTAG_DP.c +--- old/CM4/Core/Src/JTAG_DP.c 2023-05-29 09:46:06.000000000 +0800 ++++ new/CM4/Core/Src/JTAG_DP.c 2023-06-09 15:19:50.898107400 +0800 +@@ -27,7 +27,8 @@ + + #include "DAP_config.h" + #include "DAP.h" +- ++#include "swd_jtag_config.h" ++#include "debug.h" + + // JTAG Macros + +@@ -36,335 +37,551 @@ + #define PIN_TMS_SET PIN_SWDIO_TMS_SET + #define PIN_TMS_CLR PIN_SWDIO_TMS_CLR + +-#define JTAG_CYCLE_TCK() \ +- PIN_TCK_CLR(); \ +- PIN_DELAY(); \ +- PIN_TCK_SET(); \ +- PIN_DELAY() +- +-#define JTAG_CYCLE_TDI(tdi) \ +- PIN_TDI_OUT(tdi); \ +- PIN_TCK_CLR(); \ +- PIN_DELAY(); \ +- PIN_TCK_SET(); \ +- PIN_DELAY() +- +-#define JTAG_CYCLE_TDO(tdo) \ +- PIN_TCK_CLR(); \ +- PIN_DELAY(); \ +- tdo = PIN_TDO_IN(); \ +- PIN_TCK_SET(); \ +- PIN_DELAY() +- +-#define JTAG_CYCLE_TDIO(tdi,tdo) \ +- PIN_TDI_OUT(tdi); \ +- PIN_TCK_CLR(); \ +- PIN_DELAY(); \ +- tdo = PIN_TDO_IN(); \ +- PIN_TCK_SET(); \ +- PIN_DELAY() ++inline static void JTAGDP_DELAY_LEVEL_0(void) ++{ ++ return; ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_1(void) ++{ ++ __NOP(); ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_2(void) ++{ ++ __NOP();__NOP(); ++} + +-#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) ++inline static void JTAGDP_DELAY_LEVEL_3(void) ++{ ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_4(void) ++{ ++ __NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_5(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP(); ++} + ++inline static void JTAGDP_DELAY_LEVEL_6(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP(); ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_7(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP(); ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_8(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_9(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void JTAGDP_DELAY_LEVEL_LOW(uint32_t delay) ++{ ++ volatile uint32_t cnt = delay; ++ while(cnt) { ++ cnt--; ++ } ++} ++ ++#define JTAG_CYCLE_TCK() \ ++ PIN_TCK_CLR(); \ ++ __NOP();__NOP();__NOP();__NOP(); \ ++ PIN_DELAY(); \ ++ PIN_TCK_SET(); \ ++ __NOP();__NOP();__NOP(); \ ++ PIN_DELAY() ++ ++#define JTAG_CYCLE_TDI(tdi) \ ++ PIN_TDI_OUT(tdi); \ ++ PIN_TCK_CLR(); \ ++ __NOP();__NOP();__NOP();__NOP(); \ ++ PIN_DELAY(); \ ++ PIN_TCK_SET(); \ ++ __NOP(); __NOP();__NOP(); \ ++ PIN_DELAY() ++ ++#define JTAG_CYCLE_TDO(tdo) \ ++ PIN_TCK_CLR(); \ ++ __NOP();__NOP();__NOP();__NOP(); \ ++ PIN_DELAY(); \ ++ tdo = PIN_TDO_IN(); \ ++ PIN_TCK_SET(); \ ++ __NOP();__NOP();__NOP(); \ ++ PIN_DELAY() ++ ++#define JTAG_CYCLE_TDIO(tdi, tdo) \ ++ PIN_TDI_OUT(tdi); \ ++ PIN_TCK_CLR(); \ ++ __NOP();__NOP();__NOP();__NOP(); \ ++ __NOP(); __NOP(); \ ++ PIN_DELAY(); \ ++ tdo = PIN_TDO_IN(); \ ++ PIN_TCK_SET(); \ ++ __NOP();__NOP();__NOP(); \ ++ PIN_DELAY() ++ ++#define PIN_DELAY() PIN_DELAY_SLOW(g_DAP_Data.clock_delay) + + #if (DAP_JTAG != 0) ++/* Generate JTAG Sequence ++ * info: sequence information ++ * tdi: pointer to TDI generated data ++ * tdo: pointer to TDO captured data ++ * return: none ++ */ ++void JTAG_Sequence (uint32_t info, const uint8_t *tdi, uint8_t *tdo) ++{ ++ uint32_t i_val; ++ uint32_t o_val; ++ uint32_t bit; ++ uint32_t n, k; ++ ++ n = info & JTAG_SEQUENCE_TCK; ++ if (n == 0U) { ++ n = 64U; ++ } ++ ++ if (info & JTAG_SEQUENCE_TMS) { ++ PIN_TMS_SET(); ++ } else { ++ PIN_TMS_CLR(); ++ } ++ ++ while (n) { ++ i_val = *tdi++; ++ o_val = 0U; ++ for (k = 8U; k && n; k--, n--) { ++ JTAG_CYCLE_TDIO(i_val, bit); ++ i_val >>= 1; ++ o_val >>= 1; ++ o_val |= bit << 7; ++ } ++ o_val >>= k; ++ if (info & JTAG_SEQUENCE_TDO) { ++ *tdo++ = (uint8_t)o_val; ++ } ++ } ++} ++ ++/* JTAG Set IR ++ * ir: IR value ++ * return: none ++ */ ++#define JTAG_IR_Function(speed) \ ++static void JTAG_IR_##speed (uint32_t ir) \ ++{ \ ++ uint32_t n; \ ++ \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \ ++ JTAG_CYCLE_TCK(); /* Select-IR-Scan */ \ ++ PIN_TMS_CLR(); \ ++ JTAG_CYCLE_TCK(); /* Capture-IR */ \ ++ JTAG_CYCLE_TCK(); /* Shift-IR */ \ ++ \ ++ PIN_TDI_OUT(1U); \ ++ for (n = g_DAP_Data.jtag_dev.ir_before[g_DAP_Data.jtag_dev.index]; n; n--) { \ ++ JTAG_CYCLE_TCK(); /* Bypass before data */ \ ++ } \ ++ for (n = g_DAP_Data.jtag_dev.ir_length[g_DAP_Data.jtag_dev.index] - 1U; n; n--) { \ ++ JTAG_CYCLE_TDI(ir); /* Set IR bits (except last) */ \ ++ ir >>= 1; \ ++ } \ ++ n = g_DAP_Data.jtag_dev.ir_after[g_DAP_Data.jtag_dev.index]; \ ++ if (n) { \ ++ JTAG_CYCLE_TDI(ir); /* Set last IR bit */ \ ++ PIN_TDI_OUT(1U); \ ++ for (--n; n; n--) { \ ++ JTAG_CYCLE_TCK(); /* Bypass after data */ \ ++ } \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Bypass & Exit1-IR */ \ ++ } else { \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TDI(ir); /* Set last IR bit & Exit1-IR */ \ ++ } \ ++ \ ++ JTAG_CYCLE_TCK(); /* Update-IR */ \ ++ PIN_TMS_CLR(); \ ++ JTAG_CYCLE_TCK(); /* Idle */ \ ++ PIN_TDI_OUT(1U); \ ++} ++ ++ ++/* JTAG Transfer I/O ++ * request: A[3:2] RnW APnDP ++ * data: DATA[31:0] ++ * return: ACK[2:0] ++ */ ++#define JTAG_TransferFunction(speed) \ ++static uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) \ ++{ \ ++ uint32_t ack; \ ++ uint32_t bit; \ ++ uint32_t val; \ ++ uint32_t n; \ ++ \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \ ++ PIN_TMS_CLR(); \ ++ JTAG_CYCLE_TCK(); /* Capture-DR */ \ ++ JTAG_CYCLE_TCK(); /* Shift-DR */ \ ++ \ ++ for (n = g_DAP_Data.jtag_dev.index; n; n--) { \ ++ JTAG_CYCLE_TCK(); /* Bypass before data */ \ ++ } \ ++ \ ++ JTAG_CYCLE_TDIO(request >> 1, bit); /* Set RnW, Get ACK.0 */ \ ++ ack = bit << 1; \ ++ JTAG_CYCLE_TDIO(request >> 2, bit); /* Set A2, Get ACK.1 */ \ ++ ack |= bit << 0; \ ++ JTAG_CYCLE_TDIO(request >> 3, bit); /* Set A3, Get ACK.2 */ \ ++ ack |= bit << 2; \ ++ \ ++ if (ack != DAP_TRANSFER_OK) { \ ++ /* Exit on error */ \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Exit1-DR */ \ ++ goto exit; \ ++ } \ ++ \ ++ if (request & DAP_TRANSFER_RnW) { \ ++ /* Read Transfer */ \ ++ val = 0U; \ ++ for (n = 31U; n; n--) { \ ++ JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ \ ++ val |= bit << 31; \ ++ val >>= 1; \ ++ } \ ++ n = g_DAP_Data.jtag_dev.count - g_DAP_Data.jtag_dev.index - 1U; \ ++ if (n) { \ ++ JTAG_CYCLE_TDO(bit); /* Get D31 */ \ ++ for (--n; n; n--) { \ ++ JTAG_CYCLE_TCK(); /* Bypass after data */ \ ++ } \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \ ++ } else { \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ \ ++ } \ ++ val |= bit << 31; \ ++ if (data) { \ ++ *data = val; \ ++ } \ ++ } else { \ ++ /* Write Transfer */ \ ++ val = *data; \ ++ for (n = 31U; n; n--) { \ ++ JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \ ++ val >>= 1; \ ++ } \ ++ n = g_DAP_Data.jtag_dev.count - g_DAP_Data.jtag_dev.index - 1U; \ ++ if (n) { \ ++ JTAG_CYCLE_TDI(val); /* Set D31 */ \ ++ for (--n; n; n--) { \ ++ JTAG_CYCLE_TCK(); /* Bypass after data */ \ ++ } \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \ ++ } else { \ ++ PIN_TMS_SET(); \ ++ JTAG_CYCLE_TDI(val); /* Set D31 & Exit1-DR */ \ ++ } \ ++ } \ ++ \ ++exit: \ ++ JTAG_CYCLE_TCK(); /* Update-DR */ \ ++ PIN_TMS_CLR(); \ ++ JTAG_CYCLE_TCK(); /* Idle */ \ ++ PIN_TDI_OUT(1U); \ ++ \ ++ /* Capture Timestamp */ \ ++ if (request & DAP_TRANSFER_TIMESTAMP) { \ ++ g_DAP_Data.timestamp = TIMESTAMP_GET(); \ ++ } \ ++ \ ++ /* Idle cycles */ \ ++ n = g_DAP_Data.transfer.idle_cycles; \ ++ while (n--) { \ ++ JTAG_CYCLE_TCK(); /* Idle */ \ ++ } \ ++ \ ++ return ((uint8_t)ack); \ ++} ++ ++#ifdef USE_HIGHT_LEVEL ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_0() ++JTAG_IR_Function(Level0) ++JTAG_TransferFunction(Level0) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_1() ++JTAG_IR_Function(Level1) ++JTAG_TransferFunction(Level1) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_2() ++JTAG_IR_Function(Level2) ++JTAG_TransferFunction(Level2) + ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_3() ++JTAG_IR_Function(Level3) ++JTAG_TransferFunction(Level3) ++ ++#endif /* #ifdef USE_HIGHT_LEVEL */ ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_4() ++JTAG_IR_Function(Level4) ++JTAG_TransferFunction(Level4) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_5() ++JTAG_IR_Function(Level5) ++JTAG_TransferFunction(Level5) + +-// Generate JTAG Sequence +-// info: sequence information +-// tdi: pointer to TDI generated data +-// tdo: pointer to TDO captured data +-// return: none +-void JTAG_Sequence (uint32_t info, const uint8_t *tdi, uint8_t *tdo) { +- uint32_t i_val; +- uint32_t o_val; +- uint32_t bit; +- uint32_t n, k; +- +- n = info & JTAG_SEQUENCE_TCK; +- if (n == 0U) { +- n = 64U; +- } ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_6() ++JTAG_IR_Function(Level6) ++JTAG_TransferFunction(Level6) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_7() ++JTAG_IR_Function(Level7) ++JTAG_TransferFunction(Level7) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_8() ++JTAG_IR_Function(Level8) ++JTAG_TransferFunction(Level8) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_9() ++JTAG_IR_Function(Level9) ++JTAG_TransferFunction(Level9) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() JTAGDP_DELAY_LEVEL_LOW(g_DAP_Data.clock_delay) ++JTAG_IR_Function(LevelLow) ++JTAG_TransferFunction(LevelLow) ++ ++ ++/* JTAG Read IDCODE register ++ * return: value read ++ */ ++uint32_t JTAG_ReadIDCode (void) ++{ ++ uint32_t bit; ++ uint32_t val; ++ uint32_t n; + +- if (info & JTAG_SEQUENCE_TMS) { + PIN_TMS_SET(); +- } else { ++ JTAG_CYCLE_TCK(); /* Select-DR-Scan */ + PIN_TMS_CLR(); +- } ++ JTAG_CYCLE_TCK(); /* Capture-DR */ ++ JTAG_CYCLE_TCK(); /* Shift-DR */ + +- while (n) { +- i_val = *tdi++; +- o_val = 0U; +- for (k = 8U; k && n; k--, n--) { +- JTAG_CYCLE_TDIO(i_val, bit); +- i_val >>= 1; +- o_val >>= 1; +- o_val |= bit << 7; +- } +- o_val >>= k; +- if (info & JTAG_SEQUENCE_TDO) { +- *tdo++ = (uint8_t)o_val; +- } +- } +-} +- +- +-// JTAG Set IR +-// ir: IR value +-// return: none +-#define JTAG_IR_Function(speed) /**/ \ +-static void JTAG_IR_##speed (uint32_t ir) { \ +- uint32_t n; \ +- \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \ +- JTAG_CYCLE_TCK(); /* Select-IR-Scan */ \ +- PIN_TMS_CLR(); \ +- JTAG_CYCLE_TCK(); /* Capture-IR */ \ +- JTAG_CYCLE_TCK(); /* Shift-IR */ \ +- \ +- PIN_TDI_OUT(1U); \ +- for (n = DAP_Data.jtag_dev.ir_before[DAP_Data.jtag_dev.index]; n; n--) { \ +- JTAG_CYCLE_TCK(); /* Bypass before data */ \ +- } \ +- for (n = DAP_Data.jtag_dev.ir_length[DAP_Data.jtag_dev.index] - 1U; n; n--) { \ +- JTAG_CYCLE_TDI(ir); /* Set IR bits (except last) */ \ +- ir >>= 1; \ +- } \ +- n = DAP_Data.jtag_dev.ir_after[DAP_Data.jtag_dev.index]; \ +- if (n) { \ +- JTAG_CYCLE_TDI(ir); /* Set last IR bit */ \ +- PIN_TDI_OUT(1U); \ +- for (--n; n; n--) { \ +- JTAG_CYCLE_TCK(); /* Bypass after data */ \ +- } \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Bypass & Exit1-IR */ \ +- } else { \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TDI(ir); /* Set last IR bit & Exit1-IR */ \ +- } \ +- \ +- JTAG_CYCLE_TCK(); /* Update-IR */ \ +- PIN_TMS_CLR(); \ +- JTAG_CYCLE_TCK(); /* Idle */ \ +- PIN_TDI_OUT(1U); \ +-} +- +- +-// JTAG Transfer I/O +-// request: A[3:2] RnW APnDP +-// data: DATA[31:0] +-// return: ACK[2:0] +-#define JTAG_TransferFunction(speed) /**/ \ +-static uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) { \ +- uint32_t ack; \ +- uint32_t bit; \ +- uint32_t val; \ +- uint32_t n; \ +- \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \ +- PIN_TMS_CLR(); \ +- JTAG_CYCLE_TCK(); /* Capture-DR */ \ +- JTAG_CYCLE_TCK(); /* Shift-DR */ \ +- \ +- for (n = DAP_Data.jtag_dev.index; n; n--) { \ +- JTAG_CYCLE_TCK(); /* Bypass before data */ \ +- } \ +- \ +- JTAG_CYCLE_TDIO(request >> 1, bit); /* Set RnW, Get ACK.0 */ \ +- ack = bit << 1; \ +- JTAG_CYCLE_TDIO(request >> 2, bit); /* Set A2, Get ACK.1 */ \ +- ack |= bit << 0; \ +- JTAG_CYCLE_TDIO(request >> 3, bit); /* Set A3, Get ACK.2 */ \ +- ack |= bit << 2; \ +- \ +- if (ack != DAP_TRANSFER_OK) { \ +- /* Exit on error */ \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Exit1-DR */ \ +- goto exit; \ +- } \ +- \ +- if (request & DAP_TRANSFER_RnW) { \ +- /* Read Transfer */ \ +- val = 0U; \ +- for (n = 31U; n; n--) { \ +- JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ \ +- val |= bit << 31; \ +- val >>= 1; \ +- } \ +- n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \ +- if (n) { \ +- JTAG_CYCLE_TDO(bit); /* Get D31 */ \ +- for (--n; n; n--) { \ +- JTAG_CYCLE_TCK(); /* Bypass after data */ \ +- } \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \ +- } else { \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ \ +- } \ +- val |= bit << 31; \ +- if (data) { *data = val; } \ +- } else { \ +- /* Write Transfer */ \ +- val = *data; \ +- for (n = 31U; n; n--) { \ +- JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \ +- val >>= 1; \ +- } \ +- n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \ +- if (n) { \ +- JTAG_CYCLE_TDI(val); /* Set D31 */ \ +- for (--n; n; n--) { \ +- JTAG_CYCLE_TCK(); /* Bypass after data */ \ +- } \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \ +- } else { \ +- PIN_TMS_SET(); \ +- JTAG_CYCLE_TDI(val); /* Set D31 & Exit1-DR */ \ +- } \ +- } \ +- \ +-exit: \ +- JTAG_CYCLE_TCK(); /* Update-DR */ \ +- PIN_TMS_CLR(); \ +- JTAG_CYCLE_TCK(); /* Idle */ \ +- PIN_TDI_OUT(1U); \ +- \ +- /* Capture Timestamp */ \ +- if (request & DAP_TRANSFER_TIMESTAMP) { \ +- DAP_Data.timestamp = TIMESTAMP_GET(); \ +- } \ +- \ +- /* Idle cycles */ \ +- n = DAP_Data.transfer.idle_cycles; \ +- while (n--) { \ +- JTAG_CYCLE_TCK(); /* Idle */ \ +- } \ +- \ +- return ((uint8_t)ack); \ +-} +- +- +-#undef PIN_DELAY +-#define PIN_DELAY() PIN_DELAY_FAST() +-JTAG_IR_Function(Fast) +-JTAG_TransferFunction(Fast) +- +-#undef PIN_DELAY +-#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) +-JTAG_IR_Function(Slow) +-JTAG_TransferFunction(Slow) +- +- +-// JTAG Read IDCODE register +-// return: value read +-uint32_t JTAG_ReadIDCode (void) { +- uint32_t bit; +- uint32_t val; +- uint32_t n; +- +- PIN_TMS_SET(); +- JTAG_CYCLE_TCK(); /* Select-DR-Scan */ +- PIN_TMS_CLR(); +- JTAG_CYCLE_TCK(); /* Capture-DR */ +- JTAG_CYCLE_TCK(); /* Shift-DR */ +- +- for (n = DAP_Data.jtag_dev.index; n; n--) { +- JTAG_CYCLE_TCK(); /* Bypass before data */ +- } +- +- val = 0U; +- for (n = 31U; n; n--) { +- JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ +- val |= bit << 31; +- val >>= 1; +- } +- PIN_TMS_SET(); +- JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ +- val |= bit << 31; +- +- JTAG_CYCLE_TCK(); /* Update-DR */ +- PIN_TMS_CLR(); +- JTAG_CYCLE_TCK(); /* Idle */ +- +- return (val); +-} +- +- +-// JTAG Write ABORT register +-// data: value to write +-// return: none +-void JTAG_WriteAbort (uint32_t data) { +- uint32_t n; +- +- PIN_TMS_SET(); +- JTAG_CYCLE_TCK(); /* Select-DR-Scan */ +- PIN_TMS_CLR(); +- JTAG_CYCLE_TCK(); /* Capture-DR */ +- JTAG_CYCLE_TCK(); /* Shift-DR */ +- +- for (n = DAP_Data.jtag_dev.index; n; n--) { +- JTAG_CYCLE_TCK(); /* Bypass before data */ +- } +- +- PIN_TDI_OUT(0U); +- JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */ +- JTAG_CYCLE_TCK(); /* Set A2=0 */ +- JTAG_CYCLE_TCK(); /* Set A3=0 */ +- +- for (n = 31U; n; n--) { +- JTAG_CYCLE_TDI(data); /* Set D0..D30 */ +- data >>= 1; +- } +- n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; +- if (n) { +- JTAG_CYCLE_TDI(data); /* Set D31 */ +- for (--n; n; n--) { +- JTAG_CYCLE_TCK(); /* Bypass after data */ ++ for (n = g_DAP_Data.jtag_dev.index; n; n--) { ++ JTAG_CYCLE_TCK(); /* Bypass before data */ ++ } ++ ++ val = 0U; ++ for (n = 31U; n; n--) { ++ JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ ++ val |= bit << 31; ++ val >>= 1; + } + PIN_TMS_SET(); +- JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ +- } else { +- PIN_TMS_SET(); +- JTAG_CYCLE_TDI(data); /* Set D31 & Exit1-DR */ +- } ++ JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ ++ val |= bit << 31; + +- JTAG_CYCLE_TCK(); /* Update-DR */ +- PIN_TMS_CLR(); +- JTAG_CYCLE_TCK(); /* Idle */ +- PIN_TDI_OUT(1U); ++ JTAG_CYCLE_TCK(); /* Update-DR */ ++ PIN_TMS_CLR(); ++ JTAG_CYCLE_TCK(); /* Idle */ ++ ++ return (val); + } + + +-// JTAG Set IR +-// ir: IR value +-// return: none +-void JTAG_IR (uint32_t ir) { +- if (DAP_Data.fast_clock) { +- JTAG_IR_Fast(ir); +- } else { +- JTAG_IR_Slow(ir); +- } +-} ++/* JTAG Write ABORT register ++ * data: value to write ++ * return: none ++ */ ++void JTAG_WriteAbort (uint32_t data) ++{ ++ uint32_t n; ++ ++ PIN_TMS_SET(); ++ JTAG_CYCLE_TCK(); /* Select-DR-Scan */ ++ PIN_TMS_CLR(); ++ JTAG_CYCLE_TCK(); /* Capture-DR */ ++ JTAG_CYCLE_TCK(); /* Shift-DR */ ++ ++ for (n = g_DAP_Data.jtag_dev.index; n; n--) { ++ JTAG_CYCLE_TCK(); /* Bypass before data */ ++ } ++ ++ PIN_TDI_OUT(0U); ++ JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */ ++ JTAG_CYCLE_TCK(); /* Set A2=0 */ ++ JTAG_CYCLE_TCK(); /* Set A3=0 */ ++ ++ for (n = 31U; n; n--) { ++ JTAG_CYCLE_TDI(data); /* Set D0..D30 */ ++ data >>= 1; ++ } ++ n = g_DAP_Data.jtag_dev.count - g_DAP_Data.jtag_dev.index - 1U; ++ if (n) { ++ JTAG_CYCLE_TDI(data); /* Set D31 */ ++ for (--n; n; n--) { ++ JTAG_CYCLE_TCK(); /* Bypass after data */ ++ } ++ PIN_TMS_SET(); ++ JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ ++ } else { ++ PIN_TMS_SET(); ++ JTAG_CYCLE_TDI(data); /* Set D31 & Exit1-DR */ ++ } + ++ JTAG_CYCLE_TCK(); /* Update-DR */ ++ PIN_TMS_CLR(); ++ JTAG_CYCLE_TCK(); /* Idle */ ++ PIN_TDI_OUT(1U); ++} + +-// JTAG Transfer I/O +-// request: A[3:2] RnW APnDP +-// data: DATA[31:0] +-// return: ACK[2:0] +-uint8_t JTAG_Transfer(uint32_t request, uint32_t *data) { +- if (DAP_Data.fast_clock) { +- return JTAG_TransferFast(request, data); +- } else { +- return JTAG_TransferSlow(request, data); +- } ++uint8_t JTAG_RESET (void) ++{ ++ PIN_TMS_SET(); ++ for (int i = 0; i < 5; i++) { ++ JTAG_CYCLE_TCK(); ++ } ++ PIN_TMS_CLR(); ++ JTAG_CYCLE_TCK(); ++ PIN_TDI_OUT(1U); ++ return 0; + } + + +-#endif /* (DAP_JTAG != 0) */ ++/* JTAG Set IR ++ * ir: IR value ++ * return: none ++ */ ++void JTAG_IR (uint32_t ir) ++{ ++ switch (g_DAP_Data.clock_level) { ++ case SWD_JTAG_CLOCK_LEVEL_0: ++ JTAG_IR_Level4(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_1: ++ JTAG_IR_Level4(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_2: ++ JTAG_IR_Level4(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_3: ++ JTAG_IR_Level4(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_4: ++ JTAG_IR_Level4(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_5: ++ JTAG_IR_Level5(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_6: ++ JTAG_IR_Level6(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_7: ++ JTAG_IR_Level7(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_8: ++ JTAG_IR_Level8(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_9: ++ JTAG_IR_Level9(ir); ++ break; ++ case SWD_JTAG_CLOCK_LEVEL_LOW: ++ JTAG_IR_LevelLow(ir); ++ break; ++ default: ++ JTAG_IR_Level5(ir); ++ break; ++ } ++} ++ ++/* JTAG Transfer I/O ++ * request: A[3:2] RnW APnDP ++ * data: DATA[31:0] ++ * return: ACK[2:0] ++ */ ++uint8_t JTAG_Transfer(uint32_t request, uint32_t *data) ++{ ++ switch (g_DAP_Data.clock_level) { ++ case SWD_JTAG_CLOCK_LEVEL_0: ++ return JTAG_TransferLevel4(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_1: ++ return JTAG_TransferLevel4(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_2: ++ return JTAG_TransferLevel4(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_3: ++ return JTAG_TransferLevel4(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_4: ++ return JTAG_TransferLevel4(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_5: ++ return JTAG_TransferLevel5(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_6: ++ return JTAG_TransferLevel6(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_7: ++ return JTAG_TransferLevel7(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_8: ++ return JTAG_TransferLevel8(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_9: ++ return JTAG_TransferLevel9(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_LOW: ++ return JTAG_TransferLevelLow(request, data); ++ default: ++ return JTAG_TransferLevel5(request, data); ++ } ++} ++#endif /* (DAP_JTAG != 0) */ +\ No newline at end of file +diff -uNr old/CM4/Core/Src/SW_DP.c new/CM4/Core/Src/SW_DP.c +--- old/CM4/Core/Src/SW_DP.c 2023-05-29 09:46:06.000000000 +0800 ++++ new/CM4/Core/Src/SW_DP.c 2023-06-09 15:20:04.769021500 +0800 +@@ -27,6 +27,8 @@ + + #include "DAP_config.h" + #include "DAP.h" ++#include "debug.h" ++#include "swd_jtag_config.h" + + #if defined(__CC_ARM) + #pragma push +@@ -38,264 +40,412 @@ + #endif + + // SW Macros +- + #define PIN_SWCLK_SET PIN_SWCLK_TCK_SET + #define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR + +-#define SW_CLOCK_CYCLE() \ +- PIN_SWCLK_CLR(); \ +- PIN_DELAY(); \ +- PIN_SWCLK_SET(); \ +- PIN_DELAY() +- +-#define SW_WRITE_BIT(bit) \ +- PIN_SWDIO_OUT(bit); \ +- PIN_SWCLK_CLR(); \ +- PIN_DELAY(); \ +- PIN_SWCLK_SET(); \ +- PIN_DELAY() +- +-#define SW_READ_BIT(bit) \ +- PIN_SWCLK_CLR(); \ +- PIN_DELAY(); \ +- bit = PIN_SWDIO_IN(); \ +- PIN_SWCLK_SET(); \ +- PIN_DELAY() ++inline static void SWDP_DELAY_LEVEL_0(void) ++{ ++} ++ ++inline static void SWDP_DELAY_LEVEL_1(void) ++{ ++ __NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_2(void) ++{ ++ __NOP();__NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_3(void) ++{ ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_4(void) ++{ ++ __NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_5(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_6(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_7(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_8(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_9(void) ++{ ++ __NOP();__NOP(); __NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++ __NOP();__NOP();__NOP(); ++} ++ ++inline static void SWDP_DELAY_LEVEL_LOW(uint32_t delay) ++{ ++ volatile uint32_t cnt = delay; ++ while(cnt) { ++ cnt--; ++ } ++} + +-#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) ++#define SW_CLOCK_CYCLE() \ ++ PIN_SWCLK_CLR(); \ ++ __NOP();__NOP();__NOP(); \ ++ PIN_DELAY(); \ ++ PIN_SWCLK_SET(); \ ++ __NOP();__NOP();__NOP(); \ ++ PIN_DELAY() ++ ++#define SW_WRITE_BIT(bit) \ ++ PIN_SWDIO_OUT(bit); \ ++ PIN_SWCLK_CLR(); \ ++ __NOP();__NOP(); \ ++ PIN_DELAY(); \ ++ PIN_SWCLK_SET(); \ ++ __NOP(); __NOP(); \ ++ PIN_DELAY() ++ ++#define SW_READ_BIT(bit) \ ++ PIN_SWCLK_CLR(); \ ++ __NOP();__NOP();__NOP(); \ ++ PIN_DELAY(); \ ++ bit = PIN_SWDIO_IN(); \ ++ PIN_SWCLK_SET(); \ ++ __NOP();__NOP();__NOP(); \ ++ PIN_DELAY() + ++#define PIN_DELAY() SWDP_DELAY_LEVEL_9() + + // Generate SWJ Sequence + // count: sequence bit count + // data: pointer to sequence bit data + // return: none + #if ((DAP_SWD != 0) || (DAP_JTAG != 0)) +-__WEAK void SWJ_Sequence (uint32_t count, const uint8_t *data) { +- uint32_t val; +- uint32_t n; +- +- val = 0U; +- n = 0U; +- while (count--) { +- if (n == 0U) { +- val = *data++; +- n = 8U; +- } +- if (val & 1U) { +- PIN_SWDIO_TMS_SET(); +- } else { +- PIN_SWDIO_TMS_CLR(); ++__WEAK void SWJ_Sequence (uint32_t count, const uint8_t *data) ++{ ++ uint32_t val; ++ uint32_t n; ++ ++ val = 0U; ++ n = 0U; ++ while (count--) { ++ if (n == 0U) { ++ val = *data++; ++ n = 8U; ++ } ++ if (val & 1U) { ++ PIN_SWDIO_TMS_SET(); ++ } else { ++ PIN_SWDIO_TMS_CLR(); ++ } ++ SW_CLOCK_CYCLE(); ++ val >>= 1; ++ n--; + } +- SW_CLOCK_CYCLE(); +- val >>= 1; +- n--; +- } + } + #endif + +- + // Generate SWD Sequence + // info: sequence information + // swdo: pointer to SWDIO generated data + // swdi: pointer to SWDIO captured data + // return: none + #if (DAP_SWD != 0) +-__WEAK void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) { +- uint32_t val; +- uint32_t bit; +- uint32_t n, k; +- +- n = info & SWD_SEQUENCE_CLK; +- if (n == 0U) { +- n = 64U; +- } +- +- if (info & SWD_SEQUENCE_DIN) { +- while (n) { +- val = 0U; +- for (k = 8U; k && n; k--, n--) { +- SW_READ_BIT(bit); +- val >>= 1; +- val |= bit << 7; +- } +- val >>= k; +- *swdi++ = (uint8_t)val; ++__WEAK void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) ++{ ++ uint32_t val; ++ uint32_t bit; ++ uint32_t n, k; ++ ++ n = info & SWD_SEQUENCE_CLK; ++ if (n == 0U) { ++ n = 64U; + } +- } else { +- while (n) { +- val = *swdo++; +- for (k = 8U; k && n; k--, n--) { +- SW_WRITE_BIT(val); +- val >>= 1; +- } ++ ++ if (info & SWD_SEQUENCE_DIN) { ++ while (n) { ++ val = 0U; ++ for (k = 8U; k && n; k--, n--) { ++ SW_READ_BIT(bit); ++ val >>= 1; ++ val |= bit << 7; ++ } ++ val >>= k; ++ *swdi++ = (uint8_t)val; ++ } ++ } else { ++ while (n) { ++ val = *swdo++; ++ for (k = 8U; k && n; k--, n--) { ++ SW_WRITE_BIT(val); ++ val >>= 1; ++ } ++ } + } +- } + } + #endif + +- + #if (DAP_SWD != 0) + +- + // SWD Transfer I/O + // request: A[3:2] RnW APnDP + // data: DATA[31:0] + // return: ACK[2:0] +-#define SWD_TransferFunction(speed) /**/ \ +-static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \ +- uint32_t ack; \ +- uint32_t bit; \ +- uint32_t val; \ +- uint32_t parity; \ +- \ +- uint32_t n; \ +- \ +- /* Packet Request */ \ +- parity = 0U; \ +- SW_WRITE_BIT(1U); /* Start Bit */ \ +- bit = request >> 0; \ +- SW_WRITE_BIT(bit); /* APnDP Bit */ \ +- parity += bit; \ +- bit = request >> 1; \ +- SW_WRITE_BIT(bit); /* RnW Bit */ \ +- parity += bit; \ +- bit = request >> 2; \ +- SW_WRITE_BIT(bit); /* A2 Bit */ \ +- parity += bit; \ +- bit = request >> 3; \ +- SW_WRITE_BIT(bit); /* A3 Bit */ \ +- parity += bit; \ +- SW_WRITE_BIT(parity); /* Parity Bit */ \ +- SW_WRITE_BIT(0U); /* Stop Bit */ \ +- SW_WRITE_BIT(1U); /* Park Bit */ \ +- \ +- /* Turnaround */ \ +- PIN_SWDIO_OUT_DISABLE(); \ +- for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ +- SW_CLOCK_CYCLE(); \ +- } \ +- \ +- /* Acknowledge response */ \ +- SW_READ_BIT(bit); \ +- ack = bit << 0; \ +- SW_READ_BIT(bit); \ +- ack |= bit << 1; \ +- SW_READ_BIT(bit); \ +- ack |= bit << 2; \ +- \ +- if (ack == DAP_TRANSFER_OK) { /* OK response */ \ +- /* Data transfer */ \ +- if (request & DAP_TRANSFER_RnW) { \ +- /* Read data */ \ +- val = 0U; \ +- parity = 0U; \ +- for (n = 32U; n; n--) { \ +- SW_READ_BIT(bit); /* Read RDATA[0:31] */ \ +- parity += bit; \ +- val >>= 1; \ +- val |= bit << 31; \ +- } \ +- SW_READ_BIT(bit); /* Read Parity */ \ +- if ((parity ^ bit) & 1U) { \ +- ack = DAP_TRANSFER_ERROR; \ +- } \ +- if (data) { *data = val; } \ +- /* Turnaround */ \ +- for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ +- SW_CLOCK_CYCLE(); \ +- } \ +- PIN_SWDIO_OUT_ENABLE(); \ +- } else { \ +- /* Turnaround */ \ +- for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ +- SW_CLOCK_CYCLE(); \ +- } \ +- PIN_SWDIO_OUT_ENABLE(); \ +- /* Write data */ \ +- val = *data; \ +- parity = 0U; \ +- for (n = 32U; n; n--) { \ +- SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \ +- parity += val; \ +- val >>= 1; \ +- } \ +- SW_WRITE_BIT(parity); /* Write Parity Bit */ \ +- } \ +- /* Capture Timestamp */ \ +- if (request & DAP_TRANSFER_TIMESTAMP) { \ +- DAP_Data.timestamp = TIMESTAMP_GET(); \ +- } \ +- /* Idle cycles */ \ +- n = DAP_Data.transfer.idle_cycles; \ +- if (n) { \ +- PIN_SWDIO_OUT(0U); \ +- for (; n; n--) { \ +- SW_CLOCK_CYCLE(); \ +- } \ +- } \ +- PIN_SWDIO_OUT(1U); \ +- return ((uint8_t)ack); \ +- } \ +- \ +- if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \ +- /* WAIT or FAULT response */ \ +- if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \ +- for (n = 32U+1U; n; n--) { \ +- SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \ +- } \ +- } \ +- /* Turnaround */ \ +- for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ +- SW_CLOCK_CYCLE(); \ +- } \ +- PIN_SWDIO_OUT_ENABLE(); \ +- if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \ +- PIN_SWDIO_OUT(0U); \ +- for (n = 32U+1U; n; n--) { \ +- SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \ +- } \ +- } \ +- PIN_SWDIO_OUT(1U); \ +- return ((uint8_t)ack); \ +- } \ +- \ +- /* Protocol error */ \ +- for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \ +- SW_CLOCK_CYCLE(); /* Back off data phase */ \ +- } \ +- PIN_SWDIO_OUT_ENABLE(); \ +- PIN_SWDIO_OUT(1U); \ +- return ((uint8_t)ack); \ ++#define SWD_TransferFunction(speed) \ ++static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) \ ++{ \ ++ uint32_t ack; \ ++ uint32_t bit; \ ++ uint32_t val; \ ++ uint32_t parity; \ ++ \ ++ uint32_t n; \ ++ PIN_SWDIO_OUT_ENABLE(); \ ++ \ ++ /* Packet Request */ \ ++ parity = 0U; \ ++ SW_WRITE_BIT(1U); /* Start Bit */ \ ++ bit = request >> 0; \ ++ SW_WRITE_BIT(bit); /* APnDP Bit */ \ ++ parity += bit; \ ++ bit = request >> 1; \ ++ SW_WRITE_BIT(bit); /* RnW Bit */ \ ++ parity += bit; \ ++ bit = request >> 2; \ ++ SW_WRITE_BIT(bit); /* A2 Bit */ \ ++ parity += bit; \ ++ bit = request >> 3; \ ++ SW_WRITE_BIT(bit); /* A3 Bit */ \ ++ parity += bit; \ ++ SW_WRITE_BIT(parity); /* Parity Bit */ \ ++ __NOP();__NOP(); \ ++ SW_WRITE_BIT(0U); /* Stop Bit */ \ ++ __NOP();__NOP(); \ ++ SW_WRITE_BIT(1U); /* Park Bit */ \ ++ __NOP();__NOP(); \ ++ \ ++ PIN_SWDIO_OUT_DISABLE(); \ ++ /* Turnaround */ \ ++ for (n = g_DAP_Data.swd_conf.turnaround; n; n--) { \ ++ SW_CLOCK_CYCLE(); \ ++ } \ ++ \ ++ /* Acknowledge response */ \ ++ SW_READ_BIT(bit); \ ++ __NOP(); \ ++ ack = bit << 0; \ ++ SW_READ_BIT(bit); \ ++ ack |= bit << 1; \ ++ SW_READ_BIT(bit); \ ++ ack |= bit << 2; \ ++ if (ack == DAP_TRANSFER_OK) { /* OK response */ \ ++ /* Data transfer */ \ ++ if (request & DAP_TRANSFER_RnW) { \ ++ /* Read data */ \ ++ val = 0U; \ ++ parity = 0U; \ ++ for (n = 32U; n; n--) { \ ++ SW_READ_BIT(bit); /* Read RDATA[0:31] */ \ ++ parity += bit; \ ++ val >>= 1; \ ++ val |= bit << 31; \ ++ } \ ++ SW_READ_BIT(bit); /* Read Parity */ \ ++ __NOP();__NOP();__NOP(); \ ++ if ((parity ^ bit) & 1U) { \ ++ ack = DAP_TRANSFER_ERROR; \ ++ } \ ++ if (data) { \ ++ *data = val; \ ++ } \ ++ /* Turnaround */ \ ++ for (n = g_DAP_Data.swd_conf.turnaround; n; n--) { \ ++ SW_CLOCK_CYCLE(); \ ++ __NOP();__NOP(); \ ++ } \ ++ PIN_SWDIO_OUT_ENABLE(); \ ++ } else { \ ++ /* Turnaround */ \ ++ for (n = g_DAP_Data.swd_conf.turnaround; n; n--) { \ ++ SW_CLOCK_CYCLE(); \ ++ __NOP();__NOP(); \ ++ } \ ++ PIN_SWDIO_OUT_ENABLE(); \ ++ /* Write data */ \ ++ val = *data; \ ++ parity = 0U; \ ++ for (n = 32U; n; n--) { \ ++ SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \ ++ parity += val; \ ++ val >>= 1; \ ++ } \ ++ SW_WRITE_BIT(parity); /* Write Parity Bit */ \ ++ } \ ++ /* Capture Timestamp */ \ ++ if (request & DAP_TRANSFER_TIMESTAMP) { \ ++ g_DAP_Data.timestamp = TIMESTAMP_GET(); \ ++ } \ ++ /* Idle cycles */ \ ++ n = g_DAP_Data.transfer.idle_cycles; \ ++ if (n) { \ ++ PIN_SWDIO_OUT(0U); \ ++ for (; n; n--) { \ ++ SW_CLOCK_CYCLE(); \ ++ } \ ++ } \ ++ PIN_SWDIO_OUT(1U); \ ++ return ((uint8_t)ack); \ ++ } \ ++ \ ++ if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \ ++ /* WAIT or FAULT response */ \ ++ if (g_DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \ ++ for (n = 32U+1U; n; n--) { \ ++ SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \ ++ } \ ++ } \ ++ /* Turnaround */ \ ++ for (n = g_DAP_Data.swd_conf.turnaround; n; n--) { \ ++ SW_CLOCK_CYCLE(); \ ++ } \ ++ PIN_SWDIO_OUT_ENABLE(); \ ++ if (g_DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \ ++ PIN_SWDIO_OUT(0U); \ ++ for (n = 32U+1U; n; n--) { \ ++ SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \ ++ } \ ++ } \ ++ PIN_SWDIO_OUT(1U); \ ++ return ((uint8_t)ack); \ ++ } \ ++ /* Protocol error */ \ ++ for (n = g_DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \ ++ SW_CLOCK_CYCLE(); /* Back off data phase */ \ ++ } \ ++ PIN_SWDIO_OUT_ENABLE(); \ ++ PIN_SWDIO_OUT(1U); \ ++ return ((uint8_t)ack); \ + } + ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_0() ++SWD_TransferFunction(Level0) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_1() ++SWD_TransferFunction(Level1) + + #undef PIN_DELAY +-#define PIN_DELAY() PIN_DELAY_FAST() +-SWD_TransferFunction(Fast) ++#define PIN_DELAY() SWDP_DELAY_LEVEL_2() ++SWD_TransferFunction(Level2) + + #undef PIN_DELAY +-#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) +-SWD_TransferFunction(Slow) ++#define PIN_DELAY() SWDP_DELAY_LEVEL_3() ++SWD_TransferFunction(Level3) + ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_4() ++SWD_TransferFunction(Level4) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_5() ++SWD_TransferFunction(Level5) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_6() ++SWD_TransferFunction(Level6) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_7() ++SWD_TransferFunction(Level7) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_8() ++SWD_TransferFunction(Level8) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_9() ++SWD_TransferFunction(Level9) ++ ++#undef PIN_DELAY ++#define PIN_DELAY() SWDP_DELAY_LEVEL_LOW(g_DAP_Data.clock_delay) ++SWD_TransferFunction(LevelLow) + + // SWD Transfer I/O + // request: A[3:2] RnW APnDP + // data: DATA[31:0] + // return: ACK[2:0] + __WEAK uint8_t SWD_Transfer(uint32_t request, uint32_t *data) { +- if (DAP_Data.fast_clock) { +- return SWD_TransferFast(request, data); +- } else { +- return SWD_TransferSlow(request, data); +- } ++ switch (g_DAP_Data.clock_level) { ++ case SWD_JTAG_CLOCK_LEVEL_0: ++ return SWD_TransferLevel0(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_1: ++ return SWD_TransferLevel1(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_2: ++ return SWD_TransferLevel2(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_3: ++ return SWD_TransferLevel3(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_4: ++ return SWD_TransferLevel4(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_5: ++ return SWD_TransferLevel5(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_6: ++ return SWD_TransferLevel6(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_7: ++ return SWD_TransferLevel7(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_8: ++ return SWD_TransferLevel8(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_9: ++ return SWD_TransferLevel9(request, data); ++ case SWD_JTAG_CLOCK_LEVEL_LOW: ++ return SWD_TransferLevelLow(request, data); ++ default: ++ return SWD_TransferLevel6(request, data); ++ } + } + +- + #endif /* (DAP_SWD != 0) */ + +- + #if defined(__CC_ARM) + #pragma pop + #elif defined(__GNUC__) && !defined(__ARMCC_VERSION) + #pragma GCC pop_options +-#endif ++#endif +\ No newline at end of file diff --git a/src/tools/hispark_trace/open_source/README.md b/src/tools/hispark_trace/open_source/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fc5026f1cb09e54ab2b143a30b037ff747cd0757 --- /dev/null +++ b/src/tools/hispark_trace/open_source/README.md @@ -0,0 +1,3 @@ +# open source + +This folder is used to store third-party open-source code. \ No newline at end of file diff --git a/src/tools/hispark_trace/tools/daplink_create_HiSpark_Trace_Firmware.py b/src/tools/hispark_trace/tools/daplink_create_HiSpark_Trace_Firmware.py new file mode 100644 index 0000000000000000000000000000000000000000..ab808ccd84230da3c9785d7adbdcc59fe569f428 --- /dev/null +++ b/src/tools/hispark_trace/tools/daplink_create_HiSpark_Trace_Firmware.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# coding=utf-8 + +''' +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. +# daplink_create_HiSpark_Trace_Firmware.py Function implementation: Used to generate the version upgrade package. +''' +import struct +import sys +import os +import stat +import pathlib + +MAGIC_NUMBER = 0xAA55A55A +HIC_ID = 0 +FILE_TYPE = 0x9B939E8F +VER = 1 +FACTORY_ID = 0 +CHIP_ID = 0 +FLASH_TYPE = 0 +FLASH_CRC = 0xFFFFFFFF + + +def packet_fill(dst, fill_len, val): + while fill_len >= 32: + dst.write(struct.pack('IIIIIIII', val, val, val, val, val, val, val, val)) + fill_len = fill_len - 32 + while fill_len >= 4: + dst.write(struct.pack('I', val)) + fill_len = fill_len - 4 + while fill_len > 0: + dst.write(struct.pack('B', val & 0xFF)) + fill_len = fill_len - 1 + + +def add_loader_header(file_len): + header = [] + header.append(MAGIC_NUMBER) + header.append(HIC_ID) + header.append(FILE_TYPE) + header.append(VER) + header.append(FACTORY_ID) + header.append(CHIP_ID) + header.append(FLASH_TYPE) + header.append(file_len) + header.append(FLASH_CRC) + for _ in range(3): + header.append(0) + return header + + +def packet_bin(output_path, input_list): + path_list = [] + burn_size_list = [] + image_size_list = [] + for item in input_list: + path, burn_size = item.split("|") + image_size = os.path.getsize(path) + path_list.append(path) + burn_size_list.append(int(burn_size)) + image_size_list.append(image_size) + + header = add_loader_header(image_size) + + flags = os.O_RDWR | os.O_CREAT + modes = stat.S_IWUSR | stat.S_IRUSR + with os.fdopen(os.open(output_path, flags, modes), 'wb+') as file: + for i in header: + file.write(struct.pack('I', i)) + with open(path, 'rb+') as src: + data = src.read() + file.write(data) + packet_fill(file, int(burn_size) - image_size, 0xFFFFFFFF) + file.flush() + + +def main(argv): + ''' + Function description: Combine loader.bin with image.bin into allinone.bin. + ''' + curpath = pathlib.Path().cwd() + sourcepatch = curpath.joinpath("./images/allinone_upgrade_1M_CRC32.bin") + output_path = curpath.joinpath("./images/HiSpark-Trace_Firmware_forDAPLINK.bin") + + input_list = ["{}|{}".format(sourcepatch, 32 * 1024)] + packet_bin(output_path, input_list) + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) \ No newline at end of file diff --git a/src/tools/hispark_trace/tools/daplink_create_HiSpark_Trace_allinone.py b/src/tools/hispark_trace/tools/daplink_create_HiSpark_Trace_allinone.py new file mode 100644 index 0000000000000000000000000000000000000000..fb6828c4acc1cad712d775bb7d87e5c3ac08c8c3 --- /dev/null +++ b/src/tools/hispark_trace/tools/daplink_create_HiSpark_Trace_allinone.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +# coding=utf-8 + +''' +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. +# daplink_create_HiSpark_Trace_allinone.py Function implementation: Used to generate factory-level chip files. +''' +import struct +import sys +import os +import stat +import pathlib + + +class Crc16: + POLYNOMIAL = 0x1021 + PRESET = 0x0000 + _tab = [] + + + def __init__(self): + self._tab = [self._initial(i) for i in range(256)] + + + def crcb(self, i): + crc = self.PRESET + for c in i: + crc = self._update_crc(crc, c) + return crc + + + def crc(self, string): + crc = self.PRESET + for c in string: + crc = self._update_crc(crc, ord(c)) + return crc + + + def _initial(self, c): + crc = 0 + c = c << 8 + for _ in range(8): + if (crc ^ c) & 0x8000: + crc = (crc << 1) ^ self.POLYNOMIAL + else: + crc = crc << 1 + c = c << 1 + return crc + + + def _update_crc(self, crc, c): + cc = 0xff & int(c) + + tmp = (crc >> 8) ^ cc + crc = (crc << 8) ^ self._tab[tmp & 0xff] + crc = crc & 0xffff + + return crc + + + +def packet_fill(dst, fill_len, val): + while fill_len >= 32: + dst.write(struct.pack('IIIIIIII', val, val, val, val, val, val, val, val)) + fill_len = fill_len - 32 + while fill_len >= 4: + dst.write(struct.pack('I', val)) + fill_len = fill_len - 4 + while fill_len > 0: + dst.write(struct.pack('B', val & 0xFF)) + fill_len = fill_len - 1 + + +def packet_bin_write_without_crc(dst, src, pad_len, pad_val): + data = src.read() + dst.write(data) + packet_fill(dst, pad_len, pad_val) + + +def packet_bin_write_with_crc(dst, src, image_len, pad_len, pad_val): + #写bin + data = src.read() + dst.write(data) + + #写bin对应CRC16 + t = Crc16() + crc16 = t.crcb(data) + dst.write(struct.pack('BB', crc16 >> 8, crc16 & 0xFF)) + + #剩余部分填充val,val可以为0xFF或者0x0 + packet_fill(dst, pad_len, pad_val) + + #写报文长度, 包含2个字节CRC + image_len += 2 + dst.write(struct.pack('I', image_len)) + + +def packet_bin(output_path, input_list, max_time): + path_list = [] + burn_size_list = [] + image_size_list = [] + for item in input_list: + path, burn_size = item.split("|") + image_size = os.path.getsize(path) + path_list.append(path) + burn_size_list.append(int(burn_size)) + image_size_list.append(image_size) + + flags = os.O_RDWR | os.O_CREAT + modes = stat.S_IWUSR | stat.S_IRUSR + with os.fdopen(os.open(output_path, flags, modes), 'wb+') as file: + times = 0 + start = burn_size_list[0] + burn_size_list[1] + 8 # boot size + 8字节文件长度 + for path in path_list: + with open(path, 'rb+') as subfile: + pad_len = burn_size_list[times] - image_size_list[times] + pad_val = 0 if times != 1 else 0xFFFFFFFF + packet_bin_write_without_crc(file, subfile, pad_len, pad_val) + times += 1 + if times >= max_time: + break + file.flush() + + +def main(argv): + ''' + Function description: Combine loader.bin with image.bin into allinone.bin. + ''' + curpath = pathlib.Path().cwd() + bootpath = curpath.joinpath("./images/daplink_boot.stm32") + parapath = curpath.joinpath("./images/param.bin") + if os.path.exists(parapath) is False: + pathlib.Path(parapath).touch() + daplink_block_a = curpath.joinpath("./images/allinone_upgrade_1M_CRC32.bin") + daplink_block_b = curpath.joinpath("./images/allinone_upgrade_1M_CRC32.bin") + output_path = curpath.joinpath("./images/HiSpark-Trace_allinone.bin") + + input_list = [ + "{}|{}".format(bootpath, 32 * 1024), # Boot partition is 32 * 1024 bytes + "{}|{}".format(parapath, 16 * 1024), # Parameter partition is 16 * 1024 bytes + "{}|{}".format(daplink_block_a, 1024 * 1024), # A partition is 1024 * 1024 bytes + "{}|{}".format(daplink_block_b, 1024 * 1024) # B partition is 1024 * 1024 bytes + ] + packet_bin(output_path, input_list, 4) + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) \ No newline at end of file diff --git a/src/tools/hispark_trace/tools/daplink_create_allinone_interface_1M_CRC32.py b/src/tools/hispark_trace/tools/daplink_create_allinone_interface_1M_CRC32.py new file mode 100644 index 0000000000000000000000000000000000000000..b1eedd339863fd6881531159b8d8818f0d77c715 --- /dev/null +++ b/src/tools/hispark_trace/tools/daplink_create_allinone_interface_1M_CRC32.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# coding=utf-8 + +''' +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. +# daplink_create_allinone_interface_1M_CRC32.py: Used to merge A-core and M-core binary files. +''' +import struct +import sys +import os +import stat +import pathlib +import zlib + + +def packet_fill(dst, fill_len, val): + while fill_len >= 32: + dst.write(struct.pack('IIIIIIII', val, val, val, val, val, val, val, val)) + fill_len = fill_len - 32 + while fill_len >= 4: + dst.write(struct.pack('I', val)) + fill_len = fill_len - 4 + while fill_len > 0: + dst.write(struct.pack('B', val & 0xFF)) + fill_len = fill_len - 1 + + +def packet_bin_write_without_crc(dst, src, pad_len, pad_val): + data = src.read() + dst.write(data) + packet_fill(dst, pad_len, pad_val) + + +def packet_bin_write_with_crc(dst, src, image_len, pad_len, pad_val): + #构造magic + magic_str = "HiSparkFW" + magic_len = len(magic_str) + magic_bytes = bytes(magic_str.encode('utf-8')) + image_len += magic_len + pad_len -= magic_len + + #写bin+magicbytes + data = src.read() + data += magic_bytes + dst.write(data) + + #写bin对应CRC32 + crc = zlib.crc32(data) & 0xFFFFFFFF + dst.write(struct.pack('I', crc)) + + #剩余部分填充val,val可以为0xFF或者0x0 + packet_fill(dst, pad_len, pad_val) + + #写报文长度, 包含4个字节CRC + image_len += 4 + dst.write(struct.pack('I', image_len)) + + +def packet_bin(output_path, input_list, max_time): + path_list = [] + burn_size_list = [] + image_size_list = [] + for item in input_list: + path, burn_size = item.split("|") + image_size = os.path.getsize(path) + path_list.append(path) + burn_size_list.append(int(burn_size)) + image_size_list.append(image_size) + + flags = os.O_RDWR | os.O_CREAT + modes = stat.S_IWUSR | stat.S_IRUSR + with os.fdopen(os.open(output_path, flags, modes), 'wb+') as file: + times = 0 + start = burn_size_list[0] + burn_size_list[1] + 8 # boot size + 8字节文件长度 + for path in path_list: + with open(path, 'rb+') as subfile: + pad_len = burn_size_list[times] - image_size_list[times] + pad_val = 0 + pad_len -= 8 + packet_bin_write_with_crc(file, subfile, image_size_list[times], pad_len, pad_val) + + times += 1 + if times >= max_time: + break + file.flush() + + +def main(argv): + ''' + Function description: Combine loader.bin with image.bin into allinone.bin. + ''' + curpath = pathlib.Path().cwd() + daplink_blocka_ca7 = curpath.joinpath("./images/daplink_A7.bin") + daplink_blocka_cm4 = curpath.joinpath("./images/daplink_M4.bin") + output_path = curpath.joinpath("./images/allinone_upgrade_1M_CRC32.bin") + + # 需包含4字节bin长度+4字节CRC + input_list = [ + "{}|{}".format(daplink_blocka_ca7, 700 * 1024), + "{}|{}".format(daplink_blocka_cm4, 324 * 1024) + ] + packet_bin(output_path, input_list, 6) + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/src/tools/hispark_trace/tools/daplink_create_loader.py b/src/tools/hispark_trace/tools/daplink_create_loader.py new file mode 100644 index 0000000000000000000000000000000000000000..4b760ec3bfdbd786d0054349441ba6a26719e68b --- /dev/null +++ b/src/tools/hispark_trace/tools/daplink_create_loader.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python +# coding=utf-8 + +''' +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2012-2023. All rights reserved. +# daplink_create_loader.py Function implementation: Packs boot binary files. +''' +import struct +import sys +import os +import stat +import pathlib + + +_MAGIC_NUMBER = 0xAA55A55A +_HIC_ID = 0 +_FILE_TYPE = 0x9B939D93 +_VER = 0 +_FACTORY_ID = 0 +_CHIP_ID = 0 +_FLASH_TYPE = 0 + + +def packet_fill(dst, length, val): + while length >= 32: + dst.write(struct.pack('IIIIIIII', + val, val, val, val, val, val, val, val)) + length = length - 32 + while length >= 4: + dst.write(struct.pack('I', val)) + length = length - 4 + while length > 0: + dst.write(struct.pack('B', val & 0xFF)) + length = length - 1 + + +def add_loader_header(file_len): + header = [] + header.append(_MAGIC_NUMBER) + header.append(_HIC_ID) + header.append(_FILE_TYPE) + header.append(_VER) + header.append(_FACTORY_ID) + header.append(_CHIP_ID) + header.append(_FLASH_TYPE) + header.append(file_len) + for _i in range(4): + header.append(0) + return header + + +def packet_bin(output_path, input_list): + path_list = [] + burn_size_list = [] + image_size_list = [] + for item in input_list: + path, burn_size = item.split("|") + image_size = os.path.getsize(path) + path_list.append(path) + burn_size_list.append(int(burn_size)) + image_size_list.append(image_size) + + header = add_loader_header(int(burn_size)) + flags = os.O_RDWR | os.O_CREAT + modes = stat.S_IWUSR | stat.S_IRUSR + with os.fdopen(os.open(output_path, flags, modes), 'wb+') as file: + for i in header: + file.write(struct.pack('I', i)) + with open(path, 'rb+') as src: + data = src.read() + file.write(data) + packet_fill(file, int(burn_size) - image_size, 0xFFFFFFFF) + file.flush() + + +def image_header_checksum(data, offset, length): + csum = 0 + for i in range(offset, length): + csum += data[i] + return csum + + +def write_info_to_data(data_in, data_out, offset): + for i in range(4): + data_out[offset + i] = data_in.to_bytes(length=4, byteorder='big')[3 - i] + + +def gen_stm32(input_path, output_path): + stm32_hdr_offset = { + "_MAGIC_NUMBER" : 0, + "image_signature" : 4, + "image_checksum" : 68, + "header__VERsion" : 72, + "image_length" : 76, + "image_entry_point" : 80, + "load_address" : 88, + "_VERsion_number" : 96, + "option_flags" : 100, + "ecdsa_algorithm" : 104, + "ecdsa_public_key" : 108, + "binary_type" : 252, + } + flag = 0xefbeaddf + modes = stat.S_IWUSR | stat.S_IRUSR + flags = os.O_RDWR | os.O_CREAT + data = [0] * 256 + with os.fdopen(os.open(input_path, flags, modes), 'rb+') as subfile: + data += subfile.read() + write_info_to_data(0x324D5453, data, stm32_hdr_offset.get('_MAGIC_NUMBER')) + write_info_to_data(0x00010000, data, stm32_hdr_offset.get('header__VERsion')) + image_len = os.path.getsize(input_path) + write_info_to_data(image_len, data, stm32_hdr_offset.get('image_length')) + write_info_to_data(0x2ffc2500, data, stm32_hdr_offset.get('image_entry_point')) + write_info_to_data(0x2ffc2500, data, stm32_hdr_offset.get('load_address')) + write_info_to_data(0x1, data, stm32_hdr_offset.get('option_flags')) + write_info_to_data(0x1, data, stm32_hdr_offset.get('ecdsa_algorithm')) + image_checksum = image_header_checksum(data, 256, image_len + 256) + write_info_to_data(image_checksum, data, stm32_hdr_offset.get('image_checksum')) + + with os.fdopen(os.open(output_path, flags, modes), 'wb+') as file: + file.write(bytes(data)) + + +def main(argv): + ''' + Function description: Combine loader.bin with image.bin into allinone.bin. + ''' + gen_stm32('images/daplink_boot.bin', 'images/daplink_boot.stm32') + curpath = pathlib.Path().cwd() + bootpath = curpath.joinpath("images/daplink_boot.stm32") + output_path = curpath.joinpath("images/HiSpark-Trace_Boot_CRC32_forDAPLINK.bin") + + input_list = ["{}|{}".format(bootpath, 32 * 1024)] + packet_bin(output_path, input_list) + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/src/tools/toolchain/Linux/cc_riscv32_musl.tar.gz b/src/tools/toolchain/Linux/cc_riscv32_musl.tar.gz deleted file mode 100644 index 4770731411eeea3ef81672884a62467e292cb49a..0000000000000000000000000000000000000000 Binary files a/src/tools/toolchain/Linux/cc_riscv32_musl.tar.gz and /dev/null differ diff --git a/src/tools/toolchain/Linux/cc_riscv32_musl_fp.tar.gz b/src/tools/toolchain/Linux/cc_riscv32_musl_fp.tar.gz deleted file mode 100644 index 1d402c79e184317ac3a53de7b349747d29dcb71e..0000000000000000000000000000000000000000 Binary files a/src/tools/toolchain/Linux/cc_riscv32_musl_fp.tar.gz and /dev/null differ diff --git a/src/tools/toolchain/Windows/cc_riscv32_musl_fp_win.tar.gz b/src/tools/toolchain/Windows/cc_riscv32_musl_fp_win.tar.gz deleted file mode 100644 index 020434b1eb8b587d13dfaad419c09584655b1d93..0000000000000000000000000000000000000000 Binary files a/src/tools/toolchain/Windows/cc_riscv32_musl_fp_win.tar.gz and /dev/null differ diff --git a/src/tools/toolchain/Windows/cc_riscv32_musl_win.tar.gz b/src/tools/toolchain/Windows/cc_riscv32_musl_win.tar.gz deleted file mode 100644 index eda75be466d4bd6f52666c92c5f220ef1f21c462..0000000000000000000000000000000000000000 Binary files a/src/tools/toolchain/Windows/cc_riscv32_musl_win.tar.gz and /dev/null differ diff --git a/src/tools/toolchain/Windows/cc_riscv32_win_env.tar.gz b/src/tools/toolchain/Windows/cc_riscv32_win_env.tar.gz deleted file mode 100644 index fe3607d4a677f5478166359d115569fa04bd9b75..0000000000000000000000000000000000000000 Binary files a/src/tools/toolchain/Windows/cc_riscv32_win_env.tar.gz and /dev/null differ diff --git a/src/tools/uttest/uttest.h b/src/tools/uttest/uttest.h new file mode 100644 index 0000000000000000000000000000000000000000..9c13c822a310076f05e022d968238813b9e28f00 --- /dev/null +++ b/src/tools/uttest/uttest.h @@ -0,0 +1,442 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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 HOLDER 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. + * @file uttest.h + * @author MCU Driver Team + * @brief Macros for UT test + * @details This file provides firmware functions to manage the following + * functionalities of the UT test. + * + Creat UT test suite + * + Define test modes + * + Output test summary. + */ + +/* Macro definitions */ +#ifndef McuMagicTag_UT_TEST_H +#define McuMagicTag_UT_TEST_H + +#include "debug.h" +#ifndef NULL +#define NULL (void *)0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define PRINTF DBG_PRINTF +/* *************************************************************************** */ +/* System parameter configuration */ +/* *************************************************************************** */ +#define UT_TEST_VERSION "v1.0" +#define UT_TEST_WRITE_STRING(msg) PRINTF("%s", msg) +#define UT_TEST_WRITE_INT(n) PRINTF("%d", n) + +#define UT_TEST_MODE_SUMARY 0 /* Show only the final result */ +#define UT_TEST_MODE_GENERAL 1 /* Only checks that fail are displays */ +#define UT_TEST_MODE_DETAILED 2 /* Passed and failed checks are displayed */ +#define UT_TEST_MODE UT_TEST_MODE_DETAILED /* log level */ + +/* Action to take if check fails */ +#define UT_TEST_ACTION_WARNING 0 /* Goes through the checks with message depending on level */ +#define UT_TEST_ACTION_SHUTDOWN 1 /* Stops on the end of the checklist if any check has failed */ +#define UT_TEST_ACTION_SAFESTATE 2 /* Goes in safe state if check fails */ + +/* *************************************************************************** */ +/* Variables */ +/* *************************************************************************** */ +static int g_utTestChecksFailed = 0; /* Number of failed checks */ +static int g_utTestChecksPassed = 0; /* Number of passed checks */ +static int g_utTestTestcasesFailed = 0; /* Number of failed test cases */ +static int g_utTestTestcasesPassed = 0; /* Number of passed test cases */ +static int g_utTestTestcasesFailedChecks = 0; /* Number of failed checks in a testcase */ +static int g_utTestChecklistFailedChecks = 0; /* Number of failed checks in a checklist */ + +/* *************************************************************************** */ +/* Internal (private) Macros */ +/* *************************************************************************** */ + +#define UT_TEST_DEFINE_TO_STRING_HELPER(x) #x +/* Converts a define constant into a string. */ +#define UT_TEST_DEFINE_TO_STRING(x) UT_TEST_DEFINE_TO_STRING_HELPER(x) + +#if (UT_TEST_MODE == UT_TEST_MODE_DETAILED) +/** + * @Macro: UT_TEST_WRITE_PASSED_MSG(msg, args) + * + * @Description: Writes a message that check has passed. + * + * @Param msg: Message to write. This is the name of the called + * Check, without the substring UT_TEST_CHECK. + * @Param args: Argument list as string. + * + * @Remarks: This macro is used by UT_TEST_CHECK(). A message will + * only be written if verbose mode is set to UT_TEST_MODE_DETAILED. + * + */ +#define UT_TEST_WRITE_PASSED_MSG(msg, args) do { \ + UT_TEST_WRITE_STRING(__FILE__); \ + UT_TEST_WRITE_STRING(":"); \ + UT_TEST_WRITE_STRING(UT_TEST_DEFINE_TO_STRING(__LINE__)); \ + UT_TEST_WRITE_STRING(": passed:"); \ + UT_TEST_WRITE_STRING(msg); \ + UT_TEST_WRITE_STRING("("); \ + UT_TEST_WRITE_STRING(args); \ + UT_TEST_WRITE_STRING(")\r\n"); \ + } while (0) +#else +#define UT_TEST_WRITE_PASSED_MSG(msg, args) +#endif + +#if (UT_TEST_MODE == UT_TEST_MODE_SUMARY) +#define UT_TEST_WRITE_FAILED_MSG(msg, args) +#else +/** + * @Macro: UT_TEST_WRITE_FAILED_MSG(msg, args) + * + * @Description: Writes a message that check has failed. + * + * @Param msg: Message to write. This is the name of the called + * Check, without the substring UT_TEST_CHECK. + * @Param args: Argument list as string. + * + * @Remarks: This macro is used by UT_TEST_CHECK(). A message will + * only be written if verbose mode is set + * to UT_TEST_MODE_GENERAL and UT_TEST_MODE_DETAILED. + * + */ +#define UT_TEST_WRITE_FAILED_MSG(msg, args) do { \ + UT_TEST_WRITE_STRING(__FILE__); \ + UT_TEST_WRITE_STRING(":"); \ + UT_TEST_WRITE_STRING(UT_TEST_DEFINE_TO_STRING(__LINE__)); \ + UT_TEST_WRITE_STRING(": failed:"); \ + UT_TEST_WRITE_STRING(msg); \ + UT_TEST_WRITE_STRING("("); \ + UT_TEST_WRITE_STRING(args); \ + UT_TEST_WRITE_STRING(")\r\n"); \ + } while (0) +#endif + +/** + * @Macro: UT_TEST_FAIL_CHECK(msg, args) + * + * @Description: Fails a check. + * + * @Param msg: Message to write. This is the name of the called + * Check, without the substring UT_TEST_CHECK. + * @Param args: Argument list as string. + * + * @Remarks: This macro is used by UT_TEST_CHECK(). A message will + * only be written if verbose mode is set + * to UT_TEST_MODE_GENERAL and UT_TEST_MODE_DETAILED. + * + */ +#define UT_TEST_FAIL_CHECK(msg, args) \ + do { \ + UT_TEST_WRITE_FAILED_MSG(msg, args); \ + g_utTestChecksFailed++; \ + g_utTestChecklistFailedChecks++; \ + } while (0) + +/** + * @Macro: UT_TEST_PASS_CHECK(msg, args) + * + * @Description: Passes a check. + * + * @Param msg: Message to write. This is the name of the called + * Check, without the substring UT_TEST_CHECK. + * @Param args: Argument list as string. + * + * @Remarks: This macro is used by UT_TEST_CHECK(). A message will + * only be written if verbose mode is set + * to UT_TEST_MODE_DETAILED. + * + */ +#define UT_TEST_PASS_CHECK(message, args) \ + do { \ + UT_TEST_WRITE_PASSED_MSG(message, args); \ + g_utTestChecksPassed++; \ + } while (0) + +/* *************************************************************************** */ +/* Checklist Macros */ +/* *************************************************************************** */ + +/** + * @Macro: UT_TEST_CHECKLIST_BEGIN(action) + * + * @Description: Begin of a checklist. You have to tell what action + * shall be taken if a check fails. + * + * @Param action: Action to take. This can be: + * * UT_TEST_ACTION_WARNING: A warning message will be printed + * that a check has failed + * * UT_TEST_ACTION_SHUTDOWN: The system will shutdown at + * the end of the checklist. + * * UT_TEST_ACTION_SAFESTATE: The system goes into the safe state + * on the first failed check. + + * @Remarks: A checklist must be finished with UT_TEST_CHECKLIST_END() + * + */ +#define UT_TEST_CHECKLIST_BEGIN(action) \ + do { \ + UT_TEST_action = action; \ + g_utTestChecklistFailedChecks = 0; \ + } while (0) + +/** + * @Macro: UT_TEST_CHECKLIST_END() + * + * @Description: End of a checklist. If the action was UT_TEST_ACTION_SHUTDOWN + * the system will shutdown. + * + * @Remarks: A checklist must begin with UT_TEST_CHECKLIST_BEGIN(action) + * + */ +#define UT_TEST_CHECKLIST_END() \ + if (g_utTestChecklistFailedChecks != 0) { \ + UT_TEST_WRITE_FAILED_MSG("Checklist", ""); \ + if (UT_TEST_ACTION_SHUTDOWN == UT_TEST_action) { \ + UT_TEST_Shutdown(); \ + } \ + } else { \ + UT_TEST_WRITE_PASSED_MSG("Checklist", ""); \ + } + +/* *************************************************************************** */ +/* Check Macros */ +/* *************************************************************************** */ + +/** + * @Macro: UT_TEST_CHECK(condition, msg, args) + * + * @Description: Checks a condition and prints a message. + * + * @Param condition: Check the establishment conditions. + * @Param msg: Message to write. + * @Param args: Argument list as string + * + * @Remarks: Basic check. This macro is used by all higher level checks. + * + */ +#define UT_TEST_CHECK(condition, msg, args) \ + do { \ + if ((condition)) { \ + UT_TEST_PASS_CHECK(msg, args); \ + } else { \ + UT_TEST_FAIL_CHECK(msg, args); \ + } \ + } while (0) + +/** + * @Macro: UT_TEST_CHECK_IS_EQUAL(expected,actual) + * + * @Description: Checks that actual value equals the expected value. + * + * @Param expected: Expected value. + * @Param actual: Actual value. + * + * @Remarks: This macro uses UT_TEST_CHECK(condition, msg, args). + * + */ +#define UT_TEST_CHECK_IS_EQUAL(expected, actual) UT_TEST_CHECK((expected) == (actual), "IsEqual", #expected "," #actual) + +/** + * @Macro: UT_TEST_CHECK_IS_NULL(pointer) + * + * @Description: Checks that a pointer is NULL. + * + * @Param pointer: Pointer to check. + * + * @Remarks: This macro uses UT_TEST_CHECK(condition, msg, args). + * + */ +#define UT_TEST_CHECK_IS_NULL(pointer) UT_TEST_CHECK((pointer) == NULL, "IsNull", #pointer) + +/** + * @Macro: UT_TEST_CHECK_IS_NOT_NULL(pointer) + * + * @Description: Checks that a pointer is not NULL. + * + * @Param pointer: Pointer to check. + * + * @Remarks: This macro uses UT_TEST_CHECK(condition, msg, args). + * + */ +#define UT_TEST_CHECK_IS_NOT_NULL(pointer) UT_TEST_CHECK((pointer) != NULL, "IsNotNull", #pointer) + +/** + * @Macro: UT_TEST_CHECK_IS_IN_RANGE(value, lower, upper) + * + * @Description: Checks if a value is between lower and upper bounds (inclusive) + * Mathematical: lower <= value <= upper + * + * @Param value: Value to check. + * @Param lower: Lower bound. + * @Param upper: Upper bound. + * + * @Remarks: This macro uses UT_TEST_CHECK(condition, msg, args). + * + */ +#define UT_TEST_CHECK_IS_IN_RANGE(value, lower, upper) \ + UT_TEST_CHECK((((value) >= (lower)) && ((value) <= (upper))), "IsInRange", #value "," #lower "," #upper) + +/** + * @Macro: UUT_TEST_CHECK_IS_8BIT(value) + * + * @Description: Checks if a value fits into 8-bit. + * + * @Param value: Value to check. + * + * @Remarks: This macro uses UT_TEST_CHECK(condition, msg, args). + * + */ +#define UUT_TEST_CHECK_IS_8BIT(value) UT_TEST_CHECK((value) == ((value)&0xFF), "Is8Bit", #value) + +/** + * @Macro: UUT_TEST_CHECK_IS_16BIT(value) + * + * @Description: Checks if a value fits into 16-bit. + * + * @Param value: Value to check. + * + * @Remarks: This macro uses UT_TEST_CHECK(condition, msg, args). + * + */ +#define UUT_TEST_CHECK_IS_16BIT(value) UT_TEST_CHECK((value) == ((value)&0xFFFF), "Is16Bit", #value) + +/** + * @Macro: UUT_TEST_CHECK_IS_32BIT(value) + * + * @Description: Checks if a value fits into 32-bit. + * + * @Param value: Value to check. + * + * @Remarks: This macro uses UT_TEST_CHECK(condition, msg, args). + * + */ +#define UUT_TEST_CHECK_IS_32BIT(value) UT_TEST_CHECK((value) == ((value)&0xFFFFFFFF), "Is32Bit", #value) + +/** + * Checks if bit is set + */ +/** + * @Macro: UT_TEST_CHECK_IS_BIT_SET(value, bitno) + * + * @Description: Checks if a bit is set in value. + * + * @Param value: Value to check. + * @Param bitno: Bit number. The least significant bit is 0. + * + * @Remarks: This macro uses UT_TEST_CHECK(condition, msg, args). + * + */ +#define UT_TEST_CHECK_IS_BIT_SET(value, bitno) \ + UT_TEST_CHECK((1 == (((value) >> (bitno)) & 0x01)), "IsBitSet", #value "," #bitno) + +/** + * @Macro: UT_TEST_CHECK_IS_BIT_CLEAR(value, bitno) + * + * @Description: Checks if a bit is not set in value. + * + * @Param value: Value to check. + * @Param bitno: Bit number. The least significant bit is 0. + * + * @Remarks: This macro uses UT_TEST_CHECK(condition, msg, args). + * + */ +#define UT_TEST_CHECK_IS_BIT_CLEAR(value, bitno) \ + UT_TEST_CHECK((0 == (((value) >> (bitno)) & 0x01)), "IsBitClear", #value "," #bitno) +/* *************************************************************************** */ +/* Testcases */ +/* *************************************************************************** */ +/** + * @Macro: UT_TEST_TESTCASE_BEGIN(name) + * + * @Description: Marks the beginning of a test case and resets + * the test case statistic. + * + * @Param name: Name of the test case. + * + * @Remarks: This macro uses UT_TEST_WRITE_STRING(msg) to print the name. + * + */ +#define UT_TEST_TESTCASE_BEGIN(name) \ + do { \ + UT_TEST_WRITE_STRING("\r\n======================================\r\n"); \ + UT_TEST_WRITE_STRING(name); \ + UT_TEST_WRITE_STRING("\r\n======================================\r\n"); \ + g_utTestTestcasesFailedChecks = g_utTestChecksFailed; \ + } while (0) + +/** + * @Macro: UT_TEST_TESTCASE_END() + * + * @Description: Marks the end of a test case and calculates + * the test case statistics. + * + * @Remarks: This macro uses UT_TEST_WRITE_STRING(msg) to print the result. + * + */ +#define UT_TEST_TESTCASE_DETATILS() do { \ + if ((g_utTestTestcasesFailedChecks - g_utTestChecksFailed) == 0) { \ + UT_TEST_WRITE_STRING("Testcase passed.\n\r"); \ + g_utTestTestcasesPassed++; \ + } else { \ + UT_TEST_WRITE_FAILED_MSG("EndTestcase", ""); \ + g_utTestTestcasesFailed++; \ + } \ +} while (0) + +#define UT_TEST_TESTCASE_END() do { \ + UT_TEST_WRITE_STRING("======================================\r\n"); \ + UT_TEST_TESTCASE_DETATILS(); \ + UT_TEST_WRITE_STRING("======================================\r\n"); \ +} while (0) + +/** + * @Macro: UT_TEST_WriteSummary() + * + * @Description: Writes the test suite summary. + * + * @Remarks: This macro uses UT_TEST_WRITE_STRING(msg) and + * UT_TEST_WRITE_INT(n) to write the summary. + * + */ +#define UT_TEST_WRITE_SUMMARY_DETATILS() do { \ + UT_TEST_WRITE_STRING("\r\nTestcases: failed: "); \ + UT_TEST_WRITE_INT(g_utTestTestcasesFailed); \ + UT_TEST_WRITE_STRING("\r\n passed: "); \ + UT_TEST_WRITE_INT(g_utTestTestcasesPassed); \ + UT_TEST_WRITE_STRING("\r\nChecks: failed: "); \ + UT_TEST_WRITE_INT(g_utTestChecksFailed); \ + UT_TEST_WRITE_STRING("\r\n passed: "); \ + UT_TEST_WRITE_INT(g_utTestChecksPassed); \ +} while (0) + +#define UT_TEST_WRITE_SUMMARY() do { \ + UT_TEST_WRITE_STRING("\r\n**************************************"); \ + UT_TEST_WRITE_SUMMARY_DETATILS(); \ + UT_TEST_WRITE_STRING("\r\n**************************************\r\n"); \ +} while (0) + +#endif /* McuMagicTag_UT_TEST_H */