From 74f221cb75ca6571d5ac260735cdf84eeedccb53 Mon Sep 17 00:00:00 2001 From: charles Date: Fri, 3 Apr 2026 00:03:29 +0800 Subject: [PATCH] feat: add pec930_sdk-v1.0.1 --- pec930_sdk-v1.0.1/.DS_Store | Bin 0 -> 18436 bytes pec930_sdk-v1.0.1/.gitignore | 110 + pec930_sdk-v1.0.1/Apps/.DS_Store | Bin 0 -> 10244 bytes .../Apps/app_demo_project/.DS_Store | Bin 0 -> 10244 bytes .../Apps/app_demo_project/.cproject | 309 + .../Apps/app_demo_project/.project | 54 + .../Apps/app_demo_project/Project.nuproject | 25 + .../Apps/app_demo_project/component.mk | 16 + .../Apps/app_demo_project/inc/isr.h | 50 + .../Apps/app_demo_project/inc/main.h | 51 + .../Apps/app_demo_project/readme.md | 8 + .../Apps/app_demo_project/src/isr.c | 39 + .../Apps/app_demo_project/src/main.c | 67 + pec930_sdk-v1.0.1/CHANGELOG.md | 36 + pec930_sdk-v1.0.1/Common/common.mk | 16 + pec930_sdk-v1.0.1/Common/hal_conf.h | 192 + pec930_sdk-v1.0.1/Common/printf.c | 1081 + pec930_sdk-v1.0.1/Common/printf.h | 116 + pec930_sdk-v1.0.1/Common/syslog.c | 126 + pec930_sdk-v1.0.1/Common/syslog.h | 108 + pec930_sdk-v1.0.1/Docs/.DS_Store | Bin 0 -> 6148 bytes .../Schematic/PEC930_EV_BOARD_SSOP24(010).pdf | Bin 0 -> 34391 bytes .../Docs/image/ICE_normal_view.jpg | Bin 0 -> 236710 bytes .../Docs/image/IDE_close_proj.jpg | Bin 0 -> 102048 bytes .../Docs/image/IDE_debug_view.jpg | Bin 0 -> 253694 bytes .../Docs/image/IDE_delet_recent_proj.jpg | Bin 0 -> 89068 bytes pec930_sdk-v1.0.1/Drivers/.DS_Store | Bin 0 -> 6148 bytes pec930_sdk-v1.0.1/Drivers/PEC930/.DS_Store | Bin 0 -> 14340 bytes .../Drivers/PEC930/BSP/.DS_Store | Bin 0 -> 10244 bytes .../PEC930/BSP/StarterKit/starterkit.c | 38 + .../PEC930/BSP/StarterKit/starterkit.h | 49 + .../Drivers/PEC930/Device/.DS_Store | Bin 0 -> 10244 bytes .../Drivers/PEC930/Device/inc/.DS_Store | Bin 0 -> 6148 bytes .../Drivers/PEC930/Device/inc/SVD/PEC930.svd | 10421 +++++++ .../Drivers/PEC930/Device/inc/device.h | 56 + .../Drivers/PEC930/Device/inc/pec930.h | 6072 ++++ .../Drivers/PEC930/Device/inc/system_dev.h | 383 + .../Drivers/PEC930/Device/src/.DS_Store | Bin 0 -> 10244 bytes .../PEC930/Device/src/Startup/startup.S | 154 + .../Drivers/PEC930/Device/src/Startup/trap.S | 222 + .../Drivers/PEC930/Device/src/interrupt.c | 119 + .../Drivers/PEC930/Device/src/syscalls.c | 201 + .../Drivers/PEC930/Device/src/system_dev.c | 424 + .../Drivers/PEC930/HAL_Lib/.DS_Store | Bin 0 -> 10244 bytes .../Drivers/PEC930/HAL_Lib/inc/hal_adc.h | 527 + .../Drivers/PEC930/HAL_Lib/inc/hal_amisc.h | 402 + .../Drivers/PEC930/HAL_Lib/inc/hal_comp.h | 261 + .../Drivers/PEC930/HAL_Lib/inc/hal_crc.h | 110 + .../Drivers/PEC930/HAL_Lib/inc/hal_def.h | 193 + .../Drivers/PEC930/HAL_Lib/inc/hal_device.h | 138 + .../Drivers/PEC930/HAL_Lib/inc/hal_dsp.h | 107 + .../Drivers/PEC930/HAL_Lib/inc/hal_flash.h | 203 + .../Drivers/PEC930/HAL_Lib/inc/hal_gpio.h | 420 + .../Drivers/PEC930/HAL_Lib/inc/hal_i2c.h | 325 + .../Drivers/PEC930/HAL_Lib/inc/hal_lptim.h | 244 + .../Drivers/PEC930/HAL_Lib/inc/hal_opamp.h | 185 + .../Drivers/PEC930/HAL_Lib/inc/hal_pwr.h | 112 + .../Drivers/PEC930/HAL_Lib/inc/hal_spi.h | 145 + .../Drivers/PEC930/HAL_Lib/inc/hal_syscfg.h | 522 + .../Drivers/PEC930/HAL_Lib/inc/hal_tim.h | 564 + .../Drivers/PEC930/HAL_Lib/inc/hal_uart.h | 286 + .../Drivers/PEC930/HAL_Lib/inc/hal_wdg.h | 249 + .../Drivers/PEC930/HAL_Lib/src/hal_adc.c | 302 + .../Drivers/PEC930/HAL_Lib/src/hal_amisc.c | 201 + .../Drivers/PEC930/HAL_Lib/src/hal_comp.c | 94 + .../Drivers/PEC930/HAL_Lib/src/hal_crc.c | 123 + .../Drivers/PEC930/HAL_Lib/src/hal_device.c | 73 + .../Drivers/PEC930/HAL_Lib/src/hal_dsp.c | 83 + .../Drivers/PEC930/HAL_Lib/src/hal_flash.c | 280 + .../Drivers/PEC930/HAL_Lib/src/hal_gpio.c | 249 + .../Drivers/PEC930/HAL_Lib/src/hal_i2c.c | 868 + .../Drivers/PEC930/HAL_Lib/src/hal_lptim.c | 145 + .../Drivers/PEC930/HAL_Lib/src/hal_opamp.c | 74 + .../Drivers/PEC930/HAL_Lib/src/hal_pwr.c | 115 + .../Drivers/PEC930/HAL_Lib/src/hal_spi.c | 381 + .../Drivers/PEC930/HAL_Lib/src/hal_syscfg.c | 103 + .../Drivers/PEC930/HAL_Lib/src/hal_tim.c | 1647 + .../Drivers/PEC930/HAL_Lib/src/hal_uart.c | 100 + .../Drivers/PEC930/HAL_Lib/src/hal_wdg.c | 76 + .../Drivers/PEC930/NMSIS/.DS_Store | Bin 0 -> 6148 bytes .../Drivers/PEC930/NMSIS/Core/.DS_Store | Bin 0 -> 6148 bytes .../NMSIS/Core/Include/core_compatiable.h | 294 + .../NMSIS/Core/Include/core_feature_base.h | 2245 ++ .../Core/Include/core_feature_bitmanip.h | 69 + .../NMSIS/Core/Include/core_feature_cache.h | 1517 + .../NMSIS/Core/Include/core_feature_cidu.h | 438 + .../NMSIS/Core/Include/core_feature_dsp.h | 24934 ++++++++++++++++ .../NMSIS/Core/Include/core_feature_eclic.h | 1374 + .../NMSIS/Core/Include/core_feature_fpu.h | 308 + .../NMSIS/Core/Include/core_feature_plic.h | 426 + .../NMSIS/Core/Include/core_feature_pmp.h | 384 + .../NMSIS/Core/Include/core_feature_spmp.h | 449 + .../NMSIS/Core/Include/core_feature_timer.h | 683 + .../NMSIS/Core/Include/core_feature_vector.h | 93 + .../PEC930/NMSIS/Core/Include/nmsis_bench.h | 289 + .../NMSIS/Core/Include/nmsis_compiler.h | 105 + .../PEC930/NMSIS/Core/Include/nmsis_core.h | 111 + .../PEC930/NMSIS/Core/Include/nmsis_gcc.h | 210 + .../PEC930/NMSIS/Core/Include/nmsis_iar.h | 206 + .../PEC930/NMSIS/Core/Include/nmsis_version.h | 87 + .../PEC930/NMSIS/Core/Include/riscv_bits.h | 99 + .../NMSIS/Core/Include/riscv_encoding.h | 1104 + pec930_sdk-v1.0.1/Drivers/PEC930/component.mk | 92 + .../Drivers/PEC930/gcc_flashxip.ld | 267 + pec930_sdk-v1.0.1/Drivers/drivers.mk | 22 + .../Examples/adc/adc_conv_mode/.cproject | 305 + .../Examples/adc/adc_conv_mode/.project | 54 + .../adc/adc_conv_mode/Project.nuproject | 25 + .../Examples/adc/adc_conv_mode/component.mk | 16 + .../Examples/adc/adc_conv_mode/inc/isr.h | 50 + .../Examples/adc/adc_conv_mode/inc/main.h | 51 + .../Examples/adc/adc_conv_mode/readme.md | 374 + .../Examples/adc/adc_conv_mode/src/isr.c | 39 + .../Examples/adc/adc_conv_mode/src/main.c | 356 + .../Examples/adc/adc_single_conv/.cproject | 305 + .../Examples/adc/adc_single_conv/.project | 54 + .../adc/adc_single_conv/Project.nuproject | 25 + .../Examples/adc/adc_single_conv/component.mk | 16 + .../Examples/adc/adc_single_conv/inc/isr.h | 50 + .../Examples/adc/adc_single_conv/inc/main.h | 51 + .../Examples/adc/adc_single_conv/readme.md | 78 + .../Examples/adc/adc_single_conv/src/isr.c | 39 + .../Examples/adc/adc_single_conv/src/main.c | 240 + .../Examples/adc/adc_trigger_src_io/.cproject | 305 + .../Examples/adc/adc_trigger_src_io/.project | 54 + .../adc/adc_trigger_src_io/Project.nuproject | 25 + .../adc/adc_trigger_src_io/component.mk | 16 + .../Examples/adc/adc_trigger_src_io/inc/isr.h | 50 + .../adc/adc_trigger_src_io/inc/main.h | 51 + .../Examples/adc/adc_trigger_src_io/readme.md | 108 + .../Examples/adc/adc_trigger_src_io/src/isr.c | 39 + .../adc/adc_trigger_src_io/src/main.c | 223 + .../Examples/comp/comp_src_io/.cproject | 305 + .../Examples/comp/comp_src_io/.project | 54 + .../comp/comp_src_io/Project.nuproject | 25 + .../Examples/comp/comp_src_io/component.mk | 16 + .../Examples/comp/comp_src_io/inc/isr.h | 50 + .../Examples/comp/comp_src_io/inc/main.h | 51 + .../Examples/comp/comp_src_io/readme.md | 174 + .../Examples/comp/comp_src_io/src/isr.c | 39 + .../Examples/comp/comp_src_io/src/main.c | 251 + .../Examples/crc/crc_calculate/.cproject | 305 + .../Examples/crc/crc_calculate/.project | 54 + .../crc/crc_calculate/Project.nuproject | 25 + .../Examples/crc/crc_calculate/component.mk | 16 + .../Examples/crc/crc_calculate/inc/isr.h | 50 + .../Examples/crc/crc_calculate/inc/main.h | 51 + .../Examples/crc/crc_calculate/readme.md | 89 + .../Examples/crc/crc_calculate/src/isr.c | 39 + .../Examples/crc/crc_calculate/src/main.c | 194 + .../Examples/dac/dac_base/.cproject | 305 + .../Examples/dac/dac_base/.project | 54 + .../Examples/dac/dac_base/Project.nuproject | 25 + .../Examples/dac/dac_base/component.mk | 16 + .../Examples/dac/dac_base/inc/isr.h | 50 + .../Examples/dac/dac_base/inc/main.h | 51 + .../Examples/dac/dac_base/readme.md | 62 + .../Examples/dac/dac_base/src/isr.c | 39 + .../Examples/dac/dac_base/src/main.c | 93 + .../Examples/dsp/dsp_divide/.cproject | 305 + .../Examples/dsp/dsp_divide/.project | 54 + .../Examples/dsp/dsp_divide/Project.nuproject | 25 + .../Examples/dsp/dsp_divide/component.mk | 16 + .../Examples/dsp/dsp_divide/inc/isr.h | 50 + .../Examples/dsp/dsp_divide/inc/main.h | 51 + .../Examples/dsp/dsp_divide/readme.md | 81 + .../Examples/dsp/dsp_divide/src/isr.c | 39 + .../Examples/dsp/dsp_divide/src/main.c | 80 + .../Examples/dsp/dsp_sqrt/.cproject | 305 + .../Examples/dsp/dsp_sqrt/.project | 54 + .../Examples/dsp/dsp_sqrt/Project.nuproject | 25 + .../Examples/dsp/dsp_sqrt/component.mk | 16 + .../Examples/dsp/dsp_sqrt/inc/isr.h | 50 + .../Examples/dsp/dsp_sqrt/inc/main.h | 51 + .../Examples/dsp/dsp_sqrt/readme.md | 77 + .../Examples/dsp/dsp_sqrt/src/isr.c | 39 + .../Examples/dsp/dsp_sqrt/src/main.c | 76 + .../Examples/flash/flash_prog_erase/.cproject | 305 + .../Examples/flash/flash_prog_erase/.project | 54 + .../flash/flash_prog_erase/Project.nuproject | 25 + .../flash/flash_prog_erase/component.mk | 16 + .../Examples/flash/flash_prog_erase/inc/isr.h | 50 + .../flash/flash_prog_erase/inc/main.h | 55 + .../Examples/flash/flash_prog_erase/readme.md | 60 + .../Examples/flash/flash_prog_erase/src/isr.c | 39 + .../flash/flash_prog_erase/src/main.c | 365 + .../Examples/gpio/gpio_interrupt/.cproject | 305 + .../Examples/gpio/gpio_interrupt/.project | 54 + .../gpio/gpio_interrupt/Project.nuproject | 25 + .../Examples/gpio/gpio_interrupt/component.mk | 16 + .../Examples/gpio/gpio_interrupt/inc/isr.h | 50 + .../Examples/gpio/gpio_interrupt/inc/main.h | 51 + .../Examples/gpio/gpio_interrupt/readme.md | 54 + .../Examples/gpio/gpio_interrupt/src/isr.c | 39 + .../Examples/gpio/gpio_interrupt/src/main.c | 111 + .../Examples/gpio/gpio_toggle/.cproject | 305 + .../Examples/gpio/gpio_toggle/.project | 54 + .../gpio/gpio_toggle/Project.nuproject | 25 + .../Examples/gpio/gpio_toggle/component.mk | 16 + .../Examples/gpio/gpio_toggle/inc/isr.h | 50 + .../Examples/gpio/gpio_toggle/inc/main.h | 51 + .../Examples/gpio/gpio_toggle/readme.md | 31 + .../Examples/gpio/gpio_toggle/src/isr.c | 39 + .../Examples/gpio/gpio_toggle/src/main.c | 76 + .../i2c/i2c_mster_transceiver/.cproject | 305 + .../i2c/i2c_mster_transceiver/.project | 54 + .../i2c_mster_transceiver/Project.nuproject | 25 + .../i2c/i2c_mster_transceiver/component.mk | 16 + .../i2c/i2c_mster_transceiver/inc/isr.h | 50 + .../i2c/i2c_mster_transceiver/inc/main.h | 51 + .../i2c/i2c_mster_transceiver/readme.md | 79 + .../i2c/i2c_mster_transceiver/src/isr.c | 39 + .../i2c/i2c_mster_transceiver/src/main.c | 219 + .../i2c/i2c_slave_transceiver/.cproject | 305 + .../i2c/i2c_slave_transceiver/.project | 54 + .../i2c_slave_transceiver/Project.nuproject | 25 + .../i2c/i2c_slave_transceiver/component.mk | 16 + .../i2c/i2c_slave_transceiver/inc/isr.h | 50 + .../i2c/i2c_slave_transceiver/inc/main.h | 51 + .../i2c/i2c_slave_transceiver/readme.md | 67 + .../i2c/i2c_slave_transceiver/src/isr.c | 39 + .../i2c/i2c_slave_transceiver/src/main.c | 211 + .../Examples/lptim/lptim_count/.cproject | 305 + .../Examples/lptim/lptim_count/.project | 54 + .../lptim/lptim_count/Project.nuproject | 25 + .../Examples/lptim/lptim_count/component.mk | 16 + .../Examples/lptim/lptim_count/inc/isr.h | 50 + .../Examples/lptim/lptim_count/inc/main.h | 51 + .../Examples/lptim/lptim_count/readme.md | 17 + .../Examples/lptim/lptim_count/src/isr.c | 39 + .../Examples/lptim/lptim_count/src/main.c | 106 + .../lptim/lptim_match_Interrupt/.cproject | 305 + .../lptim/lptim_match_Interrupt/.project | 54 + .../lptim_match_Interrupt/Project.nuproject | 25 + .../lptim/lptim_match_Interrupt/component.mk | 16 + .../lptim/lptim_match_Interrupt/inc/isr.h | 50 + .../lptim/lptim_match_Interrupt/inc/main.h | 51 + .../lptim/lptim_match_Interrupt/readme.md | 17 + .../lptim/lptim_match_Interrupt/src/isr.c | 39 + .../lptim/lptim_match_Interrupt/src/main.c | 123 + .../Examples/lvd_lvr/lvd_lvr/.cproject | 305 + .../Examples/lvd_lvr/lvd_lvr/.project | 54 + .../lvd_lvr/lvd_lvr/Project.nuproject | 25 + .../Examples/lvd_lvr/lvd_lvr/component.mk | 16 + .../Examples/lvd_lvr/lvd_lvr/inc/isr.h | 50 + .../Examples/lvd_lvr/lvd_lvr/inc/main.h | 51 + .../Examples/lvd_lvr/lvd_lvr/readme.md | 21 + .../Examples/lvd_lvr/lvd_lvr/src/isr.c | 39 + .../Examples/lvd_lvr/lvd_lvr/src/main.c | 105 + .../Examples/pga/pga_src_internal/.cproject | 305 + .../Examples/pga/pga_src_internal/.project | 54 + .../pga/pga_src_internal/Project.nuproject | 25 + .../pga/pga_src_internal/component.mk | 16 + .../Examples/pga/pga_src_internal/inc/isr.h | 50 + .../Examples/pga/pga_src_internal/inc/main.h | 51 + .../Examples/pga/pga_src_internal/readme.md | 114 + .../Examples/pga/pga_src_internal/src/isr.c | 39 + .../Examples/pga/pga_src_internal/src/main.c | 188 + .../Examples/pga/pga_src_io/.cproject | 305 + .../Examples/pga/pga_src_io/.project | 54 + .../Examples/pga/pga_src_io/Project.nuproject | 25 + .../Examples/pga/pga_src_io/component.mk | 16 + .../Examples/pga/pga_src_io/inc/isr.h | 50 + .../Examples/pga/pga_src_io/inc/main.h | 51 + .../Examples/pga/pga_src_io/readme.md | 108 + .../Examples/pga/pga_src_io/src/isr.c | 39 + .../Examples/pga/pga_src_io/src/main.c | 220 + .../Examples/pwr/pwr_sleep_mode/.cproject | 305 + .../Examples/pwr/pwr_sleep_mode/.project | 54 + .../pwr/pwr_sleep_mode/Project.nuproject | 25 + .../Examples/pwr/pwr_sleep_mode/component.mk | 16 + .../Examples/pwr/pwr_sleep_mode/inc/isr.h | 50 + .../Examples/pwr/pwr_sleep_mode/inc/main.h | 51 + .../Examples/pwr/pwr_sleep_mode/readme.md | 210 + .../Examples/pwr/pwr_sleep_mode/src/isr.c | 39 + .../Examples/pwr/pwr_sleep_mode/src/main.c | 310 + .../Examples/spi/spi_master/.cproject | 305 + .../Examples/spi/spi_master/.project | 54 + .../Examples/spi/spi_master/Project.nuproject | 25 + .../Examples/spi/spi_master/component.mk | 16 + .../Examples/spi/spi_master/inc/isr.h | 50 + .../Examples/spi/spi_master/inc/main.h | 51 + .../Examples/spi/spi_master/readme.md | 22 + .../Examples/spi/spi_master/src/isr.c | 39 + .../Examples/spi/spi_master/src/main.c | 107 + .../Examples/spi/spi_master_IT/.cproject | 305 + .../Examples/spi/spi_master_IT/.project | 54 + .../spi/spi_master_IT/Project.nuproject | 25 + .../Examples/spi/spi_master_IT/component.mk | 16 + .../Examples/spi/spi_master_IT/inc/isr.h | 50 + .../Examples/spi/spi_master_IT/inc/main.h | 51 + .../Examples/spi/spi_master_IT/readme.md | 33 + .../Examples/spi/spi_master_IT/src/isr.c | 39 + .../Examples/spi/spi_master_IT/src/main.c | 177 + .../Examples/spi/spi_slave/.cproject | 305 + .../Examples/spi/spi_slave/.project | 54 + .../Examples/spi/spi_slave/Project.nuproject | 25 + .../Examples/spi/spi_slave/component.mk | 16 + .../Examples/spi/spi_slave/inc/isr.h | 50 + .../Examples/spi/spi_slave/inc/main.h | 51 + .../Examples/spi/spi_slave/readme.md | 21 + .../Examples/spi/spi_slave/src/isr.c | 39 + .../Examples/spi/spi_slave/src/main.c | 103 + .../Examples/spi/spi_slave_IT/.cproject | 305 + .../Examples/spi/spi_slave_IT/.project | 54 + .../spi/spi_slave_IT/Project.nuproject | 25 + .../Examples/spi/spi_slave_IT/component.mk | 16 + .../Examples/spi/spi_slave_IT/inc/isr.h | 50 + .../Examples/spi/spi_slave_IT/inc/main.h | 51 + .../Examples/spi/spi_slave_IT/readme.md | 21 + .../Examples/spi/spi_slave_IT/src/isr.c | 39 + .../Examples/spi/spi_slave_IT/src/main.c | 162 + .../system/sys_ice_unlock_lib/.cproject | 305 + .../system/sys_ice_unlock_lib/.project | 54 + .../sys_ice_unlock_lib/Project.nuproject | 25 + .../system/sys_ice_unlock_lib/component.mk | 17 + .../pec930_SW_unlock_ICE_time_slot_resp.jpg | Bin 0 -> 34721 bytes .../image/pec930_unlock_ice_dut_resp.png | Bin 0 -> 52737 bytes .../image/pec930_unlock_ice_waveform.jpg | Bin 0 -> 14818 bytes .../pec930_unlock_ice_waveform_1xxKHz.png | Bin 0 -> 80500 bytes .../pec930_unlock_ice_waveform_with_resp.png | Bin 0 -> 49879 bytes .../image/pec930_unlock_ice_working_time.png | Bin 0 -> 50696 bytes .../sys_ice_unlock_lib/inc/ice_unlock.h | 67 + .../system/sys_ice_unlock_lib/inc/isr.h | 50 + .../system/sys_ice_unlock_lib/inc/main.h | 57 + .../system/sys_ice_unlock_lib/readme.md | 132 + .../system/sys_ice_unlock_lib/src/isr.c | 39 + .../system/sys_ice_unlock_lib/src/main.c | 174 + .../Examples/system/sys_mco/.cproject | 305 + .../Examples/system/sys_mco/.project | 54 + .../Examples/system/sys_mco/Project.nuproject | 25 + .../Examples/system/sys_mco/component.mk | 16 + .../Examples/system/sys_mco/inc/isr.h | 50 + .../Examples/system/sys_mco/inc/main.h | 51 + .../Examples/system/sys_mco/readme.md | 33 + .../Examples/system/sys_mco/src/isr.c | 39 + .../Examples/system/sys_mco/src/main.c | 184 + .../Examples/system/sys_tick_swi/.cproject | 305 + .../Examples/system/sys_tick_swi/.project | 54 + .../system/sys_tick_swi/Project.nuproject | 25 + .../Examples/system/sys_tick_swi/component.mk | 16 + .../Examples/system/sys_tick_swi/inc/isr.h | 50 + .../Examples/system/sys_tick_swi/inc/main.h | 51 + .../Examples/system/sys_tick_swi/readme.md | 210 + .../Examples/system/sys_tick_swi/src/isr.c | 39 + .../Examples/system/sys_tick_swi/src/main.c | 142 + .../Examples/template/JF_01/.cproject | 294 + .../Examples/template/JF_01/.project | 54 + .../Examples/template/JF_01/Project.nuproject | 25 + .../Examples/template/JF_01/component.mk | 16 + .../Examples/template/JF_01/inc/init.h | 22 + .../Examples/template/JF_01/inc/isr.h | 50 + .../Examples/template/JF_01/inc/main.h | 51 + .../Examples/template/JF_01/readme.md | 8 + .../Examples/template/JF_01/src/init.c | 232 + .../Examples/template/JF_01/src/isr.c | 55 + .../Examples/template/JF_01/src/main.c | 53 + .../Examples/template/JF_02/.cproject | 294 + .../Examples/template/JF_02/.project | 54 + .../Examples/template/JF_02/Project.nuproject | 25 + .../Examples/template/JF_02/component.mk | 16 + .../Examples/template/JF_02/inc/init.h | 22 + .../Examples/template/JF_02/inc/isr.h | 50 + .../Examples/template/JF_02/inc/main.h | 51 + .../Examples/template/JF_02/readme.md | 8 + .../Examples/template/JF_02/src/init.c | 234 + .../Examples/template/JF_02/src/isr.c | 56 + .../Examples/template/JF_02/src/main.c | 64 + .../template/JF_02_motor/.clang-format | 52 + .../Examples/template/JF_02_motor/.cproject | 294 + .../Examples/template/JF_02_motor/.project | 54 + .../template/JF_02_motor/Project.nuproject | 25 + .../template/JF_02_motor/component.mk | 16 + .../Examples/template/JF_02_motor/inc/init.h | 24 + .../Examples/template/JF_02_motor/inc/isr.h | 54 + .../Examples/template/JF_02_motor/inc/main.h | 51 + .../Examples/template/JF_02_motor/readme.md | 8 + .../Examples/template/JF_02_motor/src/init.c | 258 + .../Examples/template/JF_02_motor/src/isr.c | 75 + .../Examples/template/JF_02_motor/src/main.c | 127 + .../Examples/template/demo_project/.cproject | 305 + .../Examples/template/demo_project/.project | 54 + .../template/demo_project/Project.nuproject | 25 + .../template/demo_project/component.mk | 16 + .../Examples/template/demo_project/inc/isr.h | 50 + .../Examples/template/demo_project/inc/main.h | 51 + .../Examples/template/demo_project/readme.md | 8 + .../Examples/template/demo_project/src/isr.c | 39 + .../Examples/template/demo_project/src/main.c | 70 + .../Examples/tim/tim_6StepOutput/.cproject | 305 + .../Examples/tim/tim_6StepOutput/.project | 54 + .../tim/tim_6StepOutput/Project.nuproject | 25 + .../Examples/tim/tim_6StepOutput/component.mk | 16 + .../Examples/tim/tim_6StepOutput/inc/isr.h | 50 + .../Examples/tim/tim_6StepOutput/inc/main.h | 51 + .../Examples/tim/tim_6StepOutput/readme.md | 16 + .../Examples/tim/tim_6StepOutput/src/isr.c | 39 + .../Examples/tim/tim_6StepOutput/src/main.c | 233 + .../Examples/tim/tim_InputCapture/.cproject | 305 + .../Examples/tim/tim_InputCapture/.project | 54 + .../tim/tim_InputCapture/Project.nuproject | 25 + .../tim/tim_InputCapture/component.mk | 16 + .../Examples/tim/tim_InputCapture/inc/isr.h | 50 + .../Examples/tim/tim_InputCapture/inc/main.h | 51 + .../Examples/tim/tim_InputCapture/readme.md | 14 + .../Examples/tim/tim_InputCapture/src/isr.c | 39 + .../Examples/tim/tim_InputCapture/src/main.c | 139 + .../Examples/tim/tim_forceOutput/.cproject | 305 + .../Examples/tim/tim_forceOutput/.project | 54 + .../tim/tim_forceOutput/Project.nuproject | 25 + .../Examples/tim/tim_forceOutput/component.mk | 16 + .../Examples/tim/tim_forceOutput/inc/isr.h | 50 + .../Examples/tim/tim_forceOutput/inc/main.h | 51 + .../Examples/tim/tim_forceOutput/readme.md | 15 + .../Examples/tim/tim_forceOutput/src/isr.c | 39 + .../Examples/tim/tim_forceOutput/src/main.c | 92 + .../Examples/tim/tim_outputCompare/.cproject | 305 + .../Examples/tim/tim_outputCompare/.project | 54 + .../tim/tim_outputCompare/Project.nuproject | 25 + .../tim/tim_outputCompare/component.mk | 16 + .../Examples/tim/tim_outputCompare/inc/isr.h | 50 + .../Examples/tim/tim_outputCompare/inc/main.h | 51 + .../Examples/tim/tim_outputCompare/readme.md | 17 + .../Examples/tim/tim_outputCompare/src/isr.c | 39 + .../Examples/tim/tim_outputCompare/src/main.c | 136 + .../Examples/tim/tim_pwm_output/.cproject | 305 + .../Examples/tim/tim_pwm_output/.project | 54 + .../tim/tim_pwm_output/Project.nuproject | 25 + .../Examples/tim/tim_pwm_output/component.mk | 16 + .../Examples/tim/tim_pwm_output/inc/isr.h | 50 + .../Examples/tim/tim_pwm_output/inc/main.h | 51 + .../Examples/tim/tim_pwm_output/readme.md | 24 + .../Examples/tim/tim_pwm_output/src/isr.c | 39 + .../Examples/tim/tim_pwm_output/src/main.c | 133 + .../Examples/uart/uart_Interrupt/.cproject | 305 + .../Examples/uart/uart_Interrupt/.project | 54 + .../uart/uart_Interrupt/Project.nuproject | 25 + .../Examples/uart/uart_Interrupt/component.mk | 16 + .../Examples/uart/uart_Interrupt/inc/isr.h | 59 + .../Examples/uart/uart_Interrupt/inc/main.h | 51 + .../Examples/uart/uart_Interrupt/readme.md | 44 + .../Examples/uart/uart_Interrupt/src/isr.c | 39 + .../Examples/uart/uart_Interrupt/src/main.c | 110 + .../Examples/uart/uart_polling/.cproject | 305 + .../Examples/uart/uart_polling/.project | 54 + .../uart/uart_polling/Project.nuproject | 25 + .../Examples/uart/uart_polling/component.mk | 16 + .../Examples/uart/uart_polling/inc/isr.h | 59 + .../Examples/uart/uart_polling/inc/main.h | 51 + .../Examples/uart/uart_polling/readme.md | 37 + .../Examples/uart/uart_polling/src/isr.c | 39 + .../Examples/uart/uart_polling/src/main.c | 111 + .../Examples/wdg/wdg_count/.cproject | 305 + .../Examples/wdg/wdg_count/.project | 54 + .../Examples/wdg/wdg_count/Project.nuproject | 25 + .../Examples/wdg/wdg_count/component.mk | 16 + .../Examples/wdg/wdg_count/inc/isr.h | 50 + .../Examples/wdg/wdg_count/inc/main.h | 51 + .../Examples/wdg/wdg_count/readme.md | 105 + .../Examples/wdg/wdg_count/src/isr.c | 39 + .../Examples/wdg/wdg_count/src/main.c | 121 + pec930_sdk-v1.0.1/Makefile | 333 + pec930_sdk-v1.0.1/README.md | 58 + pec930_sdk-v1.0.1/Tools/.DS_Store | Bin 0 -> 10244 bytes pec930_sdk-v1.0.1/Tools/openocd/.DS_Store | Bin 0 -> 6148 bytes pec930_sdk-v1.0.1/Tools/openocd/README.md | 85 + .../Tools/openocd/scripts/bitsbytes.tcl | 59 + .../Tools/openocd/scripts/interface/dummy.cfg | 5 + .../openocd/scripts/interface/flashlink.cfg | 16 + .../openocd/scripts/interface/ft232r.cfg | 2 + .../Tools/openocd/scripts/interface/jlink.cfg | 14 + .../openocd/scripts/interface/jtag_dpi.cfg | 38 + .../scripts/interface/jtag_hat_rpi2.cfg | 38 + .../openocd/scripts/interface/jtag_vpi.cfg | 18 + .../openocd/scripts/interface/openjtag.cfg | 8 + .../openocd/scripts/interface/usb-jtag.cfg | 37 + .../Tools/openocd/scripts/mem_helper.tcl | 36 + .../Tools/openocd/scripts/memory.tcl | 175 + .../Tools/openocd/scripts/mmr_helpers.tcl | 72 + .../Tools/openocd/scripts/target/pec930.cfg | 129 + pec930_sdk-v1.0.1/Tools/scripts/.DS_Store | Bin 0 -> 8196 bytes .../Profiles/Project_Debug_OpenOCD.launch | 63 + pec930_sdk-v1.0.1/Tools/scripts/tags.sh | 349 + 483 files changed, 97873 insertions(+) create mode 100644 pec930_sdk-v1.0.1/.DS_Store create mode 100644 pec930_sdk-v1.0.1/.gitignore create mode 100644 pec930_sdk-v1.0.1/Apps/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Apps/app_demo_project/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Apps/app_demo_project/.cproject create mode 100644 pec930_sdk-v1.0.1/Apps/app_demo_project/.project create mode 100644 pec930_sdk-v1.0.1/Apps/app_demo_project/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Apps/app_demo_project/component.mk create mode 100644 pec930_sdk-v1.0.1/Apps/app_demo_project/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Apps/app_demo_project/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Apps/app_demo_project/readme.md create mode 100644 pec930_sdk-v1.0.1/Apps/app_demo_project/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Apps/app_demo_project/src/main.c create mode 100644 pec930_sdk-v1.0.1/CHANGELOG.md create mode 100644 pec930_sdk-v1.0.1/Common/common.mk create mode 100644 pec930_sdk-v1.0.1/Common/hal_conf.h create mode 100644 pec930_sdk-v1.0.1/Common/printf.c create mode 100644 pec930_sdk-v1.0.1/Common/printf.h create mode 100644 pec930_sdk-v1.0.1/Common/syslog.c create mode 100644 pec930_sdk-v1.0.1/Common/syslog.h create mode 100644 pec930_sdk-v1.0.1/Docs/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Docs/Schematic/PEC930_EV_BOARD_SSOP24(010).pdf create mode 100644 pec930_sdk-v1.0.1/Docs/image/ICE_normal_view.jpg create mode 100644 pec930_sdk-v1.0.1/Docs/image/IDE_close_proj.jpg create mode 100644 pec930_sdk-v1.0.1/Docs/image/IDE_debug_view.jpg create mode 100644 pec930_sdk-v1.0.1/Docs/image/IDE_delet_recent_proj.jpg create mode 100644 pec930_sdk-v1.0.1/Drivers/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/BSP/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/SVD/PEC930.svd create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/device.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/pec930.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/system_dev.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/startup.S create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/trap.S create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/interrupt.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/syscalls.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/system_dev.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_adc.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_amisc.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_comp.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_crc.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_def.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_device.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_dsp.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_flash.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_gpio.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_i2c.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_lptim.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_opamp.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_pwr.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_spi.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_syscfg.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_tim.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_uart.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_wdg.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_adc.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_amisc.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_comp.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_crc.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_device.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_dsp.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_flash.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_gpio.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_i2c.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_lptim.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_opamp.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_pwr.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_spi.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_syscfg.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_tim.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_uart.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_wdg.c create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_compatiable.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_base.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_bitmanip.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cache.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cidu.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_dsp.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_eclic.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_fpu.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_plic.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_pmp.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_spmp.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_timer.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_vector.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_bench.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_compiler.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_core.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_gcc.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_iar.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_version.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_bits.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_encoding.h create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/component.mk create mode 100644 pec930_sdk-v1.0.1/Drivers/PEC930/gcc_flashxip.ld create mode 100644 pec930_sdk-v1.0.1/Drivers/drivers.mk create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.project create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.project create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.project create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.project create mode 100644 pec930_sdk-v1.0.1/Examples/comp/comp_src_io/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/comp/comp_src_io/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/comp/comp_src_io/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.project create mode 100644 pec930_sdk-v1.0.1/Examples/crc/crc_calculate/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/crc/crc_calculate/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/crc/crc_calculate/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/dac/dac_base/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/dac/dac_base/.project create mode 100644 pec930_sdk-v1.0.1/Examples/dac/dac_base/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/dac/dac_base/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/dac/dac_base/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/dac/dac_base/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/dac/dac_base/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.project create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.project create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.project create mode 100644 pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.project create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.project create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.project create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.project create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.project create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_count/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_count/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_count/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.project create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.project create mode 100644 pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.project create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.project create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_io/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_io/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_io/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.project create mode 100644 pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master/.project create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.project create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave/.project create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.project create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.project create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_SW_unlock_ICE_time_slot_resp.jpg create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_dut_resp.png create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform.jpg create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_1xxKHz.png create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_with_resp.png create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_working_time.png create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/ice_unlock.h create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_mco/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_mco/.project create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_mco/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_mco/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_mco/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_mco/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_mco/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.project create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_01/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_01/.project create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_01/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_01/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_01/inc/init.h create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_01/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_01/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_01/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_01/src/init.c create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_01/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_01/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02/.project create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02/inc/init.h create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02/src/init.c create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.clang-format create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.project create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/init.h create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/init.c create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/template/demo_project/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/template/demo_project/.project create mode 100644 pec930_sdk-v1.0.1/Examples/template/demo_project/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/template/demo_project/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/template/demo_project/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/template/demo_project/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/template/demo_project/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/template/demo_project/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/template/demo_project/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.project create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.project create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.project create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.project create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.project create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.project create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_polling/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_polling/.project create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_polling/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_polling/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_polling/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/main.c create mode 100644 pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.cproject create mode 100644 pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.project create mode 100644 pec930_sdk-v1.0.1/Examples/wdg/wdg_count/Project.nuproject create mode 100644 pec930_sdk-v1.0.1/Examples/wdg/wdg_count/component.mk create mode 100644 pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/isr.h create mode 100644 pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/main.h create mode 100644 pec930_sdk-v1.0.1/Examples/wdg/wdg_count/readme.md create mode 100644 pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/isr.c create mode 100644 pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/main.c create mode 100644 pec930_sdk-v1.0.1/Makefile create mode 100644 pec930_sdk-v1.0.1/README.md create mode 100644 pec930_sdk-v1.0.1/Tools/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/README.md create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/bitsbytes.tcl create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/dummy.cfg create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/flashlink.cfg create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/ft232r.cfg create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jlink.cfg create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_dpi.cfg create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_hat_rpi2.cfg create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_vpi.cfg create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/openjtag.cfg create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/usb-jtag.cfg create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/mem_helper.tcl create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/memory.tcl create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/mmr_helpers.tcl create mode 100644 pec930_sdk-v1.0.1/Tools/openocd/scripts/target/pec930.cfg create mode 100644 pec930_sdk-v1.0.1/Tools/scripts/.DS_Store create mode 100644 pec930_sdk-v1.0.1/Tools/scripts/Profiles/Project_Debug_OpenOCD.launch create mode 100644 pec930_sdk-v1.0.1/Tools/scripts/tags.sh diff --git a/pec930_sdk-v1.0.1/.DS_Store b/pec930_sdk-v1.0.1/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f2a426562d63242a58580e4fb1b93e4cc833d023 GIT binary patch literal 18436 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 DeX{GC literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/.cproject b/pec930_sdk-v1.0.1/Apps/app_demo_project/.cproject new file mode 100644 index 0000000..364917a --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/.cproject @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/.project b/pec930_sdk-v1.0.1/Apps/app_demo_project/.project new file mode 100644 index 0000000..d82ec1b --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-2-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-2-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-2-PROJECT_LOC/Tools/scripts/Profiles + + + + + 1762843010815 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/Project.nuproject b/pec930_sdk-v1.0.1/Apps/app_demo_project/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/component.mk b/pec930_sdk-v1.0.1/Apps/app_demo_project/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/isr.h b/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/main.h b/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/readme.md b/pec930_sdk-v1.0.1/Apps/app_demo_project/readme.md new file mode 100644 index 0000000..d4feae0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/readme.md @@ -0,0 +1,8 @@ +demo_project +--- + +This example is a demo project to descript `how to log message` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/src/isr.c b/pec930_sdk-v1.0.1/Apps/app_demo_project/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Apps/app_demo_project/src/main.c b/pec930_sdk-v1.0.1/Apps/app_demo_project/src/main.c new file mode 100644 index 0000000..7c42930 --- /dev/null +++ b/pec930_sdk-v1.0.1/Apps/app_demo_project/src/main.c @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +uint32_t __FASTCODE fastcode_proc(void) +{ + log_color(SLOG_CYAN, "run at fast area: $pc= x%08X\n", (uint32_t)&fastcode_proc); + return 0; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("This is a app demo project\n"); + msg("log debug message: $pc= x%08X\n", __get_pc()); + log_color(SLOG_GREEN, "color green\n"); + log_color(SLOG_YELLOW, "color yellow\n"); + + fastcode_proc(); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/CHANGELOG.md b/pec930_sdk-v1.0.1/CHANGELOG.md new file mode 100644 index 0000000..45e98b9 --- /dev/null +++ b/pec930_sdk-v1.0.1/CHANGELOG.md @@ -0,0 +1,36 @@ +# CHANGELOG +--- + +## v1.0.1 + +### Bug Fixes + ++ [PWR] Support to focus a wake-up type ++ [PWR] Review the configuration flow of wake-up with interrupt signal ++ [LPTIM] Fix reset flow when init and deinit + +### Features + ++ [ALL] Modify project files to involve libSysDev_PEC930.a ++ [ICE] Add an example of Unlock-ICE mechanism + +## v1.0.0 + +### Bug Fixes + ++ [LVD] Fix function name to call lvd driver ++ [GPIO] Fix the configuration of interrupt ++ [I2C] Add disable interrupt when deinit function ++ [WDG] Refactor hal-driver and examples for friendly usage ++ [AMISC] Review the configuration of voltage source of HSI ++ [UART] Delete dummy register field of UART ++ [GPIO] Fix configuration when disable interrupt ++ [AMISC] Fix the configuration of V15 output of hal-driver ++ [ADC] delete clock divider option to fit hardware limitation + +### Features + ++ [SPI] Add examples of interrupt of SPI master and slave ++ [COMP] Add example and hal-driver of COMP + +## v1.0.0-RC1 diff --git a/pec930_sdk-v1.0.1/Common/common.mk b/pec930_sdk-v1.0.1/Common/common.mk new file mode 100644 index 0000000..7e52ce6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/common.mk @@ -0,0 +1,16 @@ +# +# common Makefile +# + + + +C_SOURCES += \ + $(srctree)/Common/printf.c \ + $(srctree)/Common/syslog.c + +C_INCLUDES += -I$(srctree)/Common + + +CFLAGS += +CXXFLAGS += +LDFLAGS += diff --git a/pec930_sdk-v1.0.1/Common/hal_conf.h b/pec930_sdk-v1.0.1/Common/hal_conf.h new file mode 100644 index 0000000..cf71351 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/hal_conf.h @@ -0,0 +1,192 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_conf.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_conf_H_wV9UWaWV_lh0O_HTIV_ssSG_umphyc0TVXKd__ +#define __hal_conf_H_wV9UWaWV_lh0O_HTIV_ssSG_umphyc0TVXKd__ + +#ifdef __cplusplus +extern "C" { +#endif + + +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Uncomment 'USE_FULL_ASSERT' to expanse the "assert_param" macro + * in the HAL drivers code + * ps. User should implement the funciton + * 'void assert_failed(char *func, uint32_t line)' at applicaion layer + */ +// #define USE_FULL_ASSERT 1 + +/** + * The list of modules to be used in the HAL drivers + */ +#define CONFIG_ENABLE_HAL_SYSCFG +#define CONFIG_ENABLE_HAL_PWR +#define CONFIG_ENABLE_HAL_FLASH +#define CONFIG_ENABLE_HAL_GPIO +#define CONFIG_ENABLE_HAL_UART +#define CONFIG_ENABLE_HAL_I2C +#define CONFIG_ENABLE_HAL_SPI +#define CONFIG_ENABLE_HAL_LPTIM +#define CONFIG_ENABLE_HAL_TIM0 +#define CONFIG_ENABLE_HAL_TIM1 +#define CONFIG_ENABLE_HAL_TIM2 +#define CONFIG_ENABLE_HAL_WDG +#define CONFIG_ENABLE_HAL_ADC +#define CONFIG_ENABLE_HAL_AMISC +#define CONFIG_ENABLE_HAL_COMP +#define CONFIG_ENABLE_HAL_OPAMP +#define CONFIG_ENABLE_HAL_CRC +#define CONFIG_ENABLE_HAL_DSP +#define CONFIG_ENABLE_HAL_EPWM + +/** + * System-clock Definition + */ +#if !defined(SYS_HIRC_VALUE) +#define SYS_HIRC_MHZ (60ul) +#define SYS_HIRC_VALUE (SYS_HIRC_MHZ * 1000ul * 1000ul) +#endif + +#if !defined(SYS_OSC_VALUE) +#define SYS_OSC_VALUE (8 * 1000ul * 1000ul) +#endif + +#if !defined(SYS_LIRC_VALUE) +#define SYS_LIRC_VALUE 32768ul +#endif + +#define SYS_TIMER_FREQ SYS_LIRC_VALUE +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +#ifdef CONFIG_ENABLE_HAL_SYSCFG +/* Reset and Clock Control module */ +#include "hal_syscfg.h" +#endif /* CONFIG_ENABLE_HAL_SYSCFG */ + +#ifdef CONFIG_ENABLE_HAL_PWR +/* Power Management Unit module */ +#include "hal_pwr.h" +#endif /* CONFIG_ENABLE_HAL_PWR */ + +#ifdef CONFIG_ENABLE_HAL_FLASH +/* Embedded Flash module */ +#include "hal_flash.h" +#endif /* CONFIG_ENABLE_HAL_FLASH */ + +#ifdef CONFIG_ENABLE_HAL_GPIO +/* General-purpose I/O module */ +#include "hal_gpio.h" +#endif /* CONFIG_ENABLE_HAL_GPIO */ + +#ifdef CONFIG_ENABLE_HAL_UART +/* Universal Asynchronous Rx/Tx module */ +#include "hal_uart.h" +#endif /* CONFIG_ENABLE_HAL_UART */ + +#ifdef CONFIG_ENABLE_HAL_I2C +/* Inter-Integrated Circuit module */ +#include "hal_i2c.h" +#endif /* CONFIG_ENABLE_HAL_I2C */ + +#ifdef CONFIG_ENABLE_HAL_SPI +/* Serial Peripheral Interface-Bus module */ +#include "hal_spi.h" +#endif /* CONFIG_ENABLE_HAL_SPI */ + +#ifdef CONFIG_ENABLE_HAL_LPTIM +/* Low-Power Timer module */ +#include "hal_lptim.h" +#endif /* CONFIG_ENABLE_HAL_LPTIM */ + +#ifdef CONFIG_ENABLE_HAL_TIM0 +/* Tim0 module */ +#include "hal_lptim.h" +#endif /* CONFIG_ENABLE_HAL_TIM0 */ + +#ifdef CONFIG_ENABLE_HAL_TIM1 +/* Tim1 module */ +#include "hal_lptim.h" +#endif /* CONFIG_ENABLE_HAL_TIM1 */ + +#ifdef CONFIG_ENABLE_HAL_TIM2 +/* Timer module */ +#include "hal_tim.h" +#endif /* CONFIG_ENABLE_HAL_TIM2 */ + +#ifdef CONFIG_ENABLE_HAL_WDG +/* Watch Dog module */ +#include "hal_wdg.h" +#endif /* CONFIG_ENABLE_HAL_WDG */ + +#ifdef CONFIG_ENABLE_HAL_ADC +/* Analog-to-Digital Converter module */ +#include "hal_adc.h" +#endif /* CONFIG_ENABLE_HAL_ADC */ + +#ifdef CONFIG_ENABLE_HAL_AMISC +/* Analog MISC controller module */ +#include "hal_amisc.h" +#endif /* CONFIG_ENABLE_HAL_AMISC */ + +#ifdef CONFIG_ENABLE_HAL_COMP +/* Voltage Compare module */ +#include "hal_comp.h" +#endif /* CONFIG_ENABLE_HAL_COMP */ + +#ifdef CONFIG_ENABLE_HAL_OPAMP +/* OP-Amplifiers with Programmable Gain Amplifier mode */ +#include "hal_opamp.h" +#endif /* CONFIG_ENABLE_HAL_OPAMP */ + +#ifdef CONFIG_ENABLE_HAL_CRC +/* Cyclic Redundancy Check module */ +#include "hal_crc.h" +#endif /* CONFIG_ENABLE_HAL_CRC */ + +#ifdef CONFIG_ENABLE_HAL_DSP +/* Peripheral DSP module */ +#include "hal_dsp.h" +#endif /* CONFIG_ENABLE_HAL_DSP */ + +#ifdef CONFIG_ENABLE_HAL_EPWM +/* Enhance PWM module */ +#include "hal_tim.h" +#endif /* CONFIG_ENABLE_HAL_EPWM */ + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Common/printf.c b/pec930_sdk-v1.0.1/Common/printf.c new file mode 100644 index 0000000..c27acb9 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/printf.c @@ -0,0 +1,1081 @@ +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. These routines are thread +// safe and reentrant! +// Use this instead of the bloated standard/newlib printf cause these use +// malloc for printf (and may not be thread safe). +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "printf.h" + +#if !defined(CONFIG_HAS_SYSLOG_FLOAT) + #define PRINTF_DISABLE_SUPPORT_FLOAT +#endif + +#define PRINTF_DISABLE_SUPPORT_EXPONENTIAL +#define PRINTF_DISABLE_SUPPORT_LONG_LONG +#define PRINTF_DISABLE_SUPPORT_PTRDIFF_T + +// define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the +// printf_config.h header file +// default: undefined +#ifdef PRINTF_INCLUDE_CONFIG_H +#include "printf_config.h" +#endif + +#if defined(__GNUC__) +#pragma GCC push_options +#pragma GCC optimize ("Os") +#endif + +// 'ntoa' conversion buffer size, this must be big enough to hold one converted +// numeric number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef PRINTF_NTOA_BUFFER_SIZE +#define PRINTF_NTOA_BUFFER_SIZE 32U +#endif + +// 'ftoa' conversion buffer size, this must be big enough to hold one converted +// float number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef PRINTF_FTOA_BUFFER_SIZE +#define PRINTF_FTOA_BUFFER_SIZE 32U +#endif + +// support for the floating point type (%f) +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_FLOAT +#define PRINTF_SUPPORT_FLOAT +#endif + +// support for exponential floating point notation (%e/%g) +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL +#define PRINTF_SUPPORT_EXPONENTIAL +#endif + +// define the default floating point precision +// default: 6 digits +#ifndef PRINTF_DEFAULT_FLOAT_PRECISION +#define PRINTF_DEFAULT_FLOAT_PRECISION 6U +#endif + +// define the largest float suitable to print with %f +// default: 1e9 +#ifndef PRINTF_MAX_FLOAT +#define PRINTF_MAX_FLOAT 1e9 +#endif + +// support for the long long types (%llu or %p) +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG +#define PRINTF_SUPPORT_LONG_LONG +#endif + +// support for the ptrdiff_t type (%t) +// ptrdiff_t is normally defined in as long or long long type +// default: activated +#ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T +#define PRINTF_SUPPORT_PTRDIFF_T +#endif + +/////////////////////////////////////////////////////////////////////////////// + +// internal flag definitions +#define FLAGS_ZEROPAD (1U << 0U) +#define FLAGS_LEFT (1U << 1U) +#define FLAGS_PLUS (1U << 2U) +#define FLAGS_SPACE (1U << 3U) +#define FLAGS_HASH (1U << 4U) +#define FLAGS_UPPERCASE (1U << 5U) +#define FLAGS_CHAR (1U << 6U) +#define FLAGS_SHORT (1U << 7U) +#define FLAGS_LONG (1U << 8U) +#define FLAGS_LONG_LONG (1U << 9U) +#define FLAGS_PRECISION (1U << 10U) +#define FLAGS_ADAPT_EXP (1U << 11U) + + +// import float.h for DBL_MAX +#if defined(PRINTF_SUPPORT_FLOAT) +#include +#endif + + +// output function type +typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); + + +// wrapper (used as buffer) for output function type +typedef struct +{ + void (*fct)(char character, void* arg); + void* arg; +} out_fct_wrap_type; + + +// internal buffer output +static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) +{ + if (idx < maxlen) + { + ((char*)buffer)[idx] = character; + } +} + + +// internal null output +static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)character; + (void)buffer; + (void)idx; + (void)maxlen; +} + + +// internal _putchar wrapper +static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)buffer; + (void)idx; + (void)maxlen; + if (character) + { + _putchar(character); + } +} + + +// internal output function wrapper +static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)idx; + (void)maxlen; + if (character) + { + // buffer is the output fct pointer + ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); + } +} + + +// internal secure strlen +// \return The length of the string (excluding the terminating 0) limited by 'maxsize' +static inline unsigned int _strnlen_s(const char* str, size_t maxsize) +{ + const char* s; + for (s = str; *s && maxsize--; ++s); + return (unsigned int)(s - str); +} + + +// internal test if char is a digit (0-9) +// \return true if char is a digit +static inline bool _is_digit(char ch) +{ + return (ch >= '0') && (ch <= '9'); +} + + +// internal ASCII string to unsigned int conversion +static unsigned int _atoi(const char** str) +{ + unsigned int i = 0U; + while (_is_digit(**str)) + { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; +} + + +// output the specified string in reverse, taking care of any zero-padding +static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags) +{ + const size_t start_idx = idx; + + // pad spaces up to given width + if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) + { + for (size_t i = len; i < width; i++) + { + out(' ', buffer, idx++, maxlen); + } + } + + // reverse string + while (len) + { + out(buf[--len], buffer, idx++, maxlen); + } + + // append pad spaces up to given width + if (flags & FLAGS_LEFT) + { + while (idx - start_idx < width) + { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; +} + + +// internal itoa format +static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) +{ + // pad leading zeros + if (!(flags & FLAGS_LEFT)) + { + if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) + { + width--; + } + while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + } + + // handle hash + if (flags & FLAGS_HASH) + { + if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) + { + len--; + if (len && (base == 16U)) + { + len--; + } + } + if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'x'; + } + else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'X'; + } + else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'b'; + } + if (len < PRINTF_NTOA_BUFFER_SIZE) + { + buf[len++] = '0'; + } + } + + if (len < PRINTF_NTOA_BUFFER_SIZE) + { + if (negative) + { + buf[len++] = '-'; + } + else if (flags & FLAGS_PLUS) + { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & FLAGS_SPACE) + { + buf[len++] = ' '; + } + } + + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} + + +// internal itoa for 'long' type +static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) + { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) + { + do + { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } + while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} + + +// internal itoa for 'long long' type +#if defined(PRINTF_SUPPORT_LONG_LONG) +static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) + { + flags &= ~FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & FLAGS_PRECISION) || value) + { + do + { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } + while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); + } + + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} +#endif // PRINTF_SUPPORT_LONG_LONG + + +#if defined(PRINTF_SUPPORT_FLOAT) + +#if defined(PRINTF_SUPPORT_EXPONENTIAL) +// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT +static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); +#endif + + +// internal ftoa for fixed decimal floating point +static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[PRINTF_FTOA_BUFFER_SIZE]; + size_t len = 0U; + double diff = 0.0; + + // powers of 10 + static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + + // test for special values + if (value != value) + return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); + if (value < -DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); + if (value > DBL_MAX) + return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); + + // test for very large values + // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad + if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) + { +#if defined(PRINTF_SUPPORT_EXPONENTIAL) + return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); +#else + return 0U; +#endif + } + + // test for negative + bool negative = false; + if (value < 0) + { + negative = true; + value = 0 - value; + } + + // set default precision, if not set explicitly + if (!(flags & FLAGS_PRECISION)) + { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; + } + // limit precision to 9, cause a prec >= 10 can lead to overflow errors + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) + { + buf[len++] = '0'; + prec--; + } + + int whole = (int)value; + double tmp = (value - whole) * pow10[prec]; + unsigned long frac = (unsigned long)tmp; + diff = tmp - frac; + + if (diff > 0.5) + { + ++frac; + // handle rollover, e.g. case 0.99 with prec 1 is 1.0 + if (frac >= pow10[prec]) + { + frac = 0; + ++whole; + } + } + else if (diff < 0.5) + { + } + else if ((frac == 0U) || (frac & 1U)) + { + // if halfway, round up if odd OR if last digit is 0 + ++frac; + } + + if (prec == 0U) + { + diff = value - (double)whole; + if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) + { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++whole; + } + } + else + { + unsigned int count = prec; + // now do fractional part, as an unsigned number + while (len < PRINTF_FTOA_BUFFER_SIZE) + { + --count; + buf[len++] = (char)(48U + (frac % 10U)); + if (!(frac /= 10U)) + { + break; + } + } + // add extra 0s + while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) + { + buf[len++] = '0'; + } + if (len < PRINTF_FTOA_BUFFER_SIZE) + { + // add decimal + buf[len++] = '.'; + } + } + + // do whole part, number is reversed + while (len < PRINTF_FTOA_BUFFER_SIZE) + { + buf[len++] = (char)(48 + (whole % 10)); + if (!(whole /= 10)) + { + break; + } + } + + // pad leading zeros + if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) + { + if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) + { + width--; + } + while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + } + + if (len < PRINTF_FTOA_BUFFER_SIZE) + { + if (negative) + { + buf[len++] = '-'; + } + else if (flags & FLAGS_PLUS) + { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & FLAGS_SPACE) + { + buf[len++] = ' '; + } + } + + return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} + + +#if defined(PRINTF_SUPPORT_EXPONENTIAL) +// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse +static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +{ + // check for NaN and special values + if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) + { + return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); + } + + // determine the sign + const bool negative = value < 0; + if (negative) + { + value = -value; + } + + // default precision + if (!(flags & FLAGS_PRECISION)) + { + prec = PRINTF_DEFAULT_FLOAT_PRECISION; + } + + // determine the decimal exponent + // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) + union + { + uint64_t U; + double F; + } conv; + + conv.F = value; + int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 + conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) + // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 + int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); + // now we want to compute 10^expval but we want to be sure it won't overflow + exp2 = (int)(expval * 3.321928094887362 + 0.5); + const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; + conv.U = (uint64_t)(exp2 + 1023) << 52U; + // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex + conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); + // correct for rounding errors + if (value < conv.F) + { + expval--; + conv.F /= 10; + } + + // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters + unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; + + // in "%g" mode, "prec" is the number of *significant figures* not decimals + if (flags & FLAGS_ADAPT_EXP) + { + // do we want to fall-back to "%f" mode? + if ((value >= 1e-4) && (value < 1e6)) + { + if ((int)prec > expval) + { + prec = (unsigned)((int)prec - expval - 1); + } + else + { + prec = 0; + } + flags |= FLAGS_PRECISION; // make sure _ftoa respects precision + // no characters in exponent + minwidth = 0U; + expval = 0; + } + else + { + // we use one sigfig for the whole part + if ((prec > 0) && (flags & FLAGS_PRECISION)) + { + --prec; + } + } + } + + // will everything fit? + unsigned int fwidth = width; + if (width > minwidth) + { + // we didn't fall-back so subtract the characters required for the exponent + fwidth -= minwidth; + } + else + { + // not enough characters, so go back to default sizing + fwidth = 0U; + } + if ((flags & FLAGS_LEFT) && minwidth) + { + // if we're padding on the right, DON'T pad the floating part + fwidth = 0U; + } + + // rescale the float value + if (expval) + { + value /= conv.F; + } + + // output the floating part + const size_t start_idx = idx; + idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); + + // output the exponent part + if (minwidth) + { + // output the exponential symbol + out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); + // output the exponent value + idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS); + // might need to right-pad spaces + if (flags & FLAGS_LEFT) + { + while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); + } + } + return idx; +} +#endif // PRINTF_SUPPORT_EXPONENTIAL +#endif // PRINTF_SUPPORT_FLOAT + + +// internal vsnprintf +static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) +{ + unsigned int flags, width, precision, n; + size_t idx = 0U; + + if (!buffer) + { + // use null output function + out = _out_null; + } + + while (*format) + { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') + { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } + else + { + // yes, evaluate it + format++; + } + + // evaluate flags + flags = 0U; + do + { + switch (*format) + { + case '0': + flags |= FLAGS_ZEROPAD; + format++; + n = 1U; + break; + case '-': + flags |= FLAGS_LEFT; + format++; + n = 1U; + break; + case '+': + flags |= FLAGS_PLUS; + format++; + n = 1U; + break; + case ' ': + flags |= FLAGS_SPACE; + format++; + n = 1U; + break; + case '#': + flags |= FLAGS_HASH; + format++; + n = 1U; + break; + default : + n = 0U; + break; + } + } + while (n); + + // evaluate width field + width = 0U; + if (_is_digit(*format)) + { + width = _atoi(&format); + } + else if (*format == '*') + { + const int w = va_arg(va, int); + if (w < 0) + { + flags |= FLAGS_LEFT; // reverse padding + width = (unsigned int)-w; + } + else + { + width = (unsigned int)w; + } + format++; + } + + // evaluate precision field + precision = 0U; + if (*format == '.') + { + flags |= FLAGS_PRECISION; + format++; + if (_is_digit(*format)) + { + precision = _atoi(&format); + } + else if (*format == '*') + { + const int prec = (int)va_arg(va, int); + precision = prec > 0 ? (unsigned int)prec : 0U; + format++; + } + } + + // evaluate length field + switch (*format) + { + case 'l' : + flags |= FLAGS_LONG; + format++; + if (*format == 'l') + { + flags |= FLAGS_LONG_LONG; + format++; + } + break; + case 'h' : + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') + { + flags |= FLAGS_CHAR; + format++; + } + break; +#if defined(PRINTF_SUPPORT_PTRDIFF_T) + case 't' : + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; +#endif + case 'j' : + flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + case 'z' : + flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + default : + break; + } + + // evaluate specifier + switch (*format) + { + case 'd' : + case 'i' : + case 'u' : + case 'x' : + case 'X' : + case 'o' : + case 'b' : + { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') + { + base = 16U; + } + else if (*format == 'o') + { + base = 8U; + } + else if (*format == 'b') + { + base = 2U; + } + else + { + base = 10U; + flags &= ~FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') + { + flags |= FLAGS_UPPERCASE; + } + + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) + { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } + + // ignore '0' flag when precision is given + if (flags & FLAGS_PRECISION) + { + flags &= ~FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) + { + // signed + if (flags & FLAGS_LONG_LONG) + { +#if defined(PRINTF_SUPPORT_LONG_LONG) + const long long value = va_arg(va, long long); + idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); +#endif + } + else if (flags & FLAGS_LONG) + { + const long value = va_arg(va, long); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + else + { + const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + } + else + { + // unsigned + if (flags & FLAGS_LONG_LONG) + { +#if defined(PRINTF_SUPPORT_LONG_LONG) + idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); +#endif + } + else if (flags & FLAGS_LONG) + { + idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); + } + else + { + const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); + idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); + } + } + format++; + break; + } +#if defined(PRINTF_SUPPORT_FLOAT) + case 'f' : + case 'F' : + if (*format == 'F') flags |= FLAGS_UPPERCASE; + idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; +#if defined(PRINTF_SUPPORT_EXPONENTIAL) + case 'e': + case 'E': + case 'g': + case 'G': + if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; + if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; + idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; +#endif // PRINTF_SUPPORT_EXPONENTIAL +#endif // PRINTF_SUPPORT_FLOAT + case 'c' : + { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 's' : + { + const char* p = va_arg(va, char*); + unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1); + // pre padding + if (flags & FLAGS_PRECISION) + { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) + { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 'p' : + { + width = sizeof(void*) * 2U; + flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; +#if defined(PRINTF_SUPPORT_LONG_LONG) + const bool is_ll = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) + { + idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); + } + else + { +#endif + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); +#if defined(PRINTF_SUPPORT_LONG_LONG) + } +#endif + format++; + break; + } + + case '%' : + out('%', buffer, idx++, maxlen); + format++; + break; + + default : + out(*format, buffer, idx++, maxlen); + format++; + break; + } + } + + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + + // return written chars without terminating \0 + return (int)idx; +} + + +/////////////////////////////////////////////////////////////////////////////// + +int sys_printf(const char* format, ...) +{ + va_list va; + va_start(va, format); + char buffer[1]; + const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +int sys_sprintf(char* buffer, const char* format, ...) +{ + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +int sys_snprintf(char* buffer, size_t count, const char* format, ...) +{ + va_list va; + va_start(va, format); + const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); + va_end(va); + return ret; +} + + +int sys_vprintf(const char* format, va_list va) +{ + char buffer[1]; + return _vsnprintf(_out_char, buffer, (size_t)-1, format, va); +} + + +int sys_vsnprintf(char* buffer, size_t count, const char* format, va_list va) +{ + return _vsnprintf(_out_buffer, buffer, count, format, va); +} + + +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) +{ + va_list va; + va_start(va, format); + const out_fct_wrap_type out_fct_wrap = { out, arg }; + const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); + va_end(va); + return ret; +} + + +#if defined(__GNUC__) +#pragma GCC pop_options +#endif \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Common/printf.h b/pec930_sdk-v1.0.1/Common/printf.h new file mode 100644 index 0000000..9e13287 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/printf.h @@ -0,0 +1,116 @@ +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. +// Use this instead of bloated standard/newlib printf. +// These routines are thread safe and reentrant. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _PRINTF_H_ +#define _PRINTF_H_ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Output a character to a custom device like UART, used by the printf() function + * This function is declared here only. You have to write your custom implementation somewhere + * \param character Character to output + */ +void _putchar(char character); + + +/** + * Tiny printf implementation + * You have to implement _putchar if you use printf() + * To avoid conflicts with the regular printf() API it is overridden by macro defines + * and internal underscore-appended functions like printf_() are used + * \param format A string that specifies the format of the output + * \return The number of characters that are written into the array, not counting the terminating null character + */ +#define printf sys_printf +int sys_printf(const char* format, ...); + + +/** + * Tiny sprintf implementation + * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! + * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! + * \param format A string that specifies the format of the output + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ +#define sprintf sys_sprintf +int sys_sprintf(char* buffer, const char* format, ...); + + +/** + * Tiny snprintf/vsnprintf implementation + * \param buffer A pointer to the buffer where to store the formatted string + * \param count The maximum number of characters to store in the buffer, including a terminating null character + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + * If the formatted string is truncated the buffer size (count) is returned + */ +#define snprintf sys_snprintf +#define vsnprintf sys_vsnprintf +int sys_snprintf(char* buffer, size_t count, const char* format, ...); +int sys_vsnprintf(char* buffer, size_t count, const char* format, va_list va); + + +/** + * Tiny vprintf implementation + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ +#define vprintf sys_vprintf +int sys_vprintf(const char* format, va_list va); + + +/** + * printf with output function + * You may use this as dynamic alternative to printf() with its fixed _putchar() output + * \param out An output function which takes one character and an argument pointer + * \param arg An argument pointer for user data passed to output function + * \param format A string that specifies the format of the output + * \return The number of characters that are sent to the output function, not counting the terminating null character + */ +int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); + + +#ifdef __cplusplus +} +#endif + + +#endif // _PRINTF_H_ diff --git a/pec930_sdk-v1.0.1/Common/syslog.c b/pec930_sdk-v1.0.1/Common/syslog.c new file mode 100644 index 0000000..5c70b48 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/syslog.c @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file syslog.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_LOG_MSG_DEVICE UART0 +#define CONFIG_LOG_DEVICE_TX_IO_PORTx GPIOA +#define CONFIG_LOG_DEVICE_TX_IO_PINx GPIO_Pin_15 +#define CONFIG_LOG_DEVICE_TX_IO_AF GPIO_AF_1 +#define CONFIG_LOG_DEVICE_RESET() __HAL_SYSCFG_RESET_UART0() +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void _putchar(char character) +{ + UART_SendData(CONFIG_LOG_MSG_DEVICE, character); + UART_WaitTxFifoEmpty(CONFIG_LOG_MSG_DEVICE); + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +void syslog_init(void) +{ + GPIO_InitTypeDef gpio_init = {0}; + UART_InitTypeDef uart_init = {0}; + + /* configure GPIO Pin mux of UART Tx */ + gpio_init.GPIO_Pin = CONFIG_LOG_DEVICE_TX_IO_PINx; + gpio_init.GPIO_AF_Mode = CONFIG_LOG_DEVICE_TX_IO_AF; + gpio_init.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init(CONFIG_LOG_DEVICE_TX_IO_PORTx, &gpio_init); + + uart_init.BaudRate = SLOG_SERIAL_BPS; + uart_init.WordLength = UART_WordLength_8b; + uart_init.StopBits = UART_StopBits_1; + uart_init.Parity = UART_Parity_No; + uart_init.Mode = UART_Mode_TxRx; + UART_Init(CONFIG_LOG_MSG_DEVICE, &uart_init); + + UART_Start(CONFIG_LOG_MSG_DEVICE); + return; +} + +void syslog_deinit(void) +{ + GPIO_DeInit(CONFIG_LOG_DEVICE_TX_IO_PORTx, CONFIG_LOG_DEVICE_TX_IO_PINx); + CONFIG_LOG_DEVICE_RESET(); + return; +} + +void +syslog_dump_mem( + char *prefix, + uint32_t *pAddr, + int bytes, + int has_out_u32le) +{ + if( has_out_u32le ) + { + uintptr_t addr = (uintptr_t)pAddr; + uint32_t cnt = (bytes + 0x3) >> 2; + uint32_t *pCur = (uint32_t*)pAddr; + + for(int i = 0; i < cnt; i++) + { + if( (i & 0x3) == 2 ) + printf(" -"); + else if( !(i & 0x3) ) + { + printf("\n%s%08X |", prefix, addr); + addr += 16; + } + + printf(" %08X", pCur[i]); + } + printf("\n\n"); + } + else + { + uintptr_t addr = (uintptr_t)pAddr; + uint8_t *pCur = (uint8_t*)pAddr; + + for(int i = 0; i < bytes; i++) + { + if( (i & 0xF) == 8 ) + printf(" -"); + else if( !(i & 0xF) ) + { + printf("\n%s%08X |", prefix, addr); + addr += 16; + } + + printf(" %02X", pCur[i]); + } + printf("\n\n"); + } + + return; +} diff --git a/pec930_sdk-v1.0.1/Common/syslog.h b/pec930_sdk-v1.0.1/Common/syslog.h new file mode 100644 index 0000000..7ae4708 --- /dev/null +++ b/pec930_sdk-v1.0.1/Common/syslog.h @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file syslog.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __syslog_H_wWjHKLEN_l9U5_H1mZ_sZEW_uX5M5YmrWbVp__ +#define __syslog_H_wWjHKLEN_l9U5_H1mZ_sZEW_uX5M5YmrWbVp__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "printf.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * System Log message through uart with baudrate 'SLOG_SERIAL_BPS' + */ +#define SLOG_SERIAL_BPS 115200 + +#define SLOG_BLACK "\033[30m" +#define SLOG_RED "\033[31m" +#define SLOG_GREEN "\033[32m" +#define SLOG_YELLOW "\033[33m" +#define SLOG_BLUE "\033[34m" +#define SLOG_MAGENTA "\033[35m" +#define SLOG_CYAN "\033[36m" +#define SLOG_WHITE "\033[97m" +#define SLOG_DEFAULT "\033[39m" +#define SLOG_RESET "\033[m" + +#define SLOG_RED2 "\33[91m" +#define SLOG_GREEN2 "\33[92m" +#define SLOG_YELLOW2 "\33[93m" +#define SLOG_BLUE2 "\33[94m" +#define SLOG_VIOLET2 "\33[95m" +#define SLOG_BEIGE2 "\33[96m" +//============================================================================= +// Macro Definition +//============================================================================= +#define stringize(s) #s +#define _toStr(a) stringize(a) + +#define err(str, ...) printf(SLOG_RED "[error] " str SLOG_RESET, ##__VA_ARGS__) + +#if defined(NDEBUG) + /* release */ + #define info(str, ...) + #define msg(str, ...) + #define dbg(str, ...) + #define log_color(COLOR, str, ...) + +#else + #define info(str, ...) printf(SLOG_YELLOW str SLOG_RESET, ##__VA_ARGS__) + #define msg(str, ...) printf(str, ##__VA_ARGS__) + #define dbg(str, ...) printf(str, ##__VA_ARGS__) + #define log_color(COLOR, str, ...) printf(COLOR str SLOG_RESET, ##__VA_ARGS__) +#endif /* NDEBUG */ +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void syslog_init(void); +void syslog_deinit(void); + +/** + * \brief Dump memory data through system log + * + * \param [in] prefix the prefix text + * \param [in] pAddr the target memory address + * \param [in] bytes the dumped length + * \param [in] has_out_u32le layout with 32-bits little-endian or not + * \return + * None + */ +void +syslog_dump_mem( + char *prefix, + uint32_t *pAddr, + int bytes, + int has_out_u32le); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Docs/.DS_Store b/pec930_sdk-v1.0.1/Docs/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..68f3fb351fc70e39e7fe4b40d0415a04b2814cde GIT binary patch literal 6148 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�+phF@-o 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 literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Docs/image/IDE_close_proj.jpg b/pec930_sdk-v1.0.1/Docs/image/IDE_close_proj.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e4ad8501410184c97a3471e2384349796d91167a GIT binary patch literal 102048 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%0DfdPoK*?qT+I| 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 NF@m-FT*zOe{{xZlElL0Y literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Docs/image/IDE_debug_view.jpg b/pec930_sdk-v1.0.1/Docs/image/IDE_debug_view.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4f9927e350fbab1a637d8adfd8ef41bbf0342744 GIT binary patch literal 253694 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¬$4>mz)(R5)AO8;=U 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

p2Pe8-tc8H;jOj=e@H+&nY?`(qhEgC4h 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 z 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�GMd=FO3%{*C=|v;QtS%YFFI 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

  • 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 literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Docs/image/IDE_delet_recent_proj.jpg b/pec930_sdk-v1.0.1/Docs/image/IDE_delet_recent_proj.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c88038d99faf2c26086d30a70b27cc625164dbe5 GIT binary patch literal 89068 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
    RiTiJ!|2Az~Z13rT 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%0AsoXZtP#*WL;oWM&SS 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 Kvi!XFy?+AA0JtFl literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_with_resp.png b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_with_resp.png new file mode 100644 index 0000000000000000000000000000000000000000..a38efb22e769c351136deff734edbedaa7bcb12f GIT binary patch literal 49879 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¨QQduzitE- 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 literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/ice_unlock.h b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/ice_unlock.h new file mode 100644 index 0000000..ad69063 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/ice_unlock.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2025 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file ice_unlock.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2026/01/12 + * @license + * @description + */ + +#ifndef __ice_unlock_H_wHRIfKCc_lrgE_Hco5_sCMI_uyqVOtiS2itE__ +#define __ice_unlock_H_wHRIfKCc_lrgE_Hco5_sCMI_uyqVOtiS2itE__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_device.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * \brief Detect the authentic key in ISR + * The authentic key are made up of the specific 2-PINs of GPIO module + * \return + * error code + */ +void ICP_ITDetectAuthKey(GPIO_Type *pDat_port, GPIO_PinTypeDef dat_pin); + +/** + * \brief The authentication procedure which enable debug mode or not + * + * \return + * error code + */ +void ICP_AuthDProcedure(void); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/isr.h b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/main.h b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/main.h new file mode 100644 index 0000000..abc0093 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/inc/main.h @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * + NVR area + */ +#define FLASH_PROG_NVR_ADDR_START NVR_MEM_BASE + +// ignore the last sector (record flash paraments) of NVR +#define FLASH_PROG_NVR_ADDR_END (NVR_MEM_BASE + sizeof(NVR_MEM_Type) - FLASH_1_SECTOR_SIZE) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/readme.md b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/readme.md new file mode 100644 index 0000000..bd49385 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/readme.md @@ -0,0 +1,132 @@ +sys_ice_unlock_lib +--- + +This project is used to implement `Unlock-ICE` mechanism with the specific external device +> The system clock of the DUT is `60 MHz` + +## Behavior of this example + ++ Select the target I/O Pins + + - Use the ICE I/O Pins + + ```c + // at main.c + #define CONIFG_USE_ICE_IO 1 + ``` + + - Use the customization I/O Pins + + ```c + // at main.c + #define CONIFG_USE_ICE_IO 0 + ... + // the target pin definitions + #define CONFIG_TCLK_PORT GPIOA + #define CONFIG_TCLK_PIN GPIO_Pin_00 + #define CONFIG_TCLK_IRQ GPIOA_IRQn + #define CONFIG_TMSC_PORT GPIOA + #define CONFIG_TMSC_PIN GPIO_Pin_01 + ``` + ++ Select an I/O pin (as Key event) to trigger Core-Procedure + > This key event will disable ICE I/O run-time and then ICE will disconnect with Host + >> User should be carefully + + ```c + /* Input Key I/O definitions (Wake-up Key when I/O wakup case) */ + #define CONFIG_GPIO_INPUT_PORTx GPIOA + #define CONFIG_GPIO_INPUT_PINx GPIO_Pin_03 + #define CONFIG_GPIO_INPUT_IRQn GPIOA_IRQn + ``` + ++ Log + + ``` + Jan 23 2026 10:57:17 + Demo to Unlcok-ICE + Button = PA3 + Wait event to unlock ICE ... <--- trigger key event and wait to receive signal + ``` + +## Conidtion + ++ Disable the ICE function with software detection + + - User should open the code section with compile option + + ``` + // at pec930_sdk/Drivers/PEC930/Device/src/Startup/startup.S + #if 1 + /* Disable/Enable ICE I/O */ + ... + + #endif + ``` + + - User modifies the `ICE_PIN_DIS tag (32-bits value and address: 0x00201C28)` of the SysInfo sector of NVR + > + when the value of **ICE_PIN_DIS tag (Address:0x0020-1C28)** is `0x00000000`, DUT will `LOCK ICE` function + > + when the value of **ICE_PIN_DIS tag (Address:0x0020-1C28)** is `0xFFFFFFFF`, DUT will `Un-LOCK ICE` function + ++ It uses the specific 2-PINs (`TCK/TMS Pins of cJTag`) to dedicatedly receive signals + > The specific 2-PINs `CAN NOT` be used as other usage + ++ User MUST add the specific APIs to their APP by self + > + `ICP_ITDetectAuthKey()` to detect the signals of `2-PINs` + > + `ICP_AuthDProcedure()` to handle the procedure of Unlock-ICE + + ++ Resource + - It uses code size about `514-Bytes` + > + `ICP_ITDetectAuthKey()` + > + `ICP_AuthDProcedure()` + + - Some variables (on SRAM) are about `60-Bytes` + +## Flow + ++ DUT uses input interrupt of a GPIO module to run-time receive signals + - Run-time check the signals are proprietary protocol or not (in ISR) + - DUT (receiver) latches the data signal when the `Falling-edge` of the clock signal + > The transmitter prepares data when `Rising-edge` of the clock signal + + - The transmitter should support programmable frequency (**20 ~ 200 KHz**) of output clock signal + > The DUT receiving performance is dependent on the complexity of user's appliecation + ++ When the external signals fit the specific waveform, DUT enters the `Unlock-ICE` process + + - The specific waveform + > Transmitter keeps clock/data signals **high** after the specific waveform + + ![unlock_ice_waveform](./image/pec930_unlock_ice_waveform.jpg) + + 1. An example of the transmitter outputs clock signal at `170 KHz` + > + The green line is clock signal + > + The orange line is data signal + + ![pec930_unlock_ice_waveform_1xxKHz](./image/pec930_unlock_ice_waveform_1xxKHz.png) + + - DUT modifies the sysinfo to `Unlock-ICE` + > It should reserve `512-Bytes` buffer to keep the original data of sysinfo + + - DUT destroys the main-erea of eFlash + + - DUT call the specific reset (e.g. reboot-latch) or be re-powered on by the external device + + ++ The DUT (receiver) responds the specific signal through TMS pin (**16-times Falling-edge**) to transmitter after `Unlock-ICE` process is done + > The frequency of response signal is about `25 KHz` (when the DUT system clock is `60 MHz`) + > ![pec930_unlock_ice_dut_resp](./image/pec930_unlock_ice_dut_resp.png) + + - Transmitter MUST change the I/O direction of the data signal to receive the response of the DUT (receiver) + > The sequence diagram is as below + > ![pec930_SW_unlock_ICE_time_slot_resp](./image/pec930_SW_unlock_ICE_time_slot_resp.jpg) + + - The duration of DUT (receiver) Unlock-ICE process will be less then `100 msec` (when the DUT system clock is `60 MHz`) + > As below: `35128/1M => 36 msec` + + ![pec930_unlock_ice_waveform_with_resp](./image/pec930_unlock_ice_waveform_with_resp.png) + + 1. The unlock-ICE-process spent about `35 msec` + + ![pec930_unlock_ice_working_time](./image/pec930_unlock_ice_working_time.png) diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/isr.c b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/main.c b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/main.c new file mode 100644 index 0000000..53c1f4b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/src/main.c @@ -0,0 +1,174 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include +#include +#include "main.h" +#include "isr.h" + +#include "ice_unlock.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONIFG_USE_ICE_IO 0 + +#if defined(CONIFG_USE_ICE_IO) && (CONIFG_USE_ICE_IO) + #define CONFIG_TCLK_PORT GPIOB + #define CONFIG_TCLK_PIN GPIO_Pin_02 + #define CONFIG_TCLK_IRQ GPIOB_IRQn + #define CONFIG_TMSC_PORT GPIOB + #define CONFIG_TMSC_PIN GPIO_Pin_04 +#else + #define CONFIG_TCLK_PORT GPIOA + #define CONFIG_TCLK_PIN GPIO_Pin_00 + #define CONFIG_TCLK_IRQ GPIOA_IRQn + #define CONFIG_TMSC_PORT GPIOA + #define CONFIG_TMSC_PIN GPIO_Pin_01 +#endif + + +/* Input Key I/O definitions (Wake-up Key when I/O wakup case) */ +#define CONFIG_GPIO_INPUT_PORTx GPIOA +#define CONFIG_GPIO_INPUT_PINx GPIO_Pin_03 +#define CONFIG_GPIO_INPUT_IRQn GPIOA_IRQn + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static bool g_has_key_event = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + // Button Pin + if( GPIO_GetITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx) ) + { + GPIO_ClearITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + g_has_key_event = true; + } + + // ICE-CLK Pin + if( GPIO_GetITFlag(CONFIG_TCLK_PORT, CONFIG_TCLK_PIN) ) + { + GPIO_ClearITFlag(CONFIG_TCLK_PORT, CONFIG_TCLK_PIN); + + // ICE-Data Pin + ICP_ITDetectAuthKey(CONFIG_TMSC_PORT, CONFIG_TMSC_PIN); + } + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +static void _Config_ButtonIO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + msg(" Button = P%s%d\n", + (CONFIG_GPIO_INPUT_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_GPIO_INPUT_PINx)); + + GPIO_InitStruct.GPIO_Pin = CONFIG_GPIO_INPUT_PINx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN ; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Level; + GPIO_InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_GPIO_INPUT_PORTx, &GPIO_InitStruct); + + GPIO_ITEnable(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(CONFIG_GPIO_INPUT_IRQn, GPIOx_Handler, &irq_attr); + return; +} + +static int _Config_ICE_IO(void) +{ + GPIO_InitTypeDef Init = {0}; + +#if defined(CONIFG_USE_ICE_IO) && (CONIFG_USE_ICE_IO) + SYSCFG_SetICEPin2NormalIO(true); +#endif + + Init.GPIO_Pin = CONFIG_TMSC_PIN; + Init.GPIO_Mode = GPIO_Mode_IN ; + Init.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(CONFIG_TMSC_PORT , &Init); + + Init.GPIO_Pin = CONFIG_TCLK_PIN; + Init.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Edge; + Init.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_TCLK_PORT , &Init); + + GPIO_ITEnable(CONFIG_TCLK_PORT, CONFIG_TCLK_PIN); + + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_M; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(CONFIG_TCLK_IRQ, GPIOx_Handler, &irq_attr); + + return 0; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nDemo to Unlcok-ICE\n", __DATE__, __TIME__); + + _Config_ButtonIO(); + + g_has_key_event = false; + + while(1) + { + ICP_AuthDProcedure(); + + if( g_has_key_event == true ) + { + msg(" Wait event to unlock ICE ...\n"); + g_has_key_event = false; + _Config_ICE_IO(); + } + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/.cproject b/pec930_sdk-v1.0.1/Examples/system/sys_mco/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/.project b/pec930_sdk-v1.0.1/Examples/system/sys_mco/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/Project.nuproject b/pec930_sdk-v1.0.1/Examples/system/sys_mco/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/component.mk b/pec930_sdk-v1.0.1/Examples/system/sys_mco/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/isr.h b/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/main.h b/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/readme.md b/pec930_sdk-v1.0.1/Examples/system/sys_mco/readme.md new file mode 100644 index 0000000..f1f8d1e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/readme.md @@ -0,0 +1,33 @@ +system mco +--- + +This example is used to run system mco function. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Run the example ++ GPIO Pin pa2 selection mco output mode ++ GPIO Pin pa14 selection mco output + +## Log +Use serial port(pa15) with baudrate 115200, 8bit, no parity check. + +``` +Sep 30 2025 09:28:41 +This is a demo to output MCO signal (SysCLK= 60000000) + Press bottun to change output type (PA2) + No Output + MCO output HSI + MCO output LSI + MCO output HSI-DIV + No Output + +``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/isr.c b/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/main.c b/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/main.c new file mode 100644 index 0000000..a2ed8d6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_mco/src/main.c @@ -0,0 +1,184 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_BUTTON_PORT GPIOA +#define CONFIG_BUTTON_PIN GPIO_Pin_02 +#define CONFIG_BUTTON_IRQ GPIOA_IRQn + + +#define CONFIG_MCO_PORT GPIOA +#define CONFIG_MCO_PIN GPIO_Pin_14 +#define CONFIG_MCO_AF GPIO_AF_6 + +typedef enum mco_out +{ + MCO_OUT_NONE = SYSCFG_MCOCR_MCOSEL_GND << SYSCFG_MCOCR_MCOSEL_Pos, + MCO_OUT_HSI = SYSCFG_MCOCR_MCOSEL_HSI << SYSCFG_MCOCR_MCOSEL_Pos, + MCO_OUT_HSE = SYSCFG_MCOCR_MCOSEL_HSE << SYSCFG_MCOCR_MCOSEL_Pos, + MCO_OUT_HSI_DIV = SYSCFG_MCOCR_MCOSEL_CLKDIV << SYSCFG_MCOCR_MCOSEL_Pos, + MCO_OUT_LSI = SYSCFG_MCOCR_MCOSEL_LSI << SYSCFG_MCOCR_MCOSEL_Pos, +} mco_out_t; + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct mco_attr +{ + mco_out_t out_type; + char description[64]; +} mco_attr_t; + + +static mco_attr_t g_mco_attr[] = +{ + { .out_type = MCO_OUT_NONE, .description = "No Output" }, + { .out_type = MCO_OUT_HSI, .description = "MCO output HSI" }, + { .out_type = MCO_OUT_LSI, .description = "MCO output LSI" }, + { .out_type = MCO_OUT_HSI_DIV, .description = "MCO output HSI-DIV" }, + +#if 0 + { .out_type = MCO_OUT_HSE, .description = "MCO output HSE" }, +#endif +}; +//============================================================================= +// Global Data Definition +//============================================================================= +static bool g_IsButtonPress = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + if( GPIO_GetITFlag(CONFIG_BUTTON_PORT, CONFIG_BUTTON_PIN) ) + { + GPIO_ClearITFlag(CONFIG_BUTTON_PORT, CONFIG_BUTTON_PIN); + + g_IsButtonPress = true; + } + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +static void _Config_Button(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_BUTTON_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN ; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Level; + GPIO_InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_MCO_PORT , &GPIO_InitStruct); + + do { + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_BUTTON_IRQ, GPIOx_Handler, &irq_attr); + } while(0); + + /* Enable GPIO interrupt */ + GPIO_ITConfig(CONFIG_MCO_PORT, CONFIG_BUTTON_PIN, &GPIO_InitStruct.GPIO_ITInit); + GPIO_ITEnable(CONFIG_MCO_PORT, CONFIG_BUTTON_PIN); + + + return; +} + +static void _Config_MCO_IO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_MCO_PIN; + GPIO_InitStruct.GPIO_AF_Mode = CONFIG_MCO_AF; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + + GPIO_Init(CONFIG_MCO_PORT, &GPIO_InitStruct); + return; +} + + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + do{ /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + #if 1 + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + #else + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv2; + #endif + SYSCFG_SysClkConfig(&SysClkInit); + } while(0); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nThis is a demo to output MCO signal (SysCLK= %d)\n", + __DATE__, __TIME__, (int)sys_get_cpu_freq()); + + msg(" Press bottun to change output type (P%s%d)\n", + (CONFIG_BUTTON_PORT == GPIOA) ? "A" : "B", + (31 - HAL_CLZ(CONFIG_BUTTON_PIN))); + + g_IsButtonPress = false; + + SYSCFG->MCOCR_b.MCOSEL = SYSCFG_MCOCR_MCOSEL_GND; + SYSCFG->MCOCR_b.DivEn = 0; + SYSCFG->MCOCR_b.DivSel = 0; + SYSCFG->MCOCR_b.Divider = 1; + + _Config_Button(); + + _Config_MCO_IO(); + + while(1) + { + static int mco_index = 0; + + if( g_IsButtonPress == false ) + { + __NOP(); + continue; + } + + g_IsButtonPress = false; + + mco_index = (mco_index == (sizeof(g_mco_attr)/sizeof(g_mco_attr[0]))) + ? 0 : mco_index; + + SYSCFG->MCOCR_b.MCOSEL = (g_mco_attr[mco_index].out_type == MCO_OUT_HSI) ? SYSCFG_MCOCR_MCOSEL_HSI : + (g_mco_attr[mco_index].out_type == MCO_OUT_LSI) ? SYSCFG_MCOCR_MCOSEL_LSI : + (g_mco_attr[mco_index].out_type == MCO_OUT_HSI_DIV) ? SYSCFG_MCOCR_MCOSEL_CLKDIV : + SYSCFG_MCOCR_MCOSEL_GND; + + msg(" %s\n", g_mco_attr[mco_index].description); + + mco_index++; + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.cproject b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.project b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/Project.nuproject b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/component.mk b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/isr.h b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/main.h b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/readme.md b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/readme.md new file mode 100644 index 0000000..6af3cb8 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/readme.md @@ -0,0 +1,210 @@ +sys_tick_swi +--- + +This example is used to configure ECLIC module +> + Support to register the proprietary ISR for specific requirement. +> + Support programmable IRQ-Level +>> reference `sys_irq_level_t` + +> + Support programmable IRQ-Priority +>> reference `sys_irq_priority_t` + + ++ Configure SWI (Software Interupt) level + > The default level of system timer is `SYS_IRQ_LEVEL_L` + + ```c + // at main.c + /** + * The defualt level of system timer is SYS_IRQ_LEVEL_L + * ps. SYS_IRQ_LEVEL_LL/ SYS_IRQ_LEVEL_L/ SYS_IRQ_LEVEL_M + */ + #define CONFIG_IRQ_SWI_LEVEL SYS_IRQ_LEVEL_L + ``` + + - Use `sys_register_IRQ()` to re-configure attributes of an interrupt + + ```c + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(SysTimer_IRQn, _mtim_handler, &irq_attr); + ``` + ++ This example use message (in ISR) to figure out the relation of Level/Priority of ECLIC + > Logging message in ISR is misbehavior + + - For logging message, the period of system tick MUST be more then `1-msec` + + ``` + // at main.c, + /* The period MUST be more then 1 msec */ + sys_config_systick(SYS_TICK_10_MS); + ``` + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ If SWI level is equal to system timer + >```c + > // at main.c + > #define CONFIG_IRQ_SWI_LEVEL SYS_IRQ_LEVEL_L + > + > #define CONFIG_IRQ_SWI_PRIORITY SYS_IRQ_PRIORITY_MIDDEN + > ``` + + - Priority is the same + + ``` + Feb 20 2025 12:42:39 + This is a demo projec to configure ECLIC (IRQ Level: SWI == SysTim, Priority: SWI == SysTim) + -> _mtim_handler 0-th <--- enter ISR of system timer + <- _mtim_handler <--- leave system timer + => _mswi_handler 1-th <--- enter ISR of SWI (wait for system timer finish) + <= _mswi_handler <--- leave SWI + -> _mtim_handler 1-th + <- _mtim_handler + => _mswi_handler 2-th + <= _mswi_handler + -> _mtim_handler 2-th + <- _mtim_handler + => _mswi_handler 3-th + <= _mswi_handler + -> _mtim_handler 3-th + <- _mtim_handler + => _mswi_handler 4-th + <= _mswi_handler + -> _mtim_handler 4-th + <- _mtim_handler + => _mswi_handler 5-th + <= _mswi_handler + done~~~ + ``` + + - If SWI priority is greater then system timer + + ``` + Feb 20 2025 12:40:04 + This is a demo projec to configure ECLIC (IRQ Level: SWI == SysTim, Priority: SWI > SysTim) + -> _mtim_handler 0-th <--- enter ISR of system timer + <- _mtim_handler <--- leave system timer + => _mswi_handler 1-th <--- enter ISR of SWI (wait for system timer finish) + <= _mswi_handler <--- leave SWI + -> _mtim_handler 1-th + <- _mtim_handler + => _mswi_handler 2-th + <= _mswi_handler + -> _mtim_handler 2-th + <- _mtim_handler + => _mswi_handler 3-th + <= _mswi_handler + -> _mtim_handler 3-th + <- _mtim_handler + => _mswi_handler 4-th + <= _mswi_handler + -> _mtim_handler 4-th + <- _mtim_handler + => _mswi_handler 5-th + <= _mswi_handler + done~~~ + ``` + + - If SWI priority is lower then system timer + + ``` + Feb 20 2025 12:44:14 + This is a demo projec to configure ECLIC (IRQ Level: SWI == SysTim, Priority: SWI < SysTim) + -> _mtim_handler 0-th <--- enter ISR of system timer + <- _mtim_handler <--- leave system timer + => _mswi_handler 1-th <--- enter ISR of SWI (wait for system timer finish) + <= _mswi_handler <--- leave SWI + -> _mtim_handler 1-th + <- _mtim_handler + => _mswi_handler 2-th + <= _mswi_handler + -> _mtim_handler 2-th + <- _mtim_handler + => _mswi_handler 3-th + <= _mswi_handler + -> _mtim_handler 3-th + <- _mtim_handler + => _mswi_handler 4-th + <= _mswi_handler + -> _mtim_handler 4-th + <- _mtim_handler + => _mswi_handler 5-th + <= _mswi_handler + done~~~ + ``` + ++ If SWI level is greater than system timer + >```c + > // at main.c + > #define CONFIG_IRQ_SWI_LEVEL SYS_IRQ_LEVEL_M + > + > #define CONFIG_IRQ_SWI_PRIORITY SYS_IRQ_PRIORITY_MIDDEN + > ``` + + ``` + Feb 20 2025 12:45:53 + This is a demo projec to configure ECLIC (IRQ Level: SWI > SysTim, Priority: SWI == SysTim) + -> _mtim_handler 0-th <--- enter ISR of system timer + => _mswi_handler 1-th <--- Nested interrupt by SWI + <= _mswi_handler <--- leave SWI + <- _mtim_handler <--- leave system timer + -> _mtim_handler 1-th + => _mswi_handler 2-th + <= _mswi_handler + <- _mtim_handler + -> _mtim_handler 2-th + => _mswi_handler 3-th + <= _mswi_handler + <- _mtim_handler + -> _mtim_handler 3-th + => _mswi_handler 4-th + <= _mswi_handler + <- _mtim_handler + -> _mtim_handler 4-th + => _mswi_handler 5-th + <= _mswi_handler + <- _mtim_handler + done~~~ + ``` + ++ If SWI level is lower then system timer + >```c + > // at main.c + > #define CONFIG_IRQ_SWI_LEVEL SYS_IRQ_LEVEL_LL + > + > #define CONFIG_IRQ_SWI_PRIORITY SYS_IRQ_PRIORITY_MIDDEN + > ``` + + ``` + Feb 20 2025 12:47:11 + This is a demo projec to configure ECLIC (IRQ Level: SWI < SysTim, Priority: SWI == SysTim) + -> _mtim_handler 0-th <--- enter ISR of system timer + <- _mtim_handler <--- leave system timer + => _mswi_handler 1-th <--- enter ISR of SWI (wait for system timer finish) + <= _mswi_handler <--- leave SWI + -> _mtim_handler 1-th + <- _mtim_handler + => _mswi_handler 2-th + <= _mswi_handler + -> _mtim_handler 2-th + <- _mtim_handler + => _mswi_handler 3-th + <= _mswi_handler + -> _mtim_handler 3-th + <- _mtim_handler + => _mswi_handler 4-th + <= _mswi_handler + -> _mtim_handler 4-th + <- _mtim_handler + => _mswi_handler 5-th + <= _mswi_handler + done~~~ + ``` diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/isr.c b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/main.c b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/main.c new file mode 100644 index 0000000..64bd704 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_tick_swi/src/main.c @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * The defualt level of system timer is SYS_IRQ_LEVEL_L + * + SYS_IRQ_LEVEL_LL + * + SYS_IRQ_LEVEL_L + * + SYS_IRQ_LEVEL_M + * + SYS_IRQ_LEVEL_H + * + SYS_IRQ_LEVEL_HH + */ +#define CONFIG_IRQ_SWI_LEVEL SYS_IRQ_LEVEL_L +#define CONFIG_LOOP_MAX 5 + +/** + * The default priority of system time is SYS_IRQ_PRIORITY_MIDDEN + * + SYS_IRQ_PRIORITY_LOW + * + SYS_IRQ_PRIORITY_MIDDEN + * + SYS_IRQ_PRIORITY_HIGH + */ +#define CONFIG_IRQ_SWI_PRIORITY SYS_IRQ_PRIORITY_HIGH + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint8_t g_irq_swi_level = CONFIG_IRQ_SWI_LEVEL; +static uint8_t g_irq_swi_priority = CONFIG_IRQ_SWI_PRIORITY; +static uint32_t g_mtim_cnt = 0; +static uint32_t g_swi_cnt = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void _mtim_handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + msg("-> %s %u-th\n", __func__, g_mtim_cnt); + + g_mtim_cnt++; + + sys_launch_swi(); + + // Reload Timer Interrupt + SysTick_Reload(g_SysTickPeriod); + + msg("<- %s\n", __func__); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +__INTERRUPT void _mswi_handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + g_swi_cnt++; + msg(" => %s %u-th\n", __func__, g_swi_cnt); + + sys_clear_swi(); + + msg(" <= %s\n", __func__); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_10_MS); + + syslog_init(); + + info("%s %s\nThis is a demo projec to configure ECLIC " + "(IRQ Level: SWI %s SysTim, Priority: SWI %s SysTim)\n", + __DATE__, __TIME__, + (g_irq_swi_level < SYS_IRQ_LEVEL_L) ? "<" : + (g_irq_swi_level > SYS_IRQ_LEVEL_L) ? ">" : + "==", + (g_irq_swi_priority < SYS_IRQ_PRIORITY_MIDDEN) ? "<" : + (g_irq_swi_priority > SYS_IRQ_PRIORITY_MIDDEN) ? ">" : + "=="); + + do { /* Configure ECLIC interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + sys_disable_systick(); + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(SysTimer_IRQn, _mtim_handler, &irq_attr); + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = g_irq_swi_level; + irq_attr.priority = g_irq_swi_priority; + sys_register_IRQ(SysSW_IRQn, _mswi_handler, &irq_attr); + + sys_enable_systick(); + } while(0); + + while( g_swi_cnt < CONFIG_LOOP_MAX ); + + sys_disable_systick(); + + msg("done~~~\n"); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/.cproject b/pec930_sdk-v1.0.1/Examples/template/JF_01/.cproject new file mode 100644 index 0000000..1a0019e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/.project b/pec930_sdk-v1.0.1/Examples/template/JF_01/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/Project.nuproject b/pec930_sdk-v1.0.1/Examples/template/JF_01/Project.nuproject new file mode 100644 index 0000000..0072223 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/component.mk b/pec930_sdk-v1.0.1/Examples/template/JF_01/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/init.h b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/init.h new file mode 100644 index 0000000..6cf4d9f --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/init.h @@ -0,0 +1,22 @@ +/* + * init.h + * + * Created on: 2025å¹´10月9æ—¥ + * Author: jim_liao + */ + +#ifndef INC_INIT_H_ +#define INC_INIT_H_ + +void SYS_Config(); +void gpio_config(); +void opa_config(); +void adc_config(); +void pwm_config(); +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val); +void pwm_enable(); +void pwm_disable(); +void pwm_brake(); +void uart_config(); +void UART_Send_Wait(UART_Type *pHUart, uint16_t value); +#endif /* INC_INIT_H_ */ diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/isr.h b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/isr.h new file mode 100644 index 0000000..3c103a3 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void isr_epwm_handle(void); +void isr_adc_handle(void); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/main.h b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/readme.md b/pec930_sdk-v1.0.1/Examples/template/JF_01/readme.md new file mode 100644 index 0000000..a718da5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/readme.md @@ -0,0 +1,8 @@ +demo_project +--- + +This example is a demo project to descript `how to log message` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/src/init.c b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/init.c new file mode 100644 index 0000000..6d643e7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/init.c @@ -0,0 +1,232 @@ +/* + * init.c + * + * Created on: 2025å¹´8月18æ—¥ + * Author: jim_liao + */ + +#include "main.h" +#include "isr.h" +#include "init.h" +#include "hal_device.h" + +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_OPA_PGA_GAIN OPAMP_PGAGain_5 + +unsigned long ADC0Sum = 0; +unsigned char k; + +#define HIRC_Freq 60000000 //Hz +#define CurrentLoopIsrFreq 100000 //Hz +#define PWM_PERIOD HIRC_Freq/CurrentLoopIsrFreq/2 +#define DEAD_TIME 200 //ns +#define DEAD_TIME_VALUE DEAD_TIME*0.06 +//============================================================================= +// Public Function Definition +//============================================================================= +void SYS_Config() +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + gpio_config(); + opa_config(); + adc_config(); + pwm_config(); + +} + +void gpio_config() +{ +//-----------------// +// PWM +//-----------------// + GPIO_InitTypeDef GPIO_InitStruct; + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 | \ + GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); +//-----------------// +// UART +// PA15:TX PB0:RX +//-----------------// + GPIO_InitTypeDef GPIOA_InitUart; + GPIOA_InitUart.GPIO_Pin = GPIO_Pin_15; + GPIOA_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOA_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIOA_InitUart); + + GPIO_InitTypeDef GPIOB_InitUart; + GPIOB_InitUart.GPIO_Pin = GPIO_Pin_00; + GPIOB_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOB_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOB, &GPIOB_InitUart); +//-----------------// +// ADC +// PA12/13/14:OVP/OTP/CMD +//-----------------// + GPIO_InitTypeDef GPIO_InitADC; + GPIO_InitADC.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12 | GPIO_Pin_13; + GPIO_InitADC.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(GPIOA, &GPIO_InitADC); +#if 1 +//-----------------// +// test +//-----------------// +// GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_07; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif +} + +void opa_config(void) +{ + OPAMP_InitTypeDef opa_init = {0}; + + opa_init.OPAMP_VinP = OPAMP_VinP_IO; + opa_init.OPAMP_VinM = OPAMP_VinM_GND; + opa_init.OPAMP_Gain = CONFIG_OPA_PGA_GAIN; + + OPAMP_Init(OPAMP0, &opa_init); +// OPAMP_Init(OPAMP1, &opa_init); + + OPAMP_Enable(OPAMP0); +// OPAMP_Enable(OPAMP1); +} + + + +void adc_config(void) +{ + + ADC_InitTypeDef init = {0}; + ADC_StructInit(&init); + +//-----------------// +// set +//-----------------// + ADC_InitTypeDef init1 = {0}; + ADC_StructInit(&init1); + init1.SelChannels = ADC_Channel_00 | ADC_Channel_04 | ADC_Channel_05 |ADC_Channel_06 |ADC_Channel_07; + init1.ClkPrescaler = ADC_ClkDiv_4; + init1.DataAlign = ADC_DataAlign_Right; + init1.Mode = ADC_Mode_Scan; + ADC_Init(ADC0, &init1); + + ADC_ExtTrigConfig(ADC0,ADC_ExtTrigSource_EPWM_CH2R,ADC_ExtTrigMode_Enable); + + +#if 0 + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(ADC0_IRQn, isr_adc_handle, &irq_attr); + ADC0->CON0_b.INT_EN = 1; + } +#endif +} + + +void pwm_config() +{ + TIM_OCInitTypeDef TIM_OCInitStruct; + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(EPWM_IRQn, isr_epwm_handle, &irq_attr); + } + + TIM_DeInit(EPWM); + + TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); + TIM_TimeBaseInitStruct.TIM_Prescaler = 0; + TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_CenterAligned1; + TIM_TimeBaseInitStruct.TIM_Period = PWM_PERIOD-1; + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(EPWM, &TIM_TimeBaseInitStruct); + + TIM_ARRPreloadConfig(EPWM,ENABLE); + + TIM_OCStructInit(&TIM_OCInitStruct); + TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStruct.TIM_Pulse = 0; + TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct.TIM_Pulse = 1; + + TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable; + TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCPolarity_High; + TIM_OC1Init(EPWM, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC2Init(EPWM, &TIM_OCInitStruct); + + + + { /* Automatic Output enable, Break, dead time and lock configuration */ + TIM_BDTRInitTypeDef bdtr_init = {0}; + bdtr_init.TIM_LOCKLevel = TIM_LockLevel_OFF; + bdtr_init.TIM_DeadTime = DEAD_TIME_VALUE; + + TIM_BDTRConfig(EPWM, &bdtr_init); + } + + EPWM->DIER |= 0x1000; //under flow + __enable_irq(); + TIM_Cmd(EPWM, ENABLE); + TIM_CtrlPWMOutputs(EPWM,ENABLE); + +} + +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val) +{ + EPWM->CCR1 = ch1_val; + EPWM->CCR2 = ch2_val; + EPWM->CCR3 = ch3_val; + return; +} +void pwm_enable() +{ + REG_SET_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk | \ + TIM_CCER_CC2E_Msk) ; +// | TIM_CCER_CC2NE_Msk | \ +// TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk); + return; +} + + + +void uart_config() +{ + UART_InitTypeDef uart_init = {0}; + uart_init.BaudRate = 115200; + uart_init.WordLength = UART_WordLength_8b; + uart_init.StopBits = UART_StopBits_1; + uart_init.Parity = UART_Parity_No; + uart_init.Mode = UART_Mode_TxRx; + UART_Init(UART0, &uart_init); + UART_Start(UART0); +} + +void UART_Send_Wait(UART_Type *pHUart, uint16_t value) +{ + UART_SendData(pHUart,value); + UART_WaitTxFifoEmpty(pHUart); +} diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/src/isr.c b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/isr.c new file mode 100644 index 0000000..c5ea2bc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/isr.c @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#include "main.h" +#include "isr.h" +#include "init.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +long ADC_DATA[10]; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +__INTERRUPT void isr_epwm_handle(void) +{ + + if((EPWM->SR&0x20000) ==0x20000) + { + TIM_ClearITPendingBit(EPWM, 0x20000); + ADC_DATA[0] = ADC0->DAT4_b.DATA; + ADC_DATA[1] = ADC0->DAT5_b.DATA; + ADC_DATA[2] = ADC0->DAT6_b.DATA; + ADC_DATA[3] = ADC0->DAT7_b.DATA; + pwm_enable(); + pwm_set_duty(100,200,0); + GPIO_TogglePin(GPIOA, GPIO_Pin_06); + + } + +} + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_01/src/main.c b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/main.c new file mode 100644 index 0000000..9dba9ba --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_01/src/main.c @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include "init.h" +#include "hal_tim.h" +#include "hal_gpio.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + + SYS_Config(); + + while(1) + { + + } +} + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/.cproject b/pec930_sdk-v1.0.1/Examples/template/JF_02/.cproject new file mode 100644 index 0000000..1a0019e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/.project b/pec930_sdk-v1.0.1/Examples/template/JF_02/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/Project.nuproject b/pec930_sdk-v1.0.1/Examples/template/JF_02/Project.nuproject new file mode 100644 index 0000000..0072223 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/component.mk b/pec930_sdk-v1.0.1/Examples/template/JF_02/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/init.h b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/init.h new file mode 100644 index 0000000..6cf4d9f --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/init.h @@ -0,0 +1,22 @@ +/* + * init.h + * + * Created on: 2025å¹´10月9æ—¥ + * Author: jim_liao + */ + +#ifndef INC_INIT_H_ +#define INC_INIT_H_ + +void SYS_Config(); +void gpio_config(); +void opa_config(); +void adc_config(); +void pwm_config(); +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val); +void pwm_enable(); +void pwm_disable(); +void pwm_brake(); +void uart_config(); +void UART_Send_Wait(UART_Type *pHUart, uint16_t value); +#endif /* INC_INIT_H_ */ diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/isr.h b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/isr.h new file mode 100644 index 0000000..3c103a3 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void isr_epwm_handle(void); +void isr_adc_handle(void); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/main.h b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/main.h new file mode 100644 index 0000000..6bc013b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/readme.md b/pec930_sdk-v1.0.1/Examples/template/JF_02/readme.md new file mode 100644 index 0000000..a718da5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/readme.md @@ -0,0 +1,8 @@ +demo_project +--- + +This example is a demo project to descript `how to log message` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/src/init.c b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/init.c new file mode 100644 index 0000000..4c12025 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/init.c @@ -0,0 +1,234 @@ +/* + * init.c + * + * Created on: 2025å¹´8月18æ—¥ + * Author: jim_liao + */ + +#include "main.h" +#include "isr.h" +#include "init.h" +#include "hal_device.h" + +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_OPA_PGA_GAIN OPAMP_PGAGain_5 + +unsigned long ADC0Sum = 0; +unsigned char k; + +#define HIRC_Freq 60000000 //Hz +#define CurrentLoopIsrFreq 24000 //Hz +#define PWM_PERIOD HIRC_Freq/CurrentLoopIsrFreq/2 +#define DEAD_TIME 200 //ns +#define DEAD_TIME_VALUE DEAD_TIME*0.06 +//============================================================================= +// Public Function Definition +//============================================================================= +void SYS_Config() +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + sys_config_systick(SYS_TICK_1_MS); + + gpio_config(); + opa_config(); + adc_config(); + pwm_config(); + uart_config(); + +} + +void gpio_config() +{ +//-----------------// +// PWM +//-----------------// + GPIO_InitTypeDef GPIO_InitStruct; + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 | \ + GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); +//-----------------// +// UART +// PA15:TX PB0:RX +//-----------------// + GPIO_InitTypeDef GPIOA_InitUart; + GPIOA_InitUart.GPIO_Pin = GPIO_Pin_15; + GPIOA_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOA_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIOA_InitUart); + + GPIO_InitTypeDef GPIOB_InitUart; + GPIOB_InitUart.GPIO_Pin = GPIO_Pin_00; + GPIOB_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOB_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOB, &GPIOB_InitUart); +//-----------------// +// ADC +// PA12/13/14:OVP/OTP/CMD +//-----------------// + GPIO_InitTypeDef GPIO_InitADC; + GPIO_InitADC.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_12; + GPIO_InitADC.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(GPIOA, &GPIO_InitADC); +#if 0 +//-----------------// +// test +//-----------------// +// GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_07; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif +} + +void opa_config(void) +{ + OPAMP_InitTypeDef opa_init = {0}; + + opa_init.OPAMP_VinP = OPAMP_VinP_IO; + opa_init.OPAMP_VinM = OPAMP_VinM_GND; + opa_init.OPAMP_Gain = CONFIG_OPA_PGA_GAIN; + + OPAMP_Init(OPAMP0, &opa_init); + OPAMP_Init(OPAMP1, &opa_init); + + OPAMP_Enable(OPAMP0); + OPAMP_Enable(OPAMP1); +} + + + +void adc_config(void) +{ + + ADC_InitTypeDef init = {0}; + ADC_StructInit(&init); + +//-----------------// +// set +//-----------------// + ADC_InitTypeDef init1 = {0}; + ADC_StructInit(&init1); + init1.SelChannels = ADC_Channel_06 |ADC_Channel_08; + init1.ClkPrescaler = ADC_ClkDiv_4; + init1.DataAlign = ADC_DataAlign_Right; + init1.Mode = ADC_Mode_Scan; + ADC_Init(ADC0, &init1); + + ADC_ExtTrigConfig(ADC0,ADC_ExtTrigSource_EPWM_CCR4_UP,ADC_ExtTrigMode_Enable); + ADC_ExtTrigConfig(ADC0,ADC_ExtTrigSource_EPWM_CCDR4_UP,ADC_ExtTrigMode_Enable); + + +#if 0 + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(ADC0_IRQn, isr_adc_handle, &irq_attr); + ADC0->CON0_b.INT_EN = 1; + } +#endif +} + + +void pwm_config() +{ + TIM_OCInitTypeDef TIM_OCInitStruct; + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(EPWM_IRQn, isr_epwm_handle, &irq_attr); + } + + TIM_DeInit(EPWM); + + TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); + TIM_TimeBaseInitStruct.TIM_Prescaler = 0; + TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_CenterAligned1; + TIM_TimeBaseInitStruct.TIM_Period = PWM_PERIOD-1; + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(EPWM, &TIM_TimeBaseInitStruct); + + TIM_ARRPreloadConfig(EPWM,ENABLE); + + TIM_OCStructInit(&TIM_OCInitStruct); + TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStruct.TIM_Pulse = 0; + TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct.TIM_Pulse = 1; + + TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable; + TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCPolarity_High; + TIM_OC1Init(EPWM, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC2Init(EPWM, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC3Init(EPWM, &TIM_OCInitStruct); + + { /* Automatic Output enable, Break, dead time and lock configuration */ + TIM_BDTRInitTypeDef bdtr_init = {0}; + bdtr_init.TIM_LOCKLevel = TIM_LockLevel_OFF; + bdtr_init.TIM_DeadTime = DEAD_TIME_VALUE; + + TIM_BDTRConfig(EPWM, &bdtr_init); + } + + EPWM->DIER |= 0x1000; //under flow + __enable_irq(); + TIM_Cmd(EPWM, ENABLE); + TIM_CtrlPWMOutputs(EPWM,ENABLE); + +} + +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val) +{ + EPWM->CCR1 = ch1_val; + EPWM->CCR2 = ch2_val; + EPWM->CCR3 = ch3_val; + return; +} +void pwm_enable() +{ + REG_SET_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk | \ + TIM_CCER_CC2E_Msk | TIM_CCER_CC2NE_Msk | \ + TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk); + return; +} + + + +void uart_config() +{ + UART_InitTypeDef uart_init = {0}; + uart_init.BaudRate = 115200; + uart_init.WordLength = UART_WordLength_8b; + uart_init.StopBits = UART_StopBits_1; + uart_init.Parity = UART_Parity_No; + uart_init.Mode = UART_Mode_TxRx; + UART_Init(UART0, &uart_init); + UART_Start(UART0); +} + +void UART_Send_Wait(UART_Type *pHUart, uint16_t value) +{ + UART_SendData(pHUart,value); + UART_WaitTxFifoEmpty(pHUart); +} diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/src/isr.c b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/isr.c new file mode 100644 index 0000000..bc566c4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/isr.c @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#include "main.h" +#include "isr.h" +#include "init.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +long ADC_DATA[10]; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +__INTERRUPT void isr_epwm_handle(void) +{ + + if((EPWM->SR&0x20000) ==0x20000) + { + TIM_ClearITPendingBit(EPWM, 0x20000); + EPWM->CCR4 = 200; + EPWM->CCDR4 = 100; + ADC_DATA[0] = ADC0->DAT6_b.DATA; + ADC_DATA[1] = ADC0->DAT8_b.DATA; + + pwm_enable(); + +// GPIO_TogglePin(GPIOA, GPIO_Pin_06); + + } + +} + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02/src/main.c b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/main.c new file mode 100644 index 0000000..5ffb956 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02/src/main.c @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include "init.h" +#include "hal_tim.h" +#include "hal_gpio.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + + SYS_Config(); + + info("This is a demo project: JF_02\n"); + + uint32_t timer = sys_get_tick(); + + while(1) + { + if (sys_get_tick() - timer >= 1000) + { + msg("%d tick\n", sys_get_tick()); + timer = sys_get_tick(); + } + + pwm_set_duty(100,200,500); + } + +} + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.clang-format b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.clang-format new file mode 100644 index 0000000..2e9eca0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.clang-format @@ -0,0 +1,52 @@ +#Generated from Visual Studio settings +--- +BasedOnStyle: webkit +BraceWrapping: + BeforeCatch: true + BeforeElse: true + AfterClass: true + AfterFunction: true + AfterControlStatement: true + AfterEnum: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true +ColumnLimit: 80 +BreakBeforeBraces: Custom +NamespaceIndentation: All +TabWidth: 4 +IndentCaseLabels: true +AlignAfterOpenBracket: Align +PointerAlignment: Right +AlignOperands: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortLoopsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: true +BinPackArguments: true +BinPackParameters: true +BreakBeforeBinaryOperators: All +BreakBeforeTernaryOperators: false +BreakAfterJavaFieldAnnotations: true +AlignTrailingComments: true +BreakConstructorInitializers: AfterColon +AlignConsecutiveMacros: + Enabled: true + AcrossEmptyLines: true + AcrossComments: true +AlignArrayOfStructures: Right +AlignConsecutiveAssignments: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: true + PadOperators: true +AlignConsecutiveBitFields: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: true + PadOperators: true +AlignEscapedNewlines: Right +... diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.cproject b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.cproject new file mode 100644 index 0000000..1a0019e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.cproject @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.project b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.project new file mode 100644 index 0000000..2183c12 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/Project.nuproject b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/Project.nuproject new file mode 100644 index 0000000..0072223 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/component.mk b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/component.mk new file mode 100644 index 0000000..b1b2bc6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/init.h b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/init.h new file mode 100644 index 0000000..7a1cae3 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/init.h @@ -0,0 +1,24 @@ +/* + * init.h + * + * Created on: 2025å¹´10月9æ—¥ + * Author: jim_liao + */ + +#ifndef INC_INIT_H_ +#define INC_INIT_H_ + +#include "main.h" + +void SYS_Config(); +void gpio_config(); +void opa_config(); +void adc_config(); +void pwm_config(); +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val); +void pwm_enable(); +void pwm_disable(); +void pwm_brake(); +void uart_config(); +void UART_Send_Wait(UART_Type *pHUart, uint16_t value); +#endif /* INC_INIT_H_ */ diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/isr.h b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/isr.h new file mode 100644 index 0000000..8effcac --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/isr.h @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "main.h" + //============================================================================= + // Constant Definition + //============================================================================= + + //============================================================================= + // Macro Definition + //============================================================================= + + //============================================================================= + // Structure Definition + //============================================================================= + + //============================================================================= + // Global Data Definition + //============================================================================= + extern volatile bool flag_24Khz_timer; + extern volatile bool stringComplete; + extern volatile char rxBuffer[128]; + //============================================================================= + // Private Function Definition + //============================================================================= + + //============================================================================= + // Public Function Definition + //============================================================================= + void isr_epwm_handle(void); + void isr_adc_handle(void); + void isr_uart0_handle(void); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/main.h b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/main.h new file mode 100644 index 0000000..f49530e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "hal_device.h" +#include "syslog.h" + //============================================================================= + // Constant Definition + //============================================================================= + + //============================================================================= + // Macro Definition + //============================================================================= + + //============================================================================= + // Structure Definition + //============================================================================= + + //============================================================================= + // Global Data Definition + //============================================================================= + + //============================================================================= + // Private Function Definition + //============================================================================= + + //============================================================================= + // Public Function Definition + //============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/readme.md b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/readme.md new file mode 100644 index 0000000..a718da5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/readme.md @@ -0,0 +1,8 @@ +demo_project +--- + +This example is a demo project to descript `how to log message` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/init.c b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/init.c new file mode 100644 index 0000000..b46e367 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/init.c @@ -0,0 +1,258 @@ +/* + * init.c + * + * Created on: 2025å¹´8月18æ—¥ + * Author: jim_liao + */ +#include "init.h" +#include "hal_device.h" +#include "isr.h" +#include "main.h" + + +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_OPA_PGA_GAIN OPAMP_PGAGain_5 + +unsigned long ADC0Sum = 0; +unsigned char k; + +#define HIRC_Freq 60000000 // Hz +#define CurrentLoopIsrFreq 24000 // Hz +#define PWM_PERIOD HIRC_Freq / CurrentLoopIsrFreq +#define DEAD_TIME 200 // ns +#define DEAD_TIME_VALUE DEAD_TIME * 0.06 +//============================================================================= +// Public Function Definition +//============================================================================= +void SYS_Config() +{ + SYSCFG_ClkInitTypeDef SysClkInit = { 0 }; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + sys_config_systick(SYS_TICK_1_MS); + + gpio_config(); + opa_config(); + adc_config(); + pwm_config(); + uart_config(); + + __enable_irq(); +} + +void gpio_config() +{ + //-----------------// + // PWM + //-----------------// + GPIO_InitTypeDef GPIO_InitStruct; + + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 + | GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); + //-----------------// + // UART + // PB3:TX PB5:RX + //-----------------// + GPIO_InitTypeDef GPIOA_InitUart; + GPIOA_InitUart.GPIO_Pin = GPIO_Pin_03; + GPIOA_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOA_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOB, &GPIOA_InitUart); + + GPIO_InitTypeDef GPIOB_InitUart; + GPIOB_InitUart.GPIO_Pin = GPIO_Pin_05; + GPIOB_InitUart.GPIO_Mode = GPIO_Mode_AF; + GPIOB_InitUart.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOB, &GPIOB_InitUart); + //-----------------// + // ADC + // PA12/13/14:OVP/OTP/CMD + //-----------------// + GPIO_InitTypeDef GPIO_InitADC; + GPIO_InitADC.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_12; + GPIO_InitADC.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(GPIOA, &GPIO_InitADC); +#if 1 + //-----------------// + // test + //-----------------// + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif +} + +void opa_config(void) +{ + OPAMP_InitTypeDef opa_init = { 0 }; + + opa_init.OPAMP_VinP = OPAMP_VinP_IO; + opa_init.OPAMP_VinM = OPAMP_VinM_GND; + opa_init.OPAMP_Gain = CONFIG_OPA_PGA_GAIN; + + OPAMP_Init(OPAMP0, &opa_init); + OPAMP_Init(OPAMP1, &opa_init); + + OPAMP_Enable(OPAMP0); + OPAMP_Enable(OPAMP1); +} + +void adc_config(void) +{ + + ADC_InitTypeDef init = { 0 }; + ADC_StructInit(&init); + + //-----------------// + // set + //-----------------// + ADC_InitTypeDef init1 = { 0 }; + ADC_StructInit(&init1); + init1.SelChannels = ADC_Channel_06 | ADC_Channel_08; + init1.ClkPrescaler = ADC_ClkDiv_4; + init1.DataAlign = ADC_DataAlign_Right; + init1.Mode = ADC_Mode_Scan; + ADC_Init(ADC0, &init1); + + ADC_ExtTrigConfig(ADC0, ADC_ExtTrigSource_EPWM_CCR4_UP, + ADC_ExtTrigMode_Enable); + ADC_ExtTrigConfig(ADC0, ADC_ExtTrigSource_EPWM_CCDR4_UP, + ADC_ExtTrigMode_Enable); + +#if 0 + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(ADC0_IRQn, isr_adc_handle, &irq_attr); + ADC0->CON0_b.INT_EN = 1; + } +#endif +} + +void pwm_config() +{ + TIM_OCInitTypeDef TIM_OCInitStruct; + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { + .disable_vector = false, + }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(EPWM_IRQn, isr_epwm_handle, &irq_attr); + } + + TIM_DeInit(EPWM); + + TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); + TIM_TimeBaseInitStruct.TIM_Prescaler = 0; + TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInitStruct.TIM_Period = PWM_PERIOD - 1; + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(EPWM, &TIM_TimeBaseInitStruct); + + TIM_ARRPreloadConfig(EPWM, ENABLE); + + TIM_OCStructInit(&TIM_OCInitStruct); + TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Disable; + TIM_OCInitStruct.TIM_Pulse = 0; + TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct.TIM_Pulse = 1; + + TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable; + TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCPolarity_High; + TIM_OC1Init(EPWM, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC2Init(EPWM, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC3Init(EPWM, &TIM_OCInitStruct); + + { /* Automatic Output enable, Break, dead time and lock configuration */ + TIM_BDTRInitTypeDef bdtr_init = { 0 }; + bdtr_init.TIM_LOCKLevel = TIM_LockLevel_OFF; + bdtr_init.TIM_DeadTime = DEAD_TIME_VALUE; + + TIM_BDTRConfig(EPWM, &bdtr_init); + } + + EPWM->DIER |= 0x0800; // over flow + + // enable preload for CCR1, CCR2 and CCR3 + EPWM->CCMR1_OUTPUT_b.OC1PE = 1; + EPWM->CCMR1_OUTPUT_b.OC2PE = 1; + EPWM->CCMR2_OUTPUT_b.OC3PE = 1; + + TIM_Cmd(EPWM, ENABLE); + TIM_CtrlPWMOutputs(EPWM, ENABLE); +} + +void pwm_set_duty(uint16_t ch1_val, uint16_t ch2_val, uint16_t ch3_val) +{ + EPWM->CCR1 = ch1_val; + EPWM->CCR2 = ch2_val; + EPWM->CCR3 = ch3_val; + return; +} +void pwm_enable() +{ + REG_SET_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk + | TIM_CCER_CC2E_Msk | TIM_CCER_CC2NE_Msk + | TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk); + return; +} + +void pwm_disable() +{ + REG_CLR_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk + | TIM_CCER_CC2E_Msk | TIM_CCER_CC2NE_Msk + | TIM_CCER_CC3E_Msk | TIM_CCER_CC3NE_Msk); + return; +} + +void uart_config() +{ + UART_InitTypeDef uart_init = { 0 }; + uart_init.BaudRate = 115200; + uart_init.WordLength = UART_WordLength_8b; + uart_init.StopBits = UART_StopBits_1; + uart_init.Parity = UART_Parity_No; + uart_init.Mode = UART_Mode_TxRx; + UART_Init(UART0, &uart_init); + UART_Start(UART0); + + UART_ITConfig(UART0, UART_FLAG_RXNE, ENABLE); + { /* Configure TIM interrupts */ + sys_irq_attr_t irq_attr = { + .disable_vector = false, + }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_H; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(UART0_IRQn, isr_uart0_handle, &irq_attr); + } +} + +void UART_Send_Wait(UART_Type *pHUart, uint16_t value) +{ + UART_SendData(pHUart, value); + UART_WaitTxFifoEmpty(pHUart); +} diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/isr.c b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/isr.c new file mode 100644 index 0000000..21747e0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/isr.c @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#include "isr.h" +#include "init.h" +#include "main.h" + + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +#define RX_BUFFER_SIZE 128 +//============================================================================= +// Global Data Definition +//============================================================================= +long ADC_DATA[10]; +volatile bool flag_24Khz_timer = false; + +volatile char rxBuffer[RX_BUFFER_SIZE]; +volatile bool stringComplete = false; +volatile uint16_t rxIndex = 0; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +__INTERRUPT void isr_epwm_handle(void) +{ + + if ((EPWM->SR & 0x10000) == 0x10000) + { + flag_24Khz_timer = true; + ADC_DATA[0] = ADC0->DAT6_b.DATA; + ADC_DATA[1] = ADC0->DAT8_b.DATA; + TIM_ClearITPendingBit(EPWM, 0x10000); // clear OVIF + } +} + +__INTERRUPT void isr_uart0_handle(void) +{ + if (UART_GetITStatus(UART0, UART_FLAG_RXNE) == 1) + { + char receivedChar = (char)UART_ReceiveData(UART0); + + if (receivedChar == '\n' || receivedChar == '\r') + { + if (rxIndex > 0) + { + rxBuffer[rxIndex] = '\0'; + stringComplete = true; + rxIndex = 0; + msg("Received: %s\n", rxBuffer); + } + } + else if (rxIndex < RX_BUFFER_SIZE - 1) + { + rxBuffer[rxIndex++] = receivedChar; + } + } +} diff --git a/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/main.c b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/main.c new file mode 100644 index 0000000..75feb30 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/JF_02_motor/src/main.c @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ +#include + +#include "hal_gpio.h" +#include "hal_tim.h" +#include "init.h" +#include "isr.h" +#include "main.h" + + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +#define PWM_TABLE_SIZE 64 +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +const uint16_t pwm_table[PWM_TABLE_SIZE] + = { 1250, 1372, 1493, 1612, 1728, 1839, 1944, 2042, 2133, 2216, 2289, + 2352, 2404, 2446, 2475, 2493, 2499, 2493, 2475, 2446, 2404, 2352, + 2289, 2216, 2133, 2042, 1944, 1839, 1728, 1612, 1493, 1372, 1250, + 1127, 1006, 887, 771, 660, 555, 457, 366, 283, 210, 147, + 95, 53, 24, 6, 0, 6, 24, 53, 95, 147, 210, + 283, 366, 457, 555, 660, 771, 887, 1006, 1127 }; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void uvw_set_duty(uint16_t base_idx) +{ + uint16_t iA = base_idx; + uint16_t iB = (base_idx + PWM_TABLE_SIZE / 3) % PWM_TABLE_SIZE; + uint16_t iC = (base_idx + 2 * PWM_TABLE_SIZE / 3) % PWM_TABLE_SIZE; + + EPWM->CCR1 = pwm_table[iA]; + EPWM->CCR2 = pwm_table[iB]; + EPWM->CCR3 = pwm_table[iC]; +} + +static void cmd_parser(char *data, uint32_t len) +{ + char cmd_reply[64] = { 0 }; + + // echo back received command + sprintf(cmd_reply, "Received command: %s\r\n", data); + msg("%s", cmd_reply); + + // parse commands + if (strncmp(data, "help", 4) == 0) + { + msg("Available commands:\r\n"); + msg(" help - Show this help message\r\n"); + msg(" fw_ver - Show firmware version\r\n"); + } + else if (strncmp(data, "fw_ver", 6) == 0) + { + msg("FW_VER_1.0.0_20260320\r\n"); + } + else if (strncmp(data, "pwm_enable", 10) == 0) + { + pwm_enable(); + msg("PWM enabled.\r\n"); + } + else if (strncmp(data, "pwm_disable", 11) == 0) + { + pwm_disable(); + msg("PWM disabled.\r\n"); + } + else + { + msg("Unknown command. Type 'help' for available commands.\r\n"); + } +} + +int main(void) +{ + uint16_t base_idx = 0; + uint32_t timer = sys_get_tick(); + + SYS_Config(); + info("This is a demo project: JF_02\n"); + uvw_set_duty(base_idx); + pwm_enable(); + + while (1) + { + if (stringComplete) + { + cmd_parser((char *)rxBuffer, strlen((char *)rxBuffer)); + stringComplete = false; + } + + if (sys_get_tick() - timer >= 1) + { + msg("%d tick\n", sys_get_tick()); + timer = sys_get_tick(); + } + + if (flag_24Khz_timer) + { + base_idx = (base_idx + 1) % PWM_TABLE_SIZE; + uvw_set_duty(base_idx); + flag_24Khz_timer = false; + } + } +} diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/.cproject b/pec930_sdk-v1.0.1/Examples/template/demo_project/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/.project b/pec930_sdk-v1.0.1/Examples/template/demo_project/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/Project.nuproject b/pec930_sdk-v1.0.1/Examples/template/demo_project/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/component.mk b/pec930_sdk-v1.0.1/Examples/template/demo_project/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/isr.h b/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/main.h b/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/readme.md b/pec930_sdk-v1.0.1/Examples/template/demo_project/readme.md new file mode 100644 index 0000000..d4feae0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/readme.md @@ -0,0 +1,8 @@ +demo_project +--- + +This example is a demo project to descript `how to log message` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/src/isr.c b/pec930_sdk-v1.0.1/Examples/template/demo_project/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/template/demo_project/src/main.c b/pec930_sdk-v1.0.1/Examples/template/demo_project/src/main.c new file mode 100644 index 0000000..fc5e7da --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/template/demo_project/src/main.c @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +uint32_t __FASTCODE fastcode_proc(void) +{ + log_color(SLOG_CYAN, "run at fast area: $pc= x%08X\n", (uint32_t)&fastcode_proc); + return 0; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = { .ClkSource = SYSCFG_ClkSrc_HSI, }; + + #if 0 + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv2; + #endif + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("This is a demo project\n"); + msg("log debug message: $pc= x%08X\n", __get_pc()); + log_color(SLOG_GREEN, "color green\n"); + log_color(SLOG_YELLOW, "color yellow\n"); + + fastcode_proc(); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.cproject b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.project b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/Project.nuproject b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/component.mk b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/isr.h b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/main.h b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/readme.md b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/readme.md new file mode 100644 index 0000000..f654b30 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/readme.md @@ -0,0 +1,16 @@ +TIM_6StepOutput_project +--- + +This example is a demo project to TIM 6StepOutput + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## Log + ++ PA0,PA1,PA2,PA3,PA4,PA5 output pwm ++ if Enable CCPC,Need to use COM to update CCER ++ if Disable CCPC,Can use software to update CCER + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/isr.c b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/main.c b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/main.c new file mode 100644 index 0000000..884edcd --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_6StepOutput/src/main.c @@ -0,0 +1,233 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define COMPARE_PRELOAD 1 +#define TIMx EPWM +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void EPWM_6StepOutput_Sample(TIM_Type *tim,uint16_t Period,uint16_t Prescaler,uint8_t DeadTime); +void TIM1_PWM_6StepOutput_DeadTime_Break_Sample(void); +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + TIM1_PWM_6StepOutput_DeadTime_Break_Sample(); + while(1) + { + + } +} + +void EPWM_6StepOutput_Sample(TIM_Type *tim,uint16_t Period,uint16_t Prescaler,uint8_t DeadTime) +{ + GPIO_InitTypeDef GPIO_InitStruct; + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_OCInitTypeDef TIM_OCInitStructure; + TIM_BDTRInitTypeDef TIM_BDTRInitStructure; + + /* ToDo: configure GPIO Pin mux of EPWM */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 | GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + TIM_DeInit(tim); + /* Time Base configuration */ + TIM_TimeBaseStructure.TIM_Prescaler = Prescaler; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; + TIM_TimeBaseStructure.TIM_Period = Period; + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; + + TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure); + + /* Channel 1, 2,3 and 4 Configuration in PWM mode */ + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; + TIM_OCInitStructure.TIM_Pulse = 8000; + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; + TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; + TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; + + TIM_OC1Init(tim, &TIM_OCInitStructure); + + TIM_OCInitStructure.TIM_Pulse = 6000; + TIM_OC2Init(tim, &TIM_OCInitStructure); + + TIM_OCInitStructure.TIM_Pulse = 3000; + TIM_OC3Init(tim, &TIM_OCInitStructure); + + TIM_OC1PreloadConfig(tim, ENABLE); + TIM_OC2PreloadConfig(tim, ENABLE); + TIM_OC3PreloadConfig(tim, ENABLE); + + /* Automatic Output enable, Break, dead time and lock configuration*/ + TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; + TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; + TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LockLevel_OFF; + TIM_BDTRInitStructure.TIM_DeadTime = DeadTime; + TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; + TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; + TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; + + TIM_BDTRConfig(tim, &TIM_BDTRInitStructure); + +#if (COMPARE_PRELOAD == 1) + TIM_CCPreloadControl(EPWM, ENABLE); +#endif + + /* TIM1 counter enable */ + TIM_Cmd(tim, ENABLE); + + /* Main Output Enable */ + TIM_CtrlPWMOutputs(tim, ENABLE); +} + +void TIM1_PWM_6StepOutput_DeadTime_Break_Sample(void) +{ + uint8_t Index = 0; + + uint8_t Step[6] = { + 6, 2, 3, 1, 5, 4 + }; + + uint32_t delay = 0; + + EPWM_6StepOutput_Sample(TIMx,10000 - 1, 24- 1 ,64); + + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCxN_Disable); + + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Disable); + + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Disable); + + while (1) + { + switch (Step[Index]) + { + case 6: + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable); + + TIM_SetCompare2(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Enable); + + TIM_SetCompare3(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Enable); + break; + + case 2: + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Disable); + + TIM_SetCompare1(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCxN_Enable); + + TIM_SetCompare2(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Enable); + break; + + case 3: + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Disable); + + TIM_SetCompare1(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCxN_Enable); + + TIM_SetCompare3(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Enable); + break; + + case 1: + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCxN_Disable); + + TIM_SetCompare2(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Enable); + + TIM_SetCompare3(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Enable); + break; + + case 5: + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Disable); + + TIM_SetCompare1(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable); + + TIM_SetCompare2(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Enable); + break; + + case 4: + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Disable); + + TIM_SetCompare1(TIMx, 5000 - 1); + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable); + + TIM_SetCompare3(TIMx, 5000 - 1); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Enable); + break; + + default: + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_1, TIM_CCxN_Disable); + + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_2, TIM_CCxN_Disable); + + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Disable); + TIM_CCxNCmd(TIMx, TIM_Channel_3, TIM_CCxN_Disable); + break; + } + +#if (COMPARE_PRELOAD == 1) + TIM_GenerateEvent(TIMx,TIM_EventSource_COM); +#endif + + Index = (Index + 1) % 6; + + for(delay = 0; delay < 0x50000 ; delay++); + } +} diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.cproject b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.project b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/Project.nuproject b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/component.mk b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/isr.h b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/main.h b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/readme.md b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/readme.md new file mode 100644 index 0000000..dac906e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/readme.md @@ -0,0 +1,14 @@ +TIM_inputCapture_project +--- + +This example is a demo project to TIM inputCapture + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## Log + ++ Use channel 2 as the input capture channel ++ Obtain the count value in the interrupt and clear the flag bit + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/isr.c b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/main.c b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/main.c new file mode 100644 index 0000000..22953e1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_InputCapture/src/main.c @@ -0,0 +1,139 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include "hal_tim.h" + +//============================================================================= +// Constant Definition +//============================================================================= +//#define CONFIG_USE_TIM2 +#define CONFIG_USE_EPWM + +#if defined(CONFIG_USE_TIM2) + #define TIMx TIM2 + #define CONFIG_IRQ_ID TIM2_IRQn +#elif defined(CONFIG_USE_EPWM) + #define TIMx EPWM + #define CONFIG_IRQ_ID EPWM_IRQn +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +uint16_t IC2ReadValue1 = 0, IC2ReadValue2 = 0; +uint16_t CaptureNumber = 0; +uint32_t Capture = 0; +uint32_t TIMFreq = 0; +uint32_t SystemClock = 48000000; +//============================================================================= +// Private Function Definition +//============================================================================= + +void TIMx_handler(void); + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {0}; + TIM_ICInitTypeDef TIM_ICInitStruct; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* configure GPIO Pin mux of TIM capture */ +#if defined(CONFIG_USE_TIM2) + /* SET TCAP1 -> PA15*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_TCAP1,GPIO_PeriAF_2); +#elif defined(CONFIG_USE_EPWM) + /* SET ECAP1 -> PA15*/ + GPIO_PeriAFConfig(GPIOA,GPIO_Peri_ECAP1,GPIO_PeriAF_2); +#endif + + /* configure TIM */ + TIM_DeInit(TIMx); + TIM_TimeBaseInit(TIMx,&TIM_TimeBaseStructure); + + TIM_ICInitStruct.TIM_Channel = TIM_Channel_2; + TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; + TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; + TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_Div1; + TIM_ICInitStruct.TIM_ICFilter = 0x3; + TIM_ICInit(TIMx, &TIM_ICInitStruct); + + /* Enable the CC2 Interrupt Request */ + TIM_ITConfig(TIMx, TIM_IT_CC2, ENABLE); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_IRQ_ID, TIMx_handler, &irq_attr); + sys_enable_girq(); + + /* Sets the tim Counter Register value */ + TIM_SetAutoreload(TIMx,0xFFFF); + + /* TIM enable counter */ + TIM_Cmd(TIMx, ENABLE); + while(1) + { + __NOP(); + } + return 0; +} + +__INTERRUPT void TIMx_handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); // Save CSRs + + if(TIM_GetITStatus(TIMx, TIM_IT_CC2) == SET) + { + /* Clear TIM3 Capture compare interrupt pending bit */ + TIM_ClearITPendingBit(TIMx, TIM_IT_CC2); + if(CaptureNumber == 0) + { + /* Get the Input Capture value */ + IC2ReadValue1 = TIM_GetCapture2(TIMx); + CaptureNumber = 1; + } + else if(CaptureNumber == 1) + { + IC2ReadValue2 = TIM_GetCapture2(TIMx); + + if (IC2ReadValue2 > IC2ReadValue1) + { + Capture = (IC2ReadValue2 - IC2ReadValue1); + } + else + { + Capture = ((0xFFFF - IC2ReadValue1) + IC2ReadValue2); + } + /* get frequency */ + TIMFreq = (uint32_t) SystemClock / Capture; + CaptureNumber = 0; + } + } + + RESTORE_IRQ_CSR_CONTEXT(); // Restore CSRs + return; +} diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.cproject b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.project b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/Project.nuproject b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/component.mk b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/isr.h b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/main.h b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/readme.md b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/readme.md new file mode 100644 index 0000000..137f044 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/readme.md @@ -0,0 +1,15 @@ +TIM_forceOutput_project +--- + +This example is a demo project to TIM forceOutput + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## Log + ++ Enable force output and delay ++ Disable force output and delay ++ You can see PWM for SET GPIO(EPWM -> PA0 ,TIM2 -> PA2) + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/isr.c b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/main.c b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/main.c new file mode 100644 index 0000000..a288985 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_forceOutput/src/main.c @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_TIM2 +//#define CONFIG_USE_EPWM + +#if defined(CONFIG_USE_TIM2) + #define TIMx TIM2 + #define CONFIG_IRQ_ID TIM2_IRQn +#elif defined(CONFIG_USE_EPWM) + #define TIMx EPWM + #define CONFIG_IRQ_ID EPWM_IRQn +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +uint16_t delayCounter = 0; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + +#if defined(CONFIG_USE_TIM2) + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 ; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_5; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#elif defined(CONFIG_USE_EPWM) + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 ; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif + /* Resets the TIMx */ + TIM_DeInit(TIMx); + + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {0}; + TIM_TimeBaseInit(TIMx,&TIM_TimeBaseStructure); + + /* TIM1 counter enable */ + TIM_Cmd(TIMx, ENABLE); + + /* Main Output Enable */ + TIM_CtrlPWMOutputs(TIMx, ENABLE); + while(1) + { + /* TIM_ForcedAction_Inactive*/ + for(delayCounter = 0; delayCounter < 0x1000;delayCounter++); + TIM_SelectOCxM(TIMx,TIM_Channel_1,TIM_ForcedAction_Inactive); + TIM_CCxCmd(TIMx,TIM_Channel_1,TIM_CCx_Enable); + + /* TIM_ForcedAction_Active*/ + for(delayCounter = 0; delayCounter < 0x1000;delayCounter++); + TIM_SelectOCxM(TIMx,TIM_Channel_1,TIM_ForcedAction_Active); + TIM_CCxCmd(TIMx,TIM_Channel_1,TIM_CCx_Enable); + } +} diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.cproject b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.project b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/Project.nuproject b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/component.mk b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/isr.h b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/main.h b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/readme.md b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/readme.md new file mode 100644 index 0000000..b450060 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/readme.md @@ -0,0 +1,17 @@ +tim_outputCompare_project +--- + +This example is a demo project to Compare output + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## Log + ++ The output mode of channel 1 comparison is Active ++ The output mode of channel 1 comparison is Inactive ++ The output mode of channel 1 comparison is Toggle ++ PA6 indicates the start of counting ++ PA7 indicates the position of channel 2 marker + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/isr.c b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/main.c b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/main.c new file mode 100644 index 0000000..43bc439 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_outputCompare/src/main.c @@ -0,0 +1,136 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_TIM2 +//#define CONFIG_USE_EPWM + +#if defined(CONFIG_USE_TIM2) + #define TIMx TIM2 + #define CONFIG_IRQ_ID TIM2_IRQn +#elif defined(CONFIG_USE_EPWM) + #define TIMx EPWM + #define CONFIG_IRQ_ID EPWM_IRQn +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void TIMx_handler(void); +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* configure GPIO Pin mux of PWM */ +#if defined(CONFIG_USE_TIM2) + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 | GPIO_Pin_04 | GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_5; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#elif defined(CONFIG_USE_EPWM) + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_02 | GPIO_Pin_04; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif + + /* configure GPIO Pin OUT of test flag */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 | GPIO_Pin_07; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Resets the TIMx */ + TIM_DeInit(TIMx); + + /* Time Base configuration */ + TIM_TimeBaseStructure.TIM_Prescaler = 60 - 1; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseStructure.TIM_Period = 1000 - 1; + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure); + + TIM_SetCompare1(TIMx,800);//CH1 DUTY:80% + TIM_SelectOCxM(TIMx,TIM_Channel_1,TIM_OCMode_Active); + TIM_CCxCmd(TIMx,TIM_Channel_1,TIM_CCx_Enable); + + TIM_SetCompare2(TIMx,400);//CH2 DUTY:40% + TIM_SelectOCxM(TIMx,TIM_Channel_2,TIM_OCMode_Inactive); + TIM_CCxCmd(TIMx,TIM_Channel_2,TIM_CCx_Enable); + + TIM_SetCompare3(TIMx,250);//CH3 DUTY:25% + TIM_SelectOCxM(TIMx,TIM_Channel_3,TIM_OCMode_Toggle); + TIM_CCxCmd(TIMx,TIM_Channel_3,TIM_CCx_Enable); + + /* Enable the CC2 Interrupt Request */ + TIM_ITConfig(TIMx, TIM_IT_CC2, ENABLE); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_IRQ_ID, TIMx_handler, &irq_attr); + sys_enable_girq(); + + /* TIM ENABLE Flag */ + GPIO_SetBits(GPIOA,GPIO_Pin_06); + + /* TIM1 counter enable */ + TIM_Cmd(TIMx, ENABLE); + + /* Main Output Enable */ + TIM_CtrlPWMOutputs(TIMx, ENABLE); + + while(1) + { + + } + +} + +__INTERRUPT void TIMx_handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); // Save CSRs + + if(TIM_GetITStatus(TIMx, TIM_IT_CC2) == SET) + { + TIM_ClearITPendingBit(TIMx, TIM_IT_CC2); + /* TIM Interrupt Flag */ + GPIO_SetBits(GPIOA, GPIO_Pin_07); + } + + RESTORE_IRQ_CSR_CONTEXT(); // Restore CSRs + return; +} diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.cproject b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.project b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/Project.nuproject b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/component.mk b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/isr.h b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/main.h b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/readme.md b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/readme.md new file mode 100644 index 0000000..a04b548 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/readme.md @@ -0,0 +1,24 @@ +PWM_OUT +--- +This example is used to pwm output function. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +> + How to log message + +## Log + +TIM2:T2CH1 -> PA2 + T2CH2 -> PA3 + T2CH3 -> PA4 + T2CH4 -> PA5 + +EPWM:EPWMCH0P -> PA0 + EPWMCH0N -> PA1 + EPWMCH1P -> PA2 + EPWMCH1N -> PA3 + EPWMCH2P -> PA4 + EPWMCH2N -> PA5 + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/isr.c b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/main.c b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/main.c new file mode 100644 index 0000000..39355da --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/tim/tim_pwm_output/src/main.c @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include "hal_tim.h" +#include "hal_gpio.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_TIM2 +//#define CONFIG_USE_EPWM + +#if defined(CONFIG_USE_TIM2) + #define TIMx TIM2 + #define CONFIG_IRQ_ID TIM2_IRQn +#elif defined(CONFIG_USE_EPWM) + #define TIMx EPWM + #define CONFIG_IRQ_ID EPWM_IRQn +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +void TIM_PWM_OUTPUT_Sample(TIM_Type *tim,uint16_t Period,uint16_t Prescaler ,uint16_t CounterMode); +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* Configure PWM OUT */ + TIM_PWM_OUTPUT_Sample(TIMx, 100 - 1, 48 - 1, TIM_CounterMode_Up);//pwm:10K + + /* Set PWM DUTY */ + TIM_SetCompare1(TIMx, 80);//CH1 DUTY:80% + TIM_SetCompare2(TIMx, 40);//CH2 DUTY:40% + TIM_SetCompare3(TIMx, 25);//CH3 DUTY:25% + TIM_SetCompare4(TIMx, 10);//CH4 DUTY:25% + + while(1) + { + + } +} + +void TIM_PWM_OUTPUT_Sample(TIM_Type *tim,uint16_t Period,uint16_t Prescaler ,uint16_t CounterMode) +{ + GPIO_InitTypeDef GPIO_InitStruct; + TIM_OCInitTypeDef TIM_OCInitStruct; + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; + + TIM_DeInit(tim); + + TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); + TIM_TimeBaseInitStruct.TIM_Prescaler = Prescaler; + TIM_TimeBaseInitStruct.TIM_CounterMode = CounterMode; + TIM_TimeBaseInitStruct.TIM_Period = Period; + TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_Div1; + TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(tim, &TIM_TimeBaseInitStruct); + TIM_ARRPreloadConfig(tim,ENABLE); + + TIM_OCStructInit(&TIM_OCInitStruct); + TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStruct.TIM_Pulse = 0; + TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset; + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC1Init(tim, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC2Init(tim, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC3Init(tim, &TIM_OCInitStruct); + + TIM_OCInitStruct.TIM_Pulse = 1; + TIM_OC4Init(tim, &TIM_OCInitStruct); + + +#if defined(CONFIG_USE_TIM2) + /* configure GPIO Pin mux of TIM2 PWM */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 | GPIO_Pin_04| GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_5; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#elif defined(CONFIG_USE_EPWM) + /* configure GPIO Pin mux of EPWM PWM */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_02 | GPIO_Pin_04; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_6; + GPIO_Init(GPIOA, &GPIO_InitStruct); +#endif + /* configure GPIO Pin OUT */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_06 ; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Enable EPWM */ + TIM_Cmd(tim, ENABLE); + + /* Enable PWM OUT */ + TIM_CtrlPWMOutputs(tim,ENABLE); +} diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.cproject b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.project b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/Project.nuproject b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/component.mk b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/isr.h b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/isr.h new file mode 100644 index 0000000..964e1e9 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/isr.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * ISRs of Internal Interrupt of IRQC + */ +void irqc_mtip_handler(void); +void irqc_msip_handler(void); + +/** + * ISRs of External Interrupt of IRQC + */ +void irqc_uart_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/main.h b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/readme.md b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/readme.md new file mode 100644 index 0000000..b647971 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/readme.md @@ -0,0 +1,44 @@ +uart_Interrput +--- + +This is an example of UART Interrput + ++ Select the UART TX/RX pins + + ``` + // in main.c + #define CONFIG_UART_IO_TX_PORT GPIOA + #define CONFIG_UART_IO_TX_PIN GPIO_Pin_01 + #define CONFIG_UART_IO_TX_AF_MODE GPIO_AF_1 + #define CONFIG_UART_IO_RX_PORT GPIOA + #define CONFIG_UART_IO_RX_PIN GPIO_Pin_00 + #define CONFIG_UART_IO_RX_AF_MODE GPIO_AF_1 + ``` + ++ Configure the parameters related to UART + + ``` + // in main.c + #define CONFIG_BAUD_RATE_VALUE 38400 + UART_WordLength_8b //Data bit 8 + UART_StopBits_1 //Stop bit 1 + UART_Parity_No //No check bit + UART_Mode_TxRx //Transmit-Receive Mode + ``` + ++ Select the UART interrupt mode ++ It can be modified according to the requirements + + ``` + // in main.c + UART_ITConfig(UART0, UART_IE_RXNEE_Msk, ENABLE); + ``` + + +## Log + +Use serial port with baudrate 38400, 8bit, no parity check + ++ SET different uart flag bits to enable interrupts ++ Send the corresponding success log in the interrupt function + diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/isr.c b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/isr.c new file mode 100644 index 0000000..5e8b24a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/main.c b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/main.c new file mode 100644 index 0000000..22ef8eb --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_Interrupt/src/main.c @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/* UART0-TX GPIO pins are PA1 PA15 PB3 PB4 + * GPIO reuse are GPIO_AF_1 + * GPIO pins are PA0 PB0 PB5 + * GPIO reuse are GPIO_AF_2 + * UART0-RX GPIO pins are PA0 PB0 PB5 + * GPIO reuse are GPIO_AF_1 + * GPIO pins are PA1 PA15 PB4 + * GPIO reuse are GPIO_AF_2 + */ +/* adjustment Instructions for the GPIOs */ +#define CONFIG_UART_IO_TX_PORT GPIOA +#define CONFIG_UART_IO_TX_PIN GPIO_Pin_01 +#define CONFIG_UART_IO_TX_AF_MODE GPIO_AF_1 +#define CONFIG_UART_IO_RX_PORT GPIOA +#define CONFIG_UART_IO_RX_PIN GPIO_Pin_00 +#define CONFIG_UART_IO_RX_AF_MODE GPIO_AF_1 + +/* Use Baud Rate */ +#define CONFIG_BAUD_RATE_VALUE 38400 + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void UART0_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); //Save CSRs + + if(UART_GetITStatus(UART0, UART_IE_RXNEE_Msk)) + { + printf("UART0 RXNE Interrupt successful\r\n"); + UART_ITConfig(UART0, UART_IE_RXNEE_Msk, DISABLE); + } + + RESTORE_IRQ_CSR_CONTEXT(); //Restore CSRs + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + /* Configure the system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* Configure GPIO Pin mux of UART */ + GPIO_InitTypeDef GpioInit = {0}; + GpioInit.GPIO_Pin = CONFIG_UART_IO_TX_PIN; //UART0-TX + GpioInit.GPIO_Mode = GPIO_Mode_AF; + GpioInit.GPIO_AF_Mode = CONFIG_UART_IO_TX_AF_MODE; + GPIO_Init(CONFIG_UART_IO_TX_PORT, &GpioInit); + GpioInit.GPIO_Pin = CONFIG_UART_IO_RX_PIN; //UART0-RX + GpioInit.GPIO_AF_Mode = CONFIG_UART_IO_RX_AF_MODE; + GPIO_Init(CONFIG_UART_IO_RX_PORT, &GpioInit); + + /* Configure the parameters of UART */ + UART_InitTypeDef UartInit = {0}; + UartInit.BaudRate = CONFIG_BAUD_RATE_VALUE; + UartInit.WordLength = UART_WordLength_8b; + UartInit.StopBits = UART_StopBits_1; + UartInit.Parity = UART_Parity_No; + UartInit.Mode = UART_Mode_TxRx; + UART_Init(UART0, &UartInit); + + /* Configure the interrupt function of UART */ + UART_ITConfig(UART0, UART_IE_RXNEE_Msk, ENABLE); + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(UART0_IRQn, UART0_Handler, &irq_attr); + sys_enable_girq(); + + /* UART enable */ + UART_Start(UART0); + + while(1) + { + + } +} diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.cproject b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.project b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/Project.nuproject b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/component.mk b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/isr.h b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/isr.h new file mode 100644 index 0000000..964e1e9 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/isr.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * ISRs of Internal Interrupt of IRQC + */ +void irqc_mtip_handler(void); +void irqc_msip_handler(void); + +/** + * ISRs of External Interrupt of IRQC + */ +void irqc_uart_handler(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/main.h b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/readme.md b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/readme.md new file mode 100644 index 0000000..f591d26 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/readme.md @@ -0,0 +1,37 @@ +uart_polling +--- + +This is an example of UART polling + ++ Select the UART TX/RX pins + + ``` + // in main.c + #define CONFIG_UART_IO_TX_PORT GPIOA + #define CONFIG_UART_IO_TX_PIN GPIO_Pin_01 + #define CONFIG_UART_IO_TX_AF_MODE GPIO_AF_1 + #define CONFIG_UART_IO_RX_PORT GPIOA + #define CONFIG_UART_IO_RX_PIN GPIO_Pin_00 + #define CONFIG_UART_IO_RX_AF_MODE GPIO_AF_1 + ``` + ++ Configure the parameters related to UART ++ It can be modified according to the requirements + + ``` + // in main.c + #define CONFIG_BAUD_RATE_VALUE 38400 + UART_WordLength_8b //Data bit 8 + UART_StopBits_1 //Stop bit 1 + UART_Parity_No //No check bit + UART_Mode_TxRx //Transmit-Receive Mode + ``` + + +## Log + +Use serial port with baudrate 38400, 8bit, no parity check + ++ PC sends 1~255 to PEC930 ++ PEC930 receives and sends back data + diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/isr.c b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/main.c b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/main.c new file mode 100644 index 0000000..cbcb197 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/uart/uart_polling/src/main.c @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +uint16_t rxDataBuffer[256]; +uint16_t rxCounter = 0; +uint16_t rxData = 0; +uint16_t errCounter = 0; +uint16_t rightCounter = 0; + +/* UART0-TX GPIO pins are PA1 PA15 PB3 PB4 + * GPIO reuse are GPIO_AF_1 + * GPIO pins are PA0 PB0 PB5 + * GPIO reuse are GPIO_AF_2 + * UART0-RX GPIO pins are PA0 PB0 PB5 + * GPIO reuse are GPIO_AF_1 + * GPIO pins are PA1 PA15 PB4 + * GPIO reuse are GPIO_AF_2 + */ +/* adjustment Instructions for the GPIOs */ +#define CONFIG_UART_IO_TX_PORT GPIOA +#define CONFIG_UART_IO_TX_PIN GPIO_Pin_01 +#define CONFIG_UART_IO_TX_AF_MODE GPIO_AF_1 +#define CONFIG_UART_IO_RX_PORT GPIOA +#define CONFIG_UART_IO_RX_PIN GPIO_Pin_00 +#define CONFIG_UART_IO_RX_AF_MODE GPIO_AF_1 + +/* Use Baud Rate */ +#define CONFIG_BAUD_RATE_VALUE 38400 + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + /* Configure the system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* Configure GPIO Pin mux of UART */ + GPIO_InitTypeDef GpioInit = {0}; + GpioInit.GPIO_Pin = CONFIG_UART_IO_TX_PIN; //UART0-TX + GpioInit.GPIO_Mode = GPIO_Mode_AF; + GpioInit.GPIO_AF_Mode = CONFIG_UART_IO_TX_AF_MODE; + GPIO_Init(CONFIG_UART_IO_TX_PORT, &GpioInit); + GpioInit.GPIO_Pin = CONFIG_UART_IO_RX_PIN; //UART0-RX + GpioInit.GPIO_AF_Mode = CONFIG_UART_IO_RX_AF_MODE; + GPIO_Init(CONFIG_UART_IO_RX_PORT, &GpioInit); + + /* Configure the parameters of UART */ + UART_InitTypeDef UartInit = {0}; + UartInit.BaudRate = CONFIG_BAUD_RATE_VALUE; + UartInit.WordLength = UART_WordLength_8b; + UartInit.StopBits = UART_StopBits_1; + UartInit.Parity = UART_Parity_No; + UartInit.Mode = UART_Mode_TxRx; + UART_Init(UART0, &UartInit); + /* UART enable */ + UART_Start(UART0); + + for(rxCounter = 0; rxCounter < 256; rxCounter ++) + rxDataBuffer[rxCounter] = rxCounter; + + while(1) + { + if(UART_GetFlagStatus(UART0, UART_FLAG_RXNE) == 1) + { + rxData = UART_ReceiveData(UART0); + UART_ResetRxFIFO(UART0); + if(rxData != rxDataBuffer[rxData]) + errCounter++; + else + { + UART_SendData(UART0, rxData); + UART_WaitTxFifoEmpty(UART0); + rightCounter++; + } + } + } +} diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.cproject b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.project b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/Project.nuproject b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/component.mk b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/isr.h b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/main.h b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/readme.md b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/readme.md new file mode 100644 index 0000000..e29b3e7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/readme.md @@ -0,0 +1,105 @@ +wdg_count +--- + +This example is used to demo the confguration of the WatchDog + ++ Use interrut or polling mode + + - Use interrupt function + + ```c + // at mian.c + #define CONFIG_USE_WDG_INTERRUPT 1 + ``` + + - Use polling function + + ```c + // at mian.c + #define CONFIG_USE_WDG_INTERRUPT 0 + ``` + ++ Calculate timeout of the WatchDog + > It supports the API to convert milli-seconds to counter value of the WatchDog + + ``` + uint32_t WDG_MSec2Counter(uint32_t msec); + ``` + ++ Trigger system reset when WatchDog timeout + > Too small counter value of the WatchDog will lead to ICE disconnect + + ```c + // at main.c + init.ResetMode = WDG_Reset_Enable; + ``` + ++ Provid the API to extend the timeout of the WatchDog module + + ``` + void WDG_Kick(void); + ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Use interrupt function + > Set 3 seconds timeout + + ``` + [15:19:48.430] 15:19:43 + [15:19:48.430] Watch-Dog demo + [15:19:51.495] Get the new counter= 95999 + [15:19:54.554] Get the new counter= 95999 + [15:19:57.612] Get the new counter= 95999 + [15:20:00.671] Get the new counter= 95999 + [15:20:03.729] Get the new counter= 95999 + ... + ``` + ++ Use polling function + > Set 3 seconds timeout and polling the counter value + + ``` + 15:21:25 + Watch-Dog demo + Get the counter= 95999 + Get the counter= 95933 + Get the counter= 95864 + ... + Get the counter= 536 + Get the counter= 473 + Get the counter= 409 + Get the counter= 345 + Get the counter= 282 + Get the counter= 218 + Get the counter= 154 + Get the counter= 91 + Get the counter= 30 + --- timeout + Get the counter= 95969 + Get the counter= 95900 + Get the counter= 95831 + ... + ``` + ++ Use system reset when timeou + > Set 3 seconds timeout + + ``` + [15:26:16.696] 15:26:13 <--- reboot + [15:26:16.696] Watch-Dog demo + [15:26:22.824] 15:26:13 <--- reboot + [15:26:22.824] Watch-Dog demo + [15:26:25.888] 15:26:13 <--- reboot + [15:26:25.888] Watch-Dog demo + [15:26:28.952] 15:26:13 <--- reboot + [15:26:28.952] Watch-Dog demo + [15:26:32.016] 15:26:13 <--- reboot + [15:26:32.017] Watch-Dog demo + [15:26:35.080] 15:26:13 + [15:26:35.081] Watch-Dog demo + [15:26:38.145] 15:26:13 + [15:26:38.145] Watch-Dog demo + ``` diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/isr.c b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/main.c b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/main.c new file mode 100644 index 0000000..cc690eb --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/wdg/wdg_count/src/main.c @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_WDG_INTERRUPT 1 + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static bool g_has_enter_isr = false; +static uint32_t g_counter = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void WDG_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + g_has_enter_isr = true; + g_counter = WDG_GetCounter(); + + WDG_ClearITFlag(); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {.ClkSource = SYSCFG_ClkSrc_HSI,}; + + #if 0 + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv2; + #endif + + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nWatch-Dog demo\n", __DATE__, __TIME__); + + { /* Configure WDG */ + + WDG_InitTypeDef init = {0}; + + init.Counter = WDG_MSec2Counter(3000); + init.ResetMode = WDG_Reset_Disable; // WDG_Reset_Enable; + WDG_Init(&init); + } + + WDG_Unlock(); + +#if defined(CONFIG_USE_WDG_INTERRUPT) && (CONFIG_USE_WDG_INTERRUPT) + { /* Configure the interrupt function of WDG and it MUST be after init method */ + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(WDG_IRQn, WDG_Handler, &irq_attr); + + WDG_ITEnable(); + } +#else + WDG_ITDisable(); +#endif /* CONFIG_USE_WDG_INTERRUPT */ + + WDG_Enable(); + + WDG_Lock(); + + g_has_enter_isr = false; + g_counter = 0; + + while(1) + { +#if defined(CONFIG_USE_WDG_INTERRUPT) && (CONFIG_USE_WDG_INTERRUPT) + + if( g_has_enter_isr == false ) + continue; + + msg(" Get the new counter= %d\n", g_counter); + + g_has_enter_isr = false; + g_counter = 0; +#else + // WDG_Kick(); + + msg(" Get the counter= %d\n", WDG_GetCounter()); + if( WDG_GetStatusFlag() ) + { + WDG_ClearITFlag(); + msg("--- timeout\n"); + } +#endif + } +} diff --git a/pec930_sdk-v1.0.1/Makefile b/pec930_sdk-v1.0.1/Makefile new file mode 100644 index 0000000..25f962a --- /dev/null +++ b/pec930_sdk-v1.0.1/Makefile @@ -0,0 +1,333 @@ +# ------------------------------------------------ +# Generic Makefile (based on gcc) +# Copyright (c) 2022, All Rights Reserved. +# @file Makefile +# @author Wei-Lun Hsu +# @version 1.0 +# ------------------------------------------------ + +RED="\033[0;31m" +GREEN="\033[0;32m" +LIGHT_GREEN="\033[1;32m" +YELLOW="\033[0;33m" +LIGHT_YELLOW="\033[1;33m" +GREY="\033[0;37m" +BWHITE="\033[1;37m" +MAGENTA="\033[1;35m" +CYAN="\033[1;36m" +NC="\033[0m" + + +PHONY := all flash flash_nvr clean help +PHONY += gdb +PHONY += tags TAGS cscope gtags +PHONY += upload +###################################### +# target +###################################### +ifeq ("$(TARGET)","") +TARGET = Project +endif + +SOC ?= pec930 + +ifeq (,$(filter $(MAKECMDGOALS),clean help)) + +ifeq ("$(SOC)","pec930") + SOC_DRIVER = PEC930 +else +$(error "Unknown SoC, User MUST define 'SOC' name !") +endif + +endif + +srctree=$(shell pwd) + +export SOC_CPU_NAME TARGET srctree SOC_DRIVER + + +###################################### +# building variables +###################################### +# debug build? +DEBUG = y +OPT = +ifeq ("$(D)","0") + DEBUG = n + OPT = -O2 +endif + +V ?= $(VERBOSE) +ifeq ("$(V)","1") + Q = +else + Q = @ +endif + +PLATFORM = $(shell uname -o) +ifeq ("$(findstring Linux, $(PLATFORM))","Linux") + ECHO = echo + TUI = -tui +else + ECHO = echo -e + TUI = +endif + +PYTHON := python3 +PYTHON_VER := $(wordlist 2,4,$(subst ., ,$(shell $(PYTHON) --version 2>&1))) +PYTHON_VER := $(word 1,${PYTHON_VER})$(word 2,${PYTHON_VER}) + +export PLATFORM ECHO Q PYTHON PYTHON_VER TUI DEBUG OPT +####################################### +# paths +####################################### +ifeq ("$(O)","") + OUT = out +else + OUT = $(O) +endif + +ifeq ("$(P)","") + PROJ = Examples/template/demo_project +else + PROJ = $(P) +endif + +$(info Active SoC=$(SOC) @$(PROJ)) + +export OUT PROJ LIBBIN +####################################### +# binaries +####################################### +PREFIX = riscv64-unknown-elf- + +ifdef GCC_PATH +CC = $(GCC_PATH)/$(PREFIX)gcc +AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp +SZ = $(GCC_PATH)/$(PREFIX)size +GDB= $(GCC_PATH)/$(PREFIX)gdb +OBJCOPY = $(GCC_PATH)/$(PREFIX)objcopy +OBJDUMP = $(GCC_PATH)/$(PREFIX)objdump +else +CC = $(PREFIX)gcc +AS = $(PREFIX)gcc -x assembler-with-cpp +SZ = $(PREFIX)size +GDB= $(PREFIX)gdb +OBJCOPY = $(PREFIX)objcopy +OBJDUMP = $(PREFIX)objdump +endif + +HEX = $(OBJCOPY) -O ihex +BIN = $(OBJCOPY) -O binary -S + +ifeq ("$(findstring Linux, $(PLATFORM))","Linux") + OPENOCD = openocd +else + OPENOCD = openocd.exe +endif + +OPENOCDCFG := $(srctree)/Tools/openocd/scripts/target/$(SOC) +####################################### +# CFLAGS +####################################### +# mcu +MCU = + +# AS defines +AS_DEFS = + +# C defines +C_DEFS = + +# AS includes +AS_INCLUDES = + +# C includes +C_INCLUDES = + +ifeq ("$(DEBUG)","y") + OPT += -g3 -ggdb -gdwarf-2 -O0 +else + CFLAGS += -DNDEBUG +endif + +ASFLAGS = $(MCU) $(OPT) -Wall -fdata-sections -ffunction-sections -fno-common +CFLAGS = $(MCU) $(OPT) -Wall -fdata-sections -ffunction-sections -fno-common + +CFLAGS += -std=gnu99 + + +CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" + +export CFLAGS ASFLAGS C_INCLUDES AS_INCLUDES C_DEFS +####################################### +# LDFLAGS +####################################### +# link script +ifeq ("$(L)","") + LDSCRIPT = $(srctree)/Drivers/$(SOC_DRIVER)/gcc_flashxip.ld +else + LDSCRIPT = $(L) +endif + +# libraries +LIBS = +LIBDIR = + +LDFLAGS = $(MCU) -nodefaultlibs -nostartfiles -Wl,--cref \ + $(LIBDIR) \ + -Wl,-T$(LDSCRIPT) \ + -Wl,-Map=$(OUT)/$(TARGET).map + +export LDFLAGS LDSCRIPT LIBS +###################################### +# source +###################################### +# C sources +C_SOURCES := + +# ASM sources +ASM_SOURCES := + +include $(srctree)/Drivers/drivers.mk + +include $(srctree)/Common/common.mk + +ifeq ("$(PROJ)","") + $(error "Unknown project !!!") +else + include $(srctree)/$(PROJ)/component.mk +endif + + +OBJECTS = $(addprefix $(OUT)/,$(notdir $(C_SOURCES:.c=.o))) +vpath %.c $(sort $(dir $(C_SOURCES))) + +OBJECTS += $(addprefix $(OUT)/,$(notdir $(ASM_SOURCES:.S=.o))) +vpath %.S $(sort $(dir $(ASM_SOURCES))) + +RELT_SOURCES = $(foreach srcpath,$(C_SOURCES),$(subst $(srctree), ,$(srcpath))) +RELT_SOURCES += $(foreach srcpath,$(ASM_SOURCES),$(subst $(srctree),,$(srcpath))) +RELT_INCLUDES = $(foreach incpath,$(C_INCLUDES),$(subst $(srctree),,$(incpath))) + + +TARGET_GDB_SCRIPT := +####################################### +# build the application +####################################### +ASFLAGS += $(AS_DEFS) $(AS_INCLUDES) +CFLAGS += $(C_DEFS) $(C_INCLUDES) + +LDFLAGS += \ + -Wl,-gc-sections \ + -Wl,--check-sections \ + -Wl,--start-group \ + -lc_nano -lgcc -lm \ + -Wl,--end-group + +LDFLAGS += \ + -Wl,--no-warn-rwx-segments + +# default action: build all +all: $(OUT) $(OUT)/$(TARGET).elf $(OUT)/$(TARGET).hex $(OUT)/$(TARGET).bin + +$(OUT)/%.o: %.c Makefile | $(OUT) + @$(ECHO) " CC $@" + $(Q)$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(OUT)/$(notdir $(<:.c=.lst)) $< -o $@ + +$(OUT)/%.o: %.S Makefile | $(OUT) + @$(ECHO) " CC $@" + $(Q)$(AS) -c $(ASFLAGS) $(CFLAGS) $< -o $@ + +$(OUT)/$(TARGET).elf: $(OBJECTS) Makefile + $(Q)$(CC) -Wl,--whole-archive $(OBJECTS) $(LIBS) -Wl,--no-whole-archive $(LDFLAGS) -o $@ + $(Q)$(OBJDUMP) -Sx $(OUT)/$(TARGET).elf > $(OUT)/$(TARGET).disa + @$(ECHO) $(GREEN)"\nSize $(OUT)/$(TARGET).elf" $(NC) + $(Q)$(SZ) $@ + +$(OUT)/%.hex: $(OUT)/%.elf | $(OUT) + @$(ECHO) $(YELLOW) "Generate $(OUT)/$(TARGET).hex" $(NC) + $(Q)$(HEX) $< $@ + +$(OUT)/%.bin: $(OUT)/%.elf | $(OUT) + @$(ECHO) $(YELLOW) "Generate $(OUT)/$(TARGET).bin" $(NC) + $(Q)$(BIN) $< $@ + $(Q)od -A n -t x4 --width=4 -v $@ > $(OUT)/$(TARGET).txt + $(Q)$(ECHO) $(CYAN) "Project SoC=$(SOC) @$(PROJ)" $(NC) + +$(OUT): + @mkdir -p $@ + +flash: $(OUT)/$(TARGET).bin + @$(ECHO) $(YELLOW) "Program $(OUT)/$(TARGET).elf to flash of DUT" $(NC) + @$(OPENOCD) -s Tools/openocd/scripts -f Tools/openocd/scripts/target/$(SOC).cfg \ + -c "program $(OUT)/$(TARGET).bin verify 0; exit" 2>&1 | tee openocd.log + + +gdb: $(OUT)/$(TARGET).elf +ifeq ("$(DEBUG)","y") + @$(ECHO) $(YELLOW) "Download and Run GDB" $(NC) + @$(ECHO) " load $(OUT)/$(TARGET).elf" + @$(GDB) $< $(TUI) --command=$(TARGET_GDB_SCRIPT) \ + -ex "set remotetimeout 240" \ + -ex "monitor reset halt resume" \ + -ex "set mem inaccessible-by-default off" \ + -ex "target remote | $(OPENOCD) -c \"gdb_port pipe; log_output openocd.log\" \ + -s Tools/openocd/scripts \ + -f Tools/openocd/scripts/target/$(SOC).cfg" \ + -ex "j _start" +else + @$(ECHO) $(RED) "It MUST be compiled with debug mode !" $(NC) +endif + + +upload: $(OUT)/$(TARGET).bin + @$(ECHO) $(YELLOW) "Download $(OUT)/$(TARGET).elf to flash of DUT and Run" $(NC) + @$(OPENOCD) -s Tools/openocd/scripts -f Tools/openocd/scripts/target/$(SOC).cfg \ + -c "program $(OUT)/$(TARGET).elf verify reset exit" 2>&1 | tee openocd.log + +clean: + @$(ECHO) $(YELLOW) "Clean target" $(NC) + @$(ECHO) " Remove $(OUT)" + @rm -fR $(OUT) + @$(ECHO) " Done\n" + +tags TAGS cscope gtags: $(OUT) + @rm -f GPATH GRTAGS GTAGS + @$(srctree)/Tools/scripts/tags.sh $@ + + +help: + @$(ECHO) "----------------------------------------------------------------------" + @$(ECHO) "Useful make targets:" + @$(ECHO) "" + @$(ECHO) "Options:" + @$(ECHO) " SOC: $(SOC)" + @$(ECHO) " P: project path (root: $(srctree))" + @$(ECHO) " D: debug mode (0: release, default: 1)" + @$(ECHO) " O: output path (default: out)" + @$(ECHO) " L: link-script path (default: gcc_flashxip.ld in Drivers)" + @$(ECHO) "" + @$(ECHO) "e.g. make P=Examples/template/demo_project" + @$(ECHO) "" + @$(ECHO) " make clean - Remove most generated files" + @$(ECHO) "" + @$(ECHO) " make flash - Program ELF file to flash of DUT" + @$(ECHO) "" + @$(ECHO) " make upload - Program ELF file to flash of DUT and free-run" + @$(ECHO) "" + @$(ECHO) " make gdb - Download elf to flash and run GDB for development" + @$(ECHO) "" + @$(ECHO) " make tags/TAGS - Generate tags file for editors" + @$(ECHO) " make cscope - Generate cscope index" + @$(ECHO) "" + @$(ECHO) " make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build" + @$(ECHO) "----------------------------------------------------------------------" + +####################################### +# dependencies +####################################### + +-include $(wildcard $(OUT)/*.d) + +.PHONY: $(PHONY) diff --git a/pec930_sdk-v1.0.1/README.md b/pec930_sdk-v1.0.1/README.md new file mode 100644 index 0000000..b224e3f --- /dev/null +++ b/pec930_sdk-v1.0.1/README.md @@ -0,0 +1,58 @@ +# pec930_sdk + +PEC930_SDK (RISC-V 32-bits) +> `Tools/markdown/MarkdownEditor.exe` is a markdown viewer +and it assists user to view markdown file friendly (e.g. readme.md) + + +## Naming directory and file + ++ only use ASCII `a-z`, `A-Z`, `0-9`, and `_` (DONOT use white-space) + +## Development + +### Linux platform + +SDK uses Makefile to compile in Ubuntu and type `make help` to get message + +### Windows 10/11 platform + +[Nuclei-Studio IDE 2024.06](https://www.nucleisys.com/download.php#tools) is used to compile SDK in Windows 10/11. +> User opens `Project.nuproject` file of exmples with Nuclei-Studio + ++ Build with IDE + + ![ICE_normal_view](./Docs/image/ICE_normal_view.jpg) + ++ Debug with IDE + + ![IDE_debug_view](./Docs/image/IDE_debug_view.jpg) + ++ Delete the recent project before open the other project (Recommend) + > Avoid IDE automatically appends suffix serial number + + + - Close project + + ![IDE_close_proj](./Docs/image/IDE_close_proj.jpg) + + - Delete the recent project of IDE + + ![IDE_delet_recent_proj](./Docs/image/IDE_delet_recent_proj.jpg) + +### Log message + +For code size, default only support 32-bits integer. + +User should enable the other features manually + +``` +// at Common/printf.c + +/* mark to enable feature */ +#define PRINTF_DISABLE_SUPPORT_FLOAT +#define PRINTF_DISABLE_SUPPORT_EXPONENTIAL +#define PRINTF_DISABLE_SUPPORT_LONG_LONG +#define PRINTF_DISABLE_SUPPORT_PTRDIFF_T + +``` diff --git a/pec930_sdk-v1.0.1/Tools/.DS_Store b/pec930_sdk-v1.0.1/Tools/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b272a7355c2ee4e8dc0c37ef5f6ffb56cc98b0bf GIT binary patch literal 10244 zcmeHMTWl3Y7@luh+FfB`dy(ssE*?NogjNvcW=?5KxU~gZ>}iXXb6H_!yIaogIYok@ z8Zi=$CTfhqXnYW_2~Xb8m}u1KgBk->V|-C!OpFgE8udkt|Lp83w6*a?4W_%v%s;n( z=FB($xBvcg7-QI2$Tcu#GR722Lh92f`-?~Pi!|=xQA-6$kUnD`%d(u~7n?H9xY2P# zj6jS)j6jS)j6jUQ<$wVBZ1E^lrHu0!ff#`pfe{46`@y6nWHORNQiiV%%EAzUWH~j5 z50xnn2zAUzCL=i{WvEJX%IE=+DxwerQl0uuF`Q&Fl0#BTbq1-<5Uq?TLP5AX>6zhh zhNP5n9wQJVFdhLByH`@&KEN#IUK+o98OF*onE}W4gZlcfz{|>~R8%VJ6;r2a(~VSj zs;764)~8n&ZELW7Ah12xzs1V?B>VIk{sC`rOV)FDfmJwq3(|Rdr3RHdE`dbCw&}x7k*{JMCvJH)p&1 zcMsaR;6PW=_U(*gb-L+(ORd5(b$HI)dAc#*s4I2Jffp4OJ)xuu8T(Md4(=GPsjAjB zBe76b^jG%e=y$bxIk8eM>@keQ5=H41?M-=$a@njI%dR7Zbf-_)$SJgj>s3|vI}h4! zq^hmHQBn2WZYQ0w966h|Zap<^>nh6Qh#F@m6*ZOh`uk~=?U`on)ujY4#2~%g(X$><9KM7%DIwHK@fb%*FyN#R{y!TCB$gY(hJBU?)1T4>oSc zK@4IDcj0c_gA;fdkKj=}h9~e0PT^TRkJES!uj35f#Jl(iALA2zfv@om&f{DBjNfqq ze{hvo^BP{u7xNXoo;UDyyqS0LZr;Ot`5ta@mk;uz{J7i#kK7j9E9<44-%F+O{2RzP zf`9z23HWDj-m-b?w(b8*{(U(kWZacAXU$%)_}cm#*4(^t#4e>7mn`>EMua37MV*iY zp`na5VB)4RU#l~B6HBba7dbha%zC9@vLbBPxJp}S>QjhEvU;_))YL18L$bQeTyE-| zs4J@t=1NU3BVvYc0b{kfT+^Y*%35u`rk4{%)nS9oU(@OuiLfkOq{(bCbwRj)(Dc7! zKeAug1*l~D^I&2TR*|_kp_NR%7q?@ckQ;0)d%^M4QT;{$w(vp9#(@Oemt@9`6Ui$1{Eh-tT#j9SXD zeT-=rJMymMx%+8^AVeke>B2bAY;r#V^X0{H?090w6FZ*&$nlKjU+j3q7i{c!*x!9~ zUH*<|lxdG~Jfl5TT#FHyj0lv;O`GEWzh&b8|0g3f@t$J@CJh28Z|-Q`NZT!4QjFcX z2=z=#`zVP=j2n_NRG}=421$n3@l+Al@k=O)vC%b7SWZT5LsEw7G$vFhDR1-t^*;l| SWnLWr$MOF}x66~@;`vXq$Uc_< literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Tools/openocd/.DS_Store b/pec930_sdk-v1.0.1/Tools/openocd/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b2a6b3e6c870dde3f033c72e8cfe8a9aab8f5326 GIT binary patch literal 6148 zcmeHKOG-mQ5UkdK0XJD@IalxoLx?BH1p*O5K%yk-`mJ&$ zdAwS@eht7D?@tfF48WA`h?9r0`MLYZZYpC$I`4SJ8;&2V!~XeYRDC(&+&dhx!2!FU z{QWj>y-ZV93P=GdAO)m=6!@hA-g{}&`$R=4AO)nrw*vlsXmrP3I3&iWgCRx$;)Lli zu49%UHct?H;gHA-&5}w?s?~^LNoT%QT`wFGlMbul!|KUa6N<&td4G#?SWi@x0#e{y zf!o~9y#GJaugw4FB<-Yt6!=#P*krj{F8E5-TSqVFy|&TUbg%iOyKx;9hG@scXvf@m fJDx{T)-_-AycZ6ML1#YbMEwl7E;1?b*9v?AELauN literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Tools/openocd/README.md b/pec930_sdk-v1.0.1/Tools/openocd/README.md new file mode 100644 index 0000000..ede5dda --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/README.md @@ -0,0 +1,85 @@ +# Nuclei OpenOCD Distribution + +For **Nuclei OpenOCD documentation**, please check https://doc.nucleisys.com/nuclei_tools/openocd/intro.html + +If the tool version and documentation version not match, please take care. + +**Below is the changelog for Nuclei OpenOCD.** + +## 2024.06 + +* Add and update nuclei custom CSR +* Fix `nuclei cpuinfo` command implementation +* Add debug map feature for Nuclei CPU with new `nuclei expose_cpu_core` and `nuclei examine_cpu_core` commands +* changes are based on [riscv/riscv-openocd](https://github.com/riscv/riscv-openocd/commit/52177592) +* Fix hbird/hbirdv2 flash programming, and re-route fespi to nuspi flash loader for hbird/hbirdv2 processor + +## 2024.02 + +> **Still in development, not official release.** + +* Add Nuclei N100 CSR support +* Nuclei etrace support multicore trace +* Fix riscv debug 0.11 call riscv_run_algorithm error such as hbird/hbirdv2 processor +* Update and fix openocd documentation +* changes are based on [riscv/riscv-openocd](https://github.com/riscv/riscv-openocd/commit/52177592) + +## 2023.10 + +* Add nuclei command group to contains all nuclei customized commands +* Add `nuclei cpuinfo` dump support +* Add more spiflash devices according to customer request +* Fix gdb flash program error on address size > 32bit on windows +* Update nuclei custom csr +* Add `ftdi nscan1_mode` to support 2-wire cjtag for Nuclei CPU, which is replacement for `ftdi oscan1_mode` +* Add nuclei custom command in openocd documentation +* **Experimental and may change**: Add nuclei etrace command to support nuclei etrace hardware feature +* changes are based on [riscv/riscv-openocd](https://github.com/riscv/riscv-openocd/commit/52177592) + +## 2022.12 + +This is release 2022.12 of openocd. + +* nor/spi:add w25q512jv +* add 'init resethalt' command +* feature:auto search custom flashloader path +* fix riscv-debug v0.11 call riscv_run_algorithm error. + + +## 2022.08 + +This is release 2022.08 of openocd. + +* spi_nor:add xt25f256b mac25l1633e gd25q80b gd25le32e en25s40a by25q32al fm25q128 gd25B512me. +* merge upstream https://github.com/riscv/riscv-openocd commit id 52177592f9d3afc6a008f8e1b321cf74e823018f. +* custom flashloader don't rely on 'src/flash/nor/spi.c', fix memory leaks bug. + + +## 2022.04 + +This is release 2022.04 of openocd. + +* add DSP ucode csr register +* Adjustment simulation timeout param +* Fix after write_bank/write_image command read date error bug +* Add custom flash loader in openocd, please refer wiki for how to use it +* Custom flash loader: add 'simulation' parameter for simulation test. + + +## 2022.01 + +This is release 2022.01 of openocd. + +* optimize cjtag support for nuclei cjtag +* spi_nor: add BoHong bh25d80a bh25d40a bh25d20a +* spi_nor: Add Micron MT25QU512 +* flash:"flash bank" command add simulation param +* add nuclei all custom csr +* spi_nor: Add MXIC MX25U51245G +* transport/ftdi: Update to new standard cJTAG sequence +* flash: add XinSheng RISC-V MCU CM32M4xxR flash program driver +* Add nuspi loader support. +* Add nuspi SPI flash driver support. +* Enable multi-core debug. +* Previous fespi loader will be rerouted to nuspi loader. +* Changes are based on [openocd for riscv 0.11.0](https://github.com/riscv/riscv-openocd/commit/6edf98db7f98c5e24bc51cf98419bdf5bbc530e6) diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/bitsbytes.tcl b/pec930_sdk-v1.0.1/Tools/openocd/scripts/bitsbytes.tcl new file mode 100644 index 0000000..6f7d423 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/bitsbytes.tcl @@ -0,0 +1,59 @@ +#---------------------------------------- +# Purpose - Create some $BIT variables +# Create $K and $M variables +# and some bit field extraction variables. +# Create helper variables ... +# BIT0.. BIT31 + +for { set x 0 } { $x < 32 } { set x [expr {$x + 1}]} { + set vn [format "BIT%d" $x] + global $vn + set $vn [expr {1 << $x}] +} + +# Create K bytes values +# __1K ... to __2048K +for { set x 1 } { $x < 2048 } { set x [expr {$x * 2}]} { + set vn [format "__%dK" $x] + global $vn + set $vn [expr {1024 * $x}] +} + +# Create M bytes values +# __1M ... to __2048K +for { set x 1 } { $x < 2048 } { set x [expr {$x * 2}]} { + set vn [format "__%dM" $x] + global $vn + set $vn [expr {1024 * 1024 * $x}] +} + +proc create_mask { MSB LSB } { + return [expr {((1 << ($MSB - $LSB + 1))-1) << $LSB}] +} + +# Cut Bits $MSB to $LSB out of this value. +# Example: % format "0x%08x" [extract_bitfield 0x12345678 27 16] +# Result: 0x02340000 + +proc extract_bitfield { VALUE MSB LSB } { + return [expr {[create_mask $MSB $LSB] & $VALUE}] +} + + +# Cut bits $MSB to $LSB out of this value +# and shift (normalize) them down to bit 0. +# +# Example: % format "0x%08x" [normalize_bitfield 0x12345678 27 16] +# Result: 0x00000234 +# +proc normalize_bitfield { VALUE MSB LSB } { + return [expr {[extract_bitfield $VALUE $MSB $LSB ] >> $LSB}] +} + +proc show_normalize_bitfield { VALUE MSB LSB } { + set m [create_mask $MSB $LSB] + set mr [expr {$VALUE & $m}] + set sr [expr {$mr >> $LSB}] + echo [format "((0x%08x & 0x%08x) -> 0x%08x) >> %2d => (0x%x) %5d " $VALUE $m $mr $LSB $sr $sr] + return $sr +} diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/dummy.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/dummy.cfg new file mode 100644 index 0000000..8cbb5e0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/dummy.cfg @@ -0,0 +1,5 @@ +# +# Dummy interface (for testing purposes) +# + +adapter driver dummy diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/flashlink.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/flashlink.cfg new file mode 100644 index 0000000..465a03e --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/flashlink.cfg @@ -0,0 +1,16 @@ +# +# ST FlashLINK JTAG parallel cable +# +# http://www.st.com/internet/evalboard/product/94023.jsp +# http://www.st.com/stonline/products/literature/um/7889.pdf +# + +if { [info exists PARPORTADDR] } { + set _PARPORTADDR $PARPORTADDR +} else { + set _PARPORTADDR 0 +} + +adapter driver parport +parport port $_PARPORTADDR +parport cable flashlink diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/ft232r.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/ft232r.cfg new file mode 100644 index 0000000..9dd00c6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/ft232r.cfg @@ -0,0 +1,2 @@ +adapter driver ft232r +adapter speed 1000 diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jlink.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jlink.cfg new file mode 100644 index 0000000..1aa211f --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jlink.cfg @@ -0,0 +1,14 @@ +# +# SEGGER J-Link +# +# http://www.segger.com/jlink.html +# + +adapter driver jlink + +# The serial number can be used to select a specific device in case more than +# one is connected to the host. +# +# Example: Select J-Link with serial number 123456789 +# +# adapter serial 123456789 diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_dpi.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_dpi.cfg new file mode 100644 index 0000000..283c413 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_dpi.cfg @@ -0,0 +1,38 @@ +# +# Provide support for the Cadence JTAG BFM +# +# Copyright (c) 2020, Ampere Computing LLC +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; +# +# + +adapter driver jtag_dpi + +# Set the DPI JTAG server port +if { [info exists DPI_PORT] } { + set _DPI_PORT $DPI_PORT +} else { + set _DPI_PORT 5555 +} + +# Set the DPI JTAG server address +if { [info exists DPI_ADDRESS] } { + set _DPI_ADDRESS $DPI_ADDRESS +} else { + set _DPI_ADDRESS "127.0.0.1" +} + +jtag_dpi set_port $_DPI_PORT +jtag_dpi set_address $_DPI_ADDRESS diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_hat_rpi2.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_hat_rpi2.cfg new file mode 100644 index 0000000..e564199 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_hat_rpi2.cfg @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Blinkinlabs JTAG_Hat +# +# https://github.com/blinkinlabs/jtag_hat +# + +adapter driver bcm2835gpio + +bcm2835gpio_peripheral_base 0x3F000000 + +# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET +# These depend on system clock, calibrated for stock 700MHz +# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET +bcm2835gpio_speed_coeffs 146203 36 + +# Each of the JTAG lines need a gpio number set: tck tms tdi tdo +# Header pin numbers: 23 22 19 21 +bcm2835gpio_jtag_nums 11 25 10 9 + +# Each of the SWD lines need a gpio number set: swclk swdio +# Header pin numbers: 23 22 +bcm2835gpio_swd_nums 11 25 + +# Direction pin for SWDIO level shifting buffer +bcm2835gpio_swdio_dir_num 6 + +# If you define trst or srst, use appropriate reset_config +# Header pin numbers: TRST - 26, SRST - 18 + +bcm2835gpio_trst_num 7 +#reset_config trst_only + +bcm2835gpio_srst_num 24 +#reset_config srst_only + +# or if you have both connected +#reset_config trst_and_srst diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_vpi.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_vpi.cfg new file mode 100644 index 0000000..0dbd1be --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/jtag_vpi.cfg @@ -0,0 +1,18 @@ +adapter driver jtag_vpi + +# Set the VPI JTAG server port +if { [info exists VPI_PORT] } { + set _VPI_PORT $VPI_PORT +} else { + set _VPI_PORT 5555 +} + +# Set the VPI JTAG server address +if { [info exists VPI_ADDRESS] } { + set _VPI_ADDRESS $VPI_ADDRESS +} else { + set _VPI_ADDRESS "127.0.0.1" +} + +jtag_vpi set_port $_VPI_PORT +jtag_vpi set_address $_VPI_ADDRESS diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/openjtag.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/openjtag.cfg new file mode 100644 index 0000000..662ceba --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/openjtag.cfg @@ -0,0 +1,8 @@ +# +# OpenJTAG +# +# www.openjtag.org +# + +adapter driver openjtag +openjtag device_desc "Open JTAG Project" diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/usb-jtag.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/usb-jtag.cfg new file mode 100644 index 0000000..65d45e7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/interface/usb-jtag.cfg @@ -0,0 +1,37 @@ +# ixo-usb-jtag - Emulation of a Altera Bus Blaster I on a Cypress FX2 IC. +# +# The ixo-usb-jtag firmware can be loaded onto a bunch of different hardware +# including; +# * Xilinx USB Platform Cable +# * Many Digilent boards such as the Nexys, Nexys 2 and Atlys boards +# * Many fpga4fun.com boards from such as the Saxo and Xylo boards +# * The Numato Opsis +# +# Original version - http://www.ixo.de/info/usb_jtag/ +# Updated version - http://ixo-jtag.sourceforge.net/ +# Newest version - http://github.com/mithro/ixo-usb-jtag +# +# Procedure for using is; +# * Get the ixo-usb-jtag firmware for your hardware (or build it yourself). +# * Load the firmware using the fxload tool. +# * Use openocd. +# +# Unless you burn the firmware into the EEPROM on your device, power cycling +# will require you to reload the firmware using the fxload tool. This can be +# automated by using udev rules (which can be found in the firmware +# repository). +# +# Ubuntu packages built from mithro's version (with prebuilt firmware and udev +# rules) can be found at +# https://launchpad.net/~timvideos/+archive/ubuntu/fpga-support +# +# TODO: Refactor the usb_blaster driver to allow loading firmware using any low +# level driver. Loading firmware is currently only supported on the ublast2 +# driver but ixo-usb-jtag requires the ftdi driver. + +adapter driver usb_blaster +usb_blaster vid_pid 0x16C0 0x06AD +usb_blaster device_desc "Van Ooijen Technische Informatica" +# ixo-usb-jtag is only compatible with the ublast1 protocol implemented via the +# ftdi modes, using ublast2 will cause openocd to hang. +usb_blaster lowlevel_driver ftdi diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/mem_helper.tcl b/pec930_sdk-v1.0.1/Tools/openocd/scripts/mem_helper.tcl new file mode 100644 index 0000000..7cd370e --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/mem_helper.tcl @@ -0,0 +1,36 @@ +# Helper for common memory read/modify/write procedures + +# mrw: "memory read word", returns value of $reg +proc mrw {reg} { + return [read_memory $reg 32 1] +} + +add_usage_text mrw "address" +add_help_text mrw "Returns value of word in memory." + +# mrh: "memory read halfword", returns value of $reg +proc mrh {reg} { + return [read_memory $reg 16 1] +} + +add_usage_text mrh "address" +add_help_text mrh "Returns value of halfword in memory." + +# mrb: "memory read byte", returns value of $reg +proc mrb {reg} { + return [read_memory $reg 8 1] +} + +add_usage_text mrb "address" +add_help_text mrb "Returns value of byte in memory." + +# mmw: "memory modify word", updates value of $reg +# $reg <== ((value & ~$clearbits) | $setbits) +proc mmw {reg setbits clearbits} { + set old [mrw $reg] + set new [expr {($old & ~$clearbits) | $setbits}] + mww $reg $new +} + +add_usage_text mmw "address setbits clearbits" +add_help_text mmw "Modify word in memory. new_val = (old_val & ~clearbits) | setbits;" diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/memory.tcl b/pec930_sdk-v1.0.1/Tools/openocd/scripts/memory.tcl new file mode 100644 index 0000000..ecd1a25 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/memory.tcl @@ -0,0 +1,175 @@ +# MEMORY +# +# All Memory regions have two components. +# (1) A count of regions, in the form N_NAME +# (2) An array within info about each region. +# +# The ARRAY +# +# ( RegionNumber , ATTRIBUTE ) +# +# Where is one of: +# +# N_FLASH & FLASH (internal memory) +# N_RAM & RAM (internal memory) +# N_MMREGS & MMREGS (for memory mapped registers) +# N_XMEM & XMEM (off chip memory, ie: flash on cs0, sdram on cs2) +# or N_UNKNOWN & UNKNOWN for things that do not exist. +# +# We have 1 unknown region. +set N_UNKNOWN 1 +# All MEMORY regions must have these attributes +# CS - chip select (if internal, use -1) +set UNKNOWN(0,CHIPSELECT) -1 +# BASE - base address in memory +set UNKNOWN(0,BASE) 0 +# LEN - length in bytes +set UNKNOWN(0,LEN) $CPU_MAX_ADDRESS +# HUMAN - human name of the region +set UNKNOWN(0,HUMAN) "unknown" +# TYPE - one of: +# flash, ram, mmr, unknown +# For harvard arch: +# iflash, dflash, iram, dram +set UNKNOWN(0,TYPE) "unknown" +# RWX - access ablity +# unix style chmod bits +# 0 - no access +# 1 - execute +# 2 - write +# 4 - read +# hence: 7 - readwrite execute +set RWX_NO_ACCESS 0 +set RWX_X_ONLY $BIT0 +set RWX_W_ONLY $BIT1 +set RWX_R_ONLY $BIT2 +set RWX_RW [expr {$RWX_R_ONLY + $RWX_W_ONLY}] +set RWX_R_X [expr {$RWX_R_ONLY + $RWX_X_ONLY}] +set RWX_RWX [expr {$RWX_R_ONLY + $RWX_W_ONLY + $RWX_X_ONLY}] +set UNKNOWN(0,RWX) $RWX_NO_ACCESS + +# WIDTH - access width +# 8,16,32 [0 means ANY] +set ACCESS_WIDTH_NONE 0 +set ACCESS_WIDTH_8 $BIT0 +set ACCESS_WIDTH_16 $BIT1 +set ACCESS_WIDTH_32 $BIT2 +set ACCESS_WIDTH_ANY [expr {$ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_32}] +set UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE + +proc iswithin { ADDRESS BASE LEN } { + return [expr {(($ADDRESS - $BASE) >= 0) && (($BASE + $LEN - $ADDRESS) > 0)}] +} + +proc address_info { ADDRESS } { + + foreach WHERE { FLASH RAM MMREGS XMEM UNKNOWN } { + if { info exists $WHERE } { + set lmt [set N_[set WHERE]] + for { set region 0 } { $region < $lmt } { incr region } { + if { iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN) } { + return "$WHERE $region"; + } + } + } + } + + # Return the 'unknown' + return "UNKNOWN 0" +} + +proc memread32 {ADDR} { + if ![ catch { set foo [read_memory $ADDR 32 1] } msg ] { + return $foo + } else { + error "memread32: $msg" + } +} + +proc memread16 {ADDR} { + if ![ catch { set foo [read_memory $ADDR 16 1] } msg ] { + return $foo + } else { + error "memread16: $msg" + } +} + +proc memread8 {ADDR} { + if ![ catch { set foo [read_memory $ADDR 8 1] } msg ] { + return $foo + } else { + error "memread8: $msg" + } +} + +proc memwrite32 {ADDR DATA} { + if ![ catch { write_memory $ADDR 32 $DATA } msg ] { + return $DATA + } else { + error "memwrite32: $msg" + } +} + +proc memwrite16 {ADDR DATA} { + if ![ catch { write_memory $ADDR 16 $DATA } msg ] { + return $DATA + } else { + error "memwrite16: $msg" + } +} + +proc memwrite8 {ADDR DATA} { + if ![ catch { write_memory $ADDR 8 $DATA } msg ] { + return $DATA + } else { + error "memwrite8: $msg" + } +} + +proc memread32_phys {ADDR} { + if ![ catch { set foo [read_memory $ADDR 32 1 phys] } msg ] { + return $foo + } else { + error "memread32: $msg" + } +} + +proc memread16_phys {ADDR} { + if ![ catch { set foo [read_memory $ADDR 16 1 phys] } msg ] { + return $foo + } else { + error "memread16: $msg" + } +} + +proc memread8_phys {ADDR} { + if ![ catch { set foo [read_memory $ADDR 8 1 phys] } msg ] { + return $foo + } else { + error "memread8: $msg" + } +} + +proc memwrite32_phys {ADDR DATA} { + if ![ catch { write_memory $ADDR 32 $DATA phys } msg ] { + return $DATA + } else { + error "memwrite32: $msg" + } +} + +proc memwrite16_phys {ADDR DATA} { + if ![ catch { write_memory $ADDR 16 $DATA phys } msg ] { + return $DATA + } else { + error "memwrite16: $msg" + } +} + +proc memwrite8_phys {ADDR DATA} { + if ![ catch { write_memory $ADDR 8 $DATA phys } msg ] { + return $DATA + } else { + error "memwrite8: $msg" + } +} diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/mmr_helpers.tcl b/pec930_sdk-v1.0.1/Tools/openocd/scripts/mmr_helpers.tcl new file mode 100644 index 0000000..d03c8da --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/mmr_helpers.tcl @@ -0,0 +1,72 @@ + +proc proc_exists { NAME } { + set n [info commands $NAME] + set l [string length $n] + return [expr {$l != 0}] +} + +# Give: REGISTER name - must be a global variable. +proc show_mmr32_reg { NAME } { + + global $NAME + # we want $($NAME) + set a [set [set NAME]] + + if ![catch { set v [memread32 $a] } msg ] { + echo [format "%15s: (0x%08x): 0x%08x" $NAME $a $v] + + # Was a helper defined? + set fn show_${NAME}_helper + if [ proc_exists $fn ] { + # Then call it + $fn $NAME $a $v + } + return $v; + } else { + error [format "%s (%s)" $msg $NAME ] + } +} + + +# Give: NAMES - an array of names accessible +# in the callers symbol-scope. +# VAL - the bits to display. + +proc show_mmr32_bits { NAMES VAL } { + + upvar $NAMES MYNAMES + + set w 5 + foreach {IDX N} $MYNAMES { + set l [string length $N] + if { $l > $w } { set w $l } + } + + for { set x 24 } { $x >= 0 } { incr x -8 } { + echo -n " " + for { set y 7 } { $y >= 0 } { incr y -1 } { + set s $MYNAMES([expr {$x + $y}]) + echo -n [format "%2d: %-*s | " [expr {$x + $y}] $w $s ] + } + echo "" + + echo -n " " + for { set y 7 } { $y >= 0 } { incr y -1 } { + echo -n [format " %d%*s | " [expr {!!($VAL & (1 << ($x + $y)))}] [expr {$w -1}] ""] + } + echo "" + } +} + + +proc show_mmr_bitfield { MSB LSB VAL FIELDNAME FIELDVALUES } { + set width [expr {(($MSB - $LSB + 1) + 7) / 4}] + set nval [show_normalize_bitfield $VAL $MSB $LSB ] + set name0 [lindex $FIELDVALUES 0 ] + if [ string compare $name0 _NUMBER_ ] { + set sval [lindex $FIELDVALUES $nval] + } else { + set sval "" + } + echo [format "%-15s: %d (0x%0*x) %s" $FIELDNAME $nval $width $nval $sval ] +} diff --git a/pec930_sdk-v1.0.1/Tools/openocd/scripts/target/pec930.cfg b/pec930_sdk-v1.0.1/Tools/openocd/scripts/target/pec930.cfg new file mode 100644 index 0000000..57762d4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/openocd/scripts/target/pec930.cfg @@ -0,0 +1,129 @@ + +adapter speed 5000 +reset_config srst_only +adapter srst pulse_width 100 + +adapter driver ftdi +ftdi vid_pid 0x0403 0x6010 + +proc _get_loader {patt} { + set _patt_loader $patt + set _loader_bin 0 + set _level 0 + + while {1} { + if {[file exists $_patt_loader]} { + set _loader_bin [pwd] + append _loader_bin "/" $patt + break + } + + cd .. + incr _level 1 + if {$_level > 20} { + set _loader_bin "" + break + } + } + return $_loader_bin +} + +set _2WIRE_ICE 1 +if { $_2WIRE_ICE == 0 } { + # jTag 4-wire + echo "=> Use 4-wires jTag..." + ftdi nscan1_mode off +} else { + # cJtag 2-wire + echo "=> Use 2-wires cJTag..." + ftdi nscan1_mode on +} + +#/* +# * bindto 0.0.0.0 can be used to cover all available interfaces. +# * Uncomment bindto line to enable remote machine debug +# */ +# bindto 0.0.0.0 + +#/* +# * If ftdi device_desc not specified, the device description is ignored during device selection. +# * So if you want to specify a dedicated FTDI device, you can select following device description: +# * "Dual RS232-HS" is for Nuclei HummingBird Debugger V1 +# * "USB <-> JTAG-DEBUGGER" is for Nuclei HummingBird Debugger V2 +# * Uncomment one which match your device description +# */ +# ftdi device_desc "Dual RS232-HS" +# ftdi device_desc "USB <-> JTAG-DEBUGGER" +#/* you can also specify adapter serial to select a ftdi chip */ +# adapter serial "FT6S9RD6" + +# Bind JTAG with specified serial number passed by JTAGSN +if { [ info exists JTAGSN ] } { + puts "Bind JTAG with serial number $JTAGSN" + adapter serial $JTAGSN +} + +ftdi layout_init 0x0008 0x001b +ftdi layout_signal nSRST -oe 0x0020 -data 0x0020 +#/* These signals are used for cJTAG escape sequence on initialization only */ +ftdi layout_signal TCK -data 0x0001 +ftdi layout_signal TDI -data 0x0002 +ftdi layout_signal TDO -input 0x0004 +ftdi layout_signal TMS -data 0x0008 +ftdi layout_signal JTAG_SEL -data 0x0100 -oe 0x0100 +transport select jtag + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 + +#/* Work-area is a space in RAM used for flash programming */ +if { [info exists WORKAREASIZE] } { + set _WORKAREA_SIZE $WORKAREASIZE +} else { + set _WORKAREA_SIZE 0x600 +} + +set _WORKAREA_BASE 0x20000A00 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME +$_TARGETNAME configure -work-area-phys $_WORKAREA_BASE -work-area-size $_WORKAREA_SIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash + + + +#/* +# * Use external flash-loader 'loader.bin' +# */ + +set _BURN_DEV_BASE 0x0 +set _BURN_DEV_SIZE 0x8000 + +# eflash +echo "=> Burn Data to eFlash ..." +set _LOADER_BIN [_get_loader Drivers/PEC930/Flash/loader.bin] +flash bank $_FLASHNAME custom $_BURN_DEV_BASE $_BURN_DEV_SIZE 0 0 $_TARGETNAME 0x4000F800 $_LOADER_BIN sectorsize=512 + + + +#/* +# * Expose Nuclei self-defined CSRS range +# * See https://github.com/riscv/riscv-gnu-toolchain/issues/319#issuecomment-358397306 +# * Then user can view the csr register value in gdb using: info reg csr775 for CSR MTVT(0x307) +# * no need to expose since Nuclei OpenOCD 2022 +# */ +#riscv expose_csrs 770-800,835-850,1984-2032,2064-2070 + +#/* expose N100 customized csr 0xbd0 -> 0xbdc, mainly irqc and timer csrs */ +# riscv expose_csrs 3024-3036 + +riscv set_reset_timeout_sec 1 + +init + +halt + +flash protect 0 0 last off + +arm semihosting enable diff --git a/pec930_sdk-v1.0.1/Tools/scripts/.DS_Store b/pec930_sdk-v1.0.1/Tools/scripts/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..0005c61319df69af082bd87b356e2b6d1b629c57 GIT binary patch literal 8196 zcmeHMTWl3Y7@luhU{_q2UW5Wmx_AIZE3|?rH*-o`LbDtwqETPO_|MLsaw&Z?L}e$L`F8%9 zf9C8r|2K2y9L5;d7IRIE)iK62$`Zv?DlU>_yUgPfk1Q30Ab-Xj<}#ZFZcu6&*E=@E z48#n?48#n?48#ol8yKK7TPAISb6>T_Wz0a#z-7sR+#f8;5|a^*C=9m_D#9xOVI`Tv zM9*{&2z{&wlM#+63|(nVb$dYMis*^~`s`Ba73YUXHf18(aeZ$CXb~y*_pf7!(+dfc`&(blQ_g%Ns4;(pSZ>lg+Q>riU^M#gh+>}F8sR2YWu(#PX zzEiSWX_lb&f|rJVe0rU=VA0~Gx2$Piw_(e+QBhT0Q)|pH`kb8Y6`b9Uo$pNtS=-Aw z-k$BlPOh-Gr{n}q#^q{R*p+O&=HG7UQ=bH89Ce`t*qb3qss+e*17oEbLqcv64 z!Y~u_bxpjsBS)WWv!9bQ<-!)zOkAsJ{nFl&x2aTS!)&;L9MatZaifMXnr_r}5p?f! zyvWs9ezT^F+;%sev0XKqv1&D$HujX%azw@%Nli~>{lP(c$sn4xwN2B+$2;Z3o6hVTT#m*Ov**m} z>Nd>*Asnyd6lhUsnFxx3IH_q`B6*!!oJ4tz67Sm2hR-3i8{=~A}qlQti)=p!8&xH6I;=RU2t#* z_F)(!xEuH2UL3)rcnpu@2|R`8a177mMI6T)coQe^Hr~f4_!OVvD}0OZa2ns^SNw@H z_>1ejn%D4JzK}2Bjl7Ak;;p=g_wqj8&v$T}dwiH5;`gan;L*XwcB*>0l<%caqHT#$W(z`j@@%L5z62^@q{u6 zL*>E{CUu%~je2W4>BK&8R+Z<=Sxk{y)@1aWR~z#!F^QCq^b?pVoPum zuc|g#OAS#$(hTH|FW@D-j92g~UMC5hz*{7M5AY#A!sj@NQ}_a3hEn(uzu=GPOBfpq?k(l8Rv6mH z1$U_{@43FWhx(L7alTtzyCe+Av!7C(y#KdN{QG~{DK26LVg~-744|^Lt932C+eEvu z+~zIHyC};f`;90JU8o380>bb*PB`|5Aw65vRr(|&98pLXN|*eHfOEgj$LD{1{)bU` H`4xWygfJ8a literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Tools/scripts/Profiles/Project_Debug_OpenOCD.launch b/pec930_sdk-v1.0.1/Tools/scripts/Profiles/Project_Debug_OpenOCD.launch new file mode 100644 index 0000000..922e717 --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/scripts/Profiles/Project_Debug_OpenOCD.launch @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pec930_sdk-v1.0.1/Tools/scripts/tags.sh b/pec930_sdk-v1.0.1/Tools/scripts/tags.sh new file mode 100644 index 0000000..725f5ed --- /dev/null +++ b/pec930_sdk-v1.0.1/Tools/scripts/tags.sh @@ -0,0 +1,349 @@ +#!/bin/sh +# Generate tags or cscope files +# Usage tags.sh +# +# mode may be any of: tags, TAGS, cscope +# +# Uses the following environment variables: +# ARCH, SUBARCH, SRCARCH, srctree, src, obj + +# +# e.g. +# $ make tags ARCH=arm +# $ make gtags ARCH=arm +# $ make cscope ARCH=arm +# + +if [ "$KBUILD_VERBOSE" = "1" ]; then + set -x +fi + +# RCS_FIND_IGNORE has escaped ()s -- remove them. +ignore="$(echo "$RCS_FIND_IGNORE" | sed 's|\\||g' )" +# tags and cscope files should also ignore MODVERSION *.mod.c files +ignore="$ignore ( -name *.mod.c ) -prune -o" + +# Do not use full path if we do not use O=.. builds +# Use make O=. {tags|cscope} +# to force full paths for a non-O= build +if [ "${KBUILD_SRC}" = "" ]; then + tree=./ +else + tree=${srctree}/ +fi + +# ignore userspace tools +ignore="$ignore ( -path ${tree}tools ) -prune -o" +ignore="$ignore ( -path ${tree}out/syntax ) -prune -o" +ignore="$ignore ( -path ${tree}out/uncrustify ) -prune -o" + +# Find all available archs +find_all_archs() +{ + ALLSOURCE_ARCHS="" + for arch in `ls ${tree}arch`; do + ALLSOURCE_ARCHS="${ALLSOURCE_ARCHS} "${arch##\/} + done +} + +# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH +if [ "${ALLSOURCE_ARCHS}" = "" ]; then + ALLSOURCE_ARCHS=${SRCARCH} +elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then + find_all_archs +fi + +# find sources in arch/$ARCH +find_arch_sources() +{ + for i in $archincludedir; do + prune="$prune -wholename $i -prune -o" + done + find ${tree}arch/$1 $ignore $subarchprune $prune -name "$2" \ + -not -type l -print; +} + +# find sources in arch/$1/include +find_arch_include_sources() +{ + include=$(find ${tree}arch/$1/ $subarchprune \ + -name include -type d -print); + if [ -n "$include" ]; then + archincludedir="$archincludedir $include" + find $include $ignore -name "$2" -not -type l -print; + fi +} + +# find sources in include/ +find_include_sources() +{ + find ${tree} $ignore -name config -prune -o -name "$1" \ + -not -type l -print; +} + +# find sources in rest of tree +# we could benefit from a list of dirs to search in here +find_other_sources() +{ + find ${tree}* $ignore \ + \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \ + -name "$1" -not -type l -print; +} + +find_sources() +{ + find_arch_sources $1 "$2" +} + +all_sources() +{ + # find_arch_include_sources ${SRCARCH} '*.[chS]' + # if [ ! -z "$archinclude" ]; then + # find_arch_include_sources $archinclude '*.[chS]' + # fi + find_include_sources '*.[chS]' + # for arch in $ALLSOURCE_ARCHS + # do + # find_sources $arch '*.[chS]' + # done + # find_other_sources '*.[chS]' +} + +all_compiled_sources() +{ + for i in $(all_sources); do + case "$i" in + *.[cS]) + j=${i/\.[cS]/\.o} + if [ -e $j ]; then + echo $i + fi + ;; + *) + echo $i + ;; + esac + done +} + +all_target_sources() +{ + if [ -n "$COMPILED_SOURCE" ]; then + all_compiled_sources + else + all_sources + fi +} + +all_kconfigs() +{ + for arch in $ALLSOURCE_ARCHS; do + find_sources $arch 'Kconfig*' + done + find_other_sources 'Kconfig*' +} + +all_defconfigs() +{ + find_sources $ALLSOURCE_ARCHS "defconfig" +} + +docscope() +{ + (echo \-k; echo \-q; all_target_sources) > cscope.files + cscope -b -f cscope.out +} + +dogtags() +{ + (all_target_sources) > cscope.files + all_target_sources | gtags -i -f - +} + +exuberant() +{ + all_target_sources | xargs $1 -a \ + -I __initdata,__exitdata,__initconst, \ + -I __cpuinitdata,__initdata_memblock \ + -I __refdata,__attribute,__maybe_unused,__always_unused \ + -I __acquires,__releases,__deprecated \ + -I __read_mostly,__aligned,____cacheline_aligned \ + -I ____cacheline_aligned_in_smp \ + -I __cacheline_aligned,__cacheline_aligned_in_smp \ + -I ____cacheline_internodealigned_in_smp \ + -I __used,__packed,__packed2__,__must_check,__must_hold \ + -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL,ACPI_EXPORT_SYMBOL \ + -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ + -I static,const \ + --extra=+f --c-kinds=+px \ + --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \ + --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ + --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ + --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex-c++='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \ + --regex-c++='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex-c++='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \ + --regex-c++='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \ + --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \ + --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \ + --regex-c++='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \ + --regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \ + --regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \ + --regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' \ + --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' \ + --regex-c++='/TESTPCGFLAG\(([^,)]*).*/PageCgroup\1/' \ + --regex-c++='/SETPCGFLAG\(([^,)]*).*/SetPageCgroup\1/' \ + --regex-c++='/CLEARPCGFLAG\(([^,)]*).*/ClearPageCgroup\1/' \ + --regex-c++='/TESTCLEARPCGFLAG\(([^,)]*).*/TestClearPageCgroup\1/' \ + --regex-c='/PCI_OP_READ\((\w*).*[1-4]\)/pci_bus_read_config_\1/' \ + --regex-c='/PCI_OP_WRITE\((\w*).*[1-4]\)/pci_bus_write_config_\1/' \ + --regex-c='/DEFINE_(MUTEX|SEMAPHORE|SPINLOCK)\((\w*)/\2/v/' \ + --regex-c='/DEFINE_(RAW_SPINLOCK|RWLOCK|SEQLOCK)\((\w*)/\2/v/' \ + --regex-c='/DECLARE_(RWSEM|COMPLETION)\((\w*)/\2/v/' \ + --regex-c='/DECLARE_BITMAP\((\w*)/\1/v/' \ + --regex-c='/(^|\s)(|L|H)LIST_HEAD\((\w*)/\3/v/' \ + --regex-c='/(^|\s)RADIX_TREE\((\w*)/\2/v/' \ + --regex-c='/DEFINE_PER_CPU\(([^,]*,\s*)(\w*).*\)/\2/v/' \ + --regex-c='/DEFINE_PER_CPU_SHARED_ALIGNED\(([^,]*,\s*)(\w*).*\)/\2/v/' \ + --regex-c='/DECLARE_WAIT_QUEUE_HEAD\((\w*)/\1/v/' \ + --regex-c='/DECLARE_(TASKLET|WORK|DELAYED_WORK)\((\w*)/\2/v/' \ + --regex-c='/DEFINE_PCI_DEVICE_TABLE\((\w*)/\1/v/' \ + --regex-c='/(^\s)OFFSET\((\w*)/\2/v/' \ + --regex-c='/(^\s)DEFINE\((\w*)/\2/v/' \ + --regex-c='/DEFINE_HASHTABLE\((\w*)/\1/v/' + + all_kconfigs | xargs $1 -a \ + --langdef=kconfig --language-force=kconfig \ + --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/\2/' + + all_kconfigs | xargs $1 -a \ + --langdef=kconfig --language-force=kconfig \ + --regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/CONFIG_\2/' + + all_defconfigs | xargs -r $1 -a \ + --langdef=dotconfig --language-force=dotconfig \ + --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/' +} + +emacs() +{ + all_target_sources | xargs $1 -a \ + --regex='/^\(ENTRY\|_GLOBAL\)(\([^)]*\)).*/\2/' \ + --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \ + --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \ + --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' \ + --regex='/PAGEFLAG(\([^,)]*\).*/Page\1/' \ + --regex='/PAGEFLAG(\([^,)]*\).*/SetPage\1/' \ + --regex='/PAGEFLAG(\([^,)]*\).*/ClearPage\1/' \ + --regex='/TESTSETFLAG(\([^,)]*\).*/TestSetPage\1/' \ + --regex='/TESTPAGEFLAG(\([^,)]*\).*/Page\1/' \ + --regex='/SETPAGEFLAG(\([^,)]*\).*/SetPage\1/' \ + --regex='/__SETPAGEFLAG(\([^,)]*\).*/__SetPage\1/' \ + --regex='/TESTCLEARFLAG(\([^,)]*\).*/TestClearPage\1/' \ + --regex='/__TESTCLEARFLAG(\([^,)]*\).*/TestClearPage\1/' \ + --regex='/CLEARPAGEFLAG(\([^,)]*\).*/ClearPage\1/' \ + --regex='/__CLEARPAGEFLAG(\([^,)]*\).*/__ClearPage\1/' \ + --regex='/__PAGEFLAG(\([^,)]*\).*/__SetPage\1/' \ + --regex='/__PAGEFLAG(\([^,)]*\).*/__ClearPage\1/' \ + --regex='/PAGEFLAG_FALSE(\([^,)]*\).*/Page\1/' \ + --regex='/TESTSCFLAG(\([^,)]*\).*/TestSetPage\1/' \ + --regex='/TESTSCFLAG(\([^,)]*\).*/TestClearPage\1/' \ + --regex='/SETPAGEFLAG_NOOP(\([^,)]*\).*/SetPage\1/' \ + --regex='/CLEARPAGEFLAG_NOOP(\([^,)]*\).*/ClearPage\1/' \ + --regex='/__CLEARPAGEFLAG_NOOP(\([^,)]*\).*/__ClearPage\1/' \ + --regex='/TESTCLEARFLAG_FALSE(\([^,)]*\).*/TestClearPage\1/' \ + --regex='/__TESTCLEARFLAG_FALSE(\([^,)]*\).*/__TestClearPage\1/' \ + --regex='/TESTPCGFLAG\(([^,)]*).*/PageCgroup\1/' \ + --regex='/SETPCGFLAG\(([^,)]*).*/SetPageCgroup\1/' \ + --regex='/CLEARPCGFLAG\(([^,)]*).*/ClearPageCgroup\1/' \ + --regex='/TESTCLEARPCGFLAG\(([^,)]*).*/TestClearPageCgroup\1/' \ + --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' \ + --regex='/PCI_OP_READ(\([a-z]*[a-z]\).*[1-4])/pci_bus_read_config_\1/' \ + --regex='/PCI_OP_WRITE(\([a-z]*[a-z]\).*[1-4])/pci_bus_write_config_\1/'\ + --regex='/DEFINE_HASHTABLE\((\w*)/\1/v/' + + all_kconfigs | xargs $1 -a \ + --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' + + all_kconfigs | xargs $1 -a \ + --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/CONFIG_\3/' + + all_defconfigs | xargs -r $1 -a \ + --regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/' +} + +xtags() +{ + if $1 --version 2>&1 | grep -iq exuberant; then + exuberant $1 + elif $1 --version 2>&1 | grep -iq emacs; then + emacs $1 + else + all_target_sources | xargs $1 -a + fi +} + +# # Support um (which uses SUBARCH) +# if [ "${ARCH}" = "um" ]; then +# if [ "$SUBARCH" = "i386" ]; then +# archinclude=x86 +# elif [ "$SUBARCH" = "x86_64" ]; then +# archinclude=x86 +# else +# archinclude=${SUBARCH} +# fi +# elif [ "${SRCARCH}" = "arm" -a "${SUBARCH}" != "" ]; then +# subarchdir=$(find ${tree}arch/$SRCARCH/ -name "mach-*" -type d -o \ +# -name "plat-*" -type d); +# for i in $subarchdir; do +# case "$i" in +# *"mach-"${SUBARCH}) +# ;; +# *"plat-"${SUBARCH}) +# ;; +# *) +# subarchprune="$subarchprune \ +# -wholename $i -prune -o" +# ;; +# esac +# done +# fi + +remove_structs= +case "$1" in + "cscope") + docscope + ;; + + "gtags") + dogtags + ;; + + "tags") + rm -f tags + xtags ctags + remove_structs=y + ;; + + "TAGS") + rm -f TAGS + xtags etags + remove_structs=y + ;; +esac + +# Remove structure forward declarations. +if [ -n "$remove_structs" ]; then + LANG=C sed -i -e '/^\([a-zA-Z_][a-zA-Z0-9_]*\)\t.*\t\/\^struct \1;.*\$\/;"\tx$/d' $1 +fi

    l6e!AVRN_dN=IE*mJh5W_GXf=5;BqYw4^ve)13M` z%wRO6U{;%zUp8NTTz&fs&FDo~H#wPcIjNCf|{p8nj&D`!iq1uRrrAh8>(I* z`Tbf#(mQlon$J)u$PNVKx`J0*Z6~P@xGT;Ix%G%8jY@#`mH>RKCeF-)Se+oD?TTr{Xy~?#_2DG zg|!7hI?ii@J+2R39aw=xJ8CNo-J0zw+k*JGoOsVYG<>cc`p#gHRA9csoDkPS;RqsW zxwSPTn#Z3hIW;eWWol&pm7Ky`J1$j%#@*aAyge!Om4<}-;mhk(4~}(0k^rc2HnW!E z>DeD7&)zLZ-2Hy}A08?wD^B?tP&Ek=a}RLr;!xHa=Q$`BS>+On$%*a#!F}UrP%eP+ zy@ea<;QF!Ap-tO$=non`F6qKKEniOj!K4(%?gMtFd5yS4+t@#HR)??AsQscSQqrJb_(tpVQ1UQQ*N!a%ge+#^u<(g1H zJ5k(eIrJA2fb0BL&3VkEcq6HM;86uq;Hn2~{XcCc0JLez=J4sJpPd;%IS9jW|<&F%qizyLW%r`Gtqv1;~orQSXWm+z8mo_=R-Mo|J z?BDMlne{aUEmT;p-N+}k;Nj@MX7KtFH|eo%>mx~={8C72K5EID2FLgE5W1}OU27dY zX`bgv7&+h`#P7SziS_TEwqU*R5;5?YKoS3^Lj+$3D84+`WxCId92RL!2f{EY1MGSp zz7L~D4DyTWKpy5E2=ojAt>7qYu_PnKSArbuaXEMhv?2=Z?xWul@7JCN3PA3i`7ny@ zf-e{xtPu-cL&0WAQ3?`^nXEXWR@xG+qRn}}v7GTcb&2aU55IdaCJKZnvzo+pYJQ51 z@AO)LZ|t1q6Nls!o9zo6eJ3l$!lfEvH>~Fzoi3$l6-_?4eVHX&MSty6wHR5(FVf-g zjR@?I>VR}c3K0a}*>5!7c_R{+d17Nv$PJ{yB`F~=#MmX>5IJdho@gqSwY_wo2VCX7QQ_3=~J(HS%uRqO94ZKc>@z=gk^9Nz< zJ9Wu=q$^zr%`5e#N9|Z93ULA6Q@bWE)Oz4}cj4kUL(^&->2}jKZm%4st zadWuj-N4}%$Tec!z6RbBs;Q7T)!YnS`X%2}|7hWCL3v|8l#5DH(ElcIz|jm4P{u)* zX{mAOjzl8&Sa~^K+pEA@xn-tpbc^DSGh*OXvIzuxja7Iwv|iXZ4_MlDa3F3gUALPzO_W4_%3F<1fJ% zP>@)&VA^nY^?{L93b|;syYv3|ncE2;Ap);=A%pf8fmyW-J0q9Kads|?jr%`zg)=;M z+@7wh*LEa_zO}vTR2HXbb$on>HYJ|zTpvcQYmD?Hp1Quj7_=$8UY>^YmfUm=XLwtAlaG$^qj16NFE{taQVH=Z zy5}qk4}gGx0-y&MZ-g>HyWc}`w8S96U=koHI;{w#WV1fCbK$r%|HQr%d$0urDoz$4 znj`yz1fOiFa`O@phT7uBh#|C8(8VAq@mbD=Kv(9`eQz58aKrE?P}}3?b8>-z#r+%J zDZNf0v&m||XnyQ1w(hq_$s+j~{45R~(Qe$&+t*$*dyaZ0ycIwGs`r>Z9rme7X({!t zJAv73WcMgl(&X(@)2MBI%C)brY{W(SUj@MuG%V4NXHBaH1Wt6LL7OizDB?8%AdB0( zb@w}s_1{Oq^|!eQ6#{+~x|4YeI^4Ph!{5*akY`_^f0;>nb_B_WIpMr+HIL_%h4URD@|4y9G!-Zf-wv8sPTi?Je+zJYSJmBH z7Z%^~Cfat-m&VD7uX2=oR{b!x)C}2pUJFl|m(34h6p{_@zO0= z;JXxk$(0h)^uNnn?cdC_gf!_te(66c4spE55)!BOy}{?rg&{EyG*jVx*#{!oNDoR7 z_Y}-^h^QBEr0(xGot|oVll7{&r`SOz(KoQjgWhcJ(OQWmdiF{1%zYbE9y@n1Z@bWk zr{%0BpYP?Vki7X5;dep&6bKwt+I&|4LvjF$N2i3Vcpwk|`4~9I@=qq*yp&3)UD-dU z#({t?%xxG^8z>r~7LM33P$I(=7e3X@;Q3XTlLZ)ZQwFGx;RVV;XVS1;Bo}np1xN_s zbS8SP{4zqc!RolVESF}xxt=&9Pw`8+hcw~(}zs(pvygAy_CLrSPXl2!Cp1e9aG;fM|D3EbYyXi7Z-?yBYJA;M>Jv{V-J7%h9L7$%v z1HX51A9&Jk7;iA_A`Iks*Le{QetkxbwROSQt6z3isrGJ;YJ?b*gj5faGX?_3VJ*O4{`?HE&LZrJ%(wKIYg5=h>sMDhvylFdeGIf> z{AbkuAAhY(@Ghy$U)_M(-|W4*@caL)1j+>aGEuig$}0$&qLq0lXtT|Qgk=}p`RyxD zds$f)mJLag{r{#l|F<+!Mv<@OZKlC$6La4*Ifn7^mPRSy4xb%C&nbT+arBuhkIDZg zvcG#xE==+!z}v<+2F37!x++ZP+Y8N0Cl62xV(ArZSB+5QWUiARfTQ-`7Vdw_iI>q{ zbL13lz*09jrqqV)y*2krWh{@DY8p65bMkEXLYqpqM)Q~_YE`ZRXHQiA0{w|RVtC9l z< zGEUds`=!OxHJ63?1r9^P(P2t{5~p!L9vY1B?CkkSV4-Rjk18=&*o z;?J!#Csb)n&h6O*RPkt4ZMds&n3US}3U#5e0;DUIEDog&wa5T{Bcqv9?Pksyp$r}K z&Tn?6?R46mqD2dql5h>klu6lu@|IJtVFoW)5|BM=rEp<9 zcTw+Ij*+N#FHdRmI$^*FD>4z%s{)~acFU9YV?dwT6m z+4)s`qJqs3kig3UQa7P7NJuId?G_gmQOf%Q*ww?28pE7i*tDixzK`+{2;KRE*owSJ2f!7KavQKz!QEEJqO6 zOXGOu;=W?XluxVhfkz#=@Wux=A3r~TlASG>eP)fnspwgclgimV;F$3WlloP0-d@Xy&@ho>Sp|p}ufB!In8OY4_Y@*LSK8T>13ro+O01m`bqG1oq|C(n3Ko9{ zEIDk?!$}zcaE1nQpz?paHrK$G<#9X5+KSt|dOQ{j=G9JX9hlzDu-!WhB26F2?e48U zz_W}%-z-EDStpt#fGX<^uosi>adVX1z*@UDq!8Wb##mkTwCsi+`3D(k5}la8>KT(TW-Npe>PX^zfa6)*wc4$nb4=k#SnVgd zl%Y=dYw;zG#-k=iGp8Yv&u6f6Q7R8z0f{Y%Yn9)44=}@L*}5HARuBzm8@jWC@&{WeQFWFtq*nHIt4Ng zemR?oNt4nkZ=ufcv4p+Sbj|@qbuVEu0yQ#FzD?&HRNNQ@p(+fYVXBL-lh$Fw2PTTKBNXveu_hjeXp-gfOU*f%C)6!x$O zLe-4~hnvpJGK0Us1XX8j;>d$@f9pldYV_nmnio<9bHC=UCN#kcOOkP|Scn>q19NcE zF>_Q#lT`4nqqH<)I!-0pwK*a1kS5nPGmnd0kyROEzZ4R=-w?nS9 zA-||lQA=TLR#QtJ&h(H)g-lTJPO;b^7sj+PT}_h^cSO+AHJr}(j+uniTRpVxhG{+fgw6}LMN;^vG#Y&z0zdi-;F5r9lyW=VS~S(CpscyiocybE4U)2W!J#?{rZ{mLxMx|?M77Hy zl%L&V3FISS#5PVjLit;NP@%sBZenHs6H#Dv?>3^zNzAh4lh(NV$yc8)Et5AY7tb^Y zvE7Z&KKs0o9%KI!5JR7?uBTTb3Kp3wbKA_j+pD8zWC>V7CMGW_tPHPJu2E`bGL$!P zhePx(bn?lE7NGz3&ViE7?(oq*ZR=3Tb37~VRW{CQ!2~N4W;0UOL9UObDG@CycBG9P zl02o48{FxPxk{%*84*?-nTeUw8Fo_S_HMHjGie(4xVI6uWi&>&_UniEu0fj^xu~qj zshZAtpF1C14k*x`D&suzL{7t`$^@QN`j82^7S5p{46Dn z=@PPie}<=nY07Lps~G30O?mT2)7aFmoO^9e=G(f42!UC;Jns$oWBuEyui>;wAWgjH z)Nuusx8V6jdjmP1?^eep#i9Iw26-`r-Guq+=;acGmJCmN-4QmDHps9GUGF9ievWFLWJdrhvNKb#RL$E(vpLfD10_8hC_AYpjyGD=Eo083Hx?r_5TSSPhb#+JSK6_+!w^{;^(}N!J z7Jqh}9c^o7$Stwp-D4PocgUk#vyVMMH@2#_Qu4o_2_NdZ-V@&IH(7jj^G0D|L}3Hx zbn1mF-h1>9k~h##W~gYXNNu&}@X@D2CtBA!l4M?Jiz~A`ls@L|xf9bwl`(MuZFj+$ zaUp8khZt}rKr%9{LMPMzjV?6~`XWi&Qgr@>nY{OE)j@89_mq5!QJ>Qy!w0`1oN#c> z_sq)WEh9HV#+2&Rjx*x2&ds*Y#b*~3>mQMeQa}q;D-~YDRp0}WPou~}^@o|IX}8^% z&n8oSNv^yYlIv+F>n$!4(PqECEg7V}9CIqL_XAhNVy9#7c)-;c*JnOO`hvZj7CdmA zUQ0;yr;Y`9MTFC_Qki#XS0DuWV%05|V zrFiDKl!8xA6TNQC0Tq3?vZN?)jP0ugyI1Y^$Zn{S-NOF>7XSCaVJi|`FgAO6V`(?# z$y;S81oESwX~-Zc?Q5hn%`EN0RnAu;2VWS`M?5E@n2gFr-D$3+a@g{flt=d3n7Jrs z*JpXQwH_bIzy3U6y?SG#VXWKEi2X=VH(d?varD+gKC0xn_?xk!x0=DJR*%Ke%>S@4 zAXNim4_xq!`X`O4KNUqVKwj)ZzOPJr%5)6yJ7gH0lQCV}0p9!ODuVaj7sTadUlhDm zdT;p47=)EL;jM%d67gayK%(1Ts|kZYr^zfDfPiTeip({!sN0FGJePGS^y@7^R?WI9 zKo}57NPO#WkC_V;Hk-XBHFRYrFS@gclqg_SHJhDF+28)Qh_`ekn5=uyh9vQYq7Sb5 z;<3LiuKCYF0TI9v&}WFdP^%pEmnkssS^7F+Z$6;n)Z2PepS+}|Zua3D-Fmt`bx*GKJkq)pQ zfA;Ol`My1MOVjZVZ-f@^>2qDS?%3k*u||uko*!tFGIFOz7=dd#8T#7B{HY0vlF3J6 zOll=+D;jJa#v)un#~j+i<-AXWw4P5Mh)#Y+Uz@fdr-@Ow2Gd8M4SPnnxKnoK<8h5C5D)V8Cn5a+-Y%{T6H0l*y?7_b80cYu^GJ$ zR*_f9%)1YSu9@?r8dKEb|!=?#oa`&tJ@fcwG6b9%>EKsIV=^E+;~wT9sa(0F5c2wSAWUX+w8bn~Hd zDMPPX^{7Moim{Q_XT;3yU|yg#ih)xL1JYHzMjW=HBV^-ceTuz7#+GJdTFn9Cm`Ip6d(;U>UgK)6u?l`#79}+;aQdK8jepASc2lzN&Yc>? zE8rQL)FpzRKd96SVzgh>eac|*#q3^FUAyZ2FzH}QU#=#f9R-<1f#_;WF>PG8M}?>s z3-Pw&@H6snmOb8jHio*%>ED74ADboz74m+xevoNDBx-=x98D~1j)Mnqpv^eDtUsRj z#V;g?(9fR-l6N(5;crTGEie*qZyD7D-oaXZDwLdJh}PUT^gilSZ(2z3|KgwKBy=k- zCytg1vg1Mt>}MJ?kA&13CY$67I`ig4if1j#>p<1F>8odtr?Tog93*MXG6VU4sQ*iBtr-`WT(~u@*$npXW z_`EDCQYx{)iDRxQqV*H%PUs8DI2t8#?pO=87^K6t?iKIyZ8Zc28SStAD5ljzG(3;3 z+sV$>luQ&I!h0|;gCardvWj^ohu8ZTo6X|JMbLZW6lAD!3 z$)?2U>?iJ1e&vA-8KFn`AY~cl1Q>+3Z~o5L0#nPb-oD1eh7r@$OlBk)7M3B9sU80_ zkPeH8fr(Vjv5hUkJx||G&y<|T_X;6uN$WOZ^x&|+_w4nB(zQu@K3d~cEheNNV%&`=;3J`k6;XnkojD?K+nNE@cuV-y5y( zIalE9xxxBy$ZQaR^1(W}=s`|v@dg-|6X74;cGYN{&E)MC;-IeNteSBCgM%bKJ)4KT z(%3K5zTX0c`yS9p-jf-ei-#M#6sR0NNK}i?&ocv?3N`Cj9qDY0N$OciT&VjiV<(O~ zr$YQMWz9M=h!hV56wO$2CyqNionS-Qo_1c2O`IkB5Io4@Wdo-)QNK5tP(Etqv=ciN z+TL4IbsVTwKjl5P?4DF54O=pG@}PE9I_wV}_@rwUoK~(10Qo@rC~Kh!;vGkNJnslz zqo8MbfYzcZX$SkuJI>UpTm<`0^-Sb6Hqn6hD%s8#PC4VCEh}+2PRK?YvFKNT*=sHc zsck&W;Z9F$M)cET3b<{*aOhl9M4J2a;{05fQI*)x@I;pyOVwIwGu!UVzjI?)k6C@zQH&DLS#e+h7#QcMtcgk*agHfh*%##6a=(`AqD2Tnlzm@t`suSvE#>q%CeDP+0rhn6|a z*l1~ffvaYPEF8k+c$rW1G=w9six;CLb$06tE!)>v2Nm@#MC)_G#0Qwk%w?AwxD>5` z_d-KeK5@T?6dJq_az$S8-rwnu(5n2B9Ut>io$+Zp04uw?{m%e`Hy#eXP3oMz3DGF}N z+<<}|DF|7`j8W~k*u#+p3Q3bduQc~KjGklaR)*m|cx zK(uDsLRMy|wb`;37k`yURcHwo!*{uZDxqn z)$usXx*|N)hQtORF0R9gvfh&}*V_v$1G44aoGQXz$L{ZzOCM(m(y_A0Z$g5pw)za}x zIDeeH-;bj8-qD1sEUB!ob;LW4_stOTOJhi*spg8W(A8?jvd8SY9b&K)+V*Hm_lt@e zE9?7LvZ|vkvj?U3`ba3qxjj(hZ;&5>99=pWYM!rlbmxfR$Xb5AFwUFK=1H+h$n73> zD)%iFpVM6sX4YX|pcZS4mJuz2x;QvRdEaeQxXh-osy0Si=7EIImWahD-f@yem&s*T zB#V&vCb*p>THWEI+bid9taPD5TN$-}lI=OMVNAR=?5s%bU1E@`Ic7U~JK&8$ zGsHmV8g|y=>@9ECPWeRZ5DViZUJ2tL2*McU+jJxSE3 z){5K1{?_Cncse(L%RZTJJkGSb#P1q@0%kySAf(M!DST(}U^jDaF)BvlX-1D?3DC1r z`sH`!fY`NY-*!J=+PTAV&wYIdvsA|!XgV*1DpI&oTxkFK3svP$AJcY+lq`(fX(+HwbLsQlGiEbr&Z$#yY&3Fa|zN2`q30lkGh2ml0y1#@3Jz1dU`Szn96`$5Y`9 zWm=J;(!L@KVNFWQ15ZHn^NtOjJGByX{f}o2)CbnO?qBXIpd{z}2LEvt*m>{x!LB>% zbw%^WnQ0ami}!1?lgOu>U9`8bS2p01a`QGKuaq8G7Nu&%^`zXLUI>nU8p->pA1AlCEp zdQO7P(dnx9L`esv#_82L`g;}6yboB_`ntqPzSC5-x9cG~OEhd6Wchz}&j<^Bklt`5 zGRki61PEngGgr$M;0I)5BOp)?UAAk^Xu1!%X5(RP_kR8Gp>A%*V-K)`wIYvCLr#riE%3 z=mBGs=EQZs`Y^VLaMq@}E)tXRrN^sqCQp(TkVtoXJPvTC%$S9_J#=h1BZRm13n4!!bug_Q$%VYgCj zoT~|_T43jQF5V487>T>~dMa^hXVPmZZn)xGxdF{5Ps+VkZV8(r@@zuNu?W-X*0Rv3(QTHlsKR2-%gW#{S(?Pt)*}1 zAJbO59JK7uJ2h6KGy%}BpvwoT{Rk*fO{(Ui`hA*`j|d=SoASnt`yY_i9_5+N((R0>kP5N<=YSFUSmu7& zd&AvGfA!`ogG=X7LIoH8unDNGYd~=+AOrxG$?(d=QHTMTd|2CYO0Ibs7_Sham^oSi zk7cwuf9e$&N_)ZU9eB}ZT~*NjNXVczWlVp}|6bmVWviqU`8xQ;8f4|lIJ6SM=2y5cEX4&7 ztnR!h*Gui4ExyS1v1w&e3!v;A`OC*r36z6mxd)O{>AS1K)0p?IB#ePq@p)HaeK`rFV~a?K;< z3x1p=XNEBF?w=Q2t)?8&{=?VS`rlPQ7>lZW9+hSo50)1>8mq6N$$KVj;h@p^$THO! zuLkzDEDy~$|Md%v299kVKg`jsEHQU^o-^thycGQKCtSUR(fGm&bhhF12g!%HKS;2W zPzV5yQP>Az=&gzTHBkmO4$1X0B_hVj#9wB7K+`_Zyab{%{q5!o)_);?IUlC{=d!GH-McS9Wzk$M&g6 zzAufH-W*78q^_Jv5M?eBAgV<^S}!g|JJ`(Caeojon$ za`f6KE}ct?vB3HN=S)&NG8_W1nGtzmT}06s+1CiLncwFhRFU*mJv`C7YiBtkEZolw z*zXGb{;LYcY$lfy-j}$y^V*vA`jC?a%%dV!3O*IEx|us6h7Z82-yF07sG&islfY{7 z`-p#9KbE0C%*th!*7IC^R$z?Ew4YapZEG_g@MlkEs85EAH zZncvp=;7cY(9;E&(Xyl2*7yh`kUA^+ku{`R+H;5nAb9LmbojD@Mip>*hCIuiaY^GXw& z_q+&ZxuU~~b1UG^c84*2^Vl|1UZTTlZR{T;6F-%U&s-Os!xAr5k&h<)(~3wy&!&ko zrL){sG8N-RislsyR{UjN4*#luawXj^;?|yICCZi9 z5}J9 z%NG^foyR*d_}cuzJ*~oy;y0?14xxUBCtm-)ihLg`bh*D=ft0Z|wc~W@pf)o-C(SB&y+Q~6lPySixhUU(NTSN6wd7xR z;g^C|gUQZa+MqNGIGgs<8;(p!n-s15SbZYB(14qu;Z^_bTw^OG!c24yE4i?1<6riU zzpfUGi3j3EULxp5-@W6R4Lf!PFdt*KW{=OE2}X{xQ7h$jwMJ+4HO((d+(ERDl!_tC zelpK{$Haeh-GJWwe!& z`=!JiwlJ^wTHnikjqk`=6oJ@)g0JAT9E9Q2CGx{?8X}-(S72v2fMTW69Ub#zDBg}) z`%EOQ2z>5PX4IJ-j*Dw(XaJX#7jN4fa1q%}v8O~v0pNO3^gQ*2qL&kpbwU|k&;b2$ z@*vv_nfTNC-={6m=79hp7$NH+L>=${%3LgO&ca2S!6!X*=^%%YDnxZ$|Ci+Nwb9w) zy`;U$Pf`6ZuLn_(#0hQE{_A)op=}yq!Zr*~9uEXG74j5cUttbUs`vfOjoo(O`*dy= zE0h@TlJ~N1^1P{m$gC_Cdtg`nm!ISi>9utCEuf1EnRspAg4VSCR!hwV{b3KL8cbRS zZOkL3Vf3Sd>FAMZ*29w>i@k1(MMA%Qi~_kXAq?*U6c2#f9>P-QIp#D<(i$j_t#mTg zq+}F$|{-+Vr+=6-{(UW2z)4fZ~p>l;DoAEdkTW}1fWLEbHsuQQPia4?ZP zD{0*WW1Oz8{9o&39$^5NOXs<1Kd^iGFRzz(H-^(<;OOC2rxwlMqf6@V{PJdtsOP z!C$)&oUdNpSA*U()uyi&{i_Eda&gVMj`q1?xzbfz3`WD~N9o{J2Q*`r~F=ev#H>nm4j znW(aR|5-9#mW0`+Pd@EEig!}%pXMhdl4F%!BDJrgXxyAyQ!{hU{;ue5!ObJjhJBlE zf0qls-v9&&IO5{~0yHi2o5T9L!Jr@h-`ig_sl_uh`(JshI#S-==-EN#%3^e~1>nj4 zea(%L2OHcgoa;Gu@x%kz?<@Q7gFS?W#YKmjB`e{<`RjYHGQZqpNXB<)#|;yn%NSht-=;nZ~3; zNwuh6GE$anynPuvm6mDNixu0M@LDF=Tqr-sas#)D2>&j)_BmKt5H9$Ts@3$v8?q0s zX~qCv?%!RW&!Z`OvE%fX-aMu;Ec2$hmFaqPS`wAfA4q6&Gba8)5yRxkc;!Z2F0e6E zm4n>;bVVF+2iTHH1)X%;ovvw`>mKq${g=?AKm5s;U^u0Hk9+ZI;}pmri9LY>ix6|w zCu=(E_xcLay)wPC_TMWU|49ubgP5yX{69P*yQ+|t<|T_GD4$CqPqOE44vwJ(p@N$b z(7!qyE=-&m^v_m-ORInQQw4VMXA>F?xU)fl}A!qy#K1T9VmW6Y2kvXz! z_sN960AF+4?+bJX|Cr-!RObau#(rR&-37GO;EGcD%L@6+E+CmwM~9mzXKrn%{e|C0 z5F%W7dWMpbHcsdmFMAf0Y(*Mgs>uJ@aFb1eg`D@7-_l9uYqi8yjeKt_6`x^E>{(_L zcbr#@Yxhso=-))}SJ^(Jm4V|vxjMOCmkGhY9BJo{e~Foe{7$*sn#;-^6>Qc~ulJ%2_e_T%_!xd5!3dT|epFQ@;0izUK z2Ja*8d0e~G9MdfYJ2x1UlTGrXWHOv}?Yg#WIrZ-^vEfTVd3m6AS|L;7`851Z;DRFF zhRZK-=VC+gSUNo090%1gH#dxZW#o0X1~!3Ldh&fs6(T9Uk$&w!T#fp2W_~V zPJNBKhsYz_$bs-0LN>v*umT>GOvfIZGMht*2L`5ijd z^I0;_`k;D)ge+?4HTzBye{R$vO&5wn@3LLp;O8kW}N9Ntfh}Y z9WqIQ;^Wmlk{o7(U0v7sKN%%z+1M9WXS~5>8zdLdGIfgDMMx<+z6IaExJ#XV>FNhx zeJ^6d5E$6et1Wext%??LE($|*4l^G4Wj>Hqb%j*(BGK1D+H0QDr|>#9!$?{&UXosQ z4w~qYwLGB|tZq0IF_^bF6eE*y1+(8K77nG8qL$IFnvi1Ky}F@P3m;o*Dq?pW0faM_;wnjN&bGXCOwdmf3k7?`EIG-{~&y&uXh96S`0SP@qf)xHSPt z|8&&zj_!Hh)Ju^tc&?{ni_0;s$7}>6M4pUkj7wdVuxU7Rk4c_>6h$yU75?#btmoz( zjcb(oraVzhZ0W|rBvOUtEZ3$-o}E0O{F9xl)p9(gD^Og?X5+}d&l@Ss3CzHbqR7tF*#T+VKZA(w!= zpgxZgnE-0M6J0z{!{9GtU^Jauh$Y+povJF-C}wkxm4JkkETV4Uoj&a-V(n zJ$s*X&wal)?tAYy-nf6@kZ%Sn^E=m?bAD!7a~^DGEy=w$Ar6VBVrUnnn+V&7k*gjI z5#&nk6ZMt%AnlsO5cI!96#@l1oaD3+P@TEVF;jb*>Q0Inzk}wd8BsX#hM%x~H2IjX zl=<@-WyKmv4|8QtwMV?x?WKdgO@5)scq1=5jAL-5e-E>H|w z$C8X%xFttsk)jH@<_7G{%BdR(? zx@)ygu2UsG*utR~ z?dBIb1YIsVHq!N2S+ChS8GfJBsu8bu9lAQ(%LPjD>p#)o-bQ{&Ap^5~Fa^gj#_R7u z{n@Dz`&wX79-pbs`bx>#koTjrj}nt_l*s4e3%unrBA0q#u+ZoCx|o;(7*0D?frxgh z_rXTPmX>+hNj^8zI9IuHX7_2-3;0_Ds#Tie1py9kG-`# zmjNT0MqHBNA#bCPp4gDr_;&VGw^VJ9iKgegV?N65%7SF*vyNIhnm9ElALdh~)0co< z^wTFJ8|0`@_c)qbi=xcR!q#Ix2v-Ia^c|f$zxBd4dEjh><(1g1)`l&a!1qfX?huyR zT|V$Jk*trk{N??s%ZK3tIybBPkIVvPrAd$%MrFwbKbfL%4k;)u0^C`hg}hm(Z_`j|pJvf~ zya2{HqB~uUOZ;q|*%)=WTzn&^Xa36yeo+XozALbkz^)2phM5P>>x5&TA`ekZK3iP3 zK8hD6OQhMqmMk4Aw$hRts&Bdes5r$S>Qsdf?>n=%#w>ddA)WUfXOy1W(^D4VjlgZ0 zDJ4`qhOJ+xW^Y7-KK9_&?-}k25=6iWS1L2COSIbM>4IT0qmBm1&pArVnI@~eBd*J@ z6#Kq}NG&L|i|uidf3Uv1d(?u_JCyZll$m0QWWlmI7zc>ft%VtRg60qbF^$^`WkH0m z;q_jy_-K;0SyNxEC6~MRUJ88{{WvdomOQWQ+Eh@#mAJXT`|4})imP?JCssI|o84WV zYLa)_AL`FfQpF)4;_@-6e)-TmnjJ*eQ-JjYEl2$C5^?-awFk|Cx=h}w$8RGy7%5^Q zX~**?`yC?e3oSPE4xEhUE#yAFxSvHtOVfq8`5Ci+7Q*f?=CE_wpN-Pes5h(5=Y!BE zD;n&EQ=jeZzFPWyyt*i~=|s9#pZefx%~w+I14n3JegAVv285jfal{>{h0FwUk?EL? zz-Pp&{jxR6_zvH|4%b62CvFi%ox8m>ouaGbaUQy$ek8zVh!tip)hazQ+vSdDk=S^f4Q*M)o+(lY0|l#mo;A6B3@B z>@QA;Em}!xwmN7{#ZnBKx6A8XkcW|XTcQ+5vXz46f+#=-Xkp$}Cl?)~QYbVaxp*hJ z$5mgn%&1IK^@n6fr8N~fLwFJ>LPmr$*r|bt5X$!vUDEJZr9Tvd)IajdX`~7mWS=u zI%IV6zzN6j+z)S=LH`skG?5U@$MHhdizLnIREE6UUv0HvKOlHE!wfN59@)gz&`{O3 zqZ2pT*!!Hb6*R$gTSz2J+%;8p9$V~O#z5y+0J7In^G?Zo2C$FS-?7ik?rZ-=!!>n~ zKnr?D&C@4KFXUyFGkas1 zKu;F(I%E*Vh*lYcGI+KPz#JZo&-*9pdgSay19Hm-kfop$+C?Bk2#U~WVCR_@tF6*e}6YB;FSw5d6jLT8UFXnF?KKAHYyJf(%OLiGY^E*YvM%_ZjK0o>@J! ztM8V7n`#@A*Z(me_G8CbIwL?7XAHT$#{}{k2IYXOOP7E&I>4oDmmrFP18^1)hT`A~ z>{368BkOmD3z2JD1{uv|fx>!b+L9#G;UlT646=HlQC!@&hyDwJolvX;jo|~J*ui7J zQj~N)r9JfA2h8#AaN`%Gw!X94;qP=mWE2t~EtI?Mq)FaSO#~@@)Iy@VEiP$EHcS04B z#5AaL=N1jL7UMnwdUzN^{%J*=PMJ|LYP}6d-vh2Re1?vNY~u_Vfd;*pf$<&}4 z*pFV_8b{D10LGojh5mKPK-B$oJIH(ja(f>Du}_e79P5E-8VyYVZ$txzJ=lky2c2GR zCQ!|EK-}&&@~1qZd;p!joyKezyyqeHj0pg6{^tp;ExC_5&|&gm!|`6D={u^;|v zN#kv`;;49Jp)uHO!6e2mfHt80+sM@wB$BpgHH5)Cz5$K~x|1JCybJmwh#39Tnt5w} zcKpCQu>```r3RtxVeCid0lYdr!2prLebXHOw0Y_Ow5sXMMw`45qrwz4t#}Nl?xP+4 z$z%$`pPj9AAkiG(Ab;Jue|;ic)9DW}0AH`+$Q;yDe?1OR?46%XNx$C2=GU8;4kGte zvylpp5*eUC_QswI7u3IkL< zZ4TUgu4G03GKjM>A9>nt6YORbpNX9ER+6S_VNqM-*~l>%$dcz8P_@=0e=_BO8|9LK z5&gcHMe!ZIc{Gdv{f$Si#2qVnf-dUjr%!!vE8=tf5})m9RhqjMRnywx3r0;l)9 zG$;mr^AZL3k-udYIL8Gf-RNGltFB71fyNzjv>J8}YGKV7+kHckr9wRW8lzXw1u3<; z;CU-axmvCw++QU(ce<_Dlrc&GsO}aj82f-Q2OtpbAd(>mSE5;b#N*r$!HmO2Gc zXhnbLzXkO!g}sG@dm@WE;*{qukXUp-$w+vH+pOVG!h-|+@e?OFWfX<)q=m5)3Ie#! z#k{#qT1wVepIvy+s#vAQ*EI;lVph;$7*_a&BG4Qb8N-X?#m>CdG2Ch!_CQaJ!@e7;W~8)yBZb zdf$Jl*uL9jg(Q}ChHdqLZ4|3`B_=60*EW(~#JHa)~wkH%eRq z^A;46jM7!%_6ZwBhF6(24|&XwRIKU9)W3f1<26 z+p(KBV%rLiJv_^_i2L(Ge+Zn#-v#a>JqB1xHP|?$5fdRO=z2?^;{AdlFt?E`pFqkx za|Jo%L670v=y@2@nm9M)CLB9r6UsZF7A7nczM0FknkuRgK6-V6Rah^qKPa_rf5Pgs zr!iF4=ALS(Y^7C6a0DCY$5yq^8wKD@jL)qya8l4Uk3MA%+LQap`5@%XY0w^q$oGk{ z2Horiy+NV>@c$q0pMY@gKRo!K5C4Zl|KA;x0kR30;1pJ1Yaf;1J-v5&>HJzwE&wOU z38j6sgP>8B?5_UlF6lArWD9+R;{&VWB0zQKO?_#u6xE#$x8J_kDe;iM<%-E zk2bn5;L7leMZPG+yYJ6bVA z)KoAJOGiYVGW}^=n!)X`r~>BjaRft`*O0U%xDhN|#9ry8g2(8zE@Gh2H^m6q&qR;VyR$@xYZvt9Rt(Z2&&g*hmP^_$=auwkM%yq1 z4JdF%lsAcoz7D*sFUOD#tqgGx`z)ks{A8-dK(}^RBB|!c(oOn)b>5#$xK;os!GPa( zdNyw6GP#q^Fkt9mgczsoH35CVluovQ@gRN#3aer^Bm7LjcLT`R3-HW!|$rK25%5c?3dk5#?cqwoK=eos4J(DaB|2oa3PD@grTwY z+y$|)D2P_KDf|U7tw+nj4^{Hxg=W~q*t?hX?k806hW|B!Y)? zy0e(mQBOP0`>@8RI+;X7+L#z@27c?vk;gYKV%JAocvvQsdPs-bMZS9Qc?}32_tn0c za9nycx4KpFOpZV6&ai%Az-2&76mFVp1(+KN+>jsRIpok!CIZ;eUo*Px7`=qGlc4*~ z@81cEzzf!JGkoO?R`eDGn5A4U+|20^27AaB+7Ngpis^{0CVzmj4oYvN{i62QU;aYq ze`RSp9RYy-rG6awHrN$tKPzGF2;lHOOTeg(+yc}}2K|8_o{4_SA^Rdv_6K1?%Z!;7B1-YV-dxNsvg)8~-o z>~=_kkk0gQ`!q_1XSf2g=i$o-7mXQmG*Rjng|y^^MX`K`VVmL~aYm@*d2(sNSF*i|ThN!_EG{&-f~SV`?%+ zt6qrbp*Mvjp<_J8Oj~vkL*_I#(s9*&l%vFXb87vxzOr{@>D`REqs-k1;ng0=<;tT| zt{iC=N-XNufhqeQj^SG^rm#C#T`CL1{1l$hl#6G03Ig0XeG;s-%hP@Y|75xbm1_M# zdG<0}aj(ELiu6V*^ml;*Lfz^$O;YTM(uL3U7Yq*?(4rTlnN2g~SR zF649bb$U)?D)6V9f)agllFIdULPfoZSFe}vyy%R5Tk`Zo^bIAZqsrPi$wd;YmLhElev>&-CbL*jzdu*($Vpd8N-nh0h6|=BPN$}FEP~DT~_>u~1 zQs*vuqLxr8Vc|Nl=R#O1CAGs%Ub@Zrx?exXNqoWhB<4*Z7frMu-19r;$WWuKKbH@L z^y-%tjL`+`?W)S-ykC`jzqr(xX>$5wUh$cGC%C!R-1pc8Y_j7U`|2_I;?l*VQH4>3 zkz1->$`5j!5%}UjgPcj6AWaOB?Yzwq~+^U9Gl5nHQImmbF@Za>+DE~G{_1YEUUT!^ZN6>FhvOjmT6gqqj zv-ge{<}LExj-&>DY*_srLM{*7Wz;=}II692muIQm;5958QgAP@0bb&k18#Uj4VCK) zYNm=N6S3xv%|EnP6ZU>+CKXFP_0zRtIx$BK%1uKUqt=Hg3Q>%Mu%Vepn-*mu?0IZ0 zk+Ld65zCx2=VIv?gR+_H#Z%Cis)5dVE!DoSPM!dxPTEN861&KAdaBe1wc+xVg3>m3I*9qs7#rv!~FL{F_nG5OMvlwY6% zo&?!eniJT^xFiofr@iY!PVBJ(aiF8WjMFaX|IN0&|EiVm zfBNhn8s*&vA;5oxjRTNs@hQk~IYVz5Bnx)f(Dbt;#@=oHd3@%DYR@A=ez~5#xWG*M*0Rw z@fU$G+N}L+YwsPnKYthF6u2tzuFypW?nYjYF8y*kh*v}FLDFM~kar2T}* zt?&5HG-nwnY2`7NGUJvPGf>n10_K{b7wvczvrWPuJ$kfV3ZIIeZ$x4d&8cFytILa` z{527F;-B$DP|z?iPuGflkPEV7X`3Fb*>Wgf#ng@{9S%RPiXf^B8!$z412NXa zNn|xrMf4T+3dqop6X!`4a1Lvy+GAvFZCG~0Mu5}+RP>B@;!thMt3)-wWC|2T*cB)^ zgJh=}k;JXo3f5n_W>!bfB9>(00v3taQvx>?o7M8#>n9aQo%|l3H=1?uUey;5nC|Io zA!fGo8H;^g^X?90OD2$S3%HQDGs*jOP)%tk$%zG7sKXlF4VlzO<2PR0?Z|yQ-YT*% zR@gJ{cuDu<((#k@)Bfg^Jm`ut4a7g{MFAd7#IA%a7Dx{v??8gf*@WZNCI?bISFS$% z)?@bLY9m9!#bqOio~thI18GL{%SrArrrOyMAwiX1(V%B|fum_G+-216b!9AbA16a` z(VQ}=-Q08kVh%V4o^*Mq8<8@WoH<++Ua5J7%p!uHbFaKncbO|Y@m#GW>@Y!CiFXtN1sG{`vvLb`W)? zx{WvDoGA)H>k(H?nq}{K?RRw(!X_DFHFnuJPOH2`+&X=96=&K2znZlpv@pInf|ku+ zbcMsr)-RI?QJM?~gJ1&n$|#6r41cn9v2qy6RPbLo9K?)zf z?(sm)gVB>s@d`=Ym29+Rvl;zZ{CY26EQfHr0`2@ ze>f`!FJww3_OEZHl6ii%~!Q}@Gm&Lvab-6vD?l-#uNjr@}Zn;=;)Z>Qv z8$h`f($;`#$zu^%^LFOZ<2^2wQDy0wBZD2zMMDvpF=z#t~B-4O@sD%U+Zo1C};$ES*O|0mV$(k;-Hw+gz+;n8;|R3&Pti zIkvG(-}~6nFaGZySP9DT9?-ca2;uOoFewmO-JiQOd(8ro*ISrfEgiv-lcs$`vf+Lw z6`WMu9|zTV`qx2y*@L@p5b_w`v{lW4D6noVYzPod6jhd6aq=MO97)tWgXMm1uICvO zVqYF@pWt61^Q4*RlPbnwjU(&8cR0TL8|TBNijKuPu@LH$8=p0@@t@OYL6`N>Ye}N_ z^$;#o9o(%7@3#f|jK>&{d)e8U+}va4uky&~ zN}F+yejD6R0Hk6anlanIpGsf^+bs;Jdg{Np`L~^~{w4Un(~aoiVWMe0oX+<5CM{o#tXA~JA-S={^rB(?o@$hh*&}mPa{(AF%Z!Nu8{lqMR+Y7a~ z9itDvZC@~nN4ZP?+=`wg>rs~tZ1M)>p8PZx#D*$>f1-FnJ0&%P520*w(X5GkRp zOzb9TO+|{Xreem8AS=rLzck~yO`sV|A>97X&{bvsUn#TSo?s_$GDdM6G@CJLUMoj+ z(ONR_8H4>5+(`(mPfDFdQ--(=-v#C8^5sW{+CNylV=5~3Nd2Oa6LWxo$K6MUF!oYo z5Mv`Q)}IiENp1Y?5mu}WeW`lCV(uZ8yuPr-`x&X>p`=f#0@dH2uuYwE+EDbPiNjzW zwGHl#NZCq)X=eWV&bRMACF6!bhyO;G=x>xF>#Zm`z!O2U70rTB^4}EaGm6e)(U{uq zou)+ja=s1h2Oo{mDOg<=)#G+eNur3Kl1!3hcghj&F1lqrpg>FN{Fhnf_bWbz7Tm=K#b9*6B@!WUJu_{ z>RSqedU0*Z3%)VsoH`ucddp;GvvWW#KlecyOsT4Du8cO6r5|Y&&djyGFX$M^JagU9 zml;_%L-39AN=uS_PQPhZ{gVDLa;Bh9{P?&q`vI-a%MtO0yR?q|>1Q9hWQ6y<_?YiCeUK zH#fBOdPh?#B5Txnb3k3D8!J*$Vjwd$rDCOWsUqR@^{AEOq<{}f_Vv+M3(*W#-Ihgz z9Vz7Z0puFydSO+QASb1~0UZTBEO!tR!Z=BBOCc>(=(#Ts86>7S|5fs;qq4 z7^J6zNHCXI_8Is294BTXxo{?N+@~C|Q~+hBvpPHkyZ8y>}A&!vN>lq-UxN`gYXb&rzzYy zlt<%4?-yQ!)dw&>;&sYWPYZuIE7V>X@PgSs7Z!JSy+1S2#Fv?`_dxemiC$>)auJd! z_BWow|Hjix6dlws!x7WSK|AgUp%r72=qS{DlZo?%qki{&4PGD};JiK&j02PaGODSaSR>X5A&0gS#a%iex6p>A2_|1) znva@cj(qa={6hl8dz)2T#X~8`1qv9;n0=MP5zaXP25hHEcKM&m($AdNb$9j38l9<} zoSfXgs`|cwmvbT5ETZLt)!gVU;ixqmpOlsfWb5zr?)ybAvff~P0mKrxsLy`A!>?z? zfjtqAJ3QwqkMi~3_T^F%=^gR2QgIz|^5AGd?pt1i58;{xRh?u(#t?VJ2d341DvGzZ zPpr7IUnJ&@>+r|Sg;Q7W>6(5q+=bXf;aG^GBv03u;W%7vsSXNHOL1Y`f%0YeLNAs6 z0k?(T#v}8b=DN0Jwb!m^v_(9Sva&sL@`ARlG*2&t9OtuT%D9SYgwT%9KxxHq0rkMy zixsB;Du0(lB_me_#hE3n6`!Na5sRf8ZwePT;97Q6$VGpEDuTS`MwzHn<$V3sfkNc6 zBvOZFQ>8V=og&^C?C4ODMw(Itxh01h0?9hwYl%$x59mrdy_6c$1r&4ZX2pR4Ul3?BRUAoC9bw28c;Q8 zS{U=WG)dhxE4WET?|ms*x`SoF&9j^{1{XGUN{VAXPk7x6@>&t zKhj(s#wB4*)}pnw6q6jWXAD8=GwYtWpK2--O@ovc@~5tA->9297E^zKPj+=T{v)zp zpTeX7VXi%i9Ba7*5LUt|AaN*K_a9o#XeWM|w;A_N14mO%MnKsl>i_W6mE-LEvY@gv-rYe|(drRm_xva;`9{QB7d&6oawIm@Wbo7h z)*mpKveE_Z92d?Xoc0nuqzhFaC=RrvDHar-MK+S!&5a)DF(0uOi;m!mz;Y;OweEW` znn?AqMLn5K@JkBYCHoFxU6EMMLn&6aX7RW_3wUU?t9rIuIsAaCd)AO_xMkjv zY0d4_q`jdpS5sC~7^_!7fqzClg>tGN8}y0$tPnAlf(r3gsBB`qF0Au@D3@)eL2`+4 zRSS7}^475=nLQ864W=Z-cb>}}geMpcM6x?C%}qw2L`&7KLHnUcQ;5 zb*@023~7rc4-s4&mpz0#+=2|wN=9$(j|J8fX=EAGA)M?io=ICQpL(QsHZo3slXlZ! z8SYNTw^*qMaBK+oi`AF2 z3-a#}26I?tRM&x5zm>#b_4z~fS>3Ot1 z?J#pZUpc+OJmC0T`ngNMf05Goch5Ye_aGgp9RTI zeYTLT*KgBz+C@@t@p^>o#8-aXG>@x6Y8lH??>u7Qw`wEWDZ|U^@a>)QooH~CSq;hv z;)ees0Y$wEgkpQYIg;?}-SV^yxp73HUXa>6We1pur#S*^gE9ccSTB<3An-@YEj47u z{P~ZdfBFOGf@8Z}{_R&Vfth=MTJuj7<#u2CuSwV^Ca`uIh9PLJT77GnKJiTaW#ID@ zeS9Jl7aRwidz$k@ z*zp%*z<%4gS0}<}S(lExg*>xd?9)Ra-TBx)U_P(4J)^b0W%*b0-;F_-40r<%IjB60 zAm$)BblaTxT9F$xYDCEGnad8a8-~h0NaRGikup3$;20EYfH8+p9R6;hs1`6m-V4D`3 za4&`T+x}#_b=s{n5$&hga=aCjw6C6HkfYO9ouf~CV90EAE=6a28lU+JnQL(Nv)$IW zi$}FRg>Ig0)*GG5IXhCJFOQeQTDTUi3wq$=%Rjd(qptdANbG*=$tOH3KV zR+N0QqI{_wO%H}_GO(b54UBx$&EN^pev36azaWyb|Eapw@HZE}Po?GLXm=pT8hqVR zp|TT1RTj(S?rh!>D2>w}zJsJ)p*TbYvOARxZ8o7oYL!d$?a$t9xZGFZ=63hxWyPa1 zO`IPu9Xu;ME>-DhzN1dPrTM8(N_CIw%VDW0 zGdb65=KD8{)D4JmO{#}=NMogB4ZX7cgu)qtD_?A0?wQMe84%^tXm%*+NYb4Z|EeRQ z^oBgqX?1g`Q|o|CLeE6c4qX2$RU3DhSmGZT@a8T#hh)6}OmB#+&_aUVtg?HF|J+8+ zV&RvqDh5~fA}~pso59HCHsp#3gj@i1THc0KU;N1wcngFH#pl?7o4ekPizcM{dvB-f zFoIl=W8l&2ZJzBBP?S7_9D9X~`BkwX4j=N)riqOn2S(!pz-zx2LpuEcXPr*;SPOuaDUy%H>rwu&y>Zv`W?4!wW=vA%Le$nzVuh2NFXQ_ z*#eay>3@BgZHYWUefbw{iv>dg~3ia_5EE-uDgw-n+o-1fkNu@ZbzU zO-{c`ALyX;VFgVKgB#jz8`^$e-0Eh0=!UNz1xA*olh#0Y!~Cl2g_5sBzij#Y%hI!T z0S5tHKbbbC!0W%I$@8(-BtG#ME z0xntFhc23R5&b0{bK{GQGg8-$Z3m(|a|!~*nvBpTc`wqr3)0i~uA5q^IQusM5QpDL z12Z6Z8lb;@*+0MjWn3B|mHDGepjY`n?j!miw{eT=v~y$p_ah3z#9N#wstK}m3Oey0 zRL>oHW{Hcc6`vt+tQSBG`s@>=^e?k!ctG*-)&3?EJuPn&UFU_$_4@-M zNAKn7#U^q`rWLkD@^@RU%_MX(^{ev-_8!RkAv>x{Zr2d63>xs`iJE+@s z<3`&?|9s})w8M$Zp(8#&HgD+8ve#N;Dq5B0AY zgnAOF_NeEexud$keMf)(aRV-@LSrq*@NqNQ;b#T2vCbBEPBK-*-tuPU)RVwpzN8lj z)$qUk){I)BQQfnyC$6SSi~K? zWI=0=j!3EZp_1lq_1Sn>ejuzM0K#C^qwsOCI;l%lRs_!*^wMM*ECaGW1qJ<`ji($W zTTSCX45_wzmR*gTlzv=c`C`vv6@0LS*nw(}K!qKq?yEDTU8xRPSfysls@M%=McivC z!tD0_T5ECcPObb00VXcD`7zTVgzT)u6dC!#9vf#4KT^t(@wvO~LvdIlE$4c`hikbc zL@lqT+m{aKw8WK?0KdTNBKeq2snqqIm~8US_5M7J;(dAk9HDD(+pZ)=K~G zVlrg?jwR29Z9>D0SoySE^Zc#m3B+sNZ^w5lF-5g8iKF|V6VhIcZGglNS}}WUhtOUu z;Rta0F2~)<|LVpRj)>l3zYL1OfjsLQ<}rA|%-jhGS(?7LYaa{*gjt}`(W;PKBt9R# zy$gd1WTjpt?Tf5EK4Ly&fe5khUYd?oNSonMv>h8)rHe0sAwDRR-mLNzb*skvQS(9P zT@Df*>PHla(!sdmHJr-AqWCp`{EtC3UrbD=VxW1neEhWNyW_3$scB`!gENac>#re4 zB&wKA;_qcDU6T|oEUm37FkVylri46Gy-a>UlO@}y7Fxk{{ZwN{RN1hWWd~>#%`WdL z9`h!kv~mp+^1vtJ7Pcsvr!sA8;wRHpbk2UrP)$fPa=#}=z^6)M08`t&f#LXKSGGcM zPK1sM%yEPv_pZUiWh^@UONK|yPtcz*sO5)x^=5`V)$k`Ote&$$AXF?N$=Jl2fF?z)BTY-!&&*Dsh$mO`kL_g zq{KONMC}D1pgIl6q9G2V1sD2CiCzx}Zk`*lQh595^ElTGgiDT8qZT;|GMC4wV$0Fb2JV#Yy{j97z82wJZ3d^?l zaE~Dx;W1)@Kdq2 z9s>J=*JQ-Nc3SJsfP@6Px+dE|-Y4^29iZCu;bm#h>t5f7CadWrss5^}9MiI$nv zbt6dS)IeZMzLZY9a~qt)a@V7wI^nY-O{NL-xv7KxOO7 zUQc^`n0ME=N7FTrm!H<|b|kP@+XUo06~i@#o?UF;m2#fjEgMmAnIg8~-4%F-nuRy( zv!Ea(4D&^KBmF!G(H_Q(!h4BECs_58FW!7yC7T(rX{uqV`@;7tWd)IF=x#k%>84tB zzvpq9cn-~y!c!-Gm^!W*Vf<;}U9W`6T#sK|?N##{1Ah~E12j}!6-(I{?8U7Am?U7L zwPRFU`F!|?kaw83txZqOYTZw!5{F5i`l0Rx~+Oo@>vx9JU@IzE_ zYb-8e5iglNF{I=Ez&3gq`op@v`4d9H>#msbhpeG%1|ydEYl|wg@4i!$#BMuq=_<*_ z#f5Jszeo$q^BY=Uu1Md}qHb&w@pT0-vyVTSQ0+b;iC4e%_;eDjk>s6v#>wuGV6Q0( z{!L}>zA9{O(pmRUd&*9IkHnYxpc+g9CA-~Z=^9+0N-8x^gpM5N8&kcobI!-5etRU7 z)S6?>CYx9qJU7gTE{p(Zo-`P-d-9I#y=xjuuwB10xsaH7R341NY3Uv(`Rq z#1E0E;Y8P^#X`tKfiZzED!Y=`JNP#cJIC|EiXg~u}6_ag|O@t1@ zLFax7bKzT8+aoXt7u z@h1CBc};J)|NP*G%tuQF!lP-RWc)I4B&yZM7cJmN;65n^y;p_{q-E=iVReF!E4^vX zpptnx>M=f?1}D-vu2c`m>8rzzJm{Hil3bF82|R3MZgIE9k_-lQ8fwM*mc{%E?v09X zjJUgUjZ4UEPdZPBLG3vX&JQTxH)`<8YRzbwgy}n72)_c?ADKJ%V9LY!W%kXsn+E3c zLp4J+1unjpmHxVMqi^PJRT;Tl%{=zw<_&z6_rfCHqw&^wNEA(+Y+woNEYAE)l&3eHx<+|c%lH|PEW5hxjv5F0@TkBF_G3Cl_Bw3U^^W~@j&)$IUSuMBY zU#IuiXH+btyR^>q6>bYJx=&gfL&nRouWx3*&qpr*RAH)9_ZM57A$&g@ZHd|XbW&Jw7>OeB z*S$KAU-#;g8U;^&B&R(K$aPLCt8{yv^?B3O+xuqzd5ijR^9k>JT*kLK&0aF?O zF-GBsfX)SgmLfA}E!^W7CF*j`(%%pzK74R+o|bI?Cge>(sJ3>8{H1@!GegZoz|QCycC{_@OdqXx$C_gtp2gUfFg zazTWnvSths>F4^>wA(kG3i1lFV`)SAK|-SRD(Jv@es8yF#THq(T|Xn7SX?zs8!9JR z{h1-@e_}?dw(InfYC;r?#T|4w80owL`t&@-1)A?B$vhiX~xpaf!FF!0h zA~k;#?O810?4Rd25qHO)8SVDH?_$Mmle-oKLy>USY+*3VqFc+b{&**GZj#u96*TMoRyw`#y6hY4}12Lx^TYotm!1;tw z6UI4gB^mh?At#^$!v&2x1vYuyy?EJ+C-H-AOwW~bd!0w^P3_5Tx;$S?SCNmb7Zny6#D1k%55%unl_c(__&^Kef6`BPdRhaqr2YVbSrAZ;KC!b@|I6`o2E zfJd$|zuiCcFG@(x{bS+oU&=vTj~QKJ{{4pq_83*aFe>ZBSJGI3!s~%S!mW>G!-wRSdY4>kJ!S(?asnstqr}g zD7CQuQ-|{xx)#H=QjZV8vYL|CD#O#P+`tSwjW?xMy}iq(J9v*VNF`S43T+M16Zds@UgmY7hFJSgi-Bv)y!w2$K>DIH%S##G7$7 z!^iTp>~n<~aEY~Qd0>8^t##8%H^+V$rXpHbndzc8%Uv_`RXVnB=(U8Q8doeomErL7a9=#Ess{Nwu))Q!#0kc?@l_XMWSQRoE>TyACxJLDY{|SERlmxj@6fMshI} zXcwtA%MOp~Ci?i!c3&4h-z&1W@G>Tq zwkLqZae$gMhW<(z2qkvOt7pkW|- zny;?x=@XZ=p73NRE%VK)g^}LguZ8x@z1m3~7R$@(Vjz0z=p)~GnVwYbMEn)QIxOiL zDC}4((Z48Hh2(MJ!$k2k#7bcUCPkW4`IlYS})($gUU zpx+?w1hzm5zHgpS9b>1S`j&dpsN1VXp4ZKdwq>5Yy*MR-suhVI;k^uBPc;~fH@>!l zdj!B4+xO(a#Uxi#oy~QJDHMQP zr}T;awN$J8p{x>8jh=aRagq_`ei;v?#oJf4eD|o2q>#z8uPYyWnBHC;qpxcnFvr{` zq!y&F>~Cw$DD4?F0q8vdcXWk7!Yy=;!4H5LyDvzt9*t;D*#I70Dm_at&zT2uv|7u> zA*q+lLLs9x=73DL!^`3DBinw z#i1EQxeXz_K5-jYyBNH*`+b2OBm}q5O*YN?$6qT2lSC5AvgGvOYj)8Cy3?KAi6Xl$rW^m*%X z#JNlR*(+u~bIK@9^sOV1CPQB#Y`riQyjoPBR4#W3P3%&geIB62U5S?62NwexjKdrj*q z2@A+^Oek(wEwD6~sW#&V`)Shn4D!${l*1oEl9V>tkto|Py*anL>26JR5MFQRko&p8 zl$hg=sdvj>7%XQgOqFL=NqQ|-o--*9e7uS6F;V|U_1?J&v|7WMt4)*O5o**J{Fo1- zq2RRhP+1Jd0&X@N#dkpXXveY0m}8M4cP8%MxUo+T(tsXnA;O!b*%}IbbVzWJ58-m$ zRDM76fH1>2Ra#q?WN6D?<|2GkCM782e5k<0VfSZnbw)p=7!s)(Kq(=ahN`L%I~0t1 z*421EZ|dFk@HzyL30i9a%imt0^b|2tGAx%X5&I!DDN4`P^lTCZGPbW#dPwJgvG*QO zQEgkgaH$9=AWF_fMv0oGAmM=LQ)$Bs!jP9Djgweb#gNwlbKE|=6;%*BgyJsaAq zZIBomIu{zvFe&etyYd|-fy+Uac$}Nc5pOcR<=a9>r(31i{sKw%yqJA%9KO*1?j87c zpJ5#~y}u1|y(R`?J}OI{^V9cnnvK`7kvymIA!%+yeex`aTyc9LIhCv*XIj6FV9-O- z+&go({coH{H~B0e(9EqyOnot|<*z+ehZp&xe$Wr7!6>6?EIuW#NcvQfNDiu3zSMb~ z$nb4CsGKm3sHBf-k%M01nZ4K!q;Mrz9LA(A!LLZ@C{j8u`k>H_ZDHqICss^ZJs!Kqgrp@?)Q(Z z>w?})n^JTLUSN3hYR09g?2YSsOW@bA0YpRutS1#qA0G!1C@ z6Qz21?kHDt`}1fM!wF>1Ug)=yWpsM#&zag$v1DZ6D_w~}Z=*m>tNlv3VgPch0RzAs zlGYP;5sp~od*#{B;y}i=kdT*n;r%u55w7<%WqkzZVn@yC_@`& z`eTH)2pn*>JwzCP|KhiW@lsm^Sy2RI4308Qn@Bg|+0-lMj0LF^n+2_{bu6_BrtT|X zpdQbWyU2qxUhRpc1WIcfJr02AI~;7L@j43$?JymrbqmuuDoxXUWlwbVo~m!ThOz35 zyGTI!LQpf{`HUlxXnCdyM_-oI5~I{>nGFXzvr|!1GeqX*&(9Q9E?Fw0E6w<)$=tAy z6hq4F%aalUcE^|7WSR}rn!Wb+k?}h~AYi+D{%ir0clNa*Ka{`)_g)N(N^5(wDMQyt zF_V;*8*)DNz48IKT4YUpbSIP5mZvbwI5GUykGK^B||w_3%JjL^{fxc44&6#M|16ni^akH1or>n_7y(Uqxvz^Q~xk}WQSuOA?&;E9S@ z+c?QCRXohoebH~162Qj+y<19RiT6iQxkC>P105RMd8KZofh24h-<}(ssp4;s1MA*u z-lg!<#CcIyD?u{FXmoi$CvGdbG;`x9=+WJaKp4B>l|<&Vll_>i@F8vWzVq^ZwVLCf zhAD^zXWzW-{hF941lp_(zyM((O*fWc^!{=fWQP{DahE6M>y&m(uaDa@kl0Z1spoRX zh{Doa!5|_*uBSSx{M-%aB?Q_@c-g)}+M+!Q=h-VSk-YgBal=$-rc!92>KQybZGtaHe-E*ZE{s51G^X>Nhu~F82tb0FEErfrhH0L~cvW1vWJG>NvYE1` zOY7m3TGM(IB>C$^YcNZg*9fVRl-^t0<*~H9bGBrwC_ZP&QGwkYBN#?L^z(U(Jkdt# zS(4 zZdtoUt*}7)L4Qc0a0bP4%dNN{6h}189!+XC5zc(ZQR z16{uDSPVzBHh7@BI^seNEm;S4k~JJwM$5CRM>(%2+p}4YCI28!d>Sysyv*Z{hn+Fw zx;hce%OmCf0?+lCOF-`A2VC_d>%%a1tYd64x^)93mY}a>83h0 z0=aVao8cwK2xtstJA_4^5od*h<-+q7aPJp-ZQ8xqxQ4}zcLaYJQaS!?F-m6SH3^(~ zv&l}j;^90e@)BDGNZH{m4+#l5SOnqSxvf?7mYzc`0C0>RmlSC{VfewSOe%lZ2G5}-10a{s=0 zDU|TT>Z)hltBfjuqlf2Oq@;DSlpOPi|Y$G{nK-}L7nLYMb%{HNJj=syc@{u|eB!T;dk7YF{)%DV~52Kuo;UkA|s z8o~(Vfd91k6X=-b9Km-3jJpj0w^5lCR|O!18-9qB%>u-H8-gGVNKkD9>Rx3)uY#`t zxOD?);GfO>b8P-OZ~g}s!|xo#v6bASNwX3MTRZdlZZ6f?rYb6}Md%-}Mv%(iq`v)2 zD%|hA#-cwsl%P$A-+_n!MR1W4Aci?W(C!_OE5n^eN0Rc?8X^=MbYpb2M#*||qnm0l zM}aq+FJ5k+sYzXF%U?1fP@QMXOY;_#7W<12?`|EjblKgmPVr{AH|wJ;v+RtA0xUV$ zSlU*g)XgzY8mt(vf}qzn!1;@?OoK|3F<_xJo!C4%WSKJI#HrhK{SrOm^`+0u5Yoe3*%^+ro! zl^S(FPR)+|aK|>-?U! z6SGLO@X&awG1!nyhx_z znWkOD7@Zu&@!qTWmbAi4g zqKRw7t@mXa4pyOGd-uHZyP0w7yt$@Ol_Z*`mDFL3Q@2j@W9q(F z9bQ^=)W19cQ5N>ofOZeIm33y0D?ZA>y_(-8FI_u&T#wm&+>o-^(Ihe0AW_Uxwf=eH z7Q9<^HGOvH#Dv_9G_zW2Z-=zJq*zTEeLl8Lc=WDrYSdG!>gvtxPnp?~z+w4c{FDLK zS&a$`OzLknOkmrXyU}zd7k6ezI%dh(h`sztreofJOB5{@WIt0=QS;dAgGbr0X~G68 z=X%MKS~(s4ZLSXj-NDt=6V#C>VT3D#1%L-ixU#*FHe;xH*|vq007*1W;Cl3`uaQt-=w&8XOk_|!es z^0ndQ6^d!Py`~73UOMj*7p!{Gva=2IOEtZ?{;19V@VP1^3XIMHbOCTRivs00RIu_W z_2KQBUJ+Fw!|7Rr%tgjospnbm`x9SSqn}N!fbLVR+H4}P`rloQ3j<@cVG)M6H^(!m zWDRUEQTP3zyVSkV+}eEUQTzjJmuxbf290QRiQiJqGt$hY_)62{3f%yMbFm4o67KOy zuftIR0^fL2D=zG)00&4@M4ci~GiHmDuf&jGr&gvOl%((ZpA2F7mGcn7O}qy-KRl3M zWr>mu$0jGKg*D74qNi(-YZ={n?n1@v&idiDX6{s0&E*Ixp8^G&v-CrE!j*mm21p9y zLx#dU9mQ_&U{tX9)RB0x-o@ku@ev~(N5l%o%Kx?6Hvy`Gt6UfKl8({cC!2%5H+mb) zX387Of1IX9-ptefzZKELAqZC)=XdE%CU83htt*1*w2AuFBRS)QnP-p8N}oHclQNpR zo_+J$dGLB??dCNfD`tPyFZI~53f_;4Fd8izo~?cuPku+KOdox8J-;q*^t*9}HY)Y# zYoo_&5&j~1xE`f6%`vevR=vkxrdH9j_p4CCW8{tTuk=De(Xpf?HEum;ckzmtU-sre8wBcMe>=>s!ayLW1$=M2NyR&W zYlCUp_v7-F^LVe<7rzKFu(Q~Ny7!A8Xu1(ta2)eUQt0&!8LeQvNbUyRSyOSb96u>< zlv|Q>SrO^?glm-S@fJ!xLy2zgepQ3{Y^nuiuPhM@R+EYguvhZJPLS(jkWeJ$0gMgG z=7_}d#D$d#9s13Q1&gG4#7AWKfNEFog){d0UZyea+eGY7BQ0XVt;i}c3K0gO7B6SQ zc>`X^s{=42?v2a_n(#3TjowJj^twg}_~F2l;$BoS+r^_G8@T|n7n!)%3P|r~G7)h5pZ0g*i(i+Mt z>^S3w(A9UcdXizK++$h%>89IFq9;ACd6dB+OZl`vX>>+4imt^~Nqsara>Tip!>0_f z;>Q4fN;C^kv<#h{(i^oO*tTsMd0Lks%^vF*Ne>{!H$T!wkPc=s@RP2yV_XuUi&HVa zaw1xB7ERTWZ2?NoZ!G#@)ZegeLrZ?jae^fUk4NuFgXpA(vSX6oc<-MJJt>Eb{D#kj zG|Y8E5fStm6oKGb|A*E5Pq2?>*{TywUl;j6YcXAG!q<}+0_kHv7-j0H*pHF~{`hSS z{@}*_BN(WED@*X_|7Xm8`R_S(mlCn#?fVNt`V*$>RZd1xjz_~x71}m)pD%}c0yi)82A;iXHzK)g(uQEjJ)7=I=B z_&@}qA4(b>&*j|HlYZls++~m_8xbzs-=ZjrtW+XE;-pk_KIYx$8@rRiNxIDc@{~=1 zet)6)9vBI3XzWY_#^0~~aVw^JtdcvPlKq>i&oxz{tLg8Sqp_AD_h~(64CO8s42M89a=kb5v{v~xsUt)kWW68gp&^Vd1@Wj4u04$2Veq0zIOU8<3b)Y4?4#j zz092+4^EX0`FH9Iqu8HV>!-U8k2MLPTCSRG`CE{q1I9A4W=+@kZVusj+^va*J`K~) z*l~Ejb7go7BI|k;ZC$L>#FIbgXi3&G+C*=EBy?A&;dK{uVU7QDrN)Z7kVMnxobHO+ z>t3QnOQlBI1SDDdq!QdaSoTJdWJgA|m2=e?=a{f?UPBzpTS$Dg%&I4*hFTjkKA@Htua*) zi!5z*ShCv;df_^3@o;!bjj1B$qk1T-e*D-MaA=EATI($BkpJBRhlY(!CUen=8?by0 zp3<-PX&%*G@DEYeX}q?9O5*amAW5jZR5x@uW%11H+qT_4v(|^H#}Y|<%U4T`;`_gE zxZRO18i1G0E_F(pGIdF!x1TSzc(eQ1ar@l3FWtA*KDorel{ocHRt>ZGeNGd*nqjlh z7-gZSJzAQl5hWzF=(ugFq3oPO`cBH4ij*`r&lwYu8_#4eVQ}Cp%>=53G^z~e&qnPW@TZvGjc7xd{xou z`yRd0v<>LZrGxqS5qsJU1eWV@1r7m@pzr%Kyu%&|r{f_u!OvuiX{$27|EPcQe)opV z7`QDi%(v@xjq}qb?eUtlZvZDYHf!jEuAaJT2Z@U@3^%>tV?@45a%}7CZOuT@~;@%?~?!v{*WN(aH;e^X8Tf#fxfDi87x}B0GBcB z7loYVArYS6XXV$Bz zZIFI*@S$Pl&i53)JgJkgW#|+jeL(_`2)>ly$3? zRRmsPa0{142>h+rKyq_8HUEb@>D9%+5dQYiYkCCcsRgZba)5{$)Pp2Qs^BH-+A>ZV z0g&)=3Igxa(2uhh0fy&*8)pPu0z%1HF$7B59|F7vUmFs~4}2GqGl`YN<8y!t9zZh* zeCQYb__K1rQUZ?pH_{Ls3>E@8xCY&zcNOvT83Ipd0kqbz30e5i^8dcD z)n8s1NMl_ATvx*D3?Lg}z6cD|*|u+=+uw^LT!Ii(1BXKqYcmM^H8B2FH=yeHH)8@o zoqsn^O#Y_0x5 z%{4GNOKYzQlHxc_O9485*uTm>&Cz;t)n$@UK`%Wqb2r)@-N>?Ub%)R<MUHSRF6Z{Kvce+cdowpj( zy=m;;`4d|U%F}iaSDUUn_RPMv14O5oe+EU~EYFnvFT34;-MY#Uz?}R)!n^y|E%Z;e zRboJ66UQHikEfs}pyCnhavcG3seu1}6<7q^iVpz=r)8^CEmtePF7O^#J0k2*WfTL! z$Gt!aGI#EJhUcdMu~zzbEz#PgZ_X#2V_LNoD8ScE;Ak?3*k#F zaFTH@wotI=(BryjBsfLC_NIXI_BS);P)q@2xr*`wV*^D?VI3&^**>n;?=Xp zCe3hb`~HP$^PGj_JZfqfDJ>G_$972Il(E)nCkM>FCtQtGn@_k!9|NW8yEW!}s3 z$qfV9Wl;6LBWeKQx|oqax?}5)G%zna-CRBx9>CXiJd)s}Oz%sA-xLrwgTfD-*NZo& zoV}&NaV>I9I1`LyrzP)jPF?C5s)2PU*O|2~Ibqwedy-)0byBH*u2T5rx-Q@- z%D9N91Z-Nczv`GgJ$(3UAorJH!5U+{^nxFdbGc#3=B(_%9<=`GGzRY-&pq5(sS@R7 zJehl~LpJ}EWa;>2x%@5vYuJ=fj}xJV7A#$uU*443iw4VZfFaP;X%+`ULsN#}k<9BJ zN$;!W6vTWENwe;%S<~eWkTJrj#J!*nYmO=3-_j6ElC4@@M$Q*lQo<$^7px)!d7Vf! zuqv@lT(HGb_3`_dqx?dXpJP9YS7$Al;XCrJwq@-B**g!Ti4u>)dfb}qTVXg}!y3%y zQOKELy)!tXi7OX})WyaomYU=Bu+phyQN>YF1;C;I8VZ@biRp2}o^0N_R=DbOb?=2ji7fEvE#g3~jhK;VQ`jtJTp*>^RD=2YkcvHV&*>J;sY= z9SbQ`%I+qwFz*%U_CG4NC)eq6x%y-LGOysm6;Y|O#v{aexh%=q z%?ZOMn4_G`ndXwSrl^8>WY876+BaS7YDB4(L4wmDJmVh$4J$M@A!N^5mYcG|5^dA8e{_Gxs)w%1q-KFyOIW+U4 zN*Do*D+V$z540}SW)RWMa$pRzif5eeOq=lZ&@}`b)~cqsZ!^@nebz=!r8*|7K3Xq z`pn188|M!AC8}CFGDv}WrQ#1JY10IoVsq0gGI8l=rXzT9_l1unY9syzf#R$Zj@Hd| zm{u>=ZVsL1_u4*)4g`*uK1xUnHRFzISWdr#l?=-oe~P7{T30FWoQYg|$=SxI-&S;80ya;Q;XoXRj69 zN}#D2Dk=3>D(>PKIS6n%GfZU^L7g|;^FgoJm{q?oyI!UC`K^8c=aH}Fk=LY9TAk&q z@AbAdlj43B8`WoV=C~@r(o@AyqIN?Yv?4s3MY`D7WA{61*{G4jdaVu1Of50uKi;gA zJ*SAWXlr9kFwRM)k-V^UgYFK8TwdLoFJ1(*)-DHWs{?j(Xt8B(u=)_(UZ2iXaqfvp zYk|di+SaLOd&e7Y`UJ&Wj$F)lIf=1y^hcMm-eCmdjTBS);Du)JqTO1w2ZTm0uNZr` z-BP%Elv<-cNHsIV7)U}dIPPL8BKHchna;6&C+LPZ0}!QAEF=bqMD^d;Og&1=$Az^a zsKh@?w)?JB;OZ7X@={VxD>^%pA62Z=IVCeyTbB$jr6VdU_Ahoblcu;bOPd_y1*?-p_zZQGyc!T+??=BV=Xqo`J4|J>y!gP07sghkT`8L9LCw= z4qQ&a-8074wKlWOsSF(o={g)1tiYd_rY}BJAX;+OCki2YmHwVqiR-X?q=WWdv zi{x^T0F}!lA+q}vGBMnFWwYVOy$%^TC1D&;4o(FyFewzRB<2FA<>fL|Qb}-pi?3Be z;y=`M(p*EqZPB4OH&WLU(g0(k9Th4u@m731mi41 zcyy?Rrav;pfVXuPik-Q-Qi)7wazC^!PDJF^rOw_LZII5gjlUzsVNA@z5;=j>!`Ps} zMDi>XaFwQ47~XZ)KUgH zVT!{!@3JBWX|O8ihpvDM$Ov-$QAXN(X)9!9Ap-e!;}^&f9y}o^kg)uCLmvGxaVJHt ze9fltJOeqO4km@zA;am}Zem1UPbrO+32|5WJkIxYDV{(ARJv>zKK`%WQa5)^62}6)zB~d9$^%*I)LHyzU}LTZL_=<$hsWWqU@?dz zCh)0_x0O2ZQlDLt$^a=8AM9Pzu_g#W=ps;&O^9$r?#-&U;8TRZmuxg1?P{xDDwu!P z@;2wy?s+`%uu&3FrF*hZ(_w3LxFvhZ4*~7v{g|WaFl?m1m|nC#S?mBPEd;pkDg0S% z{eS1${}f;7>JCfvAW*&)%c3qThuAB}`*ly9CmKjlDx4VfQz5=J7W^f7HA%Mk^U1q3 zl1zMYYty}4#Z@P!u+W{|@@EwfM}&5DzneMM7@h#fmof2|X3>@8Qa`f-)v}UK;|U)T1UZbQ$vaG>q5aF8UoBw0Wti< z_ue_X*WE<2Gfum8eLl&Z-Vp;|pTs3F&W`s31!hyalb+Qkki;An&zD4&9$RQVdNMi_ zJP>HmY}eJ|pQcdk@UPPxlu3WkdA20k(UiS*DNQ~j7l$z|`a6m}`i-5E1yZYraP=DWQ!_%$wH8uC zF3BX3%W3j6H95tHi^uSZ`WyYA+vlptLcBeeIEJ^Lb^P^K zQqx_RI&^T}XH(u-eRx*uV zD{+3y^8XV5*hE?5V!L;7>KZDIHNgKqZ}K`~fxE&&e$D3Q-jYGQ!lOdeQ^V!u7gC2U z#z&;xbF-o~0Ipyf6OC@}Ov!95bd(3PJ5hHdmLIn(SAJuU>apf9o&bMb>UkmO*tJCD zn6)vCurEIfiCOkaP7ZaGpS7QGekZE+R+Ytm<=)j6_v+M&Qanr5mr z?l-sk*=+o*l|?s@WuNxdXAz^w`47oSXX=g(`EguB1|C{f(@r9}54lE%G*x;vzc!*n zzPDR2D#C=mCuFiQ0ve;fEpb@2GWj2gKToek$QN zx-xa5;0+_ubBk-cNlACy>UEN*2A~KE>ydHIgmImb>HtNx*Ha394o~kggli9ej%Sn5 ztI@jEs;zu;P@Z-jO>vayPCj0#^{KRv&E%4J&or&0?VF`!!TJ-gR|%j_P?^D$rdo7v zE>Hzb9Pf3zi4hAVmhyB)@r;KVX%2h#ynoIWUykny-+8KLf_lhBwzA6j;EVr! zHkNjX#L4qmIJnKtnXLP2zNU9qv~%St8F%}!SG4Nz{aZnh-~xk-P&fON^$EOq#pk*q z4wJI)KkN3LZqwQIsNMW<8d3e7f{lB0^vI-i(L5y$<2 zM|8)GJ%rD=f17??xT4zKGkkjR3v_$@^l%(=(`utG{Yt|y9+CwVKC?1c5&DjBa&n1q zzDP^rzrvFgyQW=lXp@)>GJJ}67^z{7Ve8Vu;N6@~qh=LcFZX3Fqin=0blC5ZPBgI2 z3GmylxaIJRNCd;SLLo3AB zD>&fOG)jCcab3VYEct$~+wo;n6K<)MDB(bhOxu^DFTv%9Q!7sn2*~;Al~r8fqNdw% zo35j;Wd`Yp2u!es*{t|Tv+`?|K&I=ZgsdDvhRZ@BM4-ovc4v&D)L#p zDK0rC$|Fp+(~@dV*WbQwxU)NLcG)$nls?CaJHG;s*t_YUSgh z>Tt!*Z`vm%w~g3sK12^!BSSSZH;kx^H+@GxMh|JotPfTbqZ#eGy>$l}< zeF0r6KU@JUY&m(W@l`h<^>U^Z3Z|4*@X2-*owRhQO>4c6o2vWIp{0xx49iq?hW1hczzf3ej~{c9xWOA^!aZNtA`V4p7G; zOMJxZtj)={`dIA-tF7UOM^i5eY&6HMtL2p8zMF9L6lzUjm@s)nGa|xkp%c?w?JUq~ z!2FGZYe5lYpm6d^;HBwu2Dx&6rc-KQaoHxiZ6kSga-}|j0Zqex-VrLbM3MNhL&K|^ z#h{e(tIj&p@zE!AXjY*U#nW0UP4|^s@pLLL+Lgl_E03*xB^bg zr_>BEe|S)20&3y{K7z7^%hpVdf*aAaYO`t}XI=MLC{zvSnYWIh-1fiIBR=*X>XQ6b zlb1VQk72r}E}i6&L9baG25P#Kf)Gn#t`18u<|LQRiy!D}4!vVy@Zp-WWO|d08gw1; zm8P_C84YXCMdI`djU8J!olTce4TmvrMx1w>jvMNd_lTpbiykl9xHG%C>FkfwP5>gf zwaq?-@JdamvHmkjHDtm~ranjEvWq1;x1%3^zU9JDtME*4>OT8Lk0vWjjutk(=4dl2 z>L<5DW~9=qK|^bb@8(L4{ErPrVo6VIT}OgM94yJLDB&skfK^kD7BW?kt<_pd^GI>x zh=1IFo2no)XvKH_k{%lY8JHTT;X`1JhJ=9`xNxr!#il}Kx#UN6ZXGVe4#&xZ3?ssl zP4OX=$Eo`V&kfJ=<}N4} zykG|T0tc$;&&AEHigztD_so04Y+95-bj#QQkFRA;OY_rAZyGE#%*Ja}S1QxnW?XE; z&WUfm71$D>s;V8x@yJtND$}5rsj+J=-3Podsh@}F;}i3>TwH0P!Ipzev@nYP zV$u?2aI2zZ!i^}BA4FN_`7{s>uI(LLu9bAkM$#oOE8Gd}oe1P>>^ zfw!k3Q9=;Yn(?eujoudaS`D+9GMdhU5dEw!iawuj-&nj#SrW&`fp_J!VdlXRz-4(> z?TAQ8t820(N1L0(nkI=aLi@%xb!(!-Ksx}Bv*wRhhXBP5dS`I%iLR;nb*u?SO4Ofw1^ z$XrvCawcz~JnHOu_eEvNJyVBeUfM~{9AXfOVJmYevDfn!YR6sTtn*U$0(j7xeyxNN zy-aZ4{slnT-JybCh3S}wR*juX4HT?^v$*!YfVueG%ot15^L*?Dt5P=SEM4cJ4vPar z?P!nu>OB?N4`awM{B1|XX3xs>kC7Hhlzq{r#ODd0Um$BU*CzlJf)-cfv3*du_c6=V z_-&mm@-aUtLEK5xM;rzBr5V_+L2gOAAgk}XHubTa7~Wtbx0}4sQ%qia2}I`LFn7r# z;MyFjqC-BH56|V+BPhgO)azy|&1qA&dLig@=WQD;^(J}x_04Sa37_$F&9Nf!uzTY# z-kA$^4(=^IJGjKqcel@{D5gH?2$-M2`G*thz#jeP_nEKb3V-y7K(T+8*!sH~8Gl#k zY*2{?1nmC*kT|<`>FkwU|aaFN(+~1GZwcEHA&ih za}NZVHSHV)f3i^JCXtaZkub8=e8eE7%NHO6yNd-GHgika#u< zf3Ltzz+7}!KCaUUhu(4Ihh zL4ohhojb}(9&9YQs2q6h27||0f3=1y^k~HD*03l{G^2@_(VW&6awnaEJW^(oL?g|^ z=oSJf$6@NEJY;2l=UZjHsPXh8j#z1Om|%$Zi7PR=Y**X$PoeD87LVKn3rc{0cSxm) zbcPm|W&Ui0|8R{zRm;`4Z=hOKxkMWl-6%>zgh8Wc=+rnkHb5a_(gP0s#ryKY5D`kiYZUOU`<7tHS&OK!;)%glN-% z@=28EqQ5|0KxAXYt-Bu|&L zC!X{EIqpAmcJ&+4&y+_N}r;?d#gX33qN^iPOhH%0xn)pAEyRryw)|wHvE`FH6`THuCky zTq9%6%(=zx0@r?Xf!*8c-+K7De|Zt*CZ>j!e#ml2)A#I= z8GK=u7CE@bciEObXS;Kjc~xqsBzv?PzED*&>`{@Au52Y^eQX56Ta2yi`&zI zR%u>=rWOC@P}5uIAD;WtRTm294QD}rI&bexDkMws-c^p77D#%4nl3mshy*ArufquM zfQbGt(76+2fdeSr0|CI;Um(+$Vg)60I90@Y90BqRGzMtIgHHi4I1bQBF1V!r|F7RH zTu1I*OC&UE0@X2@fC>D&J|`-^)wJCRG~BlpY#w)~1HWS**_#!*0MsP0w#&l7ba5&^ zHuLa6@P>`r$RUM_1zhL}g2n8UU^%(7)6Q^G{NjhwxfJ&6I}e{rKb~rZ)EUJzsm(X; z-e9FDtDaG8L#Kq7gyA`S$I_fLt8WKnqnV>NKYq3nEbvMR?mkIeAunSL3?&iq6F%DJncwS5^ji%qqpGQy_L+K2CT|PCq z)Y!?VNu-~S9@I*V4Fl^bbZll-)RfDkqoET7A_sx;1DZ-&w!aS@n^{O6Z^ZJo%~eyz z$a0k%|Ata}&PyFMBibYbZ`OXPQ9GCrGpdCGsuF1txoITa^NC(&6UatIdJtBJ{)H@&@`~kmN#S!}W#X3v)VVHL{Ga_ zCcYy0x&Nav-=vnp21Y)*)aI4k+_N@N#Ex@z(vy0R3-=v!ye?d~C(V51ku*DpF+sW; zdfn1V&a*vXAwW&@Kzf`#%6qJoFT6xt$WDY4(^9qgtvZdg?0#sgvk;LtbN1OoZMvi! zyFIxp53+dY^Hci}UjC%)yp8ndVtS**rlXA?hiuNcy+$6P7{ zBPcl>Zusn^ooV4VwE-Q6fHDWb8l&`=EHyEe+d?D5M0NoX$Xra%RIFIgYVylPE|!#d z+BefTzuNMrxgHZH!G3s`1{d?h-)+Hx_nK#%$Kn&Pxp&`8vse!Do9zUTj zYl*@GqUt{o)m|mPRhBW|^N6dJjGJl;m5Wl zo=Qg6ga)^6+Q1f1{An{M(;Uat%9sfEjA1VJ`8PzR14XzWgczsiKg zaF6E=?xyZ(>dLu)BTO{Y-I(kAx#^Ys6jt@A;|*QB4f*7Y_OKUIMspWrxeDQcp5jbr z6h&v$qDKAhA(;=$Ixm^9Srs0W3LC3lcV;;MgpfaPMYhGn384N#PO>mg`^u<8xLCI0Vqy>RGvKx_tqaNHPk4T*|-8!cDb)=U1?xKLv`m;QSH#33yT$= zB9msVsp(;P6TKwivc0^H&uT}Ou)_IlpG$9EypIl=CaW{N`Z7mdKRlbE-GTngkVg;X z%1?yYWfAXrD1B4k~vciT>&rU1Q01Xca>1+le zesY!?%6}{o&&z<3JpedIS(htH+t&Y3)#H;?G?G{sx=mPi{Es*$3^3=bO!A0eHW_qlFh&y#F_nY2p zA75a*nQ0v+9=2asVGr(8@;QFh1a(}PEcav(#w+s1<^FuIZxE-SzOq7%8LW2n_$|<( zQ}4r1JkKm{;l6NclvmxuRF zG#<1`=+PXm5$G0A8hlwfn(Qa(71m27ct*SedO64bMDd9zh_NJ4WMfw_#(QBx$oaXr z)Ir*ba<)Z+3HL+g5dW-Im9vQmK^rdDlgH9y!vrc*lSfsW1smhzV01*W>^LRcIa%LIhZTvsXWV8vdi&=ePWZ{({C~KPM>Z}Nv!_c}Sn%nO35y>!M?&8z zEtfkwJ7#>)B$ZbeP-fuZXMK0^3P<>6^)97i9+WBOz*#`Eu-f_NQ;EWdq!QTl;Ck6H zo;cLK7y9v zMZmycJPHQ9wHU$z;c3zDbR~;T!T3PQvy2e~i~oi+fPZm~FQ)unLhKfoiFUE@ic99` z-0$4dqPG{K&U1lM4*e}Tz&Qa>9W=pcQyBhi1A@Ek3NX^gMrrgG0B++11TpDI~QKc;-{Pb}eCQfP3p90|nEpR$ocZX8c1ar^#&=$!?4swUr$J45_ z&Iyyr2RMD9Wjwnj_9^*{w-Iu;J61Gzo60T9Psr5Qsi`qT?OEgrc!7w(jj`XR&Bh_x z*?7jpDNM&Zj%$rLJbO0NG*(tNacBX&xnih8-Q|65_(vVL_6y1Ewr?)`cg-UvhRwg=KAz_;ijb}!OY~yE zT9_;8K0{kat|xB+n6fqlv5laEN1avErp=NJsImFdc6fXuAoS*@cQdyQ{=w2jY?_7+Pgv zt`kPHi3SJb{pOLho0hb16iXdXVI5YJdhKB1 zUmzR6LodQT8&?@_0TX)DZ(;HpK5K!@m`|P`c*Rb?ernreYFT?Q{j!+qYr{^W{&|Xj zz?nWAtTuQM7wQF2(FB{AF*$}9`LqB;f$_A-rdEL&T8XtLbwZQ7IImL>RW;o~gp|GK zj3T*G8}BvSlV1#Ef;>oEiB6r%H-I{f2lST(vJxh&t^|r0!xJ{!5Hu|;01(nzaWc!E zri$hHxaCU&f3w@*@X7k(;;qNFXbAAs8L0(-Afj_w{X7Gx8M}{?2e;trF&i5FR2#>p z49Q@c^*mOIjoC|L@zcp47^dXStzVe^NT+3o5jP*q{q&9$x4ZI+bC&p@B<1{j zPS(Hs{qG76{r3@me$bx*fqK z7y;cWCyl&JP@z0>0oN`50{u8io0r5>&*|dsVzp4d`*0-cm*GJG(b-OKaGa}= zKpbskv8n%|1=?^@q+57RnJq>}XC=RG79dx;rO|qB6L)pUu&%x@GC^;cy5wA%vOrrr zs8aBxE;NdL_{1RTEx>>y8>dA=eyC%F9H*AW@iR? zdYr<7-4H-LYmY4D_|j0H(S~lSGkv{9d={}R(fBFp^PR4N3ok)zGv>7(d^?@GP-kYN zUC$}4_sfDtHE{w7k$#({)q}ntGQ9!IPC-ghrJ<@UgBY3^I@6BTV7{30a*u9t0bnEATNx-@eaElC z;&R=*`vtKPR!$3T(DlxG=2kxME>D2>IDuiibwoEzP*+_T{oEB&T^?0K2@33+l^w5+ zimTXY5D6>aEm_+e)8cg~U53v=FP4UCzxWy)t3bQ2wbgZIikb%p(a&9%HTZwpyV9Vh zvMfxafPjk1rXZ$W09y#)pwP0#jf8YqgvPK5I4U3_Lv4_hJRC_^v`b&A^z1zRti1(AL%bqQt+m(r{z|wO* z$V75np6CbYDeZo#41eqzpTD0MZ52C0mO`%)UXqo3}V3-f2}wMPR+-HN$#b-~GyWUJnXRZvJLmt!B{6@~V5=+6_l@?{y=N8>8|4D}W~dmDvFURxfjGc*!xVbFoUgynCvm$j^Vc%`QEymZbq0C7dHH%#LAHh6FK z^hrz*dZi=e!)r=*=^0C;w2!W3Ov zg&5#0b>4NbdZI4Gso@me`42B6oiQ~BXUbow^m88blxg~e1FS~l(JsZ78_>)#DyKES zG6EUhQEfBYUQ4Za4%H}&%w+MIt>9zk+=@qpja>k#=F0ygUs3I~EK81k%I0PX|`cc6_HzsoG1Zg#o zG_URrJG|wha+Ok^REH-hlwR5b@+}y2fbhMnn4hUV!KDeOG*p_ zl2WonsU@nPf_pCk@TEWzB$!Y6I~UmoNb;~C1AYiV&oba~(|eY6*srCAB`)s-^9R~i zi{P!A^#PiF|BKH&h-E57t2X&gA~;rO8S}mbl-#`6VxPM=)Y%g0ZfN~l?DDQ zklNJ4^Fz8?EcUXCZhL$6jW3uqJz_E+#(iDQw>6xeJg0v2z>Wf$P2@tbFF-rl*Vz`t z~N193jOrC~zZrCd9DVoz>EQf@EZ^ywC>O zR>XG0?hzl7R*d1X3l>0;3uL2uIGi(;?bzGU8t14u+jd-ACclIeFFq|Pr5JND3jrLO z>NrtRx+{>b+8ACu7~wPV4ciKK+iNUpC1+hzd6ahQVyLDj@e-4sng!co^6XZ^-Oe4et%E-LX8_#C^8Y-3CUBnRp?R0 zs8xD#WuhI z-taCK)8K8}-s@C-hZC&%I=09yOWH%H1c*%+uUcup5W!@iQNDh1<9S{FI2V`rvX`Hs z!Pd zBOd0T{X>UFzV2nJ)3(D{1+;$lrQzwA(S>KwSA23RjDl+ZPQU{bjr_PLN4SCq6fvV> z(w<*G7yWfM$ls_os?P8`?usLw->!6k=`e6h>nd_8d;rw0IMPq)o$_t)JWDz$DWF-8 zBkm`)*fpX{`rmRrFb(;pM|$VovD%VtOY8t35*v;To7^9vn#O*4i* zel+ICe>GHgaPK2u6eWCv?{yxe;Xt`&QMH;W~)*R(nS%xWdU#4HW?fNTQ z4{7a8kd3TfY#uP6Z)yuNXAm{?r|jtK9dCjRC}Sn>Hk~_JlB!ebuEO<6laEt zV>X{KKd^9t8Sjh_#815?2gRjdk3~e$Br4rb@=*HR!v#%K-_sVsE0Mc<*u&4hnZbf#x;kn(iwW>9VquCA?gs;MF0q)t5aRf@fvQ-0&ZTi2%k z3p17PhPjd3XJB#!haQ`)JSdKXqKQsPHJ|69Sek8_h|7)InIGJd{l4a> zIQc0;o=BOXB=BwKajB!sCK6+Ur~p;E3%8%iSsEh86|{0(d&_E{4V;Q9-VcAp?91m4 z+Mn`RnckC{gYa#V@Y0e^59mP`1vf-HZLz{+n(qdk?jJOCu% zRsd8H4uFbEW52dnAXEO7HnL@jvD#y_wL(-frP{1xaw+$!QE?N?f3Ac`!KgQWH#Xpr zQo1c=FGEft#BN6>-oR3{c2pX#MUn^=zzP25GV8_~t>3%fChUr@l5UGQbfkM;krEUQ zchQIo+{1KvgK4z2ws$k@MOneeg!OkPZ84H00LmRmLrI}{P|2j{SLUrM#+2nv#0w`z zwZceJOOrmMKok5m)`r0~V0!Eod$MSXhFv@EnW7ETC!fwf>72DRH8tI>UsN?SX-QgI zeFm}k5GD>GeQI1m4^Mh}KItj0rQe-KjO_-;QQkVDupY6@l0V(!!Ry1r-fetNoJmH2 z%2A&hGN12$vNWGpW4Ui|K2_YJ!oLg(3P)YXBp!Q>mQBRn=~kf1-u}4bzzGYuGxwCR}#`o=5tYzE}u8+S{IeN02_KW!<(HYgJ zC!Kk_v-tM!Jdn+@))!UoI!JiWo&Vt5eD3_u1;bkNlE`}W2N{2Ff6`n&+$gTFj!9EH zvI6m96Ae&e5D;M3rNIQLJYpA297AjcjsfC>{vv4vIAl*q_YfJTF@P^a6aqatE#O4b z^?5VzK?IUShI)Vk4|7p01aStA_;m3_6$pu=zadF&K;bd*c5~j`N7lcu5ct*~oNO=d aa8F1T#qMRM_3fYA231a2gHaJ5`u_n$MFGM9 literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Drivers/.DS_Store b/pec930_sdk-v1.0.1/Drivers/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6ded2c5de37b258a885cc0c0e63d70e1fecf2de9 GIT binary patch literal 6148 zcmeHKJxc>Y5S`H|ffS~++#ev4U}bkEmtII?DVKv-T-bov?;o@FZ~5j!$(aKi5s?|# zeY^9uw-0W2hlqIb($0ydL^MVdWEl*Is0U3a?tBJh&2dAs_IcAaId=nz{-R30{haP; zMN7J+gYUhUvKhmue-RKEWg@!xvrZoH_!`P7Z0y*cgH^Mw?6x)gLSTFND&eY z1Ovf9Fc1v$K+cDRCRjNZLp?gsX$b%vL9K$Z)DjYt94p6S z2n&QQ6lkIBB?enK^vV4y$6{#V#9n-`ul!NGu&$2$N!^Jn!{~#7V4%;ysZFPH|F7`N z3>NwQkeCGn!N5ObfJgPZUSLyxw;pXz?%IU*h$bR_MFtRzdyfE2XTX(A(ey>5etQijMdYG1Sw2=D4v!XPZo{` zmz+Q?gS_Sv;1ZZAfdU*#i@nW(sz}Tp8fJvTNk4YT4u_+r9mP>3tEabbPrsrh9lcFA)r67K!)iiz`jxp3%4kQ-wp!zQ z3T4w7v(4m?g_!)9YQ~aCtk;=l#5k-wJ?g=B{a}K&DPt^dn`W!+7zx9+y1Npyp}Kk; zJD%9$&f8_+Qfz_(x?IaJWp;M!aR;F!eK2=Ha9P>PHS0FkZQZ%6Z9>T}D3s;m`JE}l zF`}m4tvWH?(hO^$W5m!BgFW~QSqWpmp~odDA1c}{bx5CBxM*=FSxSIJd!`vFuTNpaXnwOkYEFx9ATN{YtV*2^0Lohk3MN+TQGBo_y|(6)x~D2~L& z>I31xUb<|P>Lgl*b&GE40>f=XT#qxT#`TsFRAFyNjX3K5o;XgK8Z;weQ=}`6P~b69 z?4}deX_~H06fRo4Fw!1C4#lui2BywX{w#y0TogqyR9nt;HpBoSp>h2Ux9!R}R9ndq zMGQ>U)Loa7)g+82yN?_oqnJ26LEa?qle6R;`HEa5SI9N;3;B)QAb$aYED#|d7D6eM zK{-^w!%zd8p$VFy1zMpSbl49AFbqjZ!9h3#Pr)H}EZ-hwtDjd=EdsHTW5RhdEB-ts1N#or+bt<gkssYCp>-Tu|R%#P$&aY|*U1gY0|n;6QdIY~sO}BW=&F1xv_UWQ z!5-)b6&{BJV1k9pe+Ul45g3IhQT3lgVFD8h0kCd z&cZqP+B1a9Xa+yQuNkVnD?_z!;(XG5`uOP=o4c4#&+uMD_OxH0oyzCib8G418S|tf zam%!=0mRU~SX6e#&y>FT74^>zdYezDSVqQ8pj3r z!zI8az$L&Xz$I|MOMu4zS)?9)aO-^%cYCKvf1mJ%eD4yZx@P+5_l%-%T_=0Hl+wK(S9>a*9+DpZBD}y0NvE*WaWtM<@?(9WC~2i)@%S?0 z=3Gp?=_G~O@)*(Y6Tj^{Q@Z!|A$&eO|MYPbksr@JInR{4xqI%(?}{hSv_76E=l+~J zF3j)V`V-N;?$3RSo$l3b?ZP6@Z)ea<`}Wyrd>+2Q{kZ0vBg4-v4Wu z{r>+QTc1zNCBP-{?@Iu(!;x@3?ql+cc;=SqUArKbeOM^XI2QU~+hxJZy^e>_y^e<+ udOv8LOXO9EtEEkZV+>*opSyk$@DAQ<;osH&$KTbbBK+{w4Y+$b{{I`aDmOX+ literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a86207171f90cc69cb27f42c7aec225679a18997 GIT binary patch literal 10244 zcmeHMU2GIp6uxI#V1|x%N`Ls9rb`xxlnQMr6@tL_kG~dLyDi=RK$+bc+Oe}U>(1=9 z&@?tapn~zqMAT?Z{EabcG^h`f0RF(EAq@%P0V6TKXky}n@`9dw?`(n6O?V-JWNvcr zx%ZxP?#%t>d^3CQ5<;Lkqt_7peyAXC#z>{)BkMAZgN0OzZ_E zKp;RMKp;RMKp;TiVMGAG*|dm7Tn24`K!8Aiz$^mv{Sd-RWyF`$T(VaOHY^1|S%}lD zU?1}U<`eQ|#Fx`tGFM!aXAj`Jf}dglcSn7Qnxl;Pa+*u-PJp`;@UIMhh63#B=oez< z1R`7pZGb?4z`Y32+_6i6Eg$oug5*LX@ z;-ToMGamIcFXJ|A=|MW`aU3h2>ud3YrZGOOl(jgvrlSXnkXS>O0nO{lJ6^Hfb}a%+8UO{ig0mDAnlD2b_ZwLHW z0(orC_D<#7o9-s8INmFDoOkoqNL@7HBvX7rxjwI*n{DAB6~uEOUCV(aEiRJf$JJPW zY+!Kc(6FLpT%+5tG|$W$t(s@J!%DG>sO?QSc30ZSB3gY3$I2va)RZJNE0IBCqsg+O z=5fOv&?b6}36J)vVxcv)!8x(%DQY;W4N??CsAQnI8}mMfO_Wlh(NTSmX;CJb9Q?UCMbQ};#(@R`}3 zdDJx0l2igUJ+_uKW|ps5S*lj5RXHzid)rr3!eT5FH=oOx-m#g|k|oM2H7pP5xYzxT zPFK@K<&4BMYt^tiNHr~K16y4b*>ts9Bloz7gs5oTaHCu&_l#jsNs7y78stW`*V5vK zB`G?0+bVBU`?CISm3BV4L#|L`_^^|>6<6YO&1$Q9m|nI+bG^=#Vbfc>#C5w-H{gzH zX`^!-gWA8NcARC;6X&T@n{IjzRWdZf>NBF)PZw;`bwi&iU9oa`v`0k`#k8{~k_hqV zTv9HJq8N@;^Uw=(K}h(V@hf;oK~9tR$fx8y zxj?=rm&rA9gZxSUCb!6cK%f9bD1qfr1?!+1YT!v|gq_d<`=JxMpdSo43L}t$3}j&f zj=>A?BD@4A;S{_EZ^B#fHoOBL!RPP=dy!d-m?x*WR)JQDEWKV#>R+@`|O)R;^uMyLs!5=Gpk<0iBECJDI`ga2JUf9ay-` z31u3SYNcEi$}#jdH#t{(kw?aaNGYu>@~u~|5s^pA0)M!!8i(!5LO!hAuu(+LDgqnI zm75wQWTsN!4>xSVA@G6x^mYk3sua$sNP?Ymm8=j+@|S7bh09!09v}g(kn7|(B*0B_ z3yMI2a#)Q)zZrwR4cb}YcR@D{!VnySVbI`N7y}Dzq`)ya4wEni&m#d|Mhd(Fufpqa z8s0z}ybmA1hww3cf+RQtU&A+W4$i{`_`#>cRV2gj@YkFGKQJf2^L~z!PHU_GEoO)D zv9lMO@{u9w==W`#8ol!~7oxW_FTt|Wv~4-|2q_#l`5C{+m5C{+m5C{->^bjcE zw;ZD9|84pI|9|v07Tj@wK!Ct~BLIc1(bi@(&-de=p0$Ut9>GcrwVURWxnRSN<59BX ycpT6?Q@9}i5Ay%J&*C3M{{KIxB<(5y literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.c b/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.c new file mode 100644 index 0000000..423cda5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.c @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file starterkit.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "starterkit.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.h b/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.h new file mode 100644 index 0000000..c1763ae --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/BSP/StarterKit/starterkit.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file starterkit.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __starterkit_H_wdeYMM70_lNLW_HSdS_sZLf_uhvq7CKQjo90__ +#define __starterkit_H_wdeYMM70_lNLW_HSdS_sZLf_uhvq7CKQjo90__ + +#ifdef __cplusplus +extern "C" { +#endif + + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f74337f42ad47625f06b41745f8b67a9297d6167 GIT binary patch literal 10244 zcmeHMTWl3Y7@mJyVArm&r56fp(?bprDHU2M6@oyo+*)YuY3b<&%AT`JyLQj+@$8<{ zLetpzfC|PZ6Hy~E!3!}4jRy5W62J>Q8q$yu9v~9qiy9Ljlo#}$nLWKwYr=y@%uX`% z&-|C!o$q}APG?F8f%>#wMM#JcB4VXdk+J!ULhZE9DuS&tO2(SikdC`uj*{t*LsIO;>bU#&04x#Zyl{KE(MPX_;l0_^EHe~7sg zsO2(f0|WvDW+On)?m5IHHi_%*^z%DYSp!v(xRXe-IOXTtQ_cyeu`y;jG1Q3XP9M{v z7p~Mzx9WdmO%6_*H9v%5_zEsbk$7y_P5QHb9!pxL>s3}>2O%eS-uwmP0x?fK7#Vbi zBcA4^-Fhw6OGh1eAXQ!MkH`BnEo)gP1{bqLQ(j$4YyikpHM|*nv4)!Zb+BMn@ zOY_W((WrTb+pjEg5sN)>$8Jj*8N{F~?pW!Bjh6hlX2sL!Y}8p+#5`uWJ=#czG2+oa z4UDH8%W896(=#2rJL=74iuSlp%4=ZrMooMapI|Y4Tx*gBy9bPvi&B!#Eh-7ETC;BB z=52L5_wH|>Q1TZS$a3+Lu8irLG0W)I+_+)urajO(Z0g=%5B?IiXC5()lqBUtMTe~= zjESYomKUg{YFRdl`%cA*N?44hW9Bny(>pp*kiS@2p@!u?9oM?g(dlfusGOIWWwjbs zd#R-%Wnim|B2$;E6>^7*NQjEY9oNfMa>o!-MN(X@sg`ThPD_g!mZa!BY>T{A?aKJ8 zRhqeSyIibBF<%n66j$Q9dbLqKL?7Ftxn671u<0vZ<+fdD>v0FQl+ikjRQ2De8MW;9 zL_G~^(oN5yMutXMeM%I&>4bHjelT+jj`G8y^m&upp8o5dCke|q} zR;*rIxoOMx`bkD|3TIh6Jr`I4%t#xS0E{5_k(aViEtShc*_@op zMxLFWm^sFXNRwDu;CruJC1U0%^ZenOavU}*^ZBrJ-FgwTR1w%vF5OryVJ<2;{&3x9 z90DK6Pi~ViE0x>{6=}aiE|V1^N&YlVJ8_z;%0Ec?>*N;s9w~p9+=Dz&pa@nX%{L*< zo1mFdy$#x-7y95J^n(UZ!w^_tBk7OAF&Kq0cor%DB9i_kco|-WQ}7xR|7~~&-i5R9 zKGOa?d+8n3WZ~$;!cqQ9{|pGu|BfA;|H*@1dHtWx|9=8tB>tfQ literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b6c143eb7a1d0ff66b8715e83c27e870c2616c43 GIT binary patch literal 6148 zcmeHKOG*Pl5Uny11A=7fvagUEw4pu0fVh;&fG#FXK-~AmT<09Qfk*JwN14IFWe}-? z?pITv{ydoOE+XRXTel%v6VVDykVTmhG0(a#JopmGGRCfNhoOf`3wQl_khL$Up$976 z>v;WY>Yq2wZrC4m8&{_U^x*waO4|=DEa0ZzJiZ_A#@_B1@8M-U>Ic$7f`MQl7zhS} zf%7pS7d2#cZ5Vwp5DWwZ-weq4kkACPV>Q&H1D%!tz$MHo(504;oaC4tt06oPwp5^{ zvX>Za>98k{%Z}C1(uuwJV4wM`cwwC#<0lO#&W6zk1Hr(Q0WZ?ma{u4smzgc{rz!Cj z3Qbi`%HYABz$c8pD0lz> literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/SVD/PEC930.svd b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/SVD/PEC930.svd new file mode 100644 index 0000000..d5c1291 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/SVD/PEC930.svd @@ -0,0 +1,10421 @@ + + + Padauk-tech + PEC930 + 1.0 + RISC-V 32-bits CPU + 8 + 32 + 32 + read-write + + 0x00000000 + 0xFFFFFFFF + + + EFLASH_MEM + Embedded flash memory + 0x00000000 + + 0 + 0x8000 + registers + + + + DATA0 + The first address + 0x00 + 32 + 0 + 0xFFFFFFFF + + + DATA_END + The endt address + 0x7FFC + 32 + 0 + 0xFFFFFFFF + + + + + SRAM_MEM + SRAM memory + 0x20000000 + + 0 + 0x1000 + registers + + + + DATA0 + The first address + 0x00 + 32 + 0 + 0xFFFFFFFF + + + DATA_END + The endt address + 0xFFC + 32 + 0 + 0xFFFFFFFF + + + + + NVR_MEM + Non-Volatile Region + 0x00200000 + + 0 + 0x2000 + registers + + + + DATA0 + The first address + 0x00 + 32 + 0 + 0xFFFFFFFF + + + DATA_END + The endt address + 0x1FFC + 32 + 0 + 0xFFFFFFFF + + + + + CORET + RISC-V core of SoC + 0x18000000 + + 0 + 0xC + registers + + + SysSW + System Software interrupt + 3 + + + SysTimer + System Timer interrupt + 7 + + + BusError + Bus error interrupt + 17 + + + PerfMon + Performance Monitor + 18 + + + + revd + NA + 0x00 + 32 + 0 + 0xFFFFFFFF + + + + + UID + Universally Unique Identifier + 0x00201F00 + + 0 + 0xC + registers + + + + UID1 + Unique Identifier 1 + 0x00 + 32 + 0 + 0xFFFFFFFF + read-only + + + UID2 + Unique Identifier 2 + 0x04 + 32 + 0 + 0xFFFFFFFF + read-only + + + UID3 + Unique Identifier 3 + 0x08 + 32 + 0 + 0xFFFFFFFF + read-only + + + + + FLASH + Flash Controller Module + 0x4000F800 + + 0 + 0x200 + registers + + + + + CMD + Flash Command Register + 0x000 + 32 + 0x0 + 0x0000FFFF + read-write + + + START + Flash command start + 0 + 1 + read-write + + + CMD + Flash command ID + 1 + 3 + read-write + + + PROG + Flash 32-bits program + 0 + + + ERASE_SECTOR + Flash sector erase + 1 + + + ERASE_CHIP + Flash chip erase + 2 + + + + + NWS + Flash waits cycles after OP + 5 + 3 + read-write + + + UNLOCK + Unlock Flash P/E operations + 8 + 1 + read-write + + + ACME + Enable Flash Access Counter + 9 + 1 + read-write + + + ACMR + Reset Flash Access Counter + 10 + 1 + read-write + + + AINC + Flash enable auto address increase or not + 13 + 1 + read-write + + + KEY + Auth key 0xA5A5 + 16 + 16 + write-only + + + + + SR + Flash Status Register + 0x004 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + CMD_END + Flash idle flag (0:busy), write 1 to clear + 0 + 1 + read-write + + + KEY_ERR + Flash error flag (0:success), W1C + 1 + 1 + read-write + + + ACC_ERR + Flash access error flag, W1C + 2 + 1 + read-write + + + ADDR_ERR + Flash addressing error flag, W1C + 3 + 1 + read-write + + + HCM + Flash access count full flag, W1C + 6 + 1 + read-write + + + HSI_TC_ERR + HSI_TC's complement do not match in sysinfo area + 7 + 1 + read-only + + + PROTCT_R2_ERR + Protect_R2's complement do not match in sysinfo area + 8 + 1 + read-only + + + PROTCT_R1_ERR + Protect_R1's complement do not match in sysinfo area + 9 + 1 + read-only + + + RSTIO_AF_ERR + RSTIO_AF's complement do not match in sysinfo area + 10 + 1 + read-only + + + LDO_TRIM_ERR + LDO_TRIM's complement do not match in sysinfo area + 11 + 1 + read-only + + + VBUF_TRIM_ERR + VBUF_TRIM's complement do not match in sysinfo area + 12 + 1 + read-only + + + LSI_TRIM_ERR + LSI_TRIM's complement do not match in sysinfo area + 13 + 1 + read-only + + + HSI_TRIM_ERR + HSI_TRIM's complement do not match in sysinfo area + 14 + 1 + read-only + + + + + AR + Flash Address Register + 0x00C + 32 + 0x0 + 0xFFFFFFFF + read-write + + + DR + Flash Data Register + 0x010 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + ACM + Flash Access Count Register + 0x20 + 32 + 0x0 + 0xFFFFFFFF + read-only + + + DIV + Flash clock division + 0x028 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + DIV + Flash Clock DIV + 0 + 8 + read-write + + + + + + + GPIO + General Purpose IO + 0x40011000 + + 0 + 0x64 + registers + + + + + DAT + GPIO Data Register + 0 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + LAT + GPIO output data latch register + 0x04 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ITS1 + GPIO interrupt type set register + 0x08 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ITC1 + GPIO interrupt type clear register + 0x0C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + OES + GPIO output enable set register + 0x10 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + OEC + GPIO output enable clear register + 0x14 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + INES + GPIO input enable set register + 0x18 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + INEC + GPIO intput enable clear register + 0x1C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + IES + GPIO pin interrupt enable register + 0x20 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + IEC + GPIO pin interrupt clear register + 0x24 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ITS0 + GPIO pin interrupt type select register + 0x28 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ITC0 + GPIO pin interrupt type clear register + 0x2C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PLS + GPIO pin interrupt polarity set register + 0x30 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PLC + GPIO pin interrupt polarity clear register + 0x34 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + IST + GPIO pin interrupt flag status register + 0x38 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PUS + GPIO input pull-up set register + 0x3C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PUC + GPIO input pull-up clear register + 0x40 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ODS + GPIO output open-drain set register + 0x44 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + ODC + GPIO output open-drain clear register + 0x48 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PDS + GPIO input pull-down set register + 0x4C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + PDC + GPIO input pull-down clear register + 0x50 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + OSRS + GPIO Open Sink Set register + 0x54 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + OSRC + GPIO Open Sink Clear register + 0x58 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + CTS + GPIO Schmitt-Trigger Set register + 0x5C + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + CTC + GPIO Schmitt-Trigger Clear register + 0x60 + 32 + 0x0 + 0xFFFFFFFF + + + P00 + Pin 0 + 0 + 1 + read-write + + + P01 + Pin 1 + 1 + 1 + read-write + + + P02 + Pin 2 + 2 + 1 + read-write + + + P03 + Pin 3 + 3 + 1 + read-write + + + P04 + Pin 4 + 4 + 1 + read-write + + + P05 + Pin 5 + 5 + 1 + read-write + + + P06 + Pin 6 + 6 + 1 + read-write + + + P07 + Pin 7 + 7 + 1 + read-write + + + P08 + Pin 8 + 8 + 1 + read-write + + + P09 + Pin 9 + 9 + 1 + read-write + + + P10 + Pin 10 + 10 + 1 + read-write + + + P11 + Pin 11 + 11 + 1 + read-write + + + P12 + Pin 12 + 12 + 1 + read-write + + + P13 + Pin 13 + 13 + 1 + read-write + + + P14 + Pin 14 + 14 + 1 + read-write + + + P15 + Pin 15 + 15 + 1 + read-write + + + + + + + GPIOA + 0x40011000 + + GPIOA + 27 + + + + GPIOB + 0x40012000 + + GPIOB + 28 + + + + AFIO + Alternate Function I/O + AFIO + 0x40011070 + + 0x0 + 0x10 + registers + + + + PAAFR + GPIO PortA AF control register + 0x0 + 0x20 + read-write + 0x00000000 + + + PA0 + Pin index + 0 + 3 + read-write + + + PA1 + Pin index + 3 + 3 + read-write + + + PA2 + Pin index + 6 + 3 + read-write + + + PA3 + Pin index + 9 + 3 + read-write + + + PA4 + Pin index + 12 + 3 + read-write + + + PA5 + Pin index + 15 + 3 + read-write + + + PA14 + Pin index + 18 + 3 + read-write + + + PA15 + Pin index + 21 + 3 + read-write + + + + + PBAFR + GPIO PortB AF control register + 0x4 + 0x20 + read-write + 0x00000000 + + + PB0 + Pin index + 0 + 3 + + + PB1 + Pin index + 3 + 3 + + + PB2 + Pin index + 6 + 3 + + + PB3 + Pin index + 9 + 3 + + + PB4 + Pin index + 12 + 3 + + + PB5 + Pin index + 15 + 3 + + + + + FN1_AFR + Peripheral Alternate Func control register + 0x8 + 0x20 + read-write + 0x00000000 + + + BKIN + Peripheral Alternate Func selection + 0 + 4 + + + ECAP0 + Peripheral Alternate Func selection + 4 + 3 + + + ECAP1 + Peripheral Alternate Func selection + 7 + 3 + + + ECAP2 + Peripheral Alternate Func selection + 10 + 3 + + + EPETR + Peripheral Alternate Func selection + 13 + 4 + + + + + FN2_AFR + Peripheral Alternate Func control register + 0xC + 0x20 + read-write + 0x00000000 + + + TCAP0 + Peripheral Alternate Func control register + 0 + 3 + + + TCAP1 + Peripheral Alternate Func control register + 3 + 3 + + + TCAP2 + Peripheral Alternate Func control register + 6 + 3 + + + T2ETR + Peripheral Alternate Func control register + 9 + 4 + + + I2C_PULL0 + Peripheral Alternate Func control register + 13 + 1 + + + I2C_PULL1 + Peripheral Alternate Func control register + 14 + 1 + + + I2C_PULL2 + Peripheral Alternate Func control register + 15 + 1 + + + I2C_PULL3 + Peripheral Alternate Func control register + 16 + 1 + + + I2C_PULL4 + Peripheral Alternate Func control register + 17 + 1 + + + I2C_PULL5 + Peripheral Alternate Func control register + 18 + 1 + + + I2C_PULL6 + Peripheral Alternate Func control register + 19 + 1 + + + I2C_PULL7 + Peripheral Alternate Func control register + 20 + 1 + + + + + + + SYSCFG + System Configuration controller + 0x4001F000 + + 0 + 0x400 + registers + + + + PMUCR + Power Management Unit Control Register + 0x04 + 32 + 0 + 0xFFFFFFFF + read-write + + + PMUEN + Enable pmu + 0 + 1 + read-write + + + + + MCOCR + MCU Clock Output Control Register + 0x0C + 32 + 0 + 0xFFFFFFFF + read-write + + + MCOSEL + Select output clock + 0 + 3 + read-write + + + HSI + HSI RC clock + 0 + + + HSE + HSE OSC clock + 1 + + + CLKDIV + HSI Clock Divider + 2 + + + LSI + LSI RC clock + 3 + + + FCLK + F clock + 4 + + + GND + Peripheral clock + 7 + + + + + DivEn + Enable MCO outupt pre-scalar + 6 + 1 + read-write + + + DivSel + Select outupt pre-scalar + 7 + 1 + read-write + + + Divider + The pre-scalar value + 8 + 8 + read-write + + + SWRstEn + Trigger software reset + 16 + 8 + read-write + + + OFF + Software reset off + 0 + + + ON + Software reset on + 0x5a + + + + + + + SYSRSTSR + System Reset Status Register + 0x10 + 32 + 0 + 0xFFFFFFFF + read-write + + + SWRST + Software reset (Write clear) + 0 + 1 + read-write + + + WDGRST + Watchdog reset (Write clear) + 1 + 1 + read-write + + + LOCKUPRST + Lock-up reset (Write clear) + 2 + 1 + read-write + + + PORRST + Power reset (Write clear) + 8 + 1 + read-write + + + PADRST + nRST Pad reset (Write clear) + 9 + 1 + read-write + + + LVDRST + LVD reset (Write clear) + 11 + 1 + read-write + + + REBOOTRST + Reboot reset (Write clear) + 12 + 1 + read-write + + + + + REBOOT_UNLOCK + Unlock reboot to latch paraments + 0x14 + 32 + 0 + 0xFFFFFFFF + read-write + + + AUTHKEY + Reboot signature: 0xAB56 + 0 + 16 + read-write + + + + + SYSRSTCR + System Reset Control Register + 0x18 + 32 + 0 + 0xFFFFFFFF + read-write + + + REBOOTEN + Trigger system Re-boot + 10 + 1 + read-write + + + + + DEBUGENCR + Debug enable Control Register + 0x1C + 32 + 0 + 0xFFFFFFFF + read-write + + + TIM0 + Tim0 debug mode + 2 + 1 + read-write + + + TIM1 + Tim1 debug mode + 3 + 1 + read-write + + + LPTIM + LPTIM debug mode + 4 + 1 + read-write + + + EPWM + EPWM debug mode + 6 + 1 + read-write + + + TIM2 + TIM2 debug mode + 11 + 1 + read-write + + + WDG + WDG debug mode(def: enable) + 14 + 1 + read-write + + + AUTHKEY + Reboot signature: 0x8A57 + 16 + 16 + write-only + + + + + SYSCLKCR + System Clock Control Register + 0x20 + 32 + 0 + 0xFFFFFFFF + read-write + + + CLKSW + System Clock Source Switch + 0 + 3 + read-write + + + HSI + HSI RC clock source + 0 + + + HSE + HSE OSC clock source + 1 + + + CLKDIV + Clock Divider source + 2 + + + LSI + LSI RC clock source + 3 + + + + + CLKDIV + Clock Divider, factors = (CLKDIV + 1) + 8 + 4 + read-write + + + LSIAON + LSI always on + 23 + 1 + read-write + + + SYSTICKCR + Sytem tick Control Register + 24 + 2 + read-write + + + LSI + Systick from LSI + 0 + + + HSI_DIV2 + Systick from HSI Divide 2 + 1 + + + HSI_DIV4 + Systick from HSI Divide 4 + 2 + + + HSI_DIV8 + Systick from HSI Divide 8 + 3 + + + + + + + PRSTEN + Peripheral Reset Control Register + 0x24 + 32 + 0 + 0xFFFFFFFF + read-write + + + UART0 + Reset enable (It should generate pulse signal to reset) + 0 + 1 + read-write + + + TIM0 + Reset enable (It should generate pulse signal to reset) + 2 + 1 + read-write + + + TIM1 + Reset enable (It should generate pulse signal to reset) + 3 + 1 + read-write + + + LPTIM + Reset enable (It should generate pulse signal to reset) + 4 + 1 + read-write + + + ADC + Reset enable (It should generate pulse signal to reset) + 5 + 1 + read-write + + + EPWM + Reset enable (It should generate pulse signal to reset) + 6 + 1 + read-write + + + DSP + Reset enable (It should generate pulse signal to reset) + 7 + 1 + read-write + + + COMP0 + Reset enable (It should generate pulse signal to reset) + 8 + 1 + read-write + + + SPI + Reset enable (It should generate pulse signal to reset) + 10 + 1 + read-write + + + TIM2 + Reset enable (It should generate pulse signal to reset) + 11 + 1 + read-write + + + I2C + Reset enable (It should generate pulse signal to reset) + 12 + 1 + read-write + + + COMP1 + Reset enable (It should generate pulse signal to reset) + 13 + 1 + read-write + + + WDG + Reset enable (It should generate pulse signal to reset) + 14 + 1 + read-write + + + AMISC + Reset enable (It should generate pulse signal to reset) + 15 + 1 + read-write + + + + + PCLKEN + Peripheral Clock Enable Control Register + 0x28 + 32 + 0 + 0xFFFFFFFF + read-write + + + UART0 + PCLK enable Uart 0 + 0 + 1 + read-write + + + TIM0 + PCLK enable TIM0 + 2 + 1 + read-write + + + TIM1 + PCLK enable TIM1 + 3 + 1 + read-write + + + LPTIM + PCLK enable LPTIM + 4 + 1 + read-write + + + ADC + PCLK enable ADC + 5 + 1 + read-write + + + EPWM + PCLK enable EPWM + 6 + 1 + read-write + + + DSP + PCLK enable DSP + 7 + 1 + read-write + + + COMP0 + PCLK enable COMP0 + 8 + 1 + read-write + + + SPI + PCLK enable SPI + 10 + 1 + read-write + + + TIM2 + PCLK enable TIM2 + 11 + 1 + read-write + + + I2C + PCLK enable I2C + 12 + 1 + read-write + + + COMP1 + PCLK enable COMP1 + 13 + 1 + read-write + + + WDG + PCLK enable WDG + 14 + 1 + read-write + + + AMISC + PCLK enable analog misc. + 15 + 1 + read-write + + + + + ICEIOCR + ICE I/O Control Register + 0x2C + 32 + 0 + 0xFFFFFFFF + read-write + + + JTAGIOEN + I/O force on jTag pins. 0: normal I/O, 1: ICE pins + 0 + 1 + read-write + + + DBG_CTRL_EN + Enable debug control + 1 + 1 + read-write + + + DBG_EN + Enable debug + 2 + 1 + read-write + + + AUTHKEY + auth-key 0xE653 + 16 + 16 + read-write + + + + + RSTPINCR + Reset pin control register + 0x30 + 32 + 0 + 0xFFFFFFFF + read-write + + + RSTPINAF + Reset Pin switch to general I/O + 0 + 16 + read-write + + + ON + Enable reset pin + 0xA563 + + + OFF + Disable reset pin (Pin changes to I/O) + 0 + + + + + + + TIM2_CON_SEL + TIM2 selection + 0x34 + 32 + 0 + 0xFFFFFFFF + read-write + + + CH1 + selection + 0 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH2 + selection + 4 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH3 + selection + 8 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH4 + selection + 12 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + BREAK_SEL + TIM IP Config + 17 + 1 + read-write + + + COMP0A_SEL + COMP0A selection + 18 + 1 + read-write + + + COMP1A_SEL + COMP1A selection + 19 + 1 + read-write + + + VC_CH1_INV + VCOUT_SEL + 20 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH1 + VCOUT_SEL + 21 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_ch1_inv)) + 0 + + + 1 + CH1_CON[2:0] + 1 + + + + + VC_CH2_INV + VCOUT_SEL + 22 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH2 + VCOUT_SEL + 23 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH2_inv)) + 0 + + + 1 + CH2_CON[6:4] + 1 + + + + + VC_CH3_INV + VCOUT_SEL + 24 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH3 + VCOUT_SEL + 25 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH3_inv)) + 0 + + + 1 + CH3_CON[[10:8] + 1 + + + + + VC_CH4_INV + VCOUT_SEL + 26 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH4 + VCOUT_SEL + 27 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH4_inv)) + 0 + + + 1 + CH4_CON[14:12] + 1 + + + + + COMP0D_SEL + COMP0D selection + 28 + 1 + read-write + + + COMP1D_SEL + COMP1D selection + 29 + 1 + read-write + + + + + EPWM_CON_SEL + EPWM selection + 0x38 + 32 + 0 + 0xFFFFFFFF + read-write + + + CH1 + selection + 0 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH2 + selection + 4 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH3 + selection + 8 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + CH4 + selection + 12 + 3 + read-write + + + PAD + From PAD + 0 + + + UART + From UART0_RXD + 1 + + + IIC + From IIC_SDA + 2 + + + OSC32K + From OSC_32K + 4 + + + + + BREAK_SEL + EPWM IP Config + 16 + 1 + read-write + + + BREAK_OSSI0_DISOUT + EPWM IP Config + 17 + 1 + read-write + + + COMP0A_SEL + COMP0A Selection + 18 + 1 + read-write + + + COMP1A_SEL + COMP1A Selection + 19 + 1 + read-write + + + VC_CH1_INV + VCOUT_SEL + 20 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH1 + VCOUT_SEL + 21 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_ch1_inv)) + 0 + + + 1 + CH1_CON[2:0] + 1 + + + + + VC_CH2_INV + VCOUT_SEL + 22 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH2 + VCOUT_SEL + 23 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH2_inv)) + 0 + + + 1 + CH2_CON[6:4] + 1 + + + + + VC_CH3_INV + VCOUT_SEL + 24 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH3 + VCOUT_SEL + 25 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH3_inv)) + 0 + + + 1 + CH3_CON[[10:8] + 1 + + + + + VC_CH4_INV + VCOUT_SEL + 26 + 1 + read-write + + + 0 + COMP + 0 + + + 1 + COMP Inverse + 1 + + + + + VC_CH4 + VCOUT_SEL + 27 + 1 + read-write + + + 0 + COMP(Used in conjunction with Vc_CH4_inv)) + 0 + + + 1 + CH4_CON[14:12] + 1 + + + + + COMP0D_SEL + COMP0D Selection + 28 + 1 + read-write + + + COMP1D_SEL + COMP1D Selection + 29 + 1 + read-write + + + LVD_SEL + LVD Selection + 30 + 1 + read-write + + + WDG_SEL + Watchdog Selection + 31 + 1 + read-write + + + + + PRSTEN1 + peripheral modules reset + 0x40 + 32 + 0 + 0xFFFFFFFF + read-write + + + GPIOA + GPIO reset enable (It should generate pulse signal to reset) + 0 + 1 + read-write + + + GPIOB + GPIO reset enable (It should generate pulse signal to reset) + 1 + 1 + read-write + + + CRC + CRC reset enable (It should generate pulse signal to reset) + 7 + 1 + read-write + + + + + HCLKEN + Enable clock of Modules of AHB + 0x44 + 32 + 0 + 0xFFFFFFFF + read-write + + + GPIOA + GPIO clock enable + 0 + 1 + read-write + + + GPIOB + GPIO clock enable + 1 + 1 + read-write + + + CRC + CRC clock enable + 7 + 1 + read-write + + + + + EVT_SEL + Event select + 0x48 + 32 + 0 + 0xFFFFFFFF + read-write + + + IRQSEL + Link interrupt source as event (bit-order is IRQ number) + 0 + 32 + read-write + + + + + NMICR + NMI Control Register + 0x4C + 32 + 0 + 0xFFFFFFFF + read-write + + + SEL + Connect IRQ number to NMI + 0 + 5 + read-write + + + EN + Enable to connect IRQ sourec to NMI + 5 + 3 + read-write + + + ON + Enable interrupt link to NMI + 0x5 + + + OFF + Disable interrupt link to NMI + 0 + + + + + + + CHIPID + Chip ID register + 0x100 + 32 + 0 + 0xFFFFFFFF + read-only + + + + + UART + Universal Asynchronous Rx/Tx + 0x40002000 + + 0 + 0x200 + registers + + + + DAT + UART TX/RX Data Register (FIFO: 8) + 0x0 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + DAT + 8/9 bits data + 0 + 9 + read-write + + + FE + Frame error flag + 9 + 1 + read-write + + + + + CR + UART Control Register + 0x4 + 32 + 0x0 + 0xFFFFFFFF + + + MODE + Mode select + 0 + 3 + read-write + + + 8D + 8-bits data + 1 + + + 7D1P + 7-bits data + 1-bit parity + 3 + + + 9D + 9-bits data + 4 + + + 8D1W + 8-bits data + 1-bit wake-up + 5 + + + 8D1P + 8-bits data + 1-bit parity + 7 + + + + + STOPB + width of STOP bits + 3 + 2 + read-write + + + 0_5B + 0.5 bit stop + 0 + + + 1B + 1 bit stop + 1 + + + 1_5B + 1.5 bits stop + 2 + + + 2B + 2 bits stop + 3 + + + + + PAR + Parity check + 5 + 1 + read-write + + + EVEN + Even parity check + 0 + + + ODD + Odd parity check + 1 + + + + + LPB + Enable Loop back mode + 6 + 1 + read-write + + + RUN + Baudrate generator run + 7 + 1 + read-write + + + RXEN + RX enable + 8 + 1 + read-write + + + RXPOL + RX data polarity inverse control + 16 + 1 + read-write + + + TXPOL + TX data polarity inverse control + 17 + 1 + read-write + + + + + BR + UART Baudrate Control Register + 0x8 + 32 + 0x0 + 0xFFFFFFFF + + + BR + Baud-Rate + 0 + 16 + read-write + + + + + IE + UART Interrupt Enable Register + 0x0C + 32 + 0x0 + 0xFFFFFFFF + + + RXNEE + RX FIFO not empty interrupt enable + 0 + 1 + read-write + + + TXEE + TX FIFO empty interrupt enable + 1 + 1 + read-write + + + TXHEE + TX FIFO half-empty interrupt enable + 2 + 1 + read-write + + + PERRE + Parity error interrupt enable + 3 + 1 + read-write + + + FERRE + Frame error interrupt enable + 4 + 1 + read-write + + + OVERRE + RX overflow interrupt enable + 5 + 1 + read-write + + + TONEE + TX time-out interrupt enable + 6 + 1 + read-write + + + TOIDLEE + TX idle time-out interrupt enable + 7 + 1 + read-write + + + RXHFE + RX FIFO half-full interrupt enable + 8 + 1 + read-write + + + RXFE + RX FIFO full interrupt enable + 9 + 1 + read-write + + + TXENDE + TX end interrupt enable + 10 + 1 + read-write + + + TXFE + TX FIFO full interrupt enable + 11 + 1 + read-write + + + RXPE + RX AUTO parity + 12 + 1 + read-write + + + + + SR + UART Status Register + 0x10 + 32 + 0x0 + 0xFFFFFFFF + + + RXNE + RX FIFO not empty + 0 + 1 + read-only + + + TXE + TX FIFO empty + 1 + 1 + read-only + + + TXHE + TX FIFO half-empty + 2 + 1 + read-only + + + PERR + Parity error flag (W1C) + 3 + 1 + read-write + oneToClear + + + FERR + Frame error flag (W1C) + 4 + 1 + read-write + oneToClear + + + OVERR + RX overflow flag (W1C) + 5 + 1 + read-write + oneToClear + + + TONE + Clean RX FIFO time-out + 6 + 1 + read-only + + + TOIDLE + TX idle time-out + 7 + 1 + read-only + + + RXHF + RX FIFO half-full + 8 + 1 + read-only + + + RXF + RX FIFO full + 9 + 1 + read-only + + + TXEND + TX end + 10 + 1 + read-only + + + TXF + TX FIFO full + 11 + 1 + read-only + + + + + GTR + UART Frame Guard-time Register + 0x14 + 32 + 0x0 + 0xFFFFFFFF + + + GT + Frame Guard-Time + 0 + 8 + read-write + + + + + TOR + UART Time-Out Control Register + 0x18 + 32 + 0x0 + 0xFFFFFFFF + + + TO + Time-Out value + 0 + 8 + read-write + + + + + TXFR + Reset UART TX FIFO with any value + 0x1C + 32 + 0x0 + 0xFFFFFFFF + write-only + + + RXFR + Reset UART RX FIFO with any value + 0x20 + 32 + 0x0 + 0xFFFFFFFF + write-only + + + + + UART0 + 0x40002000 + + UART0 + 25 + + + + I2C + Inter-Integrated Circuit + 0x40003000 + + 0 + 0x200 + registers + + + + CTLSET + Register + 0 + 32 + 0x0 + 0xFFFFFFFF + + + CR0 + CLK SET + 0 + 1 + + + CR1 + CLK SET + 1 + 1 + + + AA + answer control + 2 + 1 + + + SI + interrupt flag + 3 + 1 + + + STO + stop control + 4 + 1 + + + STA + start control + 5 + 1 + + + EN + enable + 6 + 1 + + + CR2 + clk control + 7 + 1 + + + + + STAT + Register + 0X04 + 32 + 0x1F + 0xFFFFFFFF + + + STAT + BUS STATUS + 3 + 5 + + + + + DATA + Register + 0X08 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + SEND OR RECEIVE DATA + 0 + 8 + + + + + ADDR + Register + 0X0C + 32 + 0x0 + 0xFFFFFFFF + + + GC + radio enable + 0 + 1 + + + ADDR + addre + 1 + 7 + + + FILTERDELAY + FILTERDELAY + 16 + 4 + + + FILTERDELAY_EN + FILTERDELAY_EN + 24 + 8 + + + + + CTLCLR + Register + 0X18 + 32 + 0x0 + 0xFFFFFFFF + + + CR0 + CLEAT CR0 + 0 + 1 + + + CR1 + CLEAT CR1 + 1 + 1 + + + AA + CLEAT 11 + 2 + 1 + + + SI + CLEAT SI + 3 + 1 + + + STO + CLEAT STO + 4 + 1 + + + STA + CLEAT STA + 5 + 1 + + + EN + CLEAT EN + 6 + 1 + + + CR2 + CLEAT CR2 + 7 + 1 + + + + + + + I2C0 + 0x40003000 + + I2C0 + 26 + + + + SPI + Serial Peripheral Interface Bus + 0x40003800 + + 0 + 0x200 + registers + + + + + CFG + Register + 0x0 + 32 + 0x00020000 + 0xFFFFFFFF + + + MODE + mode select + 0 + 1 + + + CPOL + clock polarity + 1 + 1 + + + CPHA + clock phase + 2 + 1 + + + DB + baud rate + 3 + 3 + + + TXWDSZ + tx data size + 6 + 2 + + + LSB + transmit control + 8 + 1 + + + SS_OUT + periphare select + 10 + 1 + + + MCS + handler section select + 14 + 1 + + + MSE + handler mode select + 15 + 1 + + + MSTC + handler command start + 16 + 1 + + + MODEF + mode fail enable + 17 + 1 + + + + + STA + Register + 0x04 + 32 + 0x04 + 0xFFFFFFFF + + + RECVOV + RX overbrim flag + 0 + 1 + + + MDF + mode false + 1 + 1 + + + TXNFUL + TX FIFO no full + 2 + 1 + + + TXFUL + TX FIFO full + 3 + 1 + + + RXNEP + RX not empty + 4 + 1 + + + RXFUL + RX full + 5 + 1 + + + TXUFL + TX underflow + 6 + 1 + + + BUSY + module busy + 7 + 1 + + + + + INTEN + Register + 0x08 + 32 + 0x0 + 0xFFFFFFFF + + + INTEN + interrupt enable + 0 + 7 + + + + + INTDIS + Register + 0x0C + 32 + 0x0 + 0xFFFFFFFF + + + INTEN + close interrupt + 0 + 7 + + + + + INTMASK + Register + 0x10 + 32 + 0x0 + 0xFFFFFFFF + + + INTEN + interrupt mask + 0 + 7 + + + + + EN + Register + 0x14 + 32 + 0x0 + 0xFFFFFFFF + + + EN + spi module enable + 0 + 1 + + + + + DELAY + Register + 0x18 + 32 + 0x0 + 0xFFFFFFFF + + + d_int + + 0 + 8 + + + d_affter + + 8 + 8 + + + d_btwn + + 16 + 8 + + + d_nss + + 24 + 8 + + + + + TX + Register + 0x1C + 32 + 0x0 + 0xFFFFFFFF + + + RX + Register + 0x20 + 32 + 0x0 + 0xFFFFFFFF + + + IDLECNT + Register + 0x24 + 32 + 0xff + 0xFFFFFFFF + + + IDLECNT + + 0 + 8 + + + + + TXTH + Register + 0x28 + 32 + 0x0 + 0xFFFFFFFF + + + TXTHOLD + cause no full interrupt + 0 + 32 + + + + + RXTH + Register + 0x2C + 32 + 0x0 + 0xFFFFFFFF + + + RXTHOLD + cause no empty interrupt + 0 + 32 + + + + + + + SPI0 + 0x40003800 + + SPI0 + 24 + + + + WDG + Watchdog + 0x40004000 + + 0 + 0x410 + registers + + + WDG + 23 + + + + + LOAD + WDT LOAD Register + 0x000 + 32 + 0xFFFFFFFF + 0xFFFFFFFF + read-write + + + + VALUE + WDT Counter Register + 0x004 + 32 + 0xFFFFFFFF + 0xFFFFFFFF + read-only + + + + CR + WDT Control Register + 0x008 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + INTE + Enable interrupt + 0 + 1 + read-write + + + IRQ_OFF + WDT disable interrupt + 0 + + + IRQ_ON + WDT enable interrupt + 1 + + + + + RSTE + Enable Reset + 1 + 1 + read-write + + + DBGE + Enable Debug Pending + 2 + 1 + read-write + + + + + + INTCLR + WDT interrupt clear Register + 0x00C + 32 + 0x0 + 0xFFFFFFFF + write-only + + + + RIS + WDT original interrupt flag Register + 0x010 + 32 + 0x0 + 0xFFFFFFFF + read-only + + + RIF + original interrupt flag + 0 + 1 + read-only + + + + + + MIS + WDT MASK interrupt flag Register + 0x014 + 32 + 0x0 + 0xFFFFFFFF + read-only + + + MIF + MASK interrupt flag + 0 + 1 + read-only + + + + + + LOCK + WDT LOCK Register + 0x400 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + LOCK + WDT LOCK Control + 0 + 1 + read-write + + + + + + + ADC + Analog-to-Digital Converter + 0x40004800 + + 0 + 0x200 + registers + + + + + CON0 + AD Control Register + 0 + 32 + 0xC0400000 + 0xFFFFFFFF + + + M + ADC input channel select + 0 + 4 + read-write + + + AIN0 + Input channel + 0 + + + AIN1 + Input channel + 1 + + + AIN2 + Input channel + 2 + + + AIN3 + Input channel + 3 + + + AIN4 + Input channel + 4 + + + AIN5 + Input channel + 5 + + + AIN6 + Input channel + 6 + + + AIN7 + Input channel + 7 + + + AIN8 + Input channel + 8 + + + AIN9 + Input channel + 9 + + + AIN10 + Input channel + 10 + + + AIN11 + Input channel + 11 + + + AIN12 + Input channel + 12 + + + AIN13 + Input channel + 13 + + + AIN14 + Input channel + 14 + + + AIN15 + Input channel + 15 + + + + + EN + ADC module enable + 5 + 1 + read-write + + + START + AD conversion start + 7 + 1 + read-write + + + CLK + ADC clock divider (800KHz ~ 16MHz) + 8 + 3 + read-write + + + Div2 + PCLK/2 + 0 + + + Div4 + PCLK/4 + 1 + + + Div8 + PCLK/8 + 2 + + + Div16 + PCLK/16 + 3 + + + Div32 + PCLK/32 + 4 + + + Div64 + PCLK/64 + 5 + + + Div3_75 + PCLK/3.75 + 6 + + + Div3_5 + PCLK/3.5 + 7 + + + + + TRIG_EN + Enable H/w trigger + 11 + 1 + read-write + + + CONTINUE + Enable continue mode + 12 + 1 + read-write + + + ALIGN + ADC result align moe + 13 + 1 + read-write + + + RIGHT + right align + 0 + + + LEFT + left align + 1 + + + + + ENCONT + 1: Never Stop Conversion in continue mode + 15 + 1 + read-write + + + INT_EN + Enable ADC interrupt + 16 + 4 + read-write + + + DISABLE + Disable interrupt + 0 + + + DONE + Interrupt when conversion done + 1 + + + GT_THR + Result is greater then threshold + 2 + + + LT_THR + Result is littler then threshold + 4 + + + EQ_THR + Result is equal to threshold + 8 + + + + + TZO + zero offset change + 20 + 3 + read-write + + + LSB_MINUS_4 + -4 LSB + 0 + + + LSB_MINUS_3 + -3 LSB + 1 + + + LSB_MINUS_2 + -2 LSB + 2 + + + LSB_MINUS_1 + -1 LSB + 3 + + + LSB + keep LSB value + 4 + + + LSB_PLUS_1 + +1 LSB + 5 + + + LSB_PLUS_2 + +2 LSB + 6 + + + LSB_PLUS_3 + +3 LSB + 7 + + + + + BAKEN + Enable backup the previous conversion value + 29 + 1 + read-write + + + PWD + Power down analog physical module + 30 + 1 + read-write + + + RST + Reset analog physical module + 31 + 1 + read-write + + + + + + STAT + ADC State Registter + 0x4 + 32 + 0x00030040 + 0xFFFFFFFF + + + DONE + ADC done(auto clear after read reg DATx) + 0 + 1 + read-only + + + INT_CLR + ADC clear interrupt flag, 1:clear + 1 + 1 + read-write + + + COMP_RESULT + Result of Comparison(auto clear after read reg DATx) + 4 + 2 + read-only + + + NONE + Auto-clear after read reg DATx + 0 + + + GT_THR + Result is greater then threshold + 1 + + + LT_THR + Result is littler then threshold + 2 + + + EQ_THR + Result is equal to threshold + 3 + + + + + EOC_CHECK_DIS + Disable End-of-Conversion checking + 6 + 1 + read-write + + + TS_SET + Set Ts cycles + 16 + 5 + read-write + + + DLY_SET + Set delay cycles with ADC clock + 21 + 3 + read-write + + + DLY_12 + Deley 12 cycles + 0 + + + DLY_14 + Deley 14 cycles + 1 + + + DLY_18 + Deley 18 cycles + 2 + + + DLY_24 + Deley 24 cycles + 3 + + + DLY_26 + Deley 26 cycles + 4 + + + + + EOC_CNT + Count of End-of-Conversion + 24 + 4 + read-only + + + START_CNT + Count of Start + 28 + 4 + read-only + + + + + + DAT0 + ADC Result0 Register + 0x8 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT1 + ADC Result1 Register + 0xC + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT2 + ADC Result2 Register + 0x10 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT3 + ADC Result3 Register + 0x14 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT4 + ADC Result4 Register + 0x18 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT5 + ADC Result5 Register + 0x1C + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT6 + ADC Result6 Register + 0x20 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT7 + ADC Result7 Register + 0x24 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT8 + ADC Result8 Register + 0x28 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT9 + ADC Result9 Register + 0x2C + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT10 + ADC Result10 Register + 0x30 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT11 + ADC Result11 Register + 0x34 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT12 + ADC Result12 Register + 0x38 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT13 + ADC Result13 Register + 0x3C + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT14 + ADC Result14 Register + 0x40 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + + DAT15 + ADC Result13 Register + 0x44 + 32 + 0x0 + 0xFFFFFFFF + + + DATA + ADC result data + 0 + 16 + read-only + + + CMPTH + Comparison threshold + 16 + 12 + read-write + + + + + CHSEL + ADC channel selection Register + 0x48 + 32 + 0x0 + 0xFFFFFFFF + + + CH_SEL + Channel 0~15 + 0 + 16 + read-write + + + CH_CNT + Selected Channel Count + 16 + 4 + read-write + + + DISC_INTSEL + Select interrupt condition when DISCEN==1 + 21 + 1 + read-write + + + DISCNUM + Discontinuous mode channel count (DISCNUM+1) + 22 + 3 + read-write + + + DISCEN + Discontinuous mode Enable + 25 + 1 + read-write + + + TRIG_SEL16 + Trigger Selection 16 + 26 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + TIM0_OVERFLOW + TIM0 overflow trigger + 1 + + + + + TRIG_SEL17 + Trigger Selection 17 + 28 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + PIN + PB1/PB2 trigger + 1 + + + + + EXTRIG_SEL + External Trigger Selection + 30 + 2 + read-write + + + PB1_RISING + PB1 rising trigger + 0 + + + PB1_FALLING + PB1 falling trigger + 1 + + + PB2_RISING + PB2 rising trigger + 2 + + + PB2_FALLING + PB2 falling trigger + 3 + + + + + + + TRGSEL + ADC Trigger selection Register + 0x4C + 32 + 0x0 + 0xFFFFFFFF + + + TRIG_SEL0 + Trigger Selection 0 + 0 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH1_RISING + EPWM0P(CH1) Rising + 1 + + + + + TRIG_SEL1 + Trigger Selection 1 + 2 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH2_RISING + EPWM0P(CH2) Rising + 1 + + + + + TRIG_SEL2 + Trigger Selection 2 + 4 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH3_RISING + EPWM0P(CH3) Rising + 1 + + + + + TRIG_SEL3 + Trigger Selection 3 + 6 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH1_FALLING + EPWM0P(CH1) Falling + 1 + + + + + TRIG_SEL4 + Trig Selection 4 + 8 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH2_FALLING + EPWM0P(CH2) Falling + 1 + + + + + TRIG_SEL5 + Trigger Selection 5 + 10 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CH3_FALLING + EPWM0P(CH3) Falling + 1 + + + + + TRIG_SEL6 + Trigger Selection 6 + 12 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + COMP0_RISING + COMP0 Rising + 1 + + + + + TRIG_SEL7 + Trigger Selection 7 + 14 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + COMP0_FALLING + COMP0 Falling + 1 + + + + + TRIG_SEL8 + Trigger Selection 8 + 16 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + COMP1_RISING + COMP1 Rising + 1 + + + + + TRIG_SEL9 + Trigger Selection 9 + 18 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + COMP1_FALLING + COMP1 Falling + 1 + + + + + TRIG_SEL10 + Trig Selection 10 + 20 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_UDF + EPWM Counter Underflow + 1 + + + + + TRIG_SEL11 + Trigger Selection 11 + 22 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_OVF + EPWM Counter Overflow + 1 + + + + + TRIG_SEL12 + Trigger Selection 12 + 24 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CCR4_UP + EPWM CCR4 up-count + 1 + + + + + TRIG_SEL13 + Trigger Selection 13 + 26 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CCDR4_UP + EPWM CCDR4 up-count + 1 + + + + + TRIG_SEL14 + Trigger Selection 14 + 28 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CCR4_DN + EPWM CCR4 down-count + 1 + + + + + TRIG_SEL15 + Trig Selection 15 + 30 + 2 + read-write + + + DISABLE + Disable selection + 0 + + + EPWM_CCDR4_DN + EPWM CCDR4 down-count + 1 + + + + + + + BKSEL + Brake Source (from ADC) Control Register + 0x50 + 32 + 0x0 + 0xFFFFFFFF + + + BK1_CH + Select a channel as brake source 1 + 0 + 4 + read-write + + + BK1_FLT + Filter the brake source 1 + 4 + 2 + read-write + + + OFF + Disable filter the brake from ADC source 1 + 0 + + + MATCH_2 + Brake if result matches 2-times + 1 + + + MATCH_4 + Brake if result matches 4-times + 2 + + + MATCH_7 + Brake if result matches 7-times + 3 + + + + + BK1_EN + Enable ondition of brake + 6 + 2 + read-write + + + OFF + Disable brake from ADC source 1 + 0 + + + GT_THR + Result is greater then threshold + 1 + + + LT_THR + Result is littler then threshold + 2 + + + EQ_THR + Result is equal to threshold + 3 + + + + + BK2_CH + Select a channel as brake source 2 + 8 + 4 + read-write + + + BK2_FLT + Filter the brake source 2 + 12 + 2 + read-write + + + OFF + Disable filter the brake from ADC source 2 + 0 + + + MATCH_2 + Brake if result matches 2-times + 1 + + + MATCH_4 + Brake if result matches 4-times + 2 + + + MATCH_7 + Brake if result matches 7-times + 3 + + + + + BK2_EN + Enable ondition of brake + 14 + 2 + read-write + + + OFF + Disable brake from ADC source 1 + 0 + + + GT_THR + Result is greater then threshold + 1 + + + LT_THR + Result is littler then threshold + 2 + + + EQ_THR + Result is equal to threshold + 3 + + + + + + + BAKDAT + Data Register of ADC Conversion backup value + 0x54 + 32 + 0x0 + 0xFFFFFFFF + + + BAKDAT + backup Data + 0 + 16 + read-only + + + + + + + ADC0 + 0x40004800 + + ADC0 + 31 + + + + AMISC + Analog MISC controller + 0x40005800 + + 0 + 0x34 + registers + + + LVD + 33 + + + + LVD_LVR_CR + LVD/LVR Control Register + 0x00 + 32 + 0 + 0xFFFFFFFF + read-write + + + LVD_EN + LVD enable + 0 + 1 + read-write + + + LDO_LP_EN + LDO lower power enable + 1 + 1 + read-write + + + LVD_F_SEL + LVD Filter Selection + 2 + 2 + read-write + + + LVD_SEL + LVD selection + 5 + 3 + read-write + + + 2V + 2.0V + 0x0 + + + 2_2V + 2.2V + 0x1 + + + 2_4V + 2.4V + 0x2 + + + 2_7V + 2.7V + 0x3 + + + 3V + 3.0V + 0x4 + + + 3_7V + 3.7V + 0x5 + + + 4V + 4.0V + 0x6 + + + 4_3V + 4.3V + 0x7 + + + + + LVR_EN + LVR enable + 8 + 1 + read-write + + + LVD_INT_EN + LVD interrupt enable + 9 + 1 + read-write + + + TEMP_EN + Temperature enable + 10 + 1 + read-write + + + LVD_STATE + LVD state, 0: VDD < LVD_SEL, 1: VDD > LVD_SEL + 11 + 1 + read-only + + + LVR_SEL + LVR selection + 13 + 3 + read-write + + + 2V + 2.0V + 0x0 + + + 2_4V + 2.4V + 0x1 + + + 2_7V + 2.7V + 0x2 + + + 3V + 3V + 0x3 + + + 3_7V + 3.7V + 0x4 + + + + + + + VBUF_CR + Vbuf Control Register + 0x04 + 32 + 0 + 0xFFFFFFFF + read-write + + + VBUF_EN + VBUF enable + 0 + 1 + read-write + + + ANA2IO_EN + Test analog signal to I/O + 4 + 1 + read-write + + + ANA2PGA_EN + Test analog signal to PGA0 + 5 + 1 + read-write + + + ANA_SEL + Test analog signal selection + 6 + 7 + read-write + + + NONE + None + 0x0 + + + TEMP + temp out + 0x1 + + + DAC0 + DAC 0 + 0x2 + + + DAC1 + DAC 1 + 0x4 + + + VBuf_1p5v + vbuf 1p5v out + 0x8 + + + VDDL + vddl + 0x10 + + + VSS + vss + 0x20 + + + VDD + vdd + 0x40 + + + + + + + DAC_CR + DAC Control Register + 0x10 + 32 + 0 + 0xFFFFFFFF + read-write + + + DAC0Step + The step of voltage + 0 + 10 + read-write + + + DAC1Step + The step of voltage + 10 + 10 + read-write + + + DAC0_EN + DAC0 enable + 20 + 1 + read-write + + + DAC1_EN + DAC1 enable + 21 + 1 + read-write + + + + + HSI_CR + HSI (OSCHF) Control Register + 0x20 + 32 + 0 + 0xFFFFFFFF + read-write + + + LDO_SEL + HSI power source selection + 0 + 16 + read-write + + + LDO + ldo_oschf Disable abd vddl_oschf from ldo + 0x8080 + + + Normal + do_oschf Enable and vddl_oschf from ldo_oschf + 0x0101 + + + + + HSI_EN + HSI enable, set 0x80(disable), set 0x1(enable) + 24 + 8 + read-write + + + + + LSI_CR + LSI (OSCLF) Control Register + 0x24 + 32 + 0 + 0xFFFFFFFF + read-write + + + LSI_EN + LSI enable, set 0x80(disable), set 0x1(enable) + 24 + 8 + read-write + + + + + ADC_AIN_CR + ADC AIN Control Register + 0x30 + 32 + 0 + 0xFFFFFFFF + read-write + + + ANA2ADC_EN + Enable ADC AIN15 from internal source + 0 + 1 + read-write + + + + + + + HWTRIM + H/w configure trim values + 0x40005860 + + 0 + 0x20 + registers + + + + + LDO_TRIM + LDO trim value + 0x00 + 32 + 0x0 + 0xFFFFFFFF + read-only + + + LDO_TRIM + LDO trim value + 0 + 5 + read-only + + + LDO_LP_TRIM + LDO lower power trim value + 5 + 5 + read-only + + + LDO_TUNE + Ldo high temp leakage current compensation + 10 + 2 + read-only + + + STRENGTH + strength + 0x0 + + + WEAK + weak + 0x1 + + + MIDDLEddle + middle + 0x2 + + + OFF + off + 0x3 + + + + + + + + VBUF_TRIM + Vbuf trim value + 0x04 + 32 + 0 + 0xFFFFFFFF + read-only + + + VBUF_TRIM + VBUF voltage trim value + 0 + 7 + read-only + + + + + HSI_TRIM + High Speed Internal clock (OSCHF) trim value + 0x08 + 32 + 0 + 0xFFFFFFFF + read-only + + + HSI_D_CFG + HSI low trim config + 0 + 9 + read-only + + + HSI_FSEL_CFG + HSI high trim config + 9 + 7 + read-only + + + HSI_TC + The TC of HSI trim value + 16 + 2 + read-only + + + + + + LSI_TRIM + Low Speed Internal clock (OSCLF) trim value + 0x0C + 32 + 0 + 0xFFFFFFFF + read-only + + + LSI_TRIM + The LSI trim value, 0xB3= 32KHz + 0 + 8 + read-only + + + + + MISC_CFG + The miscellaneous configuration + 0x10 + 32 + 0 + 0xFFFFFFFF + read-only + + + EXT_nRST_EN + External reset pin enable + 0 + 1 + read-only + + + + + + + + + CRC + Cyclic redundancy check + 0x4001E000 + + 0 + 0x200 + registers + + + + CR + Control Register + 0x00 + 32 + 0 + 0xFFFFFFFF + + + POLYSEL + CRC polynomial codes select + 0 + 1 + read-write + + + CRC16 + x16 + x12 + x5 + 1 + 1 + + + CRC32 + x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 + 0 + + + + + VERF + flag of verificaion CRC value + 1 + 1 + read-only + + + + + DIN + CRC Data input Register + 0x04 + 32 + 0 + 0xFFFFFFFF + + + DIN + Input Data + 0 + 32 + read-write + + + + + DOUT + Result output register + 0x08 + 32 + 0x0 + 0xFFFFFFFF + + + DOUT + CRC value + 0 + 32 + read-write + + + + + + + DSP + DSP hardware speedup + 0x40008000 + + 0 + 0x400 + registers + + + + + CR + DSP ACCEL Control Register + 0x00 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + MODE + Mode selection + 0 + 3 + read-write + + + DIV + 32-bits Divide Mode + 1 + + + SQRT + square root mode + 4 + + + + + + + SR + DSP ACCEL Status Register + 0x04 + 32 + 0x0 + 0xFFFFFFFF + read-only + + + DONE + DSP End + 0 + 1 + read-only + + + + + SDAT1 + DSP ACCEL Source Data1 + 0x08 + 32 + 0x00000000 + 0xFFFFFFFF + read-write + + + SDAT2 + DSP ACCEL Source Data2 + 0x10 + 32 + 0x00000000 + 0xFFFFFFFF + read-write + + + RSLT1 + DSP ACCEL Result 1 + 0x018 + 32 + 0x00000000 + 0xFFFFFFFF + read-only + + + RSLT2 + DSP ACCEL Result 2 + 0x20 + 32 + 0x00000000 + 0xFFFFFFFF + read-only + + + + + OPAMP + OP-Amplifiers with PGA mode + 0x40005880 + + 0 + 0x8 + registers + + + + PGA_CR + Control Register + 0x00 + 32 + 0 + 0xFFFFFFFF + read-write + + + PGA_EN + Enable PGA + 0 + 1 + read-write + + + PGA_IO_EN + Enable PGA output to I/O + 1 + 1 + read-write + + + PGA_GAIN + PGA gain selection + 2 + 6 + read-write + + + x1 + Multiple of gain + 0x1 + + + x2 + Multiple of gain + 0x6 + + + x3 + Multiple of gain + 0xA + + + x4 + Multiple of gain + 0xE + + + x5 + Multiple of gain + 0x12 + + + x6 + Multiple of gain + 0x16 + + + x7 + Multiple of gain + 0x1A + + + x8 + Multiple of gain + 0x1E + + + x9 + Multiple of gain + 0x22 + + + x10 + Multiple of gain + 0x26 + + + x11 + Multiple of gain + 0x2A + + + x12 + Multiple of gain + 0x2E + + + x13 + Multiple of gain + 0x32 + + + x14 + Multiple of gain + 0x36 + + + x15 + Multiple of gain + 0x3A + + + x16 + Multiple of gain + 0x3E + + + + + PGA_VIN_SEL + PGA N terminal selection + 10 + 1 + read-write + + + PGA_VIP_SEL + PGA P terminal selection + 11 + 1 + read-write + + + + + + + OPAMP0 + 0x40005880 + + + OPAMP1 + 0x40005888 + + + COMP + Analog Comparator + 0x40008800 + + 0 + 0x800 + registers + + + + CTRL + COMP Control Register + 0x00 + 32 + 0 + 0xFFFFFFFF + read-write + + + EN + COMP Enable + 0 + 1 + read-write + + + COUT + COMP Output + 1 + 1 + read-only + + + VIN_SEL + Comp n terminal input selection + 2 + 2 + read-write + + + IO + selction IO Pin + 1 + + + DAC + selction DAC + 2 + + + + + FIL_CTRL + Filter selction + 4 + 4 + read-write + + + BYPASS + No filter + 0x0 + + + SAMPLE_2 + sample 2 times + 0x1 + + + SAMPLE_4 + sample 4 times + 0x2 + + + SAMPLE_8 + sample 8 times + 0x3 + + + SAMPLE_16 + sample 16 times + 0x4 + + + SAMPLE_32 + sample 32 times + 0x5 + + + SAMPLE_64 + sample 64 times + 0x6 + + + SAMPLE_128 + sample 128 times + 0x7 + + + SAMPLE_256 + sample 256 times + 0x8 + + + + + HYS_EN + hysteresis enable + 8 + 1 + read-write + + + OUT_EN + Comp output signal + 11 + 1 + read-write + + + NONE + No signal output + 0 + + + IO + select IO output + 1 + + + + + POL_SEL + Select output polarity + 12 + 1 + read-write + + + NORMAL + Normal polarity output + 0 + + + INVERT + Inverted + 1 + + + + + + + VIPSEL + COMP P terminal DAC Register + 0x04 + 32 + 0 + 0xFFFFFFFF + read-write + + + VIP_SEL + Comp p terminal input selection + 0 + 5 + read-write + + + IO3 + I/O PA15 + 0x10 + + + IO2 + I/O PA14 + 0x08 + + + IO1 + I/O PA11 + 0x04 + + + IO0 + I/O PA8 + 0x02 + + + PGA + Select PGA + 0x01 + + + + + + + IR + COMP Interrupt Register + 0x08 + 32 + 0 + 0xFFFFFFFF + read-write + + + FIE + Enable Comp Interrupt with Falling + 0 + 1 + read-write + + + RIE + Enable Comp Interrupt with Rising + 1 + 1 + read-write + + + + + IF + COMP Interrupt Flag Register + 0x0C + 32 + 0 + 0xFFFFFFFF + read-write + + + FIF + Interrupt Falling Flag, W1C + 0 + 1 + read-write + + + RIF + Interrupt Rising Flag, W1C + 1 + 1 + read-write + + + + + INITCNT + COMP set initial delay register + 0x10 + 32 + 0X0000003C + 0xFFFFFFFF + read-write + + + INIT_DELAY + Comp Set Delay + 0 + 10 + read-write + + + + + + + COMP0 + 0x40008800 + + COMP0 + 29 + + + + COMP1 + 0x40009800 + + COMP1 + 30 + + + + TIM + Timer Controller Module + 0x4000C000 + + 0 + 0x400 + registers + + + + CR1 + Control Register 1 + 0 + 32 + 0x0 + 0xFFFFFFFF + + + CEN + Counter enable + 0 + 1 + + + UDIS + Update disable + 1 + 1 + + + URS + Update request source + 2 + 1 + + + OPM + One pulse spurce + 3 + 1 + + + DIR + Direction + 4 + 1 + + + CMS + Center-aligned mode selection + 5 + 2 + + + EDGE + edge mode + 0 + + + CENTER1 + center mode 1: count-up will trigger interrupt + 1 + + + CENTER2 + center mode 2: count-down will trigger interrupt + 2 + + + CENTER3 + center mode 3: count-up and count-down will trigger interrupt + 3 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + + CKD + Clock division + 8 + 2 + + + 0 + Tdts = tck_in + 0 + + + 1 + Tdts = tck_in*2 + 1 + + + 2 + Tdts = tck_in*4 + 2 + + + 3 + reserve + 3 + + + + + ASYMEN + Asymmetric mode enable + 10 + 1 + + + + + CR2 + Control Register 2 + 0x04 + 32 + 0x0 + 0xFFFFFFFF + + + CCPC + Capture/compare preloaded control + 0 + 1 + + + CCUS + Capture/compare control update selection + 2 + 1 + + + MMS + Master mode selection + 4 + 3 + + + RESET + UG Trigger TRGO + 0 + + + ENABLE + CEN Trigger TRGO + 1 + + + UPDATE + UPDATE Trigger TRGO + 2 + + + COMPARE + COMPARE/CAPTURE Trigger TRGO + 3 + + + OC1REF + OC1REF Trigger TRGO + 4 + + + OC2REF + OC2REF Trigger TRGO + 5 + + + OC3REF + OC3REF Trigger TRGO + 6 + + + OC4REF + OC4REF Trigger TRGO + 7 + + + + + TI1S + TI1 selection + 7 + 1 + + + OIS1 + Output Idle state 1 + 8 + 1 + + + OIS1N + Output Idle state 1 + 9 + 1 + + + OIS2 + Output Idle state 2 + 10 + 1 + + + OIS2N + Output Idle state 2 + 11 + 1 + + + OIS3 + Output Idle state 3 + 12 + 1 + + + OIS3N + Output Idle state 3 + 13 + 1 + + + OIS4 + Output Idle state 4 + 14 + 1 + + + + + SMCR + Slave Mode control Register + 0X08 + 32 + 0x0 + 0xFFFFFFFF + + + SMS + Slave mode selection + 0 + 3 + + + DISABLE + close Slave mode + 0 + + + Encode1 + Encode mode 1: + 1 + + + Encode2 + Encode mode 2 + 2 + + + Encode3 + Encode mode 3 + 3 + + + RESET + Reset mode + 4 + + + WINDOW + Window mode + 5 + + + TRIGGER + trigger mode + 6 + + + EXTCLK + External clock mode 1 + 7 + + + + + TS + Trigger selection + 4 + 3 + + + ITR0 + ITR0 + 0 + + + ITR1 + ITR1: + 1 + + + ITR2 + ITR2 + 2 + + + ITR3 + ITR3 + 3 + + + TI1F_ED + TI1F_ED + 4 + + + T1FP1 + T1FP1 + 5 + + + T1FP2 + T1FP2 + 6 + + + ETRF + ETRF + 7 + + + + + MSM + Master/slave mode + 7 + 1 + + + ETF + External trigger filter + 8 + 4 + + + 0 + No filter + 0 + + + 1 + fsampling = fclk_int,N=2 + 1 + + + 2 + fsampling = fclk_int,N=4 + 2 + + + 3 + fsampling = fclk_int,N=8 + 3 + + + 4 + fsampling = Fdts/2,N=6 + 4 + + + 5 + fsampling = Fdts/2,N=8 + 5 + + + 6 + fsampling = Fdts/4,N=6 + 6 + + + 7 + fsampling = Fdts/4,N=8 + 7 + + + 8 + fsampling = Fdts/8,N=6 + 8 + + + 9 + fsampling = Fdts/8,N=8 + 9 + + + 10 + fsampling = Fdts/16,N=5 + 10 + + + 11 + fsampling = Fdts/16,N=6 + 11 + + + 12 + fsampling = Fdts/16,N=8 + 12 + + + 13 + fsampling = Fdts/32,N=5 + 13 + + + 14 + fsampling = Fdts/32,N=6 + 14 + + + 15 + fsampling = Fdts/32,N=8 + 15 + + + + + ETPS + External trigger prescaler + 12 + 2 + + + ECE + External clock enable + 14 + 1 + + + ETP + External trigger polarity + 15 + 1 + + + + + DIER + interrupt enbale register + 0X0C + 32 + 0x0 + 0xFFFFFFFF + + + UIE + Update interrupt enable + 0 + 1 + + + CC1IE + Capture/Compare 1 interrupt enable + 1 + 1 + + + CC2IE + Capture/Compare 2 interrupt enable + 2 + 1 + + + CC3IE + Capture/Compare 3 interrupt enable + 3 + 1 + + + CC4IE + Capture/Compare 4 interrupt enable + 4 + 1 + + + COMIE + COM interrupt enable + 5 + 1 + + + TIE + Trigger interrupt enable + 6 + 1 + + + BIE + Break interrupt enable + 7 + 1 + + + CCD1IE + Capture/Compare 1 interrupt enable + 8 + 1 + + + CCD2IE + Capture/Compare 2 interrupt enable + 9 + 1 + + + CCD3IE + Capture/Compare 3 interrupt enable + 10 + 1 + + + OVIE + Overflow interrupt enable + 11 + 1 + + + UDIE + Underflow interrupt enable + 12 + 1 + + + CCD4IE + Capture/Compare 4 interrupt enable + 13 + 1 + + + + + SR + state Register + 0X10 + 32 + 0x0 + 0xFFFFFFFF + + + UIF + Update interrupt flag + 0 + 1 + + + CC1IF + Capture/Compare 1 interrupt flag + 1 + 1 + + + CC2IF + Capture/Compare 2 interrupt flag + 2 + 1 + + + CC3IF + Capture/Compare 3 interrupt flag + 3 + 1 + + + CC4IF + Capture/Compare 4 interrupt flag + 4 + 1 + + + COMIF + COM interrupt flag + 5 + 1 + + + TIF + Trigger interrupt flag + 6 + 1 + + + BIF + Break interrupt flag + 7 + 1 + + + CC1OF + CC1OF + 9 + 1 + read-write + + + CC2OF + CC2OF + 10 + 1 + read-write + + + CC3OF + CC3OF + 11 + 1 + read-write + + + CC4OF + CC4OF + 12 + 1 + read-write + + + CCD1IF + Capture/Compare 1 interrupt flag + 13 + 1 + + + CCD2IF + Capture/Compare 2 interrupt flag + 14 + 1 + + + CCD3IF + Capture/Compare 3 interrupt flag + 15 + 1 + + + OVIF + Overflow interrupt flag + 16 + 1 + + + UDIF + Underflow interrupt flag + 17 + 1 + + + CCD4IF + Break interrupt flag + 18 + 1 + + + + + EGR + event generation Register + 0X14 + 32 + 0x0 + 0xFFFFFFFF + + + UG + Update generation + 0 + 1 + + + CC1G + Capture/Compare 1 generation + 1 + 1 + + + CC2G + Capture/Compare 2 generation + 2 + 1 + + + CC3G + Capture/Compare 3 generation + 3 + 1 + + + CC4G + Capture/Compare 4 generation + 4 + 1 + + + COMG + Capture/Compare control update generation + 5 + 1 + + + TG + Trigger generation + 6 + 1 + + + BG + Break generation + 7 + 1 + + + + + CCMR1_OUTPUT + Capture or Compare mode Register (Output mode) + 0X18 + 32 + 0x0 + 0xFFFFFFFF + + + CC1S + Capture/Compare 1 selection + 0 + 2 + + + OC1FE + Output Compare 1 fast enable + 2 + 1 + + + OC1PE + Output Compare 1 preload enable + 3 + 1 + + + OC1M + Output Compare 1 mode + 4 + 3 + + + OC1CE + Output Compare 1 clear enable + 7 + 1 + + + CC2S + Capture/Compare 2 selection + 8 + 2 + + + OC2FE + Output Compare 2 fast enable + 10 + 1 + + + OC2PE + Output Compare 2 preload enable + 11 + 1 + + + OC2M + Output Compare 2 mode + 12 + 3 + + + OC2CE + Output Compare 2 clear enable + 15 + 1 + + + + + CCMR1_INPUT + Capture or Compare mode Register (Input mode) + CCMR1_OUTPUT + 0X18 + 32 + 0x0 + 0xFFFFFFFF + + + CC1S + Capture or Compare 1 Select + 0 + 2 + read-write + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + read-write + + + IC1F + Input capture 1 filter + 4 + 4 + read-write + + + CC2S + Capture or Compare 2 Select + 8 + 2 + read-write + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + read-write + + + IC2F + Input capture 2 filter + 12 + 4 + read-write + + + + + CCMR2_OUTPUT + Capture or Compare mode Register (output mode) + 0X1C + 32 + 0x0 + 0xFFFFFFFF + + + CC3S + Capture/Compare 3 selection + 0 + 2 + + + OC3FE + Output Compare 3 fast enable + 2 + 1 + + + OC3PE + Output Compare 3 preload enable + 3 + 1 + + + OC3M + Output Compare 3 mode + 4 + 3 + + + OC3CE + Output Compare 3 clear enable + 7 + 1 + + + CC4S + Capture/Compare 4 selection + 8 + 2 + + + OC4FE + Output Compare 4 fast enable + 10 + 1 + + + OC4PE + Output Compare 4 preload enable + 11 + 1 + + + OC4M + Output Compare 4 mode + 12 + 3 + + + OC4CE + Output Compare 4 clear enable + 15 + 1 + + + + + CCMR2_INPUT + Capture or Compare mode Register (input mode) + CCMR2_OUTPUT + 0X1C + 32 + 0x0 + 0xFFFFFFFF + + + CC3S + Capture or Compare 3 Select + 0 + 2 + read-write + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + read-write + + + IC3F + Input capture 3 filter + 4 + 4 + read-write + + + CC4S + Capture or Compare 4 Select + 8 + 2 + read-write + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + read-write + + + IC4F + Input capture 4 filter + 12 + 4 + read-write + + + + + CCER + Capture or Compare enable Register + 0X20 + 32 + 0x0 + 0xFFFFFFFF + + + CC1E + Capture/Compare 1 output enable + 0 + 1 + + + CC1P + Capture/Compare 1 output polarity + 1 + 1 + + + CC1NE + Capture/Compare 1 complementary output enable + 2 + 1 + + + CC1NP + Capture/Compare 1 complementary output polarity + 3 + 1 + + + CC2E + Capture/Compare 2 output enable + 4 + 1 + + + CC2P + Capture/Compare 2 output polarity + 5 + 1 + + + CC2NE + Capture/Compare 2 complementary output enable + 6 + 1 + + + CC2NP + Capture/Compare 2 complementary output polarity + 7 + 1 + + + CC3E + Capture/Compare 3 output enable + 8 + 1 + + + CC3P + Capture/Compare 3 output polarity + 9 + 1 + + + CC3NE + Capture/Compare 3 complementary output enable + 10 + 1 + + + CC3NP + Capture/Compare 3 complementary output polarity + 11 + 1 + + + CC4E + Capture/Compare 4 output enable + 12 + 1 + + + CC4P + Capture/Compare 4 output polarity + 13 + 1 + + + + + CNT + EPWM counter register + 0X24 + 32 + 0x0 + 0xFFFFFFFF + + + CNT + Counter value + 0 + 16 + + + + + PSC + Prescaler counter register + 0X28 + 32 + 0x0 + 0xFFFFFFFF + + + PSC + Prescaler value + 0 + 16 + + + + + ARR + Auto reload counter register + 0X2C + 32 + 0x0 + 0xFFFFFFFF + + + ARR + Auto reload value + 0 + 16 + + + + + RCR + Repetition counter register + 0X30 + 32 + 0x0 + 0xFFFFFFFF + + + REP + Repetition counter value + 0 + 8 + + + + + CCR1 + CR1 capture or compare value + 0X34 + 32 + 0x0 + 0xFFFFFFFF + + + CCR1 + Capture/Compare 1 value + 0 + 20 + + + + + CCR2 + CR2 capture or compare value + 0X38 + 32 + 0x0 + 0xFFFFFFFF + + + CCR2 + Capture/Compare 2 value + 0 + 20 + + + + + CCR3 + capture or compare value + 0X3C + 32 + 0x0 + 0xFFFFFFFF + + + CCR3 + Capture/Compare 3 value + 0 + 20 + + + + + CCR4 + match output control + 0X40 + 32 + 0x0 + 0xFFFFFFFF + + + CCR4 + Capture/Compare 4 value + 0 + 20 + + + + + BDTR + Braking ande dead zone control Register + 0X44 + 32 + 0x0 + 0xFFFFFFFF + + + DTG + Dead-time generator setup + 0 + 8 + + + LOCK + Lock Configuration + 8 + 2 + + + OSSI + Off-state selection for Idle mode + 10 + 1 + + + OSSR + Off-state selection for Run mode + 11 + 1 + + + BKE + Break enable + 12 + 1 + + + BKP + Break polarity + 13 + 1 + + + AOE + Automatic output enable + 14 + 1 + + + MOE + Main output enable + 15 + 1 + + + DTGF + Asymmetric Dead-time generator setup + 16 + 8 + + + DTAE + Asymmetric Dead-time enable + 24 + 1 + + + + + CCDR1 + CR1 down capture or compare value + 0X50 + 32 + 0x0 + 0xFFFFFFFF + + + CCDR1 + Down Capture/Compare 1 value + 0 + 20 + + + + + CCDR2 + CR2 down capture or compare value + 0X54 + 32 + 0x0 + 0xFFFFFFFF + + + CCDR2 + Down Capture/Compare 2 value + 0 + 20 + + + + + CCDR3 + CR3 down capture or compare value + 0X58 + 32 + 0x0 + 0xFFFFFFFF + + + CCDR3 + Down Capture/Compare 3 value + 0 + 20 + + + + + CCDR4 + CR4 down capture or compare value + 0X5C + 32 + 0x0 + 0xFFFFFFFF + + + CCDR4 + Down Capture/Compare 4 value + 0 + 20 + + + + + + + EPWM + 0x4000C000 + + EPWM + 32 + + + + TIM2 + 0x40001000 + + TIM2 + 21 + + + + LPTIM + Low-Power Timer + 0x4000C800 + + 0 + 0x400 + registers + + + LPTIM + 22 + + + + + IR + LPTIM Interrupt Flag Register + 0x000 + 32 + 0x00 + 0xFFFFFFFF + read-write + + + MR0 + MR0 match flag, writer 1 to clear + 0 + 1 + read-write + + + + + + TCR + LPTIM Control Register + 0x004 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + CEN + LPTIM Module Enable + 0 + 1 + read-write + + + CRST + LPTIM Module Reset + 1 + 1 + read-write + + + CLKS + LPTIM Clock Selection + 2 + 2 + read-write + + + SysClk + System Clock + 0 + + + LSI + LIRC 32KHz + 1 + + + + + TRIGSEL + Trigger LPTIM selector + 4 + 3 + read-write + + + Normal + Normal trigger + 0 + + + EPWMCh0P + EPWM CH0 (ouput) rising trigger + 1 + + + EPWMCh1P + EPWM CH1 (ouput) rising trigger + 2 + + + EPWMCh2P + EPWM CH2 (ouput) rising trigger + 3 + + + EPWMCh0N + EPWM CH0 (ouput) falling trigger + 4 + + + EPWMCh1N + EPWM CH1 (ouput) falling trigger + 5 + + + EPWMCh2N + EPWM CH2 (ouput) falling trigger + 6 + + + + + + + + TC + LPTIM Current Counter value Register + 0x008 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + TC + Current Counter value + 0 + 16 + read-write + + + + + + PR + LPTIM Prescaler Register + 0x00C + 32 + 0x0 + 0xFFFFFFFF + read-write + + + PR + Prescaler value, fTIM=fsys/(PR+1) + 0 + 8 + read-write + + + + + + PC + Prescaler current value Register + 0x010 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + PC + Prescaler current value + 0 + 8 + read-write + + + + + + MCR + LPTIM match control Register + 0x014 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + MR0INT + Enable interrupt when match counter + 0 + 1 + read-write + + + MR0RST + Enable reset when match counter + 1 + 1 + read-write + + + MR0STOP + Enable stop when match counter + 2 + 1 + read-write + + + + + + MR0 + Match Register 0 + 0x018 + 32 + 0x0 + 0xFFFFFFFF + read-write + + + MR0 + Match compare value + 0 + 16 + read-write + + + + + + + TIM0 + 0x40000000 + + TIM0 + 19 + + + + TIM1 + 0x40000800 + + TIM1 + 20 + + + + diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/device.h b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/device.h new file mode 100644 index 0000000..00c400b --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/device.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file device.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __device_H_wqIH3HdS_l3C8_Hgh6_syur_ubmEVDiPX8aR__ +#define __device_H_wqIH3HdS_l3C8_Hgh6_syur_ubmEVDiPX8aR__ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_USE_PEC930) + #include "pec930.h" +#else + #error "Please select first the target device !" +#endif + +//============================================================================= +// Constant Definition +//============================================================================= +typedef void (*isr_t)(void); + +typedef void (*cb_trap_t)(void); +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/pec930.h b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/pec930.h new file mode 100644 index 0000000..857d08c --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/pec930.h @@ -0,0 +1,6072 @@ +/* + * Copyright (c) 2024-2025 Paduak-Tech. All rights reserved. + * + * 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. + * + * @file PEC930.h + * @brief CMSIS HeaderFile + * @version 1.0 + * @date 11. December 2025 + * @note Generated by SVDConv V3.3.38 on Thursday, 11.12.2025 14:57:34 + * from File './PEC930.svd', + * last modified on Thursday, 11.12.2025 06:57:28 + */ + + + +/** @addtogroup Padauk-tech + * @{ + */ + + +/** @addtogroup PEC930 + * @{ + */ + + +#ifndef PEC930_H +#define PEC930_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup Configuration_of_CMSIS + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ Interrupt Number Definition ================ */ +/* =========================================================================================================================== */ + +typedef enum { +/* =========================================== PEC930 Specific Interrupt Numbers =========================================== */ + SysSW_IRQn = 3, /*!< 3 System Software interrupt */ + SysTimer_IRQn = 7, /*!< 7 System Timer interrupt */ + BusError_IRQn = 17, /*!< 17 Bus error interrupt */ + PerfMon_IRQn = 18, /*!< 18 Performance Monitor */ + TIM0_IRQn = 19, /*!< 19 TIM0 */ + TIM1_IRQn = 20, /*!< 20 TIM1 */ + TIM2_IRQn = 21, /*!< 21 TIM2 */ + LPTIM_IRQn = 22, /*!< 22 LPTIM */ + WDG_IRQn = 23, /*!< 23 WDG */ + SPI0_IRQn = 24, /*!< 24 SPI0 */ + UART0_IRQn = 25, /*!< 25 UART0 */ + I2C0_IRQn = 26, /*!< 26 I2C0 */ + GPIOA_IRQn = 27, /*!< 27 GPIOA */ + GPIOB_IRQn = 28, /*!< 28 GPIOB */ + COMP0_IRQn = 29, /*!< 29 COMP0 */ + COMP1_IRQn = 30, /*!< 30 COMP1 */ + ADC0_IRQn = 31, /*!< 31 ADC0 */ + EPWM_IRQn = 32, /*!< 32 EPWM */ + LVD_IRQn = 33 /*!< 33 LVD */ +} IRQn_Type; + + + +/* =========================================================================================================================== */ +/* ================ Processor and Core Peripheral Section ================ */ +/* =========================================================================================================================== */ + +/* =========================== Configuration of the Nuclei N/NX Processor and Core Peripherals =========================== */ +/* set the defines according your Device */ +/* define the correct core revision */ +#define __NUCLEI_N_REV 0x0100 /*!< Core Revision r1p0 */ +#define __NUCLEI_CPU_REV 0x020C00 /*!< Nuclei CPU Core Revision, version X.Y.Z, this is for the CPU Core Version, you get from Nuclei, eg. N300 v3.10.1, it should be 0x030A01 */ +#define __NUCLEI_CPU_SERIES 0x0200 /*!< Nuclei CPU Series, such as 200/300/600/900, eg. 900 will be 0x0900 */ + +#define BOOT_HARTID 0 +#define ECLIC_EXTERNAL_IRQ_OFFSET 19 + +/*!< Set to 0, 1, or 2, 0 not present, 1 single floating point unit present, 2 double floating point unit present */ +#if !defined(__riscv_flen) + #define __FPU_PRESENT 0 +#elif __riscv_flen == 32 + #define __FPU_PRESENT 1 +#else + #define __FPU_PRESENT 2 +#endif + +#if defined(__riscv_dsp) + #define __DSP_PRESENT 1 /*!< Set to 1 if Partial SIMD(DSP) extension is present */ +#else + #define __DSP_PRESENT 0 /*!< Set to 1 if Partial SIMD(DSP) extension is present */ +#endif + +/** + * Branch Prediction Unit of CORE + */ +#if defined(CONFIG_HAS_BPU) + #define __BPU_PRESENT 0 +#endif + +/** + * CPU IREGION Base Address + */ +#define __IREGION_BASEADDR 0x18000000UL + +/** + * If your hart index is different to your hartid, you must define this __HARTID_OFFSET macro. + * For example, if your cpu has 4 harts, and hartid start from 3, so the __HARTID_OFFSET should set to 3. + * Which means hartid 3-6 means hart index 0-3, this is useful for the timer software interrupt and timer interrupt trigger register location + */ +#ifndef __HARTID_OFFSET +#define __HARTID_OFFSET 0 +#endif + +/** + * Exception Configuration + */ +#define __EXCP_PRESENT 1 + +/* define the correct core features for the SoC */ +#define __ECLIC_PRESENT 1 /*!< Set to 1 if ECLIC is present */ +#if (__ECLIC_PRESENT) + #define __ECLIC_BASEADDR (__IREGION_BASEADDR + IREGION_ECLIC_OFS) /*!< Set to ECLIC baseaddr of your device */ + #define __ECLIC_INTCTLBITS 3 /*!< Set to 1 - 8, the number of hardware bits are actually implemented in the clicintctl registers. */ + #define __ECLIC_INTNUM (ECLIC_EXTERNAL_IRQ_OFFSET + 15) /*!< Set to 1 - 1005, the external interrupt number of ECLIC Unit */ +#endif /* __ECLIC_PRESENT */ + +#define __PLIC_PRESENT 0 + +#define __SYSTIMER_PRESENT 1 /*!< Set to 1 if System Timer is present */ +#if (__SYSTIMER_PRESENT) + #define __SYSTIMER_BASEADDR (__IREGION_BASEADDR + IREGION_TIMER_OFS) /*!< Set to SysTimer baseaddr of your device */ + #define __SYSTIMER_HARTID BOOT_HARTID /*!< Define the system timer hart index of the cpu */ +#endif /* __SYSTIMER_PRESENT */ + +/** + * Physical Memory Protection + */ +#define __PMP_PRESENT 0 /*!< Set to 1 if PMP is present */ +#if (__PMP_PRESENT) + #define __PMP_ENTRY_NUM 0 /*!< Set to 8 or 16, the number of PMP entries */ +#endif /* __PMP_PRESENT */ + +#define __ICACHE_PRESENT 0 /*!< Set to 1 if I-Cache is present */ +#define __DCACHE_PRESENT 0 /*!< Set to 1 if D-Cache is present */ +#define __CCM_PRESENT 0 +#define __NICE_PRESENT 0 +#define __VNICE_PRESENT 0 +#define __INC_INTRINSIC_API 0 /*!< Set to 1 if intrinsic api header files need to be included */ + + +/** + * SMP Configuration + */ +#define __SMPCC_PRESENT 0 +#if (__SMPCC_PRESENT) + #define __SMPCC_BASEADDR (__IREGION_BASEADDR + IREGION_SMP_OFS) +#endif + +#define __CIDU_PRESENT 0 +#if (__CIDU_PRESENT) + #define __CIDU_BASEADDR (__IREGION_BASEADDR + IREGION_IDU_OFS) +#endif /* __CIDU_PRESENT */ + +#define __TEE_PRESENT 0 +#if (__TEE_PRESENT) + #define __SPMP_PRESENT 0 + #define __SMPU_PRESENT 0 + #define __SPMP_ENTRY_NUM 0 +#endif /* __TEE_PRESENT */ + + +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __Vendor_EXCEPTION 0 /*!< Set to 1 if vendor exception hander is present */ + + + +/** @} */ /* End of group Configuration_of_CMSIS */ + +#include "nmsis_core.h" /*!< rv32 processor and core peripherals */ +#include "system_dev.h" /*!< System device */ + +#ifndef __IM /*!< Fallback for older CMSIS versions */ + #define __IM __I +#endif +#ifndef __OM /*!< Fallback for older CMSIS versions */ + #define __OM __O +#endif +#ifndef __IOM /*!< Fallback for older CMSIS versions */ + #define __IOM __IO +#endif + + +/* ======================================== Start of section using anonymous unions ======================================== */ +#if defined (__GNUC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_peripherals + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ EFLASH_MEM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Embedded flash memory (EFLASH_MEM) + */ + +typedef struct { /*!< (@ 0x00000000) EFLASH_MEM Structure */ + __IOM uint32_t DATA0; /*!< (@ 0x00000000) The first address */ + __IM uint32_t RESERVED[8190]; + __IOM uint32_t DATA_END; /*!< (@ 0x00007FFC) The endt address */ +} EFLASH_MEM_Type; /*!< Size = 32768 (0x8000) */ + + + +/* =========================================================================================================================== */ +/* ================ SRAM_MEM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief SRAM memory (SRAM_MEM) + */ + +typedef struct { /*!< (@ 0x20000000) SRAM_MEM Structure */ + __IOM uint32_t DATA0; /*!< (@ 0x00000000) The first address */ + __IM uint32_t RESERVED[1022]; + __IOM uint32_t DATA_END; /*!< (@ 0x00000FFC) The endt address */ +} SRAM_MEM_Type; /*!< Size = 4096 (0x1000) */ + + + +/* =========================================================================================================================== */ +/* ================ NVR_MEM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Non-Volatile Region (NVR_MEM) + */ + +typedef struct { /*!< (@ 0x00200000) NVR_MEM Structure */ + __IOM uint32_t DATA0; /*!< (@ 0x00000000) The first address */ + __IM uint32_t RESERVED[2046]; + __IOM uint32_t DATA_END; /*!< (@ 0x00001FFC) The endt address */ +} NVR_MEM_Type; /*!< Size = 8192 (0x2000) */ + + + +/* =========================================================================================================================== */ +/* ================ CORET ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief RISC-V core of SoC (CORET) + */ + +typedef struct { /*!< (@ 0x18000000) CORET Structure */ + __IOM uint32_t revd; /*!< (@ 0x00000000) NA */ +} CORET_Type; /*!< Size = 4 (0x4) */ + + + +/* =========================================================================================================================== */ +/* ================ UID ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Universally Unique Identifier (UID) + */ + +typedef struct { /*!< (@ 0x00201F00) UID Structure */ + __IM uint32_t UID1; /*!< (@ 0x00000000) Unique Identifier 1 */ + __IM uint32_t UID2; /*!< (@ 0x00000004) Unique Identifier 2 */ + __IM uint32_t UID3; /*!< (@ 0x00000008) Unique Identifier 3 */ +} UID_Type; /*!< Size = 12 (0xc) */ + + + +/* =========================================================================================================================== */ +/* ================ FLASH ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Flash Controller Module (FLASH) + */ + +typedef struct { /*!< (@ 0x4000F800) FLASH Structure */ + + union { + __IOM uint32_t CMD; /*!< (@ 0x00000000) Flash Command Register */ + + struct { + __IOM uint32_t START : 1; /*!< [0..0] Flash command start */ + __IOM uint32_t CMD : 3; /*!< [3..1] Flash command ID */ + uint32_t : 1; + __IOM uint32_t NWS : 3; /*!< [7..5] Flash waits cycles after OP */ + __IOM uint32_t UNLOCK : 1; /*!< [8..8] Unlock Flash P/E operations */ + __IOM uint32_t ACME : 1; /*!< [9..9] Enable Flash Access Counter */ + __IOM uint32_t ACMR : 1; /*!< [10..10] Reset Flash Access Counter */ + uint32_t : 2; + __IOM uint32_t AINC : 1; /*!< [13..13] Flash enable auto address increase or not */ + uint32_t : 2; + __OM uint32_t KEY : 16; /*!< [31..16] Auth key 0xA5A5 */ + } CMD_b; + } ; + + union { + __IOM uint32_t SR; /*!< (@ 0x00000004) Flash Status Register */ + + struct { + __IOM uint32_t CMD_END : 1; /*!< [0..0] Flash idle flag (0:busy), write 1 to clear */ + __IOM uint32_t KEY_ERR : 1; /*!< [1..1] Flash error flag (0:success), W1C */ + __IOM uint32_t ACC_ERR : 1; /*!< [2..2] Flash access error flag, W1C */ + __IOM uint32_t ADDR_ERR : 1; /*!< [3..3] Flash addressing error flag, W1C */ + uint32_t : 2; + __IOM uint32_t HCM : 1; /*!< [6..6] Flash access count full flag, W1C */ + __IM uint32_t HSI_TC_ERR : 1; /*!< [7..7] HSI_TC's complement do not match in sysinfo area */ + __IM uint32_t PROTCT_R2_ERR : 1; /*!< [8..8] Protect_R2's complement do not match in sysinfo area */ + __IM uint32_t PROTCT_R1_ERR : 1; /*!< [9..9] Protect_R1's complement do not match in sysinfo area */ + __IM uint32_t RSTIO_AF_ERR : 1; /*!< [10..10] RSTIO_AF's complement do not match in sysinfo area */ + __IM uint32_t LDO_TRIM_ERR : 1; /*!< [11..11] LDO_TRIM's complement do not match in sysinfo area */ + __IM uint32_t VBUF_TRIM_ERR : 1; /*!< [12..12] VBUF_TRIM's complement do not match in sysinfo area */ + __IM uint32_t LSI_TRIM_ERR : 1; /*!< [13..13] LSI_TRIM's complement do not match in sysinfo area */ + __IM uint32_t HSI_TRIM_ERR : 1; /*!< [14..14] HSI_TRIM's complement do not match in sysinfo area */ + uint32_t : 17; + } SR_b; + } ; + __IM uint32_t RESERVED; + __IOM uint32_t AR; /*!< (@ 0x0000000C) Flash Address Register */ + __IOM uint32_t DR; /*!< (@ 0x00000010) Flash Data Register */ + __IM uint32_t RESERVED1[3]; + __IM uint32_t ACM; /*!< (@ 0x00000020) Flash Access Count Register */ + __IM uint32_t RESERVED2; + + union { + __IOM uint32_t DIV; /*!< (@ 0x00000028) Flash clock division */ + + struct { + __IOM uint32_t DIV : 8; /*!< [7..0] Flash Clock DIV */ + uint32_t : 24; + } DIV_b; + } ; +} FLASH_Type; /*!< Size = 44 (0x2c) */ + + + +/* =========================================================================================================================== */ +/* ================ GPIO ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief General Purpose IO (GPIO) + */ + +typedef struct { /*!< (@ 0x40011000) GPIO Structure */ + + union { + __IOM uint32_t DAT; /*!< (@ 0x00000000) GPIO Data Register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } DAT_b; + } ; + + union { + __IOM uint32_t LAT; /*!< (@ 0x00000004) GPIO output data latch register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } LAT_b; + } ; + + union { + __IOM uint32_t ITS1; /*!< (@ 0x00000008) GPIO interrupt type set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ITS1_b; + } ; + + union { + __IOM uint32_t ITC1; /*!< (@ 0x0000000C) GPIO interrupt type clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ITC1_b; + } ; + + union { + __IOM uint32_t OES; /*!< (@ 0x00000010) GPIO output enable set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } OES_b; + } ; + + union { + __IOM uint32_t OEC; /*!< (@ 0x00000014) GPIO output enable clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } OEC_b; + } ; + + union { + __IOM uint32_t INES; /*!< (@ 0x00000018) GPIO input enable set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } INES_b; + } ; + + union { + __IOM uint32_t INEC; /*!< (@ 0x0000001C) GPIO intput enable clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } INEC_b; + } ; + + union { + __IOM uint32_t IES; /*!< (@ 0x00000020) GPIO pin interrupt enable register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } IES_b; + } ; + + union { + __IOM uint32_t IEC; /*!< (@ 0x00000024) GPIO pin interrupt clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } IEC_b; + } ; + + union { + __IOM uint32_t ITS0; /*!< (@ 0x00000028) GPIO pin interrupt type select register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ITS0_b; + } ; + + union { + __IOM uint32_t ITC0; /*!< (@ 0x0000002C) GPIO pin interrupt type clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ITC0_b; + } ; + + union { + __IOM uint32_t PLS; /*!< (@ 0x00000030) GPIO pin interrupt polarity set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PLS_b; + } ; + + union { + __IOM uint32_t PLC; /*!< (@ 0x00000034) GPIO pin interrupt polarity clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PLC_b; + } ; + + union { + __IOM uint32_t IST; /*!< (@ 0x00000038) GPIO pin interrupt flag status register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } IST_b; + } ; + + union { + __IOM uint32_t PUS; /*!< (@ 0x0000003C) GPIO input pull-up set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PUS_b; + } ; + + union { + __IOM uint32_t PUC; /*!< (@ 0x00000040) GPIO input pull-up clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PUC_b; + } ; + + union { + __IOM uint32_t ODS; /*!< (@ 0x00000044) GPIO output open-drain set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ODS_b; + } ; + + union { + __IOM uint32_t ODC; /*!< (@ 0x00000048) GPIO output open-drain clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } ODC_b; + } ; + + union { + __IOM uint32_t PDS; /*!< (@ 0x0000004C) GPIO input pull-down set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PDS_b; + } ; + + union { + __IOM uint32_t PDC; /*!< (@ 0x00000050) GPIO input pull-down clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } PDC_b; + } ; + + union { + __IOM uint32_t OSRS; /*!< (@ 0x00000054) GPIO Open Sink Set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } OSRS_b; + } ; + + union { + __IOM uint32_t OSRC; /*!< (@ 0x00000058) GPIO Open Sink Clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } OSRC_b; + } ; + + union { + __IOM uint32_t CTS; /*!< (@ 0x0000005C) GPIO Schmitt-Trigger Set register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } CTS_b; + } ; + + union { + __IOM uint32_t CTC; /*!< (@ 0x00000060) GPIO Schmitt-Trigger Clear register */ + + struct { + __IOM uint32_t P00 : 1; /*!< [0..0] Pin 0 */ + __IOM uint32_t P01 : 1; /*!< [1..1] Pin 1 */ + __IOM uint32_t P02 : 1; /*!< [2..2] Pin 2 */ + __IOM uint32_t P03 : 1; /*!< [3..3] Pin 3 */ + __IOM uint32_t P04 : 1; /*!< [4..4] Pin 4 */ + __IOM uint32_t P05 : 1; /*!< [5..5] Pin 5 */ + __IOM uint32_t P06 : 1; /*!< [6..6] Pin 6 */ + __IOM uint32_t P07 : 1; /*!< [7..7] Pin 7 */ + __IOM uint32_t P08 : 1; /*!< [8..8] Pin 8 */ + __IOM uint32_t P09 : 1; /*!< [9..9] Pin 9 */ + __IOM uint32_t P10 : 1; /*!< [10..10] Pin 10 */ + __IOM uint32_t P11 : 1; /*!< [11..11] Pin 11 */ + __IOM uint32_t P12 : 1; /*!< [12..12] Pin 12 */ + __IOM uint32_t P13 : 1; /*!< [13..13] Pin 13 */ + __IOM uint32_t P14 : 1; /*!< [14..14] Pin 14 */ + __IOM uint32_t P15 : 1; /*!< [15..15] Pin 15 */ + uint32_t : 16; + } CTC_b; + } ; +} GPIO_Type; /*!< Size = 100 (0x64) */ + + + +/* =========================================================================================================================== */ +/* ================ AFIO ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Alternate Function I/O (AFIO) + */ + +typedef struct { /*!< (@ 0x40011070) AFIO Structure */ + + union { + __IOM uint32_t PAAFR; /*!< (@ 0x00000000) GPIO PortA AF control register */ + + struct { + __IOM uint32_t PA0 : 3; /*!< [2..0] Pin index */ + __IOM uint32_t PA1 : 3; /*!< [5..3] Pin index */ + __IOM uint32_t PA2 : 3; /*!< [8..6] Pin index */ + __IOM uint32_t PA3 : 3; /*!< [11..9] Pin index */ + __IOM uint32_t PA4 : 3; /*!< [14..12] Pin index */ + __IOM uint32_t PA5 : 3; /*!< [17..15] Pin index */ + __IOM uint32_t PA14 : 3; /*!< [20..18] Pin index */ + __IOM uint32_t PA15 : 3; /*!< [23..21] Pin index */ + uint32_t : 8; + } PAAFR_b; + } ; + + union { + __IOM uint32_t PBAFR; /*!< (@ 0x00000004) GPIO PortB AF control register */ + + struct { + __IOM uint32_t PB0 : 3; /*!< [2..0] Pin index */ + __IOM uint32_t PB1 : 3; /*!< [5..3] Pin index */ + __IOM uint32_t PB2 : 3; /*!< [8..6] Pin index */ + __IOM uint32_t PB3 : 3; /*!< [11..9] Pin index */ + __IOM uint32_t PB4 : 3; /*!< [14..12] Pin index */ + __IOM uint32_t PB5 : 3; /*!< [17..15] Pin index */ + uint32_t : 14; + } PBAFR_b; + } ; + + union { + __IOM uint32_t FN1_AFR; /*!< (@ 0x00000008) Peripheral Alternate Func control register */ + + struct { + __IOM uint32_t BKIN : 4; /*!< [3..0] Peripheral Alternate Func selection */ + __IOM uint32_t ECAP0 : 3; /*!< [6..4] Peripheral Alternate Func selection */ + __IOM uint32_t ECAP1 : 3; /*!< [9..7] Peripheral Alternate Func selection */ + __IOM uint32_t ECAP2 : 3; /*!< [12..10] Peripheral Alternate Func selection */ + __IOM uint32_t EPETR : 4; /*!< [16..13] Peripheral Alternate Func selection */ + uint32_t : 15; + } FN1_AFR_b; + } ; + + union { + __IOM uint32_t FN2_AFR; /*!< (@ 0x0000000C) Peripheral Alternate Func control register */ + + struct { + __IOM uint32_t TCAP0 : 3; /*!< [2..0] Peripheral Alternate Func control register */ + __IOM uint32_t TCAP1 : 3; /*!< [5..3] Peripheral Alternate Func control register */ + __IOM uint32_t TCAP2 : 3; /*!< [8..6] Peripheral Alternate Func control register */ + __IOM uint32_t T2ETR : 4; /*!< [12..9] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL0 : 1; /*!< [13..13] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL1 : 1; /*!< [14..14] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL2 : 1; /*!< [15..15] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL3 : 1; /*!< [16..16] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL4 : 1; /*!< [17..17] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL5 : 1; /*!< [18..18] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL6 : 1; /*!< [19..19] Peripheral Alternate Func control register */ + __IOM uint32_t I2C_PULL7 : 1; /*!< [20..20] Peripheral Alternate Func control register */ + uint32_t : 11; + } FN2_AFR_b; + } ; +} AFIO_Type; /*!< Size = 16 (0x10) */ + + + +/* =========================================================================================================================== */ +/* ================ SYSCFG ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief System Configuration controller (SYSCFG) + */ + +typedef struct { /*!< (@ 0x4001F000) SYSCFG Structure */ + __IM uint32_t RESERVED; + + union { + __IOM uint32_t PMUCR; /*!< (@ 0x00000004) Power Management Unit Control Register */ + + struct { + __IOM uint32_t PMUEN : 1; /*!< [0..0] Enable pmu */ + uint32_t : 31; + } PMUCR_b; + } ; + __IM uint32_t RESERVED1; + + union { + __IOM uint32_t MCOCR; /*!< (@ 0x0000000C) MCU Clock Output Control Register */ + + struct { + __IOM uint32_t MCOSEL : 3; /*!< [2..0] Select output clock */ + uint32_t : 3; + __IOM uint32_t DivEn : 1; /*!< [6..6] Enable MCO outupt pre-scalar */ + __IOM uint32_t DivSel : 1; /*!< [7..7] Select outupt pre-scalar */ + __IOM uint32_t Divider : 8; /*!< [15..8] The pre-scalar value */ + __IOM uint32_t SWRstEn : 8; /*!< [23..16] Trigger software reset */ + uint32_t : 8; + } MCOCR_b; + } ; + + union { + __IOM uint32_t SYSRSTSR; /*!< (@ 0x00000010) System Reset Status Register */ + + struct { + __IOM uint32_t SWRST : 1; /*!< [0..0] Software reset (Write clear) */ + __IOM uint32_t WDGRST : 1; /*!< [1..1] Watchdog reset (Write clear) */ + __IOM uint32_t LOCKUPRST : 1; /*!< [2..2] Lock-up reset (Write clear) */ + uint32_t : 5; + __IOM uint32_t PORRST : 1; /*!< [8..8] Power reset (Write clear) */ + __IOM uint32_t PADRST : 1; /*!< [9..9] nRST Pad reset (Write clear) */ + uint32_t : 1; + __IOM uint32_t LVDRST : 1; /*!< [11..11] LVD reset (Write clear) */ + __IOM uint32_t REBOOTRST : 1; /*!< [12..12] Reboot reset (Write clear) */ + uint32_t : 19; + } SYSRSTSR_b; + } ; + + union { + __IOM uint32_t REBOOT_UNLOCK; /*!< (@ 0x00000014) Unlock reboot to latch paraments */ + + struct { + __IOM uint32_t AUTHKEY : 16; /*!< [15..0] Reboot signature: 0xAB56 */ + uint32_t : 16; + } REBOOT_UNLOCK_b; + } ; + + union { + __IOM uint32_t SYSRSTCR; /*!< (@ 0x00000018) System Reset Control Register */ + + struct { + uint32_t : 10; + __IOM uint32_t REBOOTEN : 1; /*!< [10..10] Trigger system Re-boot */ + uint32_t : 21; + } SYSRSTCR_b; + } ; + + union { + __IOM uint32_t DEBUGENCR; /*!< (@ 0x0000001C) Debug enable Control Register */ + + struct { + uint32_t : 2; + __IOM uint32_t TIM0 : 1; /*!< [2..2] Tim0 debug mode */ + __IOM uint32_t TIM1 : 1; /*!< [3..3] Tim1 debug mode */ + __IOM uint32_t LPTIM : 1; /*!< [4..4] LPTIM debug mode */ + uint32_t : 1; + __IOM uint32_t EPWM : 1; /*!< [6..6] EPWM debug mode */ + uint32_t : 4; + __IOM uint32_t TIM2 : 1; /*!< [11..11] TIM2 debug mode */ + uint32_t : 2; + __IOM uint32_t WDG : 1; /*!< [14..14] WDG debug mode(def: enable) */ + uint32_t : 1; + __OM uint32_t AUTHKEY : 16; /*!< [31..16] Reboot signature: 0x8A57 */ + } DEBUGENCR_b; + } ; + + union { + __IOM uint32_t SYSCLKCR; /*!< (@ 0x00000020) System Clock Control Register */ + + struct { + __IOM uint32_t CLKSW : 3; /*!< [2..0] System Clock Source Switch */ + uint32_t : 5; + __IOM uint32_t CLKDIV : 4; /*!< [11..8] Clock Divider, factors = (CLKDIV + 1) */ + uint32_t : 11; + __IOM uint32_t LSIAON : 1; /*!< [23..23] LSI always on */ + __IOM uint32_t SYSTICKCR : 2; /*!< [25..24] Sytem tick Control Register */ + uint32_t : 6; + } SYSCLKCR_b; + } ; + + union { + __IOM uint32_t PRSTEN; /*!< (@ 0x00000024) Peripheral Reset Control Register */ + + struct { + __IOM uint32_t UART0 : 1; /*!< [0..0] Reset enable (It should generate pulse signal to reset) */ + uint32_t : 1; + __IOM uint32_t TIM0 : 1; /*!< [2..2] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t TIM1 : 1; /*!< [3..3] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t LPTIM : 1; /*!< [4..4] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t ADC : 1; /*!< [5..5] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t EPWM : 1; /*!< [6..6] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t DSP : 1; /*!< [7..7] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t COMP0 : 1; /*!< [8..8] Reset enable (It should generate pulse signal to reset) */ + uint32_t : 1; + __IOM uint32_t SPI : 1; /*!< [10..10] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t TIM2 : 1; /*!< [11..11] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t I2C : 1; /*!< [12..12] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t COMP1 : 1; /*!< [13..13] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t WDG : 1; /*!< [14..14] Reset enable (It should generate pulse signal to reset) */ + __IOM uint32_t AMISC : 1; /*!< [15..15] Reset enable (It should generate pulse signal to reset) */ + uint32_t : 16; + } PRSTEN_b; + } ; + + union { + __IOM uint32_t PCLKEN; /*!< (@ 0x00000028) Peripheral Clock Enable Control Register */ + + struct { + __IOM uint32_t UART0 : 1; /*!< [0..0] PCLK enable Uart 0 */ + uint32_t : 1; + __IOM uint32_t TIM0 : 1; /*!< [2..2] PCLK enable TIM0 */ + __IOM uint32_t TIM1 : 1; /*!< [3..3] PCLK enable TIM1 */ + __IOM uint32_t LPTIM : 1; /*!< [4..4] PCLK enable LPTIM */ + __IOM uint32_t ADC : 1; /*!< [5..5] PCLK enable ADC */ + __IOM uint32_t EPWM : 1; /*!< [6..6] PCLK enable EPWM */ + __IOM uint32_t DSP : 1; /*!< [7..7] PCLK enable DSP */ + __IOM uint32_t COMP0 : 1; /*!< [8..8] PCLK enable COMP0 */ + uint32_t : 1; + __IOM uint32_t SPI : 1; /*!< [10..10] PCLK enable SPI */ + __IOM uint32_t TIM2 : 1; /*!< [11..11] PCLK enable TIM2 */ + __IOM uint32_t I2C : 1; /*!< [12..12] PCLK enable I2C */ + __IOM uint32_t COMP1 : 1; /*!< [13..13] PCLK enable COMP1 */ + __IOM uint32_t WDG : 1; /*!< [14..14] PCLK enable WDG */ + __IOM uint32_t AMISC : 1; /*!< [15..15] PCLK enable analog misc. */ + uint32_t : 16; + } PCLKEN_b; + } ; + + union { + __IOM uint32_t ICEIOCR; /*!< (@ 0x0000002C) ICE I/O Control Register */ + + struct { + __IOM uint32_t JTAGIOEN : 1; /*!< [0..0] I/O force on jTag pins. 0: normal I/O, 1: ICE pins */ + __IOM uint32_t DBG_CTRL_EN : 1; /*!< [1..1] Enable debug control */ + __IOM uint32_t DBG_EN : 1; /*!< [2..2] Enable debug */ + uint32_t : 13; + __IOM uint32_t AUTHKEY : 16; /*!< [31..16] auth-key 0xE653 */ + } ICEIOCR_b; + } ; + + union { + __IOM uint32_t RSTPINCR; /*!< (@ 0x00000030) Reset pin control register */ + + struct { + __IOM uint32_t RSTPINAF : 16; /*!< [15..0] Reset Pin switch to general I/O */ + uint32_t : 16; + } RSTPINCR_b; + } ; + + union { + __IOM uint32_t TIM2_CON_SEL; /*!< (@ 0x00000034) TIM2 selection */ + + struct { + __IOM uint32_t CH1 : 3; /*!< [2..0] selection */ + uint32_t : 1; + __IOM uint32_t CH2 : 3; /*!< [6..4] selection */ + uint32_t : 1; + __IOM uint32_t CH3 : 3; /*!< [10..8] selection */ + uint32_t : 1; + __IOM uint32_t CH4 : 3; /*!< [14..12] selection */ + uint32_t : 2; + __IOM uint32_t BREAK_SEL : 1; /*!< [17..17] TIM IP Config */ + __IOM uint32_t COMP0A_SEL : 1; /*!< [18..18] COMP0A selection */ + __IOM uint32_t COMP1A_SEL : 1; /*!< [19..19] COMP1A selection */ + __IOM uint32_t VC_CH1_INV : 1; /*!< [20..20] VCOUT_SEL */ + __IOM uint32_t VC_CH1 : 1; /*!< [21..21] VCOUT_SEL */ + __IOM uint32_t VC_CH2_INV : 1; /*!< [22..22] VCOUT_SEL */ + __IOM uint32_t VC_CH2 : 1; /*!< [23..23] VCOUT_SEL */ + __IOM uint32_t VC_CH3_INV : 1; /*!< [24..24] VCOUT_SEL */ + __IOM uint32_t VC_CH3 : 1; /*!< [25..25] VCOUT_SEL */ + __IOM uint32_t VC_CH4_INV : 1; /*!< [26..26] VCOUT_SEL */ + __IOM uint32_t VC_CH4 : 1; /*!< [27..27] VCOUT_SEL */ + __IOM uint32_t COMP0D_SEL : 1; /*!< [28..28] COMP0D selection */ + __IOM uint32_t COMP1D_SEL : 1; /*!< [29..29] COMP1D selection */ + uint32_t : 2; + } TIM2_CON_SEL_b; + } ; + + union { + __IOM uint32_t EPWM_CON_SEL; /*!< (@ 0x00000038) EPWM selection */ + + struct { + __IOM uint32_t CH1 : 3; /*!< [2..0] selection */ + uint32_t : 1; + __IOM uint32_t CH2 : 3; /*!< [6..4] selection */ + uint32_t : 1; + __IOM uint32_t CH3 : 3; /*!< [10..8] selection */ + uint32_t : 1; + __IOM uint32_t CH4 : 3; /*!< [14..12] selection */ + uint32_t : 1; + __IOM uint32_t BREAK_SEL : 1; /*!< [16..16] EPWM IP Config */ + __IOM uint32_t BREAK_OSSI0_DISOUT : 1; /*!< [17..17] EPWM IP Config */ + __IOM uint32_t COMP0A_SEL : 1; /*!< [18..18] COMP0A Selection */ + __IOM uint32_t COMP1A_SEL : 1; /*!< [19..19] COMP1A Selection */ + __IOM uint32_t VC_CH1_INV : 1; /*!< [20..20] VCOUT_SEL */ + __IOM uint32_t VC_CH1 : 1; /*!< [21..21] VCOUT_SEL */ + __IOM uint32_t VC_CH2_INV : 1; /*!< [22..22] VCOUT_SEL */ + __IOM uint32_t VC_CH2 : 1; /*!< [23..23] VCOUT_SEL */ + __IOM uint32_t VC_CH3_INV : 1; /*!< [24..24] VCOUT_SEL */ + __IOM uint32_t VC_CH3 : 1; /*!< [25..25] VCOUT_SEL */ + __IOM uint32_t VC_CH4_INV : 1; /*!< [26..26] VCOUT_SEL */ + __IOM uint32_t VC_CH4 : 1; /*!< [27..27] VCOUT_SEL */ + __IOM uint32_t COMP0D_SEL : 1; /*!< [28..28] COMP0D Selection */ + __IOM uint32_t COMP1D_SEL : 1; /*!< [29..29] COMP1D Selection */ + __IOM uint32_t LVD_SEL : 1; /*!< [30..30] LVD Selection */ + __IOM uint32_t WDG_SEL : 1; /*!< [31..31] Watchdog Selection */ + } EPWM_CON_SEL_b; + } ; + __IM uint32_t RESERVED2; + + union { + __IOM uint32_t PRSTEN1; /*!< (@ 0x00000040) peripheral modules reset */ + + struct { + __IOM uint32_t GPIOA : 1; /*!< [0..0] GPIO reset enable (It should generate pulse signal to + reset) */ + __IOM uint32_t GPIOB : 1; /*!< [1..1] GPIO reset enable (It should generate pulse signal to + reset) */ + uint32_t : 5; + __IOM uint32_t CRC : 1; /*!< [7..7] CRC reset enable (It should generate pulse signal to + reset) */ + uint32_t : 24; + } PRSTEN1_b; + } ; + + union { + __IOM uint32_t HCLKEN; /*!< (@ 0x00000044) Enable clock of Modules of AHB */ + + struct { + __IOM uint32_t GPIOA : 1; /*!< [0..0] GPIO clock enable */ + __IOM uint32_t GPIOB : 1; /*!< [1..1] GPIO clock enable */ + uint32_t : 5; + __IOM uint32_t CRC : 1; /*!< [7..7] CRC clock enable */ + uint32_t : 24; + } HCLKEN_b; + } ; + + union { + __IOM uint32_t EVT_SEL; /*!< (@ 0x00000048) Event select */ + + struct { + __IOM uint32_t IRQSEL : 32; /*!< [31..0] Link interrupt source as event (bit-order is IRQ number) */ + } EVT_SEL_b; + } ; + + union { + __IOM uint32_t NMICR; /*!< (@ 0x0000004C) NMI Control Register */ + + struct { + __IOM uint32_t SEL : 5; /*!< [4..0] Connect IRQ number to NMI */ + __IOM uint32_t EN : 3; /*!< [7..5] Enable to connect IRQ sourec to NMI */ + uint32_t : 24; + } NMICR_b; + } ; + __IM uint32_t RESERVED3[44]; + __IM uint32_t CHIPID; /*!< (@ 0x00000100) Chip ID register */ +} SYSCFG_Type; /*!< Size = 260 (0x104) */ + + + +/* =========================================================================================================================== */ +/* ================ UART ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Universal Asynchronous Rx/Tx (UART) + */ + +typedef struct { /*!< (@ 0x40002000) UART Structure */ + + union { + __IOM uint32_t DAT; /*!< (@ 0x00000000) UART TX/RX Data Register (FIFO: 8) */ + + struct { + __IOM uint32_t DAT : 9; /*!< [8..0] 8/9 bits data */ + __IOM uint32_t FE : 1; /*!< [9..9] Frame error flag */ + uint32_t : 22; + } DAT_b; + } ; + + union { + __IOM uint32_t CR; /*!< (@ 0x00000004) UART Control Register */ + + struct { + __IOM uint32_t MODE : 3; /*!< [2..0] Mode select */ + __IOM uint32_t STOPB : 2; /*!< [4..3] width of STOP bits */ + __IOM uint32_t PAR : 1; /*!< [5..5] Parity check */ + __IOM uint32_t LPB : 1; /*!< [6..6] Enable Loop back mode */ + __IOM uint32_t RUN : 1; /*!< [7..7] Baudrate generator run */ + __IOM uint32_t RXEN : 1; /*!< [8..8] RX enable */ + uint32_t : 7; + __IOM uint32_t RXPOL : 1; /*!< [16..16] RX data polarity inverse control */ + __IOM uint32_t TXPOL : 1; /*!< [17..17] TX data polarity inverse control */ + uint32_t : 14; + } CR_b; + } ; + + union { + __IOM uint32_t BR; /*!< (@ 0x00000008) UART Baudrate Control Register */ + + struct { + __IOM uint32_t BR : 16; /*!< [15..0] Baud-Rate */ + uint32_t : 16; + } BR_b; + } ; + + union { + __IOM uint32_t IE; /*!< (@ 0x0000000C) UART Interrupt Enable Register */ + + struct { + __IOM uint32_t RXNEE : 1; /*!< [0..0] RX FIFO not empty interrupt enable */ + __IOM uint32_t TXEE : 1; /*!< [1..1] TX FIFO empty interrupt enable */ + __IOM uint32_t TXHEE : 1; /*!< [2..2] TX FIFO half-empty interrupt enable */ + __IOM uint32_t PERRE : 1; /*!< [3..3] Parity error interrupt enable */ + __IOM uint32_t FERRE : 1; /*!< [4..4] Frame error interrupt enable */ + __IOM uint32_t OVERRE : 1; /*!< [5..5] RX overflow interrupt enable */ + __IOM uint32_t TONEE : 1; /*!< [6..6] TX time-out interrupt enable */ + __IOM uint32_t TOIDLEE : 1; /*!< [7..7] TX idle time-out interrupt enable */ + __IOM uint32_t RXHFE : 1; /*!< [8..8] RX FIFO half-full interrupt enable */ + __IOM uint32_t RXFE : 1; /*!< [9..9] RX FIFO full interrupt enable */ + __IOM uint32_t TXENDE : 1; /*!< [10..10] TX end interrupt enable */ + __IOM uint32_t TXFE : 1; /*!< [11..11] TX FIFO full interrupt enable */ + __IOM uint32_t RXPE : 1; /*!< [12..12] RX AUTO parity */ + uint32_t : 19; + } IE_b; + } ; + + union { + __IOM uint32_t SR; /*!< (@ 0x00000010) UART Status Register */ + + struct { + __IM uint32_t RXNE : 1; /*!< [0..0] RX FIFO not empty */ + __IM uint32_t TXE : 1; /*!< [1..1] TX FIFO empty */ + __IM uint32_t TXHE : 1; /*!< [2..2] TX FIFO half-empty */ + __IOM uint32_t PERR : 1; /*!< [3..3] Parity error flag (W1C) */ + __IOM uint32_t FERR : 1; /*!< [4..4] Frame error flag (W1C) */ + __IOM uint32_t OVERR : 1; /*!< [5..5] RX overflow flag (W1C) */ + __IM uint32_t TONE : 1; /*!< [6..6] Clean RX FIFO time-out */ + __IM uint32_t TOIDLE : 1; /*!< [7..7] TX idle time-out */ + __IM uint32_t RXHF : 1; /*!< [8..8] RX FIFO half-full */ + __IM uint32_t RXF : 1; /*!< [9..9] RX FIFO full */ + __IM uint32_t TXEND : 1; /*!< [10..10] TX end */ + __IM uint32_t TXF : 1; /*!< [11..11] TX FIFO full */ + uint32_t : 20; + } SR_b; + } ; + + union { + __IOM uint32_t GTR; /*!< (@ 0x00000014) UART Frame Guard-time Register */ + + struct { + __IOM uint32_t GT : 8; /*!< [7..0] Frame Guard-Time */ + uint32_t : 24; + } GTR_b; + } ; + + union { + __IOM uint32_t TOR; /*!< (@ 0x00000018) UART Time-Out Control Register */ + + struct { + __IOM uint32_t TO : 8; /*!< [7..0] Time-Out value */ + uint32_t : 24; + } TOR_b; + } ; + __OM uint32_t TXFR; /*!< (@ 0x0000001C) Reset UART TX FIFO with any value */ + __OM uint32_t RXFR; /*!< (@ 0x00000020) Reset UART RX FIFO with any value */ +} UART_Type; /*!< Size = 36 (0x24) */ + + + +/* =========================================================================================================================== */ +/* ================ I2C ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Inter-Integrated Circuit (I2C) + */ + +typedef struct { /*!< (@ 0x40003000) I2C Structure */ + + union { + __IOM uint32_t CTLSET; /*!< (@ 0x00000000) Register */ + + struct { + __IOM uint32_t CR0 : 1; /*!< [0..0] CLK SET */ + __IOM uint32_t CR1 : 1; /*!< [1..1] CLK SET */ + __IOM uint32_t AA : 1; /*!< [2..2] answer control */ + __IOM uint32_t SI : 1; /*!< [3..3] interrupt flag */ + __IOM uint32_t STO : 1; /*!< [4..4] stop control */ + __IOM uint32_t STA : 1; /*!< [5..5] start control */ + __IOM uint32_t EN : 1; /*!< [6..6] enable */ + __IOM uint32_t CR2 : 1; /*!< [7..7] clk control */ + uint32_t : 24; + } CTLSET_b; + } ; + + union { + __IOM uint32_t STAT; /*!< (@ 0x00000004) Register */ + + struct { + uint32_t : 3; + __IOM uint32_t STAT : 5; /*!< [7..3] BUS STATUS */ + uint32_t : 24; + } STAT_b; + } ; + + union { + __IOM uint32_t DATA; /*!< (@ 0x00000008) Register */ + + struct { + __IOM uint32_t DATA : 8; /*!< [7..0] SEND OR RECEIVE DATA */ + uint32_t : 24; + } DATA_b; + } ; + + union { + __IOM uint32_t ADDR; /*!< (@ 0x0000000C) Register */ + + struct { + __IOM uint32_t GC : 1; /*!< [0..0] radio enable */ + __IOM uint32_t ADDR : 7; /*!< [7..1] addre */ + uint32_t : 8; + __IOM uint32_t FILTERDELAY : 4; /*!< [19..16] FILTERDELAY */ + uint32_t : 4; + __IOM uint32_t FILTERDELAY_EN : 8; /*!< [31..24] FILTERDELAY_EN */ + } ADDR_b; + } ; + __IM uint32_t RESERVED[2]; + + union { + __IOM uint32_t CTLCLR; /*!< (@ 0x00000018) Register */ + + struct { + __IOM uint32_t CR0 : 1; /*!< [0..0] CLEAT CR0 */ + __IOM uint32_t CR1 : 1; /*!< [1..1] CLEAT CR1 */ + __IOM uint32_t AA : 1; /*!< [2..2] CLEAT 11 */ + __IOM uint32_t SI : 1; /*!< [3..3] CLEAT SI */ + __IOM uint32_t STO : 1; /*!< [4..4] CLEAT STO */ + __IOM uint32_t STA : 1; /*!< [5..5] CLEAT STA */ + __IOM uint32_t EN : 1; /*!< [6..6] CLEAT EN */ + __IOM uint32_t CR2 : 1; /*!< [7..7] CLEAT CR2 */ + uint32_t : 24; + } CTLCLR_b; + } ; +} I2C_Type; /*!< Size = 28 (0x1c) */ + + + +/* =========================================================================================================================== */ +/* ================ SPI ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Serial Peripheral Interface Bus (SPI) + */ + +typedef struct { /*!< (@ 0x40003800) SPI Structure */ + + union { + __IOM uint32_t CFG; /*!< (@ 0x00000000) Register */ + + struct { + __IOM uint32_t MODE : 1; /*!< [0..0] mode select */ + __IOM uint32_t CPOL : 1; /*!< [1..1] clock polarity */ + __IOM uint32_t CPHA : 1; /*!< [2..2] clock phase */ + __IOM uint32_t DB : 3; /*!< [5..3] baud rate */ + __IOM uint32_t TXWDSZ : 2; /*!< [7..6] tx data size */ + __IOM uint32_t LSB : 1; /*!< [8..8] transmit control */ + uint32_t : 1; + __IOM uint32_t SS_OUT : 1; /*!< [10..10] periphare select */ + uint32_t : 3; + __IOM uint32_t MCS : 1; /*!< [14..14] handler section select */ + __IOM uint32_t MSE : 1; /*!< [15..15] handler mode select */ + __IOM uint32_t MSTC : 1; /*!< [16..16] handler command start */ + __IOM uint32_t MODEF : 1; /*!< [17..17] mode fail enable */ + uint32_t : 14; + } CFG_b; + } ; + + union { + __IOM uint32_t STA; /*!< (@ 0x00000004) Register */ + + struct { + __IOM uint32_t RECVOV : 1; /*!< [0..0] RX overbrim flag */ + __IOM uint32_t MDF : 1; /*!< [1..1] mode false */ + __IOM uint32_t TXNFUL : 1; /*!< [2..2] TX FIFO no full */ + __IOM uint32_t TXFUL : 1; /*!< [3..3] TX FIFO full */ + __IOM uint32_t RXNEP : 1; /*!< [4..4] RX not empty */ + __IOM uint32_t RXFUL : 1; /*!< [5..5] RX full */ + __IOM uint32_t TXUFL : 1; /*!< [6..6] TX underflow */ + __IOM uint32_t BUSY : 1; /*!< [7..7] module busy */ + uint32_t : 24; + } STA_b; + } ; + + union { + __IOM uint32_t INTEN; /*!< (@ 0x00000008) Register */ + + struct { + __IOM uint32_t INTEN : 7; /*!< [6..0] interrupt enable */ + uint32_t : 25; + } INTEN_b; + } ; + + union { + __IOM uint32_t INTDIS; /*!< (@ 0x0000000C) Register */ + + struct { + __IOM uint32_t INTEN : 7; /*!< [6..0] close interrupt */ + uint32_t : 25; + } INTDIS_b; + } ; + + union { + __IOM uint32_t INTMASK; /*!< (@ 0x00000010) Register */ + + struct { + __IOM uint32_t INTEN : 7; /*!< [6..0] interrupt mask */ + uint32_t : 25; + } INTMASK_b; + } ; + + union { + __IOM uint32_t EN; /*!< (@ 0x00000014) Register */ + + struct { + __IOM uint32_t EN : 1; /*!< [0..0] spi module enable */ + uint32_t : 31; + } EN_b; + } ; + + union { + __IOM uint32_t DELAY; /*!< (@ 0x00000018) Register */ + + struct { + __IOM uint32_t d_int : 8; /*!< [7..0] d_int */ + __IOM uint32_t d_affter : 8; /*!< [15..8] d_affter */ + __IOM uint32_t d_btwn : 8; /*!< [23..16] d_btwn */ + __IOM uint32_t d_nss : 8; /*!< [31..24] d_nss */ + } DELAY_b; + } ; + __IOM uint32_t TX; /*!< (@ 0x0000001C) Register */ + __IOM uint32_t RX; /*!< (@ 0x00000020) Register */ + + union { + __IOM uint32_t IDLECNT; /*!< (@ 0x00000024) Register */ + + struct { + __IOM uint32_t IDLECNT : 8; /*!< [7..0] IDLECNT */ + uint32_t : 24; + } IDLECNT_b; + } ; + + union { + __IOM uint32_t TXTH; /*!< (@ 0x00000028) Register */ + + struct { + __IOM uint32_t TXTHOLD : 32; /*!< [31..0] cause no full interrupt */ + } TXTH_b; + } ; + + union { + __IOM uint32_t RXTH; /*!< (@ 0x0000002C) Register */ + + struct { + __IOM uint32_t RXTHOLD : 32; /*!< [31..0] cause no empty interrupt */ + } RXTH_b; + } ; +} SPI_Type; /*!< Size = 48 (0x30) */ + + + +/* =========================================================================================================================== */ +/* ================ WDG ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Watchdog (WDG) + */ + +typedef struct { /*!< (@ 0x40004000) WDG Structure */ + __IOM uint32_t LOAD; /*!< (@ 0x00000000) WDT LOAD Register */ + __IM uint32_t VALUE; /*!< (@ 0x00000004) WDT Counter Register */ + + union { + __IOM uint32_t CR; /*!< (@ 0x00000008) WDT Control Register */ + + struct { + __IOM uint32_t INTE : 1; /*!< [0..0] Enable interrupt */ + __IOM uint32_t RSTE : 1; /*!< [1..1] Enable Reset */ + __IOM uint32_t DBGE : 1; /*!< [2..2] Enable Debug Pending */ + uint32_t : 29; + } CR_b; + } ; + __OM uint32_t INTCLR; /*!< (@ 0x0000000C) WDT interrupt clear Register */ + + union { + __IM uint32_t RIS; /*!< (@ 0x00000010) WDT original interrupt flag Register */ + + struct { + __IM uint32_t RIF : 1; /*!< [0..0] original interrupt flag */ + uint32_t : 31; + } RIS_b; + } ; + + union { + __IM uint32_t MIS; /*!< (@ 0x00000014) WDT MASK interrupt flag Register */ + + struct { + __IM uint32_t MIF : 1; /*!< [0..0] MASK interrupt flag */ + uint32_t : 31; + } MIS_b; + } ; + __IM uint32_t RESERVED[250]; + + union { + __IOM uint32_t LOCK; /*!< (@ 0x00000400) WDT LOCK Register */ + + struct { + __IOM uint32_t LOCK : 1; /*!< [0..0] WDT LOCK Control */ + uint32_t : 31; + } LOCK_b; + } ; +} WDG_Type; /*!< Size = 1028 (0x404) */ + + + +/* =========================================================================================================================== */ +/* ================ ADC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Analog-to-Digital Converter (ADC) + */ + +typedef struct { /*!< (@ 0x40004800) ADC Structure */ + + union { + __IOM uint32_t CON0; /*!< (@ 0x00000000) AD Control Register */ + + struct { + __IOM uint32_t M : 4; /*!< [3..0] ADC input channel select */ + uint32_t : 1; + __IOM uint32_t EN : 1; /*!< [5..5] ADC module enable */ + uint32_t : 1; + __IOM uint32_t START : 1; /*!< [7..7] AD conversion start */ + __IOM uint32_t CLK : 3; /*!< [10..8] ADC clock divider (800KHz ~ 16MHz) */ + __IOM uint32_t TRIG_EN : 1; /*!< [11..11] Enable H/w trigger */ + __IOM uint32_t CONTINUE : 1; /*!< [12..12] Enable continue mode */ + __IOM uint32_t ALIGN : 1; /*!< [13..13] ADC result align moe */ + uint32_t : 1; + __IOM uint32_t ENCONT : 1; /*!< [15..15] 1: Never Stop Conversion in continue mode */ + __IOM uint32_t INT_EN : 4; /*!< [19..16] Enable ADC interrupt */ + __IOM uint32_t TZO : 3; /*!< [22..20] zero offset change */ + uint32_t : 6; + __IOM uint32_t BAKEN : 1; /*!< [29..29] Enable backup the previous conversion value */ + __IOM uint32_t PWD : 1; /*!< [30..30] Power down analog physical module */ + __IOM uint32_t RST : 1; /*!< [31..31] Reset analog physical module */ + } CON0_b; + } ; + + union { + __IOM uint32_t STAT; /*!< (@ 0x00000004) ADC State Registter */ + + struct { + __IM uint32_t DONE : 1; /*!< [0..0] ADC done(auto clear after read reg DATx) */ + __IOM uint32_t INT_CLR : 1; /*!< [1..1] ADC clear interrupt flag, 1:clear */ + uint32_t : 2; + __IM uint32_t COMP_RESULT : 2; /*!< [5..4] Result of Comparison(auto clear after read reg DATx) */ + __IOM uint32_t EOC_CHECK_DIS : 1; /*!< [6..6] Disable End-of-Conversion checking */ + uint32_t : 9; + __IOM uint32_t TS_SET : 5; /*!< [20..16] Set Ts cycles */ + __IOM uint32_t DLY_SET : 3; /*!< [23..21] Set delay cycles with ADC clock */ + __IM uint32_t EOC_CNT : 4; /*!< [27..24] Count of End-of-Conversion */ + __IM uint32_t START_CNT : 4; /*!< [31..28] Count of Start */ + } STAT_b; + } ; + + union { + __IOM uint32_t DAT0; /*!< (@ 0x00000008) ADC Result0 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT0_b; + } ; + + union { + __IOM uint32_t DAT1; /*!< (@ 0x0000000C) ADC Result1 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT1_b; + } ; + + union { + __IOM uint32_t DAT2; /*!< (@ 0x00000010) ADC Result2 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT2_b; + } ; + + union { + __IOM uint32_t DAT3; /*!< (@ 0x00000014) ADC Result3 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT3_b; + } ; + + union { + __IOM uint32_t DAT4; /*!< (@ 0x00000018) ADC Result4 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT4_b; + } ; + + union { + __IOM uint32_t DAT5; /*!< (@ 0x0000001C) ADC Result5 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT5_b; + } ; + + union { + __IOM uint32_t DAT6; /*!< (@ 0x00000020) ADC Result6 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT6_b; + } ; + + union { + __IOM uint32_t DAT7; /*!< (@ 0x00000024) ADC Result7 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT7_b; + } ; + + union { + __IOM uint32_t DAT8; /*!< (@ 0x00000028) ADC Result8 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT8_b; + } ; + + union { + __IOM uint32_t DAT9; /*!< (@ 0x0000002C) ADC Result9 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT9_b; + } ; + + union { + __IOM uint32_t DAT10; /*!< (@ 0x00000030) ADC Result10 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT10_b; + } ; + + union { + __IOM uint32_t DAT11; /*!< (@ 0x00000034) ADC Result11 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT11_b; + } ; + + union { + __IOM uint32_t DAT12; /*!< (@ 0x00000038) ADC Result12 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT12_b; + } ; + + union { + __IOM uint32_t DAT13; /*!< (@ 0x0000003C) ADC Result13 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT13_b; + } ; + + union { + __IOM uint32_t DAT14; /*!< (@ 0x00000040) ADC Result14 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT14_b; + } ; + + union { + __IOM uint32_t DAT15; /*!< (@ 0x00000044) ADC Result13 Register */ + + struct { + __IM uint32_t DATA : 16; /*!< [15..0] ADC result data */ + __IOM uint32_t CMPTH : 12; /*!< [27..16] Comparison threshold */ + uint32_t : 4; + } DAT15_b; + } ; + + union { + __IOM uint32_t CHSEL; /*!< (@ 0x00000048) ADC channel selection Register */ + + struct { + __IOM uint32_t CH_SEL : 16; /*!< [15..0] Channel 0~15 */ + __IOM uint32_t CH_CNT : 4; /*!< [19..16] Selected Channel Count */ + uint32_t : 1; + __IOM uint32_t DISC_INTSEL : 1; /*!< [21..21] Select interrupt condition when DISCEN==1 */ + __IOM uint32_t DISCNUM : 3; /*!< [24..22] Discontinuous mode channel count (DISCNUM+1) */ + __IOM uint32_t DISCEN : 1; /*!< [25..25] Discontinuous mode Enable */ + __IOM uint32_t TRIG_SEL16 : 2; /*!< [27..26] Trigger Selection 16 */ + __IOM uint32_t TRIG_SEL17 : 2; /*!< [29..28] Trigger Selection 17 */ + __IOM uint32_t EXTRIG_SEL : 2; /*!< [31..30] External Trigger Selection */ + } CHSEL_b; + } ; + + union { + __IOM uint32_t TRGSEL; /*!< (@ 0x0000004C) ADC Trigger selection Register */ + + struct { + __IOM uint32_t TRIG_SEL0 : 2; /*!< [1..0] Trigger Selection 0 */ + __IOM uint32_t TRIG_SEL1 : 2; /*!< [3..2] Trigger Selection 1 */ + __IOM uint32_t TRIG_SEL2 : 2; /*!< [5..4] Trigger Selection 2 */ + __IOM uint32_t TRIG_SEL3 : 2; /*!< [7..6] Trigger Selection 3 */ + __IOM uint32_t TRIG_SEL4 : 2; /*!< [9..8] Trig Selection 4 */ + __IOM uint32_t TRIG_SEL5 : 2; /*!< [11..10] Trigger Selection 5 */ + __IOM uint32_t TRIG_SEL6 : 2; /*!< [13..12] Trigger Selection 6 */ + __IOM uint32_t TRIG_SEL7 : 2; /*!< [15..14] Trigger Selection 7 */ + __IOM uint32_t TRIG_SEL8 : 2; /*!< [17..16] Trigger Selection 8 */ + __IOM uint32_t TRIG_SEL9 : 2; /*!< [19..18] Trigger Selection 9 */ + __IOM uint32_t TRIG_SEL10 : 2; /*!< [21..20] Trig Selection 10 */ + __IOM uint32_t TRIG_SEL11 : 2; /*!< [23..22] Trigger Selection 11 */ + __IOM uint32_t TRIG_SEL12 : 2; /*!< [25..24] Trigger Selection 12 */ + __IOM uint32_t TRIG_SEL13 : 2; /*!< [27..26] Trigger Selection 13 */ + __IOM uint32_t TRIG_SEL14 : 2; /*!< [29..28] Trigger Selection 14 */ + __IOM uint32_t TRIG_SEL15 : 2; /*!< [31..30] Trig Selection 15 */ + } TRGSEL_b; + } ; + + union { + __IOM uint32_t BKSEL; /*!< (@ 0x00000050) Brake Source (from ADC) Control Register */ + + struct { + __IOM uint32_t BK1_CH : 4; /*!< [3..0] Select a channel as brake source 1 */ + __IOM uint32_t BK1_FLT : 2; /*!< [5..4] Filter the brake source 1 */ + __IOM uint32_t BK1_EN : 2; /*!< [7..6] Enable ondition of brake */ + __IOM uint32_t BK2_CH : 4; /*!< [11..8] Select a channel as brake source 2 */ + __IOM uint32_t BK2_FLT : 2; /*!< [13..12] Filter the brake source 2 */ + __IOM uint32_t BK2_EN : 2; /*!< [15..14] Enable ondition of brake */ + uint32_t : 16; + } BKSEL_b; + } ; + + union { + __IOM uint32_t BAKDAT; /*!< (@ 0x00000054) Data Register of ADC Conversion backup value */ + + struct { + __IM uint32_t BAKDAT : 16; /*!< [15..0] backup Data */ + uint32_t : 16; + } BAKDAT_b; + } ; +} ADC_Type; /*!< Size = 88 (0x58) */ + + + +/* =========================================================================================================================== */ +/* ================ AMISC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Analog MISC controller (AMISC) + */ + +typedef struct { /*!< (@ 0x40005800) AMISC Structure */ + + union { + __IOM uint32_t LVD_LVR_CR; /*!< (@ 0x00000000) LVD/LVR Control Register */ + + struct { + __IOM uint32_t LVD_EN : 1; /*!< [0..0] LVD enable */ + __IOM uint32_t LDO_LP_EN : 1; /*!< [1..1] LDO lower power enable */ + __IOM uint32_t LVD_F_SEL : 2; /*!< [3..2] LVD Filter Selection */ + uint32_t : 1; + __IOM uint32_t LVD_SEL : 3; /*!< [7..5] LVD selection */ + __IOM uint32_t LVR_EN : 1; /*!< [8..8] LVR enable */ + __IOM uint32_t LVD_INT_EN : 1; /*!< [9..9] LVD interrupt enable */ + __IOM uint32_t TEMP_EN : 1; /*!< [10..10] Temperature enable */ + __IM uint32_t LVD_STATE : 1; /*!< [11..11] LVD state, 0: VDD < LVD_SEL, 1: VDD > LVD_SEL */ + uint32_t : 1; + __IOM uint32_t LVR_SEL : 3; /*!< [15..13] LVR selection */ + uint32_t : 16; + } LVD_LVR_CR_b; + } ; + + union { + __IOM uint32_t VBUF_CR; /*!< (@ 0x00000004) Vbuf Control Register */ + + struct { + __IOM uint32_t VBUF_EN : 1; /*!< [0..0] VBUF enable */ + uint32_t : 3; + __IOM uint32_t ANA2IO_EN : 1; /*!< [4..4] Test analog signal to I/O */ + __IOM uint32_t ANA2PGA_EN : 1; /*!< [5..5] Test analog signal to PGA0 */ + __IOM uint32_t ANA_SEL : 7; /*!< [12..6] Test analog signal selection */ + uint32_t : 19; + } VBUF_CR_b; + } ; + __IM uint32_t RESERVED[2]; + + union { + __IOM uint32_t DAC_CR; /*!< (@ 0x00000010) DAC Control Register */ + + struct { + __IOM uint32_t DAC0Step : 10; /*!< [9..0] The step of voltage */ + __IOM uint32_t DAC1Step : 10; /*!< [19..10] The step of voltage */ + __IOM uint32_t DAC0_EN : 1; /*!< [20..20] DAC0 enable */ + __IOM uint32_t DAC1_EN : 1; /*!< [21..21] DAC1 enable */ + uint32_t : 10; + } DAC_CR_b; + } ; + __IM uint32_t RESERVED1[3]; + + union { + __IOM uint32_t HSI_CR; /*!< (@ 0x00000020) HSI (OSCHF) Control Register */ + + struct { + __IOM uint32_t LDO_SEL : 16; /*!< [15..0] HSI power source selection */ + uint32_t : 8; + __IOM uint32_t HSI_EN : 8; /*!< [31..24] HSI enable, set 0x80(disable), set 0x1(enable) */ + } HSI_CR_b; + } ; + + union { + __IOM uint32_t LSI_CR; /*!< (@ 0x00000024) LSI (OSCLF) Control Register */ + + struct { + uint32_t : 24; + __IOM uint32_t LSI_EN : 8; /*!< [31..24] LSI enable, set 0x80(disable), set 0x1(enable) */ + } LSI_CR_b; + } ; + __IM uint32_t RESERVED2[2]; + + union { + __IOM uint32_t ADC_AIN_CR; /*!< (@ 0x00000030) ADC AIN Control Register */ + + struct { + __IOM uint32_t ANA2ADC_EN : 1; /*!< [0..0] Enable ADC AIN15 from internal source */ + uint32_t : 31; + } ADC_AIN_CR_b; + } ; +} AMISC_Type; /*!< Size = 52 (0x34) */ + + + +/* =========================================================================================================================== */ +/* ================ HWTRIM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief H/w configure trim values (HWTRIM) + */ + +typedef struct { /*!< (@ 0x40005860) HWTRIM Structure */ + + union { + __IM uint32_t LDO_TRIM; /*!< (@ 0x00000000) LDO trim value */ + + struct { + __IM uint32_t LDO_TRIM : 5; /*!< [4..0] LDO trim value */ + __IM uint32_t LDO_LP_TRIM : 5; /*!< [9..5] LDO lower power trim value */ + __IM uint32_t LDO_TUNE : 2; /*!< [11..10] Ldo high temp leakage current compensation */ + uint32_t : 20; + } LDO_TRIM_b; + } ; + + union { + __IM uint32_t VBUF_TRIM; /*!< (@ 0x00000004) Vbuf trim value */ + + struct { + __IM uint32_t VBUF_TRIM : 7; /*!< [6..0] VBUF voltage trim value */ + uint32_t : 25; + } VBUF_TRIM_b; + } ; + + union { + __IM uint32_t HSI_TRIM; /*!< (@ 0x00000008) High Speed Internal clock (OSCHF) trim value */ + + struct { + __IM uint32_t HSI_D_CFG : 9; /*!< [8..0] HSI low trim config */ + __IM uint32_t HSI_FSEL_CFG : 7; /*!< [15..9] HSI high trim config */ + __IM uint32_t HSI_TC : 2; /*!< [17..16] The TC of HSI trim value */ + uint32_t : 14; + } HSI_TRIM_b; + } ; + + union { + __IM uint32_t LSI_TRIM; /*!< (@ 0x0000000C) Low Speed Internal clock (OSCLF) trim value */ + + struct { + __IM uint32_t LSI_TRIM : 8; /*!< [7..0] The LSI trim value, 0xB3= 32KHz */ + uint32_t : 24; + } LSI_TRIM_b; + } ; + + union { + __IM uint32_t MISC_CFG; /*!< (@ 0x00000010) The miscellaneous configuration */ + + struct { + __IM uint32_t EXT_nRST_EN : 1; /*!< [0..0] External reset pin enable */ + uint32_t : 31; + } MISC_CFG_b; + } ; +} HWTRIM_Type; /*!< Size = 20 (0x14) */ + + + +/* =========================================================================================================================== */ +/* ================ CRC ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Cyclic redundancy check (CRC) + */ + +typedef struct { /*!< (@ 0x4001E000) CRC Structure */ + + union { + __IOM uint32_t CR; /*!< (@ 0x00000000) Control Register */ + + struct { + __IOM uint32_t POLYSEL : 1; /*!< [0..0] CRC polynomial codes select */ + __IM uint32_t VERF : 1; /*!< [1..1] flag of verificaion CRC value */ + uint32_t : 30; + } CR_b; + } ; + + union { + __IOM uint32_t DIN; /*!< (@ 0x00000004) CRC Data input Register */ + + struct { + __IOM uint32_t DIN : 32; /*!< [31..0] Input Data */ + } DIN_b; + } ; + + union { + __IOM uint32_t DOUT; /*!< (@ 0x00000008) Result output register */ + + struct { + __IOM uint32_t DOUT : 32; /*!< [31..0] CRC value */ + } DOUT_b; + } ; +} CRC_Type; /*!< Size = 12 (0xc) */ + + + +/* =========================================================================================================================== */ +/* ================ DSP ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief DSP hardware speedup (DSP) + */ + +typedef struct { /*!< (@ 0x40008000) DSP Structure */ + + union { + __IOM uint32_t CR; /*!< (@ 0x00000000) DSP ACCEL Control Register */ + + struct { + __IOM uint32_t MODE : 3; /*!< [2..0] Mode selection */ + uint32_t : 29; + } CR_b; + } ; + + union { + __IM uint32_t SR; /*!< (@ 0x00000004) DSP ACCEL Status Register */ + + struct { + __IM uint32_t DONE : 1; /*!< [0..0] DSP End */ + uint32_t : 31; + } SR_b; + } ; + __IOM uint32_t SDAT1; /*!< (@ 0x00000008) DSP ACCEL Source Data1 */ + __IM uint32_t RESERVED; + __IOM uint32_t SDAT2; /*!< (@ 0x00000010) DSP ACCEL Source Data2 */ + __IM uint32_t RESERVED1; + __IM uint32_t RSLT1; /*!< (@ 0x00000018) DSP ACCEL Result 1 */ + __IM uint32_t RESERVED2; + __IM uint32_t RSLT2; /*!< (@ 0x00000020) DSP ACCEL Result 2 */ +} DSP_Type; /*!< Size = 36 (0x24) */ + + + +/* =========================================================================================================================== */ +/* ================ OPAMP ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief OP-Amplifiers with PGA mode (OPAMP) + */ + +typedef struct { /*!< (@ 0x40005880) OPAMP Structure */ + + union { + __IOM uint32_t PGA_CR; /*!< (@ 0x00000000) Control Register */ + + struct { + __IOM uint32_t PGA_EN : 1; /*!< [0..0] Enable PGA */ + __IOM uint32_t PGA_IO_EN : 1; /*!< [1..1] Enable PGA output to I/O */ + __IOM uint32_t PGA_GAIN : 6; /*!< [7..2] PGA gain selection */ + uint32_t : 2; + __IOM uint32_t PGA_VIN_SEL : 1; /*!< [10..10] PGA N terminal selection */ + __IOM uint32_t PGA_VIP_SEL : 1; /*!< [11..11] PGA P terminal selection */ + uint32_t : 20; + } PGA_CR_b; + } ; +} OPAMP_Type; /*!< Size = 4 (0x4) */ + + + +/* =========================================================================================================================== */ +/* ================ COMP ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Analog Comparator (COMP) + */ + +typedef struct { /*!< (@ 0x40008800) COMP Structure */ + + union { + __IOM uint32_t CTRL; /*!< (@ 0x00000000) COMP Control Register */ + + struct { + __IOM uint32_t EN : 1; /*!< [0..0] COMP Enable */ + __IM uint32_t COUT : 1; /*!< [1..1] COMP Output */ + __IOM uint32_t VIN_SEL : 2; /*!< [3..2] Comp n terminal input selection */ + __IOM uint32_t FIL_CTRL : 4; /*!< [7..4] Filter selction */ + __IOM uint32_t HYS_EN : 1; /*!< [8..8] hysteresis enable */ + uint32_t : 2; + __IOM uint32_t OUT_EN : 1; /*!< [11..11] Comp output signal */ + __IOM uint32_t POL_SEL : 1; /*!< [12..12] Select output polarity */ + uint32_t : 19; + } CTRL_b; + } ; + + union { + __IOM uint32_t VIPSEL; /*!< (@ 0x00000004) COMP P terminal DAC Register */ + + struct { + __IOM uint32_t VIP_SEL : 5; /*!< [4..0] Comp p terminal input selection */ + uint32_t : 27; + } VIPSEL_b; + } ; + + union { + __IOM uint32_t IR; /*!< (@ 0x00000008) COMP Interrupt Register */ + + struct { + __IOM uint32_t FIE : 1; /*!< [0..0] Enable Comp Interrupt with Falling */ + __IOM uint32_t RIE : 1; /*!< [1..1] Enable Comp Interrupt with Rising */ + uint32_t : 30; + } IR_b; + } ; + + union { + __IOM uint32_t IF; /*!< (@ 0x0000000C) COMP Interrupt Flag Register */ + + struct { + __IOM uint32_t FIF : 1; /*!< [0..0] Interrupt Falling Flag, W1C */ + __IOM uint32_t RIF : 1; /*!< [1..1] Interrupt Rising Flag, W1C */ + uint32_t : 30; + } IF_b; + } ; + + union { + __IOM uint32_t INITCNT; /*!< (@ 0x00000010) COMP set initial delay register */ + + struct { + __IOM uint32_t INIT_DELAY : 10; /*!< [9..0] Comp Set Delay */ + uint32_t : 22; + } INITCNT_b; + } ; +} COMP_Type; /*!< Size = 20 (0x14) */ + + + +/* =========================================================================================================================== */ +/* ================ TIM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Timer Controller Module (TIM) + */ + +typedef struct { /*!< (@ 0x4000C000) TIM Structure */ + + union { + __IOM uint32_t CR1; /*!< (@ 0x00000000) Control Register 1 */ + + struct { + __IOM uint32_t CEN : 1; /*!< [0..0] Counter enable */ + __IOM uint32_t UDIS : 1; /*!< [1..1] Update disable */ + __IOM uint32_t URS : 1; /*!< [2..2] Update request source */ + __IOM uint32_t OPM : 1; /*!< [3..3] One pulse spurce */ + __IOM uint32_t DIR : 1; /*!< [4..4] Direction */ + __IOM uint32_t CMS : 2; /*!< [6..5] Center-aligned mode selection */ + __IOM uint32_t ARPE : 1; /*!< [7..7] Auto-reload preload enable */ + __IOM uint32_t CKD : 2; /*!< [9..8] Clock division */ + __IOM uint32_t ASYMEN : 1; /*!< [10..10] Asymmetric mode enable */ + uint32_t : 21; + } CR1_b; + } ; + + union { + __IOM uint32_t CR2; /*!< (@ 0x00000004) Control Register 2 */ + + struct { + __IOM uint32_t CCPC : 1; /*!< [0..0] Capture/compare preloaded control */ + uint32_t : 1; + __IOM uint32_t CCUS : 1; /*!< [2..2] Capture/compare control update selection */ + uint32_t : 1; + __IOM uint32_t MMS : 3; /*!< [6..4] Master mode selection */ + __IOM uint32_t TI1S : 1; /*!< [7..7] TI1 selection */ + __IOM uint32_t OIS1 : 1; /*!< [8..8] Output Idle state 1 */ + __IOM uint32_t OIS1N : 1; /*!< [9..9] Output Idle state 1 */ + __IOM uint32_t OIS2 : 1; /*!< [10..10] Output Idle state 2 */ + __IOM uint32_t OIS2N : 1; /*!< [11..11] Output Idle state 2 */ + __IOM uint32_t OIS3 : 1; /*!< [12..12] Output Idle state 3 */ + __IOM uint32_t OIS3N : 1; /*!< [13..13] Output Idle state 3 */ + __IOM uint32_t OIS4 : 1; /*!< [14..14] Output Idle state 4 */ + uint32_t : 17; + } CR2_b; + } ; + + union { + __IOM uint32_t SMCR; /*!< (@ 0x00000008) Slave Mode control Register */ + + struct { + __IOM uint32_t SMS : 3; /*!< [2..0] Slave mode selection */ + uint32_t : 1; + __IOM uint32_t TS : 3; /*!< [6..4] Trigger selection */ + __IOM uint32_t MSM : 1; /*!< [7..7] Master/slave mode */ + __IOM uint32_t ETF : 4; /*!< [11..8] External trigger filter */ + __IOM uint32_t ETPS : 2; /*!< [13..12] External trigger prescaler */ + __IOM uint32_t ECE : 1; /*!< [14..14] External clock enable */ + __IOM uint32_t ETP : 1; /*!< [15..15] External trigger polarity */ + uint32_t : 16; + } SMCR_b; + } ; + + union { + __IOM uint32_t DIER; /*!< (@ 0x0000000C) interrupt enbale register */ + + struct { + __IOM uint32_t UIE : 1; /*!< [0..0] Update interrupt enable */ + __IOM uint32_t CC1IE : 1; /*!< [1..1] Capture/Compare 1 interrupt enable */ + __IOM uint32_t CC2IE : 1; /*!< [2..2] Capture/Compare 2 interrupt enable */ + __IOM uint32_t CC3IE : 1; /*!< [3..3] Capture/Compare 3 interrupt enable */ + __IOM uint32_t CC4IE : 1; /*!< [4..4] Capture/Compare 4 interrupt enable */ + __IOM uint32_t COMIE : 1; /*!< [5..5] COM interrupt enable */ + __IOM uint32_t TIE : 1; /*!< [6..6] Trigger interrupt enable */ + __IOM uint32_t BIE : 1; /*!< [7..7] Break interrupt enable */ + __IOM uint32_t CCD1IE : 1; /*!< [8..8] Capture/Compare 1 interrupt enable */ + __IOM uint32_t CCD2IE : 1; /*!< [9..9] Capture/Compare 2 interrupt enable */ + __IOM uint32_t CCD3IE : 1; /*!< [10..10] Capture/Compare 3 interrupt enable */ + __IOM uint32_t OVIE : 1; /*!< [11..11] Overflow interrupt enable */ + __IOM uint32_t UDIE : 1; /*!< [12..12] Underflow interrupt enable */ + __IOM uint32_t CCD4IE : 1; /*!< [13..13] Capture/Compare 4 interrupt enable */ + uint32_t : 18; + } DIER_b; + } ; + + union { + __IOM uint32_t SR; /*!< (@ 0x00000010) state Register */ + + struct { + __IOM uint32_t UIF : 1; /*!< [0..0] Update interrupt flag */ + __IOM uint32_t CC1IF : 1; /*!< [1..1] Capture/Compare 1 interrupt flag */ + __IOM uint32_t CC2IF : 1; /*!< [2..2] Capture/Compare 2 interrupt flag */ + __IOM uint32_t CC3IF : 1; /*!< [3..3] Capture/Compare 3 interrupt flag */ + __IOM uint32_t CC4IF : 1; /*!< [4..4] Capture/Compare 4 interrupt flag */ + __IOM uint32_t COMIF : 1; /*!< [5..5] COM interrupt flag */ + __IOM uint32_t TIF : 1; /*!< [6..6] Trigger interrupt flag */ + __IOM uint32_t BIF : 1; /*!< [7..7] Break interrupt flag */ + uint32_t : 1; + __IOM uint32_t CC1OF : 1; /*!< [9..9] CC1OF */ + __IOM uint32_t CC2OF : 1; /*!< [10..10] CC2OF */ + __IOM uint32_t CC3OF : 1; /*!< [11..11] CC3OF */ + __IOM uint32_t CC4OF : 1; /*!< [12..12] CC4OF */ + __IOM uint32_t CCD1IF : 1; /*!< [13..13] Capture/Compare 1 interrupt flag */ + __IOM uint32_t CCD2IF : 1; /*!< [14..14] Capture/Compare 2 interrupt flag */ + __IOM uint32_t CCD3IF : 1; /*!< [15..15] Capture/Compare 3 interrupt flag */ + __IOM uint32_t OVIF : 1; /*!< [16..16] Overflow interrupt flag */ + __IOM uint32_t UDIF : 1; /*!< [17..17] Underflow interrupt flag */ + __IOM uint32_t CCD4IF : 1; /*!< [18..18] Break interrupt flag */ + uint32_t : 13; + } SR_b; + } ; + + union { + __IOM uint32_t EGR; /*!< (@ 0x00000014) event generation Register */ + + struct { + __IOM uint32_t UG : 1; /*!< [0..0] Update generation */ + __IOM uint32_t CC1G : 1; /*!< [1..1] Capture/Compare 1 generation */ + __IOM uint32_t CC2G : 1; /*!< [2..2] Capture/Compare 2 generation */ + __IOM uint32_t CC3G : 1; /*!< [3..3] Capture/Compare 3 generation */ + __IOM uint32_t CC4G : 1; /*!< [4..4] Capture/Compare 4 generation */ + __IOM uint32_t COMG : 1; /*!< [5..5] Capture/Compare control update generation */ + __IOM uint32_t TG : 1; /*!< [6..6] Trigger generation */ + __IOM uint32_t BG : 1; /*!< [7..7] Break generation */ + uint32_t : 24; + } EGR_b; + } ; + + union { + union { + __IOM uint32_t CCMR1_OUTPUT; /*!< (@ 0x00000018) Capture or Compare mode Register (Output mode) */ + + struct { + __IOM uint32_t CC1S : 2; /*!< [1..0] Capture/Compare 1 selection */ + __IOM uint32_t OC1FE : 1; /*!< [2..2] Output Compare 1 fast enable */ + __IOM uint32_t OC1PE : 1; /*!< [3..3] Output Compare 1 preload enable */ + __IOM uint32_t OC1M : 3; /*!< [6..4] Output Compare 1 mode */ + __IOM uint32_t OC1CE : 1; /*!< [7..7] Output Compare 1 clear enable */ + __IOM uint32_t CC2S : 2; /*!< [9..8] Capture/Compare 2 selection */ + __IOM uint32_t OC2FE : 1; /*!< [10..10] Output Compare 2 fast enable */ + __IOM uint32_t OC2PE : 1; /*!< [11..11] Output Compare 2 preload enable */ + __IOM uint32_t OC2M : 3; /*!< [14..12] Output Compare 2 mode */ + __IOM uint32_t OC2CE : 1; /*!< [15..15] Output Compare 2 clear enable */ + uint32_t : 16; + } CCMR1_OUTPUT_b; + } ; + + union { + __IOM uint32_t CCMR1_INPUT; /*!< (@ 0x00000018) Capture or Compare mode Register (Input mode) */ + + struct { + __IOM uint32_t CC1S : 2; /*!< [1..0] Capture or Compare 1 Select */ + __IOM uint32_t IC1PSC : 2; /*!< [3..2] Input capture 1 prescaler */ + __IOM uint32_t IC1F : 4; /*!< [7..4] Input capture 1 filter */ + __IOM uint32_t CC2S : 2; /*!< [9..8] Capture or Compare 2 Select */ + __IOM uint32_t IC2PSC : 2; /*!< [11..10] Input capture 2 prescaler */ + __IOM uint32_t IC2F : 4; /*!< [15..12] Input capture 2 filter */ + uint32_t : 16; + } CCMR1_INPUT_b; + } ; + }; + + union { + union { + __IOM uint32_t CCMR2_OUTPUT; /*!< (@ 0x0000001C) Capture or Compare mode Register (output mode) */ + + struct { + __IOM uint32_t CC3S : 2; /*!< [1..0] Capture/Compare 3 selection */ + __IOM uint32_t OC3FE : 1; /*!< [2..2] Output Compare 3 fast enable */ + __IOM uint32_t OC3PE : 1; /*!< [3..3] Output Compare 3 preload enable */ + __IOM uint32_t OC3M : 3; /*!< [6..4] Output Compare 3 mode */ + __IOM uint32_t OC3CE : 1; /*!< [7..7] Output Compare 3 clear enable */ + __IOM uint32_t CC4S : 2; /*!< [9..8] Capture/Compare 4 selection */ + __IOM uint32_t OC4FE : 1; /*!< [10..10] Output Compare 4 fast enable */ + __IOM uint32_t OC4PE : 1; /*!< [11..11] Output Compare 4 preload enable */ + __IOM uint32_t OC4M : 3; /*!< [14..12] Output Compare 4 mode */ + __IOM uint32_t OC4CE : 1; /*!< [15..15] Output Compare 4 clear enable */ + uint32_t : 16; + } CCMR2_OUTPUT_b; + } ; + + union { + __IOM uint32_t CCMR2_INPUT; /*!< (@ 0x0000001C) Capture or Compare mode Register (input mode) */ + + struct { + __IOM uint32_t CC3S : 2; /*!< [1..0] Capture or Compare 3 Select */ + __IOM uint32_t IC3PSC : 2; /*!< [3..2] Input capture 3 prescaler */ + __IOM uint32_t IC3F : 4; /*!< [7..4] Input capture 3 filter */ + __IOM uint32_t CC4S : 2; /*!< [9..8] Capture or Compare 4 Select */ + __IOM uint32_t IC4PSC : 2; /*!< [11..10] Input capture 4 prescaler */ + __IOM uint32_t IC4F : 4; /*!< [15..12] Input capture 4 filter */ + uint32_t : 16; + } CCMR2_INPUT_b; + } ; + }; + + union { + __IOM uint32_t CCER; /*!< (@ 0x00000020) Capture or Compare enable Register */ + + struct { + __IOM uint32_t CC1E : 1; /*!< [0..0] Capture/Compare 1 output enable */ + __IOM uint32_t CC1P : 1; /*!< [1..1] Capture/Compare 1 output polarity */ + __IOM uint32_t CC1NE : 1; /*!< [2..2] Capture/Compare 1 complementary output enable */ + __IOM uint32_t CC1NP : 1; /*!< [3..3] Capture/Compare 1 complementary output polarity */ + __IOM uint32_t CC2E : 1; /*!< [4..4] Capture/Compare 2 output enable */ + __IOM uint32_t CC2P : 1; /*!< [5..5] Capture/Compare 2 output polarity */ + __IOM uint32_t CC2NE : 1; /*!< [6..6] Capture/Compare 2 complementary output enable */ + __IOM uint32_t CC2NP : 1; /*!< [7..7] Capture/Compare 2 complementary output polarity */ + __IOM uint32_t CC3E : 1; /*!< [8..8] Capture/Compare 3 output enable */ + __IOM uint32_t CC3P : 1; /*!< [9..9] Capture/Compare 3 output polarity */ + __IOM uint32_t CC3NE : 1; /*!< [10..10] Capture/Compare 3 complementary output enable */ + __IOM uint32_t CC3NP : 1; /*!< [11..11] Capture/Compare 3 complementary output polarity */ + __IOM uint32_t CC4E : 1; /*!< [12..12] Capture/Compare 4 output enable */ + __IOM uint32_t CC4P : 1; /*!< [13..13] Capture/Compare 4 output polarity */ + uint32_t : 18; + } CCER_b; + } ; + + union { + __IOM uint32_t CNT; /*!< (@ 0x00000024) EPWM counter register */ + + struct { + __IOM uint32_t CNT : 16; /*!< [15..0] Counter value */ + uint32_t : 16; + } CNT_b; + } ; + + union { + __IOM uint32_t PSC; /*!< (@ 0x00000028) Prescaler counter register */ + + struct { + __IOM uint32_t PSC : 16; /*!< [15..0] Prescaler value */ + uint32_t : 16; + } PSC_b; + } ; + + union { + __IOM uint32_t ARR; /*!< (@ 0x0000002C) Auto reload counter register */ + + struct { + __IOM uint32_t ARR : 16; /*!< [15..0] Auto reload value */ + uint32_t : 16; + } ARR_b; + } ; + + union { + __IOM uint32_t RCR; /*!< (@ 0x00000030) Repetition counter register */ + + struct { + __IOM uint32_t REP : 8; /*!< [7..0] Repetition counter value */ + uint32_t : 24; + } RCR_b; + } ; + + union { + __IOM uint32_t CCR1; /*!< (@ 0x00000034) CR1 capture or compare value */ + + struct { + __IOM uint32_t CCR1 : 20; /*!< [19..0] Capture/Compare 1 value */ + uint32_t : 12; + } CCR1_b; + } ; + + union { + __IOM uint32_t CCR2; /*!< (@ 0x00000038) CR2 capture or compare value */ + + struct { + __IOM uint32_t CCR2 : 20; /*!< [19..0] Capture/Compare 2 value */ + uint32_t : 12; + } CCR2_b; + } ; + + union { + __IOM uint32_t CCR3; /*!< (@ 0x0000003C) capture or compare value */ + + struct { + __IOM uint32_t CCR3 : 20; /*!< [19..0] Capture/Compare 3 value */ + uint32_t : 12; + } CCR3_b; + } ; + + union { + __IOM uint32_t CCR4; /*!< (@ 0x00000040) match output control */ + + struct { + __IOM uint32_t CCR4 : 20; /*!< [19..0] Capture/Compare 4 value */ + uint32_t : 12; + } CCR4_b; + } ; + + union { + __IOM uint32_t BDTR; /*!< (@ 0x00000044) Braking ande dead zone control Register */ + + struct { + __IOM uint32_t DTG : 8; /*!< [7..0] Dead-time generator setup */ + __IOM uint32_t LOCK : 2; /*!< [9..8] Lock Configuration */ + __IOM uint32_t OSSI : 1; /*!< [10..10] Off-state selection for Idle mode */ + __IOM uint32_t OSSR : 1; /*!< [11..11] Off-state selection for Run mode */ + __IOM uint32_t BKE : 1; /*!< [12..12] Break enable */ + __IOM uint32_t BKP : 1; /*!< [13..13] Break polarity */ + __IOM uint32_t AOE : 1; /*!< [14..14] Automatic output enable */ + __IOM uint32_t MOE : 1; /*!< [15..15] Main output enable */ + __IOM uint32_t DTGF : 8; /*!< [23..16] Asymmetric Dead-time generator setup */ + __IOM uint32_t DTAE : 1; /*!< [24..24] Asymmetric Dead-time enable */ + uint32_t : 7; + } BDTR_b; + } ; + __IM uint32_t RESERVED[2]; + + union { + __IOM uint32_t CCDR1; /*!< (@ 0x00000050) CR1 down capture or compare value */ + + struct { + __IOM uint32_t CCDR1 : 20; /*!< [19..0] Down Capture/Compare 1 value */ + uint32_t : 12; + } CCDR1_b; + } ; + + union { + __IOM uint32_t CCDR2; /*!< (@ 0x00000054) CR2 down capture or compare value */ + + struct { + __IOM uint32_t CCDR2 : 20; /*!< [19..0] Down Capture/Compare 2 value */ + uint32_t : 12; + } CCDR2_b; + } ; + + union { + __IOM uint32_t CCDR3; /*!< (@ 0x00000058) CR3 down capture or compare value */ + + struct { + __IOM uint32_t CCDR3 : 20; /*!< [19..0] Down Capture/Compare 3 value */ + uint32_t : 12; + } CCDR3_b; + } ; + + union { + __IOM uint32_t CCDR4; /*!< (@ 0x0000005C) CR4 down capture or compare value */ + + struct { + __IOM uint32_t CCDR4 : 20; /*!< [19..0] Down Capture/Compare 4 value */ + uint32_t : 12; + } CCDR4_b; + } ; +} TIM_Type; /*!< Size = 96 (0x60) */ + + + +/* =========================================================================================================================== */ +/* ================ LPTIM ================ */ +/* =========================================================================================================================== */ + + +/** + * @brief Low-Power Timer (LPTIM) + */ + +typedef struct { /*!< (@ 0x4000C800) LPTIM Structure */ + + union { + __IOM uint32_t IR; /*!< (@ 0x00000000) LPTIM Interrupt Flag Register */ + + struct { + __IOM uint32_t MR0 : 1; /*!< [0..0] MR0 match flag, writer 1 to clear */ + uint32_t : 31; + } IR_b; + } ; + + union { + __IOM uint32_t TCR; /*!< (@ 0x00000004) LPTIM Control Register */ + + struct { + __IOM uint32_t CEN : 1; /*!< [0..0] LPTIM Module Enable */ + __IOM uint32_t CRST : 1; /*!< [1..1] LPTIM Module Reset */ + __IOM uint32_t CLKS : 2; /*!< [3..2] LPTIM Clock Selection */ + __IOM uint32_t TRIGSEL : 3; /*!< [6..4] Trigger LPTIM selector */ + uint32_t : 25; + } TCR_b; + } ; + + union { + __IOM uint32_t TC; /*!< (@ 0x00000008) LPTIM Current Counter value Register */ + + struct { + __IOM uint32_t TC : 16; /*!< [15..0] Current Counter value */ + uint32_t : 16; + } TC_b; + } ; + + union { + __IOM uint32_t PR; /*!< (@ 0x0000000C) LPTIM Prescaler Register */ + + struct { + __IOM uint32_t PR : 8; /*!< [7..0] Prescaler value, fTIM=fsys/(PR+1) */ + uint32_t : 24; + } PR_b; + } ; + + union { + __IOM uint32_t PC; /*!< (@ 0x00000010) Prescaler current value Register */ + + struct { + __IOM uint32_t PC : 8; /*!< [7..0] Prescaler current value */ + uint32_t : 24; + } PC_b; + } ; + + union { + __IOM uint32_t MCR; /*!< (@ 0x00000014) LPTIM match control Register */ + + struct { + __IOM uint32_t MR0INT : 1; /*!< [0..0] Enable interrupt when match counter */ + __IOM uint32_t MR0RST : 1; /*!< [1..1] Enable reset when match counter */ + __IOM uint32_t MR0STOP : 1; /*!< [2..2] Enable stop when match counter */ + uint32_t : 29; + } MCR_b; + } ; + + union { + __IOM uint32_t MR0; /*!< (@ 0x00000018) Match Register 0 */ + + struct { + __IOM uint32_t MR0 : 16; /*!< [15..0] Match compare value */ + uint32_t : 16; + } MR0_b; + } ; +} LPTIM_Type; /*!< Size = 28 (0x1c) */ + + +/** @} */ /* End of group Device_Peripheral_peripherals */ + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Address Map ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_peripheralAddr + * @{ + */ + +#define EFLASH_MEM_BASE 0x00000000UL +#define SRAM_MEM_BASE 0x20000000UL +#define NVR_MEM_BASE 0x00200000UL +#define CORET_BASE 0x18000000UL +#define UID_BASE 0x00201F00UL +#define FLASH_BASE 0x4000F800UL +#define GPIO_BASE 0x40011000UL +#define GPIOA_BASE 0x40011000UL +#define GPIOB_BASE 0x40012000UL +#define AFIO_BASE 0x40011070UL +#define SYSCFG_BASE 0x4001F000UL +#define UART_BASE 0x40002000UL +#define UART0_BASE 0x40002000UL +#define I2C_BASE 0x40003000UL +#define I2C0_BASE 0x40003000UL +#define SPI_BASE 0x40003800UL +#define SPI0_BASE 0x40003800UL +#define WDG_BASE 0x40004000UL +#define ADC_BASE 0x40004800UL +#define ADC0_BASE 0x40004800UL +#define AMISC_BASE 0x40005800UL +#define HWTRIM_BASE 0x40005860UL +#define CRC_BASE 0x4001E000UL +#define DSP_BASE 0x40008000UL +#define OPAMP_BASE 0x40005880UL +#define OPAMP0_BASE 0x40005880UL +#define OPAMP1_BASE 0x40005888UL +#define COMP_BASE 0x40008800UL +#define COMP0_BASE 0x40008800UL +#define COMP1_BASE 0x40009800UL +#define TIM_BASE 0x4000C000UL +#define EPWM_BASE 0x4000C000UL +#define TIM2_BASE 0x40001000UL +#define LPTIM_BASE 0x4000C800UL +#define TIM0_BASE 0x40000000UL +#define TIM1_BASE 0x40000800UL + +/** @} */ /* End of group Device_Peripheral_peripheralAddr */ + + +/* =========================================================================================================================== */ +/* ================ Peripheral declaration ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup Device_Peripheral_declaration + * @{ + */ + +#define EFLASH_MEM ((EFLASH_MEM_Type*) EFLASH_MEM_BASE) +#define SRAM_MEM ((SRAM_MEM_Type*) SRAM_MEM_BASE) +#define NVR_MEM ((NVR_MEM_Type*) NVR_MEM_BASE) +#define CORET ((CORET_Type*) CORET_BASE) +#define UID ((UID_Type*) UID_BASE) +#define FLASH ((FLASH_Type*) FLASH_BASE) +#define GPIO ((GPIO_Type*) GPIO_BASE) +#define GPIOA ((GPIO_Type*) GPIOA_BASE) +#define GPIOB ((GPIO_Type*) GPIOB_BASE) +#define AFIO ((AFIO_Type*) AFIO_BASE) +#define SYSCFG ((SYSCFG_Type*) SYSCFG_BASE) +#define UART ((UART_Type*) UART_BASE) +#define UART0 ((UART_Type*) UART0_BASE) +#define I2C ((I2C_Type*) I2C_BASE) +#define I2C0 ((I2C_Type*) I2C0_BASE) +#define SPI ((SPI_Type*) SPI_BASE) +#define SPI0 ((SPI_Type*) SPI0_BASE) +#define WDG ((WDG_Type*) WDG_BASE) +#define ADC ((ADC_Type*) ADC_BASE) +#define ADC0 ((ADC_Type*) ADC0_BASE) +#define AMISC ((AMISC_Type*) AMISC_BASE) +#define HWTRIM ((HWTRIM_Type*) HWTRIM_BASE) +#define CRC ((CRC_Type*) CRC_BASE) +#define DSP ((DSP_Type*) DSP_BASE) +#define OPAMP ((OPAMP_Type*) OPAMP_BASE) +#define OPAMP0 ((OPAMP_Type*) OPAMP0_BASE) +#define OPAMP1 ((OPAMP_Type*) OPAMP1_BASE) +#define COMP ((COMP_Type*) COMP_BASE) +#define COMP0 ((COMP_Type*) COMP0_BASE) +#define COMP1 ((COMP_Type*) COMP1_BASE) +#define TIM ((TIM_Type*) TIM_BASE) +#define EPWM ((TIM_Type*) EPWM_BASE) +#define TIM2 ((TIM_Type*) TIM2_BASE) +#define LPTIM ((LPTIM_Type*) LPTIM_BASE) +#define TIM0 ((LPTIM_Type*) TIM0_BASE) +#define TIM1 ((LPTIM_Type*) TIM1_BASE) + +/** @} */ /* End of group Device_Peripheral_declaration */ + + +/* ========================================= End of section using anonymous unions ========================================= */ +#if defined (__GNUC__) + /* anonymous unions are enabled by default */ +#endif + + +/* =========================================================================================================================== */ +/* ================ Pos/Mask Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup PosMask_peripherals + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ EFLASH_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ SRAM_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ NVR_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ CORET ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= revd ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ UID ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= UID1 ========================================================== */ +/* ========================================================= UID2 ========================================================== */ +/* ========================================================= UID3 ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ FLASH ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CMD ========================================================== */ +#define FLASH_CMD_START_Pos (0UL) /*!< START (Bit 0) */ +#define FLASH_CMD_START_Msk (0x1UL) /*!< START (Bitfield-Mask: 0x01) */ +#define FLASH_CMD_CMD_Pos (1UL) /*!< CMD (Bit 1) */ +#define FLASH_CMD_CMD_Msk (0xeUL) /*!< CMD (Bitfield-Mask: 0x07) */ +#define FLASH_CMD_NWS_Pos (5UL) /*!< NWS (Bit 5) */ +#define FLASH_CMD_NWS_Msk (0xe0UL) /*!< NWS (Bitfield-Mask: 0x07) */ +#define FLASH_CMD_UNLOCK_Pos (8UL) /*!< UNLOCK (Bit 8) */ +#define FLASH_CMD_UNLOCK_Msk (0x100UL) /*!< UNLOCK (Bitfield-Mask: 0x01) */ +#define FLASH_CMD_ACME_Pos (9UL) /*!< ACME (Bit 9) */ +#define FLASH_CMD_ACME_Msk (0x200UL) /*!< ACME (Bitfield-Mask: 0x01) */ +#define FLASH_CMD_ACMR_Pos (10UL) /*!< ACMR (Bit 10) */ +#define FLASH_CMD_ACMR_Msk (0x400UL) /*!< ACMR (Bitfield-Mask: 0x01) */ +#define FLASH_CMD_AINC_Pos (13UL) /*!< AINC (Bit 13) */ +#define FLASH_CMD_AINC_Msk (0x2000UL) /*!< AINC (Bitfield-Mask: 0x01) */ +#define FLASH_CMD_KEY_Pos (16UL) /*!< KEY (Bit 16) */ +#define FLASH_CMD_KEY_Msk (0xffff0000UL) /*!< KEY (Bitfield-Mask: 0xffff) */ +/* ========================================================== SR =========================================================== */ +#define FLASH_SR_CMD_END_Pos (0UL) /*!< CMD_END (Bit 0) */ +#define FLASH_SR_CMD_END_Msk (0x1UL) /*!< CMD_END (Bitfield-Mask: 0x01) */ +#define FLASH_SR_KEY_ERR_Pos (1UL) /*!< KEY_ERR (Bit 1) */ +#define FLASH_SR_KEY_ERR_Msk (0x2UL) /*!< KEY_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_ACC_ERR_Pos (2UL) /*!< ACC_ERR (Bit 2) */ +#define FLASH_SR_ACC_ERR_Msk (0x4UL) /*!< ACC_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_ADDR_ERR_Pos (3UL) /*!< ADDR_ERR (Bit 3) */ +#define FLASH_SR_ADDR_ERR_Msk (0x8UL) /*!< ADDR_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_HCM_Pos (6UL) /*!< HCM (Bit 6) */ +#define FLASH_SR_HCM_Msk (0x40UL) /*!< HCM (Bitfield-Mask: 0x01) */ +#define FLASH_SR_HSI_TC_ERR_Pos (7UL) /*!< HSI_TC_ERR (Bit 7) */ +#define FLASH_SR_HSI_TC_ERR_Msk (0x80UL) /*!< HSI_TC_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_PROTCT_R2_ERR_Pos (8UL) /*!< PROTCT_R2_ERR (Bit 8) */ +#define FLASH_SR_PROTCT_R2_ERR_Msk (0x100UL) /*!< PROTCT_R2_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_PROTCT_R1_ERR_Pos (9UL) /*!< PROTCT_R1_ERR (Bit 9) */ +#define FLASH_SR_PROTCT_R1_ERR_Msk (0x200UL) /*!< PROTCT_R1_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_RSTIO_AF_ERR_Pos (10UL) /*!< RSTIO_AF_ERR (Bit 10) */ +#define FLASH_SR_RSTIO_AF_ERR_Msk (0x400UL) /*!< RSTIO_AF_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_LDO_TRIM_ERR_Pos (11UL) /*!< LDO_TRIM_ERR (Bit 11) */ +#define FLASH_SR_LDO_TRIM_ERR_Msk (0x800UL) /*!< LDO_TRIM_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_VBUF_TRIM_ERR_Pos (12UL) /*!< VBUF_TRIM_ERR (Bit 12) */ +#define FLASH_SR_VBUF_TRIM_ERR_Msk (0x1000UL) /*!< VBUF_TRIM_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_LSI_TRIM_ERR_Pos (13UL) /*!< LSI_TRIM_ERR (Bit 13) */ +#define FLASH_SR_LSI_TRIM_ERR_Msk (0x2000UL) /*!< LSI_TRIM_ERR (Bitfield-Mask: 0x01) */ +#define FLASH_SR_HSI_TRIM_ERR_Pos (14UL) /*!< HSI_TRIM_ERR (Bit 14) */ +#define FLASH_SR_HSI_TRIM_ERR_Msk (0x4000UL) /*!< HSI_TRIM_ERR (Bitfield-Mask: 0x01) */ +/* ========================================================== AR =========================================================== */ +/* ========================================================== DR =========================================================== */ +/* ========================================================== ACM ========================================================== */ +/* ========================================================== DIV ========================================================== */ +#define FLASH_DIV_DIV_Pos (0UL) /*!< DIV (Bit 0) */ +#define FLASH_DIV_DIV_Msk (0xffUL) /*!< DIV (Bitfield-Mask: 0xff) */ + + +/* =========================================================================================================================== */ +/* ================ GPIO ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== DAT ========================================================== */ +#define GPIO_DAT_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_DAT_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_DAT_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_DAT_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_DAT_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_DAT_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_DAT_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_DAT_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_DAT_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_DAT_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_DAT_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_DAT_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_DAT_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_DAT_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_DAT_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_DAT_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_DAT_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_DAT_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== LAT ========================================================== */ +#define GPIO_LAT_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_LAT_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_LAT_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_LAT_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_LAT_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_LAT_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_LAT_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_LAT_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_LAT_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_LAT_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_LAT_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_LAT_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_LAT_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_LAT_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_LAT_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_LAT_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_LAT_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_LAT_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= ITS1 ========================================================== */ +#define GPIO_ITS1_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ITS1_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ITS1_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ITS1_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ITS1_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ITS1_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ITS1_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ITS1_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ITS1_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ITS1_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ITS1_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ITS1_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ITS1_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ITS1_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ITS1_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ITS1_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS1_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ITS1_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= ITC1 ========================================================== */ +#define GPIO_ITC1_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ITC1_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ITC1_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ITC1_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ITC1_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ITC1_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ITC1_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ITC1_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ITC1_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ITC1_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ITC1_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ITC1_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ITC1_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ITC1_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ITC1_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ITC1_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC1_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ITC1_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== OES ========================================================== */ +#define GPIO_OES_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_OES_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_OES_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_OES_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_OES_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_OES_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_OES_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_OES_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_OES_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_OES_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_OES_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_OES_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_OES_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_OES_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_OES_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_OES_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_OES_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_OES_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== OEC ========================================================== */ +#define GPIO_OEC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_OEC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_OEC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_OEC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_OEC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_OEC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_OEC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_OEC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_OEC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_OEC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_OEC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_OEC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_OEC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_OEC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_OEC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_OEC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_OEC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_OEC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= INES ========================================================== */ +#define GPIO_INES_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_INES_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_INES_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_INES_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_INES_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_INES_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_INES_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_INES_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_INES_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_INES_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_INES_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_INES_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_INES_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_INES_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_INES_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_INES_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_INES_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_INES_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= INEC ========================================================== */ +#define GPIO_INEC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_INEC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_INEC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_INEC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_INEC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_INEC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_INEC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_INEC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_INEC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_INEC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_INEC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_INEC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_INEC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_INEC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_INEC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_INEC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_INEC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_INEC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== IES ========================================================== */ +#define GPIO_IES_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_IES_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_IES_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_IES_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_IES_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_IES_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_IES_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_IES_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_IES_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_IES_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_IES_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_IES_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_IES_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_IES_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_IES_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_IES_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_IES_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_IES_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== IEC ========================================================== */ +#define GPIO_IEC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_IEC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_IEC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_IEC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_IEC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_IEC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_IEC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_IEC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_IEC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_IEC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_IEC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_IEC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_IEC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_IEC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_IEC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_IEC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_IEC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_IEC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= ITS0 ========================================================== */ +#define GPIO_ITS0_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ITS0_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ITS0_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ITS0_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ITS0_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ITS0_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ITS0_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ITS0_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ITS0_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ITS0_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ITS0_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ITS0_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ITS0_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ITS0_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ITS0_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ITS0_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ITS0_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ITS0_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= ITC0 ========================================================== */ +#define GPIO_ITC0_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ITC0_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ITC0_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ITC0_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ITC0_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ITC0_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ITC0_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ITC0_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ITC0_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ITC0_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ITC0_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ITC0_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ITC0_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ITC0_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ITC0_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ITC0_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ITC0_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ITC0_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PLS ========================================================== */ +#define GPIO_PLS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PLS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PLS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PLS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PLS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PLS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PLS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PLS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PLS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PLS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PLS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PLS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PLS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PLS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PLS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PLS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PLS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PLS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PLC ========================================================== */ +#define GPIO_PLC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PLC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PLC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PLC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PLC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PLC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PLC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PLC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PLC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PLC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PLC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PLC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PLC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PLC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PLC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PLC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PLC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PLC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== IST ========================================================== */ +#define GPIO_IST_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_IST_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_IST_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_IST_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_IST_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_IST_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_IST_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_IST_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_IST_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_IST_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_IST_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_IST_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_IST_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_IST_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_IST_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_IST_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_IST_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_IST_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PUS ========================================================== */ +#define GPIO_PUS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PUS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PUS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PUS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PUS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PUS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PUS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PUS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PUS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PUS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PUS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PUS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PUS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PUS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PUS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PUS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PUS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PUS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PUC ========================================================== */ +#define GPIO_PUC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PUC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PUC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PUC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PUC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PUC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PUC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PUC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PUC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PUC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PUC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PUC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PUC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PUC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PUC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PUC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PUC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PUC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== ODS ========================================================== */ +#define GPIO_ODS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ODS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ODS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ODS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ODS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ODS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ODS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ODS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ODS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ODS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ODS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ODS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ODS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ODS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ODS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ODS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ODS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ODS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== ODC ========================================================== */ +#define GPIO_ODC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_ODC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_ODC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_ODC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_ODC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_ODC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_ODC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_ODC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_ODC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_ODC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_ODC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_ODC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_ODC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_ODC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_ODC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_ODC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_ODC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_ODC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PDS ========================================================== */ +#define GPIO_PDS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PDS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PDS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PDS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PDS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PDS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PDS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PDS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PDS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PDS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PDS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PDS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PDS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PDS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PDS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PDS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PDS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PDS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== PDC ========================================================== */ +#define GPIO_PDC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_PDC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_PDC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_PDC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_PDC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_PDC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_PDC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_PDC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_PDC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_PDC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_PDC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_PDC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_PDC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_PDC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_PDC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_PDC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_PDC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_PDC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= OSRS ========================================================== */ +#define GPIO_OSRS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_OSRS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_OSRS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_OSRS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_OSRS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_OSRS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_OSRS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_OSRS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_OSRS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_OSRS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_OSRS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_OSRS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_OSRS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_OSRS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_OSRS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_OSRS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_OSRS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================= OSRC ========================================================== */ +#define GPIO_OSRC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_OSRC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_OSRC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_OSRC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_OSRC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_OSRC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_OSRC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_OSRC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_OSRC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_OSRC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_OSRC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_OSRC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_OSRC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_OSRC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_OSRC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_OSRC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_OSRC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_OSRC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== CTS ========================================================== */ +#define GPIO_CTS_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_CTS_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_CTS_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_CTS_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_CTS_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_CTS_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_CTS_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_CTS_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_CTS_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_CTS_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_CTS_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_CTS_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_CTS_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_CTS_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_CTS_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_CTS_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_CTS_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_CTS_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ +/* ========================================================== CTC ========================================================== */ +#define GPIO_CTC_P00_Pos (0UL) /*!< P00 (Bit 0) */ +#define GPIO_CTC_P00_Msk (0x1UL) /*!< P00 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P01_Pos (1UL) /*!< P01 (Bit 1) */ +#define GPIO_CTC_P01_Msk (0x2UL) /*!< P01 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P02_Pos (2UL) /*!< P02 (Bit 2) */ +#define GPIO_CTC_P02_Msk (0x4UL) /*!< P02 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P03_Pos (3UL) /*!< P03 (Bit 3) */ +#define GPIO_CTC_P03_Msk (0x8UL) /*!< P03 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P04_Pos (4UL) /*!< P04 (Bit 4) */ +#define GPIO_CTC_P04_Msk (0x10UL) /*!< P04 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P05_Pos (5UL) /*!< P05 (Bit 5) */ +#define GPIO_CTC_P05_Msk (0x20UL) /*!< P05 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P06_Pos (6UL) /*!< P06 (Bit 6) */ +#define GPIO_CTC_P06_Msk (0x40UL) /*!< P06 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P07_Pos (7UL) /*!< P07 (Bit 7) */ +#define GPIO_CTC_P07_Msk (0x80UL) /*!< P07 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P08_Pos (8UL) /*!< P08 (Bit 8) */ +#define GPIO_CTC_P08_Msk (0x100UL) /*!< P08 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P09_Pos (9UL) /*!< P09 (Bit 9) */ +#define GPIO_CTC_P09_Msk (0x200UL) /*!< P09 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P10_Pos (10UL) /*!< P10 (Bit 10) */ +#define GPIO_CTC_P10_Msk (0x400UL) /*!< P10 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P11_Pos (11UL) /*!< P11 (Bit 11) */ +#define GPIO_CTC_P11_Msk (0x800UL) /*!< P11 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P12_Pos (12UL) /*!< P12 (Bit 12) */ +#define GPIO_CTC_P12_Msk (0x1000UL) /*!< P12 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P13_Pos (13UL) /*!< P13 (Bit 13) */ +#define GPIO_CTC_P13_Msk (0x2000UL) /*!< P13 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P14_Pos (14UL) /*!< P14 (Bit 14) */ +#define GPIO_CTC_P14_Msk (0x4000UL) /*!< P14 (Bitfield-Mask: 0x01) */ +#define GPIO_CTC_P15_Pos (15UL) /*!< P15 (Bit 15) */ +#define GPIO_CTC_P15_Msk (0x8000UL) /*!< P15 (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ AFIO ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= PAAFR ========================================================= */ +#define AFIO_PAAFR_PA0_Pos (0UL) /*!< PA0 (Bit 0) */ +#define AFIO_PAAFR_PA0_Msk (0x7UL) /*!< PA0 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA1_Pos (3UL) /*!< PA1 (Bit 3) */ +#define AFIO_PAAFR_PA1_Msk (0x38UL) /*!< PA1 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA2_Pos (6UL) /*!< PA2 (Bit 6) */ +#define AFIO_PAAFR_PA2_Msk (0x1c0UL) /*!< PA2 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA3_Pos (9UL) /*!< PA3 (Bit 9) */ +#define AFIO_PAAFR_PA3_Msk (0xe00UL) /*!< PA3 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA4_Pos (12UL) /*!< PA4 (Bit 12) */ +#define AFIO_PAAFR_PA4_Msk (0x7000UL) /*!< PA4 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA5_Pos (15UL) /*!< PA5 (Bit 15) */ +#define AFIO_PAAFR_PA5_Msk (0x38000UL) /*!< PA5 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA14_Pos (18UL) /*!< PA14 (Bit 18) */ +#define AFIO_PAAFR_PA14_Msk (0x1c0000UL) /*!< PA14 (Bitfield-Mask: 0x07) */ +#define AFIO_PAAFR_PA15_Pos (21UL) /*!< PA15 (Bit 21) */ +#define AFIO_PAAFR_PA15_Msk (0xe00000UL) /*!< PA15 (Bitfield-Mask: 0x07) */ +/* ========================================================= PBAFR ========================================================= */ +#define AFIO_PBAFR_PB0_Pos (0UL) /*!< PB0 (Bit 0) */ +#define AFIO_PBAFR_PB0_Msk (0x7UL) /*!< PB0 (Bitfield-Mask: 0x07) */ +#define AFIO_PBAFR_PB1_Pos (3UL) /*!< PB1 (Bit 3) */ +#define AFIO_PBAFR_PB1_Msk (0x38UL) /*!< PB1 (Bitfield-Mask: 0x07) */ +#define AFIO_PBAFR_PB2_Pos (6UL) /*!< PB2 (Bit 6) */ +#define AFIO_PBAFR_PB2_Msk (0x1c0UL) /*!< PB2 (Bitfield-Mask: 0x07) */ +#define AFIO_PBAFR_PB3_Pos (9UL) /*!< PB3 (Bit 9) */ +#define AFIO_PBAFR_PB3_Msk (0xe00UL) /*!< PB3 (Bitfield-Mask: 0x07) */ +#define AFIO_PBAFR_PB4_Pos (12UL) /*!< PB4 (Bit 12) */ +#define AFIO_PBAFR_PB4_Msk (0x7000UL) /*!< PB4 (Bitfield-Mask: 0x07) */ +#define AFIO_PBAFR_PB5_Pos (15UL) /*!< PB5 (Bit 15) */ +#define AFIO_PBAFR_PB5_Msk (0x38000UL) /*!< PB5 (Bitfield-Mask: 0x07) */ +/* ======================================================== FN1_AFR ======================================================== */ +#define AFIO_FN1_AFR_BKIN_Pos (0UL) /*!< BKIN (Bit 0) */ +#define AFIO_FN1_AFR_BKIN_Msk (0xfUL) /*!< BKIN (Bitfield-Mask: 0x0f) */ +#define AFIO_FN1_AFR_ECAP0_Pos (4UL) /*!< ECAP0 (Bit 4) */ +#define AFIO_FN1_AFR_ECAP0_Msk (0x70UL) /*!< ECAP0 (Bitfield-Mask: 0x07) */ +#define AFIO_FN1_AFR_ECAP1_Pos (7UL) /*!< ECAP1 (Bit 7) */ +#define AFIO_FN1_AFR_ECAP1_Msk (0x380UL) /*!< ECAP1 (Bitfield-Mask: 0x07) */ +#define AFIO_FN1_AFR_ECAP2_Pos (10UL) /*!< ECAP2 (Bit 10) */ +#define AFIO_FN1_AFR_ECAP2_Msk (0x1c00UL) /*!< ECAP2 (Bitfield-Mask: 0x07) */ +#define AFIO_FN1_AFR_EPETR_Pos (13UL) /*!< EPETR (Bit 13) */ +#define AFIO_FN1_AFR_EPETR_Msk (0x1e000UL) /*!< EPETR (Bitfield-Mask: 0x0f) */ +/* ======================================================== FN2_AFR ======================================================== */ +#define AFIO_FN2_AFR_TCAP0_Pos (0UL) /*!< TCAP0 (Bit 0) */ +#define AFIO_FN2_AFR_TCAP0_Msk (0x7UL) /*!< TCAP0 (Bitfield-Mask: 0x07) */ +#define AFIO_FN2_AFR_TCAP1_Pos (3UL) /*!< TCAP1 (Bit 3) */ +#define AFIO_FN2_AFR_TCAP1_Msk (0x38UL) /*!< TCAP1 (Bitfield-Mask: 0x07) */ +#define AFIO_FN2_AFR_TCAP2_Pos (6UL) /*!< TCAP2 (Bit 6) */ +#define AFIO_FN2_AFR_TCAP2_Msk (0x1c0UL) /*!< TCAP2 (Bitfield-Mask: 0x07) */ +#define AFIO_FN2_AFR_T2ETR_Pos (9UL) /*!< T2ETR (Bit 9) */ +#define AFIO_FN2_AFR_T2ETR_Msk (0x1e00UL) /*!< T2ETR (Bitfield-Mask: 0x0f) */ +#define AFIO_FN2_AFR_I2C_PULL0_Pos (13UL) /*!< I2C_PULL0 (Bit 13) */ +#define AFIO_FN2_AFR_I2C_PULL0_Msk (0x2000UL) /*!< I2C_PULL0 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL1_Pos (14UL) /*!< I2C_PULL1 (Bit 14) */ +#define AFIO_FN2_AFR_I2C_PULL1_Msk (0x4000UL) /*!< I2C_PULL1 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL2_Pos (15UL) /*!< I2C_PULL2 (Bit 15) */ +#define AFIO_FN2_AFR_I2C_PULL2_Msk (0x8000UL) /*!< I2C_PULL2 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL3_Pos (16UL) /*!< I2C_PULL3 (Bit 16) */ +#define AFIO_FN2_AFR_I2C_PULL3_Msk (0x10000UL) /*!< I2C_PULL3 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL4_Pos (17UL) /*!< I2C_PULL4 (Bit 17) */ +#define AFIO_FN2_AFR_I2C_PULL4_Msk (0x20000UL) /*!< I2C_PULL4 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL5_Pos (18UL) /*!< I2C_PULL5 (Bit 18) */ +#define AFIO_FN2_AFR_I2C_PULL5_Msk (0x40000UL) /*!< I2C_PULL5 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL6_Pos (19UL) /*!< I2C_PULL6 (Bit 19) */ +#define AFIO_FN2_AFR_I2C_PULL6_Msk (0x80000UL) /*!< I2C_PULL6 (Bitfield-Mask: 0x01) */ +#define AFIO_FN2_AFR_I2C_PULL7_Pos (20UL) /*!< I2C_PULL7 (Bit 20) */ +#define AFIO_FN2_AFR_I2C_PULL7_Msk (0x100000UL) /*!< I2C_PULL7 (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ SYSCFG ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= PMUCR ========================================================= */ +#define SYSCFG_PMUCR_PMUEN_Pos (0UL) /*!< PMUEN (Bit 0) */ +#define SYSCFG_PMUCR_PMUEN_Msk (0x1UL) /*!< PMUEN (Bitfield-Mask: 0x01) */ +/* ========================================================= MCOCR ========================================================= */ +#define SYSCFG_MCOCR_MCOSEL_Pos (0UL) /*!< MCOSEL (Bit 0) */ +#define SYSCFG_MCOCR_MCOSEL_Msk (0x7UL) /*!< MCOSEL (Bitfield-Mask: 0x07) */ +#define SYSCFG_MCOCR_DivEn_Pos (6UL) /*!< DivEn (Bit 6) */ +#define SYSCFG_MCOCR_DivEn_Msk (0x40UL) /*!< DivEn (Bitfield-Mask: 0x01) */ +#define SYSCFG_MCOCR_DivSel_Pos (7UL) /*!< DivSel (Bit 7) */ +#define SYSCFG_MCOCR_DivSel_Msk (0x80UL) /*!< DivSel (Bitfield-Mask: 0x01) */ +#define SYSCFG_MCOCR_Divider_Pos (8UL) /*!< Divider (Bit 8) */ +#define SYSCFG_MCOCR_Divider_Msk (0xff00UL) /*!< Divider (Bitfield-Mask: 0xff) */ +#define SYSCFG_MCOCR_SWRstEn_Pos (16UL) /*!< SWRstEn (Bit 16) */ +#define SYSCFG_MCOCR_SWRstEn_Msk (0xff0000UL) /*!< SWRstEn (Bitfield-Mask: 0xff) */ +/* ======================================================= SYSRSTSR ======================================================== */ +#define SYSCFG_SYSRSTSR_SWRST_Pos (0UL) /*!< SWRST (Bit 0) */ +#define SYSCFG_SYSRSTSR_SWRST_Msk (0x1UL) /*!< SWRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_WDGRST_Pos (1UL) /*!< WDGRST (Bit 1) */ +#define SYSCFG_SYSRSTSR_WDGRST_Msk (0x2UL) /*!< WDGRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_LOCKUPRST_Pos (2UL) /*!< LOCKUPRST (Bit 2) */ +#define SYSCFG_SYSRSTSR_LOCKUPRST_Msk (0x4UL) /*!< LOCKUPRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_PORRST_Pos (8UL) /*!< PORRST (Bit 8) */ +#define SYSCFG_SYSRSTSR_PORRST_Msk (0x100UL) /*!< PORRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_PADRST_Pos (9UL) /*!< PADRST (Bit 9) */ +#define SYSCFG_SYSRSTSR_PADRST_Msk (0x200UL) /*!< PADRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_LVDRST_Pos (11UL) /*!< LVDRST (Bit 11) */ +#define SYSCFG_SYSRSTSR_LVDRST_Msk (0x800UL) /*!< LVDRST (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSRSTSR_REBOOTRST_Pos (12UL) /*!< REBOOTRST (Bit 12) */ +#define SYSCFG_SYSRSTSR_REBOOTRST_Msk (0x1000UL) /*!< REBOOTRST (Bitfield-Mask: 0x01) */ +/* ===================================================== REBOOT_UNLOCK ===================================================== */ +#define SYSCFG_REBOOT_UNLOCK_AUTHKEY_Pos (0UL) /*!< AUTHKEY (Bit 0) */ +#define SYSCFG_REBOOT_UNLOCK_AUTHKEY_Msk (0xffffUL) /*!< AUTHKEY (Bitfield-Mask: 0xffff) */ +/* ======================================================= SYSRSTCR ======================================================== */ +#define SYSCFG_SYSRSTCR_REBOOTEN_Pos (10UL) /*!< REBOOTEN (Bit 10) */ +#define SYSCFG_SYSRSTCR_REBOOTEN_Msk (0x400UL) /*!< REBOOTEN (Bitfield-Mask: 0x01) */ +/* ======================================================= DEBUGENCR ======================================================= */ +#define SYSCFG_DEBUGENCR_TIM0_Pos (2UL) /*!< TIM0 (Bit 2) */ +#define SYSCFG_DEBUGENCR_TIM0_Msk (0x4UL) /*!< TIM0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_TIM1_Pos (3UL) /*!< TIM1 (Bit 3) */ +#define SYSCFG_DEBUGENCR_TIM1_Msk (0x8UL) /*!< TIM1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_LPTIM_Pos (4UL) /*!< LPTIM (Bit 4) */ +#define SYSCFG_DEBUGENCR_LPTIM_Msk (0x10UL) /*!< LPTIM (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_EPWM_Pos (6UL) /*!< EPWM (Bit 6) */ +#define SYSCFG_DEBUGENCR_EPWM_Msk (0x40UL) /*!< EPWM (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_TIM2_Pos (11UL) /*!< TIM2 (Bit 11) */ +#define SYSCFG_DEBUGENCR_TIM2_Msk (0x800UL) /*!< TIM2 (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_WDG_Pos (14UL) /*!< WDG (Bit 14) */ +#define SYSCFG_DEBUGENCR_WDG_Msk (0x4000UL) /*!< WDG (Bitfield-Mask: 0x01) */ +#define SYSCFG_DEBUGENCR_AUTHKEY_Pos (16UL) /*!< AUTHKEY (Bit 16) */ +#define SYSCFG_DEBUGENCR_AUTHKEY_Msk (0xffff0000UL) /*!< AUTHKEY (Bitfield-Mask: 0xffff) */ +/* ======================================================= SYSCLKCR ======================================================== */ +#define SYSCFG_SYSCLKCR_CLKSW_Pos (0UL) /*!< CLKSW (Bit 0) */ +#define SYSCFG_SYSCLKCR_CLKSW_Msk (0x7UL) /*!< CLKSW (Bitfield-Mask: 0x07) */ +#define SYSCFG_SYSCLKCR_CLKDIV_Pos (8UL) /*!< CLKDIV (Bit 8) */ +#define SYSCFG_SYSCLKCR_CLKDIV_Msk (0xf00UL) /*!< CLKDIV (Bitfield-Mask: 0x0f) */ +#define SYSCFG_SYSCLKCR_LSIAON_Pos (23UL) /*!< LSIAON (Bit 23) */ +#define SYSCFG_SYSCLKCR_LSIAON_Msk (0x800000UL) /*!< LSIAON (Bitfield-Mask: 0x01) */ +#define SYSCFG_SYSCLKCR_SYSTICKCR_Pos (24UL) /*!< SYSTICKCR (Bit 24) */ +#define SYSCFG_SYSCLKCR_SYSTICKCR_Msk (0x3000000UL) /*!< SYSTICKCR (Bitfield-Mask: 0x03) */ +/* ======================================================== PRSTEN ========================================================= */ +#define SYSCFG_PRSTEN_UART0_Pos (0UL) /*!< UART0 (Bit 0) */ +#define SYSCFG_PRSTEN_UART0_Msk (0x1UL) /*!< UART0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_TIM0_Pos (2UL) /*!< TIM0 (Bit 2) */ +#define SYSCFG_PRSTEN_TIM0_Msk (0x4UL) /*!< TIM0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_TIM1_Pos (3UL) /*!< TIM1 (Bit 3) */ +#define SYSCFG_PRSTEN_TIM1_Msk (0x8UL) /*!< TIM1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_LPTIM_Pos (4UL) /*!< LPTIM (Bit 4) */ +#define SYSCFG_PRSTEN_LPTIM_Msk (0x10UL) /*!< LPTIM (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_ADC_Pos (5UL) /*!< ADC (Bit 5) */ +#define SYSCFG_PRSTEN_ADC_Msk (0x20UL) /*!< ADC (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_EPWM_Pos (6UL) /*!< EPWM (Bit 6) */ +#define SYSCFG_PRSTEN_EPWM_Msk (0x40UL) /*!< EPWM (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_DSP_Pos (7UL) /*!< DSP (Bit 7) */ +#define SYSCFG_PRSTEN_DSP_Msk (0x80UL) /*!< DSP (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_COMP0_Pos (8UL) /*!< COMP0 (Bit 8) */ +#define SYSCFG_PRSTEN_COMP0_Msk (0x100UL) /*!< COMP0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_SPI_Pos (10UL) /*!< SPI (Bit 10) */ +#define SYSCFG_PRSTEN_SPI_Msk (0x400UL) /*!< SPI (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_TIM2_Pos (11UL) /*!< TIM2 (Bit 11) */ +#define SYSCFG_PRSTEN_TIM2_Msk (0x800UL) /*!< TIM2 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_I2C_Pos (12UL) /*!< I2C (Bit 12) */ +#define SYSCFG_PRSTEN_I2C_Msk (0x1000UL) /*!< I2C (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_COMP1_Pos (13UL) /*!< COMP1 (Bit 13) */ +#define SYSCFG_PRSTEN_COMP1_Msk (0x2000UL) /*!< COMP1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_WDG_Pos (14UL) /*!< WDG (Bit 14) */ +#define SYSCFG_PRSTEN_WDG_Msk (0x4000UL) /*!< WDG (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN_AMISC_Pos (15UL) /*!< AMISC (Bit 15) */ +#define SYSCFG_PRSTEN_AMISC_Msk (0x8000UL) /*!< AMISC (Bitfield-Mask: 0x01) */ +/* ======================================================== PCLKEN ========================================================= */ +#define SYSCFG_PCLKEN_UART0_Pos (0UL) /*!< UART0 (Bit 0) */ +#define SYSCFG_PCLKEN_UART0_Msk (0x1UL) /*!< UART0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_TIM0_Pos (2UL) /*!< TIM0 (Bit 2) */ +#define SYSCFG_PCLKEN_TIM0_Msk (0x4UL) /*!< TIM0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_TIM1_Pos (3UL) /*!< TIM1 (Bit 3) */ +#define SYSCFG_PCLKEN_TIM1_Msk (0x8UL) /*!< TIM1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_LPTIM_Pos (4UL) /*!< LPTIM (Bit 4) */ +#define SYSCFG_PCLKEN_LPTIM_Msk (0x10UL) /*!< LPTIM (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_ADC_Pos (5UL) /*!< ADC (Bit 5) */ +#define SYSCFG_PCLKEN_ADC_Msk (0x20UL) /*!< ADC (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_EPWM_Pos (6UL) /*!< EPWM (Bit 6) */ +#define SYSCFG_PCLKEN_EPWM_Msk (0x40UL) /*!< EPWM (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_DSP_Pos (7UL) /*!< DSP (Bit 7) */ +#define SYSCFG_PCLKEN_DSP_Msk (0x80UL) /*!< DSP (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_COMP0_Pos (8UL) /*!< COMP0 (Bit 8) */ +#define SYSCFG_PCLKEN_COMP0_Msk (0x100UL) /*!< COMP0 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_SPI_Pos (10UL) /*!< SPI (Bit 10) */ +#define SYSCFG_PCLKEN_SPI_Msk (0x400UL) /*!< SPI (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_TIM2_Pos (11UL) /*!< TIM2 (Bit 11) */ +#define SYSCFG_PCLKEN_TIM2_Msk (0x800UL) /*!< TIM2 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_I2C_Pos (12UL) /*!< I2C (Bit 12) */ +#define SYSCFG_PCLKEN_I2C_Msk (0x1000UL) /*!< I2C (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_COMP1_Pos (13UL) /*!< COMP1 (Bit 13) */ +#define SYSCFG_PCLKEN_COMP1_Msk (0x2000UL) /*!< COMP1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_WDG_Pos (14UL) /*!< WDG (Bit 14) */ +#define SYSCFG_PCLKEN_WDG_Msk (0x4000UL) /*!< WDG (Bitfield-Mask: 0x01) */ +#define SYSCFG_PCLKEN_AMISC_Pos (15UL) /*!< AMISC (Bit 15) */ +#define SYSCFG_PCLKEN_AMISC_Msk (0x8000UL) /*!< AMISC (Bitfield-Mask: 0x01) */ +/* ======================================================== ICEIOCR ======================================================== */ +#define SYSCFG_ICEIOCR_JTAGIOEN_Pos (0UL) /*!< JTAGIOEN (Bit 0) */ +#define SYSCFG_ICEIOCR_JTAGIOEN_Msk (0x1UL) /*!< JTAGIOEN (Bitfield-Mask: 0x01) */ +#define SYSCFG_ICEIOCR_DBG_CTRL_EN_Pos (1UL) /*!< DBG_CTRL_EN (Bit 1) */ +#define SYSCFG_ICEIOCR_DBG_CTRL_EN_Msk (0x2UL) /*!< DBG_CTRL_EN (Bitfield-Mask: 0x01) */ +#define SYSCFG_ICEIOCR_DBG_EN_Pos (2UL) /*!< DBG_EN (Bit 2) */ +#define SYSCFG_ICEIOCR_DBG_EN_Msk (0x4UL) /*!< DBG_EN (Bitfield-Mask: 0x01) */ +#define SYSCFG_ICEIOCR_AUTHKEY_Pos (16UL) /*!< AUTHKEY (Bit 16) */ +#define SYSCFG_ICEIOCR_AUTHKEY_Msk (0xffff0000UL) /*!< AUTHKEY (Bitfield-Mask: 0xffff) */ +/* ======================================================= RSTPINCR ======================================================== */ +#define SYSCFG_RSTPINCR_RSTPINAF_Pos (0UL) /*!< RSTPINAF (Bit 0) */ +#define SYSCFG_RSTPINCR_RSTPINAF_Msk (0xffffUL) /*!< RSTPINAF (Bitfield-Mask: 0xffff) */ +/* ===================================================== TIM2_CON_SEL ====================================================== */ +#define SYSCFG_TIM2_CON_SEL_CH1_Pos (0UL) /*!< CH1 (Bit 0) */ +#define SYSCFG_TIM2_CON_SEL_CH1_Msk (0x7UL) /*!< CH1 (Bitfield-Mask: 0x07) */ +#define SYSCFG_TIM2_CON_SEL_CH2_Pos (4UL) /*!< CH2 (Bit 4) */ +#define SYSCFG_TIM2_CON_SEL_CH2_Msk (0x70UL) /*!< CH2 (Bitfield-Mask: 0x07) */ +#define SYSCFG_TIM2_CON_SEL_CH3_Pos (8UL) /*!< CH3 (Bit 8) */ +#define SYSCFG_TIM2_CON_SEL_CH3_Msk (0x700UL) /*!< CH3 (Bitfield-Mask: 0x07) */ +#define SYSCFG_TIM2_CON_SEL_CH4_Pos (12UL) /*!< CH4 (Bit 12) */ +#define SYSCFG_TIM2_CON_SEL_CH4_Msk (0x7000UL) /*!< CH4 (Bitfield-Mask: 0x07) */ +#define SYSCFG_TIM2_CON_SEL_BREAK_SEL_Pos (17UL) /*!< BREAK_SEL (Bit 17) */ +#define SYSCFG_TIM2_CON_SEL_BREAK_SEL_Msk (0x20000UL) /*!< BREAK_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_COMP0A_SEL_Pos (18UL) /*!< COMP0A_SEL (Bit 18) */ +#define SYSCFG_TIM2_CON_SEL_COMP0A_SEL_Msk (0x40000UL) /*!< COMP0A_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_COMP1A_SEL_Pos (19UL) /*!< COMP1A_SEL (Bit 19) */ +#define SYSCFG_TIM2_CON_SEL_COMP1A_SEL_Msk (0x80000UL) /*!< COMP1A_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH1_INV_Pos (20UL) /*!< VC_CH1_INV (Bit 20) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH1_INV_Msk (0x100000UL) /*!< VC_CH1_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH1_Pos (21UL) /*!< VC_CH1 (Bit 21) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH1_Msk (0x200000UL) /*!< VC_CH1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH2_INV_Pos (22UL) /*!< VC_CH2_INV (Bit 22) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH2_INV_Msk (0x400000UL) /*!< VC_CH2_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH2_Pos (23UL) /*!< VC_CH2 (Bit 23) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH2_Msk (0x800000UL) /*!< VC_CH2 (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH3_INV_Pos (24UL) /*!< VC_CH3_INV (Bit 24) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH3_INV_Msk (0x1000000UL) /*!< VC_CH3_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH3_Pos (25UL) /*!< VC_CH3 (Bit 25) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH3_Msk (0x2000000UL) /*!< VC_CH3 (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH4_INV_Pos (26UL) /*!< VC_CH4_INV (Bit 26) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH4_INV_Msk (0x4000000UL) /*!< VC_CH4_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH4_Pos (27UL) /*!< VC_CH4 (Bit 27) */ +#define SYSCFG_TIM2_CON_SEL_VC_CH4_Msk (0x8000000UL) /*!< VC_CH4 (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_COMP0D_SEL_Pos (28UL) /*!< COMP0D_SEL (Bit 28) */ +#define SYSCFG_TIM2_CON_SEL_COMP0D_SEL_Msk (0x10000000UL) /*!< COMP0D_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_TIM2_CON_SEL_COMP1D_SEL_Pos (29UL) /*!< COMP1D_SEL (Bit 29) */ +#define SYSCFG_TIM2_CON_SEL_COMP1D_SEL_Msk (0x20000000UL) /*!< COMP1D_SEL (Bitfield-Mask: 0x01) */ +/* ===================================================== EPWM_CON_SEL ====================================================== */ +#define SYSCFG_EPWM_CON_SEL_CH1_Pos (0UL) /*!< CH1 (Bit 0) */ +#define SYSCFG_EPWM_CON_SEL_CH1_Msk (0x7UL) /*!< CH1 (Bitfield-Mask: 0x07) */ +#define SYSCFG_EPWM_CON_SEL_CH2_Pos (4UL) /*!< CH2 (Bit 4) */ +#define SYSCFG_EPWM_CON_SEL_CH2_Msk (0x70UL) /*!< CH2 (Bitfield-Mask: 0x07) */ +#define SYSCFG_EPWM_CON_SEL_CH3_Pos (8UL) /*!< CH3 (Bit 8) */ +#define SYSCFG_EPWM_CON_SEL_CH3_Msk (0x700UL) /*!< CH3 (Bitfield-Mask: 0x07) */ +#define SYSCFG_EPWM_CON_SEL_CH4_Pos (12UL) /*!< CH4 (Bit 12) */ +#define SYSCFG_EPWM_CON_SEL_CH4_Msk (0x7000UL) /*!< CH4 (Bitfield-Mask: 0x07) */ +#define SYSCFG_EPWM_CON_SEL_BREAK_SEL_Pos (16UL) /*!< BREAK_SEL (Bit 16) */ +#define SYSCFG_EPWM_CON_SEL_BREAK_SEL_Msk (0x10000UL) /*!< BREAK_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_BREAK_OSSI0_DISOUT_Pos (17UL) /*!< BREAK_OSSI0_DISOUT (Bit 17) */ +#define SYSCFG_EPWM_CON_SEL_BREAK_OSSI0_DISOUT_Msk (0x20000UL) /*!< BREAK_OSSI0_DISOUT (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_COMP0A_SEL_Pos (18UL) /*!< COMP0A_SEL (Bit 18) */ +#define SYSCFG_EPWM_CON_SEL_COMP0A_SEL_Msk (0x40000UL) /*!< COMP0A_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_COMP1A_SEL_Pos (19UL) /*!< COMP1A_SEL (Bit 19) */ +#define SYSCFG_EPWM_CON_SEL_COMP1A_SEL_Msk (0x80000UL) /*!< COMP1A_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH1_INV_Pos (20UL) /*!< VC_CH1_INV (Bit 20) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH1_INV_Msk (0x100000UL) /*!< VC_CH1_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH1_Pos (21UL) /*!< VC_CH1 (Bit 21) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH1_Msk (0x200000UL) /*!< VC_CH1 (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH2_INV_Pos (22UL) /*!< VC_CH2_INV (Bit 22) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH2_INV_Msk (0x400000UL) /*!< VC_CH2_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH2_Pos (23UL) /*!< VC_CH2 (Bit 23) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH2_Msk (0x800000UL) /*!< VC_CH2 (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH3_INV_Pos (24UL) /*!< VC_CH3_INV (Bit 24) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH3_INV_Msk (0x1000000UL) /*!< VC_CH3_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH3_Pos (25UL) /*!< VC_CH3 (Bit 25) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH3_Msk (0x2000000UL) /*!< VC_CH3 (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH4_INV_Pos (26UL) /*!< VC_CH4_INV (Bit 26) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH4_INV_Msk (0x4000000UL) /*!< VC_CH4_INV (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH4_Pos (27UL) /*!< VC_CH4 (Bit 27) */ +#define SYSCFG_EPWM_CON_SEL_VC_CH4_Msk (0x8000000UL) /*!< VC_CH4 (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_COMP0D_SEL_Pos (28UL) /*!< COMP0D_SEL (Bit 28) */ +#define SYSCFG_EPWM_CON_SEL_COMP0D_SEL_Msk (0x10000000UL) /*!< COMP0D_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_COMP1D_SEL_Pos (29UL) /*!< COMP1D_SEL (Bit 29) */ +#define SYSCFG_EPWM_CON_SEL_COMP1D_SEL_Msk (0x20000000UL) /*!< COMP1D_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_LVD_SEL_Pos (30UL) /*!< LVD_SEL (Bit 30) */ +#define SYSCFG_EPWM_CON_SEL_LVD_SEL_Msk (0x40000000UL) /*!< LVD_SEL (Bitfield-Mask: 0x01) */ +#define SYSCFG_EPWM_CON_SEL_WDG_SEL_Pos (31UL) /*!< WDG_SEL (Bit 31) */ +#define SYSCFG_EPWM_CON_SEL_WDG_SEL_Msk (0x80000000UL) /*!< WDG_SEL (Bitfield-Mask: 0x01) */ +/* ======================================================== PRSTEN1 ======================================================== */ +#define SYSCFG_PRSTEN1_GPIOA_Pos (0UL) /*!< GPIOA (Bit 0) */ +#define SYSCFG_PRSTEN1_GPIOA_Msk (0x1UL) /*!< GPIOA (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN1_GPIOB_Pos (1UL) /*!< GPIOB (Bit 1) */ +#define SYSCFG_PRSTEN1_GPIOB_Msk (0x2UL) /*!< GPIOB (Bitfield-Mask: 0x01) */ +#define SYSCFG_PRSTEN1_CRC_Pos (7UL) /*!< CRC (Bit 7) */ +#define SYSCFG_PRSTEN1_CRC_Msk (0x80UL) /*!< CRC (Bitfield-Mask: 0x01) */ +/* ======================================================== HCLKEN ========================================================= */ +#define SYSCFG_HCLKEN_GPIOA_Pos (0UL) /*!< GPIOA (Bit 0) */ +#define SYSCFG_HCLKEN_GPIOA_Msk (0x1UL) /*!< GPIOA (Bitfield-Mask: 0x01) */ +#define SYSCFG_HCLKEN_GPIOB_Pos (1UL) /*!< GPIOB (Bit 1) */ +#define SYSCFG_HCLKEN_GPIOB_Msk (0x2UL) /*!< GPIOB (Bitfield-Mask: 0x01) */ +#define SYSCFG_HCLKEN_CRC_Pos (7UL) /*!< CRC (Bit 7) */ +#define SYSCFG_HCLKEN_CRC_Msk (0x80UL) /*!< CRC (Bitfield-Mask: 0x01) */ +/* ======================================================== EVT_SEL ======================================================== */ +#define SYSCFG_EVT_SEL_IRQSEL_Pos (0UL) /*!< IRQSEL (Bit 0) */ +#define SYSCFG_EVT_SEL_IRQSEL_Msk (0xffffffffUL) /*!< IRQSEL (Bitfield-Mask: 0xffffffff) */ +/* ========================================================= NMICR ========================================================= */ +#define SYSCFG_NMICR_SEL_Pos (0UL) /*!< SEL (Bit 0) */ +#define SYSCFG_NMICR_SEL_Msk (0x1fUL) /*!< SEL (Bitfield-Mask: 0x1f) */ +#define SYSCFG_NMICR_EN_Pos (5UL) /*!< EN (Bit 5) */ +#define SYSCFG_NMICR_EN_Msk (0xe0UL) /*!< EN (Bitfield-Mask: 0x07) */ +/* ======================================================== CHIPID ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ UART ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== DAT ========================================================== */ +#define UART_DAT_DAT_Pos (0UL) /*!< DAT (Bit 0) */ +#define UART_DAT_DAT_Msk (0x1ffUL) /*!< DAT (Bitfield-Mask: 0x1ff) */ +#define UART_DAT_FE_Pos (9UL) /*!< FE (Bit 9) */ +#define UART_DAT_FE_Msk (0x200UL) /*!< FE (Bitfield-Mask: 0x01) */ +/* ========================================================== CR =========================================================== */ +#define UART_CR_MODE_Pos (0UL) /*!< MODE (Bit 0) */ +#define UART_CR_MODE_Msk (0x7UL) /*!< MODE (Bitfield-Mask: 0x07) */ +#define UART_CR_STOPB_Pos (3UL) /*!< STOPB (Bit 3) */ +#define UART_CR_STOPB_Msk (0x18UL) /*!< STOPB (Bitfield-Mask: 0x03) */ +#define UART_CR_PAR_Pos (5UL) /*!< PAR (Bit 5) */ +#define UART_CR_PAR_Msk (0x20UL) /*!< PAR (Bitfield-Mask: 0x01) */ +#define UART_CR_LPB_Pos (6UL) /*!< LPB (Bit 6) */ +#define UART_CR_LPB_Msk (0x40UL) /*!< LPB (Bitfield-Mask: 0x01) */ +#define UART_CR_RUN_Pos (7UL) /*!< RUN (Bit 7) */ +#define UART_CR_RUN_Msk (0x80UL) /*!< RUN (Bitfield-Mask: 0x01) */ +#define UART_CR_RXEN_Pos (8UL) /*!< RXEN (Bit 8) */ +#define UART_CR_RXEN_Msk (0x100UL) /*!< RXEN (Bitfield-Mask: 0x01) */ +#define UART_CR_RXPOL_Pos (16UL) /*!< RXPOL (Bit 16) */ +#define UART_CR_RXPOL_Msk (0x10000UL) /*!< RXPOL (Bitfield-Mask: 0x01) */ +#define UART_CR_TXPOL_Pos (17UL) /*!< TXPOL (Bit 17) */ +#define UART_CR_TXPOL_Msk (0x20000UL) /*!< TXPOL (Bitfield-Mask: 0x01) */ +/* ========================================================== BR =========================================================== */ +#define UART_BR_BR_Pos (0UL) /*!< BR (Bit 0) */ +#define UART_BR_BR_Msk (0xffffUL) /*!< BR (Bitfield-Mask: 0xffff) */ +/* ========================================================== IE =========================================================== */ +#define UART_IE_RXNEE_Pos (0UL) /*!< RXNEE (Bit 0) */ +#define UART_IE_RXNEE_Msk (0x1UL) /*!< RXNEE (Bitfield-Mask: 0x01) */ +#define UART_IE_TXEE_Pos (1UL) /*!< TXEE (Bit 1) */ +#define UART_IE_TXEE_Msk (0x2UL) /*!< TXEE (Bitfield-Mask: 0x01) */ +#define UART_IE_TXHEE_Pos (2UL) /*!< TXHEE (Bit 2) */ +#define UART_IE_TXHEE_Msk (0x4UL) /*!< TXHEE (Bitfield-Mask: 0x01) */ +#define UART_IE_PERRE_Pos (3UL) /*!< PERRE (Bit 3) */ +#define UART_IE_PERRE_Msk (0x8UL) /*!< PERRE (Bitfield-Mask: 0x01) */ +#define UART_IE_FERRE_Pos (4UL) /*!< FERRE (Bit 4) */ +#define UART_IE_FERRE_Msk (0x10UL) /*!< FERRE (Bitfield-Mask: 0x01) */ +#define UART_IE_OVERRE_Pos (5UL) /*!< OVERRE (Bit 5) */ +#define UART_IE_OVERRE_Msk (0x20UL) /*!< OVERRE (Bitfield-Mask: 0x01) */ +#define UART_IE_TONEE_Pos (6UL) /*!< TONEE (Bit 6) */ +#define UART_IE_TONEE_Msk (0x40UL) /*!< TONEE (Bitfield-Mask: 0x01) */ +#define UART_IE_TOIDLEE_Pos (7UL) /*!< TOIDLEE (Bit 7) */ +#define UART_IE_TOIDLEE_Msk (0x80UL) /*!< TOIDLEE (Bitfield-Mask: 0x01) */ +#define UART_IE_RXHFE_Pos (8UL) /*!< RXHFE (Bit 8) */ +#define UART_IE_RXHFE_Msk (0x100UL) /*!< RXHFE (Bitfield-Mask: 0x01) */ +#define UART_IE_RXFE_Pos (9UL) /*!< RXFE (Bit 9) */ +#define UART_IE_RXFE_Msk (0x200UL) /*!< RXFE (Bitfield-Mask: 0x01) */ +#define UART_IE_TXENDE_Pos (10UL) /*!< TXENDE (Bit 10) */ +#define UART_IE_TXENDE_Msk (0x400UL) /*!< TXENDE (Bitfield-Mask: 0x01) */ +#define UART_IE_TXFE_Pos (11UL) /*!< TXFE (Bit 11) */ +#define UART_IE_TXFE_Msk (0x800UL) /*!< TXFE (Bitfield-Mask: 0x01) */ +#define UART_IE_RXPE_Pos (12UL) /*!< RXPE (Bit 12) */ +#define UART_IE_RXPE_Msk (0x1000UL) /*!< RXPE (Bitfield-Mask: 0x01) */ +/* ========================================================== SR =========================================================== */ +#define UART_SR_RXNE_Pos (0UL) /*!< RXNE (Bit 0) */ +#define UART_SR_RXNE_Msk (0x1UL) /*!< RXNE (Bitfield-Mask: 0x01) */ +#define UART_SR_TXE_Pos (1UL) /*!< TXE (Bit 1) */ +#define UART_SR_TXE_Msk (0x2UL) /*!< TXE (Bitfield-Mask: 0x01) */ +#define UART_SR_TXHE_Pos (2UL) /*!< TXHE (Bit 2) */ +#define UART_SR_TXHE_Msk (0x4UL) /*!< TXHE (Bitfield-Mask: 0x01) */ +#define UART_SR_PERR_Pos (3UL) /*!< PERR (Bit 3) */ +#define UART_SR_PERR_Msk (0x8UL) /*!< PERR (Bitfield-Mask: 0x01) */ +#define UART_SR_FERR_Pos (4UL) /*!< FERR (Bit 4) */ +#define UART_SR_FERR_Msk (0x10UL) /*!< FERR (Bitfield-Mask: 0x01) */ +#define UART_SR_OVERR_Pos (5UL) /*!< OVERR (Bit 5) */ +#define UART_SR_OVERR_Msk (0x20UL) /*!< OVERR (Bitfield-Mask: 0x01) */ +#define UART_SR_TONE_Pos (6UL) /*!< TONE (Bit 6) */ +#define UART_SR_TONE_Msk (0x40UL) /*!< TONE (Bitfield-Mask: 0x01) */ +#define UART_SR_TOIDLE_Pos (7UL) /*!< TOIDLE (Bit 7) */ +#define UART_SR_TOIDLE_Msk (0x80UL) /*!< TOIDLE (Bitfield-Mask: 0x01) */ +#define UART_SR_RXHF_Pos (8UL) /*!< RXHF (Bit 8) */ +#define UART_SR_RXHF_Msk (0x100UL) /*!< RXHF (Bitfield-Mask: 0x01) */ +#define UART_SR_RXF_Pos (9UL) /*!< RXF (Bit 9) */ +#define UART_SR_RXF_Msk (0x200UL) /*!< RXF (Bitfield-Mask: 0x01) */ +#define UART_SR_TXEND_Pos (10UL) /*!< TXEND (Bit 10) */ +#define UART_SR_TXEND_Msk (0x400UL) /*!< TXEND (Bitfield-Mask: 0x01) */ +#define UART_SR_TXF_Pos (11UL) /*!< TXF (Bit 11) */ +#define UART_SR_TXF_Msk (0x800UL) /*!< TXF (Bitfield-Mask: 0x01) */ +/* ========================================================== GTR ========================================================== */ +#define UART_GTR_GT_Pos (0UL) /*!< GT (Bit 0) */ +#define UART_GTR_GT_Msk (0xffUL) /*!< GT (Bitfield-Mask: 0xff) */ +/* ========================================================== TOR ========================================================== */ +#define UART_TOR_TO_Pos (0UL) /*!< TO (Bit 0) */ +#define UART_TOR_TO_Msk (0xffUL) /*!< TO (Bitfield-Mask: 0xff) */ +/* ========================================================= TXFR ========================================================== */ +/* ========================================================= RXFR ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ I2C ================ */ +/* =========================================================================================================================== */ + +/* ======================================================== CTLSET ========================================================= */ +#define I2C_CTLSET_CR0_Pos (0UL) /*!< CR0 (Bit 0) */ +#define I2C_CTLSET_CR0_Msk (0x1UL) /*!< CR0 (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_CR1_Pos (1UL) /*!< CR1 (Bit 1) */ +#define I2C_CTLSET_CR1_Msk (0x2UL) /*!< CR1 (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_AA_Pos (2UL) /*!< AA (Bit 2) */ +#define I2C_CTLSET_AA_Msk (0x4UL) /*!< AA (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_SI_Pos (3UL) /*!< SI (Bit 3) */ +#define I2C_CTLSET_SI_Msk (0x8UL) /*!< SI (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_STO_Pos (4UL) /*!< STO (Bit 4) */ +#define I2C_CTLSET_STO_Msk (0x10UL) /*!< STO (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_STA_Pos (5UL) /*!< STA (Bit 5) */ +#define I2C_CTLSET_STA_Msk (0x20UL) /*!< STA (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_EN_Pos (6UL) /*!< EN (Bit 6) */ +#define I2C_CTLSET_EN_Msk (0x40UL) /*!< EN (Bitfield-Mask: 0x01) */ +#define I2C_CTLSET_CR2_Pos (7UL) /*!< CR2 (Bit 7) */ +#define I2C_CTLSET_CR2_Msk (0x80UL) /*!< CR2 (Bitfield-Mask: 0x01) */ +/* ========================================================= STAT ========================================================== */ +#define I2C_STAT_STAT_Pos (3UL) /*!< STAT (Bit 3) */ +#define I2C_STAT_STAT_Msk (0xf8UL) /*!< STAT (Bitfield-Mask: 0x1f) */ +/* ========================================================= DATA ========================================================== */ +#define I2C_DATA_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define I2C_DATA_DATA_Msk (0xffUL) /*!< DATA (Bitfield-Mask: 0xff) */ +/* ========================================================= ADDR ========================================================== */ +#define I2C_ADDR_GC_Pos (0UL) /*!< GC (Bit 0) */ +#define I2C_ADDR_GC_Msk (0x1UL) /*!< GC (Bitfield-Mask: 0x01) */ +#define I2C_ADDR_ADDR_Pos (1UL) /*!< ADDR (Bit 1) */ +#define I2C_ADDR_ADDR_Msk (0xfeUL) /*!< ADDR (Bitfield-Mask: 0x7f) */ +#define I2C_ADDR_FILTERDELAY_Pos (16UL) /*!< FILTERDELAY (Bit 16) */ +#define I2C_ADDR_FILTERDELAY_Msk (0xf0000UL) /*!< FILTERDELAY (Bitfield-Mask: 0x0f) */ +#define I2C_ADDR_FILTERDELAY_EN_Pos (24UL) /*!< FILTERDELAY_EN (Bit 24) */ +#define I2C_ADDR_FILTERDELAY_EN_Msk (0xff000000UL) /*!< FILTERDELAY_EN (Bitfield-Mask: 0xff) */ +/* ======================================================== CTLCLR ========================================================= */ +#define I2C_CTLCLR_CR0_Pos (0UL) /*!< CR0 (Bit 0) */ +#define I2C_CTLCLR_CR0_Msk (0x1UL) /*!< CR0 (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_CR1_Pos (1UL) /*!< CR1 (Bit 1) */ +#define I2C_CTLCLR_CR1_Msk (0x2UL) /*!< CR1 (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_AA_Pos (2UL) /*!< AA (Bit 2) */ +#define I2C_CTLCLR_AA_Msk (0x4UL) /*!< AA (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_SI_Pos (3UL) /*!< SI (Bit 3) */ +#define I2C_CTLCLR_SI_Msk (0x8UL) /*!< SI (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_STO_Pos (4UL) /*!< STO (Bit 4) */ +#define I2C_CTLCLR_STO_Msk (0x10UL) /*!< STO (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_STA_Pos (5UL) /*!< STA (Bit 5) */ +#define I2C_CTLCLR_STA_Msk (0x20UL) /*!< STA (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_EN_Pos (6UL) /*!< EN (Bit 6) */ +#define I2C_CTLCLR_EN_Msk (0x40UL) /*!< EN (Bitfield-Mask: 0x01) */ +#define I2C_CTLCLR_CR2_Pos (7UL) /*!< CR2 (Bit 7) */ +#define I2C_CTLCLR_CR2_Msk (0x80UL) /*!< CR2 (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ SPI ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CFG ========================================================== */ +#define SPI_CFG_MODE_Pos (0UL) /*!< MODE (Bit 0) */ +#define SPI_CFG_MODE_Msk (0x1UL) /*!< MODE (Bitfield-Mask: 0x01) */ +#define SPI_CFG_CPOL_Pos (1UL) /*!< CPOL (Bit 1) */ +#define SPI_CFG_CPOL_Msk (0x2UL) /*!< CPOL (Bitfield-Mask: 0x01) */ +#define SPI_CFG_CPHA_Pos (2UL) /*!< CPHA (Bit 2) */ +#define SPI_CFG_CPHA_Msk (0x4UL) /*!< CPHA (Bitfield-Mask: 0x01) */ +#define SPI_CFG_DB_Pos (3UL) /*!< DB (Bit 3) */ +#define SPI_CFG_DB_Msk (0x38UL) /*!< DB (Bitfield-Mask: 0x07) */ +#define SPI_CFG_TXWDSZ_Pos (6UL) /*!< TXWDSZ (Bit 6) */ +#define SPI_CFG_TXWDSZ_Msk (0xc0UL) /*!< TXWDSZ (Bitfield-Mask: 0x03) */ +#define SPI_CFG_LSB_Pos (8UL) /*!< LSB (Bit 8) */ +#define SPI_CFG_LSB_Msk (0x100UL) /*!< LSB (Bitfield-Mask: 0x01) */ +#define SPI_CFG_SS_OUT_Pos (10UL) /*!< SS_OUT (Bit 10) */ +#define SPI_CFG_SS_OUT_Msk (0x400UL) /*!< SS_OUT (Bitfield-Mask: 0x01) */ +#define SPI_CFG_MCS_Pos (14UL) /*!< MCS (Bit 14) */ +#define SPI_CFG_MCS_Msk (0x4000UL) /*!< MCS (Bitfield-Mask: 0x01) */ +#define SPI_CFG_MSE_Pos (15UL) /*!< MSE (Bit 15) */ +#define SPI_CFG_MSE_Msk (0x8000UL) /*!< MSE (Bitfield-Mask: 0x01) */ +#define SPI_CFG_MSTC_Pos (16UL) /*!< MSTC (Bit 16) */ +#define SPI_CFG_MSTC_Msk (0x10000UL) /*!< MSTC (Bitfield-Mask: 0x01) */ +#define SPI_CFG_MODEF_Pos (17UL) /*!< MODEF (Bit 17) */ +#define SPI_CFG_MODEF_Msk (0x20000UL) /*!< MODEF (Bitfield-Mask: 0x01) */ +/* ========================================================== STA ========================================================== */ +#define SPI_STA_RECVOV_Pos (0UL) /*!< RECVOV (Bit 0) */ +#define SPI_STA_RECVOV_Msk (0x1UL) /*!< RECVOV (Bitfield-Mask: 0x01) */ +#define SPI_STA_MDF_Pos (1UL) /*!< MDF (Bit 1) */ +#define SPI_STA_MDF_Msk (0x2UL) /*!< MDF (Bitfield-Mask: 0x01) */ +#define SPI_STA_TXNFUL_Pos (2UL) /*!< TXNFUL (Bit 2) */ +#define SPI_STA_TXNFUL_Msk (0x4UL) /*!< TXNFUL (Bitfield-Mask: 0x01) */ +#define SPI_STA_TXFUL_Pos (3UL) /*!< TXFUL (Bit 3) */ +#define SPI_STA_TXFUL_Msk (0x8UL) /*!< TXFUL (Bitfield-Mask: 0x01) */ +#define SPI_STA_RXNEP_Pos (4UL) /*!< RXNEP (Bit 4) */ +#define SPI_STA_RXNEP_Msk (0x10UL) /*!< RXNEP (Bitfield-Mask: 0x01) */ +#define SPI_STA_RXFUL_Pos (5UL) /*!< RXFUL (Bit 5) */ +#define SPI_STA_RXFUL_Msk (0x20UL) /*!< RXFUL (Bitfield-Mask: 0x01) */ +#define SPI_STA_TXUFL_Pos (6UL) /*!< TXUFL (Bit 6) */ +#define SPI_STA_TXUFL_Msk (0x40UL) /*!< TXUFL (Bitfield-Mask: 0x01) */ +#define SPI_STA_BUSY_Pos (7UL) /*!< BUSY (Bit 7) */ +#define SPI_STA_BUSY_Msk (0x80UL) /*!< BUSY (Bitfield-Mask: 0x01) */ +/* ========================================================= INTEN ========================================================= */ +#define SPI_INTEN_INTEN_Pos (0UL) /*!< INTEN (Bit 0) */ +#define SPI_INTEN_INTEN_Msk (0x7fUL) /*!< INTEN (Bitfield-Mask: 0x7f) */ +/* ======================================================== INTDIS ========================================================= */ +#define SPI_INTDIS_INTEN_Pos (0UL) /*!< INTEN (Bit 0) */ +#define SPI_INTDIS_INTEN_Msk (0x7fUL) /*!< INTEN (Bitfield-Mask: 0x7f) */ +/* ======================================================== INTMASK ======================================================== */ +#define SPI_INTMASK_INTEN_Pos (0UL) /*!< INTEN (Bit 0) */ +#define SPI_INTMASK_INTEN_Msk (0x7fUL) /*!< INTEN (Bitfield-Mask: 0x7f) */ +/* ========================================================== EN =========================================================== */ +#define SPI_EN_EN_Pos (0UL) /*!< EN (Bit 0) */ +#define SPI_EN_EN_Msk (0x1UL) /*!< EN (Bitfield-Mask: 0x01) */ +/* ========================================================= DELAY ========================================================= */ +#define SPI_DELAY_d_int_Pos (0UL) /*!< d_int (Bit 0) */ +#define SPI_DELAY_d_int_Msk (0xffUL) /*!< d_int (Bitfield-Mask: 0xff) */ +#define SPI_DELAY_d_affter_Pos (8UL) /*!< d_affter (Bit 8) */ +#define SPI_DELAY_d_affter_Msk (0xff00UL) /*!< d_affter (Bitfield-Mask: 0xff) */ +#define SPI_DELAY_d_btwn_Pos (16UL) /*!< d_btwn (Bit 16) */ +#define SPI_DELAY_d_btwn_Msk (0xff0000UL) /*!< d_btwn (Bitfield-Mask: 0xff) */ +#define SPI_DELAY_d_nss_Pos (24UL) /*!< d_nss (Bit 24) */ +#define SPI_DELAY_d_nss_Msk (0xff000000UL) /*!< d_nss (Bitfield-Mask: 0xff) */ +/* ========================================================== TX =========================================================== */ +/* ========================================================== RX =========================================================== */ +/* ======================================================== IDLECNT ======================================================== */ +#define SPI_IDLECNT_IDLECNT_Pos (0UL) /*!< IDLECNT (Bit 0) */ +#define SPI_IDLECNT_IDLECNT_Msk (0xffUL) /*!< IDLECNT (Bitfield-Mask: 0xff) */ +/* ========================================================= TXTH ========================================================== */ +#define SPI_TXTH_TXTHOLD_Pos (0UL) /*!< TXTHOLD (Bit 0) */ +#define SPI_TXTH_TXTHOLD_Msk (0xffffffffUL) /*!< TXTHOLD (Bitfield-Mask: 0xffffffff) */ +/* ========================================================= RXTH ========================================================== */ +#define SPI_RXTH_RXTHOLD_Pos (0UL) /*!< RXTHOLD (Bit 0) */ +#define SPI_RXTH_RXTHOLD_Msk (0xffffffffUL) /*!< RXTHOLD (Bitfield-Mask: 0xffffffff) */ + + +/* =========================================================================================================================== */ +/* ================ WDG ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= LOAD ========================================================== */ +/* ========================================================= VALUE ========================================================= */ +/* ========================================================== CR =========================================================== */ +#define WDG_CR_INTE_Pos (0UL) /*!< INTE (Bit 0) */ +#define WDG_CR_INTE_Msk (0x1UL) /*!< INTE (Bitfield-Mask: 0x01) */ +#define WDG_CR_RSTE_Pos (1UL) /*!< RSTE (Bit 1) */ +#define WDG_CR_RSTE_Msk (0x2UL) /*!< RSTE (Bitfield-Mask: 0x01) */ +#define WDG_CR_DBGE_Pos (2UL) /*!< DBGE (Bit 2) */ +#define WDG_CR_DBGE_Msk (0x4UL) /*!< DBGE (Bitfield-Mask: 0x01) */ +/* ======================================================== INTCLR ========================================================= */ +/* ========================================================== RIS ========================================================== */ +#define WDG_RIS_RIF_Pos (0UL) /*!< RIF (Bit 0) */ +#define WDG_RIS_RIF_Msk (0x1UL) /*!< RIF (Bitfield-Mask: 0x01) */ +/* ========================================================== MIS ========================================================== */ +#define WDG_MIS_MIF_Pos (0UL) /*!< MIF (Bit 0) */ +#define WDG_MIS_MIF_Msk (0x1UL) /*!< MIF (Bitfield-Mask: 0x01) */ +/* ========================================================= LOCK ========================================================== */ +#define WDG_LOCK_LOCK_Pos (0UL) /*!< LOCK (Bit 0) */ +#define WDG_LOCK_LOCK_Msk (0x1UL) /*!< LOCK (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ ADC ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= CON0 ========================================================== */ +#define ADC_CON0_M_Pos (0UL) /*!< M (Bit 0) */ +#define ADC_CON0_M_Msk (0xfUL) /*!< M (Bitfield-Mask: 0x0f) */ +#define ADC_CON0_EN_Pos (5UL) /*!< EN (Bit 5) */ +#define ADC_CON0_EN_Msk (0x20UL) /*!< EN (Bitfield-Mask: 0x01) */ +#define ADC_CON0_START_Pos (7UL) /*!< START (Bit 7) */ +#define ADC_CON0_START_Msk (0x80UL) /*!< START (Bitfield-Mask: 0x01) */ +#define ADC_CON0_CLK_Pos (8UL) /*!< CLK (Bit 8) */ +#define ADC_CON0_CLK_Msk (0x700UL) /*!< CLK (Bitfield-Mask: 0x07) */ +#define ADC_CON0_TRIG_EN_Pos (11UL) /*!< TRIG_EN (Bit 11) */ +#define ADC_CON0_TRIG_EN_Msk (0x800UL) /*!< TRIG_EN (Bitfield-Mask: 0x01) */ +#define ADC_CON0_CONTINUE_Pos (12UL) /*!< CONTINUE (Bit 12) */ +#define ADC_CON0_CONTINUE_Msk (0x1000UL) /*!< CONTINUE (Bitfield-Mask: 0x01) */ +#define ADC_CON0_ALIGN_Pos (13UL) /*!< ALIGN (Bit 13) */ +#define ADC_CON0_ALIGN_Msk (0x2000UL) /*!< ALIGN (Bitfield-Mask: 0x01) */ +#define ADC_CON0_ENCONT_Pos (15UL) /*!< ENCONT (Bit 15) */ +#define ADC_CON0_ENCONT_Msk (0x8000UL) /*!< ENCONT (Bitfield-Mask: 0x01) */ +#define ADC_CON0_INT_EN_Pos (16UL) /*!< INT_EN (Bit 16) */ +#define ADC_CON0_INT_EN_Msk (0xf0000UL) /*!< INT_EN (Bitfield-Mask: 0x0f) */ +#define ADC_CON0_TZO_Pos (20UL) /*!< TZO (Bit 20) */ +#define ADC_CON0_TZO_Msk (0x700000UL) /*!< TZO (Bitfield-Mask: 0x07) */ +#define ADC_CON0_BAKEN_Pos (29UL) /*!< BAKEN (Bit 29) */ +#define ADC_CON0_BAKEN_Msk (0x20000000UL) /*!< BAKEN (Bitfield-Mask: 0x01) */ +#define ADC_CON0_PWD_Pos (30UL) /*!< PWD (Bit 30) */ +#define ADC_CON0_PWD_Msk (0x40000000UL) /*!< PWD (Bitfield-Mask: 0x01) */ +#define ADC_CON0_RST_Pos (31UL) /*!< RST (Bit 31) */ +#define ADC_CON0_RST_Msk (0x80000000UL) /*!< RST (Bitfield-Mask: 0x01) */ +/* ========================================================= STAT ========================================================== */ +#define ADC_STAT_DONE_Pos (0UL) /*!< DONE (Bit 0) */ +#define ADC_STAT_DONE_Msk (0x1UL) /*!< DONE (Bitfield-Mask: 0x01) */ +#define ADC_STAT_INT_CLR_Pos (1UL) /*!< INT_CLR (Bit 1) */ +#define ADC_STAT_INT_CLR_Msk (0x2UL) /*!< INT_CLR (Bitfield-Mask: 0x01) */ +#define ADC_STAT_COMP_RESULT_Pos (4UL) /*!< COMP_RESULT (Bit 4) */ +#define ADC_STAT_COMP_RESULT_Msk (0x30UL) /*!< COMP_RESULT (Bitfield-Mask: 0x03) */ +#define ADC_STAT_EOC_CHECK_DIS_Pos (6UL) /*!< EOC_CHECK_DIS (Bit 6) */ +#define ADC_STAT_EOC_CHECK_DIS_Msk (0x40UL) /*!< EOC_CHECK_DIS (Bitfield-Mask: 0x01) */ +#define ADC_STAT_TS_SET_Pos (16UL) /*!< TS_SET (Bit 16) */ +#define ADC_STAT_TS_SET_Msk (0x1f0000UL) /*!< TS_SET (Bitfield-Mask: 0x1f) */ +#define ADC_STAT_DLY_SET_Pos (21UL) /*!< DLY_SET (Bit 21) */ +#define ADC_STAT_DLY_SET_Msk (0xe00000UL) /*!< DLY_SET (Bitfield-Mask: 0x07) */ +#define ADC_STAT_EOC_CNT_Pos (24UL) /*!< EOC_CNT (Bit 24) */ +#define ADC_STAT_EOC_CNT_Msk (0xf000000UL) /*!< EOC_CNT (Bitfield-Mask: 0x0f) */ +#define ADC_STAT_START_CNT_Pos (28UL) /*!< START_CNT (Bit 28) */ +#define ADC_STAT_START_CNT_Msk (0xf0000000UL) /*!< START_CNT (Bitfield-Mask: 0x0f) */ +/* ========================================================= DAT0 ========================================================== */ +#define ADC_DAT0_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT0_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT0_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT0_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT1 ========================================================== */ +#define ADC_DAT1_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT1_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT1_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT1_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT2 ========================================================== */ +#define ADC_DAT2_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT2_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT2_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT2_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT3 ========================================================== */ +#define ADC_DAT3_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT3_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT3_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT3_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT4 ========================================================== */ +#define ADC_DAT4_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT4_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT4_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT4_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT5 ========================================================== */ +#define ADC_DAT5_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT5_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT5_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT5_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT6 ========================================================== */ +#define ADC_DAT6_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT6_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT6_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT6_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT7 ========================================================== */ +#define ADC_DAT7_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT7_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT7_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT7_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT8 ========================================================== */ +#define ADC_DAT8_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT8_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT8_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT8_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT9 ========================================================== */ +#define ADC_DAT9_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT9_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT9_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT9_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT10 ========================================================= */ +#define ADC_DAT10_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT10_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT10_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT10_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT11 ========================================================= */ +#define ADC_DAT11_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT11_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT11_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT11_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT12 ========================================================= */ +#define ADC_DAT12_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT12_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT12_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT12_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT13 ========================================================= */ +#define ADC_DAT13_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT13_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT13_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT13_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT14 ========================================================= */ +#define ADC_DAT14_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT14_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT14_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT14_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= DAT15 ========================================================= */ +#define ADC_DAT15_DATA_Pos (0UL) /*!< DATA (Bit 0) */ +#define ADC_DAT15_DATA_Msk (0xffffUL) /*!< DATA (Bitfield-Mask: 0xffff) */ +#define ADC_DAT15_CMPTH_Pos (16UL) /*!< CMPTH (Bit 16) */ +#define ADC_DAT15_CMPTH_Msk (0xfff0000UL) /*!< CMPTH (Bitfield-Mask: 0xfff) */ +/* ========================================================= CHSEL ========================================================= */ +#define ADC_CHSEL_CH_SEL_Pos (0UL) /*!< CH_SEL (Bit 0) */ +#define ADC_CHSEL_CH_SEL_Msk (0xffffUL) /*!< CH_SEL (Bitfield-Mask: 0xffff) */ +#define ADC_CHSEL_CH_CNT_Pos (16UL) /*!< CH_CNT (Bit 16) */ +#define ADC_CHSEL_CH_CNT_Msk (0xf0000UL) /*!< CH_CNT (Bitfield-Mask: 0x0f) */ +#define ADC_CHSEL_DISC_INTSEL_Pos (21UL) /*!< DISC_INTSEL (Bit 21) */ +#define ADC_CHSEL_DISC_INTSEL_Msk (0x200000UL) /*!< DISC_INTSEL (Bitfield-Mask: 0x01) */ +#define ADC_CHSEL_DISCNUM_Pos (22UL) /*!< DISCNUM (Bit 22) */ +#define ADC_CHSEL_DISCNUM_Msk (0x1c00000UL) /*!< DISCNUM (Bitfield-Mask: 0x07) */ +#define ADC_CHSEL_DISCEN_Pos (25UL) /*!< DISCEN (Bit 25) */ +#define ADC_CHSEL_DISCEN_Msk (0x2000000UL) /*!< DISCEN (Bitfield-Mask: 0x01) */ +#define ADC_CHSEL_TRIG_SEL16_Pos (26UL) /*!< TRIG_SEL16 (Bit 26) */ +#define ADC_CHSEL_TRIG_SEL16_Msk (0xc000000UL) /*!< TRIG_SEL16 (Bitfield-Mask: 0x03) */ +#define ADC_CHSEL_TRIG_SEL17_Pos (28UL) /*!< TRIG_SEL17 (Bit 28) */ +#define ADC_CHSEL_TRIG_SEL17_Msk (0x30000000UL) /*!< TRIG_SEL17 (Bitfield-Mask: 0x03) */ +#define ADC_CHSEL_EXTRIG_SEL_Pos (30UL) /*!< EXTRIG_SEL (Bit 30) */ +#define ADC_CHSEL_EXTRIG_SEL_Msk (0xc0000000UL) /*!< EXTRIG_SEL (Bitfield-Mask: 0x03) */ +/* ======================================================== TRGSEL ========================================================= */ +#define ADC_TRGSEL_TRIG_SEL0_Pos (0UL) /*!< TRIG_SEL0 (Bit 0) */ +#define ADC_TRGSEL_TRIG_SEL0_Msk (0x3UL) /*!< TRIG_SEL0 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL1_Pos (2UL) /*!< TRIG_SEL1 (Bit 2) */ +#define ADC_TRGSEL_TRIG_SEL1_Msk (0xcUL) /*!< TRIG_SEL1 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL2_Pos (4UL) /*!< TRIG_SEL2 (Bit 4) */ +#define ADC_TRGSEL_TRIG_SEL2_Msk (0x30UL) /*!< TRIG_SEL2 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL3_Pos (6UL) /*!< TRIG_SEL3 (Bit 6) */ +#define ADC_TRGSEL_TRIG_SEL3_Msk (0xc0UL) /*!< TRIG_SEL3 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL4_Pos (8UL) /*!< TRIG_SEL4 (Bit 8) */ +#define ADC_TRGSEL_TRIG_SEL4_Msk (0x300UL) /*!< TRIG_SEL4 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL5_Pos (10UL) /*!< TRIG_SEL5 (Bit 10) */ +#define ADC_TRGSEL_TRIG_SEL5_Msk (0xc00UL) /*!< TRIG_SEL5 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL6_Pos (12UL) /*!< TRIG_SEL6 (Bit 12) */ +#define ADC_TRGSEL_TRIG_SEL6_Msk (0x3000UL) /*!< TRIG_SEL6 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL7_Pos (14UL) /*!< TRIG_SEL7 (Bit 14) */ +#define ADC_TRGSEL_TRIG_SEL7_Msk (0xc000UL) /*!< TRIG_SEL7 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL8_Pos (16UL) /*!< TRIG_SEL8 (Bit 16) */ +#define ADC_TRGSEL_TRIG_SEL8_Msk (0x30000UL) /*!< TRIG_SEL8 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL9_Pos (18UL) /*!< TRIG_SEL9 (Bit 18) */ +#define ADC_TRGSEL_TRIG_SEL9_Msk (0xc0000UL) /*!< TRIG_SEL9 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL10_Pos (20UL) /*!< TRIG_SEL10 (Bit 20) */ +#define ADC_TRGSEL_TRIG_SEL10_Msk (0x300000UL) /*!< TRIG_SEL10 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL11_Pos (22UL) /*!< TRIG_SEL11 (Bit 22) */ +#define ADC_TRGSEL_TRIG_SEL11_Msk (0xc00000UL) /*!< TRIG_SEL11 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL12_Pos (24UL) /*!< TRIG_SEL12 (Bit 24) */ +#define ADC_TRGSEL_TRIG_SEL12_Msk (0x3000000UL) /*!< TRIG_SEL12 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL13_Pos (26UL) /*!< TRIG_SEL13 (Bit 26) */ +#define ADC_TRGSEL_TRIG_SEL13_Msk (0xc000000UL) /*!< TRIG_SEL13 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL14_Pos (28UL) /*!< TRIG_SEL14 (Bit 28) */ +#define ADC_TRGSEL_TRIG_SEL14_Msk (0x30000000UL) /*!< TRIG_SEL14 (Bitfield-Mask: 0x03) */ +#define ADC_TRGSEL_TRIG_SEL15_Pos (30UL) /*!< TRIG_SEL15 (Bit 30) */ +#define ADC_TRGSEL_TRIG_SEL15_Msk (0xc0000000UL) /*!< TRIG_SEL15 (Bitfield-Mask: 0x03) */ +/* ========================================================= BKSEL ========================================================= */ +#define ADC_BKSEL_BK1_CH_Pos (0UL) /*!< BK1_CH (Bit 0) */ +#define ADC_BKSEL_BK1_CH_Msk (0xfUL) /*!< BK1_CH (Bitfield-Mask: 0x0f) */ +#define ADC_BKSEL_BK1_FLT_Pos (4UL) /*!< BK1_FLT (Bit 4) */ +#define ADC_BKSEL_BK1_FLT_Msk (0x30UL) /*!< BK1_FLT (Bitfield-Mask: 0x03) */ +#define ADC_BKSEL_BK1_EN_Pos (6UL) /*!< BK1_EN (Bit 6) */ +#define ADC_BKSEL_BK1_EN_Msk (0xc0UL) /*!< BK1_EN (Bitfield-Mask: 0x03) */ +#define ADC_BKSEL_BK2_CH_Pos (8UL) /*!< BK2_CH (Bit 8) */ +#define ADC_BKSEL_BK2_CH_Msk (0xf00UL) /*!< BK2_CH (Bitfield-Mask: 0x0f) */ +#define ADC_BKSEL_BK2_FLT_Pos (12UL) /*!< BK2_FLT (Bit 12) */ +#define ADC_BKSEL_BK2_FLT_Msk (0x3000UL) /*!< BK2_FLT (Bitfield-Mask: 0x03) */ +#define ADC_BKSEL_BK2_EN_Pos (14UL) /*!< BK2_EN (Bit 14) */ +#define ADC_BKSEL_BK2_EN_Msk (0xc000UL) /*!< BK2_EN (Bitfield-Mask: 0x03) */ +/* ======================================================== BAKDAT ========================================================= */ +#define ADC_BAKDAT_BAKDAT_Pos (0UL) /*!< BAKDAT (Bit 0) */ +#define ADC_BAKDAT_BAKDAT_Msk (0xffffUL) /*!< BAKDAT (Bitfield-Mask: 0xffff) */ + + +/* =========================================================================================================================== */ +/* ================ AMISC ================ */ +/* =========================================================================================================================== */ + +/* ====================================================== LVD_LVR_CR ======================================================= */ +#define AMISC_LVD_LVR_CR_LVD_EN_Pos (0UL) /*!< LVD_EN (Bit 0) */ +#define AMISC_LVD_LVR_CR_LVD_EN_Msk (0x1UL) /*!< LVD_EN (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_LDO_LP_EN_Pos (1UL) /*!< LDO_LP_EN (Bit 1) */ +#define AMISC_LVD_LVR_CR_LDO_LP_EN_Msk (0x2UL) /*!< LDO_LP_EN (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_LVD_F_SEL_Pos (2UL) /*!< LVD_F_SEL (Bit 2) */ +#define AMISC_LVD_LVR_CR_LVD_F_SEL_Msk (0xcUL) /*!< LVD_F_SEL (Bitfield-Mask: 0x03) */ +#define AMISC_LVD_LVR_CR_LVD_SEL_Pos (5UL) /*!< LVD_SEL (Bit 5) */ +#define AMISC_LVD_LVR_CR_LVD_SEL_Msk (0xe0UL) /*!< LVD_SEL (Bitfield-Mask: 0x07) */ +#define AMISC_LVD_LVR_CR_LVR_EN_Pos (8UL) /*!< LVR_EN (Bit 8) */ +#define AMISC_LVD_LVR_CR_LVR_EN_Msk (0x100UL) /*!< LVR_EN (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_LVD_INT_EN_Pos (9UL) /*!< LVD_INT_EN (Bit 9) */ +#define AMISC_LVD_LVR_CR_LVD_INT_EN_Msk (0x200UL) /*!< LVD_INT_EN (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_TEMP_EN_Pos (10UL) /*!< TEMP_EN (Bit 10) */ +#define AMISC_LVD_LVR_CR_TEMP_EN_Msk (0x400UL) /*!< TEMP_EN (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_LVD_STATE_Pos (11UL) /*!< LVD_STATE (Bit 11) */ +#define AMISC_LVD_LVR_CR_LVD_STATE_Msk (0x800UL) /*!< LVD_STATE (Bitfield-Mask: 0x01) */ +#define AMISC_LVD_LVR_CR_LVR_SEL_Pos (13UL) /*!< LVR_SEL (Bit 13) */ +#define AMISC_LVD_LVR_CR_LVR_SEL_Msk (0xe000UL) /*!< LVR_SEL (Bitfield-Mask: 0x07) */ +/* ======================================================== VBUF_CR ======================================================== */ +#define AMISC_VBUF_CR_VBUF_EN_Pos (0UL) /*!< VBUF_EN (Bit 0) */ +#define AMISC_VBUF_CR_VBUF_EN_Msk (0x1UL) /*!< VBUF_EN (Bitfield-Mask: 0x01) */ +#define AMISC_VBUF_CR_ANA2IO_EN_Pos (4UL) /*!< ANA2IO_EN (Bit 4) */ +#define AMISC_VBUF_CR_ANA2IO_EN_Msk (0x10UL) /*!< ANA2IO_EN (Bitfield-Mask: 0x01) */ +#define AMISC_VBUF_CR_ANA2PGA_EN_Pos (5UL) /*!< ANA2PGA_EN (Bit 5) */ +#define AMISC_VBUF_CR_ANA2PGA_EN_Msk (0x20UL) /*!< ANA2PGA_EN (Bitfield-Mask: 0x01) */ +#define AMISC_VBUF_CR_ANA_SEL_Pos (6UL) /*!< ANA_SEL (Bit 6) */ +#define AMISC_VBUF_CR_ANA_SEL_Msk (0x1fc0UL) /*!< ANA_SEL (Bitfield-Mask: 0x7f) */ +/* ======================================================== DAC_CR ========================================================= */ +#define AMISC_DAC_CR_DAC0Step_Pos (0UL) /*!< DAC0Step (Bit 0) */ +#define AMISC_DAC_CR_DAC0Step_Msk (0x3ffUL) /*!< DAC0Step (Bitfield-Mask: 0x3ff) */ +#define AMISC_DAC_CR_DAC1Step_Pos (10UL) /*!< DAC1Step (Bit 10) */ +#define AMISC_DAC_CR_DAC1Step_Msk (0xffc00UL) /*!< DAC1Step (Bitfield-Mask: 0x3ff) */ +#define AMISC_DAC_CR_DAC0_EN_Pos (20UL) /*!< DAC0_EN (Bit 20) */ +#define AMISC_DAC_CR_DAC0_EN_Msk (0x100000UL) /*!< DAC0_EN (Bitfield-Mask: 0x01) */ +#define AMISC_DAC_CR_DAC1_EN_Pos (21UL) /*!< DAC1_EN (Bit 21) */ +#define AMISC_DAC_CR_DAC1_EN_Msk (0x200000UL) /*!< DAC1_EN (Bitfield-Mask: 0x01) */ +/* ======================================================== HSI_CR ========================================================= */ +#define AMISC_HSI_CR_LDO_SEL_Pos (0UL) /*!< LDO_SEL (Bit 0) */ +#define AMISC_HSI_CR_LDO_SEL_Msk (0xffffUL) /*!< LDO_SEL (Bitfield-Mask: 0xffff) */ +#define AMISC_HSI_CR_HSI_EN_Pos (24UL) /*!< HSI_EN (Bit 24) */ +#define AMISC_HSI_CR_HSI_EN_Msk (0xff000000UL) /*!< HSI_EN (Bitfield-Mask: 0xff) */ +/* ======================================================== LSI_CR ========================================================= */ +#define AMISC_LSI_CR_LSI_EN_Pos (24UL) /*!< LSI_EN (Bit 24) */ +#define AMISC_LSI_CR_LSI_EN_Msk (0xff000000UL) /*!< LSI_EN (Bitfield-Mask: 0xff) */ +/* ====================================================== ADC_AIN_CR ======================================================= */ +#define AMISC_ADC_AIN_CR_ANA2ADC_EN_Pos (0UL) /*!< ANA2ADC_EN (Bit 0) */ +#define AMISC_ADC_AIN_CR_ANA2ADC_EN_Msk (0x1UL) /*!< ANA2ADC_EN (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ HWTRIM ================ */ +/* =========================================================================================================================== */ + +/* ======================================================= LDO_TRIM ======================================================== */ +#define HWTRIM_LDO_TRIM_LDO_TRIM_Pos (0UL) /*!< LDO_TRIM (Bit 0) */ +#define HWTRIM_LDO_TRIM_LDO_TRIM_Msk (0x1fUL) /*!< LDO_TRIM (Bitfield-Mask: 0x1f) */ +#define HWTRIM_LDO_TRIM_LDO_LP_TRIM_Pos (5UL) /*!< LDO_LP_TRIM (Bit 5) */ +#define HWTRIM_LDO_TRIM_LDO_LP_TRIM_Msk (0x3e0UL) /*!< LDO_LP_TRIM (Bitfield-Mask: 0x1f) */ +#define HWTRIM_LDO_TRIM_LDO_TUNE_Pos (10UL) /*!< LDO_TUNE (Bit 10) */ +#define HWTRIM_LDO_TRIM_LDO_TUNE_Msk (0xc00UL) /*!< LDO_TUNE (Bitfield-Mask: 0x03) */ +/* ======================================================= VBUF_TRIM ======================================================= */ +#define HWTRIM_VBUF_TRIM_VBUF_TRIM_Pos (0UL) /*!< VBUF_TRIM (Bit 0) */ +#define HWTRIM_VBUF_TRIM_VBUF_TRIM_Msk (0x7fUL) /*!< VBUF_TRIM (Bitfield-Mask: 0x7f) */ +/* ======================================================= HSI_TRIM ======================================================== */ +#define HWTRIM_HSI_TRIM_HSI_D_CFG_Pos (0UL) /*!< HSI_D_CFG (Bit 0) */ +#define HWTRIM_HSI_TRIM_HSI_D_CFG_Msk (0x1ffUL) /*!< HSI_D_CFG (Bitfield-Mask: 0x1ff) */ +#define HWTRIM_HSI_TRIM_HSI_FSEL_CFG_Pos (9UL) /*!< HSI_FSEL_CFG (Bit 9) */ +#define HWTRIM_HSI_TRIM_HSI_FSEL_CFG_Msk (0xfe00UL) /*!< HSI_FSEL_CFG (Bitfield-Mask: 0x7f) */ +#define HWTRIM_HSI_TRIM_HSI_TC_Pos (16UL) /*!< HSI_TC (Bit 16) */ +#define HWTRIM_HSI_TRIM_HSI_TC_Msk (0x30000UL) /*!< HSI_TC (Bitfield-Mask: 0x03) */ +/* ======================================================= LSI_TRIM ======================================================== */ +#define HWTRIM_LSI_TRIM_LSI_TRIM_Pos (0UL) /*!< LSI_TRIM (Bit 0) */ +#define HWTRIM_LSI_TRIM_LSI_TRIM_Msk (0xffUL) /*!< LSI_TRIM (Bitfield-Mask: 0xff) */ +/* ======================================================= MISC_CFG ======================================================== */ +#define HWTRIM_MISC_CFG_EXT_nRST_EN_Pos (0UL) /*!< EXT_nRST_EN (Bit 0) */ +#define HWTRIM_MISC_CFG_EXT_nRST_EN_Msk (0x1UL) /*!< EXT_nRST_EN (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ CRC ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR =========================================================== */ +#define CRC_CR_POLYSEL_Pos (0UL) /*!< POLYSEL (Bit 0) */ +#define CRC_CR_POLYSEL_Msk (0x1UL) /*!< POLYSEL (Bitfield-Mask: 0x01) */ +#define CRC_CR_VERF_Pos (1UL) /*!< VERF (Bit 1) */ +#define CRC_CR_VERF_Msk (0x2UL) /*!< VERF (Bitfield-Mask: 0x01) */ +/* ========================================================== DIN ========================================================== */ +#define CRC_DIN_DIN_Pos (0UL) /*!< DIN (Bit 0) */ +#define CRC_DIN_DIN_Msk (0xffffffffUL) /*!< DIN (Bitfield-Mask: 0xffffffff) */ +/* ========================================================= DOUT ========================================================== */ +#define CRC_DOUT_DOUT_Pos (0UL) /*!< DOUT (Bit 0) */ +#define CRC_DOUT_DOUT_Msk (0xffffffffUL) /*!< DOUT (Bitfield-Mask: 0xffffffff) */ + + +/* =========================================================================================================================== */ +/* ================ DSP ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR =========================================================== */ +#define DSP_CR_MODE_Pos (0UL) /*!< MODE (Bit 0) */ +#define DSP_CR_MODE_Msk (0x7UL) /*!< MODE (Bitfield-Mask: 0x07) */ +/* ========================================================== SR =========================================================== */ +#define DSP_SR_DONE_Pos (0UL) /*!< DONE (Bit 0) */ +#define DSP_SR_DONE_Msk (0x1UL) /*!< DONE (Bitfield-Mask: 0x01) */ +/* ========================================================= SDAT1 ========================================================= */ +/* ========================================================= SDAT2 ========================================================= */ +/* ========================================================= RSLT1 ========================================================= */ +/* ========================================================= RSLT2 ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ OPAMP ================ */ +/* =========================================================================================================================== */ + +/* ======================================================== PGA_CR ========================================================= */ +#define OPAMP_PGA_CR_PGA_EN_Pos (0UL) /*!< PGA_EN (Bit 0) */ +#define OPAMP_PGA_CR_PGA_EN_Msk (0x1UL) /*!< PGA_EN (Bitfield-Mask: 0x01) */ +#define OPAMP_PGA_CR_PGA_IO_EN_Pos (1UL) /*!< PGA_IO_EN (Bit 1) */ +#define OPAMP_PGA_CR_PGA_IO_EN_Msk (0x2UL) /*!< PGA_IO_EN (Bitfield-Mask: 0x01) */ +#define OPAMP_PGA_CR_PGA_GAIN_Pos (2UL) /*!< PGA_GAIN (Bit 2) */ +#define OPAMP_PGA_CR_PGA_GAIN_Msk (0xfcUL) /*!< PGA_GAIN (Bitfield-Mask: 0x3f) */ +#define OPAMP_PGA_CR_PGA_VIN_SEL_Pos (10UL) /*!< PGA_VIN_SEL (Bit 10) */ +#define OPAMP_PGA_CR_PGA_VIN_SEL_Msk (0x400UL) /*!< PGA_VIN_SEL (Bitfield-Mask: 0x01) */ +#define OPAMP_PGA_CR_PGA_VIP_SEL_Pos (11UL) /*!< PGA_VIP_SEL (Bit 11) */ +#define OPAMP_PGA_CR_PGA_VIP_SEL_Msk (0x800UL) /*!< PGA_VIP_SEL (Bitfield-Mask: 0x01) */ + + +/* =========================================================================================================================== */ +/* ================ COMP ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= CTRL ========================================================== */ +#define COMP_CTRL_EN_Pos (0UL) /*!< EN (Bit 0) */ +#define COMP_CTRL_EN_Msk (0x1UL) /*!< EN (Bitfield-Mask: 0x01) */ +#define COMP_CTRL_COUT_Pos (1UL) /*!< COUT (Bit 1) */ +#define COMP_CTRL_COUT_Msk (0x2UL) /*!< COUT (Bitfield-Mask: 0x01) */ +#define COMP_CTRL_VIN_SEL_Pos (2UL) /*!< VIN_SEL (Bit 2) */ +#define COMP_CTRL_VIN_SEL_Msk (0xcUL) /*!< VIN_SEL (Bitfield-Mask: 0x03) */ +#define COMP_CTRL_FIL_CTRL_Pos (4UL) /*!< FIL_CTRL (Bit 4) */ +#define COMP_CTRL_FIL_CTRL_Msk (0xf0UL) /*!< FIL_CTRL (Bitfield-Mask: 0x0f) */ +#define COMP_CTRL_HYS_EN_Pos (8UL) /*!< HYS_EN (Bit 8) */ +#define COMP_CTRL_HYS_EN_Msk (0x100UL) /*!< HYS_EN (Bitfield-Mask: 0x01) */ +#define COMP_CTRL_OUT_EN_Pos (11UL) /*!< OUT_EN (Bit 11) */ +#define COMP_CTRL_OUT_EN_Msk (0x800UL) /*!< OUT_EN (Bitfield-Mask: 0x01) */ +#define COMP_CTRL_POL_SEL_Pos (12UL) /*!< POL_SEL (Bit 12) */ +#define COMP_CTRL_POL_SEL_Msk (0x1000UL) /*!< POL_SEL (Bitfield-Mask: 0x01) */ +/* ======================================================== VIPSEL ========================================================= */ +#define COMP_VIPSEL_VIP_SEL_Pos (0UL) /*!< VIP_SEL (Bit 0) */ +#define COMP_VIPSEL_VIP_SEL_Msk (0x1fUL) /*!< VIP_SEL (Bitfield-Mask: 0x1f) */ +/* ========================================================== IR =========================================================== */ +#define COMP_IR_FIE_Pos (0UL) /*!< FIE (Bit 0) */ +#define COMP_IR_FIE_Msk (0x1UL) /*!< FIE (Bitfield-Mask: 0x01) */ +#define COMP_IR_RIE_Pos (1UL) /*!< RIE (Bit 1) */ +#define COMP_IR_RIE_Msk (0x2UL) /*!< RIE (Bitfield-Mask: 0x01) */ +/* ========================================================== IF =========================================================== */ +#define COMP_IF_FIF_Pos (0UL) /*!< FIF (Bit 0) */ +#define COMP_IF_FIF_Msk (0x1UL) /*!< FIF (Bitfield-Mask: 0x01) */ +#define COMP_IF_RIF_Pos (1UL) /*!< RIF (Bit 1) */ +#define COMP_IF_RIF_Msk (0x2UL) /*!< RIF (Bitfield-Mask: 0x01) */ +/* ======================================================== INITCNT ======================================================== */ +#define COMP_INITCNT_INIT_DELAY_Pos (0UL) /*!< INIT_DELAY (Bit 0) */ +#define COMP_INITCNT_INIT_DELAY_Msk (0x3ffUL) /*!< INIT_DELAY (Bitfield-Mask: 0x3ff) */ + + +/* =========================================================================================================================== */ +/* ================ TIM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR1 ========================================================== */ +#define TIM_CR1_CEN_Pos (0UL) /*!< CEN (Bit 0) */ +#define TIM_CR1_CEN_Msk (0x1UL) /*!< CEN (Bitfield-Mask: 0x01) */ +#define TIM_CR1_UDIS_Pos (1UL) /*!< UDIS (Bit 1) */ +#define TIM_CR1_UDIS_Msk (0x2UL) /*!< UDIS (Bitfield-Mask: 0x01) */ +#define TIM_CR1_URS_Pos (2UL) /*!< URS (Bit 2) */ +#define TIM_CR1_URS_Msk (0x4UL) /*!< URS (Bitfield-Mask: 0x01) */ +#define TIM_CR1_OPM_Pos (3UL) /*!< OPM (Bit 3) */ +#define TIM_CR1_OPM_Msk (0x8UL) /*!< OPM (Bitfield-Mask: 0x01) */ +#define TIM_CR1_DIR_Pos (4UL) /*!< DIR (Bit 4) */ +#define TIM_CR1_DIR_Msk (0x10UL) /*!< DIR (Bitfield-Mask: 0x01) */ +#define TIM_CR1_CMS_Pos (5UL) /*!< CMS (Bit 5) */ +#define TIM_CR1_CMS_Msk (0x60UL) /*!< CMS (Bitfield-Mask: 0x03) */ +#define TIM_CR1_ARPE_Pos (7UL) /*!< ARPE (Bit 7) */ +#define TIM_CR1_ARPE_Msk (0x80UL) /*!< ARPE (Bitfield-Mask: 0x01) */ +#define TIM_CR1_CKD_Pos (8UL) /*!< CKD (Bit 8) */ +#define TIM_CR1_CKD_Msk (0x300UL) /*!< CKD (Bitfield-Mask: 0x03) */ +#define TIM_CR1_ASYMEN_Pos (10UL) /*!< ASYMEN (Bit 10) */ +#define TIM_CR1_ASYMEN_Msk (0x400UL) /*!< ASYMEN (Bitfield-Mask: 0x01) */ +/* ========================================================== CR2 ========================================================== */ +#define TIM_CR2_CCPC_Pos (0UL) /*!< CCPC (Bit 0) */ +#define TIM_CR2_CCPC_Msk (0x1UL) /*!< CCPC (Bitfield-Mask: 0x01) */ +#define TIM_CR2_CCUS_Pos (2UL) /*!< CCUS (Bit 2) */ +#define TIM_CR2_CCUS_Msk (0x4UL) /*!< CCUS (Bitfield-Mask: 0x01) */ +#define TIM_CR2_MMS_Pos (4UL) /*!< MMS (Bit 4) */ +#define TIM_CR2_MMS_Msk (0x70UL) /*!< MMS (Bitfield-Mask: 0x07) */ +#define TIM_CR2_TI1S_Pos (7UL) /*!< TI1S (Bit 7) */ +#define TIM_CR2_TI1S_Msk (0x80UL) /*!< TI1S (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS1_Pos (8UL) /*!< OIS1 (Bit 8) */ +#define TIM_CR2_OIS1_Msk (0x100UL) /*!< OIS1 (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS1N_Pos (9UL) /*!< OIS1N (Bit 9) */ +#define TIM_CR2_OIS1N_Msk (0x200UL) /*!< OIS1N (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS2_Pos (10UL) /*!< OIS2 (Bit 10) */ +#define TIM_CR2_OIS2_Msk (0x400UL) /*!< OIS2 (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS2N_Pos (11UL) /*!< OIS2N (Bit 11) */ +#define TIM_CR2_OIS2N_Msk (0x800UL) /*!< OIS2N (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS3_Pos (12UL) /*!< OIS3 (Bit 12) */ +#define TIM_CR2_OIS3_Msk (0x1000UL) /*!< OIS3 (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS3N_Pos (13UL) /*!< OIS3N (Bit 13) */ +#define TIM_CR2_OIS3N_Msk (0x2000UL) /*!< OIS3N (Bitfield-Mask: 0x01) */ +#define TIM_CR2_OIS4_Pos (14UL) /*!< OIS4 (Bit 14) */ +#define TIM_CR2_OIS4_Msk (0x4000UL) /*!< OIS4 (Bitfield-Mask: 0x01) */ +/* ========================================================= SMCR ========================================================== */ +#define TIM_SMCR_SMS_Pos (0UL) /*!< SMS (Bit 0) */ +#define TIM_SMCR_SMS_Msk (0x7UL) /*!< SMS (Bitfield-Mask: 0x07) */ +#define TIM_SMCR_TS_Pos (4UL) /*!< TS (Bit 4) */ +#define TIM_SMCR_TS_Msk (0x70UL) /*!< TS (Bitfield-Mask: 0x07) */ +#define TIM_SMCR_MSM_Pos (7UL) /*!< MSM (Bit 7) */ +#define TIM_SMCR_MSM_Msk (0x80UL) /*!< MSM (Bitfield-Mask: 0x01) */ +#define TIM_SMCR_ETF_Pos (8UL) /*!< ETF (Bit 8) */ +#define TIM_SMCR_ETF_Msk (0xf00UL) /*!< ETF (Bitfield-Mask: 0x0f) */ +#define TIM_SMCR_ETPS_Pos (12UL) /*!< ETPS (Bit 12) */ +#define TIM_SMCR_ETPS_Msk (0x3000UL) /*!< ETPS (Bitfield-Mask: 0x03) */ +#define TIM_SMCR_ECE_Pos (14UL) /*!< ECE (Bit 14) */ +#define TIM_SMCR_ECE_Msk (0x4000UL) /*!< ECE (Bitfield-Mask: 0x01) */ +#define TIM_SMCR_ETP_Pos (15UL) /*!< ETP (Bit 15) */ +#define TIM_SMCR_ETP_Msk (0x8000UL) /*!< ETP (Bitfield-Mask: 0x01) */ +/* ========================================================= DIER ========================================================== */ +#define TIM_DIER_UIE_Pos (0UL) /*!< UIE (Bit 0) */ +#define TIM_DIER_UIE_Msk (0x1UL) /*!< UIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CC1IE_Pos (1UL) /*!< CC1IE (Bit 1) */ +#define TIM_DIER_CC1IE_Msk (0x2UL) /*!< CC1IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CC2IE_Pos (2UL) /*!< CC2IE (Bit 2) */ +#define TIM_DIER_CC2IE_Msk (0x4UL) /*!< CC2IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CC3IE_Pos (3UL) /*!< CC3IE (Bit 3) */ +#define TIM_DIER_CC3IE_Msk (0x8UL) /*!< CC3IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CC4IE_Pos (4UL) /*!< CC4IE (Bit 4) */ +#define TIM_DIER_CC4IE_Msk (0x10UL) /*!< CC4IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_COMIE_Pos (5UL) /*!< COMIE (Bit 5) */ +#define TIM_DIER_COMIE_Msk (0x20UL) /*!< COMIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_TIE_Pos (6UL) /*!< TIE (Bit 6) */ +#define TIM_DIER_TIE_Msk (0x40UL) /*!< TIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_BIE_Pos (7UL) /*!< BIE (Bit 7) */ +#define TIM_DIER_BIE_Msk (0x80UL) /*!< BIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CCD1IE_Pos (8UL) /*!< CCD1IE (Bit 8) */ +#define TIM_DIER_CCD1IE_Msk (0x100UL) /*!< CCD1IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CCD2IE_Pos (9UL) /*!< CCD2IE (Bit 9) */ +#define TIM_DIER_CCD2IE_Msk (0x200UL) /*!< CCD2IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CCD3IE_Pos (10UL) /*!< CCD3IE (Bit 10) */ +#define TIM_DIER_CCD3IE_Msk (0x400UL) /*!< CCD3IE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_OVIE_Pos (11UL) /*!< OVIE (Bit 11) */ +#define TIM_DIER_OVIE_Msk (0x800UL) /*!< OVIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_UDIE_Pos (12UL) /*!< UDIE (Bit 12) */ +#define TIM_DIER_UDIE_Msk (0x1000UL) /*!< UDIE (Bitfield-Mask: 0x01) */ +#define TIM_DIER_CCD4IE_Pos (13UL) /*!< CCD4IE (Bit 13) */ +#define TIM_DIER_CCD4IE_Msk (0x2000UL) /*!< CCD4IE (Bitfield-Mask: 0x01) */ +/* ========================================================== SR =========================================================== */ +#define TIM_SR_UIF_Pos (0UL) /*!< UIF (Bit 0) */ +#define TIM_SR_UIF_Msk (0x1UL) /*!< UIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC1IF_Pos (1UL) /*!< CC1IF (Bit 1) */ +#define TIM_SR_CC1IF_Msk (0x2UL) /*!< CC1IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC2IF_Pos (2UL) /*!< CC2IF (Bit 2) */ +#define TIM_SR_CC2IF_Msk (0x4UL) /*!< CC2IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC3IF_Pos (3UL) /*!< CC3IF (Bit 3) */ +#define TIM_SR_CC3IF_Msk (0x8UL) /*!< CC3IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC4IF_Pos (4UL) /*!< CC4IF (Bit 4) */ +#define TIM_SR_CC4IF_Msk (0x10UL) /*!< CC4IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_COMIF_Pos (5UL) /*!< COMIF (Bit 5) */ +#define TIM_SR_COMIF_Msk (0x20UL) /*!< COMIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_TIF_Pos (6UL) /*!< TIF (Bit 6) */ +#define TIM_SR_TIF_Msk (0x40UL) /*!< TIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_BIF_Pos (7UL) /*!< BIF (Bit 7) */ +#define TIM_SR_BIF_Msk (0x80UL) /*!< BIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC1OF_Pos (9UL) /*!< CC1OF (Bit 9) */ +#define TIM_SR_CC1OF_Msk (0x200UL) /*!< CC1OF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC2OF_Pos (10UL) /*!< CC2OF (Bit 10) */ +#define TIM_SR_CC2OF_Msk (0x400UL) /*!< CC2OF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC3OF_Pos (11UL) /*!< CC3OF (Bit 11) */ +#define TIM_SR_CC3OF_Msk (0x800UL) /*!< CC3OF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CC4OF_Pos (12UL) /*!< CC4OF (Bit 12) */ +#define TIM_SR_CC4OF_Msk (0x1000UL) /*!< CC4OF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CCD1IF_Pos (13UL) /*!< CCD1IF (Bit 13) */ +#define TIM_SR_CCD1IF_Msk (0x2000UL) /*!< CCD1IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CCD2IF_Pos (14UL) /*!< CCD2IF (Bit 14) */ +#define TIM_SR_CCD2IF_Msk (0x4000UL) /*!< CCD2IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CCD3IF_Pos (15UL) /*!< CCD3IF (Bit 15) */ +#define TIM_SR_CCD3IF_Msk (0x8000UL) /*!< CCD3IF (Bitfield-Mask: 0x01) */ +#define TIM_SR_OVIF_Pos (16UL) /*!< OVIF (Bit 16) */ +#define TIM_SR_OVIF_Msk (0x10000UL) /*!< OVIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_UDIF_Pos (17UL) /*!< UDIF (Bit 17) */ +#define TIM_SR_UDIF_Msk (0x20000UL) /*!< UDIF (Bitfield-Mask: 0x01) */ +#define TIM_SR_CCD4IF_Pos (18UL) /*!< CCD4IF (Bit 18) */ +#define TIM_SR_CCD4IF_Msk (0x40000UL) /*!< CCD4IF (Bitfield-Mask: 0x01) */ +/* ========================================================== EGR ========================================================== */ +#define TIM_EGR_UG_Pos (0UL) /*!< UG (Bit 0) */ +#define TIM_EGR_UG_Msk (0x1UL) /*!< UG (Bitfield-Mask: 0x01) */ +#define TIM_EGR_CC1G_Pos (1UL) /*!< CC1G (Bit 1) */ +#define TIM_EGR_CC1G_Msk (0x2UL) /*!< CC1G (Bitfield-Mask: 0x01) */ +#define TIM_EGR_CC2G_Pos (2UL) /*!< CC2G (Bit 2) */ +#define TIM_EGR_CC2G_Msk (0x4UL) /*!< CC2G (Bitfield-Mask: 0x01) */ +#define TIM_EGR_CC3G_Pos (3UL) /*!< CC3G (Bit 3) */ +#define TIM_EGR_CC3G_Msk (0x8UL) /*!< CC3G (Bitfield-Mask: 0x01) */ +#define TIM_EGR_CC4G_Pos (4UL) /*!< CC4G (Bit 4) */ +#define TIM_EGR_CC4G_Msk (0x10UL) /*!< CC4G (Bitfield-Mask: 0x01) */ +#define TIM_EGR_COMG_Pos (5UL) /*!< COMG (Bit 5) */ +#define TIM_EGR_COMG_Msk (0x20UL) /*!< COMG (Bitfield-Mask: 0x01) */ +#define TIM_EGR_TG_Pos (6UL) /*!< TG (Bit 6) */ +#define TIM_EGR_TG_Msk (0x40UL) /*!< TG (Bitfield-Mask: 0x01) */ +#define TIM_EGR_BG_Pos (7UL) /*!< BG (Bit 7) */ +#define TIM_EGR_BG_Msk (0x80UL) /*!< BG (Bitfield-Mask: 0x01) */ +/* ===================================================== CCMR1_OUTPUT ====================================================== */ +#define TIM_CCMR1_OUTPUT_CC1S_Pos (0UL) /*!< CC1S (Bit 0) */ +#define TIM_CCMR1_OUTPUT_CC1S_Msk (0x3UL) /*!< CC1S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_OUTPUT_OC1FE_Pos (2UL) /*!< OC1FE (Bit 2) */ +#define TIM_CCMR1_OUTPUT_OC1FE_Msk (0x4UL) /*!< OC1FE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR1_OUTPUT_OC1PE_Pos (3UL) /*!< OC1PE (Bit 3) */ +#define TIM_CCMR1_OUTPUT_OC1PE_Msk (0x8UL) /*!< OC1PE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR1_OUTPUT_OC1M_Pos (4UL) /*!< OC1M (Bit 4) */ +#define TIM_CCMR1_OUTPUT_OC1M_Msk (0x70UL) /*!< OC1M (Bitfield-Mask: 0x07) */ +#define TIM_CCMR1_OUTPUT_OC1CE_Pos (7UL) /*!< OC1CE (Bit 7) */ +#define TIM_CCMR1_OUTPUT_OC1CE_Msk (0x80UL) /*!< OC1CE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR1_OUTPUT_CC2S_Pos (8UL) /*!< CC2S (Bit 8) */ +#define TIM_CCMR1_OUTPUT_CC2S_Msk (0x300UL) /*!< CC2S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_OUTPUT_OC2FE_Pos (10UL) /*!< OC2FE (Bit 10) */ +#define TIM_CCMR1_OUTPUT_OC2FE_Msk (0x400UL) /*!< OC2FE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR1_OUTPUT_OC2PE_Pos (11UL) /*!< OC2PE (Bit 11) */ +#define TIM_CCMR1_OUTPUT_OC2PE_Msk (0x800UL) /*!< OC2PE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR1_OUTPUT_OC2M_Pos (12UL) /*!< OC2M (Bit 12) */ +#define TIM_CCMR1_OUTPUT_OC2M_Msk (0x7000UL) /*!< OC2M (Bitfield-Mask: 0x07) */ +#define TIM_CCMR1_OUTPUT_OC2CE_Pos (15UL) /*!< OC2CE (Bit 15) */ +#define TIM_CCMR1_OUTPUT_OC2CE_Msk (0x8000UL) /*!< OC2CE (Bitfield-Mask: 0x01) */ +/* ====================================================== CCMR1_INPUT ====================================================== */ +#define TIM_CCMR1_INPUT_CC1S_Pos (0UL) /*!< CC1S (Bit 0) */ +#define TIM_CCMR1_INPUT_CC1S_Msk (0x3UL) /*!< CC1S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_INPUT_IC1PSC_Pos (2UL) /*!< IC1PSC (Bit 2) */ +#define TIM_CCMR1_INPUT_IC1PSC_Msk (0xcUL) /*!< IC1PSC (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_INPUT_IC1F_Pos (4UL) /*!< IC1F (Bit 4) */ +#define TIM_CCMR1_INPUT_IC1F_Msk (0xf0UL) /*!< IC1F (Bitfield-Mask: 0x0f) */ +#define TIM_CCMR1_INPUT_CC2S_Pos (8UL) /*!< CC2S (Bit 8) */ +#define TIM_CCMR1_INPUT_CC2S_Msk (0x300UL) /*!< CC2S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_INPUT_IC2PSC_Pos (10UL) /*!< IC2PSC (Bit 10) */ +#define TIM_CCMR1_INPUT_IC2PSC_Msk (0xc00UL) /*!< IC2PSC (Bitfield-Mask: 0x03) */ +#define TIM_CCMR1_INPUT_IC2F_Pos (12UL) /*!< IC2F (Bit 12) */ +#define TIM_CCMR1_INPUT_IC2F_Msk (0xf000UL) /*!< IC2F (Bitfield-Mask: 0x0f) */ +/* ===================================================== CCMR2_OUTPUT ====================================================== */ +#define TIM_CCMR2_OUTPUT_CC3S_Pos (0UL) /*!< CC3S (Bit 0) */ +#define TIM_CCMR2_OUTPUT_CC3S_Msk (0x3UL) /*!< CC3S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_OUTPUT_OC3FE_Pos (2UL) /*!< OC3FE (Bit 2) */ +#define TIM_CCMR2_OUTPUT_OC3FE_Msk (0x4UL) /*!< OC3FE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR2_OUTPUT_OC3PE_Pos (3UL) /*!< OC3PE (Bit 3) */ +#define TIM_CCMR2_OUTPUT_OC3PE_Msk (0x8UL) /*!< OC3PE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR2_OUTPUT_OC3M_Pos (4UL) /*!< OC3M (Bit 4) */ +#define TIM_CCMR2_OUTPUT_OC3M_Msk (0x70UL) /*!< OC3M (Bitfield-Mask: 0x07) */ +#define TIM_CCMR2_OUTPUT_OC3CE_Pos (7UL) /*!< OC3CE (Bit 7) */ +#define TIM_CCMR2_OUTPUT_OC3CE_Msk (0x80UL) /*!< OC3CE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR2_OUTPUT_CC4S_Pos (8UL) /*!< CC4S (Bit 8) */ +#define TIM_CCMR2_OUTPUT_CC4S_Msk (0x300UL) /*!< CC4S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_OUTPUT_OC4FE_Pos (10UL) /*!< OC4FE (Bit 10) */ +#define TIM_CCMR2_OUTPUT_OC4FE_Msk (0x400UL) /*!< OC4FE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR2_OUTPUT_OC4PE_Pos (11UL) /*!< OC4PE (Bit 11) */ +#define TIM_CCMR2_OUTPUT_OC4PE_Msk (0x800UL) /*!< OC4PE (Bitfield-Mask: 0x01) */ +#define TIM_CCMR2_OUTPUT_OC4M_Pos (12UL) /*!< OC4M (Bit 12) */ +#define TIM_CCMR2_OUTPUT_OC4M_Msk (0x7000UL) /*!< OC4M (Bitfield-Mask: 0x07) */ +#define TIM_CCMR2_OUTPUT_OC4CE_Pos (15UL) /*!< OC4CE (Bit 15) */ +#define TIM_CCMR2_OUTPUT_OC4CE_Msk (0x8000UL) /*!< OC4CE (Bitfield-Mask: 0x01) */ +/* ====================================================== CCMR2_INPUT ====================================================== */ +#define TIM_CCMR2_INPUT_CC3S_Pos (0UL) /*!< CC3S (Bit 0) */ +#define TIM_CCMR2_INPUT_CC3S_Msk (0x3UL) /*!< CC3S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_INPUT_IC3PSC_Pos (2UL) /*!< IC3PSC (Bit 2) */ +#define TIM_CCMR2_INPUT_IC3PSC_Msk (0xcUL) /*!< IC3PSC (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_INPUT_IC3F_Pos (4UL) /*!< IC3F (Bit 4) */ +#define TIM_CCMR2_INPUT_IC3F_Msk (0xf0UL) /*!< IC3F (Bitfield-Mask: 0x0f) */ +#define TIM_CCMR2_INPUT_CC4S_Pos (8UL) /*!< CC4S (Bit 8) */ +#define TIM_CCMR2_INPUT_CC4S_Msk (0x300UL) /*!< CC4S (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_INPUT_IC4PSC_Pos (10UL) /*!< IC4PSC (Bit 10) */ +#define TIM_CCMR2_INPUT_IC4PSC_Msk (0xc00UL) /*!< IC4PSC (Bitfield-Mask: 0x03) */ +#define TIM_CCMR2_INPUT_IC4F_Pos (12UL) /*!< IC4F (Bit 12) */ +#define TIM_CCMR2_INPUT_IC4F_Msk (0xf000UL) /*!< IC4F (Bitfield-Mask: 0x0f) */ +/* ========================================================= CCER ========================================================== */ +#define TIM_CCER_CC1E_Pos (0UL) /*!< CC1E (Bit 0) */ +#define TIM_CCER_CC1E_Msk (0x1UL) /*!< CC1E (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC1P_Pos (1UL) /*!< CC1P (Bit 1) */ +#define TIM_CCER_CC1P_Msk (0x2UL) /*!< CC1P (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC1NE_Pos (2UL) /*!< CC1NE (Bit 2) */ +#define TIM_CCER_CC1NE_Msk (0x4UL) /*!< CC1NE (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC1NP_Pos (3UL) /*!< CC1NP (Bit 3) */ +#define TIM_CCER_CC1NP_Msk (0x8UL) /*!< CC1NP (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC2E_Pos (4UL) /*!< CC2E (Bit 4) */ +#define TIM_CCER_CC2E_Msk (0x10UL) /*!< CC2E (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC2P_Pos (5UL) /*!< CC2P (Bit 5) */ +#define TIM_CCER_CC2P_Msk (0x20UL) /*!< CC2P (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC2NE_Pos (6UL) /*!< CC2NE (Bit 6) */ +#define TIM_CCER_CC2NE_Msk (0x40UL) /*!< CC2NE (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC2NP_Pos (7UL) /*!< CC2NP (Bit 7) */ +#define TIM_CCER_CC2NP_Msk (0x80UL) /*!< CC2NP (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC3E_Pos (8UL) /*!< CC3E (Bit 8) */ +#define TIM_CCER_CC3E_Msk (0x100UL) /*!< CC3E (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC3P_Pos (9UL) /*!< CC3P (Bit 9) */ +#define TIM_CCER_CC3P_Msk (0x200UL) /*!< CC3P (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC3NE_Pos (10UL) /*!< CC3NE (Bit 10) */ +#define TIM_CCER_CC3NE_Msk (0x400UL) /*!< CC3NE (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC3NP_Pos (11UL) /*!< CC3NP (Bit 11) */ +#define TIM_CCER_CC3NP_Msk (0x800UL) /*!< CC3NP (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC4E_Pos (12UL) /*!< CC4E (Bit 12) */ +#define TIM_CCER_CC4E_Msk (0x1000UL) /*!< CC4E (Bitfield-Mask: 0x01) */ +#define TIM_CCER_CC4P_Pos (13UL) /*!< CC4P (Bit 13) */ +#define TIM_CCER_CC4P_Msk (0x2000UL) /*!< CC4P (Bitfield-Mask: 0x01) */ +/* ========================================================== CNT ========================================================== */ +#define TIM_CNT_CNT_Pos (0UL) /*!< CNT (Bit 0) */ +#define TIM_CNT_CNT_Msk (0xffffUL) /*!< CNT (Bitfield-Mask: 0xffff) */ +/* ========================================================== PSC ========================================================== */ +#define TIM_PSC_PSC_Pos (0UL) /*!< PSC (Bit 0) */ +#define TIM_PSC_PSC_Msk (0xffffUL) /*!< PSC (Bitfield-Mask: 0xffff) */ +/* ========================================================== ARR ========================================================== */ +#define TIM_ARR_ARR_Pos (0UL) /*!< ARR (Bit 0) */ +#define TIM_ARR_ARR_Msk (0xffffUL) /*!< ARR (Bitfield-Mask: 0xffff) */ +/* ========================================================== RCR ========================================================== */ +#define TIM_RCR_REP_Pos (0UL) /*!< REP (Bit 0) */ +#define TIM_RCR_REP_Msk (0xffUL) /*!< REP (Bitfield-Mask: 0xff) */ +/* ========================================================= CCR1 ========================================================== */ +#define TIM_CCR1_CCR1_Pos (0UL) /*!< CCR1 (Bit 0) */ +#define TIM_CCR1_CCR1_Msk (0xfffffUL) /*!< CCR1 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCR2 ========================================================== */ +#define TIM_CCR2_CCR2_Pos (0UL) /*!< CCR2 (Bit 0) */ +#define TIM_CCR2_CCR2_Msk (0xfffffUL) /*!< CCR2 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCR3 ========================================================== */ +#define TIM_CCR3_CCR3_Pos (0UL) /*!< CCR3 (Bit 0) */ +#define TIM_CCR3_CCR3_Msk (0xfffffUL) /*!< CCR3 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCR4 ========================================================== */ +#define TIM_CCR4_CCR4_Pos (0UL) /*!< CCR4 (Bit 0) */ +#define TIM_CCR4_CCR4_Msk (0xfffffUL) /*!< CCR4 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= BDTR ========================================================== */ +#define TIM_BDTR_DTG_Pos (0UL) /*!< DTG (Bit 0) */ +#define TIM_BDTR_DTG_Msk (0xffUL) /*!< DTG (Bitfield-Mask: 0xff) */ +#define TIM_BDTR_LOCK_Pos (8UL) /*!< LOCK (Bit 8) */ +#define TIM_BDTR_LOCK_Msk (0x300UL) /*!< LOCK (Bitfield-Mask: 0x03) */ +#define TIM_BDTR_OSSI_Pos (10UL) /*!< OSSI (Bit 10) */ +#define TIM_BDTR_OSSI_Msk (0x400UL) /*!< OSSI (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_OSSR_Pos (11UL) /*!< OSSR (Bit 11) */ +#define TIM_BDTR_OSSR_Msk (0x800UL) /*!< OSSR (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_BKE_Pos (12UL) /*!< BKE (Bit 12) */ +#define TIM_BDTR_BKE_Msk (0x1000UL) /*!< BKE (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_BKP_Pos (13UL) /*!< BKP (Bit 13) */ +#define TIM_BDTR_BKP_Msk (0x2000UL) /*!< BKP (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_AOE_Pos (14UL) /*!< AOE (Bit 14) */ +#define TIM_BDTR_AOE_Msk (0x4000UL) /*!< AOE (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_MOE_Pos (15UL) /*!< MOE (Bit 15) */ +#define TIM_BDTR_MOE_Msk (0x8000UL) /*!< MOE (Bitfield-Mask: 0x01) */ +#define TIM_BDTR_DTGF_Pos (16UL) /*!< DTGF (Bit 16) */ +#define TIM_BDTR_DTGF_Msk (0xff0000UL) /*!< DTGF (Bitfield-Mask: 0xff) */ +#define TIM_BDTR_DTAE_Pos (24UL) /*!< DTAE (Bit 24) */ +#define TIM_BDTR_DTAE_Msk (0x1000000UL) /*!< DTAE (Bitfield-Mask: 0x01) */ +/* ========================================================= CCDR1 ========================================================= */ +#define TIM_CCDR1_CCDR1_Pos (0UL) /*!< CCDR1 (Bit 0) */ +#define TIM_CCDR1_CCDR1_Msk (0xfffffUL) /*!< CCDR1 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCDR2 ========================================================= */ +#define TIM_CCDR2_CCDR2_Pos (0UL) /*!< CCDR2 (Bit 0) */ +#define TIM_CCDR2_CCDR2_Msk (0xfffffUL) /*!< CCDR2 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCDR3 ========================================================= */ +#define TIM_CCDR3_CCDR3_Pos (0UL) /*!< CCDR3 (Bit 0) */ +#define TIM_CCDR3_CCDR3_Msk (0xfffffUL) /*!< CCDR3 (Bitfield-Mask: 0xfffff) */ +/* ========================================================= CCDR4 ========================================================= */ +#define TIM_CCDR4_CCDR4_Pos (0UL) /*!< CCDR4 (Bit 0) */ +#define TIM_CCDR4_CCDR4_Msk (0xfffffUL) /*!< CCDR4 (Bitfield-Mask: 0xfffff) */ + + +/* =========================================================================================================================== */ +/* ================ LPTIM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== IR =========================================================== */ +#define LPTIM_IR_MR0_Pos (0UL) /*!< MR0 (Bit 0) */ +#define LPTIM_IR_MR0_Msk (0x1UL) /*!< MR0 (Bitfield-Mask: 0x01) */ +/* ========================================================== TCR ========================================================== */ +#define LPTIM_TCR_CEN_Pos (0UL) /*!< CEN (Bit 0) */ +#define LPTIM_TCR_CEN_Msk (0x1UL) /*!< CEN (Bitfield-Mask: 0x01) */ +#define LPTIM_TCR_CRST_Pos (1UL) /*!< CRST (Bit 1) */ +#define LPTIM_TCR_CRST_Msk (0x2UL) /*!< CRST (Bitfield-Mask: 0x01) */ +#define LPTIM_TCR_CLKS_Pos (2UL) /*!< CLKS (Bit 2) */ +#define LPTIM_TCR_CLKS_Msk (0xcUL) /*!< CLKS (Bitfield-Mask: 0x03) */ +#define LPTIM_TCR_TRIGSEL_Pos (4UL) /*!< TRIGSEL (Bit 4) */ +#define LPTIM_TCR_TRIGSEL_Msk (0x70UL) /*!< TRIGSEL (Bitfield-Mask: 0x07) */ +/* ========================================================== TC =========================================================== */ +#define LPTIM_TC_TC_Pos (0UL) /*!< TC (Bit 0) */ +#define LPTIM_TC_TC_Msk (0xffffUL) /*!< TC (Bitfield-Mask: 0xffff) */ +/* ========================================================== PR =========================================================== */ +#define LPTIM_PR_PR_Pos (0UL) /*!< PR (Bit 0) */ +#define LPTIM_PR_PR_Msk (0xffUL) /*!< PR (Bitfield-Mask: 0xff) */ +/* ========================================================== PC =========================================================== */ +#define LPTIM_PC_PC_Pos (0UL) /*!< PC (Bit 0) */ +#define LPTIM_PC_PC_Msk (0xffUL) /*!< PC (Bitfield-Mask: 0xff) */ +/* ========================================================== MCR ========================================================== */ +#define LPTIM_MCR_MR0INT_Pos (0UL) /*!< MR0INT (Bit 0) */ +#define LPTIM_MCR_MR0INT_Msk (0x1UL) /*!< MR0INT (Bitfield-Mask: 0x01) */ +#define LPTIM_MCR_MR0RST_Pos (1UL) /*!< MR0RST (Bit 1) */ +#define LPTIM_MCR_MR0RST_Msk (0x2UL) /*!< MR0RST (Bitfield-Mask: 0x01) */ +#define LPTIM_MCR_MR0STOP_Pos (2UL) /*!< MR0STOP (Bit 2) */ +#define LPTIM_MCR_MR0STOP_Msk (0x4UL) /*!< MR0STOP (Bitfield-Mask: 0x01) */ +/* ========================================================== MR0 ========================================================== */ +#define LPTIM_MR0_MR0_Pos (0UL) /*!< MR0 (Bit 0) */ +#define LPTIM_MR0_MR0_Msk (0xffffUL) /*!< MR0 (Bitfield-Mask: 0xffff) */ + +/** @} */ /* End of group PosMask_peripherals */ + + +/* =========================================================================================================================== */ +/* ================ Enumerated Values Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup EnumValue_peripherals + * @{ + */ + + + +/* =========================================================================================================================== */ +/* ================ EFLASH_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ SRAM_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ NVR_MEM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= DATA0 ========================================================= */ +/* ======================================================= DATA_END ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ CORET ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= revd ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ UID ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= UID1 ========================================================== */ +/* ========================================================= UID2 ========================================================== */ +/* ========================================================= UID3 ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ FLASH ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CMD ========================================================== */ +/* ================================================= FLASH CMD CMD [1..3] ================================================== */ +typedef enum { /*!< FLASH_CMD_CMD */ + FLASH_CMD_CMD_PROG = 0, /*!< PROG : Flash 32-bits program */ + FLASH_CMD_CMD_ERASE_SECTOR = 1, /*!< ERASE_SECTOR : Flash sector erase */ + FLASH_CMD_CMD_ERASE_CHIP = 2, /*!< ERASE_CHIP : Flash chip erase */ +} FLASH_CMD_CMD_Enum; + +/* ========================================================== SR =========================================================== */ +/* ========================================================== AR =========================================================== */ +/* ========================================================== DR =========================================================== */ +/* ========================================================== ACM ========================================================== */ +/* ========================================================== DIV ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ GPIO ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== DAT ========================================================== */ +/* ========================================================== LAT ========================================================== */ +/* ========================================================= ITS1 ========================================================== */ +/* ========================================================= ITC1 ========================================================== */ +/* ========================================================== OES ========================================================== */ +/* ========================================================== OEC ========================================================== */ +/* ========================================================= INES ========================================================== */ +/* ========================================================= INEC ========================================================== */ +/* ========================================================== IES ========================================================== */ +/* ========================================================== IEC ========================================================== */ +/* ========================================================= ITS0 ========================================================== */ +/* ========================================================= ITC0 ========================================================== */ +/* ========================================================== PLS ========================================================== */ +/* ========================================================== PLC ========================================================== */ +/* ========================================================== IST ========================================================== */ +/* ========================================================== PUS ========================================================== */ +/* ========================================================== PUC ========================================================== */ +/* ========================================================== ODS ========================================================== */ +/* ========================================================== ODC ========================================================== */ +/* ========================================================== PDS ========================================================== */ +/* ========================================================== PDC ========================================================== */ +/* ========================================================= OSRS ========================================================== */ +/* ========================================================= OSRC ========================================================== */ +/* ========================================================== CTS ========================================================== */ +/* ========================================================== CTC ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ AFIO ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= PAAFR ========================================================= */ +/* ========================================================= PBAFR ========================================================= */ +/* ======================================================== FN1_AFR ======================================================== */ +/* ======================================================== FN2_AFR ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ SYSCFG ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= PMUCR ========================================================= */ +/* ========================================================= MCOCR ========================================================= */ +/* ============================================== SYSCFG MCOCR MCOSEL [0..2] =============================================== */ +typedef enum { /*!< SYSCFG_MCOCR_MCOSEL */ + SYSCFG_MCOCR_MCOSEL_HSI = 0, /*!< HSI : HSI RC clock */ + SYSCFG_MCOCR_MCOSEL_HSE = 1, /*!< HSE : HSE OSC clock */ + SYSCFG_MCOCR_MCOSEL_CLKDIV = 2, /*!< CLKDIV : HSI Clock Divider */ + SYSCFG_MCOCR_MCOSEL_LSI = 3, /*!< LSI : LSI RC clock */ + SYSCFG_MCOCR_MCOSEL_FCLK = 4, /*!< FCLK : F clock */ + SYSCFG_MCOCR_MCOSEL_GND = 7, /*!< GND : Peripheral clock */ +} SYSCFG_MCOCR_MCOSEL_Enum; + +/* ============================================= SYSCFG MCOCR SWRstEn [16..23] ============================================= */ +typedef enum { /*!< SYSCFG_MCOCR_SWRstEn */ + SYSCFG_MCOCR_SWRstEn_OFF = 0, /*!< OFF : Software reset off */ + SYSCFG_MCOCR_SWRstEn_ON = 90, /*!< ON : Software reset on */ +} SYSCFG_MCOCR_SWRstEn_Enum; + +/* ======================================================= SYSRSTSR ======================================================== */ +/* ===================================================== REBOOT_UNLOCK ===================================================== */ +/* ======================================================= SYSRSTCR ======================================================== */ +/* ======================================================= DEBUGENCR ======================================================= */ +/* ======================================================= SYSCLKCR ======================================================== */ +/* ============================================= SYSCFG SYSCLKCR CLKSW [0..2] ============================================== */ +typedef enum { /*!< SYSCFG_SYSCLKCR_CLKSW */ + SYSCFG_SYSCLKCR_CLKSW_HSI = 0, /*!< HSI : HSI RC clock source */ + SYSCFG_SYSCLKCR_CLKSW_HSE = 1, /*!< HSE : HSE OSC clock source */ + SYSCFG_SYSCLKCR_CLKSW_CLKDIV = 2, /*!< CLKDIV : Clock Divider source */ + SYSCFG_SYSCLKCR_CLKSW_LSI = 3, /*!< LSI : LSI RC clock source */ +} SYSCFG_SYSCLKCR_CLKSW_Enum; + +/* ========================================== SYSCFG SYSCLKCR SYSTICKCR [24..25] =========================================== */ +typedef enum { /*!< SYSCFG_SYSCLKCR_SYSTICKCR */ + SYSCFG_SYSCLKCR_SYSTICKCR_LSI = 0, /*!< LSI : Systick from LSI */ + SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV2 = 1, /*!< HSI_DIV2 : Systick from HSI Divide 2 */ + SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV4 = 2, /*!< HSI_DIV4 : Systick from HSI Divide 4 */ + SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV8 = 3, /*!< HSI_DIV8 : Systick from HSI Divide 8 */ +} SYSCFG_SYSCLKCR_SYSTICKCR_Enum; + +/* ======================================================== PRSTEN ========================================================= */ +/* ======================================================== PCLKEN ========================================================= */ +/* ======================================================== ICEIOCR ======================================================== */ +/* ======================================================= RSTPINCR ======================================================== */ +/* =========================================== SYSCFG RSTPINCR RSTPINAF [0..15] ============================================ */ +typedef enum { /*!< SYSCFG_RSTPINCR_RSTPINAF */ + SYSCFG_RSTPINCR_RSTPINAF_ON = 42339, /*!< ON : Enable reset pin */ + SYSCFG_RSTPINCR_RSTPINAF_OFF = 0, /*!< OFF : Disable reset pin (Pin changes to I/O) */ +} SYSCFG_RSTPINCR_RSTPINAF_Enum; + +/* ===================================================== TIM2_CON_SEL ====================================================== */ +/* ============================================ SYSCFG TIM2_CON_SEL CH1 [0..2] ============================================= */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_CH1 */ + SYSCFG_TIM2_CON_SEL_CH1_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_TIM2_CON_SEL_CH1_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_TIM2_CON_SEL_CH1_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_TIM2_CON_SEL_CH1_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_TIM2_CON_SEL_CH1_Enum; + +/* ============================================ SYSCFG TIM2_CON_SEL CH2 [4..6] ============================================= */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_CH2 */ + SYSCFG_TIM2_CON_SEL_CH2_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_TIM2_CON_SEL_CH2_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_TIM2_CON_SEL_CH2_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_TIM2_CON_SEL_CH2_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_TIM2_CON_SEL_CH2_Enum; + +/* ============================================ SYSCFG TIM2_CON_SEL CH3 [8..10] ============================================ */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_CH3 */ + SYSCFG_TIM2_CON_SEL_CH3_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_TIM2_CON_SEL_CH3_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_TIM2_CON_SEL_CH3_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_TIM2_CON_SEL_CH3_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_TIM2_CON_SEL_CH3_Enum; + +/* =========================================== SYSCFG TIM2_CON_SEL CH4 [12..14] ============================================ */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_CH4 */ + SYSCFG_TIM2_CON_SEL_CH4_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_TIM2_CON_SEL_CH4_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_TIM2_CON_SEL_CH4_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_TIM2_CON_SEL_CH4_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_TIM2_CON_SEL_CH4_Enum; + +/* ======================================== SYSCFG TIM2_CON_SEL VC_CH1_INV [20..20] ======================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH1_INV */ + SYSCFG_TIM2_CON_SEL_VC_CH1_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_TIM2_CON_SEL_VC_CH1_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_TIM2_CON_SEL_VC_CH1_INV_Enum; + +/* ========================================== SYSCFG TIM2_CON_SEL VC_CH1 [21..21] ========================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH1 */ + SYSCFG_TIM2_CON_SEL_VC_CH1_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_ch1_inv)) */ + SYSCFG_TIM2_CON_SEL_VC_CH1_1 = 1, /*!< 1 : CH1_CON[2:0] */ +} SYSCFG_TIM2_CON_SEL_VC_CH1_Enum; + +/* ======================================== SYSCFG TIM2_CON_SEL VC_CH2_INV [22..22] ======================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH2_INV */ + SYSCFG_TIM2_CON_SEL_VC_CH2_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_TIM2_CON_SEL_VC_CH2_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_TIM2_CON_SEL_VC_CH2_INV_Enum; + +/* ========================================== SYSCFG TIM2_CON_SEL VC_CH2 [23..23] ========================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH2 */ + SYSCFG_TIM2_CON_SEL_VC_CH2_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH2_inv)) */ + SYSCFG_TIM2_CON_SEL_VC_CH2_1 = 1, /*!< 1 : CH2_CON[6:4] */ +} SYSCFG_TIM2_CON_SEL_VC_CH2_Enum; + +/* ======================================== SYSCFG TIM2_CON_SEL VC_CH3_INV [24..24] ======================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH3_INV */ + SYSCFG_TIM2_CON_SEL_VC_CH3_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_TIM2_CON_SEL_VC_CH3_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_TIM2_CON_SEL_VC_CH3_INV_Enum; + +/* ========================================== SYSCFG TIM2_CON_SEL VC_CH3 [25..25] ========================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH3 */ + SYSCFG_TIM2_CON_SEL_VC_CH3_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH3_inv)) */ + SYSCFG_TIM2_CON_SEL_VC_CH3_1 = 1, /*!< 1 : CH3_CON[[10:8] */ +} SYSCFG_TIM2_CON_SEL_VC_CH3_Enum; + +/* ======================================== SYSCFG TIM2_CON_SEL VC_CH4_INV [26..26] ======================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH4_INV */ + SYSCFG_TIM2_CON_SEL_VC_CH4_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_TIM2_CON_SEL_VC_CH4_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_TIM2_CON_SEL_VC_CH4_INV_Enum; + +/* ========================================== SYSCFG TIM2_CON_SEL VC_CH4 [27..27] ========================================== */ +typedef enum { /*!< SYSCFG_TIM2_CON_SEL_VC_CH4 */ + SYSCFG_TIM2_CON_SEL_VC_CH4_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH4_inv)) */ + SYSCFG_TIM2_CON_SEL_VC_CH4_1 = 1, /*!< 1 : CH4_CON[14:12] */ +} SYSCFG_TIM2_CON_SEL_VC_CH4_Enum; + +/* ===================================================== EPWM_CON_SEL ====================================================== */ +/* ============================================ SYSCFG EPWM_CON_SEL CH1 [0..2] ============================================= */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_CH1 */ + SYSCFG_EPWM_CON_SEL_CH1_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_EPWM_CON_SEL_CH1_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_EPWM_CON_SEL_CH1_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_EPWM_CON_SEL_CH1_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_EPWM_CON_SEL_CH1_Enum; + +/* ============================================ SYSCFG EPWM_CON_SEL CH2 [4..6] ============================================= */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_CH2 */ + SYSCFG_EPWM_CON_SEL_CH2_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_EPWM_CON_SEL_CH2_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_EPWM_CON_SEL_CH2_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_EPWM_CON_SEL_CH2_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_EPWM_CON_SEL_CH2_Enum; + +/* ============================================ SYSCFG EPWM_CON_SEL CH3 [8..10] ============================================ */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_CH3 */ + SYSCFG_EPWM_CON_SEL_CH3_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_EPWM_CON_SEL_CH3_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_EPWM_CON_SEL_CH3_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_EPWM_CON_SEL_CH3_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_EPWM_CON_SEL_CH3_Enum; + +/* =========================================== SYSCFG EPWM_CON_SEL CH4 [12..14] ============================================ */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_CH4 */ + SYSCFG_EPWM_CON_SEL_CH4_PAD = 0, /*!< PAD : From PAD */ + SYSCFG_EPWM_CON_SEL_CH4_UART = 1, /*!< UART : From UART0_RXD */ + SYSCFG_EPWM_CON_SEL_CH4_IIC = 2, /*!< IIC : From IIC_SDA */ + SYSCFG_EPWM_CON_SEL_CH4_OSC32K = 4, /*!< OSC32K : From OSC_32K */ +} SYSCFG_EPWM_CON_SEL_CH4_Enum; + +/* ======================================== SYSCFG EPWM_CON_SEL VC_CH1_INV [20..20] ======================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH1_INV */ + SYSCFG_EPWM_CON_SEL_VC_CH1_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_EPWM_CON_SEL_VC_CH1_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_EPWM_CON_SEL_VC_CH1_INV_Enum; + +/* ========================================== SYSCFG EPWM_CON_SEL VC_CH1 [21..21] ========================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH1 */ + SYSCFG_EPWM_CON_SEL_VC_CH1_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_ch1_inv)) */ + SYSCFG_EPWM_CON_SEL_VC_CH1_1 = 1, /*!< 1 : CH1_CON[2:0] */ +} SYSCFG_EPWM_CON_SEL_VC_CH1_Enum; + +/* ======================================== SYSCFG EPWM_CON_SEL VC_CH2_INV [22..22] ======================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH2_INV */ + SYSCFG_EPWM_CON_SEL_VC_CH2_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_EPWM_CON_SEL_VC_CH2_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_EPWM_CON_SEL_VC_CH2_INV_Enum; + +/* ========================================== SYSCFG EPWM_CON_SEL VC_CH2 [23..23] ========================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH2 */ + SYSCFG_EPWM_CON_SEL_VC_CH2_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH2_inv)) */ + SYSCFG_EPWM_CON_SEL_VC_CH2_1 = 1, /*!< 1 : CH2_CON[6:4] */ +} SYSCFG_EPWM_CON_SEL_VC_CH2_Enum; + +/* ======================================== SYSCFG EPWM_CON_SEL VC_CH3_INV [24..24] ======================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH3_INV */ + SYSCFG_EPWM_CON_SEL_VC_CH3_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_EPWM_CON_SEL_VC_CH3_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_EPWM_CON_SEL_VC_CH3_INV_Enum; + +/* ========================================== SYSCFG EPWM_CON_SEL VC_CH3 [25..25] ========================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH3 */ + SYSCFG_EPWM_CON_SEL_VC_CH3_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH3_inv)) */ + SYSCFG_EPWM_CON_SEL_VC_CH3_1 = 1, /*!< 1 : CH3_CON[[10:8] */ +} SYSCFG_EPWM_CON_SEL_VC_CH3_Enum; + +/* ======================================== SYSCFG EPWM_CON_SEL VC_CH4_INV [26..26] ======================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH4_INV */ + SYSCFG_EPWM_CON_SEL_VC_CH4_INV_0 = 0, /*!< 0 : COMP */ + SYSCFG_EPWM_CON_SEL_VC_CH4_INV_1 = 1, /*!< 1 : COMP Inverse */ +} SYSCFG_EPWM_CON_SEL_VC_CH4_INV_Enum; + +/* ========================================== SYSCFG EPWM_CON_SEL VC_CH4 [27..27] ========================================== */ +typedef enum { /*!< SYSCFG_EPWM_CON_SEL_VC_CH4 */ + SYSCFG_EPWM_CON_SEL_VC_CH4_0 = 0, /*!< 0 : COMP(Used in conjunction with Vc_CH4_inv)) */ + SYSCFG_EPWM_CON_SEL_VC_CH4_1 = 1, /*!< 1 : CH4_CON[14:12] */ +} SYSCFG_EPWM_CON_SEL_VC_CH4_Enum; + +/* ======================================================== PRSTEN1 ======================================================== */ +/* ======================================================== HCLKEN ========================================================= */ +/* ======================================================== EVT_SEL ======================================================== */ +/* ========================================================= NMICR ========================================================= */ +/* ================================================ SYSCFG NMICR EN [5..7] ================================================= */ +typedef enum { /*!< SYSCFG_NMICR_EN */ + SYSCFG_NMICR_EN_ON = 5, /*!< ON : Enable interrupt link to NMI */ + SYSCFG_NMICR_EN_OFF = 0, /*!< OFF : Disable interrupt link to NMI */ +} SYSCFG_NMICR_EN_Enum; + +/* ======================================================== CHIPID ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ UART ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== DAT ========================================================== */ +/* ========================================================== CR =========================================================== */ +/* ================================================== UART CR MODE [0..2] ================================================== */ +typedef enum { /*!< UART_CR_MODE */ + UART_CR_MODE_8D = 1, /*!< 8D : 8-bits data */ + UART_CR_MODE_7D1P = 3, /*!< 7D1P : 7-bits data + 1-bit parity */ + UART_CR_MODE_9D = 4, /*!< 9D : 9-bits data */ + UART_CR_MODE_8D1W = 5, /*!< 8D1W : 8-bits data + 1-bit wake-up */ + UART_CR_MODE_8D1P = 7, /*!< 8D1P : 8-bits data + 1-bit parity */ +} UART_CR_MODE_Enum; + +/* ================================================= UART CR STOPB [3..4] ================================================== */ +typedef enum { /*!< UART_CR_STOPB */ + UART_CR_STOPB_0_5B = 0, /*!< 0_5B : 0.5 bit stop */ + UART_CR_STOPB_1B = 1, /*!< 1B : 1 bit stop */ + UART_CR_STOPB_1_5B = 2, /*!< 1_5B : 1.5 bits stop */ + UART_CR_STOPB_2B = 3, /*!< 2B : 2 bits stop */ +} UART_CR_STOPB_Enum; + +/* ================================================== UART CR PAR [5..5] =================================================== */ +typedef enum { /*!< UART_CR_PAR */ + UART_CR_PAR_EVEN = 0, /*!< EVEN : Even parity check */ + UART_CR_PAR_ODD = 1, /*!< ODD : Odd parity check */ +} UART_CR_PAR_Enum; + +/* ========================================================== BR =========================================================== */ +/* ========================================================== IE =========================================================== */ +/* ========================================================== SR =========================================================== */ +/* ========================================================== GTR ========================================================== */ +/* ========================================================== TOR ========================================================== */ +/* ========================================================= TXFR ========================================================== */ +/* ========================================================= RXFR ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ I2C ================ */ +/* =========================================================================================================================== */ + +/* ======================================================== CTLSET ========================================================= */ +/* ========================================================= STAT ========================================================== */ +/* ========================================================= DATA ========================================================== */ +/* ========================================================= ADDR ========================================================== */ +/* ======================================================== CTLCLR ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ SPI ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CFG ========================================================== */ +/* ========================================================== STA ========================================================== */ +/* ========================================================= INTEN ========================================================= */ +/* ======================================================== INTDIS ========================================================= */ +/* ======================================================== INTMASK ======================================================== */ +/* ========================================================== EN =========================================================== */ +/* ========================================================= DELAY ========================================================= */ +/* ========================================================== TX =========================================================== */ +/* ========================================================== RX =========================================================== */ +/* ======================================================== IDLECNT ======================================================== */ +/* ========================================================= TXTH ========================================================== */ +/* ========================================================= RXTH ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ WDG ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= LOAD ========================================================== */ +/* ========================================================= VALUE ========================================================= */ +/* ========================================================== CR =========================================================== */ +/* ================================================== WDG CR INTE [0..0] =================================================== */ +typedef enum { /*!< WDG_CR_INTE */ + WDG_CR_INTE_IRQ_OFF = 0, /*!< IRQ_OFF : WDT disable interrupt */ + WDG_CR_INTE_IRQ_ON = 1, /*!< IRQ_ON : WDT enable interrupt */ +} WDG_CR_INTE_Enum; + +/* ======================================================== INTCLR ========================================================= */ +/* ========================================================== RIS ========================================================== */ +/* ========================================================== MIS ========================================================== */ +/* ========================================================= LOCK ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ ADC ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= CON0 ========================================================== */ +/* =================================================== ADC CON0 M [0..3] =================================================== */ +typedef enum { /*!< ADC_CON0_M */ + ADC_CON0_M_AIN0 = 0, /*!< AIN0 : Input channel */ + ADC_CON0_M_AIN1 = 1, /*!< AIN1 : Input channel */ + ADC_CON0_M_AIN2 = 2, /*!< AIN2 : Input channel */ + ADC_CON0_M_AIN3 = 3, /*!< AIN3 : Input channel */ + ADC_CON0_M_AIN4 = 4, /*!< AIN4 : Input channel */ + ADC_CON0_M_AIN5 = 5, /*!< AIN5 : Input channel */ + ADC_CON0_M_AIN6 = 6, /*!< AIN6 : Input channel */ + ADC_CON0_M_AIN7 = 7, /*!< AIN7 : Input channel */ + ADC_CON0_M_AIN8 = 8, /*!< AIN8 : Input channel */ + ADC_CON0_M_AIN9 = 9, /*!< AIN9 : Input channel */ + ADC_CON0_M_AIN10 = 10, /*!< AIN10 : Input channel */ + ADC_CON0_M_AIN11 = 11, /*!< AIN11 : Input channel */ + ADC_CON0_M_AIN12 = 12, /*!< AIN12 : Input channel */ + ADC_CON0_M_AIN13 = 13, /*!< AIN13 : Input channel */ + ADC_CON0_M_AIN14 = 14, /*!< AIN14 : Input channel */ + ADC_CON0_M_AIN15 = 15, /*!< AIN15 : Input channel */ +} ADC_CON0_M_Enum; + +/* ================================================= ADC CON0 CLK [8..10] ================================================== */ +typedef enum { /*!< ADC_CON0_CLK */ + ADC_CON0_CLK_Div2 = 0, /*!< Div2 : PCLK/2 */ + ADC_CON0_CLK_Div4 = 1, /*!< Div4 : PCLK/4 */ + ADC_CON0_CLK_Div8 = 2, /*!< Div8 : PCLK/8 */ + ADC_CON0_CLK_Div16 = 3, /*!< Div16 : PCLK/16 */ + ADC_CON0_CLK_Div32 = 4, /*!< Div32 : PCLK/32 */ + ADC_CON0_CLK_Div64 = 5, /*!< Div64 : PCLK/64 */ + ADC_CON0_CLK_Div3_75 = 6, /*!< Div3_75 : PCLK/3.75 */ + ADC_CON0_CLK_Div3_5 = 7, /*!< Div3_5 : PCLK/3.5 */ +} ADC_CON0_CLK_Enum; + +/* ================================================ ADC CON0 ALIGN [13..13] ================================================ */ +typedef enum { /*!< ADC_CON0_ALIGN */ + ADC_CON0_ALIGN_RIGHT = 0, /*!< RIGHT : right align */ + ADC_CON0_ALIGN_LEFT = 1, /*!< LEFT : left align */ +} ADC_CON0_ALIGN_Enum; + +/* =============================================== ADC CON0 INT_EN [16..19] ================================================ */ +typedef enum { /*!< ADC_CON0_INT_EN */ + ADC_CON0_INT_EN_DISABLE = 0, /*!< DISABLE : Disable interrupt */ + ADC_CON0_INT_EN_DONE = 1, /*!< DONE : Interrupt when conversion done */ + ADC_CON0_INT_EN_GT_THR = 2, /*!< GT_THR : Result is greater then threshold */ + ADC_CON0_INT_EN_LT_THR = 4, /*!< LT_THR : Result is littler then threshold */ + ADC_CON0_INT_EN_EQ_THR = 8, /*!< EQ_THR : Result is equal to threshold */ +} ADC_CON0_INT_EN_Enum; + +/* ================================================= ADC CON0 TZO [20..22] ================================================= */ +typedef enum { /*!< ADC_CON0_TZO */ + ADC_CON0_TZO_LSB_MINUS_4 = 0, /*!< LSB_MINUS_4 : -4 LSB */ + ADC_CON0_TZO_LSB_MINUS_3 = 1, /*!< LSB_MINUS_3 : -3 LSB */ + ADC_CON0_TZO_LSB_MINUS_2 = 2, /*!< LSB_MINUS_2 : -2 LSB */ + ADC_CON0_TZO_LSB_MINUS_1 = 3, /*!< LSB_MINUS_1 : -1 LSB */ + ADC_CON0_TZO_LSB = 4, /*!< LSB : keep LSB value */ + ADC_CON0_TZO_LSB_PLUS_1 = 5, /*!< LSB_PLUS_1 : +1 LSB */ + ADC_CON0_TZO_LSB_PLUS_2 = 6, /*!< LSB_PLUS_2 : +2 LSB */ + ADC_CON0_TZO_LSB_PLUS_3 = 7, /*!< LSB_PLUS_3 : +3 LSB */ +} ADC_CON0_TZO_Enum; + +/* ========================================================= STAT ========================================================== */ +/* ============================================== ADC STAT COMP_RESULT [4..5] ============================================== */ +typedef enum { /*!< ADC_STAT_COMP_RESULT */ + ADC_STAT_COMP_RESULT_NONE = 0, /*!< NONE : Auto-clear after read reg DATx */ + ADC_STAT_COMP_RESULT_GT_THR = 1, /*!< GT_THR : Result is greater then threshold */ + ADC_STAT_COMP_RESULT_LT_THR = 2, /*!< LT_THR : Result is littler then threshold */ + ADC_STAT_COMP_RESULT_EQ_THR = 3, /*!< EQ_THR : Result is equal to threshold */ +} ADC_STAT_COMP_RESULT_Enum; + +/* =============================================== ADC STAT DLY_SET [21..23] =============================================== */ +typedef enum { /*!< ADC_STAT_DLY_SET */ + ADC_STAT_DLY_SET_DLY_12 = 0, /*!< DLY_12 : Deley 12 cycles */ + ADC_STAT_DLY_SET_DLY_14 = 1, /*!< DLY_14 : Deley 14 cycles */ + ADC_STAT_DLY_SET_DLY_18 = 2, /*!< DLY_18 : Deley 18 cycles */ + ADC_STAT_DLY_SET_DLY_24 = 3, /*!< DLY_24 : Deley 24 cycles */ + ADC_STAT_DLY_SET_DLY_26 = 4, /*!< DLY_26 : Deley 26 cycles */ +} ADC_STAT_DLY_SET_Enum; + +/* ========================================================= DAT0 ========================================================== */ +/* ========================================================= DAT1 ========================================================== */ +/* ========================================================= DAT2 ========================================================== */ +/* ========================================================= DAT3 ========================================================== */ +/* ========================================================= DAT4 ========================================================== */ +/* ========================================================= DAT5 ========================================================== */ +/* ========================================================= DAT6 ========================================================== */ +/* ========================================================= DAT7 ========================================================== */ +/* ========================================================= DAT8 ========================================================== */ +/* ========================================================= DAT9 ========================================================== */ +/* ========================================================= DAT10 ========================================================= */ +/* ========================================================= DAT11 ========================================================= */ +/* ========================================================= DAT12 ========================================================= */ +/* ========================================================= DAT13 ========================================================= */ +/* ========================================================= DAT14 ========================================================= */ +/* ========================================================= DAT15 ========================================================= */ +/* ========================================================= CHSEL ========================================================= */ +/* ============================================= ADC CHSEL TRIG_SEL16 [26..27] ============================================= */ +typedef enum { /*!< ADC_CHSEL_TRIG_SEL16 */ + ADC_CHSEL_TRIG_SEL16_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_CHSEL_TRIG_SEL16_TIM0_OVERFLOW = 1, /*!< TIM0_OVERFLOW : TIM0 overflow trigger */ +} ADC_CHSEL_TRIG_SEL16_Enum; + +/* ============================================= ADC CHSEL TRIG_SEL17 [28..29] ============================================= */ +typedef enum { /*!< ADC_CHSEL_TRIG_SEL17 */ + ADC_CHSEL_TRIG_SEL17_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_CHSEL_TRIG_SEL17_PIN = 1, /*!< PIN : PB1/PB2 trigger */ +} ADC_CHSEL_TRIG_SEL17_Enum; + +/* ============================================= ADC CHSEL EXTRIG_SEL [30..31] ============================================= */ +typedef enum { /*!< ADC_CHSEL_EXTRIG_SEL */ + ADC_CHSEL_EXTRIG_SEL_PB1_RISING = 0, /*!< PB1_RISING : PB1 rising trigger */ + ADC_CHSEL_EXTRIG_SEL_PB1_FALLING = 1, /*!< PB1_FALLING : PB1 falling trigger */ + ADC_CHSEL_EXTRIG_SEL_PB2_RISING = 2, /*!< PB2_RISING : PB2 rising trigger */ + ADC_CHSEL_EXTRIG_SEL_PB2_FALLING = 3, /*!< PB2_FALLING : PB2 falling trigger */ +} ADC_CHSEL_EXTRIG_SEL_Enum; + +/* ======================================================== TRGSEL ========================================================= */ +/* ============================================== ADC TRGSEL TRIG_SEL0 [0..1] ============================================== */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL0 */ + ADC_TRGSEL_TRIG_SEL0_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL0_EPWM_CH1_RISING = 1, /*!< EPWM_CH1_RISING : EPWM0P(CH1) Rising */ +} ADC_TRGSEL_TRIG_SEL0_Enum; + +/* ============================================== ADC TRGSEL TRIG_SEL1 [2..3] ============================================== */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL1 */ + ADC_TRGSEL_TRIG_SEL1_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL1_EPWM_CH2_RISING = 1, /*!< EPWM_CH2_RISING : EPWM0P(CH2) Rising */ +} ADC_TRGSEL_TRIG_SEL1_Enum; + +/* ============================================== ADC TRGSEL TRIG_SEL2 [4..5] ============================================== */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL2 */ + ADC_TRGSEL_TRIG_SEL2_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL2_EPWM_CH3_RISING = 1, /*!< EPWM_CH3_RISING : EPWM0P(CH3) Rising */ +} ADC_TRGSEL_TRIG_SEL2_Enum; + +/* ============================================== ADC TRGSEL TRIG_SEL3 [6..7] ============================================== */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL3 */ + ADC_TRGSEL_TRIG_SEL3_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL3_EPWM_CH1_FALLING = 1, /*!< EPWM_CH1_FALLING : EPWM0P(CH1) Falling */ +} ADC_TRGSEL_TRIG_SEL3_Enum; + +/* ============================================== ADC TRGSEL TRIG_SEL4 [8..9] ============================================== */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL4 */ + ADC_TRGSEL_TRIG_SEL4_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL4_EPWM_CH2_FALLING = 1, /*!< EPWM_CH2_FALLING : EPWM0P(CH2) Falling */ +} ADC_TRGSEL_TRIG_SEL4_Enum; + +/* ============================================= ADC TRGSEL TRIG_SEL5 [10..11] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL5 */ + ADC_TRGSEL_TRIG_SEL5_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL5_EPWM_CH3_FALLING = 1, /*!< EPWM_CH3_FALLING : EPWM0P(CH3) Falling */ +} ADC_TRGSEL_TRIG_SEL5_Enum; + +/* ============================================= ADC TRGSEL TRIG_SEL6 [12..13] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL6 */ + ADC_TRGSEL_TRIG_SEL6_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL6_COMP0_RISING = 1, /*!< COMP0_RISING : COMP0 Rising */ +} ADC_TRGSEL_TRIG_SEL6_Enum; + +/* ============================================= ADC TRGSEL TRIG_SEL7 [14..15] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL7 */ + ADC_TRGSEL_TRIG_SEL7_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL7_COMP0_FALLING = 1, /*!< COMP0_FALLING : COMP0 Falling */ +} ADC_TRGSEL_TRIG_SEL7_Enum; + +/* ============================================= ADC TRGSEL TRIG_SEL8 [16..17] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL8 */ + ADC_TRGSEL_TRIG_SEL8_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL8_COMP1_RISING = 1, /*!< COMP1_RISING : COMP1 Rising */ +} ADC_TRGSEL_TRIG_SEL8_Enum; + +/* ============================================= ADC TRGSEL TRIG_SEL9 [18..19] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL9 */ + ADC_TRGSEL_TRIG_SEL9_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL9_COMP1_FALLING = 1, /*!< COMP1_FALLING : COMP1 Falling */ +} ADC_TRGSEL_TRIG_SEL9_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL10 [20..21] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL10 */ + ADC_TRGSEL_TRIG_SEL10_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL10_EPWM_UDF = 1, /*!< EPWM_UDF : EPWM Counter Underflow */ +} ADC_TRGSEL_TRIG_SEL10_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL11 [22..23] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL11 */ + ADC_TRGSEL_TRIG_SEL11_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL11_EPWM_OVF = 1, /*!< EPWM_OVF : EPWM Counter Overflow */ +} ADC_TRGSEL_TRIG_SEL11_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL12 [24..25] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL12 */ + ADC_TRGSEL_TRIG_SEL12_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL12_EPWM_CCR4_UP = 1, /*!< EPWM_CCR4_UP : EPWM CCR4 up-count */ +} ADC_TRGSEL_TRIG_SEL12_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL13 [26..27] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL13 */ + ADC_TRGSEL_TRIG_SEL13_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL13_EPWM_CCDR4_UP = 1, /*!< EPWM_CCDR4_UP : EPWM CCDR4 up-count */ +} ADC_TRGSEL_TRIG_SEL13_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL14 [28..29] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL14 */ + ADC_TRGSEL_TRIG_SEL14_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL14_EPWM_CCR4_DN = 1, /*!< EPWM_CCR4_DN : EPWM CCR4 down-count */ +} ADC_TRGSEL_TRIG_SEL14_Enum; + +/* ============================================ ADC TRGSEL TRIG_SEL15 [30..31] ============================================= */ +typedef enum { /*!< ADC_TRGSEL_TRIG_SEL15 */ + ADC_TRGSEL_TRIG_SEL15_DISABLE = 0, /*!< DISABLE : Disable selection */ + ADC_TRGSEL_TRIG_SEL15_EPWM_CCDR4_DN = 1, /*!< EPWM_CCDR4_DN : EPWM CCDR4 down-count */ +} ADC_TRGSEL_TRIG_SEL15_Enum; + +/* ========================================================= BKSEL ========================================================= */ +/* =============================================== ADC BKSEL BK1_FLT [4..5] ================================================ */ +typedef enum { /*!< ADC_BKSEL_BK1_FLT */ + ADC_BKSEL_BK1_FLT_OFF = 0, /*!< OFF : Disable filter the brake from ADC source 1 */ + ADC_BKSEL_BK1_FLT_MATCH_2 = 1, /*!< MATCH_2 : Brake if result matches 2-times */ + ADC_BKSEL_BK1_FLT_MATCH_4 = 2, /*!< MATCH_4 : Brake if result matches 4-times */ + ADC_BKSEL_BK1_FLT_MATCH_7 = 3, /*!< MATCH_7 : Brake if result matches 7-times */ +} ADC_BKSEL_BK1_FLT_Enum; + +/* ================================================ ADC BKSEL BK1_EN [6..7] ================================================ */ +typedef enum { /*!< ADC_BKSEL_BK1_EN */ + ADC_BKSEL_BK1_EN_OFF = 0, /*!< OFF : Disable brake from ADC source 1 */ + ADC_BKSEL_BK1_EN_GT_THR = 1, /*!< GT_THR : Result is greater then threshold */ + ADC_BKSEL_BK1_EN_LT_THR = 2, /*!< LT_THR : Result is littler then threshold */ + ADC_BKSEL_BK1_EN_EQ_THR = 3, /*!< EQ_THR : Result is equal to threshold */ +} ADC_BKSEL_BK1_EN_Enum; + +/* ============================================== ADC BKSEL BK2_FLT [12..13] =============================================== */ +typedef enum { /*!< ADC_BKSEL_BK2_FLT */ + ADC_BKSEL_BK2_FLT_OFF = 0, /*!< OFF : Disable filter the brake from ADC source 2 */ + ADC_BKSEL_BK2_FLT_MATCH_2 = 1, /*!< MATCH_2 : Brake if result matches 2-times */ + ADC_BKSEL_BK2_FLT_MATCH_4 = 2, /*!< MATCH_4 : Brake if result matches 4-times */ + ADC_BKSEL_BK2_FLT_MATCH_7 = 3, /*!< MATCH_7 : Brake if result matches 7-times */ +} ADC_BKSEL_BK2_FLT_Enum; + +/* =============================================== ADC BKSEL BK2_EN [14..15] =============================================== */ +typedef enum { /*!< ADC_BKSEL_BK2_EN */ + ADC_BKSEL_BK2_EN_OFF = 0, /*!< OFF : Disable brake from ADC source 1 */ + ADC_BKSEL_BK2_EN_GT_THR = 1, /*!< GT_THR : Result is greater then threshold */ + ADC_BKSEL_BK2_EN_LT_THR = 2, /*!< LT_THR : Result is littler then threshold */ + ADC_BKSEL_BK2_EN_EQ_THR = 3, /*!< EQ_THR : Result is equal to threshold */ +} ADC_BKSEL_BK2_EN_Enum; + +/* ======================================================== BAKDAT ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ AMISC ================ */ +/* =========================================================================================================================== */ + +/* ====================================================== LVD_LVR_CR ======================================================= */ +/* ============================================ AMISC LVD_LVR_CR LVD_SEL [5..7] ============================================ */ +typedef enum { /*!< AMISC_LVD_LVR_CR_LVD_SEL */ + AMISC_LVD_LVR_CR_LVD_SEL_2V = 0, /*!< 2V : 2.0V */ + AMISC_LVD_LVR_CR_LVD_SEL_2_2V = 1, /*!< 2_2V : 2.2V */ + AMISC_LVD_LVR_CR_LVD_SEL_2_4V = 2, /*!< 2_4V : 2.4V */ + AMISC_LVD_LVR_CR_LVD_SEL_2_7V = 3, /*!< 2_7V : 2.7V */ + AMISC_LVD_LVR_CR_LVD_SEL_3V = 4, /*!< 3V : 3.0V */ + AMISC_LVD_LVR_CR_LVD_SEL_3_7V = 5, /*!< 3_7V : 3.7V */ + AMISC_LVD_LVR_CR_LVD_SEL_4V = 6, /*!< 4V : 4.0V */ + AMISC_LVD_LVR_CR_LVD_SEL_4_3V = 7, /*!< 4_3V : 4.3V */ +} AMISC_LVD_LVR_CR_LVD_SEL_Enum; + +/* =========================================== AMISC LVD_LVR_CR LVR_SEL [13..15] =========================================== */ +typedef enum { /*!< AMISC_LVD_LVR_CR_LVR_SEL */ + AMISC_LVD_LVR_CR_LVR_SEL_2V = 0, /*!< 2V : 2.0V */ + AMISC_LVD_LVR_CR_LVR_SEL_2_4V = 1, /*!< 2_4V : 2.4V */ + AMISC_LVD_LVR_CR_LVR_SEL_2_7V = 2, /*!< 2_7V : 2.7V */ + AMISC_LVD_LVR_CR_LVR_SEL_3V = 3, /*!< 3V : 3V */ + AMISC_LVD_LVR_CR_LVR_SEL_3_7V = 4, /*!< 3_7V : 3.7V */ +} AMISC_LVD_LVR_CR_LVR_SEL_Enum; + +/* ======================================================== VBUF_CR ======================================================== */ +/* ============================================= AMISC VBUF_CR ANA_SEL [6..12] ============================================= */ +typedef enum { /*!< AMISC_VBUF_CR_ANA_SEL */ + AMISC_VBUF_CR_ANA_SEL_NONE = 0, /*!< NONE : None */ + AMISC_VBUF_CR_ANA_SEL_TEMP = 1, /*!< TEMP : temp out */ + AMISC_VBUF_CR_ANA_SEL_DAC0 = 2, /*!< DAC0 : DAC 0 */ + AMISC_VBUF_CR_ANA_SEL_DAC1 = 4, /*!< DAC1 : DAC 1 */ + AMISC_VBUF_CR_ANA_SEL_VBuf_1p5v = 8, /*!< VBuf_1p5v : vbuf 1p5v out */ + AMISC_VBUF_CR_ANA_SEL_VDDL = 16, /*!< VDDL : vddl */ + AMISC_VBUF_CR_ANA_SEL_VSS = 32, /*!< VSS : vss */ + AMISC_VBUF_CR_ANA_SEL_VDD = 64, /*!< VDD : vdd */ +} AMISC_VBUF_CR_ANA_SEL_Enum; + +/* ======================================================== DAC_CR ========================================================= */ +/* ======================================================== HSI_CR ========================================================= */ +/* ============================================= AMISC HSI_CR LDO_SEL [0..15] ============================================== */ +typedef enum { /*!< AMISC_HSI_CR_LDO_SEL */ + AMISC_HSI_CR_LDO_SEL_LDO = 32896, /*!< LDO : ldo_oschf Disable abd vddl_oschf from ldo */ + AMISC_HSI_CR_LDO_SEL_Normal = 257, /*!< Normal : do_oschf Enable and vddl_oschf from ldo_oschf */ +} AMISC_HSI_CR_LDO_SEL_Enum; + +/* ======================================================== LSI_CR ========================================================= */ +/* ====================================================== ADC_AIN_CR ======================================================= */ + + +/* =========================================================================================================================== */ +/* ================ HWTRIM ================ */ +/* =========================================================================================================================== */ + +/* ======================================================= LDO_TRIM ======================================================== */ +/* =========================================== HWTRIM LDO_TRIM LDO_TUNE [10..11] =========================================== */ +typedef enum { /*!< HWTRIM_LDO_TRIM_LDO_TUNE */ + HWTRIM_LDO_TRIM_LDO_TUNE_STRENGTH = 0, /*!< STRENGTH : strength */ + HWTRIM_LDO_TRIM_LDO_TUNE_WEAK = 1, /*!< WEAK : weak */ + HWTRIM_LDO_TRIM_LDO_TUNE_MIDDLEddle = 2, /*!< MIDDLEddle : middle */ + HWTRIM_LDO_TRIM_LDO_TUNE_OFF = 3, /*!< OFF : off */ +} HWTRIM_LDO_TRIM_LDO_TUNE_Enum; + +/* ======================================================= VBUF_TRIM ======================================================= */ +/* ======================================================= HSI_TRIM ======================================================== */ +/* ======================================================= LSI_TRIM ======================================================== */ +/* ======================================================= MISC_CFG ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ CRC ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR =========================================================== */ +/* ================================================= CRC CR POLYSEL [0..0] ================================================= */ +typedef enum { /*!< CRC_CR_POLYSEL */ + CRC_CR_POLYSEL_CRC16 = 1, /*!< CRC16 : x16 + x12 + x5 + 1 */ + CRC_CR_POLYSEL_CRC32 = 0, /*!< CRC32 : x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + + x7 + x5 + x4 + x2 + x + 1 */ +} CRC_CR_POLYSEL_Enum; + +/* ========================================================== DIN ========================================================== */ +/* ========================================================= DOUT ========================================================== */ + + +/* =========================================================================================================================== */ +/* ================ DSP ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR =========================================================== */ +/* ================================================== DSP CR MODE [0..2] =================================================== */ +typedef enum { /*!< DSP_CR_MODE */ + DSP_CR_MODE_DIV = 1, /*!< DIV : 32-bits Divide Mode */ + DSP_CR_MODE_SQRT = 4, /*!< SQRT : square root mode */ +} DSP_CR_MODE_Enum; + +/* ========================================================== SR =========================================================== */ +/* ========================================================= SDAT1 ========================================================= */ +/* ========================================================= SDAT2 ========================================================= */ +/* ========================================================= RSLT1 ========================================================= */ +/* ========================================================= RSLT2 ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ OPAMP ================ */ +/* =========================================================================================================================== */ + +/* ======================================================== PGA_CR ========================================================= */ +/* ============================================= OPAMP PGA_CR PGA_GAIN [2..7] ============================================== */ +typedef enum { /*!< OPAMP_PGA_CR_PGA_GAIN */ + OPAMP_PGA_CR_PGA_GAIN_x1 = 1, /*!< x1 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x2 = 6, /*!< x2 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x3 = 10, /*!< x3 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x4 = 14, /*!< x4 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x5 = 18, /*!< x5 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x6 = 22, /*!< x6 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x7 = 26, /*!< x7 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x8 = 30, /*!< x8 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x9 = 34, /*!< x9 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x10 = 38, /*!< x10 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x11 = 42, /*!< x11 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x12 = 46, /*!< x12 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x13 = 50, /*!< x13 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x14 = 54, /*!< x14 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x15 = 58, /*!< x15 : Multiple of gain */ + OPAMP_PGA_CR_PGA_GAIN_x16 = 62, /*!< x16 : Multiple of gain */ +} OPAMP_PGA_CR_PGA_GAIN_Enum; + + + +/* =========================================================================================================================== */ +/* ================ COMP ================ */ +/* =========================================================================================================================== */ + +/* ========================================================= CTRL ========================================================== */ +/* =============================================== COMP CTRL VIN_SEL [2..3] ================================================ */ +typedef enum { /*!< COMP_CTRL_VIN_SEL */ + COMP_CTRL_VIN_SEL_IO = 1, /*!< IO : selction IO Pin */ + COMP_CTRL_VIN_SEL_DAC = 2, /*!< DAC : selction DAC */ +} COMP_CTRL_VIN_SEL_Enum; + +/* =============================================== COMP CTRL FIL_CTRL [4..7] =============================================== */ +typedef enum { /*!< COMP_CTRL_FIL_CTRL */ + COMP_CTRL_FIL_CTRL_BYPASS = 0, /*!< BYPASS : No filter */ + COMP_CTRL_FIL_CTRL_SAMPLE_2 = 1, /*!< SAMPLE_2 : sample 2 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_4 = 2, /*!< SAMPLE_4 : sample 4 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_8 = 3, /*!< SAMPLE_8 : sample 8 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_16 = 4, /*!< SAMPLE_16 : sample 16 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_32 = 5, /*!< SAMPLE_32 : sample 32 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_64 = 6, /*!< SAMPLE_64 : sample 64 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_128 = 7, /*!< SAMPLE_128 : sample 128 times */ + COMP_CTRL_FIL_CTRL_SAMPLE_256 = 8, /*!< SAMPLE_256 : sample 256 times */ +} COMP_CTRL_FIL_CTRL_Enum; + +/* =============================================== COMP CTRL OUT_EN [11..11] =============================================== */ +typedef enum { /*!< COMP_CTRL_OUT_EN */ + COMP_CTRL_OUT_EN_NONE = 0, /*!< NONE : No signal output */ + COMP_CTRL_OUT_EN_IO = 1, /*!< IO : select IO output */ +} COMP_CTRL_OUT_EN_Enum; + +/* ============================================== COMP CTRL POL_SEL [12..12] =============================================== */ +typedef enum { /*!< COMP_CTRL_POL_SEL */ + COMP_CTRL_POL_SEL_NORMAL = 0, /*!< NORMAL : Normal polarity output */ + COMP_CTRL_POL_SEL_INVERT = 1, /*!< INVERT : Inverted */ +} COMP_CTRL_POL_SEL_Enum; + +/* ======================================================== VIPSEL ========================================================= */ +/* ============================================== COMP VIPSEL VIP_SEL [0..4] =============================================== */ +typedef enum { /*!< COMP_VIPSEL_VIP_SEL */ + COMP_VIPSEL_VIP_SEL_IO3 = 16, /*!< IO3 : I/O PA15 */ + COMP_VIPSEL_VIP_SEL_IO2 = 8, /*!< IO2 : I/O PA14 */ + COMP_VIPSEL_VIP_SEL_IO1 = 4, /*!< IO1 : I/O PA11 */ + COMP_VIPSEL_VIP_SEL_IO0 = 2, /*!< IO0 : I/O PA8 */ + COMP_VIPSEL_VIP_SEL_PGA = 1, /*!< PGA : Select PGA */ +} COMP_VIPSEL_VIP_SEL_Enum; + +/* ========================================================== IR =========================================================== */ +/* ========================================================== IF =========================================================== */ +/* ======================================================== INITCNT ======================================================== */ + + +/* =========================================================================================================================== */ +/* ================ TIM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== CR1 ========================================================== */ +/* ================================================== TIM CR1 CMS [5..6] =================================================== */ +typedef enum { /*!< TIM_CR1_CMS */ + TIM_CR1_CMS_EDGE = 0, /*!< EDGE : edge mode */ + TIM_CR1_CMS_CENTER1 = 1, /*!< CENTER1 : center mode 1: count-up will trigger interrupt */ + TIM_CR1_CMS_CENTER2 = 2, /*!< CENTER2 : center mode 2: count-down will trigger interrupt */ + TIM_CR1_CMS_CENTER3 = 3, /*!< CENTER3 : center mode 3: count-up and count-down will trigger + interrupt */ +} TIM_CR1_CMS_Enum; + +/* ================================================== TIM CR1 CKD [8..9] =================================================== */ +typedef enum { /*!< TIM_CR1_CKD */ + TIM_CR1_CKD_0 = 0, /*!< 0 : Tdts = tck_in */ + TIM_CR1_CKD_1 = 1, /*!< 1 : Tdts = tck_in*2 */ + TIM_CR1_CKD_2 = 2, /*!< 2 : Tdts = tck_in*4 */ + TIM_CR1_CKD_3 = 3, /*!< 3 : reserve */ +} TIM_CR1_CKD_Enum; + +/* ========================================================== CR2 ========================================================== */ +/* ================================================== TIM CR2 MMS [4..6] =================================================== */ +typedef enum { /*!< TIM_CR2_MMS */ + TIM_CR2_MMS_RESET = 0, /*!< RESET : UG Trigger TRGO */ + TIM_CR2_MMS_ENABLE = 1, /*!< ENABLE : CEN Trigger TRGO */ + TIM_CR2_MMS_UPDATE = 2, /*!< UPDATE : UPDATE Trigger TRGO */ + TIM_CR2_MMS_COMPARE = 3, /*!< COMPARE : COMPARE/CAPTURE Trigger TRGO */ + TIM_CR2_MMS_OC1REF = 4, /*!< OC1REF : OC1REF Trigger TRGO */ + TIM_CR2_MMS_OC2REF = 5, /*!< OC2REF : OC2REF Trigger TRGO */ + TIM_CR2_MMS_OC3REF = 6, /*!< OC3REF : OC3REF Trigger TRGO */ + TIM_CR2_MMS_OC4REF = 7, /*!< OC4REF : OC4REF Trigger TRGO */ +} TIM_CR2_MMS_Enum; + +/* ========================================================= SMCR ========================================================== */ +/* ================================================== TIM SMCR SMS [0..2] ================================================== */ +typedef enum { /*!< TIM_SMCR_SMS */ + TIM_SMCR_SMS_DISABLE = 0, /*!< DISABLE : close Slave mode */ + TIM_SMCR_SMS_Encode1 = 1, /*!< Encode1 : Encode mode 1: */ + TIM_SMCR_SMS_Encode2 = 2, /*!< Encode2 : Encode mode 2 */ + TIM_SMCR_SMS_Encode3 = 3, /*!< Encode3 : Encode mode 3 */ + TIM_SMCR_SMS_RESET = 4, /*!< RESET : Reset mode */ + TIM_SMCR_SMS_WINDOW = 5, /*!< WINDOW : Window mode */ + TIM_SMCR_SMS_TRIGGER = 6, /*!< TRIGGER : trigger mode */ + TIM_SMCR_SMS_EXTCLK = 7, /*!< EXTCLK : External clock mode 1 */ +} TIM_SMCR_SMS_Enum; + +/* ================================================== TIM SMCR TS [4..6] =================================================== */ +typedef enum { /*!< TIM_SMCR_TS */ + TIM_SMCR_TS_ITR0 = 0, /*!< ITR0 : ITR0 */ + TIM_SMCR_TS_ITR1 = 1, /*!< ITR1 : ITR1: */ + TIM_SMCR_TS_ITR2 = 2, /*!< ITR2 : ITR2 */ + TIM_SMCR_TS_ITR3 = 3, /*!< ITR3 : ITR3 */ + TIM_SMCR_TS_TI1F_ED = 4, /*!< TI1F_ED : TI1F_ED */ + TIM_SMCR_TS_T1FP1 = 5, /*!< T1FP1 : T1FP1 */ + TIM_SMCR_TS_T1FP2 = 6, /*!< T1FP2 : T1FP2 */ + TIM_SMCR_TS_ETRF = 7, /*!< ETRF : ETRF */ +} TIM_SMCR_TS_Enum; + +/* ================================================= TIM SMCR ETF [8..11] ================================================== */ +typedef enum { /*!< TIM_SMCR_ETF */ + TIM_SMCR_ETF_0 = 0, /*!< 0 : No filter */ + TIM_SMCR_ETF_1 = 1, /*!< 1 : fsampling = fclk_int,N=2 */ + TIM_SMCR_ETF_2 = 2, /*!< 2 : fsampling = fclk_int,N=4 */ + TIM_SMCR_ETF_3 = 3, /*!< 3 : fsampling = fclk_int,N=8 */ + TIM_SMCR_ETF_4 = 4, /*!< 4 : fsampling = Fdts/2,N=6 */ + TIM_SMCR_ETF_5 = 5, /*!< 5 : fsampling = Fdts/2,N=8 */ + TIM_SMCR_ETF_6 = 6, /*!< 6 : fsampling = Fdts/4,N=6 */ + TIM_SMCR_ETF_7 = 7, /*!< 7 : fsampling = Fdts/4,N=8 */ + TIM_SMCR_ETF_8 = 8, /*!< 8 : fsampling = Fdts/8,N=6 */ + TIM_SMCR_ETF_9 = 9, /*!< 9 : fsampling = Fdts/8,N=8 */ + TIM_SMCR_ETF_10 = 10, /*!< 10 : fsampling = Fdts/16,N=5 */ + TIM_SMCR_ETF_11 = 11, /*!< 11 : fsampling = Fdts/16,N=6 */ + TIM_SMCR_ETF_12 = 12, /*!< 12 : fsampling = Fdts/16,N=8 */ + TIM_SMCR_ETF_13 = 13, /*!< 13 : fsampling = Fdts/32,N=5 */ + TIM_SMCR_ETF_14 = 14, /*!< 14 : fsampling = Fdts/32,N=6 */ + TIM_SMCR_ETF_15 = 15, /*!< 15 : fsampling = Fdts/32,N=8 */ +} TIM_SMCR_ETF_Enum; + +/* ========================================================= DIER ========================================================== */ +/* ========================================================== SR =========================================================== */ +/* ========================================================== EGR ========================================================== */ +/* ===================================================== CCMR1_OUTPUT ====================================================== */ +/* ====================================================== CCMR1_INPUT ====================================================== */ +/* ===================================================== CCMR2_OUTPUT ====================================================== */ +/* ====================================================== CCMR2_INPUT ====================================================== */ +/* ========================================================= CCER ========================================================== */ +/* ========================================================== CNT ========================================================== */ +/* ========================================================== PSC ========================================================== */ +/* ========================================================== ARR ========================================================== */ +/* ========================================================== RCR ========================================================== */ +/* ========================================================= CCR1 ========================================================== */ +/* ========================================================= CCR2 ========================================================== */ +/* ========================================================= CCR3 ========================================================== */ +/* ========================================================= CCR4 ========================================================== */ +/* ========================================================= BDTR ========================================================== */ +/* ========================================================= CCDR1 ========================================================= */ +/* ========================================================= CCDR2 ========================================================= */ +/* ========================================================= CCDR3 ========================================================= */ +/* ========================================================= CCDR4 ========================================================= */ + + +/* =========================================================================================================================== */ +/* ================ LPTIM ================ */ +/* =========================================================================================================================== */ + +/* ========================================================== IR =========================================================== */ +/* ========================================================== TCR ========================================================== */ +/* ================================================= LPTIM TCR CLKS [2..3] ================================================= */ +typedef enum { /*!< LPTIM_TCR_CLKS */ + LPTIM_TCR_CLKS_SysClk = 0, /*!< SysClk : System Clock */ + LPTIM_TCR_CLKS_LSI = 1, /*!< LSI : LIRC 32KHz */ +} LPTIM_TCR_CLKS_Enum; + +/* =============================================== LPTIM TCR TRIGSEL [4..6] ================================================ */ +typedef enum { /*!< LPTIM_TCR_TRIGSEL */ + LPTIM_TCR_TRIGSEL_Normal = 0, /*!< Normal : Normal trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh0P = 1, /*!< EPWMCh0P : EPWM CH0 (ouput) rising trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh1P = 2, /*!< EPWMCh1P : EPWM CH1 (ouput) rising trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh2P = 3, /*!< EPWMCh2P : EPWM CH2 (ouput) rising trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh0N = 4, /*!< EPWMCh0N : EPWM CH0 (ouput) falling trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh1N = 5, /*!< EPWMCh1N : EPWM CH1 (ouput) falling trigger */ + LPTIM_TCR_TRIGSEL_EPWMCh2N = 6, /*!< EPWMCh2N : EPWM CH2 (ouput) falling trigger */ +} LPTIM_TCR_TRIGSEL_Enum; + +/* ========================================================== TC =========================================================== */ +/* ========================================================== PR =========================================================== */ +/* ========================================================== PC =========================================================== */ +/* ========================================================== MCR ========================================================== */ +/* ========================================================== MR0 ========================================================== */ + +/** @} */ /* End of group EnumValue_peripherals */ + + +#ifdef __cplusplus +} +#endif + +#endif /* PEC930_H */ + + +/** @} */ /* End of group PEC930 */ + +/** @} */ /* End of group Padauk-tech */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/system_dev.h b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/system_dev.h new file mode 100644 index 0000000..98d0fa4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/inc/system_dev.h @@ -0,0 +1,383 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file system_dev.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __system_dev_H_wjaCXWfu_lqsX_H0XR_svyC_uj3MxJR5UZzV__ +#define __system_dev_H_wjaCXWfu_lqsX_H0XR_svyC_uj3MxJR5UZzV__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +//============================================================================= +// Constant Definition +//============================================================================= + +#ifndef SYS_TIMER_FREQ +#define SYS_TIMER_FREQ 32768ul +#endif + +#ifndef SYS_MAX_DELAY +#define SYS_MAX_DELAY 0x7FFFFFFFul +#endif + +#define SYS_IGNORE_TAG (~0) + +/** + * Exception Code + */ +typedef enum EXCPn +{ + /* =============== Nuclei N/NX Specific Exception Code =============== */ + EXCPn_InsUnalign = 0, /*!< Instruction address misaligned */ + EXCPn_InsAccFault = 1, /*!< Instruction access fault */ + EXCPn_IlleIns = 2, /*!< Illegal instruction */ + EXCPn_Break = 3, /*!< Beakpoint */ + EXCPn_LdAddrUnalign = 4, /*!< Load address misaligned */ + EXCPn_LdFault = 5, /*!< Load access fault */ + EXCPn_StAddrUnalign = 6, /*!< Store or AMO address misaligned */ + EXCPn_StAccessFault = 7, /*!< Store or AMO access fault */ + EXCPn_UmodeEcall = 8, /*!< Environment call from User mode */ + EXCPn_SmodeEcall = 9, /*!< Environment call from S-mode */ + EXCPn_MmodeEcall = 11, /*!< Environment call from Machine mode */ + +#if 1 + EXCPn_Total, +#else + EXCPn_InsPageFault = 12, /*!< Instruction page fault */ + EXCPn_LdPageFault = 13, /*!< Load page fault */ + EXCPn_StPageFault = 15, /*!< Store or AMO page fault */ + EXCPn_StackOverflow = 24, /*!< Stack overflow fault */ + EXCPn_StackUnderflow = 25, /*!< Stack underflow fault */ + EXCPn_Total, +#endif + EXCPn_NMI = 0xfff, /*!< NMI interrupt */ +} EXCPn_Type; + +/** + * SYS_TIMER_PERIOD with 1ms, 10ms, 100ms + */ +typedef enum sys_tick +{ + SYS_TICK_1_MS = 0, + SYS_TICK_10_MS, + SYS_TICK_100_MS, + SYS_TICK_1_SEC, +} sys_tick_t; + + +#if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) +typedef enum sys_irq_trigger +{ + SYS_IRQ_TRIGGER_LEVEL = ECLIC_LEVEL_TRIGGER, /*!< Level Triggerred */ + SYS_IRQ_TRIGGER_POSTIVE_EDGE = ECLIC_POSTIVE_EDGE_TRIGGER, /*!< Postive/Rising Edge Triggered */ + SYS_IRQ_TRIGGER_NEGTIVE_EDGE = ECLIC_NEGTIVE_EDGE_TRIGGER, /*!< Negtive/Falling Edge Triggered */ + SYS_IRQ_TRIGGER_MAX = ECLIC_MAX_TRIGGER, /*!< MAX Supported Trigger Mode */ +} sys_irq_trigger_t; + +typedef enum sys_irq_level +{ + SYS_IRQ_LEVEL_LL = 0, /*!< Interrupt Level lowest */ + SYS_IRQ_LEVEL_L = 1, /*!< Interrupt Level low */ + SYS_IRQ_LEVEL_M = 2, /*!< Interrupt Level midden */ + SYS_IRQ_LEVEL_H = 3, /*!< Interrupt Level high */ + SYS_IRQ_LEVEL_HH = 4, /*!< Interrupt Level highest */ +} sys_irq_level_t; + +typedef enum sys_irq_priority +{ + SYS_IRQ_PRIORITY_LOW = 0, /*!< Interrupt Priority Low */ + SYS_IRQ_PRIORITY_MIDDEN = 1, /*!< Interrupt Priority Midden */ + SYS_IRQ_PRIORITY_HIGH = 2, /*!< Interrupt Priority High */ +} sys_irq_priority_t; + +#endif /* __ECLIC_PRESENT */ + + +typedef void (*fp_isr_t)(void); + +/** + * Exception Handler Function Typedef + */ +typedef void (*cb_excp_handler_t)(uint32_t cause, uint32_t sp); +//============================================================================= +// Macro Definition +//============================================================================= +/** + * Locate function to specific section + * e.g. + * uint32_t __FASTCODE foo(void) { return 123; } + */ +#define __FASTCODE __attribute__((__section__(".fastcode"))) + + +__STATIC_FORCEINLINE uint32_t* __get_pc(void) +{ + uint32_t *pc; + __asm__("auipc %0, 0" : "=r"(pc)); + return pc; +} + +__STATIC_FORCEINLINE uint32_t* __get_sp(void) +{ + uint32_t *sp; + __asm__("move %0, sp" : "=r"(sp)); + return sp; +} + +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct excp_frame +{ + uint32_t ra; /* ra: x1, return address for jump */ + uint32_t tp; /* tp: x4, thread pointer */ + uint32_t t0; /* t0: x5, temporary register 0 */ + uint32_t t1; /* t1: x6, temporary register 1 */ + uint32_t t2; /* t2: x7, temporary register 2 */ + uint32_t a0; /* a0: x10, return value or function argument 0 */ + uint32_t a1; /* a1: x11, return value or function argument 1 */ + uint32_t a2; /* a2: x12, function argument 2 */ + uint32_t a3; /* a3: x13, function argument 3 */ + uint32_t a4; /* a4: x14, function argument 4 */ + uint32_t a5; /* a5: x15, function argument 5 */ + uint32_t cause; /* cause: machine cause csr register */ + uint32_t epc; /* epc: machine exception program counter csr register */ + uint32_t msubm; /* msubm: machine sub-mode csr register, nuclei customized */ +} excp_frame_t; + +typedef struct sys_irq_attr +{ + uint8_t trig_mode; /*!< the interrupt trigger mode, @ref sys_irq_trigger_t */ + uint8_t disable_vector; /*!< use vector table or not */ + uint8_t level; /*!< interupt nested level, + high-level (bigger value) will interrupt low-level, @ref sys_irq_level_t */ + uint8_t priority; /*!< interrupt priority, + the priority of the pended interrupts (when the same IRQ level), @ref sys_irq_priority_t + ps. This priority has NOTHING about nested interrup */ +} sys_irq_attr_t; +//============================================================================= +// Global Data Definition +//============================================================================= +extern volatile uint32_t g_SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ +extern volatile uint32_t g_SysTicks; +extern volatile uint32_t g_SysTickPeriod; +extern volatile uint32_t g_SysTickUnit_MS; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Enable system tick + */ +__STATIC_FORCEINLINE void sys_enable_systick(void) +{ + SysTick_Reload(g_SysTickPeriod); + ECLIC_EnableIRQ(SysTimer_IRQn); + SysTimer_Start(); + return; +} + +/** + * \brief Disable system tick + */ +__STATIC_FORCEINLINE void sys_disable_systick(void) +{ + ECLIC_DisableIRQ(SysTimer_IRQn); + SysTimer_Stop(); + return; +} + +/** + * \brief Trigger software interrupt through system timer + * + * \return None + */ +__STATIC_FORCEINLINE void sys_launch_swi(void) +{ + SysTimer_SetSWIRQ(); + return; +} + +/** + * \brief Clear software interrupt + * + * \return None + */ +__STATIC_FORCEINLINE void sys_clear_swi(void) +{ + SysTimer_ClearSWIRQ(); + return; +} + +/** + * \brief Clear interrupt flags of interrupt controller + * + * \param [in] irq_id the target IRQ Id, @ref IRQn_Type + * \return None + */ +__STATIC_FORCEINLINE void sys_clear_IRQFlag(IRQn_Type irq_id) +{ + ECLIC_ClearPendingIRQ(irq_id); + return; +} + +/** + * \brief Get the pending specific interrupt of interrupt controller + * + * \param [in] irq_id the target IRQ Id, @ref IRQn_Type + * \return + * IRQ is pending or not + * + */ +__STATIC_FORCEINLINE int sys_get_IRQPending(IRQn_Type irq_id) +{ + return ECLIC_GetPendingIRQ(irq_id); +} + +/** + * \brief Get system ticks + * + * \return + * System Ticks + */ +__STATIC_FORCEINLINE uint32_t sys_get_tick(void) +{ + return g_SysTicks; +} + +/** + * \brief Open interrupt source of interrupt controller + * + * \param [in] irq_id the target IRQ Id, @ref IRQn_Type + * \return None + */ +__STATIC_FORCEINLINE void sys_open_IRQ(IRQn_Type irq_id) +{ + ECLIC_EnableIRQ(irq_id); + ECLIC_ClearPendingIRQ(irq_id); + return; +} + +/** + * \brief Close interrupt source of interrupt controller + * + * \param [in] irq_id the target IRQ Id, @ref IRQn_Type + * \return None + */ +__STATIC_FORCEINLINE void sys_close_IRQ(IRQn_Type irq_id) +{ + ECLIC_DisableIRQ(irq_id); + return; +} + +/** + * \brief Enable global interrupt + * + * \return None + */ +__STATIC_FORCEINLINE void sys_enable_girq(void) +{ + __enable_irq(); + return; +} + +/** + * \brief Disable global interrupt + * + * \return None + */ +__STATIC_FORCEINLINE void sys_disable_girq(void) +{ + __disable_irq(); + return; +} + +/** + * \brief system high accuracy delay with systick + * + * \param [in] msec milli-seconds + * \return None + */ +void sys_delay(uint32_t msec); + +/** + * \brief system low accuracy delay with the CPU tick + * + * \param [in] ticks the CPU ticks + * \return None + */ +void sys_busy_wait(uint32_t ticks); + +/** + * \brief get system frequency + * + * \return the cpu frequency value + */ +uint32_t sys_get_cpu_freq(void); + +#if defined(__EXCP_PRESENT) && (__EXCP_PRESENT == 1) +/** + * \brief Register handler to Exception table + * + * \param [in] excp_id exception ID, @ref EXCPn_Type + * \param [in] excp_handler the handler function + * \return + * 0 : ok + * others: fail + */ +int sys_excp_register_handler(EXCPn_Type excp_id, uint32_t excp_handler); +#endif + +#if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) +/** + * \brief Set the attribute of the target interrupt + * + * \param [in] irq_id the terget IRQ ID, @ref IRQn_Type + * \param [in] pAttr pointer to a attribute of interrupt if necessary, @ref sys_irq_attr_t + * \return + * 0 : ok + * others: fail + */ +int sys_set_IRQAttr(IRQn_Type irq_id, sys_irq_attr_t *pAttr); + +/** + * \brief Register ISR to Interrupt + * + * \param [in] irq_id the terget IRQ ID, @ref IRQn_Type + * \param [in] cb_handler the ISR funciotn + * \param [in] pAttr pointer to a attribute of interrupt if necessary, @ref sys_irq_attr_t + * \return + * 0 : ok + * others: fail + */ +int sys_register_IRQ(IRQn_Type irq_id, void *cb_handler, sys_irq_attr_t *pAttr); + +#endif /* __ECLIC_PRESENT == 1 */ + +/** + * \brief Configure system tick + * + * \param [in] ticks period of ticks + * SYS_TICK_1_MS/ SYS_TICK_10_MS/ SYS_TICK_100_MS + */ +void sys_config_systick(uint32_t ticks); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..65a9795966c54538f4b4f669e61d7ca30cfcc29b GIT binary patch literal 10244 zcmeHMTWl0n7(V~B&>1_*lwP<^((1=9 z&@?tapn~zqMAT?Zyv7(c8q^0#059-pNJBz+z(|ZS(Zs|DqfIxu23)NB3uS-fIxu2Yy@cSUPNM8xoaeSYyIvd(DFqhWtpy5TYCwFg2H+8i^L+aSUeCL zcE)0!=4IR_E!|IhU5;ZVa@Sg7ziEsODrL=%?P;cMq*;Ke8|X67W7@hi*5qVt-DR;c zZV)9=8dMffOssEsv?f$nzj3lAG_iSoZB3|tL&M~xB$kKQZRs2wu|{p@I9~|(F9Y&m z-oj4IUX|`9tpwgB4ar-uHB=W%I-@B*$cmru;NfPQ6BdP}Ad!RQN)8g~fnr&HNR9W# z`}zkC3@S>-H98GT^USOf)jY!;R2I01(e9*UcchIhV$+j!tjws5mXf4qB{S%3G+I{7 zJZiXo+IW{S?$K)+m`ppC)#13NXF7Io+?&f3?{l5B*UZL^n>ZC8U?H8ZJw=1v{YKhF zDM=qLSR7ipdhLcyTN`)m+1EL(lq@Wj<%&f;S<^KWmeH%ZNyFAnd#HQN)V<+8d_uNo z9yX1%B$Yr-m#vK&(@T~vD^)Ais$3NJy%{SiVKJUbm``R*@5pp%$wFnh8kPriTKPPu5?p(#ngM}x9vn*pF6Cj zjrK82VgHU=QOlku>S<7mZh8(iGBm>K-o)qziLFNcfEL2D@e$ha?pxnjOzeKK*A2Ic> zlN(SB3Y5bNO!tkL?k&*DQoaK^p&tg|01Sc#PrwLRU}N$hfuk@1lkgO#{&Sf8&%+Dw z5}bsWkpOSO+wcy&2k&G0pMuZeb2tNM;T(MJ6X7z_;3xPkFSYmOrS=^@KBG=F%2S*E z0-ky(e)@dlYyylr`akeW4d419W3P@pB4uM~+j8t7oFPZQ+ix-G1qcKP1PBBO1PBBO z+}{Wk@a2W*{(sBd|Nr0LAOx!m5cr=X0EN+5v zv+a27(Czq#eVxCD!R!%VH^n6j$2b;_lJDl<^*;md@%~#-{|EJdZnynj)&GA351->3 literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/startup.S b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/startup.S new file mode 100644 index 0000000..dcb3c91 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/startup.S @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2024 Padauk Limited. All rights reserved. + * + * 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 + * + * 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. + */ +/****************************************************************************** + * \file startup.S + * \brief Modified NMSIS RISC-V Core based Core Device Startup File for + * RISC-V evaluation SoC which support RISC-V cores + * \version V1.00 + * \date 10/24/2024 + * + ******************************************************************************/ + +#include "riscv_encoding.h" + + .section .init + + .globl _start + .type _start,@function + +_start: + nop + /* ===== Startup Stage 1 ===== */ + csrc CSR_MSTATUS, MSTATUS_MIE + csrw CSR_MIE, 0x0 + + .option push + .option norelax + la gp, __global_pointer$ + la tp, __tls_base +#if defined(__riscv_zcmt) + la t0, __jvt_base$ + csrw CSR_JVT, t0 +#endif + .option pop + + la sp, _sp + +#if 0 + /* Disable/Enable ICE I/O */ + li a0, 0x00001C28 + li a1, 0x4000F804 + li a2, 0x80000000 + lw t0, (a1) + and t1, t0, a2 + beq t1, a2, 1f + li a0, 0x00201C28 +1: + li a1, 0xFFFFFFFF + li a2, 0x31454349 + lw t0, (a0) + beq t0, a1, 2f + beq t0, a2, 2f + li a0, 0x4001F02C + li a1, 0xE6530000 + sw a1, (a0) +2: +#endif + + li t0, MMISC_CTL_NMI_CAUSE_FFF + csrs CSR_MMISC_CTL, t0 + + li t0, MMISC_CTL_ZC + #if defined(__riscv_zcmp) || defined(__riscv_zcmt) + csrs CSR_MMISC_CTL, t0 + #else + csrc CSR_MMISC_CTL, t0 + #endif + + la t0, early_excp_entry + csrw CSR_MTVEC, t0 + + li t0, 0x3f + csrc CSR_MTVEC, t0 + csrs CSR_MTVEC, 0x3 + + csrci CSR_MCOUNTINHIBIT, 0x5 + + la a0, __fastcode_lma_start + la a1, __fastcode_vma_start + beq a0, a1, 2f + la a2, __fastcode_vma_end + bgeu a1, a2, 2f +1: + lw t0, (a0) + sw t0, (a1) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a1, a2, 1b +2: + + la a0, _data_lma + la a1, _data + beq a0, a1, 2f + la a2, _edata + bgeu a1, a2, 2f +1: + lw t0, (a0) + sw t0, (a1) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a1, a2, 1b +2: + + + la a0, __bss_start + la a1, _end + bgeu a0, a1, 2f +1: + sw zero, (a0) + addi a0, a0, 4 + bltu a0, a1, 1b +2: + + call sys_init + + call sys_premain_init + +#if defined(CONFIG_HAS_BPU) + li t0, MMISC_CTL_BPU + csrs CSR_MMISC_CTL, t0 +#endif + + /* ===== Call Main Function ===== */ + li a0, 0 + li a1, 0 + + call main + + call sys_postmain_fini + +1: + j 1b + + + .align 6 + .global early_excp_entry + .type early_excp_entry, @function +early_excp_entry: + wfi + j early_excp_entry diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/trap.S b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/trap.S new file mode 100644 index 0000000..eb049fe --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/Startup/trap.S @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2024 Padauk Limited. All rights reserved. + * + * 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 + * + * 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. + */ +/****************************************************************************** + * \file trap.S + * \brief Modified NMSIS Interrupt and Exception Handling Template File + * for RISC-V evaluation SoC which support RISC-V cores + * \version V1.00 + * \date 10/24/2024 + * + ******************************************************************************/ + +#include "riscv_encoding.h" + +/****************************************************************************** + * \brief Global interrupt disabled + * \details + * This function disable global interrupt. + * \remarks + * - All the interrupt requests will be ignored by CPU. + */ +.macro DISABLE_MIE + csrc CSR_MSTATUS, MSTATUS_MIE +.endm + +/****************************************************************************** + * \brief Macro for context save + * \details + * This macro save ABI defined caller saved registers in the stack. + * \remarks + * - This Macro could use to save context when you enter to interrupt + * or exception + */ +/* Save caller registers */ +.macro SAVE_CONTEXT + + #ifndef __riscv_32e + /* rv32i */ + addi sp, sp, -20*REGBYTES + #else + /* rv32e */ + addi sp, sp, -14*REGBYTES + #endif /* __riscv_32e */ + + STORE x1, 0*REGBYTES(sp) + STORE x4, 1*REGBYTES(sp) + STORE x5, 2*REGBYTES(sp) + STORE x6, 3*REGBYTES(sp) + STORE x7, 4*REGBYTES(sp) + STORE x10, 5*REGBYTES(sp) + STORE x11, 6*REGBYTES(sp) + STORE x12, 7*REGBYTES(sp) + STORE x13, 8*REGBYTES(sp) + STORE x14, 9*REGBYTES(sp) + STORE x15, 10*REGBYTES(sp) + + #ifndef __riscv_32e + /* rv32i */ + STORE x16, 14*REGBYTES(sp) + STORE x17, 15*REGBYTES(sp) + STORE x28, 16*REGBYTES(sp) + STORE x29, 17*REGBYTES(sp) + STORE x30, 18*REGBYTES(sp) + STORE x31, 19*REGBYTES(sp) + #endif /* __riscv_32e */ +.endm + +/****************************************************************************** + * \brief Macro for restore caller registers + * \details + * This macro restore ABI defined caller saved registers from stack. + * \remarks + * - You could use this macro to restore context before you want return + * from interrupt or exeception + */ +/* Restore caller registers */ +.macro RESTORE_CONTEXT + LOAD x1, 0*REGBYTES(sp) + LOAD x4, 1*REGBYTES(sp) + LOAD x5, 2*REGBYTES(sp) + LOAD x6, 3*REGBYTES(sp) + LOAD x7, 4*REGBYTES(sp) + LOAD x10, 5*REGBYTES(sp) + LOAD x11, 6*REGBYTES(sp) + LOAD x12, 7*REGBYTES(sp) + LOAD x13, 8*REGBYTES(sp) + LOAD x14, 9*REGBYTES(sp) + LOAD x15, 10*REGBYTES(sp) + + #ifndef __riscv_32e + /* rv32i */ + LOAD x16, 14*REGBYTES(sp) + LOAD x17, 15*REGBYTES(sp) + LOAD x28, 16*REGBYTES(sp) + LOAD x29, 17*REGBYTES(sp) + LOAD x30, 18*REGBYTES(sp) + LOAD x31, 19*REGBYTES(sp) + + addi sp, sp, 20*REGBYTES + #else + /* rv32e */ + addi sp, sp, 14*REGBYTES + #endif /* __riscv_32e */ + +.endm + +/****************************************************************************** + * \brief Macro for save necessary CSRs to stack + * \details + * This macro store MCAUSE, MEPC, MSUBM to stack. + */ +.macro SAVE_CSR_CONTEXT + csrrwi x0, CSR_PUSHMCAUSE, 11 + csrrwi x0, CSR_PUSHMEPC, 12 + csrrwi x0, CSR_PUSHMSUBM, 13 +.endm + +/****************************************************************************** + * \brief Macro for restore necessary CSRs from stack + * \details + * This macro restore MSUBM, MEPC, MCAUSE from stack. + */ +.macro RESTORE_CSR_CONTEXT + LOAD x5, 13*REGBYTES(sp) + csrw CSR_MSUBM, x5 + LOAD x5, 12*REGBYTES(sp) + csrw CSR_MEPC, x5 + LOAD x5, 11*REGBYTES(sp) + csrw CSR_MCAUSE, x5 +.endm + +/****************************************************************************** + * \brief Exception/NMI Entry + * \details + * This function provide common entry functions for exception/nmi. + * \remarks + * This function provide a default exception/nmi entry. + * ABI defined caller save register and some CSR registers + * to be saved before enter interrupt handler and be restored before return. + */ + + .section .text.trap + .align 6 + .global excp_entry + .type excp_entry, @function +excp_entry: + + SAVE_CONTEXT + SAVE_CSR_CONTEXT + + csrr a0, mcause + mv a1, sp + + /** + * Call the exception handler function + * By default, the function template is provided in + * system_Device.c, you can adjust it as you want + */ + call sys_core_excp_handler + + RESTORE_CSR_CONTEXT + RESTORE_CONTEXT + + mret + + .size excp_entry, . - excp_entry + +/** + * \brief Non-Vector Interrupt Entry + * \details + * This function provide common entry functions for handling + * non-vector interrupts + * \remarks + * This function provide a default non-vector interrupt entry. + * ABI defined caller save register and some CSR registers need + * to be saved before enter interrupt handler and be restored before return. + */ + .section .text.irq + .align 2 + .weak irq_entry + .type irq_entry, @function +irq_entry: + + SAVE_CONTEXT + SAVE_CSR_CONTEXT + + csrrw ra, CSR_JALMNXTI, ra + + DISABLE_MIE + + RESTORE_CSR_CONTEXT + RESTORE_CONTEXT + + mret + + .size irq_entry, . - irq_entry + + + .section .text + .align 7 + .weak default_handler + .type default_handler, @function +Undef_Handler: +default_handler: +1: + j 1b + + .size default_handler, . - default_handler diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/interrupt.c b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/interrupt.c new file mode 100644 index 0000000..754ddcf --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/interrupt.c @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file interrupt.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "device.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +extern void default_handler(void); + +//============================================================================= +// Private Function Definition +//============================================================================= +/** + * \brief System Timer ISR + * + * \return None + */ +void eclic_mtim_handler(void) +{ + g_SysTicks++; + + // Reload Timer Interrupt + SysTick_Reload(g_SysTickPeriod); + return; +} + +/** + * \brief System Software ISR + * + * \return None + */ +__INTERRUPT void eclic_mswi_handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + sys_clear_swi(); + sys_clear_IRQFlag(SysSW_IRQn); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +__INTERRUPT void eclic_bwei_handler(void) +{ + return; +} + +__INTERRUPT void eclic_pmovi_handler(void) +{ + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * irq vector table + */ +const fp_isr_t __Vectors[__ECLIC_INTNUM] __USED __attribute__((section (".mintvec"))) = +{ + (fp_isr_t)0, /* 0: Reserved */ + default_handler, /* 1: Reserved */ + default_handler, /* 2: Reserved */ + eclic_mswi_handler, /* 3: Machine software interrupt */ + default_handler, /* 4: Reserved */ + default_handler, /* 5: Reserved */ + default_handler, /* 6: Reserved */ + eclic_mtim_handler, /* 7: Machine timer interrupt */ + default_handler, /* 8: Reserved */ + default_handler, /* 9: Reserved */ + default_handler, /* 10: Reserved */ + default_handler, /* 11: Reserved */ + default_handler, /* 12: Reserved */ + default_handler, /* 13: Reserved */ + default_handler, /* 14: Reserved */ + default_handler, /* 15: Reserved */ + default_handler, /* 16: Reserved */ + eclic_bwei_handler, /* 17: Bus Error interrupt */ + eclic_pmovi_handler, /* 18: Performance Monitor */ + + /*========= external interrupt ================*/ + default_handler, /* 19: ext_irq Reserved */ + default_handler, /* 20: ext_irq Reserved */ + default_handler, /* 21: ext_irq Reserved */ + default_handler, /* 22: ext_irq Reserved */ + default_handler, /* 23: ext_irq Reserved */ + default_handler, /* 24: ext_irq Reserved */ + default_handler, /* 25: ext_irq Reserved */ + default_handler, /* 26: ext_irq Reserved */ + default_handler, /* 27: ext_irq Reserved */ + default_handler, /* 28: ext_irq Reserved */ + default_handler, /* 29: ext_irq Reserved */ + default_handler, /* 30: ext_irq Reserved */ + default_handler, /* 31: ext_irq Reserved */ + default_handler, /* 32: ext_irq Reserved */ + default_handler, /* 33: ext_irq Reserved */ +}; diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/syscalls.c b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/syscalls.c new file mode 100644 index 0000000..366b5ff --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/syscalls.c @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file syscalls.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/02 + * @license + * @description + */ + +#include +#include +#include +#include +#include +#include "nmsis_core.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +#ifndef TIMEVAL_TO_TIMESPEC +#define TIMEVAL_TO_TIMESPEC(tv, ts) \ + do { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ + } while (0) +#endif +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +__WEAK int _open(const char *name, int flags, int mode) +{ + return -1; +} + +__WEAK int _close(int fd) +{ + return -1; +} + +__WEAK ssize_t _read(int fd, void *ptr, size_t len) +{ + return 0; +} + +__WEAK ssize_t _write(int fd, const void *ptr, size_t len) +{ + return 0; +} + +__WEAK int _lseek(int file, int offset, int whence) +{ + return 0; +} + +__WEAK int _isatty(int fd) +{ + return 1; +} + +__WEAK int _stat(char *file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; +} + +__WEAK int _fstat(int file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; +} + + +__WEAK void _exit(int fd) +{ + while(1) + { + __WFI(); + } +} + +__WEAK int _wait(int *status) +{ + return -1; +} + +int _link(char *old, char *new) +{ + return -1; +} + +__WEAK int _unlink(const char *name) +{ + return -1; +} + + +__WEAK int _fork(void) +{ + return -1; +} + +__WEAK int _getpid(void) +{ + return 1; +} + +__WEAK int _kill(int pid, int sig) +{ + return -1; +} + +__WEAK int _execve(char *name, char **argv, char **env) +{ + return -1; +} + +__WEAK int _gettimeofday(struct timeval *tp, void *tzp) +{ + extern uint32_t SystemCoreClock; + uint64_t cycles; + + cycles = __get_rv_cycle(); + + tp->tv_sec = cycles / SystemCoreClock; + tp->tv_usec = (cycles % SystemCoreClock) * 1000000 / SystemCoreClock; + return 0; +} + +__WEAK int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + struct timeval tv; + int retval = -1; + + retval = _gettimeofday(&tv, NULL); + if (retval == 0) + { + TIMEVAL_TO_TIMESPEC(&tv, tp); + } + + return retval; +} + +__WEAK int clock_settime(clockid_t clock_id, const struct timespec *tp) +{ + return -1; +} + +__WEAK int clock_getres(clockid_t clock_id, struct timespec *res) +{ + extern uint32_t SystemCoreClock; + + res->tv_sec = 0; + res->tv_nsec = 1000000000l / SystemCoreClock; + + return 0; +} + +__WEAK clock_t _times(struct tms *buf) +{ + static struct timeval t0; + struct timeval t; + long long utime; + + /* When called for the first time, initialize t0. */ + if( t0.tv_sec == 0 && t0.tv_usec == 0 ) + { + _gettimeofday(&t0, 0); + } + + _gettimeofday(&t, 0); + + utime = (t.tv_sec - t0.tv_sec) * 1000000 + (t.tv_usec - t0.tv_usec); + buf->tms_utime = utime * CLOCKS_PER_SEC / 1000000; + buf->tms_stime = buf->tms_cstime = buf->tms_cutime = 0; + + return buf->tms_utime; +} + +__WEAK void *_sbrk(ptrdiff_t incr) +{ + return 0; +} diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/system_dev.c b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/system_dev.c new file mode 100644 index 0000000..0f1c46f --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/Device/src/system_dev.c @@ -0,0 +1,424 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file system_dev.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#include "device.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_ENABLE_STACK_DEBUG 0 + +#if (CONFIG_ENABLE_STACK_DEBUG) + extern int sys_printf(const char* format, ...); + #define DEBUG(str, ...) sys_printf(str, ##__VA_ARGS__) +#else + #define DEBUG(str, ...) +#endif + +#if !defined(SYS_HIRC_VALUE) +#define SYS_HIRC_MHZ (60ul) +#define SYS_HIRC_VALUE (SYS_HIRC_MHZ * 1000ul * 1000ul) +#endif + +#if !defined(SYS_OSC_VALUE) +#define SYS_OSC_VALUE (8 * 1000ul * 1000ul) +#endif + +#if !defined(SYS_LIRC_VALUE) +#define SYS_LIRC_VALUE 32768ul +#endif + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +volatile uint32_t g_SystemCoreClock = SYS_HIRC_VALUE; +volatile uint32_t g_SysTicks = 0; +volatile uint32_t g_SysTickPeriod = 0; +volatile uint32_t g_SysTickUnit_MS = 0; + +//============================================================================= +// Private Function Definition +//============================================================================= + +#if defined(__EXCP_PRESENT) && (__EXCP_PRESENT == 1) + +/** + * Max exception handler number + */ +#define CONFIG_SYS_EXCP_MAX_NUM ((int)EXCPn_Total) + +/** + * \brief Store the exception handlers for each exception ID + * \note + * - This g_SysExcpHandlers are used to store all the handlers for all + * the exception codes Nuclei N100 core provided. + * - Exception code 0 - 11, totally 12 exceptions are mapped to g_SysExcpHandlers[0:11] + */ +static uint32_t g_SysExcpHandlers[CONFIG_SYS_EXCP_MAX_NUM] = {0}; +static uint32_t g_cb_nmi_handler = 0; + +/** + * @brief System Default Exception Handler + * This function provides a default exception handler for all exception IDs. + * By default, It will just print some information for debug, + * Vendor can customize it according to its requirements. + * + * @param [in] mcause code indicating the reason that caused the trap in machine mode + * @param [in] sp stack pointer + * @return + * None + */ +static void _sys_def_excp_handler(uint32_t mcause, uint32_t sp) +{ + DEBUG("MCAUSE : 0x%08X\n", mcause); + DEBUG("MEPC : 0x%08X\n", __RV_CSR_READ(CSR_MEPC)); + DEBUG("MTVAL : 0x%08X\n", __RV_CSR_READ(CSR_MTVAL)); + DEBUG("HARTID : %u\n", (unsigned int)__get_hart_id()); + + do{ /* Dump the frame of stack */ + DEBUG("ra: 0x%08X, tp: 0x%08X,\n" + "t0: 0x%08X, t1: 0x%08X, t2: 0x%08X,\n" + "a0: 0x%08X, a1: 0x%08X, a2: 0x%08X, a3: 0x%08X,\n" + "a4: 0x%08X, a5: 0x%08X,\n" + "cause: 0x%08X, epc: 0x%08X\n", + ((excp_frame_t*)sp)->ra, ((excp_frame_t*)sp)->tp, + ((excp_frame_t*)sp)->t0, ((excp_frame_t*)sp)->t1, ((excp_frame_t*)sp)->t2, + ((excp_frame_t*)sp)->a0, ((excp_frame_t*)sp)->a1, ((excp_frame_t*)sp)->a2, ((excp_frame_t*)sp)->a3, + ((excp_frame_t*)sp)->a4, ((excp_frame_t*)sp)->a5, + ((excp_frame_t*)sp)->cause, ((excp_frame_t*)sp)->epc); + DEBUG("sp: 0x%08X\n", (int)__get_sp()); + + #ifndef __riscv_32e + /* rv32i */ + DEBUG("t3: 0x%08X, t4: 0x%08X, t5: 0x%08X, t6: 0x%08X,\n" + "a6: 0x%08X, a7: 0x%08X\n", + ((excp_frame_t*)sp)->t3, ((excp_frame_t*)sp)->t4, ((excp_frame_t*)sp)->t5, ((excp_frame_t*)sp)->t6, + ((excp_frame_t*)sp)->a6, ((excp_frame_t*)sp)->a7); + #endif /* __riscv_32e */ + }while(0); + + while (1) + { + __WFI(); + } +} + + +/** + * @brief Common Exception handler entry + * This function provided a command entry for exception. + * Silicon Vendor could modify this template implementation according to requirement. + * @param [in] mcause code indicating the reason that caused the trap in machine mode + * @param [in] sp stack pointer + * @return + * 0 + * \remarks + * - RISCV provided common entry for all types of exception. This is proposed code template + * for exception entry function, Silicon Vendor could modify the implementation. + * - For the sys_core_excp_handler template, we provided exception register function \ref Exception_Register_EXC + * which can help developer to register your exception handler for specific exception number. + */ +__WEAK uint32_t sys_core_excp_handler(uint32_t mcause, uint32_t sp) +{ + uint32_t excp_code = (uint32_t)(mcause & 0x00000FFF); + cb_excp_handler_t cb_excp_handler = 0; + + cb_excp_handler = (excp_code == EXCPn_NMI) ? (cb_excp_handler_t)g_cb_nmi_handler + : (excp_code < CONFIG_SYS_EXCP_MAX_NUM) ? (cb_excp_handler_t)g_SysExcpHandlers[excp_code] + : (cb_excp_handler_t)_sys_def_excp_handler; + + if( cb_excp_handler ) + { + cb_excp_handler(mcause, sp); + } + return 0; +} + + +/** + * @brief Initialize all the default exception handlers + * The core exception handler for each exception ID + * will be initialized to @ref _sys_def_excp_handler. + * ps. Called in @ref sys_premain_init function, + * used to initialize default exception handlers for all exception IDs + * @return + * None + */ +__WEAK void sys_excp_init(void) +{ + extern void excp_entry(void); + + g_cb_nmi_handler = (uint32_t)_sys_def_excp_handler; + for(int i = 0; i < CONFIG_SYS_EXCP_MAX_NUM; i++) + { + g_SysExcpHandlers[i] = (uint32_t)_sys_def_excp_handler; + } + + __RV_CSR_WRITE(CSR_MTVEC, (uint32_t)excp_entry | 0x3ul); + + return; +} + +__WEAK int sys_excp_register_handler(EXCPn_Type excp_id, uint32_t excp_handler) +{ + if( (int)excp_id == EXCPn_NMI ) + { + g_cb_nmi_handler = excp_handler; + } + else if( (int)excp_id < CONFIG_SYS_EXCP_MAX_NUM ) + { + g_SysExcpHandlers[excp_id] = (uint32_t)excp_handler; + } + else + return -1; + + return 0; +} + +#else /* __EXCP_PRESENT == 1 */ + #define sys_excp_init() + #define sys_excp_register_handler() +#endif /* __EXCP_PRESENT == 1 */ + + +#if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) +/** + * @brief Initialize interrupt config + * Interrupt needs be initialized after boot up + * + * @return None + */ +static void sys_interrupt_init(void) +{ + extern const fp_isr_t __Vectors[__ECLIC_INTNUM]; + extern void irq_entry(void); + + __RV_CSR_WRITE(CSR_MTVT, (uint32_t)__Vectors); + __RV_CSR_WRITE(CSR_MTVT2, (uint32_t)irq_entry | 0x1ul); + + ECLIC_SetMth(0); + ECLIC_SetCfgNlbits(__ECLIC_INTCTLBITS); + + return; +} + +int sys_set_IRQAttr(IRQn_Type irq_id, sys_irq_attr_t *pAttr) +{ + if( irq_id >= __ECLIC_INTNUM || !pAttr ) + return -1; + + /* set interrupt vector mode */ + ECLIC_SetShvIRQ(irq_id, + (pAttr->disable_vector) ? ECLIC_NON_VECTOR_INTERRUPT : ECLIC_VECTOR_INTERRUPT); + + ECLIC_SetTrigIRQ(irq_id, pAttr->trig_mode); /* set interrupt vector mode */ + ECLIC_SetLevelIRQ(irq_id, pAttr->level); /* set interrupt level */ + ECLIC_SetPriorityIRQ(irq_id, pAttr->priority); /* set interrupt priority */ + + /* enable interrupt */ + ECLIC_EnableIRQ(irq_id); + + return 0; +} + +int sys_register_IRQ(IRQn_Type irq_id, void *cb_handler, sys_irq_attr_t *pAttr) +{ + if( irq_id >= __ECLIC_INTNUM || !cb_handler || !pAttr ) + return -1; + + ECLIC_DisableIRQ(irq_id); + + if( cb_handler ) + { + /* set interrupt handler entry to vector table */ + ECLIC_SetVector(irq_id, (rv_csr_t)cb_handler); + } + + sys_set_IRQAttr(irq_id, pAttr); + + return 0; +} + +#else /* __ECLIC_PRESENT == 1 */ + #define sys_interrupt_init() +#endif /* __ECLIC_PRESENT == 1 */ + + +/** + * \brief early init function before main + * + * \return + * none + * \details + * This function is executed right before main function. + * For RISC-V gnu toolchain, _init function might not be called + * by __libc_init_array function, so we defined a new function + * to do initialization + */ +void sys_premain_init(void) +{ + SysTimer_Stop(); + + g_SysTickPeriod = SYS_TICK_1_MS; + g_SysTicks = 0; + g_SystemCoreClock = sys_get_cpu_freq(); + + sys_excp_init(); + + sys_interrupt_init(); + + return; +} + +/** + * \brief finish function after main + * + * \param [in] status + * \return + * + * \details + * This function is executed right after main function. + * For RISC-V gnu toolchain, _fini function might not be called + * by __libc_fini_array function, so we defined a new function + * to do initialization + */ +void sys_postmain_fini(int status) +{ + return; +} + + +//============================================================================= +// Public Function Definition +//============================================================================= +void sys_init(void) +{ + /** + * Configure eFlash + * + Set eFlash latency + * + Disable and clear interrup + */ + FLASH->CMD = 0xA5A50020ul; + FLASH->SR = 0xFFFFFFFFul; + FLASH->DIV = (FLASH->DIV & ~FLASH_DIV_DIV_Msk) | \ + (SYS_HIRC_MHZ << FLASH_DIV_DIV_Pos) | \ + (0x1ul << 8); + +#if 1 + SYSCFG->PCLKEN |= SYSCFG_PCLKEN_AMISC_Msk; + AMISC->HSI_CR = (AMISC->HSI_CR & ~AMISC_HSI_CR_LDO_SEL_Msk) | \ + (AMISC_HSI_CR_LDO_SEL_LDO << AMISC_HSI_CR_LDO_SEL_Pos); +#endif + + return; +} + +/** + * \brief delay a time in milliseconds + * + * \param [in] msec count in milliseconds + * \return + * none + */ +void sys_delay(uint32_t msec) +{ +#if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1) + /** + * Only for 1ms system tick + */ + uint32_t tick_start = 0; + + tick_start = g_SysTicks; + while( (g_SysTicks - tick_start) < msec ) + { + } + +#else + #warning "sys_delay_1ms function require system timer present, if you are using this, it will not work" +#endif +} + +void sys_busy_wait(uint32_t ticks) +{ + while( ticks-- ); + return; +} + +uint32_t sys_get_cpu_freq(void) +{ + if( (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKSW_Msk) + == (SYSCFG_SYSCLKCR_CLKSW_HSI << SYSCFG_SYSCLKCR_CLKSW_Pos) ) + { + g_SystemCoreClock = SYS_HIRC_VALUE; + } + else if( (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKSW_Msk) + == SYSCFG_SYSCLKCR_CLKSW_LSI << SYSCFG_SYSCLKCR_CLKSW_Pos ) + { + g_SystemCoreClock = SYS_LIRC_VALUE; + } + else if( (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKSW_Msk) + == (SYSCFG_SYSCLKCR_CLKSW_HSE << SYSCFG_SYSCLKCR_CLKSW_Pos) ) + { + g_SystemCoreClock = SYS_OSC_VALUE; + } + else + { + uint32_t div = (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKDIV_Msk) >> SYSCFG_SYSCLKCR_CLKDIV_Pos; + div = (div) ? (div + 1) : 2; + g_SystemCoreClock = SYS_HIRC_VALUE / div; + } + + return g_SystemCoreClock; +} + +void sys_config_systick(uint32_t ticks) +{ + volatile register uint32_t value = 0; + uint32_t sys_clock = SYS_HIRC_VALUE; + + if( (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKSW_Msk) + == (SYSCFG_SYSCLKCR_CLKSW_CLKDIV << SYSCFG_SYSCLKCR_CLKSW_Pos) ) + { + uint32_t div = (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_CLKDIV_Msk) >> SYSCFG_SYSCLKCR_CLKDIV_Pos; + div = (div) ? (div + 1) : 2; + sys_clock = SYS_HIRC_VALUE / div; + } + + + value = (SYSCFG->SYSCLKCR & SYSCFG_SYSCLKCR_SYSTICKCR_Msk) >> SYSCFG_SYSCLKCR_SYSTICKCR_Pos; + + g_SysTickUnit_MS = (value == SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV2) ? (sys_clock / 2000ul) : + (value == SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV4) ? (sys_clock / 4000ul) : + (value == SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV8) ? (sys_clock / 8000ul) : + (SYS_TIMER_FREQ / 1000ul); + + g_SysTickPeriod = (ticks == SYS_TICK_10_MS) ? (10ul * g_SysTickUnit_MS) : + (ticks == SYS_TICK_100_MS) ? (100ul * g_SysTickUnit_MS) : + (ticks == SYS_TICK_1_SEC) ? (1000ul * g_SysTickUnit_MS) : + g_SysTickUnit_MS; + + __disable_irq(); + + SysTimer_Stop(); + SysTick_Config(g_SysTickPeriod); + SysTimer_Start(); + + __enable_irq(); + return; +} diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..62e35619dcd45bd23d4bd0e65e14e7e7798928bc GIT binary patch literal 10244 zcmeHMU2GLa6rQuUz^+|oOMm#=rb{jmDHU2M6@oy2`D>xIx23l~Q1;$k+O^x=dUx+_ zp=oSmo9_RP#Bgg|ZDs31fmgos!uRb;IG=AnFAZhM4aL_rFuPrRXo?Iy7Id1B}` z>2M(QK1L7d(JDn?7PLr(qp>AoM`!fk_Y0?}LVg(&~VYbILv)Sg|7j z(i|LS54P!Xfa+)gtq$lor^vwvxGGYv3c(QrxH^t&fn0S!$2sNd1cJi{1S>;uLIJiq z&aW|X0@a*`b?AZ61GjsChD(H4#39MV@YM6WZFzoq`DG9yIdkUD6X%J!;{I5_I~?JYHUmr3!`f{xAqR$gN}Qg8vwyafIK+EpcA*O zvHL1wNq3OnLkOpmQ#f9xj^9&65{V&h=hdv8(gV4&{E!;&jCXbS?C({Sv}d-Ow(eUQ zvtIX2uUDDxq2arduG5k-GiY!}(zVlr4s!C6x}8j;uvuf+*R56)y zZM((wEZ=gS&bU7tE8gX~DZh@*8@F&NKEVRIT=NiB_V$@652+-5Fn^J@V%3`U8@JSK z-@UhWLdjc@FUv&>J2IAMC2X@(_mZY#SWaL2ux0rDUFdelw+>lmN|N%Rtj*B}&56ZJ zmgcL)YDrd$%ihuzm8cj`C#)yamVbC6KW~AuOpVGt2HLvEHRx=HsGODJs~PO7hEe>$ZZ3N3rX?#NTpn*w%dBbv?ayhYMbQEYDXrpR%zse zTje4(jz8}pn&L@(tX8d8571?sbkA=dG9CI#7ddYS^18f!J!LizBQAqCYQ$0Yd*V1% zYA`I{rA+3HsQS1lcG3xJ48t@g@|P@K9BWfiL$REUg>iuX=i#7S5=AjuUCQAY&7v}T z)_jAtnUAB@<(yH#$z)A)UkO=9>PZthNCwClIZ95FH_7|t963+EB$vola-IB4ej_)@ zpFki2BILnhD1lW_3T5yJRKYfAf<4d-Ezk)j9D+U=f;41c1P;T~@C-Z)$KeFL0I$HS z@EW`h@4$!f5qu1vz!&f}d;=HYTet?_!S`?-euCfO54a%+LV-{y6bU7QCM*+H3zfnS zVVAI5XcU@+cHw}~C)h%oTOnj4^1!53tRWml5`155FB9Ak3TI}CyW*X@cJ6L$+H*g| z-Ie(?(h3TT7A{)0a&`HJOH(MeWpBU;!{KY*+v=fXo0dMWI?OmuT6TycLZ+ zI@>XF%n^|Wu`(}^UcN%a$Wi75-BqR7ZB*v+ZtHw88u?yU_bPN4o|=U*x(@O55o}{g)w*vA%6@({~SCIFTqK88G(Na-h#K`U3d>+ ze;Pi8&)_VagY)oJ5CB&Y{y)O6Ga$Wp2Bay}14s|L_4UD(H@hW|pSe&om22FAJJdfV zK}9sWNHA+AmU3*@>BAAemPbpR zu02@0Iv5-0l&PZ(Q%8E2{tWmx?%l%ke|Y|%b%Vh!)Cb*JHW-XMZG#cfXgu7_^Z#E_ Cp~;Q_ literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_adc.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_adc.h new file mode 100644 index 0000000..5f438fa --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_adc.h @@ -0,0 +1,527 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_adc.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_adc_H_wiD001de_llts_HbDE_s9jK_uDX2acTbwqSx__ +#define __hal_adc_H_wiD001de_llts_HbDE_s9jK_uDX2acTbwqSx__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define ADC_AIN_CHANNEL_NUM 16 + +/** + * ADC AIN channels + * ps. Channel-0 conversion priority is the highest and + * Channel-15 conversion priority is the lowest + */ +typedef enum ADC_Channels +{ + ADC_Channel_00 = (0x1ul << 0 ), + ADC_Channel_01 = (0x1ul << 1 ), + ADC_Channel_02 = (0x1ul << 2 ), + ADC_Channel_03 = (0x1ul << 3 ), + ADC_Channel_04 = (0x1ul << 4 ), + ADC_Channel_05 = (0x1ul << 5 ), + ADC_Channel_06 = (0x1ul << 6 ), + ADC_Channel_07 = (0x1ul << 7 ), + ADC_Channel_08 = (0x1ul << 8 ), + ADC_Channel_09 = (0x1ul << 9 ), + ADC_Channel_10 = (0x1ul << 10), + ADC_Channel_11 = (0x1ul << 11), + ADC_Channel_12 = (0x1ul << 12), + ADC_Channel_13 = (0x1ul << 13), + ADC_Channel_14 = (0x1ul << 14), + ADC_Channel_15 = (0x1ul << 15), + + ADC_Channel_OPA0_O = ADC_Channel_00, + ADC_Channel_OPA1_O = ADC_Channel_01, + ADC_Channel_AVSS = ADC_Channel_14, + ADC_Channel_AMISC = ADC_Channel_15, // It should configure AMISC->VBUF_CR_b.ANA_SEL +} ADC_ChannelsTypeDef; + +/** + * Sub-Channels of Channel-AMISC (channel-15) of ADC + * ref. AMISC->VBUF_CR_b.ANA_SEL + */ +typedef enum ADC_SubChannel +{ + ADC_SubChannel_NONE = (AMISC_VBUF_CR_ANA_SEL_NONE << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_TEMP = (AMISC_VBUF_CR_ANA_SEL_TEMP << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_DAC0 = (AMISC_VBUF_CR_ANA_SEL_DAC0 << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_DAC1 = (AMISC_VBUF_CR_ANA_SEL_DAC1 << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_VBuf_1_5 = (AMISC_VBUF_CR_ANA_SEL_VBuf_1p5v << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_VDDL = (AMISC_VBUF_CR_ANA_SEL_VDDL << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_VSS = (AMISC_VBUF_CR_ANA_SEL_VSS << AMISC_VBUF_CR_ANA_SEL_Pos), + ADC_SubChannel_VDD = (AMISC_VBUF_CR_ANA_SEL_VDD << AMISC_VBUF_CR_ANA_SEL_Pos), +} ADC_SubChannelTypeDef; + +/** + * ADC working clock divides + * Note 1: The Working-Clock of ADC MUST be 800KHz ~ 16MHz + * Note 2: It MUST wait 20-cycles after change ADC working-clock + */ +typedef enum ADC_ClkDiv +{ + ADC_ClkDiv_Auto = 0, + ADC_ClkDiv_2 = (ADC_CON0_CLK_Div2 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_4 = (ADC_CON0_CLK_Div4 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_8 = (ADC_CON0_CLK_Div8 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_16 = (ADC_CON0_CLK_Div16 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_32 = (ADC_CON0_CLK_Div32 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_3_75 = (ADC_CON0_CLK_Div3_75 << ADC_CON0_CLK_Pos), + ADC_ClkDiv_3_5 = (ADC_CON0_CLK_Div3_5 << ADC_CON0_CLK_Pos), +} ADC_ClkDivTypeDef; + +/** + * ADC mode + */ +typedef enum ADC_Mode +{ + ADC_Mode_SingleConv = 0, + ADC_Mode_Continuous, /*!< ADC Continuous mode will be Never-Stop-Conversion. + This mode NOT support interrupt. */ + ADC_Mode_Scan, + ADC_Mode_Discontinuous, +} ADC_ModeTypeDef; + +/** + * ADC external trigger source for conversion + */ +typedef enum ADC_ExtTrigSource +{ + ADC_ExtTrigSource_00 = 0x0, + ADC_ExtTrigSource_01 = 0x1, + ADC_ExtTrigSource_02 = 0x2, + ADC_ExtTrigSource_03 = 0x3, + ADC_ExtTrigSource_04 = 0x4, + ADC_ExtTrigSource_05 = 0x5, + ADC_ExtTrigSource_06 = 0x6, + ADC_ExtTrigSource_07 = 0x7, + ADC_ExtTrigSource_08 = 0x8, + ADC_ExtTrigSource_09 = 0x9, + ADC_ExtTrigSource_10 = 0xA, + ADC_ExtTrigSource_11 = 0xB, + ADC_ExtTrigSource_12 = 0xC, + ADC_ExtTrigSource_13 = 0xD, + ADC_ExtTrigSource_14 = 0xE, + ADC_ExtTrigSource_15 = 0xF, + ADC_ExtTrigSource_16 = 0x1D, + ADC_ExtTrigSource_17 = 0x1E, + ADC_ExtTrigSource_Soft = 0xFF, /*!< ADC Software trigger */ + + ADC_ExtTrigSource_EPWM_CH1R = ADC_ExtTrigSource_00, /*!< ADC external source trigger from EPWM CH1 Rising */ + ADC_ExtTrigSource_EPWM_CH2R = ADC_ExtTrigSource_01, /*!< ADC external source trigger from EPWM CH2 Rising */ + ADC_ExtTrigSource_EPWM_CH3R = ADC_ExtTrigSource_02, /*!< ADC external source trigger from EPWM CH3 Rising */ + ADC_ExtTrigSource_EPWM_CH1F = ADC_ExtTrigSource_03, /*!< ADC external source trigger from EPWM CH1 Falling */ + ADC_ExtTrigSource_EPWM_CH2F = ADC_ExtTrigSource_04, /*!< ADC external source trigger from EPWM CH2 Falling */ + ADC_ExtTrigSource_EPWM_CH3F = ADC_ExtTrigSource_05, /*!< ADC external source trigger from EPWM CH3 Falling */ + ADC_ExtTrigSource_COMP0_Rise = ADC_ExtTrigSource_06, /*!< ADC external source trigger from COMP0 Rising */ + ADC_ExtTrigSource_COMP1_Rise = ADC_ExtTrigSource_08, /*!< ADC external source trigger from COMP1 Rising */ + ADC_ExtTrigSource_COMP0_Fall = ADC_ExtTrigSource_07, /*!< ADC external source trigger from COMP0 Falling */ + ADC_ExtTrigSource_COMP1_Fall = ADC_ExtTrigSource_09, /*!< ADC external source trigger from COMP1 Falling */ + ADC_ExtTrigSource_EPWM_UDF = ADC_ExtTrigSource_10, /*!< ADC external source trigger from EPWM Counter UDF */ + ADC_ExtTrigSource_EPWM_OVF = ADC_ExtTrigSource_11, /*!< ADC external source trigger from EPWM Counter OVF */ + ADC_ExtTrigSource_EPWM_CCR4_UP = ADC_ExtTrigSource_12, /*!< ADC external source trigger from EPWM_CNTUP == CCR4 */ + ADC_ExtTrigSource_EPWM_CCDR4_UP = ADC_ExtTrigSource_13, /*!< ADC external source trigger from EPWM_CNTUP == CCDR4 */ + ADC_ExtTrigSource_EPWM_CCR4_DN = ADC_ExtTrigSource_14, /*!< ADC external source trigger from EPWM_CNTDN == CCR4 */ + ADC_ExtTrigSource_EPWM_CCDR4_DN = ADC_ExtTrigSource_15, /*!< ADC external source trigger from EPWM_CNTDN == CCDR4 */ + ADC_ExtTrigSource_TIM0 = ADC_ExtTrigSource_16, /*!< ADC external source trigger from Tim0 */ + ADC_ExtTrigSource_PB1 = (ADC_ExtTrigSource_17), /*!< ADC external source trigger from Pin (PB1) */ + ADC_ExtTrigSource_PB2 = (ADC_ExtTrigSource_17 | 0x20ul), /*!< ADC external source trigger from Pin (PB2) */ +} ADC_ExtTrigSourceTypeDef; + +typedef enum ADC_ExtTrigMode +{ + ADC_ExtTrigMode_Disable = 0ul, + ADC_ExtTrigMode_Enable = 0x1ul, + ADC_ExtTrigMode_PinRising = ADC_ExtTrigMode_Enable, // Be used when external source is ADC_ExtTrigSource_17 + ADC_ExtTrigMode_PinFaling = (ADC_ExtTrigMode_Enable | 0x2ul), // Be used when external source is ADC_ExtTrigSource_17 +} ADC_ExtTrigModeTypeDef; + +/** + * ADC Data Align + */ +typedef enum ADC_DataAlign +{ + ADC_DataAlign_Right = (ADC_CON0_ALIGN_RIGHT << ADC_CON0_ALIGN_Pos), + ADC_DataAlign_Left = (ADC_CON0_ALIGN_LEFT << ADC_CON0_ALIGN_Pos), +} ADC_DataAlignTypeDef; + +/** + * The ADC interrupt type + */ +typedef enum ADC_IT +{ + ADC_IT_DISABLE = (ADC_CON0_INT_EN_DISABLE << ADC_CON0_INT_EN_Pos), + ADC_IT_CONV_DONE = (ADC_CON0_INT_EN_DONE << ADC_CON0_INT_EN_Pos), /*!< ADC conversion is done */ + ADC_IT_LOWER_THRESHOLD = (ADC_CON0_INT_EN_LT_THR << ADC_CON0_INT_EN_Pos), /*!< ADC conversion value is below threshold */ + ADC_IT_HIGHER_THRESHOLD = (ADC_CON0_INT_EN_GT_THR << ADC_CON0_INT_EN_Pos), /*!< ADC conversion value is above threshold */ + ADC_IT_EQUAL_THRESHOLD = (ADC_CON0_INT_EN_EQ_THR << ADC_CON0_INT_EN_Pos), /*!< ADC conversion value is equal to threshold */ + ADC_IT_CONV_GROUP_SUBSET = (0x80000000ul | ADC_CHSEL_DISC_INTSEL_Msk), + ADC_IT_CONV_GROUP_DONE = 0x80000000ul, +} ADC_ITTypeDef; + +/** + * The ADC interrupt status + */ +typedef enum ADC_ITStatus +{ + ADC_ITStatus_None = (ADC_STAT_COMP_RESULT_NONE << ADC_STAT_COMP_RESULT_Pos), + ADC_ITStatus_LowerThreshold = (ADC_STAT_COMP_RESULT_LT_THR << ADC_STAT_COMP_RESULT_Pos), + ADC_ITStatus_HigherThreshold = (ADC_STAT_COMP_RESULT_GT_THR << ADC_STAT_COMP_RESULT_Pos), + ADC_ITStatus_EqualThreshold = (ADC_STAT_COMP_RESULT_EQ_THR << ADC_STAT_COMP_RESULT_Pos), +} ADC_ITStatusTypeDef; + +/** + * The brake source type from an ADC channel + */ +typedef enum ADC_BKSrc +{ + ADC_BKSrc_Src1 = 0, + ADC_BKSrc_Src2 = 8, +} ADC_BKSrcTypeDef; + +/** + * The ADC brake filter type + */ +typedef enum ADC_BKFilter +{ + ADC_BKFilter_MATCH_1 = (ADC_BKSEL_BK1_FLT_OFF << ADC_BKSEL_BK1_FLT_Pos), + ADC_BKFilter_MATCH_2 = (ADC_BKSEL_BK1_FLT_MATCH_2 << ADC_BKSEL_BK1_FLT_Pos), + ADC_BKFilter_MATCH_4 = (ADC_BKSEL_BK1_FLT_MATCH_4 << ADC_BKSEL_BK1_FLT_Pos), + ADC_BKFilter_MATCH_7 = (ADC_BKSEL_BK1_FLT_MATCH_7 << ADC_BKSEL_BK1_FLT_Pos), +} ADC_BKFilterTypeDef; + +/** + * The Brake condition with the ADC brake source + */ +typedef enum ADC_BKCond +{ + ADC_BKCond_Disabe = (ADC_BKSEL_BK1_EN_OFF << ADC_BKSEL_BK1_EN_Pos), + ADC_BKCond_LOWER_THRESHOLD = (ADC_BKSEL_BK1_EN_GT_THR << ADC_BKSEL_BK1_EN_Pos), + ADC_BKCond_HIGHER_THRESHOLD = (ADC_BKSEL_BK1_EN_LT_THR << ADC_BKSEL_BK1_EN_Pos), + ADC_BKCond_EQUAL_THRESHOLD = (ADC_BKSEL_BK1_EN_EQ_THR << ADC_BKSEL_BK1_EN_Pos), +} ADC_BKCondTypeDef; + +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief ADC Start + * ps. This API MUST be called after ADC_Init() + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_Start(ADC_Type *pHADC) +{ + REG_SET_BITS(pHADC->STAT, ADC_STAT_INT_CLR_Msk); // clear flag + REG_SET_BITS(pHADC->CON0, ADC_CON0_START_Msk); + + sys_busy_wait(32); + return; +} + +/** + * \brief ADC conversion is idle or not + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * 0: busy, others: idle + */ +__STATIC_FORCEINLINE uint32_t ADC_IsIdle(ADC_Type *pHADC) +{ + return REG_READ_MASK(pHADC->STAT, ADC_STAT_DONE_Msk); +} + +/** + * \brief Get the status of interrupt of ADC + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * Interrupt flags, @ref ADC_ITStatusTypeDef + */ +__STATIC_FORCEINLINE ADC_ITStatusTypeDef ADC_GetITStatus(ADC_Type *pHADC) +{ + return REG_READ_MASK(pHADC->STAT, ADC_STAT_COMP_RESULT_Msk); +} + +/** + * \brief ADC Clear interrupt flag + * + * \param [in] pHADC + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_ClearITFlag(ADC_Type *pHADC) +{ + REG_SET_BITS(pHADC->STAT, ADC_STAT_INT_CLR_Msk); + return; +} + +/** + * \brief Set the subset number of grouped-channels in ADC Discontinuous mode + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] subset_ch_num the subset channel number of a group + * ps. the group_ch_num ONLY be 1 ~ 8 + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_DiscMode_SetGroupSubsetNum(ADC_Type *pHADC, uint8_t subset_ch_num) +{ + REG_WRITE_MASK(pHADC->CHSEL, ADC_CHSEL_DISCNUM_Msk, (subset_ch_num - 1) << ADC_CHSEL_DISCNUM_Pos); + return; +} + +/** + * \brief Get the EOC count of ADC + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * The EOC count of ADC + */ +__STATIC_FORCEINLINE uint8_t ADC_GetEOCCnt(ADC_Type *pHADC) +{ + return (uint8_t)pHADC->STAT_b.EOC_CNT; +} + +/** + * \brief Enable/Disable backup ADC conversion value + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_EnableBackup(ADC_Type *pHADC) +{ + REG_SET_BITS(pHADC->CON0, ADC_CON0_BAKEN_Msk); + return; +} + +__STATIC_FORCEINLINE void ADC_DisableBackup(ADC_Type *pHADC) +{ + REG_CLR_BITS(pHADC->CON0, ADC_CON0_BAKEN_Msk); + return; +} + +/** + * \brief Get the backup of ADC conversion value + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * The backup value + */ +__STATIC_FORCEINLINE uint16_t ADC_GetBakcupValue(ADC_Type *pHADC) +{ + return (uint16_t)pHADC->BAKDAT_b.BAKDAT; +} + + +/** + * \brief Set the sample-period of an ADC + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] cycles extern cycles (range: 0 ~ 31, default: 3) + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_SetSampleCycles(ADC_Type *pHADC, uint8_t cycles) +{ + pHADC->STAT_b.TS_SET = cycles; + return; +} + + +/** + * \brief Get the conversion value of the ADC in ISR + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] channel The target channel, @ref ADC_ChannelsTypeDef + * \return + * The ADC conversion value + */ +__STATIC_FORCEINLINE uint16_t ADC_ITGetConvValue(ADC_Type *pHADC, ADC_ChannelsTypeDef channel) +{ +#define __ADC_CLZ(x) __builtin_clz(x) + volatile uint32_t *pData = (volatile uint32_t*)&pHADC->DAT0; + uint32_t chnnl_id = (31ul - __ADC_CLZ(channel)); + + pData += (chnnl_id & 0xFul); + return (uint16_t)((*pData) & 0xFFFFul); +} + +/** + * \brief Disable interrupt of ADC + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_ITDisable(ADC_Type *pHADC) +{ + REG_WRITE_MASK(pHADC->CON0, ADC_CON0_INT_EN_Msk, ADC_IT_DISABLE); + return; +} + +//============================================================================= +// Structure Definition +//============================================================================= +/** + * ADC initialization info + */ +typedef struct ADC_Init +{ + ADC_ChannelsTypeDef SelChannels; + ADC_ClkDivTypeDef ClkPrescaler; /*!< ADC the max working clock is 16-MHz */ + ADC_DataAlignTypeDef DataAlign; + ADC_ModeTypeDef Mode; + bool IsSoftTrig; +} ADC_InitTypeDef; + +/** + * The initialization info of brake source from the ADC Channel + */ +typedef struct ADC_BKSrcInit +{ + uint8_t SelBKChannel; // The target channel ID (0~15) as brake source + ADC_BKFilterTypeDef BkFilter; + ADC_BKCondTypeDef BKCond; +} ADC_BKSrcInitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * \brief Deinitializes ADC module + * + * \param [in] pHADC Pointer to an ADC handler + * \return + * None + */ +void ADC_DeInit(ADC_Type *pHADC); + +/** + * \brief Initializes ADC module + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] pInit Pointer to an ADC_InitTypeDef structure, @ref ADC_InitTypeDef + * \return + * None + */ +void ADC_Init(ADC_Type *pHADC, ADC_InitTypeDef *pInit); + +/** + * \brief Fills each ADC_InitStruct member with its default value. + * + * \param [in] pInit Pointer to an ADC_InitTypeDef structure, @ref ADC_InitTypeDef + * \return + * None + */ +void ADC_StructInit(ADC_InitTypeDef *pInit); + +/** + * \brief ADC external trigger configuration + * Note. It should one by one to configure external sources + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] ext_src The target external source, @ref ADC_ExtTrigSourceTypeDef + * Note. if ext_src == ADC_ExtTrigSource_Soft, + * it will ignore trig_mode and DISABLE external trigger function + * \param [in] trig_mode The target ADC trigger mode, @ref ADC_ExtTrigModeTypeDef + * \return + * None + */ +void ADC_ExtTrigConfig(ADC_Type *pHADC, ADC_ExtTrigSourceTypeDef ext_src, ADC_ExtTrigModeTypeDef trig_mode); + +/** + * \brief Select the sub-channel of the ADC Channel-15 + * + * \param [in] subchannel The selected sub-channel of ADC channel-15, @ref ADC_SubChannelTypeDef + * \return + * None + */ +void ADC_SelSubChannel(ADC_SubChannelTypeDef subchannel); + +/** + * \brief Get the conversion value of an ADC channel + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] channel The target channel, @ref ADC_ChannelsTypeDef + * \return + * The ADC conversion value + */ +uint16_t ADC_GetChannelConvValue(ADC_Type *pHADC, ADC_ChannelsTypeDef channel); + +/** + * \brief Configures the comparison thresholds of an ADC channel + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] channel The target channel, @ref ADC_ChannelsTypeDef + * \param [in] threshold The target thershold value + * \return + * None + */ +void ADC_ChannelThresholdConfig(ADC_Type *pHADC, ADC_ChannelsTypeDef channel, uint16_t threshold); + +/** + * \brief Enables or disables the specified ADC interrupts + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] it_types The target interrupt types + * ps. It supports multi-interrupts selection, + * but 'ADC_IT_DISABLE' is standalone + * \return + * None + */ +void ADC_ITConfig(ADC_Type *pHADC, ADC_ITTypeDef it_types); + + +/** + * \brief Configures the brake source from an ADC channel + * + * \param [in] pHADC Pointer to an ADC handler + * \param [in] bk_src the brake source type, @ref ADC_BKSrcTypeDef + * \param [in] pBKInit Pointer to an instance of the ADC brake initialization info, @ref ADC_BKSrcInitTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void ADC_BrakeSrcConfig(ADC_Type *pHADC, ADC_BKSrcTypeDef bk_src, ADC_BKSrcInitTypeDef *pBKInit) +{ + REG_WRITE_MASK(pHADC->BKSEL, + (ADC_BKSEL_BK1_CH_Msk | ADC_BKSEL_BK1_FLT_Msk | ADC_BKSEL_BK1_EN_Msk) << bk_src, + ((pBKInit->SelBKChannel & 0xFul) | pBKInit->BkFilter | pBKInit->BKCond) << bk_src); + return; +} + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_amisc.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_amisc.h new file mode 100644 index 0000000..be9686c --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_amisc.h @@ -0,0 +1,402 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_amisc.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_amisc_H_wiD001de_alts_HbDE_s9jK_uDb2acTbwQSx__ +#define __hal_amisc_H_wiD001de_alts_HbDE_s9jK_uDb2acTbwQSx__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +typedef enum +{ + AMISC_Status_OK = 0, + AMISC_Status_Error, + AMISC_Status_Bypass, +} AMISC_StatusTypeDef; + +/** + * The threshold of LVD voltage + */ +typedef enum +{ + AMISC_LVDVoltage_2V = (AMISC_LVD_LVR_CR_LVD_SEL_2V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_2_2V = (AMISC_LVD_LVR_CR_LVD_SEL_2_2V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_2_4V = (AMISC_LVD_LVR_CR_LVD_SEL_2_4V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_2_7V = (AMISC_LVD_LVR_CR_LVD_SEL_2_7V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_3V = (AMISC_LVD_LVR_CR_LVD_SEL_3V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_3_7V = (AMISC_LVD_LVR_CR_LVD_SEL_3_7V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_4V = (AMISC_LVD_LVR_CR_LVD_SEL_4V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), + AMISC_LVDVoltage_4_3V = (AMISC_LVD_LVR_CR_LVD_SEL_4_3V << AMISC_LVD_LVR_CR_LVD_SEL_Pos), +} AMISC_LVDVoltageTypeDef; + +/** + * The threshold of LVR voltage + */ +typedef enum +{ + AMISC_LVRVoltage_2V = (AMISC_LVD_LVR_CR_LVR_SEL_2V << AMISC_LVD_LVR_CR_LVR_SEL_Pos), + AMISC_LVRVoltage_2_4V = (AMISC_LVD_LVR_CR_LVR_SEL_2_4V << AMISC_LVD_LVR_CR_LVR_SEL_Pos), + AMISC_LVRVoltage_2_7V = (AMISC_LVD_LVR_CR_LVR_SEL_2_7V << AMISC_LVD_LVR_CR_LVR_SEL_Pos), + AMISC_LVRVoltage_3V = (AMISC_LVD_LVR_CR_LVR_SEL_3V << AMISC_LVD_LVR_CR_LVR_SEL_Pos), + AMISC_LVRVoltage_3_7V = (AMISC_LVD_LVR_CR_LVR_SEL_3_7V << AMISC_LVD_LVR_CR_LVR_SEL_Pos), +} AMISC_LVRVoltageTypeDef; + +typedef enum +{ + AMISC_LVDFunc_LP = AMISC_LVD_LVR_CR_LDO_LP_EN_Msk, // LDO low power mode + AMISC_LVDFunc_TEMP = AMISC_LVD_LVR_CR_TEMP_EN_Msk, // Temperature detection + +} AMISC_LVDFuncTypeDef; + +typedef enum +{ + AMISC_InternalSrc_NONE = (AMISC_VBUF_CR_ANA_SEL_NONE << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_TEMP = (AMISC_VBUF_CR_ANA_SEL_TEMP << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_DAC0 = (AMISC_VBUF_CR_ANA_SEL_DAC0 << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_DAC1 = (AMISC_VBUF_CR_ANA_SEL_DAC1 << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_VBuf_1P5V = (AMISC_VBUF_CR_ANA_SEL_VBuf_1p5v << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_VDDL = (AMISC_VBUF_CR_ANA_SEL_VDDL << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_VSS = (AMISC_VBUF_CR_ANA_SEL_VSS << AMISC_VBUF_CR_ANA_SEL_Pos), + AMISC_InternalSrc_VDD = (AMISC_VBUF_CR_ANA_SEL_VDD << AMISC_VBUF_CR_ANA_SEL_Pos), +} AMISC_InternalSrcTypeDef; + +typedef enum +{ + AMISC_HSIPwrSrc_Normal = (AMISC_HSI_CR_LDO_SEL_Normal << AMISC_HSI_CR_LDO_SEL_Pos), + AMISC_HSIPwrSrc_LowPower = (AMISC_HSI_CR_LDO_SEL_LDO << AMISC_HSI_CR_LDO_SEL_Pos), + +} AMISC_HSIPwrSrcTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Configure DAC0 of Analog Misc. + * + * \param [in] step the voltage step (10-bits) of DAC + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC0_Config(uint16_t step) +{ + REG_WRITE_MASK(AMISC->DAC_CR, + AMISC_DAC_CR_DAC0Step_Msk, + ((uint32_t)step << AMISC_DAC_CR_DAC0Step_Pos)); + return; +} + +/** + * \brief Configure DAC1 of Analog Misc. + * + * \param [in] step the voltage step (10-bits) of DAC + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC1_Config(uint16_t step) +{ + REG_WRITE_MASK(AMISC->DAC_CR, + AMISC_DAC_CR_DAC1Step_Msk, + ((uint32_t)step << AMISC_DAC_CR_DAC1Step_Pos)); + return; +} + +/** + * \brief Enable DAC0 of Analog Misc. + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC0_Enable(void) +{ + REG_SET_BITS(AMISC->DAC_CR, AMISC_DAC_CR_DAC0_EN_Msk); + return; +} + +/** + * \brief Enable DAC1 of Analog Misc. + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC1_Enable(void) +{ + REG_SET_BITS(AMISC->DAC_CR, AMISC_DAC_CR_DAC1_EN_Msk); + return; +} + +/** + * \brief Disable DAC0 of Analog Misc. + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC0_Disable(void) +{ + REG_CLR_BITS(AMISC->DAC_CR, AMISC_DAC_CR_DAC0_EN_Msk); + return; +} + +/** + * \brief Disable DAC1 of Analog Misc. + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_DAC1_Disable(void) +{ + REG_CLR_BITS(AMISC->DAC_CR, AMISC_DAC_CR_DAC1_EN_Msk); + return; +} + + +/** + * \brief Enable LVD module + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVD_Enable(void) +{ + REG_SET_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVD_EN_Msk); + return; +} + +/** + * \brief Disable LVD module + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVD_Disable(void) +{ + REG_CLR_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVD_EN_Msk); + return; +} + +/** + * \brief Enable LVR interrupt + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVR_Enable(void) +{ + REG_SET_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVR_EN_Msk); + return; +} + +/** + * \brief Disable LVR interrupt + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVR_Disable(void) +{ + REG_CLR_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVR_EN_Msk); + return; +} + +/** + * \brief Enable LVD interrupt + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVD_ITEnable(void) +{ + REG_SET_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVD_INT_EN_Msk); + return; +} + +/** + * \brief Disable LVD interrupt + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_LVD_ITDisable(void) +{ + REG_CLR_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVD_INT_EN_Msk); + return; +} + +/** + * \brief Get the status of LVD + * + * \return + * The new state of flags (SET or RESET) + */ +__STATIC_FORCEINLINE FlagStatus AMISC_LVD_GetFlagStatus(void) +{ + return REG_READ_MASK(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_LVD_STATE_Msk) ? SET : RESET; +} + +/** + * \brief Enable VBUF + * + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_Vbuf_Enable(void) +{ + REG_SET_BITS(AMISC->VBUF_CR, AMISC_VBUF_CR_VBUF_EN_Msk); + return; +} + +/** + * \brief Disable VBUF + * + * \param [in] pHAMisc Pointer to a Analog Misc. handler + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_Vbuf_Disable(void) +{ + REG_CLR_BITS(AMISC->VBUF_CR, AMISC_VBUF_CR_VBUF_EN_Msk); + return; +} + + +/** + * \brief Set the power source of HSI + * + * \param [in] pwr_src The target power source, @ref AMISC_HSIPwrSrcTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void AMISC_SetHSIPwrSrc(AMISC_HSIPwrSrcTypeDef pwr_src) +{ + REG_WRITE_MASK(AMISC->HSI_CR, AMISC_HSI_CR_LDO_SEL_Msk, pwr_src); + return; +} + +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct +{ + AMISC_LVDVoltageTypeDef LVD_Voltage; + AMISC_LVRVoltageTypeDef LVR_Voltage; + AMISC_LVDFuncTypeDef LVD_FuncModes; + +} AMISC_LVDRInitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Initialize Analog misc. module + * + * \return + * result status, @ref AMISC_StatusTypeDef + */ +AMISC_StatusTypeDef AMISC_Init(void); + +/** + * \brief De-Initialize Analog misc. module + * + * \param [in] is_force Force to de-initialize or not + * 0: Conditionally de-initialize + * others: Force to de-initialize + * \return + * result status, @ref AMISC_StatusTypeDef + */ +AMISC_StatusTypeDef AMISC_DeInit(uint32_t is_force); + +/** + * \brief Reset Analog misc. module + * NOTE: It will reset OPAMP, DAC, LDO functions at the same time + * + * \return + * result status, @ref AMISC_StatusTypeDef + */ +AMISC_StatusTypeDef AMISC_Reset(void); + +/** + * \brief Configure LVD/LVR module + * + * \param [in] pInit Pointer to a AMISC_LVDRInitTypeDef structure, @ref AMISC_LVDRInitTypeDef + * \return + * result status, @ref AMISC_StatusTypeDef + */ +AMISC_StatusTypeDef AMISC_LVD_LVR_Config(AMISC_LVDRInitTypeDef *pInit); + +/** + * \brief Disable HSI clock source + * + * \return + * None + */ +void AMISC_HSI_Disable(void); + +/** + * \brief Enable HSI clock source + * + * \return + * None + */ +void AMISC_HSI_Enable(void); + +/** + * \brief Disable LSI clock source + * + * \return + * None + */ +void AMISC_LSI_Disable(void); + +/** + * \brief Enable LSI clock source + * + * \return + * None + */ +void AMISC_LSI_Enable(void); + +/** + * \brief Select the VinP internal source of PGA + * + * \param [in] src_type the target VinP internal source + * \return + * None + */ +void AMISC_Sel_PGA_VinP_Src(AMISC_InternalSrcTypeDef src_type); + + +/** + * \brief Output the internal signals to I/O Pin + * + * \param [in] src_type The target internal signal, @ref AMISC_InternalSrcTypeDef + * \param [in] has_output Enable output or not + * \return + * None + */ +void AMISC_OutInternalSignalToIO(AMISC_InternalSrcTypeDef src_type, int has_output); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_comp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_comp.h new file mode 100644 index 0000000..677f07b --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_comp.h @@ -0,0 +1,261 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_comp.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_comp_H_wqqzibVO_lvKI_HWdK_sROD_uhjcZz7SHMtL__ +#define __hal_comp_H_wqqzibVO_lvKI_HWdK_sROD_uhjcZz7SHMtL__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Input-minus type of the Comparator + */ +typedef enum COMP_VinM +{ + COMP_VinM_IO = (COMP_CTRL_VIN_SEL_IO << COMP_CTRL_VIN_SEL_Pos), + COMP_VinM_DAC = (COMP_CTRL_VIN_SEL_DAC << COMP_CTRL_VIN_SEL_Pos), +} COMP_VinMTypeDef; + + +/** + * Input-plus type of the Comparator + */ +typedef enum COMP_VinP +{ + COMP_VinP_PGA = (COMP_VIPSEL_VIP_SEL_PGA << COMP_VIPSEL_VIP_SEL_Pos), + COMP_VinP_IO0 = (COMP_VIPSEL_VIP_SEL_IO0 << COMP_VIPSEL_VIP_SEL_Pos), + COMP_VinP_IO1 = (COMP_VIPSEL_VIP_SEL_IO1 << COMP_VIPSEL_VIP_SEL_Pos), + COMP_VinP_IO2 = (COMP_VIPSEL_VIP_SEL_IO2 << COMP_VIPSEL_VIP_SEL_Pos), + COMP_VinP_IO3 = (COMP_VIPSEL_VIP_SEL_IO3 << COMP_VIPSEL_VIP_SEL_Pos), +} COMP_VinPTypeDef; + +/** + * Filter frequency of the Comparator + */ +typedef enum COMP_Filter +{ + COMP_Filter_Bypass = (COMP_CTRL_FIL_CTRL_BYPASS << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_2 = (COMP_CTRL_FIL_CTRL_SAMPLE_2 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_4 = (COMP_CTRL_FIL_CTRL_SAMPLE_4 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_8 = (COMP_CTRL_FIL_CTRL_SAMPLE_8 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_16 = (COMP_CTRL_FIL_CTRL_SAMPLE_16 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_32 = (COMP_CTRL_FIL_CTRL_SAMPLE_32 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_64 = (COMP_CTRL_FIL_CTRL_SAMPLE_64 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_128 = (COMP_CTRL_FIL_CTRL_SAMPLE_128 << COMP_CTRL_FIL_CTRL_Pos), + COMP_Filter_Sample_256 = (COMP_CTRL_FIL_CTRL_SAMPLE_256 << COMP_CTRL_FIL_CTRL_Pos), +} COMP_FilterTypeDef; + +/** + * Output polarity of the Comparator + */ +typedef enum COMP_OutPolarity +{ + COMP_OutPolarity_Normal = (COMP_CTRL_POL_SEL_NORMAL << COMP_CTRL_POL_SEL_Pos), + COMP_OutPolarity_Invert = (COMP_CTRL_POL_SEL_INVERT << COMP_CTRL_POL_SEL_Pos), +} COMP_OutPolarityTypeDef; + +/** + * Interrupt type of the Comparator + */ +typedef enum COMP_IE +{ + COMP_IE_None = 0x0ul, + COMP_IE_Rising = COMP_IR_RIE_Msk, + COMP_IE_Falling = COMP_IR_FIE_Msk, + COMP_IE_ALL = (COMP_IR_RIE_Msk | COMP_IR_FIE_Msk), +} COMP_IETypeDef; + +/** + * Output type of the Comparator + */ +typedef enum COMP_Vout +{ + COMP_Vout_None = 0x0, + COMP_Vout_IO = COMP_CTRL_OUT_EN_Msk, +} COMP_VoutTypeDef; + +/** + * Input hysteresis type of the Comparator + */ +typedef enum COMP_Hysteresis +{ + COMP_Hysteresis_Disable = 0x0, + COMP_Hysteresis_Enable = COMP_CTRL_HYS_EN_Msk, +} COMP_HysteresisTypeDef; + + +//============================================================================= +// Macro Definition +//============================================================================= + +/** + * \brief COMP enable/disable + * + * \param [in] pHComp pointer to a COMP instance + * \return + * None + */ +__STATIC_INLINE void COMP_Enable(COMP_Type *pHComp) +{ + REG_SET_BITS(pHComp->CTRL, COMP_CTRL_EN_Msk); + return; +} + +__STATIC_INLINE void COMP_Disable(COMP_Type *pHComp) +{ + + REG_CLR_BITS(pHComp->CTRL, COMP_CTRL_EN_Msk); + return; +} + +/** + * \brief COMP get output level + * + * \param [in] pHComp pointer to a COMP instance + * \return + * 0 : COMP OUT Low + * others: COMP OUT High + */ +__STATIC_INLINE uint32_t COMP_GetOutputLevel(COMP_Type *pHComp) +{ + return REG_READ_MASK(pHComp->CTRL, COMP_CTRL_COUT_Msk); +} + +/** + * \brief COMP configure interrupt + * + * \param [in] pHComp pointer to a COMP instance + * \param [in] it_types the target interrupt type, @ref COMP_IETypeDef + * \return + * None + */ +__STATIC_INLINE void COMP_ITConfig(COMP_Type *pHComp, COMP_IETypeDef it_types) +{ + REG_WRITE_MASK(pHComp->IR, COMP_IR_RIE_Msk | COMP_IR_FIE_Msk, it_types); + return; +} + +/** + * \brief Get the status flags of the COMP + * + * \param [in] pHComp pointer to a COMP instance + * \param [in] flags the target flag type, @ref COMP_IETypeDef + * \return + * 0 : No target status + * other: Get the target status + */ +__STATIC_INLINE uint32_t COMP_GetFlagStatus(COMP_Type *pHComp, COMP_IETypeDef flags) +{ + return REG_READ_MASK(pHComp->IF, flags); +} + +/** + * \brief Clear the status flags of the COMP + * + * \param [in] pHComp pointer to a COMP instance + * \param [in] it_types the target interrupt type, @ref COMP_IETypeDef + * \return + * None + */ +__STATIC_INLINE void COMP_ClearFlag(COMP_Type *pHComp, COMP_IETypeDef it_types) +{ + REG_WRITE_MASK(pHComp->IF, COMP_IR_RIE_Msk | COMP_IR_FIE_Msk, it_types); + return; +} + +/** + * \brief Get the interrupt setting flags of the COMP + * + * \param [in] pHComp pointer to a COMP instance + * \return + * it_types, @ref COMP_IETypeDef + */ +__STATIC_INLINE COMP_IETypeDef COMP_GetITFlags(COMP_Type *pHComp) +{ + return REG_READ_MASK(pHComp->IR, COMP_IR_RIE_Msk | COMP_IR_FIE_Msk); +} +//============================================================================= +// Structure Definition +//============================================================================= + +typedef struct +{ + COMP_VinPTypeDef InputPlus; /*!< Set comparator Vin+. @ref COMP_VinPTypeDef */ + + COMP_VinMTypeDef InputMinus; /*!< Set comparator Vin-. @ref COMP_VinMTypeDef */ + + COMP_HysteresisTypeDef InputHysteresis; /*!< Set comparator hysteresis mode of the input minus. @ref COMP_HysteresisTypeDef */ + + COMP_FilterTypeDef FilterFreq; /*!< Set comparator filter frequency. @ref COMP_FilterTypeDef */ + + COMP_OutPolarityTypeDef OutputPolarity; /*!< Set comparator output polarity. @ref COMP_OutPolarityTypeDef */ + + COMP_VoutTypeDef OutputSel; /*!< Set comparator output selection. @ref COMP_VoutTypeDef */ + + uint16_t InitDelay; /*!< Set comparator initial delay ticks */ + +} COMP_InitTypeDef; + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * @brief Initializes the COMP module according to + * the specified parameters in the init_struct. + * + * @param pHComp: pointer to a COMP instance + * @param pInit: pointer to a COMP_InitTypeDef structure + * that contains the configuration information for the specified COMP module. + * @retval None. + */ +void COMP_Init(COMP_Type *pHComp, COMP_InitTypeDef *pInit); + + +/** + * \brief De-initializes the COMP module + * + * \param [in] pHComp pointer to a COMP instance + * \return + * None + */ +void COMP_DeInit(COMP_Type *pHComp); + +/** + * \brief Set each initial field to default value. + * + * \param [in] pInit pointer to a COMP_InitTypeDef structure. @ref COMP_InitTypeDef + * \return + * None + */ +void COMP_StructInit(COMP_InitTypeDef *pInit); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_crc.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_crc.h new file mode 100644 index 0000000..7b87b81 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_crc.h @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_crc.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_crc_H_w0Q7P8ed_lHTg_HFk4_sJpZ_ukncYhoixtqA__ +#define __hal_crc_H_w0Q7P8ed_lHTg_HFk4_sJpZ_ukncYhoixtqA__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CRC_START_CODE (~0u) + +typedef enum +{ + CRC_Status_OK, + CRC_Status_Error, +} CRC_Status; + +typedef enum +{ + CRC_Width_CRC32 = (CRC_CR_POLYSEL_CRC32 << CRC_CR_POLYSEL_Pos), + CRC_Width_CRC16 = (CRC_CR_POLYSEL_CRC16 << CRC_CR_POLYSEL_Pos), + +} CRC_WidthTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Initialize CRC module + * + * \return + * None + */ +void CRC_Init(void); + +/** + * \brief Calculate the crc value with singal value + * + * \param [in] pValue pointer to an instance of value + * \param [in] crc_width the type of crc width, @ref CRC_WidthTypeDef + * \return + * CRC value + */ +uint32_t CRC_CalcCRC(uint8_t *pValue, CRC_WidthTypeDef crc_width); + +/** + * \brief Calculate the CRC value of data stream + * + * \param [in] pData Pointer to the buffer containing the data to be computed + * \param [in] length Length of the buffer to be computed + * \param [in] crc_width the type of crc width, @ref CRC_WidthTypeDef + * \return + * CRC value + */ +uint32_t CRC_CalcBlockCRC(uint8_t *pData, int length, CRC_WidthTypeDef crc_width); + + +/** + * \brief Get the current CRC value + * + * \return + * CRC value + */ +uint32_t CRC_GetCRC(void); + +/** + * \brief Verify the completeness of data + * + * \param [in] Valid_CRC The expected CRC value + * \return + * 0: data does not match + * others: verify success + */ +uint32_t CRC_VerifyFlag(uint32_t Valid_CRC); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_def.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_def.h new file mode 100644 index 0000000..f011f42 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_def.h @@ -0,0 +1,193 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_def.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_def_H_wrmPni7q_lbcH_Hmna_sBkY_uUTtDspcvhdh__ +#define __hal_def_H_wrmPni7q_lbcH_Hmna_sBkY_uUTtDspcvhdh__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "device.h" +//============================================================================= +// Constant Definition +//============================================================================= +#if defined(__GNUC__) + +#else + #warning Not supported compiler type +#endif + +typedef enum +{ + DISABLE = 0, + ENABLE = !DISABLE +} FuncStatus, FunctionalState; + +typedef enum +{ + RESET = 0, + SET = !RESET +} FlagStatus, ITStatus; + +typedef enum +{ + ERROR = 0, + SUCCESS = !ERROR +} ErrorStatus; +//============================================================================= +// Macro Definition +//============================================================================= +#define REG_SET_BITS(__reg32__, __bit_msk__) ((__reg32__) |= (__bit_msk__)) +#define REG_CLR_BITS(__reg32__, __bit_msk__) ((__reg32__) &= ~(__bit_msk__)) + +#define REG_READ(__reg32__) (__reg32__) +#define REG_READ_MASK(__reg32__, __msk__) ((__reg32__) & (__msk__)) + +#define REG_WRITE(__reg32__, __val__) ((__reg32__) = (__val__)) +#define REG_WRITE_MASK(__reg32__, __msk__, __val__) ((__reg32__) = ((__reg32__) & ~(__msk__)) | ((__val__) & (__msk__))) + +#define ALIGN_4(x) (((x) + 0x3ul) & ~0x3ul) + +#define UNUSED(X) (void)(X) +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +/** + * register 32-bits operators + */ +__STATIC_INLINE void reg32_set_bits(uint32_t *addr, uint32_t bit_msk) +{ + *((uint32_t*)addr) |= bit_msk; + return; +} + +__STATIC_INLINE void reg32_clr_bits(uint32_t *addr, uint32_t bit_msk) +{ + *((uint32_t*)addr) &= ~bit_msk; + return; +} + +__STATIC_INLINE uint32_t reg32_read(uint32_t *addr) +{ + return *((uint32_t*)addr); +} + +__STATIC_INLINE uint32_t reg32_read_mask(uint32_t *addr, uint32_t mask) +{ + return (*((uint32_t*)addr) & mask); +} + +__STATIC_INLINE void reg32_write(uint32_t *addr, uint32_t value) +{ + *(uint32_t*)addr = value; + return; +} + +__STATIC_INLINE void reg32_write_mask(uint32_t *addr, uint32_t mask, uint32_t value) +{ + *(uint32_t*)addr = ((*(uint32_t*)addr) & ~mask) | (value & mask); + return; +} + +/** + * register 16-bits operators + */ +__STATIC_INLINE void reg16_set_bits(uint16_t *addr, uint16_t bit_msk) +{ + *((uint16_t*)addr) |= bit_msk; + return; +} + +__STATIC_INLINE void reg16_clr_bits(uint16_t *addr, uint16_t bit_msk) +{ + *((uint16_t*)addr) &= ~bit_msk; + return; +} + +__STATIC_INLINE uint16_t reg16_read(uint16_t *addr) +{ + return *((uint16_t*)addr); +} + +__STATIC_INLINE uint16_t reg16_read_mask(uint16_t *addr, uint16_t mask) +{ + return (*((uint16_t*)addr) & mask); +} + +__STATIC_INLINE void reg16_write(uint16_t *addr, uint16_t value) +{ + *(uint16_t*)addr = value; + return; +} + +__STATIC_INLINE void reg16_write_mask(uint16_t *addr, uint16_t mask, uint16_t value) +{ + *(uint16_t*)addr = ((*(uint16_t*)addr) & ~mask) | (value & mask); + return; +} + +/** + * register 8-bits operators + */ +__STATIC_INLINE void reg8_set_bits(uint8_t *addr, uint8_t bit_msk) +{ + *((uint8_t*)addr) |= bit_msk; + return; +} + +__STATIC_INLINE void reg8_clr_bits(uint8_t *addr, uint8_t bit_msk) +{ + *((uint8_t*)addr) &= ~bit_msk; + return; +} + +__STATIC_INLINE uint8_t reg8_read(uint8_t *addr) +{ + return *((uint8_t*)addr); +} + +__STATIC_INLINE uint8_t reg8_read_mask(uint8_t *addr, uint8_t mask) +{ + return (*((uint8_t*)addr) & mask); +} + +__STATIC_INLINE void reg8_write(uint8_t *addr, uint8_t value) +{ + *(uint8_t*)addr = value; + return; +} + +__STATIC_INLINE void reg8_write_mask(uint8_t *addr, uint8_t mask, uint8_t value) +{ + *(uint8_t*)addr = ((*(uint8_t*)addr) & ~mask) | (value & mask); + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_device.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_device.h new file mode 100644 index 0000000..d569167 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_device.h @@ -0,0 +1,138 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_device.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_device_H_wh21It4q_lc5o_HN4v_sYN9_uMvM6ZVOvOoN__ +#define __hal_device_H_wh21It4q_lc5o_HN4v_sYN9_uMvM6ZVOvOoN__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_conf.h" +//============================================================================= +// Constant Definition +//============================================================================= +#if defined(USE_FULL_ASSERT) + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((char*)__func__, __LINE__)) + void assert_failed(char *func, uint32_t line); +#else + #define assert_param(expr) +#endif +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Count leading zeros + * + * \param [in] x Value to count the leading zeros + * \return + * Number of leading zeros in value + */ +__STATIC_FORCEINLINE int HAL_CLZ(uint32_t x) +{ + return __builtin_clz(x); +} + +/** + * \brief Count the amount of bit-1 + * + * \param [in] x Value to count the amount of bit-1 + * \return + * The amount of bit-1 + */ +__STATIC_FORCEINLINE int HAL_PopCount(uint32_t x) +{ + return __builtin_popcount(x); +} + +/** + * \brief Get UID-1 value + * \return UID-1 + */ +__STATIC_FORCEINLINE uint32_t HAL_GetUID1(void) +{ + return REG_READ(UID->UID1); +} + +/** + * \brief Get UID-2 value + * \return UID-2 + */ +__STATIC_FORCEINLINE uint32_t HAL_GetUID2(void) +{ + return REG_READ(UID->UID2); +} + +/** + * \brief Get UID-3 value + * \return UID-3 + */ +__STATIC_FORCEINLINE uint32_t HAL_GetUID3(void) +{ + return REG_READ(UID->UID3); +} + +/** + * \brief Initialize the peripherals of this device + * + * \return + * None + */ +__STATIC_FORCEINLINE void HAL_DeviceInit(void) +{ + REG_WRITE(SYSCFG->PRSTEN1, 0xFFFFFFFFul); + REG_WRITE(SYSCFG->PRSTEN, 0xFFFFFFFFul); + REG_WRITE(SYSCFG->PRSTEN1, 0x0ul); + REG_WRITE(SYSCFG->PRSTEN, 0x0ul); + return; +} + +#define HAL_SetBits(_val_, _bit_mak_) REG_SET_BITS(_val_, _bit_mak_) +#define HAL_ClearBits(_val_, _bit_mak_) REG_CLR_BITS(_val_, _bit_mak_) +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Set the seed to initialize pseudo-random number generator + * + * \param [in] seed The seed value + * \return + * None + */ +void HAL_SRand(uint32_t seed); + +/** + * \brief Generate pseudo-random number + * + * \return + * The pseudo-random value + */ +uint32_t HAL_Rand(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_dsp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_dsp.h new file mode 100644 index 0000000..2572b70 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_dsp.h @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_dsp.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_dsp_H_we15xl18_lz2k_Hix7_sTLr_uIRwmlwU5wH6__ +#define __hal_dsp_H_we15xl18_lz2k_Hix7_sTLr_uIRwmlwU5wH6__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief H/W DSP Divide operation + * + * \param [in] numerator The numerator of Fraction + * \param [in] denominator The denominator of Fraction + * \param [in] pQuotient Pointer to a 32-bits signed value (Quotient) + * \param [in] pRemainder Pointer to a 32-bits signed value (Remainder) + * \return + * 0: ok + * others: fail + */ +__STATIC_FORCEINLINE int DSP_Div32(int numerator, int denominator, int *pQuotient, int *pRemainder) +{ + DSP->CR_b.MODE = DSP_CR_MODE_DIV; + + REG_WRITE(DSP->SDAT1, numerator); + REG_WRITE(DSP->SDAT2, denominator); + + while( !REG_READ(DSP->SR) ) {} + + if( pQuotient ) *pQuotient = REG_READ(DSP->RSLT1); + if( pRemainder ) *pRemainder = REG_READ(DSP->RSLT2); + + return 0; +} +//============================================================================= +// Structure Definition +//============================================================================= +/** + * the paraments of dsp square root calculate + */ +typedef struct +{ + union { + uint64_t value64; + uint32_t value32[2]; + }; +} DSP_SqrtParamTypeDef; + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +#if 0 +/** + * \brief H/W DSP Divide operation + * + * \param [in] numerator The numerator of Fraction + * \param [in] denominator The denominator of Fraction + * \param [in] pQuotient Pointer to a 32-bits signed value (Quotient) + * \param [in] pRemainder Pointer to a 32-bits signed value (Remainder) + * \return + * 0: ok + * others: fail + */ +int DSP_Div32(int numerator, int denominator, int *pQuotient, int *pRemainder); +#endif + +/** + * \brief H/w DSP Square root operation (unsigned 64-bits) + * + * \param [in] pParam The input paraments of Square root operation + * \return + * the calculated value + */ +uint32_t DSP_Sqrt32(DSP_SqrtParamTypeDef *pParam); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_flash.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_flash.h new file mode 100644 index 0000000..676d17c --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_flash.h @@ -0,0 +1,203 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_flash.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_flash_H_wm4SBnn4_laN2_HBZw_sxWM_uBboLm9QaVsk__ +#define __hal_flash_H_wm4SBnn4_laN2_HBZw_sxWM_uBboLm9QaVsk__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define FLASH_1_SECTOR_SIZE 512 +#define FLASH_1_PAGE_SIZE FLASH_1_SECTOR_SIZE + +#define FLASH_AUTH_KEY 0xA5A50000ul + +/** + * eFlash status + */ +typedef enum flash_state +{ + FLASH_STATE_OK = 0, + FLASH_STATE_BUSY, + FLASH_STATE_FAIL_PROG, + FLASH_STATE_FAIL_ERASE, + FLASH_STATE_FAIL_ADDR, + FLASH_STATE_NOT_4_ALIGN, + FLASH_STATE_FAIL_PARAM, + FLASH_STATE_TIMEOUT +} flash_state_t; + +/** + * eFlash latency type + */ +typedef enum flash_latency +{ + FLASH_LATENCY_1 = (0x1ul << FLASH_CMD_NWS_Pos), + FLASH_LATENCY_2 = (0x2ul << FLASH_CMD_NWS_Pos), + FLASH_LATENCY_3 = (0x3ul << FLASH_CMD_NWS_Pos), + +} flash_latency_t; + +/** + * eFlash H/w error type + */ +typedef enum flash_err_type +{ + FLASH_ERR_TYPE_OK = 0, + FLASH_ERR_TYPE_KEY = FLASH_SR_KEY_ERR_Msk, + FLASH_ERR_TYPE_ACCESS = FLASH_SR_ACC_ERR_Msk, + FLASH_ERR_TYPE_ADDRESS = FLASH_SR_ADDR_ERR_Msk, + + FLASH_ERR_TYPE_SYSINFO_FAIL = (FLASH_SR_HSI_TC_ERR_Msk | FLASH_SR_RSTIO_AF_ERR_Msk | \ + FLASH_SR_LDO_TRIM_ERR_Msk | FLASH_SR_VBUF_TRIM_ERR_Msk | \ + FLASH_SR_LSI_TRIM_ERR_Msk | FLASH_SR_HSI_TRIM_ERR_Msk), + + FLASH_ERR_TYPE_INVALID_TRIM_HSI = FLASH_SR_HSI_TRIM_ERR_Msk, + FLASH_ERR_TYPE_INVALID_TRIM_HSI_TC = FLASH_SR_HSI_TC_ERR_Msk, + FLASH_ERR_TYPE_INVALID_TRIM_LSI = FLASH_SR_LSI_TRIM_ERR_Msk, + FLASH_ERR_TYPE_INVALID_TRIM_VBUF = FLASH_SR_VBUF_TRIM_ERR_Msk, + FLASH_ERR_TYPE_INVALID_TRIM_LDO = FLASH_SR_LDO_TRIM_ERR_Msk, + FLASH_ERR_TYPE_INVALID_RSTIO_CFG = FLASH_SR_RSTIO_AF_ERR_Msk, +} flash_err_type_t; +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Check eFlash is idle or not. + * + * \return + * 0 : busy + * others: idle + */ +__STATIC_FORCEINLINE uint32_t FLASH_IsIdle(void) +{ + return !REG_READ_MASK(FLASH->CMD, FLASH_CMD_START_Msk); +} + + +/** + * \brief Get the latency type of eFlash + * + * \return + * Latency value, @ref flash_latency_t + */ +__STATIC_FORCEINLINE uint32_t FLASH_GetLatency(void) +{ + return REG_READ_MASK(FLASH->CMD, FLASH_CMD_NWS_Msk); +} + +/** + * \brief Get eFlash H/w error type + * + * \return + * eFlash H/w error type, @ref flash_err_type_t + */ +__STATIC_FORCEINLINE flash_err_type_t FLASH_GetHwErr(void) +{ + return (flash_err_type_t)REG_READ(FLASH->SR); +} +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Set Flash latency + * When CPU frequency is over eFlash, + * CPU MUST wait eFlash response + * + * \param [in] latency CPU wait latency (cycles) for eFlash, @ref flash_latency_t + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_SetLatency(flash_latency_t latency); + + +/** + * \brief Erase a page of eFlash + * + * \param [in] page_addr the target address (FLASH_1_PAGE_SIZE align) of the eFlash + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_ErasePage(uint32_t page_addr); + + +/** + * \brief Program a word (32-bits) value to eFlash + * + * \param [in] addr the target address of the eFlash + * \param [in] value the target value (32-bits) + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_ProgWord(uint32_t addr, uint32_t value); + +/** + * \brief Program a half-word (16-bits) value to eFlash + * + * \param [in] addr the target address of the eFlash + * \param [in] value the target value (16-bits) + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_ProgHWord(uint32_t addr, uint16_t value); + +/** + * \brief Program a byte (8-bits) value to eFlash + * + * \param [in] addr the target address of the eFlash + * \param [in] value the target value (8-bits) + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_ProgByte(uint32_t addr, uint8_t value); + +/** + * \brief Program data set to eFlash + * + * \param [in] addr the target address of the eFlash + * \param [in] pData pointer to a 32-bits buffer of data set + * \param [in] length the 4-align length of data + * \return + * state, @ref flash_state_t + */ +flash_state_t +FLASH_ProgData(uint32_t addr, uint32_t *pData, int length); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_gpio.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_gpio.h new file mode 100644 index 0000000..cca4b6f --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_gpio.h @@ -0,0 +1,420 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_gpio.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_gpio_H_wPOJofWz_lXUp_H0cZ_sE46_uv8ZKHIsTlMH__ +#define __hal_gpio_H_wPOJofWz_lXUp_H0cZ_sE46_uv8ZKHIsTlMH__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= + +typedef enum +{ + GPIO_PIN_RESET = 0u, + GPIO_PIN_SET, + GPIO_PIN_LOW = GPIO_PIN_RESET, + GPIO_PIN_HIGH = GPIO_PIN_SET, +} GPIO_PinStateTypeDef; + +typedef enum +{ + GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ + GPIO_Mode_OUT, /*!< GPIO Output Mode */ + GPIO_Mode_ANAL, /*!< GPIO Analog In/Out Mode */ + GPIO_Mode_AF, /*!< GPIO Alternate function Mode */ + GPIO_Mode_PWR_Saving, /*!< GPIO Power-Saving Mode */ + +} GPIO_ModeTypeDef; + +typedef enum +{ + GPIO_PuPd_NOPULL = 0x00, + GPIO_PuPd_UP = 0x01, + GPIO_PuPd_DOWN = 0x02 +}GPIO_PuPdTypeDef; + +typedef enum +{ + GPIO_OType_PP = 0x0, + GPIO_OType_OD +}GPIO_OTypeTypeDef; + +typedef enum +{ + GPIO_Pin_00 = (0x1ul << 0), + GPIO_Pin_01 = (0x1ul << 1), + GPIO_Pin_02 = (0x1ul << 2), + GPIO_Pin_03 = (0x1ul << 3), + GPIO_Pin_04 = (0x1ul << 4), + GPIO_Pin_05 = (0x1ul << 5), + GPIO_Pin_06 = (0x1ul << 6), + GPIO_Pin_07 = (0x1ul << 7), + GPIO_Pin_08 = (0x1ul << 8), + GPIO_Pin_09 = (0x1ul << 9), + GPIO_Pin_10 = (0x1ul << 10), + GPIO_Pin_11 = (0x1ul << 11), + GPIO_Pin_12 = (0x1ul << 12), + GPIO_Pin_13 = (0x1ul << 13), + GPIO_Pin_14 = (0x1ul << 14), + GPIO_Pin_15 = (0x1ul << 15), + GPIO_PIN_All = 0xFFFFul + +} GPIO_PinTypeDef; + +/** + * GPIO Pin Alternate Function + */ +typedef enum +{ + GPIO_AF_0 = 0, + GPIO_AF_1, + GPIO_AF_2, + GPIO_AF_3, + GPIO_AF_4, + GPIO_AF_5, + GPIO_AF_6, + GPIO_AF_7, +} GPIO_AFTypeDef; + +typedef enum +{ + GPIO_Peri_Fn1, + GPIO_Peri_BKIN, + GPIO_Peri_ECAP0, + GPIO_Peri_ECAP1, + GPIO_Peri_ECAP2, + GPIO_Peri_EPETR, + GPIO_Peri_Fn2, + GPIO_Peri_TCAP0, + GPIO_Peri_TCAP1, + GPIO_Peri_TCAP2, + GPIO_Peri_T2ETR, + GPIO_Peri_I2C_PULL0, + GPIO_Peri_I2C_PULL1, + GPIO_Peri_I2C_PULL2, + GPIO_Peri_I2C_PULL3, + GPIO_Peri_I2C_PULL4, + GPIO_Peri_I2C_PULL5, + GPIO_Peri_I2C_PULL6, + GPIO_Peri_I2C_PULL7, +} GPIO_PeriTypeDef; + +/** + * Peripheral Alternate Function + * ps. GPIO FNx_AFR + */ +typedef enum +{ + GPIO_PeriAF_0 = 0, + GPIO_PeriAF_1, + GPIO_PeriAF_2, + GPIO_PeriAF_3, + GPIO_PeriAF_4, + GPIO_PeriAF_5, + GPIO_PeriAF_6, + GPIO_PeriAF_7, + GPIO_PeriAF_8, + GPIO_PeriAF_9, + GPIO_PeriAF_10, + GPIO_PeriAF_11, +} GPIO_PeriAFTypeDef; + +typedef enum +{ + GPIO_Polarity_Low_Fall = 0, // Low level or falling edge + GPIO_Polarity_High_Rise = 1, // High level or rising edge +} GPIO_PolarityTypeDef; + +typedef enum +{ + GPIO_Trigger_Level = 0, // Level trigger + GPIO_Trigger_Edge = 1, // Edge trigger + GPIO_Trigger_Any_Edge = 2, +} GPIO_TriggerTypeDef; + + +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Reads the input data of specified GPIO port pin. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin the target pin, @ref GPIO_PinTypeDef + * \return + * 0 : pin low state + * others: pin high state + */ +__STATIC_FORCEINLINE uint8_t GPIO_ReadInputDataBit(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + return REG_READ_MASK(pHGpio->DAT, pin) ? GPIO_PIN_HIGH : GPIO_PIN_LOW; +} + + +/** + * \brief Read all input data of a GPIO port. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \return + * the gpio pins data + */ +__STATIC_FORCEINLINE uint16_t GPIO_ReadInputData(GPIO_Type *pHGpio) +{ + return REG_READ(pHGpio->DAT); +} + + +/** + * \brief Reads the output data of specified GPIO port pin. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin the target pin, @ref GPIO_PinTypeDef + * \return + * 0 : pin low state + * others: pin high state + */ +__STATIC_FORCEINLINE uint8_t GPIO_ReadOutputDataBit(GPIO_Type *pHGpio, uint16_t pin) +{ + return REG_READ_MASK(pHGpio->DAT, pin) ? GPIO_PIN_HIGH : GPIO_PIN_LOW; +} + +/** + * \brief Reads all GPIO port pins output data. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \return + * the gpio pins data + */ +__STATIC_FORCEINLINE uint16_t GPIO_ReadOutputData(GPIO_Type *pHGpio) +{ + return REG_READ(pHGpio->DAT); +} + + +/** + * \brief Sets the selected data port bits. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pins the target pin, @ref GPIO_PinTypeDef + * \return + * none + */ +__STATIC_FORCEINLINE void GPIO_SetBits(GPIO_Type *pHGpio, uint16_t pins) +{ + REG_SET_BITS(pHGpio->LAT, pins); + return; +} + +/** + * \brief Clears the selected data port bits. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pins the target pin, @ref GPIO_PinTypeDef + * \return + * none + */ +__STATIC_FORCEINLINE void GPIO_ResetBits(GPIO_Type *pHGpio, uint16_t pins) +{ + REG_CLR_BITS(pHGpio->LAT, pins); + return; +} + + +/** + * \brief Sets or clears the selected data port bit. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pins the target pin, @ref GPIO_PinTypeDef + * \param [in] state the target pin state, @ref GPIO_PinStateTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void GPIO_WriteBit(GPIO_Type *pHGpio, uint16_t pins, GPIO_PinStateTypeDef state) +{ + (state == GPIO_PIN_HIGH) ? + REG_SET_BITS(pHGpio->LAT, pins) : + REG_CLR_BITS(pHGpio->LAT, pins); + return; +} + +/** + * \brief Writes data to the specified GPIO data port. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] value Specifies the value to be written to the port output data register + * \return + * None + */ +__STATIC_FORCEINLINE void GPIO_Write(GPIO_Type *pHGpio, uint16_t value) +{ + REG_WRITE(pHGpio->LAT, value); + return; +} + +/** + * \brief Toggle the specified pin of GPIO port. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin The target pin, @ref GPIO_PinTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void GPIO_TogglePin(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + pHGpio->LAT ^= pin; + return; +} + +/** + * \brief Enable/Disable the pin interrupt of GPIO + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin The target pin, @ref GPIO_PinTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void GPIO_ITEnable(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + REG_SET_BITS(pHGpio->IES, pin); + return; +} + +__STATIC_FORCEINLINE void GPIO_ITDisable(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + REG_SET_BITS(pHGpio->IEC, pin); + return; +} + +/** + * \brief Get the interrupt flag of a GPIO pin + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin The target pin, @ref GPIO_PinTypeDef + * \return + * the flag of status + */ +__STATIC_FORCEINLINE uint32_t GPIO_GetITFlag(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + return REG_READ_MASK(pHGpio->IST, pin); +} +/** + * \brief Clear GPIO interrupt flag + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pin The target pin, @ref GPIO_PinTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void GPIO_ClearITFlag(GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + REG_SET_BITS(pHGpio->IST, pin); + return; +} +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct GPIO_ITInit +{ + GPIO_PolarityTypeDef GPIO_Polarity; /*!< Interrupt polarity. + This parameter can be a value of @ref GPIO_PolarityTypeDef */ + + GPIO_TriggerTypeDef GPIO_Trigger; /*!< Interrupt trigger type. + This parameter can be a value of @ref GPIO_TriggerTypeDef */ +} GPIO_ITInitTypeDef; + +typedef struct GPIO_Init +{ + uint16_t GPIO_Pin; /*!< GPIO_Pin */ + + GPIO_ModeTypeDef GPIO_Mode; /*!< GPIO_Mode */ + + GPIO_PuPdTypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. + This parameter can be a value of @ref GPIO_PuPdTypeDef */ + + GPIO_OTypeTypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. + This parameter can be a value of @ref GPIO_OTypeTypeDef */ + + GPIO_AFTypeDef GPIO_AF_Mode; /*!< Peripheral to be connected to the selected pins. + This parameter can be a value of @ref GPIO_AFTypeDef */ + + GPIO_ITInitTypeDef GPIO_ITInit; /*!< Specifies the interrupt initial parameters, @ref GPIO_ITInitTypeDef */ + + +} GPIO_InitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Initializes the gpio peripheral according to the specified parameters. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pInit Pointer to a instance of GPIO_InitTypeDef + * \return + * 0 : success + * other: fail + */ +int GPIO_Init(GPIO_Type *pHGpio, GPIO_InitTypeDef *pInit); + +/** + * \brief De-initializes the gpio peripheral according to the specified parameters. + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pins The target pin, @ref GPIO_PinTypeDef + * \return + * None + */ +void GPIO_DeInit(GPIO_Type *pHGpio, uint32_t pins); + + +/** + * \brief Set Pin configuration of Peripheral IP with the specific Alternate Function + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] peri_type the specific peripheral IP, @ref GPIO_PeriTypeDef + * \param [in] af_mode the af mode, @ref GPIO_PeriAFTypeDef + * \return + * None + */ +void GPIO_PeriAFConfig(GPIO_Type *pHGpio, GPIO_PeriTypeDef peri_type, GPIO_PeriAFTypeDef af_mode); + + +/** + * \brief Configure GPIO interrrupt + * + * \param [in] pHGpio Pointer to a GPIO handler + * \param [in] pins The target pin, @ref GPIO_PinTypeDef + * \param [in] pInit Pointer to an instance of GPIO_ITInitTypeDef, @ref GPIO_ITInitTypeDef + * \return + * Nore + */ +void GPIO_ITConfig(GPIO_Type *pHGpio, GPIO_PinTypeDef pins, GPIO_ITInitTypeDef *pInit); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_i2c.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_i2c.h new file mode 100644 index 0000000..8172fd4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_i2c.h @@ -0,0 +1,325 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_i2c.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_i2c_H_wiTQLukR_lyWI_H9X1_s634_uL7YYZQ9qyOX__ +#define __hal_i2c_H_wiTQLukR_lyWI_H9X1_s634_uL7YYZQ9qyOX__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define I2C_BLOCKING 0xFFFF + +typedef enum +{ + I2C_Err_OK = 0, + I2C_Err_Fail, + I2C_Err_WrongParams, + I2C_Err_TimeOut, + +} I2C_ErrTypeDef; + +typedef enum +{ + /* Misc */ + I2C_State_ERROR = 0x00u, + I2C_State_BUS_IDLE = 0xF8u, + I2C_State_SLAVE_STOP_RESTART = 0xA0u, + + /* Master Transmit */ + I2C_State_MASTER_TX_START = 0x08u, + I2C_State_MASTER_TX_RESTART = 0x10u, + I2C_State_MASTER_TX_SLAW_ACK = 0x18u, // Master sent (SlaveAddress + W-bit) and received ACK + I2C_State_MASTER_TX_SLAW_NOACK = 0x20u, + I2C_State_MASTER_TX_DATA_ACK = 0x28u, // Master sent data and received ACK + I2C_State_MASTER_TX_DATA_NOACK = 0x30u, + I2C_State_MASTER_TX_LOST_BUS = 0x38u, + + /* Master Receive */ + I2C_State_MASTER_RX_START = I2C_State_MASTER_TX_START, + I2C_State_MASTER_RX_RESTART = I2C_State_MASTER_TX_RESTART, + I2C_State_MASTER_RX_SLAR_ACK = 0x40u, // Master sent (SlaveAddress + R-bit) and received ACK + I2C_State_MASTER_RX_SLAR_NOACK = 0x48u, + I2C_State_MASTER_RX_DATA_ACK = 0x50u, // Master received data and received ACK + I2C_State_MASTER_RX_DATA_NOACK = 0x58u, + I2C_State_MASTER_RX_LOST_BUS = I2C_State_MASTER_TX_LOST_BUS, + + /* Slave Receive */ + I2C_State_SLAVE_RX_SLAW_ACK = 0x60u, + I2C_State_SLAVE_RX_SLAW_LOST_BUS = 0x68u, + I2C_State_SLAVE_RX_BROAD_ACK = 0x70u, // received broad address and sent ACK + I2C_State_SLAVE_RX_BADDR_LOST_BUS = 0x78u, + I2C_State_SLAVE_RX_DATA_ACK = 0x80u, // received data and sent ACK + I2C_State_SLAVE_RX_DATA_NOACK = 0x88u, + I2C_State_SLAVE_RX_BDATA_ACK = 0x90u, // received data (with broad address) and sent ACK + I2C_State_SLAVE_RX_BDATA_NOACK = 0x98u, + + /* Slave Transmit */ + I2C_State_SLAVE_RX_SLAR_ACK = 0xA8u, + I2C_State_SLAVE_TX_LOST_BUS = 0xB0u, + I2C_State_SLAVE_TX_DATA_ACK = 0xB8u, + I2C_State_SLAVE_TX_DATA_NOACK = 0xC0u, + I2C_State_SLAVE_TX_LAST_DATA = 0xC8u, + +} I2C_StateTypeDef; + +/** + * I2C role mode + */ +typedef enum +{ + I2C_Mode_NONE = 0x00U, /*!< No I2C communication on going */ + I2C_Mode_MASTER = 0x10U, /*!< I2C communication is in Master Mode */ + I2C_Mode_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */ +} I2C_ModeTypeDef; + +/** + * The divide of I2C Clock + */ +typedef enum +{ + I2C_CLK_Div60 = 60, + I2C_CLK_Div120 = 120, + I2C_CLK_Div160 = 160, + I2C_CLK_Div192 = 192, + I2C_CLK_Div244 = 244, + I2C_CLK_Div256 = 256, + I2C_CLK_Div960 = 960, + +} I2C_Clk_DivTypeDef; + +typedef enum +{ + I2C_BroadAck_Disable = 0x0ul, + I2C_BroadAck_Enable = I2C_ADDR_GC_Msk, +} I2C_BroadAckTypeDef; + +typedef enum +{ + I2C_XferMode_Idle = 0, + I2C_XferMode_Transmite, + I2C_XferMode_Recevie, +} I2C_XferModeTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Get the Hardware state of an I2C + * + * \param [in] pHI2C The handle of I2C + * \return + * Hardware state + */ +__STATIC_FORCEINLINE uint32_t I2C_GetHwState(I2C_Type *pHI2C) +{ + return pHI2C->STAT_b.STAT; +} +//============================================================================= +// Structure Definition +//============================================================================= +/** + * I2C Initial Configuration + */ +typedef struct I2C_Init +{ + I2C_Clk_DivTypeDef ClockDiv; + I2C_ModeTypeDef Mode; /*!< Specifies the I2C mode. This parameter can be a value of I2C_mode. */ + uint8_t OwnAddress; /*!< Specifies the first device own address. This parameter can be a 7-bit address. */ + I2C_BroadAckTypeDef BroadAck; /*!< ACK enable or disable when as slave. + This parameter can be a value of @ref I2C_BroadAckTypeDef */ +} I2C_InitTypeDef; + +typedef struct I2C_IT_Handle +{ + I2C_Type *pHI2C; + + uint8_t *pTxBuffPtr; /*!< Pointer to I2C Tx transfer Buffer */ + __IO uint16_t TxXferCount; /*!< I2C Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /*!< Pointer to I2C Rx transfer Buffer */ + __IO uint16_t RxXferCount; /*!< I2C Rx Transfer Counter */ + + I2C_XferModeTypeDef XferMode; + __IO uint16_t DevAddress; /*!< I2C Target device address */ + +} I2C_IT_HandleTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Fills each init_struct member with its default value. + * + * \param [in] pInit Pointer to an I2C_InitTypeDef structure + * which will be initialized. + * \return + * None + */ +void I2C_StructInit(I2C_InitTypeDef *pInit); + +/** + * \brief Initializes the I2C module + * + * \param [in] pHI2C Pointer to an I2C handler + * \param [in] pInit Pointer to an I2C_InitTypeDef structure that + * contains the configuration information for the specified + * I2C peripheral + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Init(I2C_Type *pHI2C, I2C_InitTypeDef *pInit); + +/** + * \brief De-Initializes the I2C peripheral registers to their default values. + * + * \param [in] pHI2C Pointer to an I2C handler + * \return + * None + */ +void I2C_DeInit(I2C_Type *pHI2C); + +/** + * \brief I2C-Master transmits an amount of data in blocking mode. + * + * \param [in] pHI2C Pointer to an I2C handler + * \param [in] DevAddr Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be sent + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Master_Transmit(I2C_Type *pHI2C, uint16_t DevAddr, uint8_t *pData, uint16_t Size); + +/** + * \brief I2C-Master receives an amount of data in blocking mode. + * + * \param [in] pHI2C Pointer to an I2C handler + * \param [in] DevAddr Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface + * \param [in] pData Pointer to data buffer + * \param [in] pSize Amount of data to be received + * \param [in] Timeout_ms Timeout with mseconds. If Timeout_ms == I2C_BLOCKING, slave transmit with blocking mode + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Master_Receive(I2C_Type *pHI2C, uint8_t DevAddr, uint8_t *pData, uint16_t *pSize, uint16_t Timeout_ms); + + +/** + * \brief I2C-Slave Transmit data in blocking mode + * + * \param [in] pHI2C Pointer to an I2C handler + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be sent + * \param [in] Timeout_ms Timeout with mseconds. If Timeout_ms == I2C_BLOCKING, slave transmit with blocking mode + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Slave_Transmit(I2C_Type *pHI2C, uint8_t *pData, uint16_t Size, uint16_t Timeout_ms); + +/** + * \brief I2C-Slave Receive data in blocking mode + * + * \param [in] pHI2C Pointer to an I2C handler + * \param [in] pData Pointer to data buffer + * \param [in] pSize Amount of data to be received + * \param [in] Timeout_ms Timeout with mseconds. If Timeout_ms == I2C_BLOCKING, slave transmit with blocking mode + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Slave_Receive(I2C_Type *pHI2C, uint8_t *pData, uint16_t *pSize, uint16_t Timeout_ms); + +/** + * \brief I2C-Master transmits an amount of data in interrupt mode. + * + * \param [in] pHITI2C Pointer to an I2C IT handler, @ref I2C_IT_HandleTypeDef + * \param [in] DevAddr Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be sent + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Master_Transmit_IT(I2C_IT_HandleTypeDef *pHITI2C, uint16_t DevAddr, uint8_t *pData, uint16_t Size); + +/** + * \brief I2C-Master receives an amount of data in interrupt mode. + * + * \param [in] pHITI2C Pointer to an I2C IT handler, @ref I2C_IT_HandleTypeDef + * \param [in] DevAddr Target device address: The device 7 bits address value + * in datasheet must be shift at right before call interface + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be received + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Master_Receive_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t DevAddr, uint8_t *pData, uint16_t Size); + +/** + * \brief I2C-Slave Transmit data in interrupt mode + * + * \param [in] pHITI2C Pointer to an I2C IT handler, @ref I2C_IT_HandleTypeDef + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be sent + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Slave_Transmit_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t *pData, uint16_t Size); + +/** + * \brief I2C-Slave Receive data in interrupt mode + * + * \param [in] pHITI2C Pointer to an I2C IT handler, @ref I2C_IT_HandleTypeDef + * \param [in] pData Pointer to data buffer + * \param [in] Size Amount of data to be received + * \return + * error code, @ref I2C_ErrTypeDef + */ +I2C_ErrTypeDef I2C_Slave_Receive_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t *pData, uint16_t Size); + +/** + * \brief This function handles I2C-Master interrupt request. + * + * \param [in] pHITI2C Pointer to an I2C IT Handler, @ref I2C_IT_HandleTypeDef + * \return + * None + */ +void I2C_Master_IRQHandler(I2C_IT_HandleTypeDef *pHITI2C); + +/** + * \brief This function handles I2C-Slave interrupt request. + * + * \param [in] pHITI2C Pointer to an I2C IT Handler, @ref I2C_IT_HandleTypeDef + * \return + * None + */ +void I2C_Slave_IRQHandler(I2C_IT_HandleTypeDef *pHITI2C); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_lptim.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_lptim.h new file mode 100644 index 0000000..2baa23a --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_lptim.h @@ -0,0 +1,244 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file lptim.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_lptim_H_wP2Tfucu_lfcA_HOTx_s6ox_udtG8lP5WVqK__ +#define __hal_lptim_H_wP2Tfucu_lfcA_HOTx_s6ox_udtG8lP5WVqK__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +typedef enum +{ + LPTIM_CLK_Src_SysClk = (LPTIM_TCR_CLKS_SysClk << LPTIM_TCR_CLKS_Pos), + LPTIM_CLK_Src_LSI = (LPTIM_TCR_CLKS_LSI << LPTIM_TCR_CLKS_Pos), + +} LPTIM_CLK_SrcTypeDef; + +typedef enum +{ + LPTIM_MatchMode_Normal = 0, + LPTIM_MatchMode_IRQ = LPTIM_MCR_MR0INT_Msk, + LPTIM_MatchMode_Reset = LPTIM_MCR_MR0RST_Msk, + LPTIM_MatchMode_Stop = LPTIM_MCR_MR0STOP_Msk, +} LPTIM_MatchModeTypeDef; + +typedef enum +{ + LPTIM_Flag_Match0 = LPTIM_IR_MR0_Msk, +} LPTIM_FlagTypeDef; + +typedef enum +{ + LPTIM_TrigSrc_Normal = (LPTIM_TCR_TRIGSEL_Normal << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh0_Rising = (LPTIM_TCR_TRIGSEL_EPWMCh0P << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh1_Rising = (LPTIM_TCR_TRIGSEL_EPWMCh1P << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh2_Rising = (LPTIM_TCR_TRIGSEL_EPWMCh2P << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh0_Falling = (LPTIM_TCR_TRIGSEL_EPWMCh0N << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh1_Falling = (LPTIM_TCR_TRIGSEL_EPWMCh1N << LPTIM_TCR_TRIGSEL_Pos), + LPTIM_TrigSrc_PWMCh2_Falling = (LPTIM_TCR_TRIGSEL_EPWMCh2N << LPTIM_TCR_TRIGSEL_Pos), +} LPTIM_TrigSrcTypeDef; + +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief LpTim enable/disable + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \return + * None + */ +__STATIC_INLINE void LPTIM_Enable(LPTIM_Type *pHLpTim) +{ + REG_SET_BITS(pHLpTim->TCR, LPTIM_TCR_CEN_Msk); + return; +} + +__STATIC_INLINE void LPTIM_Disable(LPTIM_Type *pHLpTim) +{ + REG_CLR_BITS(pHLpTim->TCR, LPTIM_TCR_CEN_Msk); + return; +} + +/** + * \brief Check whether the specified LpTIM flag is set or not. + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] flag specifies the flag to check, @ref LPTIM_FlagTypeDef. + * \return + * 0: no status + * others: get the status + */ +__STATIC_INLINE uint32_t LPTIM_GetFlagStatus(LPTIM_Type *pHLpTim, LPTIM_FlagTypeDef flag) +{ + return REG_READ_MASK(pHLpTim->IR, flag); +} + +/** + * \brief Clear the LpTim's pending flags. + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] flag specifies the flag to clear, @ref LPTIM_FlagTypeDef. + * \return + * None + */ +__STATIC_INLINE void LPTIM_ClearFlag(LPTIM_Type *pHLpTim, LPTIM_FlagTypeDef flag) +{ + REG_SET_BITS(pHLpTim->IR, flag); + return; +} + +/** + * \brief Reset LpTim + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \return + * None + */ +__STATIC_INLINE void LPTIM_Reset(LPTIM_Type *pHLpTim) +{ + REG_SET_BITS(pHLpTim->TCR, LPTIM_TCR_CRST_Msk); + return; +} + +/** + * \brief Set the compare mode + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] mode the specific match mode, @ref LPTIM_MatchModeTypeDef + * \param [in] MatchValue the target match value + * \return + * None + */ +__STATIC_INLINE void LPTIM_SetMatch(LPTIM_Type *pHLpTim, LPTIM_MatchModeTypeDef mode, uint16_t MatchValue) +{ + REG_SET_BITS(pHLpTim->MCR, mode); + REG_WRITE_MASK(pHLpTim->MR0, LPTIM_MR0_MR0_Msk, (MatchValue << LPTIM_MR0_MR0_Pos)); + return; +} + +/** + * \brief Set LpTim prescaler + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] pr_value prescaler value + * \return + * None + */ +__STATIC_INLINE void LPTIM_SetPrescaler(LPTIM_Type *pHLpTim, uint8_t pr_value) +{ + REG_WRITE_MASK(pHLpTim->PR, LPTIM_PR_PR_Msk, (pr_value << LPTIM_PR_PR_Pos)); + return; +} + +/** + * \brief Get actual counter value + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \return + * Counter value + */ +__STATIC_INLINE uint16_t LPTIM_GetCounter(LPTIM_Type *pHLpTim) +{ + return REG_READ_MASK(pHLpTim->TC, LPTIM_TC_TC_Msk); +} + + +/** + * \brief Configure the external trigger used as a trigger event for the LPTIM. + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] trig_src specific the tirgger source of LpTim, @ref LPTIM_TrigSrcTypeDef + * \return + * None + */ +__STATIC_INLINE void LPTIM_ConfigTrigger(LPTIM_Type *pHLpTim, LPTIM_TrigSrcTypeDef trig_src) +{ + REG_WRITE_MASK(pHLpTim->TCR, LPTIM_TCR_TRIGSEL_Msk, trig_src); + return; +} +//============================================================================= +// Structure Definition +//============================================================================= + +/** + * LpTIM Init structure definition + */ +typedef struct +{ + LPTIM_CLK_SrcTypeDef LPTIM_ClockSource; /*!< Specifies the source of the clock. */ + LPTIM_MatchModeTypeDef LPTIM_MatchMode; /*!< Specifies the mode when LPTIM matches the target counter value. */ + uint16_t LPTIM_MatchValue; /*!< Specifies the repetition counter value. */ + uint8_t LPTIM_Prescaler; /*!< Specifies the prescaler value used to divide the LPTIM clock. */ +} LPTIM_InitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * @brief Fills each LPTIM_InitTypeDef member with its default value. + * @param pInit: pointer to a LPTIM_TimeBaseInitTypeDef + * structure which will be initialized. + * @retval None. + */ +void LPTIM_StructInit(LPTIM_InitTypeDef *pInit); + + +/** + * @brief Initializes the lptim module according to + * the specified parameters in the init_struct. + * + * @param pHLpTim: the LpTim/TIm0/TIM1 instance + * @param pInit: pointer to a LPTIM_InitTypeDef structure + that contains the configuration information for the + * specified LpTIM module. + * @retval None. + */ +void LPTIM_Init(LPTIM_Type *pHLpTim, LPTIM_InitTypeDef *pInit); + +/** + * \brief De-initialize LpTim + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \return + * None + */ +void LPTIM_DeInit(LPTIM_Type *pHLpTim); + +/** + * \brief Enables or disables the specified LpTim interrupts + * + * \param [in] pHLpTim the LpTim/TIm0/TIM1 instance + * \param [in] has_enable enable or not + * \return + * None + */ +void LPTIM_ITConfig(LPTIM_Type *pHLpTim, int has_enable); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_opamp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_opamp.h new file mode 100644 index 0000000..7993a53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_opamp.h @@ -0,0 +1,185 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_opamp.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/12/05 + * @license + * @description + */ + +#ifndef __hal_opamp_H_wWPO7hlc_lEYx_HN8q_ssua_u8WscF53B3q1__ +#define __hal_opamp_H_wWPO7hlc_lEYx_HN8q_ssua_u8WscF53B3q1__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * The gain type of PGA of OPAMP + */ +typedef enum +{ + OPAMP_PGAGain_Ext = (0x00 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_1 = (OPAMP_PGA_CR_PGA_GAIN_x1 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_2 = (OPAMP_PGA_CR_PGA_GAIN_x2 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_3 = (OPAMP_PGA_CR_PGA_GAIN_x3 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_4 = (OPAMP_PGA_CR_PGA_GAIN_x4 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_5 = (OPAMP_PGA_CR_PGA_GAIN_x5 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_6 = (OPAMP_PGA_CR_PGA_GAIN_x6 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_7 = (OPAMP_PGA_CR_PGA_GAIN_x7 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_8 = (OPAMP_PGA_CR_PGA_GAIN_x8 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_9 = (OPAMP_PGA_CR_PGA_GAIN_x9 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_10 = (OPAMP_PGA_CR_PGA_GAIN_x10 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_11 = (OPAMP_PGA_CR_PGA_GAIN_x11 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_12 = (OPAMP_PGA_CR_PGA_GAIN_x12 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_13 = (OPAMP_PGA_CR_PGA_GAIN_x13 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_14 = (OPAMP_PGA_CR_PGA_GAIN_x14 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_15 = (OPAMP_PGA_CR_PGA_GAIN_x15 << OPAMP_PGA_CR_PGA_GAIN_Pos), + OPAMP_PGAGain_16 = (OPAMP_PGA_CR_PGA_GAIN_x16 << OPAMP_PGA_CR_PGA_GAIN_Pos), + +} OPAMP_PGAGainTypeDef; + + +/** + * The Vinput Plus signal source + */ +typedef enum +{ + OPAMP_VinP_Internal = (0x0ul << OPAMP_PGA_CR_PGA_VIP_SEL_Pos), + OPAMP_VinP_IO = (0x1ul << OPAMP_PGA_CR_PGA_VIP_SEL_Pos), +} OPAMP_VinPTypeDef; + +/** + * The Vinput Minus signal source + */ +typedef enum +{ + OPAMP_VinM_GND = (0x0ul << OPAMP_PGA_CR_PGA_VIN_SEL_Pos), + OPAMP_VinM_IO = (0x1ul << OPAMP_PGA_CR_PGA_VIN_SEL_Pos), +} OPAMP_VinMTypeDef; + +/** + * The Voutput destination + */ +typedef enum +{ + OPAMP_Vout_None = (0x0ul << OPAMP_PGA_CR_PGA_IO_EN_Pos), + OPAMP_Vout_IO = (0x1ul << OPAMP_PGA_CR_PGA_IO_EN_Pos), +} OPAMP_VoutTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Enable OPAMP + * + * \param [in] pHOPAmp The OPAMP instance + * \return + * None + */ +__STATIC_FORCEINLINE void OPAMP_Enable(OPAMP_Type *pHOPAmp) +{ + REG_SET_BITS(pHOPAmp->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk); + return; +} + +/** + * \brief Disable OPAMP + * + * \param [in] pHOPAmp The OPAMP instance + * \return + * None + */ +__STATIC_FORCEINLINE void OPAMP_Disable(OPAMP_Type *pHOPAmp) +{ + REG_CLR_BITS(pHOPAmp->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk); + return; +} + +/** + * \brief Set OPAMP PGA gain + * + * \param [in] pHOPAmp The OPAMP instance + * \param [in] gain The PGA gain, @ref OPAMP_PGAGainTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void OPAMP_SetPGAGain(OPAMP_Type *pHOPAmp, OPAMP_PGAGainTypeDef gain) +{ + REG_WRITE_MASK(pHOPAmp->PGA_CR, OPAMP_PGA_CR_PGA_GAIN_Msk, gain); + return; +} + +/** + * \brief Get OPAMP PGA gain + * + * \param [in] pHOPAmp The OPAMP instance + * \return + * the gain value, @ref OPAMP_PGAGainTypeDef + */ +__STATIC_FORCEINLINE OPAMP_PGAGainTypeDef OPAMP_GetPGAGain(OPAMP_Type *pHOPAmp) +{ + return REG_READ_MASK(pHOPAmp->PGA_CR, OPAMP_PGA_CR_PGA_GAIN_Msk); +} + +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct +{ + OPAMP_VinPTypeDef OPAMP_VinP; + OPAMP_VinMTypeDef OPAMP_VinM; + OPAMP_VoutTypeDef OPAMP_Vout; + OPAMP_PGAGainTypeDef OPAMP_Gain; /*!< Specifies the PGA Gain of OPAMP, @ref OPAMP_PGAGainTypeDef */ +} OPAMP_InitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Initialize OPAMP + * + * \param [in] pHOPAmp The OPAMP instance + * \param [in] pInit pointer to a OPAMP_InitTypeDef structure + * \return + * 0: ok, others: fail + */ +int OPAMP_Init(OPAMP_Type *pHOPAmp, OPAMP_InitTypeDef *pInit); + +/** + * \brief De-Initialize OPAMP + * + * \param [in] pHOPAmp The OPAMP instance + * \return + * None + */ +void OPAMP_DeInit(OPAMP_Type *pHOPAmp); + +/** + * \brief Set each field to default value + * + * \param [in] pInit pointer to a OPAMP_InitTypeDef structure + * \return + * None + */ +void OPAMP_StructInit(OPAMP_InitTypeDef *pInit); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_pwr.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_pwr.h new file mode 100644 index 0000000..0f377fb --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_pwr.h @@ -0,0 +1,112 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_pwr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_pmu_H_w8beFgJ5_lJKl_Ha3F_skkM_ujsx8CpdddI2__ +#define __hal_pmu_H_w8beFgJ5_lJKl_Ha3F_skkM_ujsx8CpdddI2__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Power mode type + */ +typedef enum PWR_Mode +{ + PWR_Mode_Sleep = 0, + PWR_Mode_DeepSleep, + +} PWR_ModeTypeDef; + +/** + * The wake-up type of power mode + */ +typedef enum PWR_Wakeup +{ + PWR_Wakeup_IO_PORT_A = (0x1ul << 0), + PWR_Wakeup_IO_PORT_B = (0x1ul << 1), + PWR_Wakeup_LpTIM = (0x1ul << 2), + PWR_Wakeup_WDG = (0x1ul << 3), + +} PWR_WakeupTypeDef; + +/** + * \brief Set the peripheral before entering power mode + * + * \param [in] pwr_mode the target power mode, @ref PWR_ModeTypeDef + * \param [in] pWakeup_type provide the target wake-up module from App level + * \return + * None + */ +typedef void (*CallbaskPreSleepTypeDef)(PWR_ModeTypeDef pwr_mode, PWR_WakeupTypeDef *pWakeup_type); + +/** + * \brief Set the peripheral after power mode wake-up + * + * \param [in] pwr_mode the target power mode, @ref PWR_ModeTypeDef + * \return + * None + */ +typedef void (*CallbaskPostSleepTypeDef)(PWR_ModeTypeDef pwr_mode); + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Enters Sleep mode + * + * @param [in] cb_pre_set_clk Set peripheral BEFORE entering sleep + * @param [in] cb_post_set_clk Set peripheral AFTER wake-up from sleep + * \return + * None + */ +void PWR_EnterSleepMode(CallbaskPreSleepTypeDef cb_pre_set, + CallbaskPostSleepTypeDef cb_post_set); + + +/** + * @brief Enters Deep Sleep mode. + * + * @param [in] cb_pre_set_clk Set peripheral BEFORE entering deepsleep + * @param [in] cb_post_set_clk Set peripheral AFTER wake-up from deepsleep + * @return + * None + */ +void PWR_EnterDeepSleepMode(CallbaskPreSleepTypeDef cb_pre_set, + CallbaskPostSleepTypeDef cb_post_set); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_spi.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_spi.h new file mode 100644 index 0000000..3bddd67 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_spi.h @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_spi.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_spi_H_wPLkKnnQ_le5I_Hr02_sscR_uSVsVXDq15tf__ +#define __hal_spi_H_wPLkKnnQ_le5I_Hr02_sscR_uSVsVXDq15tf__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define SPI_Mode_Slave (0x00U) /*!< SPI slave mode */ +#define SPI_Mode_Master (0x01U) /*!< SPI master mode */ + +#define SPI_CPOL_Low (0x00U) /*!< The clock is low in idle state. */ +#define SPI_CPOL_High (0x01U) /*!< The clock is high in idle state. */ + +#define SPI_CPHA_Effective (0x00U) /*!< Data sampling starts from the second clock edge. */ +#define SPI_CPHA_Ineffective (0x01U) /*!< Data sampling starts from the first clock edge. */ + + +#define SPI_FirstBit_MSB (0x00U) /*!< Data transfers start from MSB */ +#define SPI_FirstBit_LSB (0x01U) /*!< Data transfers start from LSB */ + +#define SPI_SSOUT_Selected (0x00U) +#define SPI_SSOUT_NoSelected (0x01U) + +#define SPI_ManualMode_Disable (0x00U) +#define SPI_ManualMode_Enable (0x01U) + +#define SPI_RECVOV_Flag (0x01 << SPI_STA_RECVOV_Pos) +#define SPI_MDF_Flag (0x01 << SPI_STA_MDF_Pos) +#define SPI_TXNFUL_Flag (0x01 << SPI_STA_TXNFUL_Pos) +#define SPI_TXFUL_Flag (0x01 << SPI_STA_TXFUL_Pos) +#define SPI_RXNEP_Flag (0x01 << SPI_STA_RXNEP_Pos) +#define SPI_RXFUL_Flag (0x01 << SPI_STA_RXFUL_Pos) +#define SPI_TXUFL_Flag (0x01 << SPI_STA_TXUFL_Pos) +#define SPI_BUSY_Flag (0x01 << SPI_STA_BUSY_Pos) + +typedef enum +{ + SPI_TxDataSize_8b = 0, /*!< 8 bits valid data */ + SPI_TxDataSize_16b , /*!< 16 bits valid data */ + SPI_TxDataSize_24b , /*!< 24 bits valid data */ + SPI_TxDataSize_32b , /*!< 32 bits valid data */ +} SPI_TXDataSizeTypedef; + +typedef enum +{ + SPI_BaudratePrescaler_2 = 0, /*!< SCK clock devide by 2 */ + SPI_BaudratePrescaler_4 , /*!< SCK clock devide by 4 */ + SPI_BaudratePrescaler_8 , /*!< SCK clock devide by 7 */ + SPI_BaudratePrescaler_16 , /*!< SCK clock devide by 16 */ + SPI_BaudratePrescaler_32 , /*!< SCK clock devide by 32 */ + SPI_BaudratePrescaler_64 , /*!< SCK clock devide by 64 */ + SPI_BaudratePrescaler_128 , /*!< SCK clock devide by 128 */ + SPI_BaudratePrescaler_256 , /*!< SCK clock devide by 256 */ +} SPI_DBTypedef; +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= +/** + * @brief SPI Init structure definition + */ +typedef struct +{ + uint32_t SPI_Mode; /*!< Specifies the SPI operating mode */ + uint32_t SPI_CPOL; /*!< Specifies the serial clock steady state */ + uint32_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture */ + uint32_t SPI_TxDataSize; /*!< Specifies the SPI available data size */ + uint32_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be */ + uint32_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit */ +} SPI_InitTypeDef; + +typedef struct +{ + uint8_t d_int; /*!< Specifies the SPI operating mode */ + uint8_t d_after; /*!< Specifies the serial clock steady state */ + uint8_t d_btwn; /*!< Specifies the clock active edge for the bit capture */ + uint8_t d_nss; /*!< Specifies the SPI available data size */ + +} SPI_DelayTypeDef; + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void SPI_DeInit(SPI_Type *spi); +void SPI_StructInit(SPI_InitTypeDef *init_struct); +void SPI_Init(SPI_Type *spi, SPI_InitTypeDef *init_struct); +void SPI_Enable(SPI_Type *spi); +void SPI_Disable(SPI_Type *spi); +void SPI_MasterEnable(SPI_Type *spi); +void SPI_SlaveEnable(SPI_Type *spi); +void SPI_SendData(SPI_Type *spi, uint32_t data); +uint32_t SPI_ReceiveData(SPI_Type *spi); +void SPI_SetBaudRatePrescaler(SPI_Type *spi, SPI_DBTypedef spi_baudrateprescaler); +void SPI_SetSSOUT(SPI_Type *spi, uint32_t ss_out_value); +void SPI_SetManualChipSelect(SPI_Type *spi, uint32_t mcs_value); +void SPI_SetManualMode(SPI_Type *spi, uint32_t mce_en); +void SPI_ManualModeStart(SPI_Type *spi); +void SPI_SetTxDataSize(SPI_Type *spi, SPI_TXDataSizeTypedef datasize_value); +uint32_t SPI_GetInterruptStatus(SPI_Type *spi, uint32_t flag); +uint32_t SPI_GetFlagStatus(SPI_Type *spi, uint32_t flag); +void SPI_ClearFlagStatus(SPI_Type *spi, uint32_t flag); +void SPI_SetInterrupt(SPI_Type *spi, uint32_t flag); +void SPI_SetInterruptDisable(SPI_Type *spi, uint32_t flag); +void SPI_SetDelay(SPI_Type *spi, SPI_DelayTypeDef * delay_set); +void SPI_SetIdleCnt(SPI_Type *spi, uint32_t idle_cnt); +void SPI_SetTXTH(SPI_Type *spi, uint32_t txth); +void SPI_SetRXTH(SPI_Type *spi, uint32_t rxth); + +void SPI_ManualSendData(SPI_Type *spi, uint32_t data); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_syscfg.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_syscfg.h new file mode 100644 index 0000000..019682d --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_syscfg.h @@ -0,0 +1,522 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_rcc.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_rcc_H_wdMtMHdK_l9Vy_HKdj_sp8x_uwqQm6IIBDo5__ +#define __hal_rcc_H_wdMtMHdK_l9Vy_HKdj_sp8x_uwqQm6IIBDo5__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= + +#define SYSCFG_SIGN_RST_PIN_EN 0xA563 + +/** + * Clock source + */ +typedef enum +{ + SYSCFG_ClkSrc_HSI = SYSCFG_SYSCLKCR_CLKSW_HSI << SYSCFG_SYSCLKCR_CLKSW_Pos, /*!< Internal High Speed Clock. */ + SYSCFG_ClkSrc_HSE = SYSCFG_SYSCLKCR_CLKSW_HSE << SYSCFG_SYSCLKCR_CLKSW_Pos, /*!< External High Speed Clock. */ + SYSCFG_ClkSrc_LSI = SYSCFG_SYSCLKCR_CLKSW_LSI << SYSCFG_SYSCLKCR_CLKSW_Pos, /*!< Internal Low Speed Clock. */ + SYSCFG_ClkSrc_FreqDiv = SYSCFG_SYSCLKCR_CLKSW_CLKDIV << SYSCFG_SYSCLKCR_CLKSW_Pos, /*!< Prescaler Clock. */ +} SYSCFG_ClkSrcTypeDef; + +typedef enum +{ + SYSCFG_SysClkDiv2 = (1ul << SYSCFG_SYSCLKCR_CLKDIV_Pos), + SYSCFG_SysClkDiv4 = (3ul << SYSCFG_SYSCLKCR_CLKDIV_Pos), + SYSCFG_SysClkDiv8 = (7ul << SYSCFG_SYSCLKCR_CLKDIV_Pos), +} SYSCFG_SysClkDivTypeDef; + +typedef enum +{ + SYSCFG_SysTickSrc_LSI = (SYSCFG_SYSCLKCR_SYSTICKCR_LSI << SYSCFG_SYSCLKCR_SYSTICKCR_Pos), + SYSCFG_SysTickSrc_HSI_Div2 = (SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV2 << SYSCFG_SYSCLKCR_SYSTICKCR_Pos), + SYSCFG_SysTickSrc_HSI_Div4 = (SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV4 << SYSCFG_SYSCLKCR_SYSTICKCR_Pos), + SYSCFG_SysTickSrc_HSI_Div8 = (SYSCFG_SYSCLKCR_SYSTICKCR_HSI_DIV8 << SYSCFG_SYSCLKCR_SYSTICKCR_Pos), +} SYSCFG_SysTickSrcTypeDef; + +typedef enum +{ +#define SYSCFG_FLAGS_TYPE_Msk 0x3F + SYSCFG_FLAG_PINRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_PADRST_Pos), /*!< PIN reset flag */ + SYSCFG_FLAG_PORRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_PORRST_Pos), /*!< POR/PDR reset flag */ + SYSCFG_FLAG_SFTRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_SWRST_Pos), /*!< Software Reset flag */ + SYSCFG_FLAG_WDGRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_WDGRST_Pos), /*!< Watchdog reset flag */ + SYSCFG_FLAG_LOCKUPRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_LOCKUPRST_Pos), /*!< LOCKUP reset flag */ + SYSCFG_FLAG_LVDRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_LVDRST_Pos), /*!< LVD reset flag */ + SYSCFG_FLAG_REBOOTRST = (uint8_t)((1 << 6U) | SYSCFG_SYSRSTSR_REBOOTRST_Pos), /*!< Re-boot latch reset flag */ + + SYSCFG_FLAG_ALL = (uint8_t)((1 << 6U) | SYSCFG_FLAGS_TYPE_Msk) /*!< Only for clearing flags */ +} SYSCFG_FlagTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= + +/*** PCLK Module Enable ***/ + +/* UART0 */ +#define __HAL_SYSCFG_UART0_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_UART0_Msk) +#define __HAL_SYSCFG_UART0_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_UART0_Msk)) + +#define __HAL_SYSCFG_UART0_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_UART0_Msk) + +/* TIM0 */ +#define __HAL_SYSCFG_TIM0_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM0_Msk) +#define __HAL_SYSCFG_TIM0_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_TIM0_Msk)) + +#define __HAL_SYSCFG_TIM0_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM0_Msk) + +/* TIM1 */ +#define __HAL_SYSCFG_TIM1_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM1_Msk) +#define __HAL_SYSCFG_TIM1_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_TIM1_Msk)) + +#define __HAL_SYSCFG_TIM1_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM1_Msk) + +/* LPTIM */ +#define __HAL_SYSCFG_LPTIM_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_LPTIM_Msk) +#define __HAL_SYSCFG_LPTIM_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_LPTIM_Msk)) + +#define __HAL_SYSCFG_LPTIM_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_LPTIM_Msk) + +/* ADC */ +#define __HAL_SYSCFG_ADC_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_ADC_Msk) +#define __HAL_SYSCFG_ADC_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_ADC_Msk)) + +#define __HAL_SYSCFG_ADC_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_ADC_Msk) + +/* EPWM */ +#define __HAL_SYSCFG_EPWM_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_EPWM_Msk) +#define __HAL_SYSCFG_EPWM_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_EPWM_Msk)) + +#define __HAL_SYSCFG_EPWM_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_EPWM_Msk) + +/* DSP */ +#define __HAL_SYSCFG_DSP_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_DSP_Msk) +#define __HAL_SYSCFG_DSP_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_DSP_Msk)) + +#define __HAL_SYSCFG_DSP_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_DSP_Msk) + +/* COMP0 */ +#define __HAL_SYSCFG_COMP0_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_COMP0_Msk) +#define __HAL_SYSCFG_COMP0_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_COMP0_Msk)) + +#define __HAL_SYSCFG_COMP0_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_COMP0_Msk) + +/* SPI */ +#define __HAL_SYSCFG_SPI_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_SPI_Msk) +#define __HAL_SYSCFG_SPI_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_SPI_Msk)) + +#define __HAL_SYSCFG_SPI_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_SPI_Msk) + +/* TIM2 */ +#define __HAL_SYSCFG_TIM2_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM2_Msk) +#define __HAL_SYSCFG_TIM2_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_TIM2_Msk)) + +#define __HAL_SYSCFG_TIM2_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_TIM2_Msk) + +/* I2C */ +#define __HAL_SYSCFG_I2C_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_I2C_Msk) +#define __HAL_SYSCFG_I2C_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_I2C_Msk)) + +#define __HAL_SYSCFG_I2C_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_I2C_Msk) + +/* COMP1 */ +#define __HAL_SYSCFG_COMP1_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_COMP1_Msk) +#define __HAL_SYSCFG_COMP1_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_COMP1_Msk)) + +#define __HAL_SYSCFG_COMP1_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_COMP1_Msk) + +/* WDG */ +#define __HAL_SYSCFG_WDG_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_WDG_Msk) +#define __HAL_SYSCFG_WDG_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_WDG_Msk)) + +#define __HAL_SYSCFG_WDG_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_WDG_Msk) + +/* AMISC */ +#define __HAL_SYSCFG_AMISC_CLK_ENABLE() REG_SET_BITS(SYSCFG->PCLKEN, SYSCFG_PCLKEN_AMISC_Msk) +#define __HAL_SYSCFG_AMISC_CLK_DISABLE() REG_CLR_BITS(SYSCFG->PCLKEN, (SYSCFG_PCLKEN_AMISC_Msk)) + +#define __HAL_SYSCFG_AMISC_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->PCLKEN, SYSCFG_PCLKEN_AMISC_Msk) + + +/*** HCLK Module Enable ***/ + +/* GPIOA */ +#define __HAL_SYSCFG_GPIOA_CLK_ENABLE() REG_SET_BITS(SYSCFG->HCLKEN, SYSCFG_HCLKEN_GPIOA_Msk) +#define __HAL_SYSCFG_GPIOA_CLK_DISABLE() REG_CLR_BITS(SYSCFG->HCLKEN, (SYSCFG_HCLKEN_GPIOA_Msk)) + +#define __HAL_SYSCFG_GPIOA_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->HCLKEN, SYSCFG_HCLKEN_GPIOA_Msk) + +/* GPIOB */ +#define __HAL_SYSCFG_GPIOB_CLK_ENABLE() REG_SET_BITS(SYSCFG->HCLKEN, SYSCFG_HCLKEN_GPIOB_Msk) +#define __HAL_SYSCFG_GPIOB_CLK_DISABLE() REG_CLR_BITS(SYSCFG->HCLKEN, (SYSCFG_HCLKEN_GPIOB_Msk)) + +#define __HAL_SYSCFG_GPIOB_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->HCLKEN, SYSCFG_HCLKEN_GPIOB_Msk) + +/* CRC */ +#define __HAL_SYSCFG_CRC_CLK_ENABLE() REG_SET_BITS(SYSCFG->HCLKEN, SYSCFG_HCLKEN_CRC_Msk) +#define __HAL_SYSCFG_CRC_CLK_DISABLE() REG_CLR_BITS(SYSCFG->HCLKEN, (SYSCFG_HCLKEN_CRC_Msk)) + +#define __HAL_SYSCFG_CRC_IS_CLK_ENABLED() REG_READ_MASK(SYSCFG->HCLKEN, SYSCFG_HCLKEN_CRC_Msk) + + +/*** peripherals reset ***/ + +/* UART0 */ +#define __HAL_SYSCFG_UART0_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_UART0_Msk) +#define __HAL_SYSCFG_UART0_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_UART0_Msk) + +#define __HAL_SYSCFG_RESET_UART0() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_UART0_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_UART0_Msk); \ + }while(0) + + +/* TIM0 */ +#define __HAL_SYSCFG_TIM0_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM0_Msk) +#define __HAL_SYSCFG_TIM0_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM0_Msk) + +#define __HAL_SYSCFG_RESET_TIM0() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM0_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM0_Msk); \ + }while(0) + + +/* TIM1 */ +#define __HAL_SYSCFG_TIM1_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM1_Msk) +#define __HAL_SYSCFG_TIM1_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM1_Msk) + +#define __HAL_SYSCFG_RESET_TIM1() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM1_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM1_Msk); \ + }while(0) + + +/* LPTIM */ +#define __HAL_SYSCFG_LPTIM_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_LPTIM_Msk) +#define __HAL_SYSCFG_LPTIM_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_LPTIM_Msk) + +#define __HAL_SYSCFG_RESET_LPTIM() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_LPTIM_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_LPTIM_Msk); \ + }while(0) + + +/* ADC */ +#define __HAL_SYSCFG_ADC_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_ADC_Msk) +#define __HAL_SYSCFG_ADC_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_ADC_Msk) + +#define __HAL_SYSCFG_RESET_ADC() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_ADC_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_ADC_Msk); \ + }while(0) + + +/* EPWM */ +#define __HAL_SYSCFG_EPWM_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_EPWM_Msk) +#define __HAL_SYSCFG_EPWM_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_EPWM_Msk) + +#define __HAL_SYSCFG_RESET_EPWM() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_EPWM_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_EPWM_Msk); \ + }while(0) + + +/* DSP */ +#define __HAL_SYSCFG_DSP_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_DSP_Msk) +#define __HAL_SYSCFG_DSP_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_DSP_Msk) + +#define __HAL_SYSCFG_RESET_DSP() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_DSP_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_DSP_Msk); \ + }while(0) + + +/* COMP0 */ +#define __HAL_SYSCFG_COMP0_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP0_Msk) +#define __HAL_SYSCFG_COMP0_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP0_Msk) + +#define __HAL_SYSCFG_RESET_COMP0() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP0_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP0_Msk); \ + }while(0) + + +/* SPI */ +#define __HAL_SYSCFG_SPI_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_SPI_Msk) +#define __HAL_SYSCFG_SPI_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_SPI_Msk) + +#define __HAL_SYSCFG_RESET_SPI() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_SPI_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_SPI_Msk); \ + }while(0) + + +/* TIM2 */ +#define __HAL_SYSCFG_TIM2_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM2_Msk) +#define __HAL_SYSCFG_TIM2_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM2_Msk) + +#define __HAL_SYSCFG_RESET_TIM2() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM2_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_TIM2_Msk); \ + }while(0) + + +/* I2C */ +#define __HAL_SYSCFG_I2C_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_I2C_Msk) +#define __HAL_SYSCFG_I2C_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_I2C_Msk) + +#define __HAL_SYSCFG_RESET_I2C() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_I2C_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_I2C_Msk); \ + }while(0) + + +/* COMP1 */ +#define __HAL_SYSCFG_COMP1_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP1_Msk) +#define __HAL_SYSCFG_COMP1_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP1_Msk) + +#define __HAL_SYSCFG_RESET_COMP1() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP1_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_COMP1_Msk); \ + }while(0) + + +/* WDG */ +#define __HAL_SYSCFG_WDG_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_WDG_Msk) +#define __HAL_SYSCFG_WDG_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_WDG_Msk) + +#define __HAL_SYSCFG_RESET_WDG() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_WDG_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_WDG_Msk); \ + }while(0) + + +/* AMISC */ +#define __HAL_SYSCFG_AMISC_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_AMISC_Msk) +#define __HAL_SYSCFG_AMISC_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_AMISC_Msk) + +#define __HAL_SYSCFG_RESET_AMISC() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_AMISC_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN, SYSCFG_PRSTEN_AMISC_Msk); \ + }while(0) + + + +/*** peripherals reset ***/ + +/* GPIOA */ +#define __HAL_SYSCFG_GPIOA_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOA_Msk) +#define __HAL_SYSCFG_GPIOA_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOA_Msk) + +#define __HAL_SYSCFG_RESET_GPIOA() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOA_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOA_Msk); \ + }while(0) + + +/* GPIOB */ +#define __HAL_SYSCFG_GPIOB_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOB_Msk) +#define __HAL_SYSCFG_GPIOB_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOB_Msk) + +#define __HAL_SYSCFG_RESET_GPIOB() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOB_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_GPIOB_Msk); \ + }while(0) + + +/* CRC */ +#define __HAL_SYSCFG_CRC_CLK_FORCE_RESET() REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_CRC_Msk) +#define __HAL_SYSCFG_CRC_RELEASE_RESET() REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_CRC_Msk) + +#define __HAL_SYSCFG_RESET_CRC() \ + do{ REG_SET_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_CRC_Msk); \ + REG_CLR_BITS(SYSCFG->PRSTEN1, SYSCFG_PRSTEN1_CRC_Msk); \ + }while(0) + + + +/** + * \brief Get chip ID of DUT + * + * \return + * Chip ID + */ +__STATIC_FORCEINLINE uint32_t SYSCFG_GetChipID(void) +{ + return REG_READ(SYSCFG->CHIPID); +} + +/** + * \brief Configure Reset-Pin to normal I/O or not + * + * \param [in] is_enable Set Reset-Pin to normal I/O or not + * \return + * None + */ +__STATIC_FORCEINLINE void SYSCFG_SetRstPin2NormalIO(int is_enable) +{ + (is_enable) + ? REG_WRITE_MASK(SYSCFG->RSTPINCR, SYSCFG_RSTPINCR_RSTPINAF_Msk, SYSCFG_RSTPINCR_RSTPINAF_OFF << SYSCFG_RSTPINCR_RSTPINAF_Pos) + : REG_WRITE_MASK(SYSCFG->RSTPINCR, SYSCFG_RSTPINCR_RSTPINAF_Msk, SYSCFG_RSTPINCR_RSTPINAF_ON << SYSCFG_RSTPINCR_RSTPINAF_Pos); + return; +} + +/** + * \brief Enable low-power feature or not + * + * \param [in] is_enable 0: disable, others: enable + * \return + * None + */ +__STATIC_FORCEINLINE void SYSCFG_SetLowPower(int is_enable) +{ + (is_enable) + ? REG_SET_BITS(SYSCFG->PMUCR, SYSCFG_PMUCR_PMUEN_Msk) + : REG_CLR_BITS(SYSCFG->PMUCR, SYSCFG_PMUCR_PMUEN_Msk); + return; +} + +/** + * \brief Get the system clock source type + * + * \return + * The system clock source type, @ref SYSCFG_ClkSrcTypeDef + */ +__STATIC_FORCEINLINE SYSCFG_ClkSrcTypeDef SYSCFG_GetSysClkType(void) +{ + return REG_READ_MASK(SYSCFG->SYSCLKCR, SYSCFG_SYSCLKCR_CLKSW_Msk); +} + +/** + * \brief Set System-Tick source + * + * \param [in] ClkSrc the target clock source of System-Tick, @ref SYSCFG_SysTickSrcTypeDef + * \return + * None + */ +__STATIC_FORCEINLINE void SYSCFG_SetSysTickSrc(SYSCFG_SysTickSrcTypeDef ClkSrc) +{ + REG_WRITE_MASK(SYSCFG->SYSCLKCR, SYSCFG_SYSCLKCR_SYSTICKCR_Msk, ClkSrc); + return; +} + +/** + * \brief Get System-Tick source + * + * \return + * the current clock source of System-Tick, @ref SYSCFG_SysTickSrcTypeDef + */ +__STATIC_FORCEINLINE SYSCFG_SysTickSrcTypeDef SYSCFG_GetSysTickSrc(void) +{ + return REG_READ_MASK(SYSCFG->SYSCLKCR, SYSCFG_SYSCLKCR_SYSTICKCR_Msk); +} + +/** + * \brief Set LSI Always On + * + * \param [in] is_enable 0: disable, others: enable + * \return + * None + */ +__STATIC_FORCEINLINE void SYSCFG_SetLSIAlwaysOn(int is_enable) +{ + (is_enable) + ? REG_SET_BITS(SYSCFG->SYSCLKCR, SYSCFG_SYSCLKCR_LSIAON_Msk) + : REG_CLR_BITS(SYSCFG->SYSCLKCR, SYSCFG_SYSCLKCR_LSIAON_Msk); + return; +} +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct +{ + SYSCFG_ClkSrcTypeDef ClkSource; /*!< The target clock source, @ref SYSCFG_ClkSrcTypeDef. + If ClkSource == SYSCFG_ClkSrc_FreqDiv, + SysClk_Div will be effective. */ + + SYSCFG_SysClkDivTypeDef SysClk_Div; /*!< SYSCLK clock prescaler, @ref SYSCFG_SysClkDivTypeDef (default: Div2). */ + + SYSCFG_SysTickSrcTypeDef SysTickSrc; /*!< Select the clock source of system-tick, @ref SYSCFG_SysTickSrcTypeDef (default: LSI) */ + +} SYSCFG_ClkInitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Configure system clock + * + * \param [in] pInit Pointer to a SYSCFG_ClkInitTypeDef structure, @ref SYSCFG_ClkInitTypeDef + * \return + * None + */ +void SYSCFG_SysClkConfig(SYSCFG_ClkInitTypeDef *pInit); + +/** + * \brief Checks whether the specified SYSCFG flag is set or not. + * + * \param [in] flag Specifies the flag to check, @ref SYSCFG_FlagTypeDef + * \return + * 0 : Nothing + * others: Get the specific status + */ +int SYSCFG_GetFlagStatus(SYSCFG_FlagTypeDef flag); + +/** + * \brief Clear the SYSCFG flags. + * + * \param [in] flag Specifies the flag to check, @ref SYSCFG_FlagTypeDef + * \return + * None + */ +void SYSCFG_ClearFlags(SYSCFG_FlagTypeDef flag); + + +/** + * \brief Trigger DUT to reboot and letch system parameters + * ps. This API will block program and force to reboot DUT + * + * \return + * No return + */ +void SYSCFG_RebootLetch(void); + +/** + * \brief Configure Alternate Function mode of I/O Pins of ICE (jTag) + * + * \param [in] is_enable Enable ICE I/O pins or not + * \return + * None + */ +void SYSCFG_SetICEPin2NormalIO(int is_enable); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_tim.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_tim.h new file mode 100644 index 0000000..dd588d9 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_tim.h @@ -0,0 +1,564 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_timer.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_timer_H_wP2TyFFu_lfcA_HOTx_s6ox_udtPYlP5WVqK__ +#define __hal_timer_H_wP2TyFFu_lfcA_HOTx_s6ox_udtPYlP5WVqK__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * @brief TIM Time Base Init structure definition + */ +typedef struct +{ + uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. */ + uint32_t TIM_CounterMode; /*!< Specifies the counter mode. */ + uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active */ + uint32_t TIM_ClockDivision; /*!< Specifies the clock division. */ + uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter */ +} TIM_TimeBaseInitTypeDef; + +/** + * @brief TIM Output Compare Init structure definition + */ +typedef struct +{ + uint32_t TIM_OCMode; /*!< Specifies the TIM mode. */ + uint32_t TIM_OutputState; /*!< Specifies the TIM Output Compare state. */ + uint32_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state. */ + uint32_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. */ + uint32_t TIM_OCPolarity; /*!< Specifies the output polarity. */ + uint32_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity. */ + uint32_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. */ + uint32_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. */ +} TIM_OCInitTypeDef; + +/** + * @brief TIM Input Capture Init structure definition + */ +typedef struct +{ + uint16_t TIM_Channel; /*!< Specifies the TIM channel. */ + uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal. */ + uint16_t TIM_ICSelection; /*!< Specifies the input. */ + uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler. */ + uint16_t TIM_ICFilter; /*!< Specifies the input capture filter. */ +} TIM_ICInitTypeDef; + +/** + * @brief BDTR structure definition + */ +typedef struct +{ + uint16_t TIM_OSSRState; /*!< Specifies the Off-State selection used in Run mode. */ + uint16_t TIM_OSSIState; /*!< Specifies the Off-State used in Idle state. */ + uint16_t TIM_LOCKLevel; /*!< Specifies the LOCK level parameters. */ + uint16_t TIM_DeadTime; /*!< Specifies the delay time between the switching-off and */ + uint16_t TIM_Break; /*!< Specifies whether the TIM Break input is enabled or not. */ + uint16_t TIM_BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. */ + uint16_t TIM_AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not. */ + uint16_t TIM_DTGFTime; /*!< Specifies the delay time between the switching-off and */ + uint32_t TIM_DTAEState; /*!< Specifies the delay time between the switching-off and */ +} TIM_BDTRInitTypeDef; +/** + * @} + */ + +/** @defgroup TIM_Exported_Constants + * @{ + */ + +/** + * @brief TIM_Clock_Division_CKD + */ +#define TIM_CKD_Div1 (0x00U << TIM_CR1_CKD_Pos) /*!< TDTS = Tck_tim */ +#define TIM_CKD_Div2 (0x01U << TIM_CR1_CKD_Pos) /*!< TDTS = 2 * Tck_tim */ +#define TIM_CKD_Div4 (0x02U << TIM_CR1_CKD_Pos) /*!< TDTS = 4 * Tck_tim */ + +/** + * @brief TIM_Counter_Mode + */ +#define TIM_CounterMode_Up (0x00U << TIM_CR1_DIR_Pos) /*!< TIM Up Counting Mode */ +#define TIM_CounterMode_Down (0x01U << TIM_CR1_DIR_Pos) /*!< TIM Down Counting Mode */ +#define TIM_CounterMode_CenterAligned1 (0x01U << TIM_CR1_CMS_Pos) /*!< TIM Center Aligned Mode1 */ +#define TIM_CounterMode_CenterAligned2 (0x02U << TIM_CR1_CMS_Pos) /*!< TIM Center Aligned Mode2 */ +#define TIM_CounterMode_CenterAligned3 (0x03U << TIM_CR1_CMS_Pos) /*!< TIM Center Aligned Mode3 */ + +/** + * @brief TIM_Prescaler_Reload_Mode + */ +#define TIM_PSCReloadMode_Update (0x00U << TIM_EGR_UG_Pos) /*!< The Prescaler is loaded at the update event */ +#define TIM_PSCReloadMode_Immediate (0x01U << TIM_EGR_UG_Pos) /*!< The Prescaler is loaded immediately */ + +/** + * @brief TIM_Output_Compare_and_PWM_modes_and_Forced_Action + */ +#define TIM_OCMode_Timing 0x00U /*!< Output compare mode: Timing */ +#define TIM_OCMode_Active 0x01U /*!< Output compare mode: Active */ +#define TIM_OCMode_Inactive 0x02U /*!< Output compare mode: Inactive */ +#define TIM_OCMode_Toggle 0x03U /*!< Output compare mode: Toggle */ +#define TIM_ForcedAction_Inactive 0x04U /*!< Force inactive level on OCnREF */ +#define TIM_ForcedAction_Active 0x05U /*!< Force active level on OCnREF */ +#define TIM_OCMode_PWM1 0x06U /*!< Output compare mode: PWM1 */ +#define TIM_OCMode_PWM2 0x07U /*!< Output compare mode: PWM2 */ + +/** + * @brief TIM_Output_Compare_Polarity + */ +#define TIM_OCPolarity_High 0x00U /*!< Output Compare active high */ +#define TIM_OCPolarity_Low 0x01U /*!< Output Compare active low */ + +/** + * @brief TIM_Output_Compare_N_Polarity + */ +#define TIM_OCNPolarity_High 0x00U /*!< Output Compare active high */ +#define TIM_OCNPolarity_Low 0x01U /*!< Output Compare active low */ + +/** + * @brief TIM_Output_Compare_state + */ +#define TIM_OutputState_Disable 0x00U /*!< Output Compare Disable */ +#define TIM_OutputState_Enable 0x01U /*!< Output Compare Enable */ + +/** + * @brief TIM_Output_Compare_N_state + */ +#define TIM_OutputNState_Disable 0x00U /*!< Output Compare N Disable */ +#define TIM_OutputNState_Enable 0x01U /*!< Output Compare N Enable */ + +/** + * @brief TIM_Output_Compare_Idle_State + */ +#define TIM_OCIdleState_Reset 0x00U /*!< OCn=0 (after a dead-time if OCnN is implemented) when MOE=0.(n= 0 : 4) */ +#define TIM_OCIdleState_Set 0x01U /*!< OCn=1 (after a dead-time if OCnN is implemented) when MOE=0.(n= 0 : 4) */ + +/** + * @brief TIM_Output_Compare_N_Idle_State + */ +#define TIM_OCNIdleState_Reset 0x00U /*!< OCnN=0 after a dead-time when MOE=0.(n= 0 : 4) */ +#define TIM_OCNIdleState_Set 0x01U /*!< OCnN=1 after a dead-time when MOE=0.(n= 0 : 4) */ + +/** + * @brief TIM_Channel + */ +#define TIM_Channel_1 0x0000 /*!< TIM Channel 1 */ +#define TIM_Channel_2 0x0004 /*!< TIM Channel 2 */ +#define TIM_Channel_3 0x0008 /*!< TIM Channel 3 */ +#define TIM_Channel_4 0x000C /*!< TIM Channel 4 */ + + +/** + * @brief TIM_Input_Capture_Polarity + */ +#define TIM_ICPolarity_Rising (0x00 << TIM_CCER_CC1P_Pos) /*!< IC Rising edge */ +#define TIM_ICPolarity_Falling (0x01 << TIM_CCER_CC1P_Pos) /*!< IC Falling edge */ +//#define TIM_ICPolarity_BothEdge ((0x01 << TIM_CCER_CC1P_Pos) | (0x01 << TIM_CCER_CC1NP_Pos)) + +/** + * @brief TIM_Input_Capture_Selection + */ +#define TIM_ICSelection_DirectTI 0x01U +#define TIM_ICSelection_IndirectTI 0x02U +#define TIM_ICSelection_TRC 0x03U + +/** + * @brief TIM_Input_Capture_Prescaler + */ +#define TIM_ICPSC_Div1 0x0000 /*!< no prescaler */ +#define TIM_ICPSC_Div2 0x0004 /*!< capture is done once every 2 events */ +#define TIM_ICPSC_Div4 0x0008 /*!< capture is done once every 4 events */ +#define TIM_ICPSC_Div8 0x000C /*!< capture is done once every 8 events */ + +/** + * @brief OSSR_Off_State_Selection_for_Run_mode_state + */ +#define TIM_OSSRState_Disable (0x00U << TIM_BDTR_OSSR_Pos) +#define TIM_OSSRState_Enable (0x01U << TIM_BDTR_OSSR_Pos) + +/** + * @brief OSSI_Off_State_Selection_for_Idle_mode_state + */ +#define TIM_OSSIState_Disable (0x00U << TIM_BDTR_OSSI_Pos) +#define TIM_OSSIState_Enable (0x01U << TIM_BDTR_OSSI_Pos) + +/** + * @brief Lock_level + */ +#define TIM_LockLevel_OFF (0x00U << TIM_BDTR_LOCK_Pos)//svd should LOOK -> LOCK +#define TIM_LockLevel_1 (0x01U << TIM_BDTR_LOCK_Pos) +#define TIM_LockLevel_2 (0x02U << TIM_BDTR_LOCK_Pos) +#define TIM_LockLevel_3 (0x03U << TIM_BDTR_LOCK_Pos) + +/** + * @brief Break_Input_enable_disable + */ +#define TIM_Break_Disable (0x00U << TIM_BDTR_BKE_Pos) /*!< Break inputs (BRK and CSS clock failure event) disabled */ +#define TIM_Break_Enable (0x01U << TIM_BDTR_BKE_Pos) /*!< Break inputs (BRK and CSS clock failure event) enabled */ + +/** + * @brief Break_Polarity + */ +#define TIM_BreakPolarity_Low (0x00U << TIM_BDTR_BKP_Pos) /*!< Break input BRK is active low */ +#define TIM_BreakPolarity_High (0x01U << TIM_BDTR_BKP_Pos) /*!< Break input BRK is active high */ + +/** + * @brief TIM_AOE_Bit_Set_Reset + */ +#define TIM_AutomaticOutput_Disable (0x00U << TIM_BDTR_AOE_Pos) /*!< MOE can be set only by software. */ +#define TIM_AutomaticOutput_Enable (0x01U << TIM_BDTR_AOE_Pos) /*!< MOE can be set by software or automatically at the next + update event (if the break input is not be active). */ +/** + * @brief TIM_DOE_Bit_Set_Reset + */ +#define TIM_DirectOutput_Disable (0x00U << TIM_BDTR_DOE_Pos) /*!< Direct output disable, output waiting for dead time */ +#define TIM_DirectOutput_Enable (0x01U << TIM_BDTR_DOE_Pos) /*!< Direct output enable, no longer waiting for output after dead time */ + +/** + * @brief DATE_State_Selection_for_Idle_mode_state + */ +#define TIM_DTAEState_Disable (0x00U << TIM_BDTR_DTAE_Pos) +#define TIM_DTAEState_Enable (0x01U << TIM_BDTR_DTAE_Pos) +/** + * @brief TIM_interrupt_sources + */ +#define TIM_IT_Update (0x01U << TIM_DIER_UIE_Pos) /*!< TIM update Interrupt source */ +#define TIM_IT_CC1 (0x01U << TIM_DIER_CC1IE_Pos) /*!< TIM Capture Compare 1 Interrupt source */ +#define TIM_IT_CC2 (0x01U << TIM_DIER_CC2IE_Pos) /*!< TIM Capture Compare 2 Interrupt source */ +#define TIM_IT_CC3 (0x01U << TIM_DIER_CC3IE_Pos) /*!< TIM Capture Compare 3 Interrupt source */ +#define TIM_IT_CC4 (0x01U << TIM_DIER_CC4IE_Pos) /*!< TIM Capture Compare 4 Interrupt source */ +#define TIM_IT_COM (0x01U << TIM_DIER_COMIE_Pos) /*!< TIM Commutation Interrupt source */ +#define TIM_IT_Trigger (0x01U << TIM_DIER_TIE_Pos) /*!< TIM Trigger Interrupt source */ +#define TIM_IT_Break (0x01U << TIM_DIER_BIE_Pos) /*!< TIM Break Interrupt source */ +#define TIM_IT_CCD1 (0x01U << TIM_DIER_CCD1IE_Pos) /*!< TIM Capture Compare 1 Interrupt source */ +#define TIM_IT_CCD2 (0x01U << TIM_DIER_CCD2IE_Pos) /*!< TIM Capture Compare 2 Interrupt source */ +#define TIM_IT_CCD3 (0x01U << TIM_DIER_CCD3IE_Pos) /*!< TIM Capture Compare 3 Interrupt source */ +#define TIM_IT_OV (0x01U << TIM_DIER_OVIE_Pos) /*!< TIM Trigger Interrupt source */ +#define TIM_IT_UD (0x01U << TIM_DIER_UDIE_Pos) /*!< TIM Break Interrupt source */ +#define TIM_IT_CCD4 (0x01U << TIM_DIER_CCD4IE_Pos) /*!< TIM Capture Compare 4 Interrupt source */ + + +/** + * @brief TIM_Event_Source + */ +#define TIM_EventSource_Update (0x01U << TIM_EGR_UG_Pos) /*!< Timer update Event source */ +#define TIM_EventSource_CC1 (0x01U << TIM_EGR_CC1G_Pos) /*!< Timer Capture Compare 1 Event source */ +#define TIM_EventSource_CC2 (0x01U << TIM_EGR_CC2G_Pos) /*!< Timer Capture Compare 2 Event source */ +#define TIM_EventSource_CC3 (0x01U << TIM_EGR_CC3G_Pos) /*!< Timer Capture Compare 3 Event source */ +#define TIM_EventSource_CC4 (0x01U << TIM_EGR_CC4G_Pos) /*!< Timer Capture Compare 4 Event source */ +#define TIM_EventSource_COM (0x01U << TIM_EGR_COMG_Pos) /*!< Timer COM event source */ +#define TIM_EventSource_Trigger (0x01U << TIM_EGR_TG_Pos) /*!< Timer Trigger Event source */ +#define TIM_EventSource_Break (0x01U << TIM_EGR_BG_Pos) /*!< Timer Break event source */ + + +/** + * @brief TIM_Internal_Trigger_Selection + */ +#define TIM_TS_ITR0 (0x00U << TIM_SMCR_TS_Pos) /*!< Internal Trigger 0 */ +#define TIM_TS_ITR1 (0x01U << TIM_SMCR_TS_Pos) /*!< Internal Trigger 1 */ +#define TIM_TS_ITR2 (0x02U << TIM_SMCR_TS_Pos) /*!< Internal Trigger 2 */ +#define TIM_TS_ITR3 (0x03U << TIM_SMCR_TS_Pos) /*!< Internal Trigger 3 */ +#define TIM_TS_TI1F_ED (0x04U << TIM_SMCR_TS_Pos) /*!< TI1 Edge Detector */ +#define TIM_TS_TI1FP1 (0x05U << TIM_SMCR_TS_Pos) /*!< Filtered Timer Input 1 */ +#define TIM_TS_TI2FP2 (0x06U << TIM_SMCR_TS_Pos) /*!< Filtered Timer Input 2 */ +#define TIM_TS_ETRF (0x07U << TIM_SMCR_TS_Pos) /*!< TI1 Edge Detector */ + +/** + * @brief TIM_Encoder_Mode + */ +#define TIM_EncoderMode_TI1 (0x01U << TIM_SMCR_SMS_Pos) /*!< Counter counts on TI1FP1 edge depending on TI2FP2 level. */ +#define TIM_EncoderMode_TI2 (0x02U << TIM_SMCR_SMS_Pos) /*!< Counter counts on TI2FP2 edge depending on TI1FP1 level. */ +#define TIM_EncoderMode_TI12 (0x03U << TIM_SMCR_SMS_Pos) /*!< Counter counts on both TI1FP1 and TI2FP2 edges depending on the level of the other input. */ + +#define TIM_CCMR1_CC1S_OC (0x00U << TIM_CCMR1_OUTPUT_CC1S_Pos) +#define TIM_CCMR1_CC1S_DirectTI (0x01U << TIM_CCMR1_OUTPUT_CC1S_Pos) +#define TIM_CCMR1_CC1S_IndirectTI (0x02U << TIM_CCMR1_OUTPUT_CC1S_Pos) +#define TIM_CCMR1_CC1S_TRC (0x03U << TIM_CCMR1_OUTPUT_CC1S_Pos) + +#define TIM_CCMR1_CC2S_OC (0x00U << TIM_CCMR1_OUTPUT_CC2S_Pos) +#define TIM_CCMR1_CC2S_DirectTI (0x01U << TIM_CCMR1_OUTPUT_CC2S_Pos) +#define TIM_CCMR1_CC2S_IndirectTI (0x02U << TIM_CCMR1_OUTPUT_CC2S_Pos) +#define TIM_CCMR1_CC2S_TRC (0x03U << TIM_CCMR1_OUTPUT_CC2S_Pos) + +/** + * @brief TIM_Output_Compare_Preload_State + */ +#define TIM_OCPreload_Disable (0x00U << TIM_CCMR1_OUTPUT_OC1PE_Pos) /*!< TIM output compare preload disable */ +#define TIM_OCPreload_Enable (0x01U << TIM_CCMR1_OUTPUT_OC1PE_Pos) /*!< TIM output compare preload enable */ + +/** + * @brief TIM_Output_Compare_Clear_State + */ +#define TIM_OCClear_Disable (0x00U << TIM_CCMR1_OUTPUT_OC1CE_Pos) /*!< TIM Output clear disable */ +#define TIM_OCClear_Enable (0x01U << TIM_CCMR1_OUTPUT_OC1CE_Pos) /*!< TIM Output clear enable */ + +/** + * @brief TIM_Output_Compare_Fast_State + */ +#define TIM_OCFast_Disable (0x00U << TIM_CCMR1_OUTPUT_OC1FE_Pos) /*!< TIM output compare fast disable */ +#define TIM_OCFast_Enable (0x01U << TIM_CCMR1_OUTPUT_OC1FE_Pos) /*!< TIM output compare fast enable */ + +/** + * @brief TIM_Capture_Compare_state + */ +#define TIM_CCx_Disable (0x00U << TIM_CCER_CC1E_Pos) /*!< Capture/Compare Enable */ +#define TIM_CCx_Enable (0x01U << TIM_CCER_CC1E_Pos) /*!< Capture/Compare Enable */ + +/** + * @brief TIM_Capture_Compare_N_state + */ +#define TIM_CCxN_Disable (0x00U << TIM_CCER_CC1NE_Pos) /*!< Capture/Compare N Enable */ +#define TIM_CCxN_Enable (0x01U << TIM_CCER_CC1NE_Pos) /*!< Capture/Compare N Enable */ + +/** + * @brief TIM_Update_Source + */ +#define TIM_UpdateSource_Global (0x00U << TIM_CR1_URS_Pos) /*!< Source of update is counter overflow/underflow. */ +#define TIM_UpdateSource_Regular (0x01U << TIM_CR1_URS_Pos) /*!< Source of update is the counter overflow/underflow + or the setting of UG bit, or an update generation + through the slave mode controller. */ + +/** + * @brief TIM_One_Pulse_Mode + */ +#define TIM_OPMode_Repetitive (0x00U << TIM_CR1_OPM_Pos) /*!< Counter is not stopped at update event */ +#define TIM_OPMode_Single (0x01U << TIM_CR1_OPM_Pos) /*!< Counter stops counting at the next update event (clearing the bit CEN) */ + +/** + * @brief TIM_Trigger_Output_Source + */ +#define TIM_TRIGSource_Reset (0x00U << TIM_CR2_MMS_Pos) /*!< The UG bit in the TIM_EGR register is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_Enable (0x01U << TIM_CR2_MMS_Pos) /*!< The Counter Enable CEN is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_Update (0x02U << TIM_CR2_MMS_Pos) /*!< The update event is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_OC1 (0x03U << TIM_CR2_MMS_Pos) /*!< The trigger output sends a positive pulse when the CC1IF flag */ +#define TIM_TRIGSource_OC1REF (0x04U << TIM_CR2_MMS_Pos) /*!< OC1REF signal is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_OC2REF (0x05U << TIM_CR2_MMS_Pos) /*!< OC2REF signal is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_OC3REF (0x06U << TIM_CR2_MMS_Pos) /*!< OC3REF signal is used as the trigger output (TRIG). */ +#define TIM_TRIGSource_OC4REF (0x07U << TIM_CR2_MMS_Pos) /*!< OC4REF signal is used as the trigger output (TRIG). */ + +/** + * @brief TIM_Slave_Mode + */ +#define TIM_SlaveMode_Reset (0x04U << TIM_SMCR_SMS_Pos) /*!< Rising edge of the selected trigger signal (TRGI) re-initializes */ +#define TIM_SlaveMode_Gated (0x05U << TIM_SMCR_SMS_Pos) /*!< The counter clock is enabled when the trigger signal (TRGI) is high. */ +#define TIM_SlaveMode_Trigger (0x06U << TIM_SMCR_SMS_Pos) /*!< The counter starts at a rising edge of the trigger TRGI. */ +#define TIM_SlaveMode_External1 (0x07U << TIM_SMCR_SMS_Pos) /*!< Rising edges of the selected trigger (TRGI) clock the counter. */ + +/** + * @brief TIM_Master_Slave_Mode + */ +#define TIM_MasterSlaveMode_Disable (0x00U << TIM_SMCR_MSM_Pos) /*!< No action */ +#define TIM_MasterSlaveMode_Enable (0x01U << TIM_SMCR_MSM_Pos) /*!< synchronization between the current timer and its slaves (through TRIG) */ + +/** + * @brief TIM_Flags + */ +#define TIM_FLAG_Update (0x01U << TIM_SR_UIF_Pos) /*!< TIM update Flag */ +#define TIM_FLAG_CC1 (0x01U << TIM_SR_CC1IF_Pos) /*!< TIM Capture Compare 1 Flag */ +#define TIM_FLAG_CC2 (0x01U << TIM_SR_CC2IF_Pos) /*!< TIM Capture Compare 2 Flag */ +#define TIM_FLAG_CC3 (0x01U << TIM_SR_CC3IF_Pos) /*!< TIM Capture Compare 3 Flag */ +#define TIM_FLAG_CC4 (0x01U << TIM_SR_CC4IF_Pos) /*!< TIM Capture Compare 4 Flag */ +#define TIM_FLAG_COM (0x01U << TIM_SR_COMIF_Pos) /*!< TIM Commutation Flag */ +#define TIM_FLAG_Trigger (0x01U << TIM_SR_TIF_Pos) /*!< TIM Trigger Flag */ +#define TIM_FLAG_Break (0x01U << TIM_SR_BIF_Pos) /*!< TIM Break Flag */ +#define TIM_FLAG_CC1OF (0x01U << TIM_SR_CC1OF_Pos) /*!< TIM Capture Compare 1 overcapture Flag */ +#define TIM_FLAG_CC2OF (0x01U << TIM_SR_CC2OF_Pos) /*!< TIM Capture Compare 2 overcapture Flag */ +#define TIM_FLAG_CC3OF (0x01U << TIM_SR_CC3OF_Pos) /*!< TIM Capture Compare 3 overcapture Flag */ +#define TIM_FLAG_CC4OF (0x01U << TIM_SR_CC4OF_Pos) /*!< TIM Capture Compare 4 overcapture Flag */ + +/** + * @brief PWM phase shift and DMA repeat update + */ +#define TIM_PDER_CCR1SHIFTEN (0x01U << TIM_PDER_CCR1_SHIFT_EN_Pos) /*!< TIM Channel 1 output PWM phase shift enable bit */ +#define TIM_PDER_CCR2SHIFTEN (0x01U << TIM_PDER_CCR2_SHIFT_EN_Pos) /*!< TIM Channel 2 output PWM phase shift enable bit */ +#define TIM_PDER_CCR3SHIFTEN (0x01U << TIM_PDER_CCR3_SHIFT_EN_Pos) /*!< TIM Channel 3 output PWM phase shift enable bit */ +#define TIM_PDER_CCR4SHIFTEN (0x01U << TIM_PDER_CCR4_SHIFT_EN_Pos) /*!< TIM Channel 4 output PWM phase shift enable bit */ +#define TIM_PDER_CCR5SHIFTEN (0x01U << TIM_PDER_CCR5_SHIFT_EN_Pos) /*!< TIM Channel 5 output PWM phase shift enable bit */ + +/** @defgroup TIM_TIx_External_Clock_Source + * @{ + */ +#define TIM_TIxExternalCLK1Source_TI1 ((uint16_t)0x0050) +#define TIM_TIxExternalCLK1Source_TI2 ((uint16_t)0x0060) +#define TIM_TIxExternalCLK1Source_TI1ED ((uint16_t)0x0040) + +/** @defgroup TIM_External_Trigger_Prescaler + * @{ + */ + +#define TIM_ExtTRGPSC_OFF (0x00U << TIM_SMCR_ETPS_Pos) +#define TIM_ExtTRGPSC_DIV2 (0x01U << TIM_SMCR_ETPS_Pos) +#define TIM_ExtTRGPSC_DIV4 (0x02U << TIM_SMCR_ETPS_Pos) +#define TIM_ExtTRGPSC_DIV8 (0x03U << TIM_SMCR_ETPS_Pos) + +/** @defgroup TIM_External_Trigger_Polarity + * @{ + */ +#define TIM_ExtTRGPolarity_Inverted (0x01U << TIM_SMCR_ETP_Pos) +#define TIM_ExtTRGPolarity_NonInverted (0x00U << TIM_SMCR_ETP_Pos) + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void TIM_DeInit(TIM_Type *tim); + +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef *init_struct); +void TIM_TimeBaseInit(TIM_Type *tim, TIM_TimeBaseInitTypeDef *init_struct); + +void TIM_OCStructInit(TIM_OCInitTypeDef *init_struct); +void TIM_OC1Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct); +void TIM_OC2Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct); +void TIM_OC3Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct); +void TIM_OC4Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct); + +void TIM_SetIC1Prescaler(TIM_Type *tim, uint32_t psc); +void TIM_SetIC2Prescaler(TIM_Type *tim, uint32_t psc); +void TIM_SetIC3Prescaler(TIM_Type *tim, uint32_t psc); +void TIM_SetIC4Prescaler(TIM_Type *tim, uint32_t psc); +void TIM_ICStructInit(TIM_ICInitTypeDef *init_struct); +void TIM_ICInit(TIM_Type *tim, TIM_ICInitTypeDef *init_struct); +void TIM_PWMIConfig(TIM_Type *tim, TIM_ICInitTypeDef *init_struct); +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef *init_struct); +void TIM_BDTRConfig(TIM_Type *tim, TIM_BDTRInitTypeDef *init_struct); +void TIM_CtrlPWMOutputs(TIM_Type *tim, FunctionalState state); + +void TIM_Cmd(TIM_Type *tim, FunctionalState state); + +void TIM_ITConfig(TIM_Type *tim, uint32_t it, FunctionalState state); +void TIM_GenerateEvent(TIM_Type *tim, uint32_t source); + +void TIM_InternalClockConfig(TIM_Type *tim); +void TIM_ITRxExternalClockConfig(TIM_Type *tim, uint32_t source); + +void TIM_SelectInputTrigger(TIM_Type *tim, uint16_t source); + +void TIM_PrescalerConfig(TIM_Type *tim, uint16_t prescaler, uint16_t reloadMode); +void TIM_CounterModeConfig(TIM_Type *tim, uint32_t counter_mode); + +void TIM_EncoderInterfaceConfig(TIM_Type *tim, uint32_t encoder_mode, uint32_t ic1_polarity, uint32_t ic2_polarity); +void TIM_ForcedOC1Config(TIM_Type *tim, uint32_t forced_action); +void TIM_ForcedOC2Config(TIM_Type *tim, uint32_t forced_action); +void TIM_ForcedOC3Config(TIM_Type *tim, uint32_t forced_action); +void TIM_ForcedOC4Config(TIM_Type *tim, uint32_t forced_action); + +void TIM_ClearOC1Ref(TIM_Type *tim, uint16_t TIM_OCClear); +void TIM_ClearOC2Ref(TIM_Type *tim, uint16_t TIM_OCClear); +void TIM_ClearOC3Ref(TIM_Type *tim, uint16_t TIM_OCClear); +void TIM_ClearOC4Ref(TIM_Type *tim, uint16_t TIM_OCClear); + +void TIM_ARRPreloadConfig(TIM_Type *tim, FunctionalState state); +void TIM_SelectCOM(TIM_Type *tim, FunctionalState state); +void TIM_SelectCCDMA(TIM_Type *tim, FunctionalState state); +void TIM_CCPreloadControl(TIM_Type *tim, FunctionalState state); + +void TIM_OC1PreloadConfig(TIM_Type *tim, uint32_t preload); +void TIM_OC2PreloadConfig(TIM_Type *tim, uint32_t preload); +void TIM_OC3PreloadConfig(TIM_Type *tim, uint32_t preload); +void TIM_OC4PreloadConfig(TIM_Type *tim, uint32_t preload); + +void TIM_OC1FastConfig(TIM_Type *tim, uint32_t fast); +void TIM_OC2FastConfig(TIM_Type *tim, uint32_t fast); +void TIM_OC3FastConfig(TIM_Type *tim, uint32_t fast); +void TIM_OC4FastConfig(TIM_Type *tim, uint32_t fast); + +void TIM_OC1PolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC1NPolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC2PolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC2NPolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC3PolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC3NPolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC4PolarityConfig(TIM_Type *tim, uint32_t polarity); +void TIM_OC4NPolarityConfig(TIM_Type *tim, uint32_t polarity); + +void TIM_CCxCmd(TIM_Type *tim, uint16_t channel, uint32_t ccx_en); +void TIM_CCxNCmd(TIM_Type *tim, uint16_t channel, uint32_t ccxn_en); + +void TIM_SelectOCxM(TIM_Type *tim, uint16_t channel, uint32_t mode); +void TIM_SetCompare1(TIM_Type *tim, uint32_t compare); +void TIM_SetCompare2(TIM_Type *tim, uint32_t compare); +void TIM_SetCompare3(TIM_Type *tim, uint32_t compare); +void TIM_SetCompare4(TIM_Type *tim, uint32_t compare); + +void TIM_ASYMEN_Cmd(TIM_Type *tim, FunctionalState state); +void TIM_SetDownCompare1(TIM_Type *tim, uint32_t compare); +void TIM_SetDownCompare2(TIM_Type *tim, uint32_t compare); +void TIM_SetDownCompare3(TIM_Type *tim, uint32_t compare); +void TIM_SetDownCompare4(TIM_Type *tim, uint32_t compare); + +void TIM_UpdateDisableConfig(TIM_Type *tim, FunctionalState state); +void TIM_UpdateRequestConfig(TIM_Type *tim, uint32_t source); +void TIM_SelectHallSensor(TIM_Type *tim, FunctionalState state); +void TIM_SelectOnePulseMode(TIM_Type *tim, uint32_t mode); +void TIM_SelectOutputTrigger(TIM_Type *tim, uint32_t source); + +void TIM_SelectSlaveMode(TIM_Type *tim, uint32_t mode); +void TIM_SelectMasterSlaveMode(TIM_Type *tim, uint32_t mode); + +void TIM_SetAutoreload(TIM_Type *tim, uint16_t auto_reload); +void TIM_SetCounter(TIM_Type *tim, uint32_t counter); + +void TIM_SetClockDivision(TIM_Type *tim, uint32_t clock_div); + +uint32_t TIM_GetCapture1(TIM_Type *tim); +uint32_t TIM_GetCapture2(TIM_Type *tim); +uint32_t TIM_GetCapture3(TIM_Type *tim); +uint32_t TIM_GetCapture4(TIM_Type *tim); + +uint32_t TIM_GetCounter(TIM_Type *tim); +uint16_t TIM_GetPrescaler(TIM_Type *tim); + +FlagStatus TIM_GetFlagStatus(TIM_Type *tim, uint32_t flag); +void TIM_ClearFlag(TIM_Type *tim, uint32_t flag); +ITStatus TIM_GetITStatus(TIM_Type *tim, uint32_t it); +void TIM_ClearITPendingBit(TIM_Type *tim, uint32_t it); + +void TIM_PWMShiftConfig(TIM_Type *tim, uint32_t it, FunctionalState state); +void TIM_SetCCR1FALL(TIM_Type *tim, uint32_t shift); +void TIM_SetCCR2FALL(TIM_Type *tim, uint32_t shift); +void TIM_SetCCR3FALL(TIM_Type *tim, uint32_t shift); +void TIM_SetCCR4FALL(TIM_Type *tim, uint32_t shift); + +FlagStatus TIM_GetCountDirection(TIM_Type *tim); +uint32_t TIM_GetTIMxClock(TIM_Type *tim); + +void TIM_ETRClockMode1Config(TIM_Type *tim, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); +void TIM_ETRClockMode2Config(TIM_Type* TIMx, uint16_t TIM_ExtTRGPrescaler,uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter); +void TIM_TIxExternalClockConfig(TIM_Type *TIMx, uint16_t TIM_TIxExternalCLKSource, uint16_t TIM_ICPolarity, uint16_t ICFilter); +void TIM_ETRConfig(TIM_Type *tim, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_uart.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_uart.h new file mode 100644 index 0000000..d3ef924 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_uart.h @@ -0,0 +1,286 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_uart.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + +#ifndef __hal_uart_H_wrM7moXg_lQUd_HTJv_sOBv_uu2tvbtzutNR__ +#define __hal_uart_H_wrM7moXg_lQUd_HTJv_sOBv_uu2tvbtzutNR__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +typedef enum +{ + UART_ERR_OK = 0, + UART_ERR_NULL_POINTER, + +} UART_ErrTypeDef; + +/** + * UART Word Length + */ +typedef enum +{ + UART_WordLength_8b = (UART_CR_MODE_8D << UART_CR_MODE_Pos), + UART_WordLength_8b1P = (UART_CR_MODE_8D1P << UART_CR_MODE_Pos), + UART_WordLength_9b = (UART_CR_MODE_9D << UART_CR_MODE_Pos), + +} UART_WordLengthTypeDef; + + +/** + * UART Stop Bits + */ +typedef enum +{ + UART_StopBits_1 = (UART_CR_STOPB_1B << UART_CR_STOPB_Pos), + UART_StopBits_2 = (UART_CR_STOPB_2B << UART_CR_STOPB_Pos), +} UART_StopBitsTypeDef; + + +/** + * UART Parity + */ +typedef enum +{ + UART_Parity_No = (UART_CR_PAR_EVEN << UART_CR_PAR_Pos), + UART_Parity_Even = (UART_CR_PAR_EVEN << UART_CR_PAR_Pos), + UART_Parity_Odd = (UART_CR_PAR_ODD << UART_CR_PAR_Pos), +} UART_ParityTypeDef; + + +/** + * UART Mode + */ +typedef enum +{ + UART_Mode_Tx = 0, + UART_Mode_TxRx = UART_CR_RXEN_Msk, + +} UART_ModeTypeDef; + +typedef enum +{ + /* tx type */ + UART_IT_TX_FIFO_EMPTY = UART_IE_TXEE_Msk, + UART_IT_TX_FIFO_FULL = UART_IE_TXFE_Msk, + UART_IT_TX_FIFO_HEMPTY = UART_IE_TXHEE_Msk, // Half-Empty + UART_IT_TX_DONE = UART_IE_TXENDE_Msk, + + /* rx type */ + UART_IT_RX_FIFO_NO_EMPTY = UART_IE_RXNEE_Msk, + UART_IT_RX_FIFO_FULL = UART_IE_RXFE_Msk, + UART_IT_RX_FIFO_HFULL = UART_IE_RXHFE_Msk, // Half-Full + + /* error type */ + #if 1 + UART_IT_ERR = (UART_IE_PERRE_Msk | UART_IE_FERRE_Msk | UART_IE_OVERRE_Msk | \ + UART_IE_TONEE_Msk | UART_IE_TOIDLEE_Msk) + #else + UART_IT_ERR_PARITY = UART_IE_PERRE_Msk, + UART_IT_ERR_FRAME = UART_IE_FERRE_Msk, + UART_IT_ERR_OVERFLOW = UART_IE_OVERRE_Msk, + UART_IT_ERR_CLR_FIFO_TIMEOUT = UART_IE_TONEE_Msk, + UART_IT_ERR_IDLE_TIMEOUT = UART_IE_TOIDLEE_Msk, + #endif + +} UART_ITTypeDef; + + +/** + * UART_Flags + */ +typedef enum +{ + UART_FLAG_RXNE = UART_SR_RXNE_Msk, /*!< Read data register not empty */ + UART_FLAG_TXE = UART_SR_TXE_Msk, /*!< Transmit data register Empty */ + UART_FLAG_TXHE = UART_SR_TXHE_Msk, /*!< Transmit data register half Empty */ + UART_FLAG_PERR = UART_SR_PERR_Msk, /*!< Parity error */ + UART_FLAG_FERR = UART_SR_FERR_Msk, /*!< Framing error */ + UART_FLAG_OVERR = UART_SR_OVERR_Msk, /*!< Overrun error */ + UART_FLAG_TONE = UART_SR_TONE_Msk, /*!< TONE Interrupt enable */ + UART_FLAG_TOIDLE = UART_SR_TOIDLE_Msk, /*!< TOIDLE interrupt enable */ + UART_FLAG_RXHF = UART_SR_RXHF_Msk, /*!< Read data register half empty */ + UART_FLAG_RXF = UART_SR_RXF_Msk, /*!< Read data register empty */ + UART_FLAG_TXEND = UART_SR_TXEND_Msk, /*!< TXEND interrupt enable */ + UART_FLAG_TXF = UART_SR_TXF_Msk, /*!< TXF interrupt enable */ +} UART_FlagTypeDef; + +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Uart reset/clear reception FIFO + * + * \param [in] pHUart Pointer to a UART handle + * \return + * None + */ +__STATIC_FORCEINLINE void UART_ResetRxFIFO(UART_Type *pHUart) +{ + REG_WRITE(pHUart->RXFR, 0xe930); + return; +} + +/** + * \brief Uart reset/clear transmission FIFO + * + * \param [in] pHUart Pointer to a UART handle + * \return + * None + */ +__STATIC_FORCEINLINE void UART_ResetTxFIFO(UART_Type *pHUart) +{ + REG_WRITE(pHUart->TXFR, 0xe930); + return; +} + +/** + * \brief Start UART module + * + * \param [in] pHUart Pointer to a UART handle + * \return + * None + */ +__STATIC_FORCEINLINE void UART_Start(UART_Type *pHUart) +{ + REG_SET_BITS(pHUart->CR, UART_CR_RUN_Msk); + return; +} + +/** + * \brief Stop UART module + * + * \param [in] pHUart Pointer to a UART handle + * \return + * + */ +__STATIC_FORCEINLINE void UART_Stop(UART_Type *pHUart) +{ + REG_CLR_BITS(pHUart->CR, UART_CR_RUN_Msk); + return; +} + +/** + * \brief Wait UART module Tx FIFO empty + * + * \param [in] pHUart Pointer to a UART handle + * \return + * None + */ +__STATIC_FORCEINLINE void UART_WaitTxFifoEmpty(UART_Type *pHUart) +{ + while( !REG_READ_MASK(pHUart->SR, UART_SR_TXE_Msk) ); + + return; +} + +/** + * \brief Get the interrupt status + * + * \param [in] pHUart Pointer to a UART handle + * \param [in] flags The target interrupt types, @ref UART_ITTypeDef + * \return + * status, @ref UART_ITTypeDef + */ +__STATIC_FORCEINLINE uint32_t UART_GetITStatus(UART_Type *pHUart, uint32_t flags) +{ + return REG_READ_MASK(pHUart->SR, flags); +} + +/** + * \brief Get the status of UART + * + * \param [in] pHUart Pointer to a UART handle + * \param [in] flags The specifies flags to check, @ref UART_FlagTypeDef + * \return + * The new state of flags (SET or RESET) + */ +__STATIC_FORCEINLINE FlagStatus UART_GetFlagStatus(UART_Type *pHUart, UART_FlagTypeDef flags) +{ + return (pHUart->SR & flags) ? SET : RESET; +} +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct +{ + uint32_t BaudRate; + UART_WordLengthTypeDef WordLength; + UART_StopBitsTypeDef StopBits; + UART_ParityTypeDef Parity; + UART_ModeTypeDef Mode; + +} UART_InitTypeDef; +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Initialize UART module + * + * \param [in] pHUart Pointer to a UART handle + * \param [in] pInit Pointer to a init structure, @ref UART_InitTypeDef + * \return + * Error number, @ref UART_ErrTypeDef + */ +UART_ErrTypeDef UART_Init(UART_Type *pHUart, UART_InitTypeDef *pInit); + +/** + * \brief Send data througn UART module + * + * \param [in] pHUart Pointer to a UART handle + * \param [in] value the sent data + * \return + * None + */ +void UART_SendData(UART_Type *pHUart, uint16_t value); + +/** + * \brief Receive data through UART module + * + * \param [in] pHUart Pointer to a UART handle + * \return + * received data + */ +uint16_t UART_ReceiveData(UART_Type *pHUart); + +/** + * \brief Configure the interrupts of UART module + * + * \param [in] pHUart Pointer to a UART handle + * \param [in] flags The target interrupt types, @ref UART_ITTypeDef + * \param [in] is_enable enable or disable interrupts (0: disable, others: enable) + * \return + * Error number, @ref UART_ErrTypeDef + */ +UART_ErrTypeDef UART_ITConfig(UART_Type *pHUart, uint32_t flags, uint32_t is_enable); + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_wdg.h b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_wdg.h new file mode 100644 index 0000000..99e4ae9 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/inc/hal_wdg.h @@ -0,0 +1,249 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_wdg.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + +#ifndef __hal_wdg_H_wI4mp2FJ_l3m6_H3ua_sohm_ufSbFzwpuIAH__ +#define __hal_wdg_H_wI4mp2FJ_l3m6_H3ua_sohm_ufSbFzwpuIAH__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_def.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * The reset mode of the WatchDog + */ +typedef enum WDG_Reset +{ + WDG_Reset_Disable = 0x0ul, + WDG_Reset_Enable = WDG_CR_RSTE_Msk, /*!< WatchDog trigger system reset if timeout */ +} WDG_ResetTypeDef; +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Lock/Unlonk the WatchDog accessing + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_Lock(void) +{ + REG_WRITE(WDG->LOCK, 0x930ul); + return; +} + +__STATIC_FORCEINLINE void WDG_Unlock(void) +{ + REG_WRITE(WDG->LOCK, 0x1ACCE551ul); + return; +} + +/** + * \brief Enable/Disable the WatchDog + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_Enable(void) +{ + WDG_Unlock(); + REG_SET_BITS(WDG->CR, WDG_CR_INTE_Msk); + WDG_Lock(); + return; +} + +__STATIC_FORCEINLINE void WDG_Disable(void) +{ + WDG_Unlock(); + REG_CLR_BITS(WDG->CR, WDG_CR_INTE_Msk); + WDG_Lock(); + return; +} + +/** + * \brief Set the counter value of the WatchDog + * + * \param [in] Counter the specific counter value (32-bits) of the WDG + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_SetCounter(uint32_t Counter) +{ + REG_WRITE(WDG->LOAD, Counter); + REG_WRITE(WDG->INTCLR, 0x1ul); + return; +} + +/** + * \brief Get the counter value of the WatchDog + * + * \return + * the counter value of the WatchDog + */ +__STATIC_FORCEINLINE uint32_t WDG_GetCounter(void) +{ + return REG_READ(WDG->VALUE); +} + +/** + * \brief Enable interrupt function of the WatchDog + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_ITEnable(void) +{ + sys_open_IRQ(WDG_IRQn); + sys_enable_girq(); + return; +} + +/** + * \brief Disable interrupt function of the WatchDog + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_ITDisable(void) +{ + sys_close_IRQ(WDG_IRQn); + return; +} + +/** + * \brief Get the timeout status of the WatchDog + * + * \return + * 0: No timeout + * other: timeout happened + */ +__STATIC_FORCEINLINE uint32_t WDG_GetStatusFlag(void) +{ + return REG_READ_MASK(WDG->RIS, WDG_RIS_RIF_Msk); +} + +/** + * \brief Clear the flag of interrupt of the WatchDog + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_ClearITFlag(void) +{ + if( !REG_READ_MASK(WDG->CR, WDG_CR_RSTE_Msk) ) + { + WDG_Unlock(); + REG_WRITE(WDG->INTCLR, 0x1ul); + WDG_Lock(); + } + return; +} + +/** + * \brief Extend timeout of the WatchDog + * + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_Kick(void) +{ + WDG_Unlock(); + REG_WRITE(WDG->INTCLR, 0x1ul); + WDG_Lock(); + return; +} + +/** + * \brief Enable/Disable debug mode of the WatchDog + * ps. WatchDog stop to conunt when enable debug mode + * + * \param [in] is_debug_mode enable debug mode or not + * \return + * None + */ +__STATIC_FORCEINLINE void WDG_DebugMode(int is_debug_mode) +{ + (is_debug_mode) + ? REG_SET_BITS(WDG->CR, WDG_CR_DBGE_Msk) + : REG_CLR_BITS(WDG->CR, WDG_CR_DBGE_Msk); + return; +} + +/** + * \brief Convert the mille-seconds to counter value + * + * \param [in] msec Mille-second (max: 134217727) + * \return + * the counter value + */ +__STATIC_INLINE uint32_t WDG_MSec2Counter(uint32_t msec) +{ + return (((uint32_t)msec * 32ul) - 1ul); +} +//============================================================================= +// Structure Definition +//============================================================================= +typedef struct WDG_Init +{ + uint32_t Counter; /*!< Specifies the WatchDog counter value */ + WDG_ResetTypeDef ResetMode; /*!< Reset system or not when timeout, @ref WDG_ResetTypeDef */ +} WDG_InitTypeDef; + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +/** + * \brief Fills each WDG_InitTypeDef member with its default value. + * + * \param [in] pInit Pointer to a WatchDog initial structure, @ref WDG_InitTypeDef + * \return + * None + */ +void WDG_StructInit(WDG_InitTypeDef *pInit); + +/** + * \brief Initialize the WatchDog + * ps. Register-ISR MUST be after WDG_Init() + * + * \param [in] pInit Pointer to a WatchDog initial structure, @ref WDG_InitTypeDef + * \return + * None + */ +void WDG_Init(WDG_InitTypeDef *pInit); + +/** + * \brief De-initialize the WatchDog + * + * \return + * None + */ +void WDG_DeInit(void); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_adc.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_adc.c new file mode 100644 index 0000000..9f7e668 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_adc.c @@ -0,0 +1,302 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_adc.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_ADC) +//============================================================================= +// Constant Definition +//============================================================================= +#define ADC_TIMEOUT_CNT (60*1000*10) + +#define ADC_ALL_CHANNELS_Msk (0xFFFF) + +#define ADC_MAX_WORK_CLK (16*1000*1000) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void ADC_DeInit(ADC_Type *pHADC) +{ + __HAL_SYSCFG_RESET_ADC(); + __HAL_SYSCFG_ADC_CLK_DISABLE(); + + return; +} + +void ADC_Init(ADC_Type *pHADC, ADC_InitTypeDef *pInit) +{ + /* Enable ADC Controller */ + __HAL_SYSCFG_ADC_CLK_ENABLE(); + __HAL_SYSCFG_RESET_ADC(); + + if( pInit->ClkPrescaler == ADC_ClkDiv_Auto ) + { + /** + * The max working clock of ADC is 16-MHz (min 800KHz). + * Auto-Calculate the fastest ADC working clock at the current system clock + */ + uint32_t divider = 0; + + divider = (g_SystemCoreClock + (ADC_MAX_WORK_CLK - 1)) / ADC_MAX_WORK_CLK; + pInit->ClkPrescaler = (divider <= 2) ? ADC_ClkDiv_2 : + (divider <= 4) ? ADC_ClkDiv_4 : + ADC_ClkDiv_8; + } + + /** + * + When change ADC working clock, it should wait 20-cycles + * + Enable Analog Physical Module + * Clear_Bits(ADC_CON0_PWD_Msk | ADC_CON0_RST_Msk) + * + Enable ADC (ADC_START MUST wait 32-cycles after enable) + */ + REG_WRITE_MASK(pHADC->CON0, + ADC_CON0_CLK_Msk | ADC_CON0_PWD_Msk | ADC_CON0_RST_Msk | ADC_CON0_EN_Msk, + pInit->ClkPrescaler | ADC_CON0_EN_Msk); + sys_busy_wait(100); + + REG_CLR_BITS(pHADC->CHSEL, ADC_CHSEL_DISCEN_Msk); + REG_CLR_BITS(pHADC->STAT, ADC_STAT_EOC_CHECK_DIS_Msk); + + if( pInit->Mode == ADC_Mode_SingleConv ) + { + /** + * CONTINUE | ENCONT | DISCEN + * 0 | 0 | 0 + */ + uint32_t channel_id = (31ul - HAL_CLZ(pInit->SelChannels)); + + REG_WRITE_MASK(pHADC->CON0, + ADC_CON0_M_Msk | \ + (ADC_CON0_CONTINUE_Msk | ADC_CON0_ENCONT_Msk) | \ + ADC_CON0_ALIGN_Msk, + (channel_id << ADC_CON0_M_Pos) | + 0x0ul | 0x0ul | + pInit->DataAlign); + } + else + { + int chnnl_cnt = 0; + uint32_t target_chnnls = (uint32_t)pInit->SelChannels; + + while( target_chnnls ) + { + int index = 31ul - HAL_CLZ(target_chnnls); + + target_chnnls &= ~(0x1ul << index); + chnnl_cnt++; + } + + switch( pInit->Mode ) + { + default: + return; + break; + + case ADC_Mode_Continuous: + /** + * Never Stop Conversion and + * NOT support interrupt (Done-Flag will always be 0) + * + * CONTINUE | ENCONT | DISCEN + * 1 | 1 | 0 + */ + REG_WRITE_MASK(pHADC->CON0, + (ADC_CON0_CONTINUE_Msk | ADC_CON0_ENCONT_Msk) | \ + ADC_CON0_ALIGN_Msk, + ADC_CON0_CONTINUE_Msk | ADC_CON0_ENCONT_Msk | + pInit->DataAlign); + + REG_SET_BITS(pHADC->STAT, ADC_STAT_EOC_CHECK_DIS_Msk); + REG_WRITE_MASK(pHADC->CHSEL, ADC_CHSEL_CH_SEL_Msk, pInit->SelChannels); + break; + + case ADC_Mode_Scan: + /** + * CONTINUE | ENCONT | DISCEN + * 1 | 0 | 0 + */ + REG_WRITE_MASK(pHADC->CON0, + (ADC_CON0_CONTINUE_Msk | ADC_CON0_ENCONT_Msk) | \ + ADC_CON0_ALIGN_Msk, + ADC_CON0_CONTINUE_Msk | 0x0ul | + pInit->DataAlign); + + REG_WRITE_MASK(pHADC->CHSEL, + ADC_CHSEL_CH_SEL_Msk | ADC_CHSEL_DISCEN_Msk | ADC_CHSEL_CH_CNT_Msk, + pInit->SelChannels | 0x0ul | (chnnl_cnt - 1) << ADC_CHSEL_CH_CNT_Pos); + break; + + case ADC_Mode_Discontinuous: + /** + * CONTINUE | ENCONT | DISCEN + * 1 | 0 | 1 + */ + REG_WRITE_MASK(pHADC->CON0, + (ADC_CON0_CONTINUE_Msk | ADC_CON0_ENCONT_Msk) | \ + ADC_CON0_ALIGN_Msk, + ADC_CON0_CONTINUE_Msk | 0x0ul | + pInit->DataAlign); + + REG_WRITE_MASK(pHADC->CHSEL, + ADC_CHSEL_CH_SEL_Msk | ADC_CHSEL_DISCEN_Msk | \ + ADC_CHSEL_CH_CNT_Msk | ADC_CHSEL_DISCNUM_Msk, + pInit->SelChannels | ADC_CHSEL_DISCEN_Msk | + (chnnl_cnt - 1) << ADC_CHSEL_CH_CNT_Pos); + break; + } + } + + + (pInit->IsSoftTrig == true) ? + REG_CLR_BITS(pHADC->CON0, ADC_CON0_TRIG_EN_Msk) : + REG_SET_BITS(pHADC->CON0, ADC_CON0_TRIG_EN_Msk); + + return; +} + +void ADC_StructInit(ADC_InitTypeDef *pInit) +{ + pInit->SelChannels = ADC_Channel_AVSS; + pInit->ClkPrescaler = ADC_ClkDiv_Auto; + pInit->DataAlign = ADC_DataAlign_Right; + pInit->Mode = ADC_Mode_SingleConv; + pInit->IsSoftTrig = true; + return; +} + + +void ADC_ExtTrigConfig(ADC_Type *pHADC, ADC_ExtTrigSourceTypeDef ext_src, ADC_ExtTrigModeTypeDef trig_mode) +{ + if( ext_src == ADC_ExtTrigSource_Soft ) + { + REG_CLR_BITS(pHADC->CON0, ADC_CON0_TRIG_EN_Msk); + } + else + { + int shift = (ext_src & 0xF) << 1; + + REG_SET_BITS(pHADC->CON0, ADC_CON0_TRIG_EN_Msk); + + if( ext_src & 0x10 ) + { + uint32_t pin_sel = 0; + + /* TRIG_SEL17 rising/falling configuraion */ + pin_sel = (((ext_src & 0x20ul) >> 4) | ((trig_mode >> 1) & 0x1ul)) << ADC_CHSEL_EXTRIG_SEL_Pos; + + REG_WRITE_MASK(pHADC->CHSEL, + (0x3ul << shift) | ADC_CHSEL_EXTRIG_SEL_Msk, + ((trig_mode & 0x1ul) << shift) | pin_sel); + } + else + { + REG_WRITE_MASK(pHADC->TRGSEL, ADC_TRGSEL_TRIG_SEL0_Msk << shift, (trig_mode & 0x1ul) << shift); + } + } + return; +} + +/** + * \brief Select the sub-channel of the ADC Channel-15 + * + * \param [in] subchannel The selected sub-channel of ADC channel-15, @ref ADC_SubChannelTypeDef + * \return + * None + */ +void ADC_SelSubChannel(ADC_SubChannelTypeDef subchannel) +{ + AMISC_InternalSrcTypeDef src_type = AMISC_InternalSrc_NONE; + + src_type = (subchannel == ADC_SubChannel_TEMP) ? AMISC_InternalSrc_TEMP : + (subchannel == ADC_SubChannel_DAC0) ? AMISC_InternalSrc_DAC0 : + (subchannel == ADC_SubChannel_DAC1) ? AMISC_InternalSrc_DAC1 : + (subchannel == ADC_SubChannel_VBuf_1_5) ? AMISC_InternalSrc_VBuf_1P5V : + (subchannel == ADC_SubChannel_VDDL) ? AMISC_InternalSrc_VDDL : + (subchannel == ADC_SubChannel_VSS) ? AMISC_InternalSrc_VSS : + (subchannel == ADC_SubChannel_VDD) ? AMISC_InternalSrc_VDD : + AMISC_InternalSrc_NONE; + + AMISC_OutInternalSignalToIO(src_type, false); + + REG_SET_BITS(AMISC->ADC_AIN_CR, AMISC_ADC_AIN_CR_ANA2ADC_EN_Msk); + return; +} + +uint16_t ADC_GetChannelConvValue(ADC_Type *pHADC, ADC_ChannelsTypeDef channel) +{ + volatile uint32_t *pData = (volatile uint32_t*)&pHADC->DAT0; + int timeout = 0; + uint32_t chnnl_id = (31ul - HAL_CLZ(channel)); + + while( REG_READ_MASK(pHADC->CON0, ADC_CON0_ENCONT_Msk) == 0 && + REG_READ_MASK(pHADC->STAT, ADC_STAT_DONE_Msk) == 0 ) + { + if( timeout++ > ADC_TIMEOUT_CNT ) + return 0; + } + + pData += (chnnl_id & 0xFul); + return (uint16_t)((*pData) & 0xFFFFul); +} + +void ADC_ChannelThresholdConfig(ADC_Type *pHADC, ADC_ChannelsTypeDef channel, uint16_t threshold) +{ + volatile uint32_t *pReg = (volatile uint32_t*)&pHADC->DAT0; + uint32_t chnnl_id = (31ul - HAL_CLZ(channel)); + + pReg += (chnnl_id & 0xFul); + + REG_WRITE_MASK(*pReg, ADC_DAT0_CMPTH_Msk, (threshold << ADC_DAT0_CMPTH_Pos)); + return; +} + +void ADC_ITConfig(ADC_Type *pHADC, ADC_ITTypeDef it_types) +{ + REG_CLR_BITS(pHADC->CHSEL, ADC_CHSEL_DISC_INTSEL_Msk); + + if( it_types == ADC_IT_DISABLE ) + { + sys_close_IRQ(ADC0_IRQn); + REG_CLR_BITS(pHADC->CON0, ADC_CON0_INT_EN_Msk); + } + else + { + if( it_types == ADC_IT_CONV_GROUP_SUBSET ) + REG_SET_BITS(pHADC->CHSEL, ADC_CHSEL_DISC_INTSEL_Msk); + + REG_WRITE_MASK(pHADC->CON0, ADC_CON0_INT_EN_Msk, it_types); + sys_open_IRQ(ADC0_IRQn); + } + + return; +} + + + +#endif /* CONFIG_ENABLE_HAL_ADC */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_amisc.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_amisc.c new file mode 100644 index 0000000..048aab0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_amisc.c @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_amisc.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_AMISC) +//============================================================================= +// Constant Definition +//============================================================================= +#define AMISC_LVD_LVR_ENABLE_FLAGS (AMISC_LVD_LVR_CR_LVD_EN_Msk | AMISC_LVD_LVR_CR_LVR_EN_Msk | \ + AMISC_LVD_LVR_CR_LDO_LP_EN_Msk | AMISC_LVD_LVR_CR_TEMP_EN_Msk) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +AMISC_StatusTypeDef AMISC_Init(void) +{ + /* AMISC clock enable */ + __HAL_SYSCFG_AMISC_CLK_ENABLE(); + AMISC_SetHSIPwrSrc(AMISC_HSIPwrSrc_LowPower); + return AMISC_Status_OK; +} + +AMISC_StatusTypeDef AMISC_DeInit(uint32_t is_force) +{ + if( is_force || + (REG_READ_MASK(AMISC->DAC_CR, AMISC_DAC_CR_DAC0_EN_Msk | AMISC_DAC_CR_DAC1_EN_Msk) == 0 && + REG_READ_MASK(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_ENABLE_FLAGS) == 0 && + REG_READ_MASK(OPAMP0->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk) == 0 && + REG_READ_MASK(OPAMP1->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk) == 0) ) + { + /* AMISC clock disable */ + __HAL_SYSCFG_AMISC_CLK_DISABLE(); + return AMISC_Status_OK; + } + return AMISC_Status_Bypass; +} + +AMISC_StatusTypeDef AMISC_Reset(void) +{ + if( REG_READ_MASK(AMISC->DAC_CR, AMISC_DAC_CR_DAC0_EN_Msk | AMISC_DAC_CR_DAC1_EN_Msk) == 0 && + REG_READ_MASK(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_ENABLE_FLAGS) == 0 && + REG_READ_MASK(OPAMP0->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk) == 0 && + REG_READ_MASK(OPAMP1->PGA_CR, OPAMP_PGA_CR_PGA_EN_Msk) == 0 ) + { + /* AMISC reset */ + __HAL_SYSCFG_RESET_AMISC(); + AMISC_SetHSIPwrSrc(AMISC_HSIPwrSrc_LowPower); + return AMISC_Status_OK; + } + + return AMISC_Status_Error; +} + +AMISC_StatusTypeDef AMISC_LVD_LVR_Config(AMISC_LVDRInitTypeDef *pInit) +{ + REG_WRITE_MASK(AMISC->LVD_LVR_CR, + AMISC_LVD_LVR_CR_LVD_SEL_Msk | AMISC_LVD_LVR_CR_LVR_SEL_Msk | \ + AMISC_LVD_LVR_CR_LDO_LP_EN_Msk | AMISC_LVD_LVR_CR_TEMP_EN_Msk, + pInit->LVD_Voltage | pInit->LVR_Voltage | pInit->LVD_FuncModes); + + return AMISC_Status_OK; +} + +void AMISC_HSI_Disable(void) +{ + if( SYSCFG_GetSysClkType() == SYSCFG_ClkSrc_LSI ) + { + REG_WRITE(AMISC->HSI_CR, 0x80000000); + } + return; +} + +void AMISC_HSI_Enable(void) +{ + REG_WRITE(AMISC->HSI_CR, 0x01000000); + return; +} + +void AMISC_LSI_Disable(void) +{ + if( SYSCFG_GetSysClkType() != SYSCFG_ClkSrc_LSI ) + { + REG_WRITE(AMISC->LSI_CR, 0x80000000); + } + return; +} + +void AMISC_LSI_Enable(void) +{ + REG_WRITE(AMISC->LSI_CR, 0x01000000); + return; +} + +void AMISC_Sel_PGA_VinP_Src(AMISC_InternalSrcTypeDef src_type) +{ + AMISC_InternalSrcTypeDef VinP_Src = AMISC_InternalSrc_NONE; + + /* AMISC clock enable */ + __HAL_SYSCFG_AMISC_CLK_ENABLE(); + + VinP_Src = (src_type == AMISC_InternalSrc_NONE) + ? src_type : (AMISC_VBUF_CR_ANA2PGA_EN_Msk | src_type); + + switch( src_type ) + { + default: + break; + + case AMISC_InternalSrc_NONE: + break; + + case AMISC_InternalSrc_TEMP: + REG_SET_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_TEMP_EN_Msk); + break; + + case AMISC_InternalSrc_DAC0: + AMISC_DAC0_Enable(); + break; + case AMISC_InternalSrc_DAC1: + AMISC_DAC1_Enable(); + break; + case AMISC_InternalSrc_VBuf_1P5V: + REG_SET_BITS(AMISC->VBUF_CR, AMISC_VBUF_CR_VBUF_EN_Msk); + break; + } + + REG_WRITE_MASK(AMISC->VBUF_CR, + AMISC_VBUF_CR_ANA_SEL_Msk | AMISC_VBUF_CR_ANA2PGA_EN_Msk, + VinP_Src); + + sys_busy_wait(60*1000); + return; +} + +void AMISC_OutInternalSignalToIO(AMISC_InternalSrcTypeDef src_type, int has_output) +{ + uint32_t value = (has_output) + ? (src_type | AMISC_VBUF_CR_ANA2IO_EN_Msk) : src_type; + + /* AMISC clock enable */ + __HAL_SYSCFG_AMISC_CLK_ENABLE(); + + switch( src_type ) + { + default: + break; + + case AMISC_InternalSrc_NONE: + break; + + case AMISC_InternalSrc_TEMP: + REG_SET_BITS(AMISC->LVD_LVR_CR, AMISC_LVD_LVR_CR_TEMP_EN_Msk); + break; + + case AMISC_InternalSrc_DAC0: + AMISC_DAC0_Enable(); + break; + case AMISC_InternalSrc_DAC1: + AMISC_DAC1_Enable(); + break; + case AMISC_InternalSrc_VBuf_1P5V: + REG_SET_BITS(value, AMISC_VBUF_CR_VBUF_EN_Msk); + break; + } + + REG_WRITE_MASK(AMISC->VBUF_CR, + AMISC_VBUF_CR_ANA_SEL_Msk | AMISC_VBUF_CR_ANA2IO_EN_Msk | AMISC_VBUF_CR_VBUF_EN_Msk, + value); + + sys_busy_wait(60*1000); + return; +} + + +#endif /* CONFIG_ENABLE_HAL_AMISC */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_comp.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_comp.c new file mode 100644 index 0000000..47ff3f6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_comp.c @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_vcmp.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_COMP) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void COMP_StructInit(COMP_InitTypeDef *pInit) +{ + pInit->InputPlus = COMP_VinP_IO3; + pInit->InputMinus = 0x0; + pInit->InputHysteresis = COMP_Hysteresis_Disable; + pInit->FilterFreq = COMP_Filter_Bypass; + pInit->OutputPolarity = COMP_OutPolarity_Normal; + pInit->OutputSel = COMP_Vout_None; + pInit->InitDelay = 0x3C; + return; +} + +void COMP_Init(COMP_Type *pHComp, COMP_InitTypeDef *pInit) +{ + if( pHComp == COMP0 ) + { + __HAL_SYSCFG_RESET_COMP0(); + __HAL_SYSCFG_COMP0_CLK_ENABLE(); + } + else if( pHComp == COMP1 ) + { + __HAL_SYSCFG_RESET_COMP1(); + __HAL_SYSCFG_COMP1_CLK_ENABLE(); + } + + REG_WRITE_MASK(pHComp->CTRL, + COMP_CTRL_VIN_SEL_Msk | COMP_CTRL_FIL_CTRL_Msk | COMP_CTRL_POL_SEL_Msk | + COMP_CTRL_OUT_EN_Msk | COMP_CTRL_HYS_EN_Msk , + pInit->InputMinus | pInit->FilterFreq | pInit->OutputPolarity | + pInit->OutputSel | pInit->InputHysteresis); + + REG_WRITE_MASK(pHComp->VIPSEL, COMP_VIPSEL_VIP_SEL_Msk, pInit->InputPlus); + + REG_WRITE_MASK(pHComp->INITCNT, COMP_INITCNT_INIT_DELAY_Msk, pInit->InitDelay); + + return; +} + +void COMP_DeInit(COMP_Type *pHComp) +{ + if( pHComp == COMP0 ) + { + __HAL_SYSCFG_RESET_COMP0(); + __HAL_SYSCFG_COMP0_CLK_DISABLE(); + } + else if( pHComp == COMP1 ) + { + __HAL_SYSCFG_RESET_COMP1(); + __HAL_SYSCFG_COMP1_CLK_DISABLE(); + } + return; +} + +#endif /* CONFIG_ENABLE_HAL_VCMP */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_crc.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_crc.c new file mode 100644 index 0000000..27f4831 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_crc.c @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_crc.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_CRC) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void CRC_Init(void) +{ + /* reset CRC module */ + __HAL_SYSCFG_RESET_CRC(); + + /* enable clock */ + __HAL_SYSCFG_CRC_CLK_ENABLE(); + + return; +} + +uint32_t CRC_CalcCRC(uint8_t *pData, CRC_WidthTypeDef crc_width) +{ + REG_WRITE(CRC->CR, crc_width); + + *((uint8_t*)&CRC->DIN) = *pData; + + return REG_READ_MASK(CRC->DOUT, REG_READ_MASK(CRC->CR, CRC_CR_POLYSEL_Msk) ? 0xFFFFul : 0xFFFFFFFFul); +} + +uint32_t CRC_CalcBlockCRC(uint8_t *pData, int length, CRC_WidthTypeDef crc_width) +{ + REG_WRITE(CRC->CR, crc_width); + + if( ((uint32_t)pData & 0x3) == 0 && (length & 0x3) == 0 ) + { + uint32_t *pWord = (uint32_t*)pData; + + length = length >> 2; + while( length-- ) + { + // Write each word to the CRC_DATA register + *((uint32_t*)&CRC->DIN) = *pWord++; + } + } + else if( ((uint32_t)pData & 0x1) == 0 && (length & 0x1) == 0 ) + { + uint16_t *pHWord = (uint16_t*)pData; + volatile uint16_t *pDatIn = (volatile uint16_t*)&CRC->DIN; + + length = length >> 1; + while( length-- ) + { + // Write each half-word to the CRC_DATA register + *pDatIn = *pHWord++; + } + } + else + { + volatile uint8_t *pDatIn = (volatile uint8_t*)&CRC->DIN; + + while( length-- ) + { + // Write each byte to the CRC_DATA register + *pDatIn = *pData++; + } + } + + return REG_READ_MASK(CRC->DOUT, REG_READ_MASK(CRC->CR, CRC_CR_POLYSEL_Msk) ? 0xFFFFul : 0xFFFFFFFFul); +} + +uint32_t CRC_GetCRC(void) +{ + return REG_READ_MASK(CRC->DOUT, REG_READ_MASK(CRC->CR, CRC_CR_POLYSEL_Msk) ? 0xFFFFul : 0xFFFFFFFFul); +} + + +uint32_t CRC_VerifyFlag(uint32_t Valid_CRC) +{ + if( Valid_CRC & 0xFFFF0000 ) + { + *((uint32_t*)&CRC->DIN) = (uint32_t)(Valid_CRC & CRC_DIN_DIN_Msk); + } + else + { + volatile uint16_t *pDatIn = (volatile uint16_t*)&CRC->DIN; + *pDatIn = (uint16_t)(Valid_CRC & CRC_DIN_DIN_Msk); + } + + return REG_READ_MASK(CRC->CR, CRC_CR_VERF_Msk); +} + +#endif /* CONFIG_ENABLE_HAL_CRC */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_device.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_device.c new file mode 100644 index 0000000..3755582 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_device.c @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_device.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + + +#include "hal_device.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint32_t g_seed1 = 0, g_seed2 = 0, g_seed3 = 0, g_seed4 = 0; +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +__WEAK void assert_failed(char *func, uint32_t line) +{ + while (1); +} + +void HAL_SRand(uint32_t seed) +{ + g_seed1 = seed; + g_seed2 = seed << 2; + g_seed3 = seed << 3; + g_seed4 = seed << 4; + return; +} + +uint32_t HAL_Rand(void) +{ + if( g_seed1 == 0 && g_seed2 == 0 ) + { + g_seed1 = ((uint16_t*)&__TIME__)[0]; + g_seed2 = ((uint16_t*)&__TIME__)[1]; + g_seed3 = ((uint16_t*)&__TIME__)[2]; + g_seed4 = ((uint16_t*)&__TIME__)[3]; + } + + uint32_t b; + b = ((g_seed1 << 6) ^ g_seed1) >> 13; + g_seed1 = ((g_seed1 & 0xFFFFFFFEU) << 18) ^ b; + b = ((g_seed2 << 2) ^ g_seed2) >> 27; + g_seed2 = ((g_seed2 & 0xFFFFFFF8U) << 2) ^ b; + b = ((g_seed3 << 13) ^ g_seed3) >> 21; + g_seed3 = ((g_seed3 & 0xFFFFFFF0U) << 7) ^ b; + b = ((g_seed4 << 3) ^ g_seed4) >> 12; + g_seed4 = ((g_seed4 & 0xFFFFFF80U) << 13) ^ b; + return (g_seed1 ^ g_seed2 ^ g_seed3 ^ g_seed4); +} diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_dsp.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_dsp.c new file mode 100644 index 0000000..7794eb7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_dsp.c @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_dsp.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_DSP) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +#if 0 +int DSP_Div32(int numerator, int denominator, int *pQuotient, int *pRemainder) +{ + #if 0 + /* ToDo: It need to check RSLT1/RSLT2 should be clear with CPU or not */ + REG_WRITE(DSP->RSLT1, 0x0ul); + REG_WRITE(DSP->RSLT2, 0x0ul); + #endif + + DSP->CR_b.MODE = DSP_CR_MODE_DIV; + + REG_WRITE(DSP->SDAT1, numerator); + REG_WRITE(DSP->SDAT2, denominator); + + while( !REG_READ(DSP->SR) ) {} + + if( pQuotient ) *pQuotient = REG_READ(DSP->RSLT1); + if( pRemainder ) *pRemainder = REG_READ(DSP->RSLT2); + + return 0; +} +#endif + +uint32_t DSP_Sqrt32(DSP_SqrtParamTypeDef *pParam) +{ + #if 0 + /* ToDo: It need to check RSLT1/RSLT2 should be clear with CPU or not */ + REG_WRITE(DSP->RSLT1, 0x0ul); + REG_WRITE(DSP->RSLT2, 0x0ul); + #endif + + DSP->CR_b.MODE = DSP_CR_MODE_SQRT; + + REG_WRITE(DSP->SDAT1, pParam->value32[0]); + REG_WRITE(DSP->SDAT2, pParam->value32[1]); + + while( !REG_READ(DSP->SR) ) {} + + return REG_READ(DSP->RSLT1); +} + + +#endif /* CONFIG_ENABLE_HAL_DSP */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_flash.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_flash.c new file mode 100644 index 0000000..e9f4a79 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_flash.c @@ -0,0 +1,280 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_flash.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_FLASH) +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_FLASH_TIMEOUT 0xFFFFFFFFul +#define FLASH_PE_CLK_MAX (1ul*1000*1000) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +static void +_FLASH_SetDivider(void) +{ + uint32_t div = 0; + div = sys_get_cpu_freq() / FLASH_PE_CLK_MAX; + + REG_WRITE(FLASH->DIV, div | (0x1ul << 8)); + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +flash_state_t FLASH_SetLatency(flash_latency_t latency) +{ + uint32_t pclk = 0; + + /* ToDo: verify system clock and latency relation */ + + pclk = sys_get_cpu_freq(); + + if( pclk > 80*1000*1000 && + latency == FLASH_LATENCY_1 ) + { + return FLASH_STATE_FAIL_PARAM; + } + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_NWS_Msk), + (FLASH_AUTH_KEY | latency)); + + return FLASH_STATE_OK; +} + +flash_state_t +FLASH_ErasePage(uint32_t page_addr) +{ + flash_state_t rval = FLASH_STATE_OK; + + _FLASH_SetDivider(); + + do { + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean interrutp flags + + // FLASH->FLIER = FLASH_FLIER_CMD_ENDE_Msk | FLASH_FLIER_CMD_ERRE_Msk; + // FLASH->FLIER = FLASH_FLIER_ADDR_ERRE_Msk; + + FLASH->AR = page_addr & ~(FLASH_1_PAGE_SIZE - 1); + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_START_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk), + (FLASH_AUTH_KEY | FLASH_CMD_START_Msk | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_ERASE_SECTOR << FLASH_CMD_CMD_Pos))); + + while( !FLASH_IsIdle() ); + } while(0); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + + return rval; +} + +flash_state_t +FLASH_ProgWord(uint32_t addr, uint32_t value) +{ + flash_state_t rval = FLASH_STATE_OK; + + do { + if( addr & 0x3 ) + { + rval = FLASH_STATE_FAIL_ADDR; + break; + } + + _FLASH_SetDivider(); + + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean interrutp flags + + FLASH->AR = addr; + FLASH->DR = value; + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_START_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk), + (FLASH_AUTH_KEY | FLASH_CMD_START_Msk | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_PROG << FLASH_CMD_CMD_Pos))); + + while( !FLASH_IsIdle() ); + } while(0); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + + return rval; +} + +flash_state_t +FLASH_ProgHWord(uint32_t addr, uint16_t value) +{ + flash_state_t rval = FLASH_STATE_OK; + + do { + union { + uint16_t hword[2]; + uint32_t word; + } u; + + if( addr & 0x1 ) + { + rval = FLASH_STATE_FAIL_ADDR; + break; + } + + _FLASH_SetDivider(); + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean interrutp flags + + #if 0 + u.word = 0xFFFFFFFFul; + #else + u.word = *(uint32_t*)(addr & ~0x3); + #endif + + u.hword[(addr & 0x2) ? 1 : 0] = value; + + FLASH->AR = (addr & ~0x3); + FLASH->DR = u.word; + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_START_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk), + (FLASH_AUTH_KEY | FLASH_CMD_START_Msk | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_PROG << FLASH_CMD_CMD_Pos))); + + while( !FLASH_IsIdle() ); + } while(0); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + + return rval; +} + +flash_state_t +FLASH_ProgByte(uint32_t addr, uint8_t value) +{ + flash_state_t rval = FLASH_STATE_OK; + + do { + union { + uint8_t byte[4]; + uint32_t word; + } u; + + _FLASH_SetDivider(); + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean interrutp flags + + #if 0 + u.word = 0xFFFFFFFFul; + #else + u.word = *(uint32_t*)(addr & ~0x3); + #endif + + u.byte[(addr & 0x3)] = value; + + FLASH->AR = (addr & ~0x3); + FLASH->DR = u.word; + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_START_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk), + (FLASH_AUTH_KEY | FLASH_CMD_START_Msk | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_PROG << FLASH_CMD_CMD_Pos))); + + while( !FLASH_IsIdle() ); + } while(0); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + + return rval; +} + +flash_state_t +FLASH_ProgData(uint32_t addr, uint32_t *pData, int length) +{ + flash_state_t rval = FLASH_STATE_OK; + + do { + if( addr & 0x3 || length & 0x3 ) + { + rval = FLASH_STATE_NOT_4_ALIGN; + break; + } + + _FLASH_SetDivider(); + REG_WRITE(FLASH->SR, 0xFFFFFFFFul); // clean interrutp flags + + FLASH->AR = addr; + + do { + FLASH->DR = *pData++; + FLASH->AR = addr; + + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | + FLASH_CMD_UNLOCK_Msk | + FLASH_CMD_CMD_Msk | FLASH_CMD_START_Msk), + (FLASH_AUTH_KEY | \ + (0x1ul << FLASH_CMD_UNLOCK_Pos) | \ + (FLASH_CMD_CMD_PROG << FLASH_CMD_CMD_Pos) | FLASH_CMD_START_Msk)); + + while( !FLASH_IsIdle() ); + + length -= 4; + addr += 4; + } while( length > 0 ); + + /* lock P/E operations */ + REG_WRITE_MASK(FLASH->CMD, + (FLASH_CMD_KEY_Msk | FLASH_CMD_UNLOCK_Msk), + FLASH_AUTH_KEY); + } while(0); + + return rval; +} + +#endif /* CONFIG_ENABLE_HAL_FLASH */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_gpio.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_gpio.c new file mode 100644 index 0000000..702bd42 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_gpio.c @@ -0,0 +1,249 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_gpio.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_GPIO) + +//============================================================================= +// Constant Definition +//============================================================================= +#define GPIO_PORTA_AF_PINS (GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 | GPIO_Pin_03 | \ + GPIO_Pin_04 | GPIO_Pin_05 | GPIO_Pin_14 | GPIO_Pin_15) + +#define GPIO_PORTB_AF_PINS (GPIO_Pin_00 | GPIO_Pin_01 | GPIO_Pin_02 | GPIO_Pin_03 | \ + GPIO_Pin_04 | GPIO_Pin_05) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int GPIO_Init(GPIO_Type *pHGpio, GPIO_InitTypeDef *pInit) +{ + int rval = 0; + + if( pHGpio == GPIOA ) + { + __HAL_SYSCFG_GPIOA_CLK_ENABLE(); + } + else if( pHGpio == GPIOB ) + { + __HAL_SYSCFG_GPIOB_CLK_ENABLE(); + } + + for(int i = 0; i < 16; i++) + { + uint32_t pin_cur = (0x1ul << i); + + if( REG_READ_MASK(pInit->GPIO_Pin, pin_cur) == 0 ) + continue; + + // enable Schmitt-Trigger + REG_SET_BITS(pHGpio->CTS, pin_cur); + + (pInit->GPIO_OType == GPIO_OType_OD) + ? REG_SET_BITS(pHGpio->ODS, pin_cur) + : REG_SET_BITS(pHGpio->ODC, pin_cur); + + switch( pInit->GPIO_Mode ) + { + default: + case GPIO_Mode_IN: /* Input mode */ + REG_SET_BITS(pHGpio->OEC, pin_cur); + REG_SET_BITS(pHGpio->INES, pin_cur); + + if( pInit->GPIO_PuPd == GPIO_PuPd_UP ) + { + REG_SET_BITS(pHGpio->PUS, pin_cur); + REG_SET_BITS(pHGpio->PDC, pin_cur); + } + else if( pInit->GPIO_PuPd == GPIO_PuPd_DOWN ) + { + REG_SET_BITS(pHGpio->PDS, pin_cur); + REG_SET_BITS(pHGpio->PUC, pin_cur); + } + else + { /* NOPULL */ + REG_SET_BITS(pHGpio->PDC, pin_cur); + REG_SET_BITS(pHGpio->PUC, pin_cur); + } + + GPIO_ITConfig(pHGpio, (GPIO_PinTypeDef)pin_cur, &pInit->GPIO_ITInit); + break; + + case GPIO_Mode_OUT: /* Output mode */ + REG_SET_BITS(pHGpio->INEC, pin_cur); + REG_SET_BITS(pHGpio->OES, pin_cur); + + if( pInit->GPIO_PuPd == GPIO_PuPd_UP ) + { + REG_SET_BITS(pHGpio->LAT, pin_cur); + } + else if( pInit->GPIO_PuPd == GPIO_PuPd_DOWN ) + { + REG_CLR_BITS(pHGpio->LAT, pin_cur); + } + else + { + /* NOPULL, H/w not support */ + } + break; + + case GPIO_Mode_ANAL: /* Analog mode */ + REG_SET_BITS(pHGpio->INEC, pin_cur); + + // disable Schmitt-Trigger + REG_SET_BITS(pHGpio->CTC, pin_cur); + break; + + case GPIO_Mode_PWR_Saving: + REG_SET_BITS(pHGpio->INEC, pin_cur); + REG_SET_BITS(pHGpio->OEC, pin_cur); + break; + + case GPIO_Mode_AF: /* Alternate mode */ + if( pHGpio == GPIOA && (pin_cur & GPIO_PORTA_AF_PINS) ) + { + int shift = 31 - HAL_CLZ(pin_cur); + + shift = (shift > 5) ? (shift - 8) : shift; + REG_WRITE_MASK(AFIO->PAAFR, (AFIO_PAAFR_PA0_Msk << 3*shift), pInit->GPIO_AF_Mode << 3*shift); + } + else if( pHGpio == GPIOB && (pin_cur & GPIO_PORTB_AF_PINS) ) + { + int shift = 31 - HAL_CLZ(pin_cur); + + REG_WRITE_MASK(AFIO->PBAFR, (AFIO_PBAFR_PB0_Msk << 3*shift), pInit->GPIO_AF_Mode << 3*shift); + } + else + { + // The target pin is not supported AF mode + return -1; + } + break; + } + } + + return rval; +} + +void GPIO_DeInit(GPIO_Type *pHGpio, uint32_t pins) +{ + while( pins ) + { + int shift = 31 - HAL_CLZ(pins); + uint32_t pin_cur = 0x0; + + pin_cur = 0x1ul << shift; + REG_CLR_BITS(pins, pin_cur); + + REG_SET_BITS(pHGpio->IEC, pin_cur); // disable interrupt + + REG_SET_BITS(pHGpio->INEC, pin_cur); + REG_SET_BITS(pHGpio->OEC, pin_cur); + + REG_SET_BITS(pHGpio->ODC, pin_cur); + + REG_SET_BITS(pHGpio->ITC0, pin_cur); + REG_SET_BITS(pHGpio->ITC1, pin_cur); + REG_SET_BITS(pHGpio->PLC, pin_cur); + REG_SET_BITS(pHGpio->IST, pin_cur); + + REG_SET_BITS(pHGpio->CTS, pin_cur); + + if( pHGpio == GPIOA && (pin_cur & GPIO_PORTA_AF_PINS) ) + { + shift = (shift > 5) ? (shift - 8) : shift; + REG_WRITE_MASK(AFIO->PAAFR, (AFIO_PAAFR_PA0_Msk << 3*shift), GPIO_AF_0 << 3*shift); + } + else if( pHGpio == GPIOB && (pin_cur & GPIO_PORTB_AF_PINS) ) + { + REG_WRITE_MASK(AFIO->PBAFR, (AFIO_PBAFR_PB0_Msk << 3*shift), GPIO_AF_0 << 3*shift); + } + } + + return; +} + +void GPIO_PeriAFConfig(GPIO_Type *pHGpio, GPIO_PeriTypeDef peri_type, GPIO_PeriAFTypeDef af_mode) +{ + if( peri_type < GPIO_Peri_Fn2 ) + { + // Fn1_AFR case + (peri_type == GPIO_Peri_BKIN) ? REG_WRITE_MASK(AFIO->FN1_AFR, AFIO_FN1_AFR_BKIN_Msk, af_mode << AFIO_FN1_AFR_BKIN_Pos) : + (peri_type == GPIO_Peri_ECAP0) ? REG_WRITE_MASK(AFIO->FN1_AFR, AFIO_FN1_AFR_ECAP0_Msk, af_mode << AFIO_FN1_AFR_ECAP0_Pos) : + (peri_type == GPIO_Peri_ECAP1) ? REG_WRITE_MASK(AFIO->FN1_AFR, AFIO_FN1_AFR_ECAP1_Msk, af_mode << AFIO_FN1_AFR_ECAP1_Pos) : + (peri_type == GPIO_Peri_ECAP2) ? REG_WRITE_MASK(AFIO->FN1_AFR, AFIO_FN1_AFR_ECAP2_Msk, af_mode << AFIO_FN1_AFR_ECAP2_Pos) : + REG_WRITE_MASK(AFIO->FN1_AFR, AFIO_FN1_AFR_EPETR_Msk, af_mode << AFIO_FN1_AFR_EPETR_Pos); + } + else + { + // Fn2_AFR case + (peri_type == GPIO_Peri_TCAP0) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_TCAP0_Msk, af_mode << AFIO_FN2_AFR_TCAP0_Pos) : + (peri_type == GPIO_Peri_TCAP1) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_TCAP1_Msk, af_mode << AFIO_FN2_AFR_TCAP1_Pos) : + (peri_type == GPIO_Peri_TCAP2) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_TCAP2_Msk, af_mode << AFIO_FN2_AFR_TCAP2_Pos) : + (peri_type == GPIO_Peri_I2C_PULL0) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL0_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL0_Pos) : + (peri_type == GPIO_Peri_I2C_PULL1) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL1_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL1_Pos) : + (peri_type == GPIO_Peri_I2C_PULL2) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL2_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL2_Pos) : + (peri_type == GPIO_Peri_I2C_PULL3) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL3_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL3_Pos) : + (peri_type == GPIO_Peri_I2C_PULL4) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL4_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL4_Pos) : + (peri_type == GPIO_Peri_I2C_PULL5) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL5_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL5_Pos) : + (peri_type == GPIO_Peri_I2C_PULL6) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL6_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL6_Pos) : + (peri_type == GPIO_Peri_I2C_PULL7) ? REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_I2C_PULL7_Msk, af_mode << AFIO_FN2_AFR_I2C_PULL7_Pos) : + REG_WRITE_MASK(AFIO->FN2_AFR, AFIO_FN2_AFR_T2ETR_Msk, af_mode << AFIO_FN2_AFR_T2ETR_Pos); + } + return; +} + + + +void GPIO_ITConfig(GPIO_Type *pHGpio, GPIO_PinTypeDef pins, GPIO_ITInitTypeDef *pInit) +{ + // set Interrupt trigger type & polarity + if( pInit->GPIO_Trigger == GPIO_Trigger_Any_Edge ) + { + REG_SET_BITS(pHGpio->ITS1, pins); // both edge + } + else if( pInit->GPIO_Trigger == GPIO_Trigger_Edge ) + { + REG_SET_BITS(pHGpio->ITC1, pins); + REG_SET_BITS(pHGpio->ITS0, pins); // Edge trigger + } + else + { + REG_SET_BITS(pHGpio->ITC1, pins); + REG_SET_BITS(pHGpio->ITC0, pins); // Level trigger + } + + (pInit->GPIO_Polarity == GPIO_Polarity_High_Rise) ? + REG_SET_BITS(pHGpio->PLS, pins) : // High level or rising edge + REG_SET_BITS(pHGpio->PLC, pins); // Low level or falling edge + + return; +} + +#endif /* CONFIG_ENABLE_HAL_GPIO */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_i2c.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_i2c.c new file mode 100644 index 0000000..d55ce9e --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_i2c.c @@ -0,0 +1,868 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_i2c.c +* +* @author Wei-Lun Hsu +* @version 0.1 +* @date 2024/09/10 +* @license +* @description +*/ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_I2C) +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_I2C_TIMEOUT 20U /*!< Timeout 20 ms */ +#define I2C_CLOCK_FREQ_MAX (400ul*1000) + +typedef enum +{ + I2C_SwState_SUCCESS = 0, /*!< Waited i2c status flag */ + I2C_SwState_ERROR = 1, /*!< No i2c status flag */ + I2C_SwState_WAITING = 2, /*!< Waiting i2c status flag */ + I2C_SwState_HOLD_DATA = 3, /*!< I2C hold data flag */ + I2C_SwState_FORCE_STOP = 4, /*!< I2C force stop flag */ + I2C_SwState_RESTART = 5, /*!< I2C restart flag */ +} I2C_SwState; + +typedef enum +{ + I2C_TxStage_START_BIT = 0, + I2C_TxStage_ADDRESS, + I2C_TxStage_DATA, + +} I2C_TxStage; + +#define I2C_START_BIT_H I2C_CTLSET_STA_Msk +#define I2C_START_BIT_L 0x0u + +#define I2C_STOP_BIT_H I2C_CTLSET_STO_Msk +#define I2C_STOP_BIT_L 0x0u + +#define I2C_ACK_BIT_H I2C_CTLSET_AA_Msk +#define I2C_ACK_BIT_L 0x0u + + +#define I2C_CLK_DIVIDER_60 (I2C_CTLSET_CR1_Msk | I2C_CTLSET_CR2_Msk) +#define I2C_CLK_DIVIDER_120 (I2C_CTLSET_CR0_Msk | I2C_CTLSET_CR2_Msk) +#define I2C_CLK_DIVIDER_160 (I2C_CTLSET_CR0_Msk | I2C_CTLSET_CR1_Msk) +#define I2C_CLK_DIVIDER_192 I2C_CTLSET_CR1_Msk +#define I2C_CLK_DIVIDER_244 I2C_CTLSET_CR0_Msk +#define I2C_CLK_DIVIDER_256 0x0ul +#define I2C_CLK_DIVIDER_960 I2C_CTLSET_CR2_Msk +#define I2C_CLK_DIVIDER_Msk (I2C_CTLSET_CR0_Msk | I2C_CTLSET_CR1_Msk | I2C_CTLSET_CR2_Msk) +//============================================================================= +// Macro Definition +//============================================================================= +/** + * \brief Set/Clear Ack bit + * + * \param [in] pHI2C The handle of I2C + * \return None + */ +__STATIC_FORCEINLINE void _I2C_SET_ACK_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLSET, I2C_CTLSET_AA_Msk); + return; +} + +__STATIC_FORCEINLINE void _I2C_CLR_ACK_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLCLR, I2C_CTLCLR_AA_Msk); + return; +} + +/** + * \brief Set/Clear Start bit + * + * \param [in] pHI2C The handle of I2C + * \return None + */ +__STATIC_FORCEINLINE void _I2C_SET_START_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLSET, I2C_CTLSET_STA_Msk); + return; +} + +__STATIC_FORCEINLINE void _I2C_CLR_START_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLCLR, I2C_CTLCLR_STA_Msk); + return; +} + +/** + * \brief Check Interrupt flag of an I2C + * + * \param [in] __HANDLE__ The handle of I2C + * \return + * 0 : no interrupt + * others: get interrupt + */ +#define __I2C_GET_SI_FLAG(__HANDLE__) REG_READ_MASK((__HANDLE__)->CTLSET, I2C_CTLSET_SI_Msk) + + +/** + * \brief Set/Clear the I2C interrupt set-flag + * + * \param [in] pHI2C The handle of I2C + * \return + * None + */ +__STATIC_FORCEINLINE void _I2C_SET_SI_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLSET, I2C_CTLSET_SI_Msk); + return; +} + +__STATIC_FORCEINLINE void _I2C_CLR_SI_FLAG(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLCLR, I2C_CTLCLR_SI_Msk); + return; +} + +/** + * \brief Enable/Disable General Call + * + * \param [in] pHI2C The handle of I2C + * \return None + */ +__STATIC_FORCEINLINE void _I2C_GC_ENABLE(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->ADDR, I2C_ADDR_GC_Msk); + return; +} + +__STATIC_FORCEINLINE void _I2C_GC_DISABLE(I2C_Type *pHI2C) +{ + REG_CLR_BITS(pHI2C->ADDR, I2C_ADDR_GC_Msk); + return; +} + +/** + * \brief Enable/Disable I2C module + * + * \param [in] pHI2C The handle of I2C + * \return + * None + */ +__STATIC_FORCEINLINE void _I2C_ENABLE(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLSET, I2C_CTLSET_EN_Msk); + return; +} + +__STATIC_FORCEINLINE void _I2C_DISABLE(I2C_Type *pHI2C) +{ + REG_SET_BITS(pHI2C->CTLCLR, I2C_CTLSET_EN_Msk); + return; +} + + + /** + * \brief Configure the Start/Stop/ACK flag + * + * \param [in] pHI2C The handle of I2C + * \param [in] start_bit The target state of start_bit + * \param [in] stop_bit The target state of stop_bit + * \param [in] ack_bit The target state of ack_bit + * \return + * None + */ + __STATIC_FORCEINLINE void _I2C_Config(I2C_Type *pHI2C, uint32_t start_bit, uint32_t stop_bit, uint32_t ack_bit) +{ + REG_WRITE_MASK(pHI2C->CTLCLR, + I2C_CTLCLR_STA_Msk | I2C_CTLCLR_STO_Msk | I2C_CTLCLR_AA_Msk, + I2C_CTLCLR_STA_Msk | I2C_CTLCLR_STO_Msk | I2C_CTLCLR_AA_Msk); + + REG_WRITE_MASK(pHI2C->CTLSET, + I2C_CTLSET_STA_Msk | I2C_CTLSET_STO_Msk | I2C_CTLSET_AA_Msk, + (start_bit) | (stop_bit) | (ack_bit)); + return; +} + + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +static I2C_ErrTypeDef +_I2C_Wait_SI_Flag(I2C_Type *pHI2C, uint32_t timeout_ms) +{ + uint32_t start_ticks = 0; + + start_ticks = sys_get_tick(); + + while( !REG_READ_MASK(pHI2C->CTLSET, I2C_CTLSET_SI_Msk) ) + { + if( (sys_get_tick() - start_ticks) > timeout_ms ) + { + return I2C_Err_TimeOut; + } + } + + return I2C_Err_OK; +} + +static I2C_SwState +_I2C_Master_Send_Byte(I2C_Type *pHI2C, uint8_t **ppData, bool is_end) +{ + __IO uint32_t *pData_reg = &pHI2C->DATA; + I2C_SwState rval = I2C_SwState_SUCCESS; + + switch( REG_READ(pHI2C->STAT) ) + { + default: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_L); + rval = I2C_SwState_ERROR; + break; + + case I2C_State_MASTER_TX_START: + case I2C_State_MASTER_TX_RESTART: + case I2C_State_MASTER_TX_SLAW_ACK: + *((__IO uint8_t*)pData_reg) = *((__IO uint8_t*)(*ppData)); + *ppData = *ppData + 1; + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_L); + break; + + case I2C_State_MASTER_TX_SLAW_NOACK: + case I2C_State_MASTER_TX_DATA_NOACK: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_L); + break; + + case I2C_State_MASTER_TX_DATA_ACK: + if( is_end ) + { + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_L); + break; + } + + *((__IO uint8_t*)pData_reg) = *((__IO uint8_t*)(*ppData)); + *ppData = *ppData + 1; + break; + + case I2C_State_MASTER_TX_LOST_BUS: + _I2C_Config(pHI2C, I2C_START_BIT_H, I2C_STOP_BIT_L, I2C_ACK_BIT_L); + break; + } + + _I2C_CLR_SI_FLAG(pHI2C); + + return rval; +} + +static I2C_SwState +_I2C_Master_Recv_Byte(I2C_Type *pHI2C, uint8_t **ppData, uint32_t is_end) +{ + __IO uint32_t *pData_reg = &pHI2C->DATA; + I2C_SwState rval = I2C_SwState_SUCCESS; + + switch( REG_READ(pHI2C->STAT) ) + { + default: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_L); + rval = I2C_SwState_ERROR; + break; + + case I2C_State_MASTER_TX_DATA_ACK: + _I2C_Config(pHI2C, I2C_START_BIT_H, I2C_STOP_BIT_L, I2C_ACK_BIT_L); + break; + + case I2C_State_MASTER_RX_START: + case I2C_State_MASTER_RX_RESTART: + *((__IO uint8_t*)pData_reg) = *((__IO uint8_t*)(*ppData)); + *ppData = *ppData + 1; + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_L); + break; + + case I2C_State_MASTER_RX_SLAR_ACK: + _I2C_Config(pHI2C, I2C_START_BIT_L, + I2C_STOP_BIT_L, + (is_end)? I2C_ACK_BIT_L : I2C_ACK_BIT_H); + break; + + case I2C_State_MASTER_RX_DATA_ACK: + _I2C_Config(pHI2C, I2C_START_BIT_L, + I2C_STOP_BIT_L, + (is_end) ? I2C_ACK_BIT_L : I2C_ACK_BIT_H); + + *(__IO uint8_t*)(*ppData) = *((__IO uint8_t*)pData_reg); + *ppData = *ppData + 1; + + break; + + case I2C_State_MASTER_RX_DATA_NOACK: + *(__IO uint8_t*)(*ppData) = *((__IO uint8_t*)pData_reg); + *ppData = *ppData + 1; + + case I2C_State_MASTER_RX_SLAR_NOACK: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_H); + break; + + case I2C_State_MASTER_RX_LOST_BUS: + _I2C_Config(pHI2C, I2C_START_BIT_H, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + break; + } + + _I2C_CLR_SI_FLAG(pHI2C); + + return rval; +} + +static I2C_SwState +_I2C_Slave_Send_Byte(I2C_Type *pHI2C, uint8_t **ppData, bool *pHasRxAddr, bool is_end) +{ + __IO uint32_t *pData_reg = &pHI2C->DATA; + I2C_SwState rval = I2C_SwState_SUCCESS; + + switch( REG_READ(pHI2C->STAT) ) + { + default: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_H); + rval = I2C_SwState_ERROR; + break; + + case I2C_State_SLAVE_RX_SLAR_ACK: + *pHasRxAddr = true; + case I2C_State_SLAVE_TX_DATA_ACK: + if( is_end ) + { + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_H); + break; + } + + *((__IO uint8_t*)pData_reg) = *((__IO uint8_t*)(*ppData)); + *ppData = *ppData + 1; + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_TX_LOST_BUS: + *((__IO uint8_t*)pData_reg) = *((__IO uint8_t*)(*ppData)); + *ppData = *ppData + 1; + _I2C_Config(pHI2C, I2C_START_BIT_H, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_TX_DATA_NOACK: + case I2C_State_SLAVE_TX_LAST_DATA: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + rval = I2C_SwState_SUCCESS; + break; + + case I2C_State_SLAVE_STOP_RESTART: // master force stop + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + rval = (*pHasRxAddr) ? I2C_SwState_FORCE_STOP : I2C_SwState_RESTART; + break; + } + + _I2C_CLR_SI_FLAG(pHI2C); + + return rval; +} + +static I2C_SwState +_I2C_Slave_Recv_Byte(I2C_Type *pHI2C, uint8_t **ppData, uint32_t is_end) +{ + __IO uint32_t *pData_reg = &pHI2C->DATA; + I2C_SwState rval = I2C_SwState_SUCCESS; + + switch( REG_READ(pHI2C->STAT) ) + { + default: + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_H, I2C_ACK_BIT_H); + rval = I2C_SwState_ERROR; + break; + + case I2C_State_SLAVE_RX_SLAW_LOST_BUS: + case I2C_State_SLAVE_RX_BADDR_LOST_BUS: + _I2C_Config(pHI2C, I2C_START_BIT_H, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_RX_SLAW_ACK: + case I2C_State_SLAVE_RX_BDATA_NOACK: + case I2C_State_SLAVE_RX_BROAD_ACK: + _I2C_Config(pHI2C, I2C_START_BIT_L, + I2C_STOP_BIT_L, + (is_end) ? I2C_ACK_BIT_L : I2C_ACK_BIT_H); + + rval = I2C_SwState_HOLD_DATA; + break; + + case I2C_State_SLAVE_RX_DATA_ACK: + *(__IO uint8_t*)(*ppData) = *((__IO uint8_t*)pData_reg); + *ppData = *ppData + 1; + + _I2C_Config(pHI2C, I2C_START_BIT_L, + I2C_STOP_BIT_L, + (is_end) ? I2C_ACK_BIT_L : I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_RX_DATA_NOACK: + *(__IO uint8_t*)(*ppData) = *((__IO uint8_t*)pData_reg); + *ppData = *ppData + 1; + + _I2C_Config(pHI2C, I2C_START_BIT_L, + (is_end) ? I2C_STOP_BIT_H : I2C_STOP_BIT_L, + I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_RX_BDATA_ACK: + *(__IO uint8_t*)(*ppData) = *((__IO uint8_t*)pData_reg); + *ppData = *ppData + 1; + + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + break; + + case I2C_State_SLAVE_STOP_RESTART: // master force stop + _I2C_Config(pHI2C, I2C_START_BIT_L, I2C_STOP_BIT_L, I2C_ACK_BIT_H); + rval = I2C_SwState_FORCE_STOP; + break; + } + + _I2C_CLR_SI_FLAG(pHI2C); + + return rval; +} +//============================================================================= +// Public Function Definition +//============================================================================= +void I2C_StructInit(I2C_InitTypeDef *pInit) +{ + int divider = 0; + + pInit->Mode = I2C_Mode_MASTER; + pInit->OwnAddress = 0x0; + pInit->BroadAck = I2C_BroadAck_Disable; + + divider = (g_SystemCoreClock / I2C_CLOCK_FREQ_MAX); + pInit->ClockDiv = (divider <= I2C_CLK_Div60) ? I2C_CLK_Div60 : + (divider <= I2C_CLK_Div120) ? I2C_CLK_Div120 : + (divider <= I2C_CLK_Div160) ? I2C_CLK_Div160 : + (divider <= I2C_CLK_Div192) ? I2C_CLK_Div192 : + (divider <= I2C_CLK_Div244) ? I2C_CLK_Div244 : + (divider <= I2C_CLK_Div256) ? I2C_CLK_Div256 : + I2C_CLK_Div960; + + return; +} + +void I2C_DeInit(I2C_Type *pHI2C) +{ + if( (int)pHI2C == (int)I2C0 ) + sys_close_IRQ(I2C0_IRQn); + + _I2C_DISABLE(pHI2C); + + __HAL_SYSCFG_RESET_I2C(); + __HAL_SYSCFG_I2C_CLK_DISABLE(); + return; +} + + +I2C_ErrTypeDef I2C_Init(I2C_Type *pHI2C, I2C_InitTypeDef *pInit) +{ + __HAL_SYSCFG_I2C_CLK_ENABLE(); + __HAL_SYSCFG_RESET_I2C(); + + if( pInit->Mode == I2C_Mode_MASTER ) + { + uint32_t divider = 0ul; + + #if 0 + /** + * I2C clock freq should less than I2C_CLOCK_FREQ_MAX + */ + if( (g_SystemCoreClock / pInit->ClockDiv) > I2C_CLOCK_FREQ_MAX ) + return I2C_Err_WrongParams; + #endif + + divider = (pInit->ClockDiv == I2C_CLK_Div960) ? I2C_CLK_DIVIDER_960 : + (pInit->ClockDiv == I2C_CLK_Div256) ? I2C_CLK_DIVIDER_256 : + (pInit->ClockDiv == I2C_CLK_Div244) ? I2C_CLK_DIVIDER_244 : + (pInit->ClockDiv == I2C_CLK_Div192) ? I2C_CLK_DIVIDER_192 : + (pInit->ClockDiv == I2C_CLK_Div160) ? I2C_CLK_DIVIDER_160 : + (pInit->ClockDiv == I2C_CLK_Div120) ? I2C_CLK_DIVIDER_120 : + I2C_CLK_DIVIDER_60; + + /* Set divider */ + REG_WRITE_MASK(pHI2C->CTLSET, I2C_CLK_DIVIDER_Msk, divider); + + /* clear ack flag */ + _I2C_CLR_ACK_FLAG(pHI2C); + } + else if( pInit->Mode == I2C_Mode_SLAVE ) + { + /* Configure Slave Address */ + REG_WRITE_MASK(pHI2C->ADDR, + I2C_ADDR_ADDR_Msk | I2C_ADDR_GC_Msk, + (pInit->OwnAddress << I2C_ADDR_ADDR_Pos) | pInit->BroadAck); + + REG_WRITE_MASK(pHI2C->CTLSET, I2C_CLK_DIVIDER_Msk, pInit->ClockDiv); + + _I2C_SET_ACK_FLAG(pHI2C); + } + else + return I2C_Err_WrongParams; + + + _I2C_ENABLE(pHI2C); + _I2C_CLR_SI_FLAG(pHI2C); + + return I2C_Err_OK; +} + +I2C_ErrTypeDef I2C_Master_Transmit(I2C_Type *pHI2C, uint16_t DevAddr, uint8_t *pData, uint16_t Size) +{ + I2C_SwState rval = I2C_SwState_SUCCESS; + I2C_TxStage stage = I2C_TxStage_START_BIT; + uint16_t tx_nbytes = 0; + + if( (int)pHI2C == (int)I2C0 ) + sys_close_IRQ(I2C0_IRQn); + + _I2C_SET_START_FLAG(pHI2C); + stage = I2C_TxStage_ADDRESS; + + while( tx_nbytes < Size ) + { + if( _I2C_Wait_SI_Flag(pHI2C, CONFIG_I2C_TIMEOUT) != I2C_Err_OK ) + break; + + if( stage == I2C_TxStage_ADDRESS ) + { + uint8_t addr = (uint8_t)DevAddr & ~0x1u; // write mode + uint8_t *pAddr = 0; + + pAddr = &addr; + rval = _I2C_Master_Send_Byte(pHI2C, &pAddr, false); + if( rval == I2C_SwState_ERROR ) + break; + + stage = I2C_TxStage_DATA; + continue; + } + else + { + rval = _I2C_Master_Send_Byte(pHI2C, &pData, false); + if( rval == I2C_SwState_ERROR ) + break; + } + + tx_nbytes = (rval == I2C_SwState_SUCCESS) ? tx_nbytes + 1 : tx_nbytes; + } + + if( rval == I2C_SwState_SUCCESS ) + { + // send STOP-bit + _I2C_Wait_SI_Flag(pHI2C, CONFIG_I2C_TIMEOUT); + _I2C_Master_Send_Byte(pHI2C, &pData, true); + } + + return (rval == I2C_SwState_SUCCESS) ? I2C_Err_OK : I2C_Err_Fail; +} + +I2C_ErrTypeDef I2C_Master_Receive(I2C_Type *pHI2C, uint8_t DevAddr, uint8_t *pData, uint16_t *pSize, uint16_t Timeout_ms) +{ + I2C_SwState rval = I2C_SwState_SUCCESS; + I2C_TxStage stage = I2C_TxStage_START_BIT; + uint16_t buf_size = *pSize; + int rx_nbytes = 0; + + if( (int)pHI2C == (int)I2C0 ) + sys_close_IRQ(I2C0_IRQn); + + _I2C_SET_START_FLAG(pHI2C); + stage = I2C_TxStage_ADDRESS; + + if( pSize ) *pSize = 0; + + while( rx_nbytes < buf_size ) + { + if( _I2C_Wait_SI_Flag(pHI2C, Timeout_ms) != I2C_Err_OK ) + { + if( Timeout_ms == I2C_BLOCKING ) + continue; + + return I2C_Err_TimeOut; + } + + if( stage == I2C_TxStage_ADDRESS ) + { + uint8_t addr = (uint8_t)DevAddr | 0x1u; // read mode + uint8_t *pAddr = 0; + + pAddr = &addr; + rval = _I2C_Master_Recv_Byte(pHI2C, &pAddr, (buf_size == 1)); + if( rval == I2C_SwState_ERROR ) + break; + + /** + * send DevAddr+R and then receive data + * ps. Decrease the DevAddr+R byte + */ + rx_nbytes = -1; + stage = I2C_TxStage_DATA; + continue; + } + else + { + rval = _I2C_Master_Recv_Byte(pHI2C, &pData, ((rx_nbytes + 1) == (buf_size-1))); + if( rval == I2C_SwState_ERROR ) + break; + } + + rx_nbytes = (rval == I2C_SwState_SUCCESS) ? rx_nbytes + 1 : rx_nbytes; + } + + if( pSize ) *pSize = rx_nbytes; + + return (rval == I2C_SwState_SUCCESS) ? I2C_Err_OK : I2C_Err_Fail; +} + +I2C_ErrTypeDef I2C_Slave_Transmit(I2C_Type *pHI2C, uint8_t *pData, uint16_t Size, uint16_t Timeout_ms) +{ + __IO uint16_t tx_nbytes = 0; + I2C_SwState rval = I2C_SwState_SUCCESS; + bool HasRecvAddr = false; + + if( (int)pHI2C == (int)I2C0 ) + sys_close_IRQ(I2C0_IRQn); + + while( tx_nbytes < Size ) + { + if( _I2C_Wait_SI_Flag(pHI2C, Timeout_ms) != I2C_Err_OK ) + { + if( Timeout_ms == I2C_BLOCKING ) + continue; + + return I2C_Err_TimeOut; + } + + rval = _I2C_Slave_Send_Byte(pHI2C, &pData, &HasRecvAddr, false); + if( rval == I2C_SwState_ERROR || rval == I2C_SwState_FORCE_STOP ) + { + break; + } + + tx_nbytes = (rval == I2C_SwState_SUCCESS) ? tx_nbytes + 1 : tx_nbytes; + } + + if( rval == I2C_SwState_SUCCESS ) + { + // send STOP-bit + _I2C_Wait_SI_Flag(pHI2C, CONFIG_I2C_TIMEOUT); + _I2C_Slave_Send_Byte(pHI2C, &pData, &HasRecvAddr, true); + } + + return (rval == I2C_SwState_SUCCESS) ? I2C_Err_OK : I2C_Err_Fail; +} + +I2C_ErrTypeDef I2C_Slave_Receive(I2C_Type *pHI2C, uint8_t *pData, uint16_t *pSize, uint16_t Timeout_ms) +{ + uint16_t rx_nbytes = 0; + uint16_t buf_size = *pSize; + I2C_SwState rval = I2C_SwState_SUCCESS; + + if( (int)pHI2C == (int)I2C0 ) + sys_close_IRQ(I2C0_IRQn); + + if( pSize ) *pSize = 0; + + while( rx_nbytes < buf_size ) + { + if( _I2C_Wait_SI_Flag(pHI2C, Timeout_ms) != I2C_Err_OK ) + { + if( Timeout_ms == I2C_BLOCKING ) + continue; + + return I2C_Err_TimeOut; + } + + rval = _I2C_Slave_Recv_Byte(pHI2C, &pData, ((rx_nbytes + 1) == buf_size)); + if( rval == I2C_SwState_ERROR || rval == I2C_SwState_FORCE_STOP ) + { + break; + } + + rx_nbytes = (rval == I2C_SwState_SUCCESS) ? rx_nbytes + 1 : rx_nbytes; + } + + if( pSize ) *pSize = rx_nbytes; + + return (rval == I2C_SwState_SUCCESS) ? I2C_Err_OK : I2C_Err_Fail; +} + +I2C_ErrTypeDef I2C_Master_Transmit_IT(I2C_IT_HandleTypeDef *pHITI2C, uint16_t DevAddr, uint8_t *pData, uint16_t Size) +{ + pHITI2C->XferMode = I2C_XferMode_Transmite; + pHITI2C->DevAddress = (uint8_t)DevAddr; + pHITI2C->pTxBuffPtr = pData; + pHITI2C->TxXferCount = Size; + + if( (int)pHITI2C->pHI2C == (int)I2C0 ) + sys_open_IRQ(I2C0_IRQn); + + REG_WRITE_MASK(pHITI2C->pHI2C->CTLSET, + I2C_CTLSET_STA_Msk | I2C_CTLSET_SI_Msk, + I2C_CTLSET_STA_Msk | I2C_CTLSET_SI_Msk); + + return I2C_Err_OK; +} + +I2C_ErrTypeDef I2C_Master_Receive_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t DevAddr, uint8_t *pData, uint16_t Size) +{ + pHITI2C->XferMode = I2C_XferMode_Recevie; + pHITI2C->DevAddress = (uint8_t)DevAddr; + pHITI2C->pRxBuffPtr = pData; + pHITI2C->RxXferCount = Size; + + if( (int)pHITI2C->pHI2C == (int)I2C0 ) + sys_open_IRQ(I2C0_IRQn); + + REG_WRITE_MASK(pHITI2C->pHI2C->CTLSET, + I2C_CTLSET_STA_Msk | I2C_CTLSET_SI_Msk, + I2C_CTLSET_STA_Msk | I2C_CTLSET_SI_Msk); + + return I2C_Err_OK; +} + +I2C_ErrTypeDef I2C_Slave_Transmit_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t *pData, uint16_t Size) +{ + pHITI2C->XferMode = I2C_XferMode_Transmite; + pHITI2C->pTxBuffPtr = pData; + pHITI2C->TxXferCount = Size; + + _I2C_SET_SI_FLAG(pHITI2C->pHI2C); + if( (int)pHITI2C->pHI2C == (int)I2C0 ) + sys_open_IRQ(I2C0_IRQn); + + return I2C_Err_OK; +} + +I2C_ErrTypeDef I2C_Slave_Receive_IT(I2C_IT_HandleTypeDef *pHITI2C, uint8_t *pData, uint16_t Size) +{ + pHITI2C->XferMode = I2C_XferMode_Recevie; + pHITI2C->pRxBuffPtr = pData; + pHITI2C->RxXferCount = Size; + + _I2C_SET_SI_FLAG(pHITI2C->pHI2C); + if( (int)pHITI2C->pHI2C == (int)I2C0 ) + sys_open_IRQ(I2C0_IRQn); + + return I2C_Err_OK; +} + +void I2C_Master_IRQHandler(I2C_IT_HandleTypeDef *pHITI2C) +{ + I2C_SwState rval = I2C_SwState_SUCCESS; + + if( pHITI2C->XferMode == I2C_XferMode_Transmite ) + { + if( pHITI2C->DevAddress & 0x8000 ) + { + // xfer data stage, if pHITI2C->TxXferCount == 0, I2C should send STOP-bit + rval = _I2C_Master_Send_Byte(pHITI2C->pHI2C, &pHITI2C->pTxBuffPtr, (pHITI2C->TxXferCount) ? false : true); + if( rval == I2C_SwState_SUCCESS ) + pHITI2C->TxXferCount--; + + if( pHITI2C->TxXferCount == 0xFFFF ) + { + pHITI2C->XferMode = I2C_XferMode_Idle; + } + } + else + { + uint8_t *pAddr = 0; + + pHITI2C->DevAddress &= ~0x1u; // write mode + + pAddr = (uint8_t*)&pHITI2C->DevAddress; + rval = _I2C_Master_Send_Byte(pHITI2C->pHI2C, &pAddr, false); + if( rval == I2C_SwState_SUCCESS ) + pHITI2C->DevAddress |= 0x8000; + } + } + else if( pHITI2C->XferMode == I2C_XferMode_Recevie ) + { + if( pHITI2C->DevAddress & 0x8000 ) + { + rval = _I2C_Master_Recv_Byte(pHITI2C->pHI2C, &pHITI2C->pRxBuffPtr, (pHITI2C->RxXferCount - 2) ? false : true); + if( rval == I2C_SwState_SUCCESS ) + pHITI2C->RxXferCount--; + + if( pHITI2C->RxXferCount == 0 ) + { + pHITI2C->XferMode = I2C_XferMode_Idle; + } + } + else + { + uint8_t *pAddr = 0; + + pHITI2C->DevAddress |= 0x1u; // read mode + + pAddr = (uint8_t*)&pHITI2C->DevAddress; + rval = _I2C_Master_Recv_Byte(pHITI2C->pHI2C, &pAddr, false); + if( rval == I2C_SwState_SUCCESS ) + { + pHITI2C->DevAddress |= 0x8000; + + /** + * send DevAddr+R and then receive data + * ps. Decrease the DevAddr+R byte + */ + pHITI2C->RxXferCount++; + } + } + } + + return; +} + +void I2C_Slave_IRQHandler(I2C_IT_HandleTypeDef *pHITI2C) +{ + I2C_SwState rval = I2C_SwState_SUCCESS; + + if( pHITI2C->XferMode == I2C_XferMode_Transmite ) + { + bool HasRecvAddr = false; + + // xfer data stage, if pHITI2C->TxXferCount == 0, I2C should send STOP-bit + rval = _I2C_Slave_Send_Byte(pHITI2C->pHI2C, &pHITI2C->pTxBuffPtr, &HasRecvAddr, (pHITI2C->TxXferCount) ? false : true); + pHITI2C->TxXferCount = (rval == I2C_SwState_SUCCESS) ? pHITI2C->TxXferCount - 1 : + (rval == I2C_SwState_FORCE_STOP) ? 0xFFFF : + pHITI2C->TxXferCount; + + if( pHITI2C->TxXferCount == 0xFFFF ) + { + pHITI2C->XferMode = I2C_XferMode_Idle; + } + } + else if( pHITI2C->XferMode == I2C_XferMode_Recevie ) + { + rval = _I2C_Slave_Recv_Byte(pHITI2C->pHI2C, &pHITI2C->pRxBuffPtr, (pHITI2C->RxXferCount == 2)); + + pHITI2C->RxXferCount = (rval == I2C_SwState_SUCCESS) ? pHITI2C->RxXferCount - 1 : + (rval == I2C_SwState_FORCE_STOP) ? 0 : + pHITI2C->RxXferCount; + + if( pHITI2C->RxXferCount == 0 ) + { + pHITI2C->XferMode = I2C_XferMode_Idle; + } + } + + return; +} + +#endif /* CONFIG_ENABLE_HAL_I2C */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_lptim.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_lptim.c new file mode 100644 index 0000000..4024828 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_lptim.c @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_lptim.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_LPTIM) || defined(CONFIG_ENABLE_HAL_TIM0) || defined(CONFIG_ENABLE_HAL_TIM1) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void LPTIM_StructInit(LPTIM_InitTypeDef *pInit) +{ + pInit->LPTIM_Prescaler = 0; + pInit->LPTIM_ClockSource = LPTIM_CLK_Src_SysClk; + pInit->LPTIM_MatchMode = LPTIM_MatchMode_Normal; + pInit->LPTIM_MatchValue = 0; + + return; +} + + +void LPTIM_Init(LPTIM_Type *pHLpTim, LPTIM_InitTypeDef *pInit) +{ + if( pHLpTim == LPTIM ) + { + sys_close_IRQ(LPTIM_IRQn); + + __HAL_SYSCFG_RESET_LPTIM(); + __HAL_SYSCFG_LPTIM_CLK_ENABLE(); + + REG_WRITE_MASK(pHLpTim->TCR, LPTIM_TCR_CLKS_Msk, pInit->LPTIM_ClockSource); + } + else if( pHLpTim == TIM0 ) + { + sys_close_IRQ(TIM0_IRQn); + + __HAL_SYSCFG_RESET_TIM0(); + __HAL_SYSCFG_TIM0_CLK_ENABLE(); + } + else if( pHLpTim == TIM1 ) + { + sys_close_IRQ(TIM1_IRQn); + + __HAL_SYSCFG_RESET_TIM1(); + __HAL_SYSCFG_TIM1_CLK_ENABLE(); + } + + REG_SET_BITS(pHLpTim->IR, LPTIM_IR_MR0_Msk); + REG_SET_BITS(pHLpTim->TCR, LPTIM_TCR_CRST_Msk); + + pHLpTim->PR = pInit->LPTIM_Prescaler; + pHLpTim->MCR = pInit->LPTIM_MatchMode; + pHLpTim->MR0 = pInit->LPTIM_MatchValue; + + return; +} + + +void LPTIM_DeInit(LPTIM_Type *pHLpTim) +{ + REG_SET_BITS(pHLpTim->TCR, LPTIM_TCR_CRST_Msk); + + if( pHLpTim == LPTIM ) + { + __HAL_SYSCFG_LPTIM_CLK_DISABLE(); + __HAL_SYSCFG_RESET_LPTIM(); + + sys_close_IRQ(LPTIM_IRQn); + } + else if( pHLpTim == TIM0 ) + { + __HAL_SYSCFG_TIM1_CLK_DISABLE(); + __HAL_SYSCFG_RESET_TIM0(); + + sys_close_IRQ(TIM0_IRQn); + } + else if( pHLpTim == TIM1 ) + { + __HAL_SYSCFG_TIM1_CLK_DISABLE(); + __HAL_SYSCFG_RESET_TIM1(); + + sys_close_IRQ(TIM1_IRQn); + } + + return; +} + + +void LPTIM_ITConfig(LPTIM_Type *pHLpTim, int has_enable) +{ + if( pHLpTim == LPTIM ) + { + (has_enable) + ? sys_open_IRQ(LPTIM_IRQn) + : sys_close_IRQ(LPTIM_IRQn); + } + else if( pHLpTim == TIM0 ) + { + (has_enable) + ? sys_open_IRQ(TIM0_IRQn) + : sys_close_IRQ(TIM0_IRQn); + } + else if( pHLpTim == TIM1 ) + { + (has_enable) + ? sys_open_IRQ(TIM1_IRQn) + : sys_close_IRQ(TIM1_IRQn); + } + + return; +} + + + +#endif /* CONFIG_ENABLE_HAL_LPTIM || CONFIG_ENABLE_HAL_TIM0 || CONFIG_ENABLE_HAL_TIM1 */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_opamp.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_opamp.c new file mode 100644 index 0000000..482e971 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_opamp.c @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_opamp.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/12/05 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_OPAMP) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int OPAMP_Init(OPAMP_Type *pHOPAmp, OPAMP_InitTypeDef *pInit) +{ + AMISC_Init(); + + REG_WRITE_MASK(pHOPAmp->PGA_CR, + OPAMP_PGA_CR_PGA_VIP_SEL_Msk | OPAMP_PGA_CR_PGA_VIN_SEL_Msk | \ + OPAMP_PGA_CR_PGA_IO_EN_Msk | OPAMP_PGA_CR_PGA_GAIN_Msk, + pInit->OPAMP_VinP | pInit->OPAMP_VinM | pInit->OPAMP_Vout | pInit->OPAMP_Gain); + return 0; +} + +void OPAMP_DeInit(OPAMP_Type *pHOPAmp) +{ + OPAMP_Disable(pHOPAmp); + + REG_WRITE_MASK(pHOPAmp->PGA_CR, + OPAMP_PGA_CR_PGA_VIP_SEL_Msk | OPAMP_PGA_CR_PGA_VIN_SEL_Msk | \ + OPAMP_PGA_CR_PGA_IO_EN_Msk | OPAMP_PGA_CR_PGA_GAIN_Msk, + OPAMP_VinP_Internal | OPAMP_VinM_GND | OPAMP_Vout_None | OPAMP_PGAGain_1); + + AMISC_DeInit(false); + return; +} + +void OPAMP_StructInit(OPAMP_InitTypeDef *pInit) +{ + pInit->OPAMP_VinP = OPAMP_VinP_Internal; + pInit->OPAMP_VinM = OPAMP_VinM_GND; + pInit->OPAMP_Vout = OPAMP_Vout_None; + pInit->OPAMP_Gain = OPAMP_PGAGain_1; + return; +} + +#endif /* CONFIG_ENABLE_HAL_OPAMP */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_pwr.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_pwr.c new file mode 100644 index 0000000..ef9d377 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_pwr.c @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_pwr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_PWR) + +//============================================================================= +// Constant Definition +//============================================================================= +#if 1 + #define __PWR_WAIT_RECHARGE() do{ __NOP(); __NOP(); __NOP(); __NOP(); \ + }while(0) +#else + #define __PWR_WAIT_RECHARGE() +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void PWR_EnterSleepMode(CallbaskPreSleepTypeDef cb_pre_set, + CallbaskPostSleepTypeDef cb_post_set) +{ + int wakeup_type = 0; + + sys_disable_girq(); + + if( cb_pre_set ) + cb_pre_set(PWR_Mode_Sleep, (PWR_WakeupTypeDef*)&wakeup_type); + + __HAL_SYSCFG_AMISC_CLK_ENABLE(); + + AMISC_SetHSIPwrSrc(AMISC_HSIPwrSrc_LowPower); + + REG_WRITE(AMISC->DAC_CR, 0x0ul); // Off DAC leakage + + __set_wfi_sleepmode(WFI_SHALLOW_SLEEP); + + __WFI(); + /* __PWR_WAIT_RECHARGE(); */ + + if( cb_post_set ) + cb_post_set(PWR_Mode_Sleep); + + sys_enable_girq(); + + return; +} + + +void PWR_EnterDeepSleepMode(CallbaskPreSleepTypeDef cb_pre_set, + CallbaskPostSleepTypeDef cb_post_set) +{ + int wakeup_type = 0; + + sys_disable_girq(); + + if( cb_pre_set ) + cb_pre_set(PWR_Mode_DeepSleep, (PWR_WakeupTypeDef*)&wakeup_type); + + __HAL_SYSCFG_AMISC_CLK_ENABLE(); + + AMISC_SetHSIPwrSrc(AMISC_HSIPwrSrc_LowPower); + + REG_WRITE(AMISC->DAC_CR, 0x0ul); // Off DAC leakage + + SYSCFG_SetLowPower(true); + + /* Judge wakeup trigger */ + (wakeup_type & PWR_Wakeup_LpTIM) ? sys_open_IRQ(LPTIM_IRQn) : sys_close_IRQ(LPTIM_IRQn); + (wakeup_type & PWR_Wakeup_WDG) ? sys_open_IRQ(WDG_IRQn) : sys_close_IRQ(WDG_IRQn); + (wakeup_type & PWR_Wakeup_IO_PORT_A) ? sys_open_IRQ(GPIOA_IRQn) : sys_close_IRQ(GPIOA_IRQn); + (wakeup_type & PWR_Wakeup_IO_PORT_B) ? sys_open_IRQ(GPIOB_IRQn) : sys_close_IRQ(GPIOB_IRQn); + + __set_wfi_sleepmode(WFI_DEEP_SLEEP); + + __WFI(); + __PWR_WAIT_RECHARGE(); + + SYSCFG_SetLowPower(false); + + if( cb_post_set ) + cb_post_set(PWR_Mode_DeepSleep); + + sys_enable_girq(); + + return; +} + +#endif /* CONFIG_ENABLE_HAL_PMU */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_spi.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_spi.c new file mode 100644 index 0000000..9e593d5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_spi.c @@ -0,0 +1,381 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_spi.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_SPI) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * @brief Deinitializes the spi peripheral registers to their + * default reset values. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @retval None. + */ +void SPI_DeInit(SPI_Type *spi) +{ + if (spi == SPI0) + { + __HAL_SYSCFG_RESET_SPI(); + } +} + +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct: pointer to a SPI_InitTypeDef structure + * which will be initialized. + * @retval None. + */ +void SPI_StructInit(SPI_InitTypeDef *init_struct) +{ + init_struct->SPI_Mode = SPI_Mode_Master; + init_struct->SPI_CPOL = SPI_CPOL_Low; + init_struct->SPI_CPHA = SPI_CPHA_Effective; + init_struct->SPI_TxDataSize = SPI_TxDataSize_8b; + init_struct->SPI_BaudRatePrescaler = SPI_BaudratePrescaler_256; + init_struct->SPI_FirstBit = SPI_FirstBit_MSB; +} + +/** + * @brief Initializes the spi peripheral according to the specified + * parameters in the init_struct . + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param init_struct: pointer to a SPI_InitTypeDef structure + * that contains the configuration information for the + * specified SPI peripheral. + * @retval None. + */ +void SPI_Init(SPI_Type *spi, SPI_InitTypeDef *init_struct) +{ + + __HAL_SYSCFG_SPI_CLK_ENABLE(); + + REG_WRITE_MASK(spi->CFG, SPI_CFG_MODE_Msk, (init_struct->SPI_Mode << SPI_CFG_MODE_Pos)); + REG_WRITE_MASK(spi->CFG, SPI_CFG_CPOL_Msk, (init_struct->SPI_CPOL << SPI_CFG_CPOL_Pos)); + REG_WRITE_MASK(spi->CFG, SPI_CFG_CPHA_Msk, (init_struct->SPI_CPHA << SPI_CFG_CPHA_Pos)); + REG_WRITE_MASK(spi->CFG, SPI_CFG_TXWDSZ_Msk, (init_struct->SPI_TxDataSize << SPI_CFG_TXWDSZ_Pos)); + REG_WRITE_MASK(spi->CFG, SPI_CFG_DB_Msk, (init_struct->SPI_BaudRatePrescaler << SPI_CFG_DB_Pos)); + REG_WRITE_MASK(spi->CFG, SPI_CFG_LSB_Msk, (init_struct->SPI_FirstBit << SPI_CFG_LSB_Pos)); +} + +/** + * @brief Enables or disables the specified SPI peripheral. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param state: new state of the spi peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void SPI_Enable(SPI_Type *spi) +{ + REG_SET_BITS(spi->EN, SPI_EN_EN_Msk); +} + +void SPI_Disable(SPI_Type *spi) +{ + REG_CLR_BITS(spi->EN, SPI_EN_EN_Msk); +} + + +void SPI_MasterEnable(SPI_Type *spi) +{ + REG_SET_BITS(spi->CFG, SPI_CFG_MODE_Msk); +} + +void SPI_SlaveEnable(SPI_Type *spi) +{ + REG_CLR_BITS(spi->CFG, SPI_CFG_MODE_Msk); +} + +/** + * @brief Transmits a Data through the spi peripheral. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param data : Data to be transmitted. + * @retval None. + */ +void SPI_SendData(SPI_Type *spi, uint32_t data) +{ + spi->TX = data; +} + +/** + * @brief Returns the most recent received data by the spi peripheral. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @retval The value of the received data. + */ +uint32_t SPI_ReceiveData(SPI_Type *spi) +{ + return (spi->RX); +} + +/** + * @brief Set the clock divide + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param baudrate: the clcok divide value + * @retval None. + */ +void SPI_SetBaudRatePrescaler(SPI_Type *spi, SPI_DBTypedef spi_baudrateprescaler) +{ + REG_WRITE_MASK(spi->CFG, SPI_CFG_DB_Msk, (spi_baudrateprescaler << SPI_CFG_DB_Pos)); +} + +/** + * @brief Configures the CS pin control select for the selected SPI. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param nss: specifies the SPI NSS internal state. + * This parameter can be one of the following values: + * @arg SPI_SSOUT_Selected: CS pin is low + * @arg SPI_SSOUT_NoSelected: CS pin is high + * @retval None. + */ +void SPI_SetSSOUT(SPI_Type *spi, uint32_t ss_out_value) +{ + REG_WRITE_MASK(spi->CFG, SPI_CFG_SS_OUT_Msk, (ss_out_value << SPI_CFG_SS_OUT_Pos)); +} + +/** + * @brief Configures the CS pin manual select enable for the selected SPI. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param mcs_value: CS manual select enable + * @retval None. + */ +void SPI_SetManualChipSelect(SPI_Type *spi, uint32_t mcs_value) +{ + REG_WRITE_MASK(spi->CFG, SPI_CFG_MCS_Msk, (mcs_value << SPI_CFG_MCS_Pos)); +} + +/** + * @brief Configures the manual mode for the selected SPI. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param mce_en: Manual mode enable or disable + * @retval None. + */ +void SPI_SetManualMode(SPI_Type *spi, uint32_t mce_en) +{ + REG_WRITE_MASK(spi->CFG, SPI_CFG_MSE_Msk, (mce_en << SPI_CFG_MSE_Pos)); +} + +/** + * @brief Configures the manual send data for the selected SPI. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @retval None. + */ +void SPI_ManualModeStart(SPI_Type *spi) +{ + REG_SET_BITS(spi->CFG, SPI_CFG_MSTC_Msk); +} +/** + * @brief Configures the data size for the selected SPI. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param datasize_value: specifies the SPI data size. + * @retval None. + * @retval None. + */ +void SPI_SetTxDataSize(SPI_Type *spi, SPI_TXDataSizeTypedef datasize_value) +{ + REG_WRITE_MASK(spi->CFG, SPI_CFG_TXWDSZ_Msk, (datasize_value << SPI_CFG_TXWDSZ_Pos)); +} + +/** + * @brief Get interrupt status + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param flag: selects the position of the interrupt flag + * @arg SPI_RECVOV_Flag + * @arg SPI_MDF_Flag + * @arg SPI_TXNFUL_Flag + * @arg SPI_TXFUL_Flag + * @arg SPI_RXNEP_Flag + * @arg SPI_RXFUL_Flag + * @arg SPI_TXUFL_Flag + * @arg SPI_BUSY_Flag + * @retval indicate the interrupt flag is set or reset + */ +uint32_t SPI_GetInterruptStatus(SPI_Type *spi, uint32_t flag) +{ + return ((spi->STA & flag) ? 1 : 0); +} + +/** + * @brief Get interrupt flag status + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param flag: selects the position of the interrupt flag + * @retval indicate the interrupt flag is set or reset + */ +uint32_t SPI_GetFlagStatus(SPI_Type *spi, uint32_t flag) +{ + return ((spi->STA & flag) ? 1 : 0); +} + +/** + * @brief Clear interrupt flag + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param flag: selects the position of the interrupt flag + * only for RECVOV,MDF,TXUFL + * @retval write 1 to clear the interrupt flag + */ +void SPI_ClearFlagStatus(SPI_Type *spi, uint32_t flag) +{ + REG_SET_BITS(spi->STA, flag); +} + +/** + * @brief Set interrupt bit enable + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param interrupt: specifies the SPI interrupt source to enable. + * @retval None + */ +void SPI_SetInterrupt(SPI_Type *spi, uint32_t flag) +{ + REG_SET_BITS(spi->INTEN, flag); +} + +/** + * @brief Set interrupt bit disable + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param interrupt: specifies the SPI interrupt source to disable. + * @retval None + */ +void SPI_SetInterruptDisable(SPI_Type *spi, uint32_t flag) +{ + REG_SET_BITS(spi->INTDIS, flag); +} +/** + * @brief Config the delay of spi transmit. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param delay_set: the delay value to set + * @retval None. + */ +void SPI_SetDelay(SPI_Type *spi, SPI_DelayTypeDef * delay_set) +{ + REG_WRITE_MASK(spi->DELAY, SPI_DELAY_d_int_Msk, (delay_set->d_int << SPI_DELAY_d_int_Pos)); + REG_WRITE_MASK(spi->DELAY, SPI_DELAY_d_affter_Msk, (delay_set->d_after << SPI_DELAY_d_affter_Pos)); + REG_WRITE_MASK(spi->DELAY, SPI_DELAY_d_btwn_Msk, (delay_set->d_btwn << SPI_DELAY_d_btwn_Pos)); + REG_WRITE_MASK(spi->DELAY, SPI_DELAY_d_nss_Msk, (delay_set->d_nss << SPI_DELAY_d_nss_Pos)); + +} + +/** + * @brief Set the idle time of the slaver device + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param idle_cnt: the idle time in slave mode + * @retval None. + */ +void SPI_SetIdleCnt(SPI_Type *spi, uint32_t idle_cnt) +{ + spi->IDLECNT = idle_cnt; +} + +/** + * @brief Transmits a Data through the spi peripheral. + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param data : Data to be transmitted by manual mode. + * @retval None. + */ +void SPI_ManualSendData(SPI_Type *spi, uint32_t data) +{ + spi->TX = data; + + SPI_ManualModeStart(spi); +} + + + +/** + * @brief Set the send fifo threshold + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param txth: the value of send fifo threshold + * @retval None. + */ +void SPI_SetTXTH(SPI_Type *spi, uint32_t txth) +{ + spi->TXTH = txth; +} + +/** + * @brief Set the receive fifo threshold + * @param spi: Select the SPI peripheral. + * This parameter can be one of the following values: + * SPI0. + * @param txth: the value of receive fifo threshold + * @retval None. + */ +void SPI_SetRXTH(SPI_Type *spi, uint32_t rxth) +{ + spi->RXTH = rxth; +} + + + +#endif /* CONFIG_ENABLE_HAL_SPI */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_syscfg.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_syscfg.c new file mode 100644 index 0000000..6d877d8 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_syscfg.c @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_rcc.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_SYSCFG) + +//============================================================================= +// Constant Definition +//============================================================================= +#define SYSCFG_RST_FLAGS_ALL (SYSCFG_SYSRSTSR_SWRST_Msk | SYSCFG_SYSRSTSR_WDGRST_Msk | \ + SYSCFG_SYSRSTSR_LOCKUPRST_Msk | SYSCFG_SYSRSTSR_PORRST_Msk | \ + SYSCFG_SYSRSTSR_PADRST_Msk | SYSCFG_SYSRSTSR_LVDRST_Msk | \ + SYSCFG_SYSRSTSR_REBOOTRST_Msk) + +#define SYSCFG_AUTHKEY_REBOOT_UNLOCK 0xAB56 + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +void SYSCFG_SysClkConfig(SYSCFG_ClkInitTypeDef *pInit) +{ + REG_WRITE_MASK(SYSCFG->SYSCLKCR, + (SYSCFG_SYSCLKCR_CLKSW_Msk | SYSCFG_SYSCLKCR_CLKDIV_Msk), + (pInit->ClkSource | pInit->SysClk_Div)); + + SYSCFG_SetSysTickSrc(pInit->SysTickSrc); + + g_SystemCoreClock = sys_get_cpu_freq(); + return; +} + +int SYSCFG_GetFlagStatus(SYSCFG_FlagTypeDef flag) +{ + uint32_t status = 0; + uint32_t mask = (flag == SYSCFG_FLAG_ALL) + ? SYSCFG_FLAGS_TYPE_Msk + : (uint32_t)1ul << (flag & SYSCFG_FLAGS_TYPE_Msk); + + status = REG_READ(SYSCFG->SYSRSTSR); + + return (status & mask); +} + + +void SYSCFG_ClearFlags(SYSCFG_FlagTypeDef flag) +{ + uint32_t shift = flag & SYSCFG_FLAGS_TYPE_Msk; + + (shift == SYSCFG_FLAGS_TYPE_Msk) + ? REG_SET_BITS(SYSCFG->SYSRSTSR, SYSCFG_RST_FLAGS_ALL) + : REG_SET_BITS(SYSCFG->SYSRSTSR, ((uint32_t)1ul << shift)); + + return; +} + +void SYSCFG_RebootLetch(void) +{ + REG_WRITE(SYSCFG->REBOOT_UNLOCK, SYSCFG_AUTHKEY_REBOOT_UNLOCK); + REG_SET_BITS(SYSCFG->SYSRSTCR, SYSCFG_SYSRSTCR_REBOOTEN_Msk); + + while(1); + return; +} + +void SYSCFG_SetICEPin2NormalIO(int is_enable) +{ + (is_enable) + ? REG_WRITE(SYSCFG->ICEIOCR, 0xE653ul << SYSCFG_ICEIOCR_AUTHKEY_Pos) + : REG_WRITE(SYSCFG->ICEIOCR, + (0xE653ul << SYSCFG_ICEIOCR_AUTHKEY_Pos) | \ + SYSCFG_ICEIOCR_JTAGIOEN_Msk | SYSCFG_ICEIOCR_DBG_CTRL_EN_Msk | SYSCFG_ICEIOCR_DBG_EN_Msk); + return; +} + + +#endif /* CONFIG_ENABLE_HAL_RCC */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_tim.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_tim.c new file mode 100644 index 0000000..f278fb6 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_tim.c @@ -0,0 +1,1647 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_timer.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_TIM2) || defined(CONFIG_ENABLE_HAL_EPWM) + +//============================================================================= +// Constant Definition +//============================================================================= +#define SMCR_ETR_Mask ((uint16_t)0x00FF) +#define CCMR_Offset ((uint16_t)0x0018) +#define CCER_CCE_Set ((uint16_t)0x0001) +#define CCER_CCNE_Set ((uint16_t)0x0004) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +/** + * @brief Deinitializes the tim peripheral registers to their default reset values. + * @param tim: select the TIM peripheral. + * @retval None. + */ +void TIM_DeInit(TIM_Type *tim) +{ + if (tim == TIM2) + { + __HAL_SYSCFG_RESET_TIM2(); + } + else if (tim == EPWM) + { + __HAL_SYSCFG_RESET_EPWM(); + } + return; +} + +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct : pointer to a TIM_TimeBaseInitTypeDef + * structure which will be initialized. + * @retval None. + */ +void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef *init_struct) +{ + init_struct->TIM_Period = 0xFFFFFFFF; + init_struct->TIM_Prescaler = 0x0000; + init_struct->TIM_ClockDivision = TIM_CKD_Div1; + init_struct->TIM_CounterMode = TIM_CounterMode_Up; + init_struct->TIM_RepetitionCounter = 0x00; +} + +/** + * @brief Initializes the tim Time Base Unit peripheral according to + * the specified parameters in the init_struct. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_TimeBaseInitTypeDef + * structure that contains the configuration information for the + * specified TIM peripheral. + * @retval None. + */ +void TIM_TimeBaseInit(TIM_Type *tim, TIM_TimeBaseInitTypeDef *init_struct) +{ + if (tim == TIM2) + { + __HAL_SYSCFG_TIM2_CLK_ENABLE(); + } + else if (tim == EPWM) + { + __HAL_SYSCFG_EPWM_CLK_ENABLE(); + } + REG_WRITE_MASK(tim->CR1, TIM_CR1_CKD_Msk, init_struct->TIM_ClockDivision); + REG_WRITE_MASK(tim->CR1, TIM_CR1_CMS_Msk | TIM_CR1_DIR_Msk, init_struct->TIM_CounterMode); + REG_WRITE_MASK(tim->RCR, TIM_RCR_REP_Msk, init_struct->TIM_RepetitionCounter); + + tim->ARR = init_struct->TIM_Period; + tim->PSC = init_struct->TIM_Prescaler; + + tim->EGR = TIM_PSCReloadMode_Immediate; +} + +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct : pointer to a TIM_OCInitTypeDef structure which will be initialized. + * @retval None. + */ +void TIM_OCStructInit(TIM_OCInitTypeDef *init_struct) +{ + init_struct->TIM_OCMode = TIM_OCMode_Timing; + init_struct->TIM_OutputState = TIM_OutputState_Disable; + init_struct->TIM_OutputNState = TIM_OutputNState_Disable; + init_struct->TIM_Pulse = 0x00000000; + init_struct->TIM_OCPolarity = TIM_OCPolarity_High; + init_struct->TIM_OCNPolarity = TIM_OCNPolarity_High; + init_struct->TIM_OCIdleState = TIM_OCIdleState_Reset; + init_struct->TIM_OCNIdleState = TIM_OCNIdleState_Reset; +} + +/** + * @brief Initializes the tim Channel1 according to the specified + * parameters in the init_struct. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_OCInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_OC1Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1M_Msk, init_struct->TIM_OCMode << TIM_CCMR1_OUTPUT_OC1M_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1E_Msk, init_struct->TIM_OutputState << TIM_CCER_CC1E_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1P_Msk, init_struct->TIM_OCPolarity << TIM_CCER_CC1P_Pos); + + tim->CCR1 = init_struct->TIM_Pulse; + + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1NE_Msk, init_struct->TIM_OutputNState << TIM_CCER_CC1NE_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1NP_Msk, init_struct->TIM_OCNPolarity << TIM_CCER_CC1NP_Pos); + + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS1_Msk, init_struct->TIM_OCIdleState << TIM_CR2_OIS1_Pos); + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS1N_Msk, init_struct->TIM_OCNIdleState << TIM_CR2_OIS1N_Pos); + +} + +/** + * @brief Initializes the tim Channel2 according to the specified + * parameters in the init_struct. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_OCInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_OC2Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2M_Msk, init_struct->TIM_OCMode << TIM_CCMR1_OUTPUT_OC2M_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2E_Msk, init_struct->TIM_OutputState << TIM_CCER_CC2E_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2P_Msk, init_struct->TIM_OCPolarity << TIM_CCER_CC2P_Pos); + + tim->CCR2 = init_struct->TIM_Pulse; + + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2NE_Msk, init_struct->TIM_OutputNState << TIM_CCER_CC2NE_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2NP_Msk, init_struct->TIM_OCNPolarity << TIM_CCER_CC2NP_Pos); + + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS2_Msk, init_struct->TIM_OCIdleState << TIM_CR2_OIS2_Pos); + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS2N_Msk, init_struct->TIM_OCNIdleState << TIM_CR2_OIS2N_Pos); + +} + +/** + * @brief Initializes the tim Channel3 according to the specified + * parameters in the init_struct. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_OCInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_OC3Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3M_Msk, init_struct->TIM_OCMode << TIM_CCMR2_OUTPUT_OC3M_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3E_Msk, init_struct->TIM_OutputState << TIM_CCER_CC3E_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3P_Msk, init_struct->TIM_OCPolarity << TIM_CCER_CC3P_Pos); + + tim->CCR3 = init_struct->TIM_Pulse; + + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3NE_Msk, init_struct->TIM_OutputNState << TIM_CCER_CC3NE_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3NP_Msk, init_struct->TIM_OCNPolarity << TIM_CCER_CC3NP_Pos); + + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS3_Msk, init_struct->TIM_OCIdleState << TIM_CR2_OIS3_Pos); + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS3N_Msk, init_struct->TIM_OCNIdleState << TIM_CR2_OIS3N_Pos); + +} + +/** + * @brief Initializes the tim Channel4 according to the specified + * parameters in the init_struct. + * @param tim:select the TIM peripheral. + * @param init_struct: pointer to a TIM_OCInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_OC4Init(TIM_Type *tim, TIM_OCInitTypeDef *init_struct) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4M_Msk, init_struct->TIM_OCMode << TIM_CCMR2_OUTPUT_OC4M_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC4E_Msk, init_struct->TIM_OutputState << TIM_CCER_CC4E_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC4P_Msk, init_struct->TIM_OCPolarity << TIM_CCER_CC4P_Pos); + + tim->CCR4 = init_struct->TIM_Pulse; + + REG_WRITE_MASK(tim->CR2, TIM_CR2_OIS4_Msk, init_struct->TIM_OCIdleState << TIM_CR2_OIS4_Pos); + +} + +/** + * @brief Configure the TI1 as Input. + * @param tim: select the TIM peripheral. + * @param polarity : The Input Polarity. + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param selection: specifies the input to be used. + * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1. + * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2. + * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC. + * @param filter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None. + */ +static void TI1_Configure(TIM_Type *tim, uint16_t polarity, uint16_t selection, uint16_t filter) +{ + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_CC1S_Msk, selection << TIM_CCMR1_INPUT_CC1S_Pos); + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_IC1F_Msk, filter << TIM_CCMR1_INPUT_IC1F_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1P_Msk | TIM_CCER_CC1NP_Msk, polarity | TIM_CCER_CC1E_Msk); +} + +/** + * @brief Configure the TI2 as Input. + * @param tim: select the TIM peripheral. + * @param polarity : The Input Polarity. + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param selection: specifies the input to be used. + * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2. + * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1. + * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC. + * @param filter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None. + */ +static void TI2_Configure(TIM_Type *tim, uint16_t polarity, uint16_t selection, uint16_t filter) +{ + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_CC2S_Msk, selection << TIM_CCMR1_INPUT_CC2S_Pos); + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_IC2F_Msk, filter << TIM_CCMR1_INPUT_IC2F_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2E_Msk | TIM_CCER_CC2P_Msk | TIM_CCER_CC2NP_Msk, (polarity << 4) | TIM_CCER_CC2E_Msk); +} + +/** + * @brief Configure the TI3 as Input. + * @param tim: select the TIM peripheral. + * @param polarity : The Input Polarity. + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param selection: specifies the input to be used. + * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3. + * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4. + * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC. + * @param filter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None. + */ +static void TI3_Configure(TIM_Type *tim, uint16_t polarity, uint16_t selection, uint16_t filter) +{ + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_CC3S_Msk, selection << TIM_CCMR2_INPUT_CC3S_Pos); + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_IC3F_Msk, filter << TIM_CCMR2_INPUT_IC3F_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3E_Msk | TIM_CCER_CC3P_Msk | TIM_CCER_CC3NP_Msk, (polarity << 8) | TIM_CCER_CC3E_Msk); +} + +/** + * @brief Configure the TI4 as Input. + * @param tim: select the TIM peripheral. + * @param polarity : The Input Polarity. + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param selection: specifies the input to be used. + * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4. + * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3. + * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC. + * @param filter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None. + */ +static void TI4_Configure(TIM_Type *tim, uint16_t polarity, uint16_t selection, uint16_t filter) +{ + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_CC4S_Msk, selection << TIM_CCMR2_INPUT_CC4S_Pos); + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_IC4F_Msk, filter << TIM_CCMR2_INPUT_IC4F_Pos); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC4E_Msk | TIM_CCER_CC4P_Msk, (polarity << 12) | TIM_CCER_CC4E_Msk);// | TIM_CCER_CC4NP_Msk +} + +/** + * @brief Sets the tim Input Capture 1 prescaler. + * @param tim: select the TIM peripheral. + * @param psc: specifies the Input Capture1 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_Div1: no prescaler + * @arg TIM_ICPSC_Div2: capture is done once every 2 events + * @arg TIM_ICPSC_Div4: capture is done once every 4 events + * @arg TIM_ICPSC_Div8: capture is done once every 8 events + * @retval None. + */ +void TIM_SetIC1Prescaler(TIM_Type *tim, uint32_t psc) +{ + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_IC1PSC_Msk, psc); +} + +/** + * @brief Sets the tim Input Capture 2 prescaler. + * @param tim: select the TIM peripheral. + * @param psc: specifies the Input Capture2 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_Div1: no prescaler + * @arg TIM_ICPSC_Div2: capture is done once every 2 events + * @arg TIM_ICPSC_Div4: capture is done once every 4 events + * @arg TIM_ICPSC_Div8: capture is done once every 8 events + * @retval None. + */ +void TIM_SetIC2Prescaler(TIM_Type *tim, uint32_t psc) +{ + REG_WRITE_MASK(tim->CCMR1_INPUT, TIM_CCMR1_INPUT_IC2PSC_Msk, psc << 8); +} + +/** + * @brief Sets the tim Input Capture 3 prescaler. + * @param tim: select the TIM peripheral. + * @param psc: specifies the Input Capture3 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_Div1: no prescaler + * @arg TIM_ICPSC_Div2: capture is done once every 2 events + * @arg TIM_ICPSC_Div4: capture is done once every 4 events + * @arg TIM_ICPSC_Div8: capture is done once every 8 events + * @retval None. + */ +void TIM_SetIC3Prescaler(TIM_Type *tim, uint32_t psc) +{ + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_IC3PSC_Msk, psc); +} + +/** + * @brief Sets the tim Input Capture 4 prescaler. + * @param tim: select the TIM peripheral. + * @param psc: specifies the Input Capture4 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_Div1: no prescaler + * @arg TIM_ICPSC_Div2: capture is done once every 2 events + * @arg TIM_ICPSC_Div4: capture is done once every 4 events + * @arg TIM_ICPSC_Div8: capture is done once every 8 events + * @retval None. + */ +void TIM_SetIC4Prescaler(TIM_Type *tim, uint32_t psc) +{ + REG_WRITE_MASK(tim->CCMR2_INPUT, TIM_CCMR2_INPUT_IC4PSC_Msk, psc << 8); +} + +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct: pointer to a TIM_ICInitTypeDef structure which will + * be initialized. + * @retval None. + */ +void TIM_ICStructInit(TIM_ICInitTypeDef *init_struct) +{ + init_struct->TIM_Channel = TIM_Channel_1; + init_struct->TIM_ICPolarity = TIM_ICPolarity_Rising; + init_struct->TIM_ICSelection = TIM_ICSelection_DirectTI; + init_struct->TIM_ICPrescaler = TIM_ICPSC_Div1; + init_struct->TIM_ICFilter = 0x00; +} + +/** + * @brief Initializes the TIM peripheral according to the specified + * parameters in the init_struct. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_ICInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_ICInit(TIM_Type *tim, TIM_ICInitTypeDef *init_struct) +{ + switch (init_struct->TIM_Channel) + { + case TIM_Channel_1: + TI1_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC1Prescaler(tim, init_struct->TIM_ICPrescaler); + break; + + case TIM_Channel_2: + TI2_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC2Prescaler(tim, init_struct->TIM_ICPrescaler); + break; + + case TIM_Channel_3: + TI3_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC3Prescaler(tim, init_struct->TIM_ICPrescaler); + break; + + case TIM_Channel_4: + TI4_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC4Prescaler(tim, init_struct->TIM_ICPrescaler); + break; + + default: + break; + } +} + +/** + * @brief Configures the TIM peripheral according to the specified + * parameters in the init_struct to measure an external PWM signal. + * @param tim: select the TIM peripheral. + * @param init_struct: pointer to a TIM_ICInitTypeDef structure that + * contains the configuration information for the specified TIM peripheral. + * @retval None. + */ +void TIM_PWMIConfig(TIM_Type *tim, TIM_ICInitTypeDef *init_struct) +{ + uint16_t icoppositepolarity = TIM_ICPolarity_Rising; + uint16_t icoppositeselection = TIM_ICSelection_DirectTI; + + icoppositepolarity = (init_struct->TIM_ICPolarity == TIM_ICPolarity_Rising) ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising; + icoppositeselection = (init_struct->TIM_ICSelection == TIM_ICSelection_DirectTI) ? TIM_ICSelection_IndirectTI : TIM_ICSelection_DirectTI; + + if (init_struct->TIM_Channel == TIM_Channel_1) + { + TI1_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC1Prescaler(tim, init_struct->TIM_ICPrescaler); + TI2_Configure(tim, icoppositepolarity, icoppositeselection, init_struct->TIM_ICFilter); + TIM_SetIC2Prescaler(tim, init_struct->TIM_ICPrescaler); + } + else + { + TI2_Configure(tim, init_struct->TIM_ICPolarity, init_struct->TIM_ICSelection, init_struct->TIM_ICFilter); + TIM_SetIC2Prescaler(tim, init_struct->TIM_ICPrescaler); + TI1_Configure(tim, icoppositepolarity, icoppositeselection, init_struct->TIM_ICFilter); + TIM_SetIC1Prescaler(tim, init_struct->TIM_ICPrescaler); + } +} + +/** + * @brief Fills each init_struct member with its default value. + * @param init_struct: pointer to a TIM_BDTRInitTypeDef structure which will be initialized. + * @retval None. + */ +void TIM_BDTRStructInit(TIM_BDTRInitTypeDef *init_struct) +{ + init_struct->TIM_OSSRState = TIM_OSSRState_Disable; + init_struct->TIM_OSSIState = TIM_OSSIState_Disable; + init_struct->TIM_LOCKLevel = TIM_LockLevel_OFF; + init_struct->TIM_DeadTime = 0x00; + init_struct->TIM_Break = TIM_Break_Disable; + init_struct->TIM_BreakPolarity = TIM_BreakPolarity_Low; + init_struct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; +} + +/** + * @brief Configures the: Break feature, dead time, Lock level, the OSSI, + * the OSSR State and the AOE(automatic output enable). + * @param tim: select the TIM + * @param init_struct: pointer to a TIM_BDTRInitTypeDef structure that + * contains the BDTR Register configuration information for the TIM peripheral. + * @retval None. + */ +void TIM_BDTRConfig(TIM_Type *tim, TIM_BDTRInitTypeDef *init_struct) +{ + tim->BDTR = (uint32_t)init_struct->TIM_OSSRState | init_struct->TIM_OSSIState | init_struct->TIM_LOCKLevel | + init_struct->TIM_DeadTime | init_struct->TIM_Break | init_struct->TIM_BreakPolarity | + init_struct->TIM_AutomaticOutput; +} + +/** + * @brief Enables or disables the specified TIM peripheral. + * @param tim: select the TIM peripheral. + * @param state: new state of the tim peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_Cmd(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR1 |= (0x01U << TIM_CR1_CEN_Pos)) : \ + (tim->CR1 &= ~(0x01U << TIM_CR1_CEN_Pos)); +} + +/** + * @brief Enables or disables the Asymmetric Mode. + * @param tim: select the TIM peripheral. + * @param state: new state of the tim peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_ASYMEN_Cmd(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR1 |= (0x01U << TIM_CR1_ASYMEN_Pos)) : \ + (tim->CR1 &= ~(0x01U << TIM_CR1_ASYMEN_Pos)); +} + +/** + * @brief Enables or disables the TIM peripheral Main Outputs. + * @param tim: select the TIM peripheral. + * @param state: new state of the TIM peripheral Main Outputs. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_CtrlPWMOutputs(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->BDTR |= (0x01U << TIM_BDTR_MOE_Pos)) : \ + (tim->BDTR &= ~(0x01U << TIM_BDTR_MOE_Pos)); +} + +/** + * @brief Enables or disables the specified TIM interrupts. + * @param tim: select the tim peripheral. + * @param it: specifies the TIM interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * @arg TIM_IT_CC5 + * @param state: new state of the TIM interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_ITConfig(TIM_Type *tim, uint32_t it, FunctionalState state) // TIMIT_TypeDef +{ + (state) ? \ + (tim->DIER |= it) : \ + (tim->DIER &= ~it); +} + +/** + * @brief Configures the tim event to be generate by software. + * @param tim: select the TIM peripheral. + * @param source: specifies the event source. + * This parameter can be one or more of the following values: + * @arg TIM_EventSource_Update :Timer update Event source + * @arg TIM_EventSource_CC1 :Timer Capture Compare 1 Event source + * @arg TIM_EventSource_CC2 :Timer Capture Compare 2 Event source + * @arg TIM_EventSource_CC3 :Timer Capture Compare 3 Event source + * @arg TIM_EventSource_CC4 :Timer Capture Compare 4 Event source + * @arg TIM_EventSource_COM :Timer COM event source + * @arg TIM_EventSource_Trigger:Timer Trigger Event source + * @arg TIM_EventSource_Break :Timer Break event source + * @arg TIM_EventSource_CC5 :Timer Capture Compare 5 Event source + * @note + * - TIM_EventSource_COM and TIM_EventSource_Break are used only with partial timer. + * @retval None. + */ +void TIM_GenerateEvent(TIM_Type *tim, uint32_t source) +{ + tim->EGR = source; +} + +/** + * @brief Configures the tim internal Clock + * @param tim: select the TIM peripheral. + * @retval None. + */ +void TIM_InternalClockConfig(TIM_Type *tim) +{ + tim->SMCR &= (uint16_t)(~(uint16_t)TIM_SMCR_SMS_Msk); +} + +/** + * @brief Configures the tim Internal Trigger as External Clock + * @param tim: select the TIM peripheral. + * @param source: Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @arg TIM_TS_TI1F_ED : TI1 Edge Detector + * @arg TIM_TS_TI1FP1 : Filtered Timer Input + * @arg TIM_TS_TI2FP2 : Filtered Timer Input + * @arg TIM_TS_ETRF : TI1 Edge Detector + * @retval None. + */ +void TIM_ITRxExternalClockConfig(TIM_Type *tim, uint32_t source) +{ + TIM_SelectInputTrigger(tim, source); + tim->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Selects the Input Trigger source + * @param tim: select the TIM peripheral. + * @param source: The Input Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @arg TIM_TS_TI1F_ED: TI1 Edge Detector + * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 + * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 + * @arg TIM_TS_ETRF: External Trigger input + * @retval None. + */ +void TIM_SelectInputTrigger(TIM_Type *tim, uint16_t source) +{ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_TS_Msk, source); +} + +/** + * @brief Configures the tim Prescaler. + * @param tim: select the TIM peripheral. + * @param prescaler: specifies the Prescaler Register value + * @param reloadMode: specifies the TIM Prescaler Reload mode + * @arg TIM_PSCReloadMode_Update :The Prescaler is loaded at the update event. + * @arg TIM_PSCReloadMode_Immediate :The Prescaler is loaded immediately. + * @retval None. + */ +void TIM_PrescalerConfig(TIM_Type *tim, uint16_t prescaler, uint16_t reloadMode) +{ + tim->PSC = prescaler; + tim->EGR = reloadMode; +} + + +/** + * @brief Configures the External clock Mode1 + * @param TIMx: where x can be 2, EPWM to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode1Config(TIM_Type *tim, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + /* Configure the ETR Clock source */ + TIM_ETRConfig(tim, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + + /* Select the External clock mode1 . Select the Trigger selection : ETRF */ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_SMS_Msk | TIM_SMCR_TS_Msk , TIM_SlaveMode_External1 | TIM_TS_ETRF ); +} + + + +/** + * @brief Configures the TIMx Trigger as External Clock + * @param TIMx: where x can be 2, EPWM to select the TIM peripheral. + * @param TIM_TIxExternalCLKSource: Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector + * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1 + * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2 + * @param TIM_ICPolarity: specifies the TIx Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @param ICFilter : specifies the filter value. + * This parameter must be a value between 0x0 and 0xF. + * @retval None + */ +void TIM_TIxExternalClockConfig(TIM_Type *TIMx, uint16_t TIM_TIxExternalCLKSource, uint16_t TIM_ICPolarity, uint16_t ICFilter) +{ + /* Configure the Timer Input Clock Source */ + + /* Select the Trigger source */ + TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource); + /* Select the External clock mode1 */ + TIMx->SMCR |= TIM_SlaveMode_External1; +} + +/** + * @brief Configures the External clock Mode2 + * @param TIMx: where x can be 2, EPWM to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRClockMode2Config(TIM_Type *tim, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter) +{ + /* Configure the ETR Clock source */ + TIM_ETRConfig(tim, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter); + /* Enable the External clock mode2 */ + tim->SMCR |= TIM_SMCR_ECE_Msk; +} + +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx: where x can be 2, EPWM to select the TIM peripheral. + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETRConfig(TIM_Type *tim, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter) +{ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_ETPS_Msk | TIM_SMCR_ETP_Msk | TIM_SMCR_ETF_Msk,TIM_ExtTRGPrescaler | TIM_ExtTRGPolarity | ExtTRGFilter << TIM_SMCR_ETF_Pos); +} + +/** + * @brief Specifies the tim Counter Mode to be used. + * @param tim:select the TIM peripheral. + * @param counter_mode: specifies the Counter Mode to be used + * This parameter can be one of the following values: + * @arg TIM_CounterMode_Up : TIM Up Counting Mode + * @arg TIM_CounterMode_Down : TIM Down Counting Mode + * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1 + * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2 + * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3 + * @retval None. + */ +void TIM_CounterModeConfig(TIM_Type *tim, uint32_t counter_mode) +{ + REG_WRITE_MASK(tim->CR1, TIM_CR1_CMS_Msk | TIM_CR1_DIR_Msk, counter_mode); +} + +/** + * @brief Configures the tim Encoder Interface. + * @param tim: select the TIM peripheral. + * @param encoder_mode: specifies the tim Encoder Mode. + * This parameter can be one of the following values: + * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level. + * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level. + * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending + * on the level of the other input. + * @param ic1_polarity: specifies the IC1 Polarity + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @param ic2_polarity: specifies the IC2 Polarity + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Falling: IC Falling edge. + * @arg TIM_ICPolarity_Rising: IC Rising edge. + * @retval None. + */ +void TIM_EncoderInterfaceConfig(TIM_Type *tim, uint32_t encoder_mode, uint32_t ic1_polarity, uint32_t ic2_polarity) +{ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_SMS_Msk, encoder_mode); + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_CC1S_Msk | TIM_CCMR1_OUTPUT_CC2S_Msk, TIM_CCMR1_CC1S_DirectTI | TIM_CCMR1_CC2S_DirectTI); + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1P_Msk | TIM_CCER_CC2P_Msk, ic1_polarity | (ic2_polarity << 4)); +} + +/** + * @brief Forces the tim output 1 waveform to active or inactive level. + * @param tim: select the TIM peripheral. + * @param forced_action: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC1REF + * @arg TIM_ForcedAction_Inactive: Force inactive level on OC1REF. + * @retval None. + */ +void TIM_ForcedOC1Config(TIM_Type *tim, uint32_t forced_action) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1M_Msk, forced_action << TIM_CCMR1_OUTPUT_OC1M_Pos); +} + +/** + * @brief Forces the tim output 2 waveform to active or inactive level. + * @param tim: select the TIM peripheral. + * @param forced_action: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC2REF + * @arg TIM_ForcedAction_Inactive: Force inactive level on OC2REF. + * @retval None. + */ +void TIM_ForcedOC2Config(TIM_Type *tim, uint32_t forced_action) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2M_Msk, forced_action << TIM_CCMR1_OUTPUT_OC2M_Pos); +} + +/** + * @brief Forces the tim output 3 waveform to active or inactive level. + * @param tim: select the TIM peripheral. + * @param forced_action: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC3REF + * @arg TIM_ForcedAction_Inactive: Force inactive level on OC3REF. + * @retval None. + */ +void TIM_ForcedOC3Config(TIM_Type *tim, uint32_t forced_action) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3M_Msk, forced_action << TIM_CCMR2_OUTPUT_OC3M_Pos); +} + +/** + * @brief Forces the tim output 4 waveform to active or inactive level. + * @param tim: select the TIM peripheral. + * @param forced_action: specifies the forced Action to be set to the output waveform. + * This parameter can be one of the following values: + * @arg TIM_ForcedAction_Active: Force active level on OC4REF + * @arg TIM_ForcedAction_Inactive: Force inactive level on OC4REF. + * @retval None. + */ +void TIM_ForcedOC4Config(TIM_Type *tim, uint32_t forced_action) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4M_Msk, forced_action << TIM_CCMR2_OUTPUT_OC4M_Pos); +} + +/** + * @brief Enables or disables tim peripheral Preload register on ARR. + * @param tim: select the TIM peripheral. + * @param state: new state of the tim peripheral Preload register + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_ARRPreloadConfig(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR1 |= (0x01U << TIM_CR1_ARPE_Pos)) : \ + (tim->CR1 &= ~(0x01U << TIM_CR1_ARPE_Pos)); +} + +/** + * @brief Selects the TIM peripheral Commutation event. + * @param tim: select the tim peripheral. + * @param state: new state of the Commutation event. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_SelectCOM(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR2 |= (0x01U << TIM_CR2_CCUS_Pos)) : \ + (tim->CR2 &= ~(0x01U << TIM_CR2_CCUS_Pos)); +} + +/** + * @brief Sets or Resets the TIM peripheral Capture Compare Preload Control bit. + * @param tim: select the tim peripheral. + * @param state: new state of the Capture Compare Preload Control bit + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_CCPreloadControl(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR2 |= (0x01U << TIM_CR2_CCPC_Pos)) : \ + (tim->CR2 &= ~(0x01U << TIM_CR2_CCPC_Pos)); +} + +/** + * @brief Enables or disables the tim peripheral Preload register on CCR1. + * @param tim: select the TIM peripheral. + * @param preload: new state of the tim peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Disable + * @arg TIM_OCPreload_Enable + * @retval None. + */ +void TIM_OC1PreloadConfig(TIM_Type *tim, uint32_t preload) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1PE_Msk, preload); +} + +/** + * @brief Enables or disables the tim peripheral Preload register on CCR2. + * @param tim: select the TIM peripheral. + * @param preload: new state of the tim peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Disable + * @arg TIM_OCPreload_Enable + * @retval None. + */ +void TIM_OC2PreloadConfig(TIM_Type *tim, uint32_t preload) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2PE_Msk, preload << 8); +} + +/** + * @brief Enables or disables the tim peripheral Preload register on CCR3. + * @param tim: select the TIM peripheral. + * @param preload: new state of the tim peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Disable + * @arg TIM_OCPreload_Enable + * @retval None. + */ +void TIM_OC3PreloadConfig(TIM_Type *tim, uint32_t preload) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3PE_Msk, preload); +} + +/** + * @brief Enables or disables the tim peripheral Preload register on CCR4. + * @param tim: select the TIM peripheral. + * @param preload: new state of the tim peripheral Preload register + * This parameter can be one of the following values: + * @arg TIM_OCPreload_Disable + * @arg TIM_OCPreload_Enable + * @retval None. + */ +void TIM_OC4PreloadConfig(TIM_Type *tim, uint32_t preload) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4PE_Msk, preload << 8); +} + + + +/** + * @brief Configures the tim Output Compare 1 Fast feature. + * @param tim: select the TIM peripheral. + * @param fast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None. + */ +void TIM_OC1FastConfig(TIM_Type *tim, uint32_t fast) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1FE_Msk, fast); +} + +/** + * @brief Configures the tim Output Compare 2 Fast feature. + * @param tim: select the TIM peripheral. + * @param fast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None. + */ +void TIM_OC2FastConfig(TIM_Type *tim, uint32_t fast) +{ + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2FE_Msk, fast << 8); +} + +/** + * @brief Configures the tim Output Compare 3 Fast feature. + * @param tim: select the TIM peripheral. + * @param fast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None. + */ +void TIM_OC3FastConfig(TIM_Type *tim, uint32_t fast) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3FE_Msk, fast); +} + +/** + * @brief Configures the tim Output Compare 4 Fast feature. + * @param tim: select the TIM peripheral. + * @param fast: new state of the Output Compare Fast Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCFast_Enable: TIM output compare fast enable + * @arg TIM_OCFast_Disable: TIM output compare fast disable + * @retval None. + */ +void TIM_OC4FastConfig(TIM_Type *tim, uint32_t fast) +{ + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4FE_Msk, fast << 8); +} + +/** + * @brief Configures the tim channel 1 polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC1 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC1PolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1P_Msk, polarity << TIM_CCER_CC1P_Pos); +} + +/** + * @brief Configures the tim Channel 1N polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC1N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC1NPolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1NP_Msk, polarity << TIM_CCER_CC1NP_Pos); +} + +/** + * @brief Configures the tim channel 2 polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC2 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC2PolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2P_Msk, polarity << TIM_CCER_CC2P_Pos); +} + +/** + * @brief Configures the tim Channel 2N polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC2N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC2NPolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC2NP_Msk, polarity << TIM_CCER_CC2NP_Pos); +} + +/** + * @brief Configures the tim channel 3 polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC3 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC3PolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3P_Msk, polarity << TIM_CCER_CC3P_Pos); +} + +/** + * @brief Configures the tim Channel 3N polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC3N Polarity + * This parameter can be one of the following values: + * @arg TIM_OCNPolarity_High: Output Compare active high + * @arg TIM_OCNPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC3NPolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC3NP_Msk, polarity << TIM_CCER_CC3NP_Pos); +} + +/** + * @brief Configures the tim channel 4 polarity. + * @param tim: select the TIM peripheral. + * @param polarity: specifies the OC4 Polarity + * This parameter can be one of the following values: + * @arg TIM_OCPolarity_High: Output Compare active high + * @arg TIM_OCPolarity_Low: Output Compare active low + * @retval None. + */ +void TIM_OC4PolarityConfig(TIM_Type *tim, uint32_t polarity) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC4P_Msk, polarity << TIM_CCER_CC4P_Pos); +} + +///** +// * @brief Configures the tim channel 4N polarity. +// * @param tim: select the TIM peripheral. +// * @param polarity: specifies the OC4N Polarity +// * This parameter can be one of the following values: +// * @arg TIM_OCNPolarity_High: Output Compare active high +// * @arg TIM_OCNPolarity_Low: Output Compare active low +// * @retval None. +// */ +//void TIM_OC4NPolarityConfig(TIM_Type *tim, uint32_t polarity) +//{ +// REG_WRITE_MASK(tim->CCER, TIM_CCER_CC4NP_Msk, polarity << TIM_CCER_CC4NP_Pos); +//} + +/** + * @brief Enables or disables the TIM Capture Compare Channel x. + * @param tim: select the TIM peripheral. + * @param channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @arg TIM_Channel_5: TIM Channel 5(Only for some MM32 TIM1/8) + * @param TIM_CCx: specifies the TIM Channel CCxE bit new state. + * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable. + * @retval None. + */ +void TIM_CCxCmd(TIM_Type *tim, uint16_t channel, uint32_t ccx_en) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1E_Msk << channel, ccx_en << channel); +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel xN. + * @param tim: select the TIM peripheral. + * @param channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @param TTIM_CHANNEL_5IM_CCxN: specifies the TIM Channel CCxNE bit new state. + * This parameter can be: TIM_CCXN_ENABLE or TIM_CCXN_Disable. + * @retval None. + */ +void TIM_CCxNCmd(TIM_Type *tim, uint16_t channel, uint32_t ccxn_en) +{ + REG_WRITE_MASK(tim->CCER, TIM_CCER_CC1NE_Msk << channel, ccxn_en << channel); +} + +/** + * @brief Selects the TIM Output Compare Mode. + * @note This function disables the selected channel before changing the Output Compare Mode. + * User has to enable this channel using TIM_CCxCmd and TIM_CCxNCmd functions. + * @param tim: select the TIM peripheral. + * @param channel: specifies the TIM Channel + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @param mode: specifies the TIM Output Compare Mode. + * @arg TIM_OCMode_Timing + * @arg TIM_OCMode_Active + * @arg TIM_OCMode_Inactive + * @arg TIM_OCMode_Toggle + * @arg TIM_ForcedAction_Inactive + * @arg TIM_ForcedAction_Active + * @arg TIM_OCMode_PWM1 + * @arg TIM_OCMode_PWM2 + * @retval None. + */ +void TIM_SelectOCxM(TIM_Type *tim, uint16_t channel, uint32_t mode) +{ + tim->CCER &= ~(TIM_CCER_CC1E_Msk << channel); + + switch (channel) + { + case TIM_Channel_1: + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1M_Msk, mode << TIM_CCMR1_OUTPUT_OC1M_Pos); + break; + + case TIM_Channel_2: + REG_WRITE_MASK(tim->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2M_Msk, mode << TIM_CCMR1_OUTPUT_OC2M_Pos); + break; + + case TIM_Channel_3: + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3M_Msk, mode << TIM_CCMR2_OUTPUT_OC3M_Pos); + break; + + case TIM_Channel_4: + REG_WRITE_MASK(tim->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4M_Msk, mode << TIM_CCMR2_OUTPUT_OC4M_Pos); + break; + + default: + break; + } +} + +/** + * @brief Enables or Disables the tim Update event. + * @param tim: select the TIM peripheral. + * @param state: new state of the tim UDIS bit + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_UpdateDisableConfig(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR1 |= (0x01U << TIM_CR1_UDIS_Pos)) : \ + (tim->CR1 &= ~(0x01U << TIM_CR1_UDIS_Pos)); +} + +/** + * @brief Configures the tim Update Request Interrupt source. + * @param tim: select the TIM peripheral. + * @param source: specifies the Update source. + * This parameter can be one of the following values: + * @arg TIM_UPDATESOURCE_REGULAR: Source of update is the counter overflow/underflow + * or the setting of UG bit, or an update generation + * through the slave mode controller. + * @arg TIM_UPDATESOURCE_GLOBAL: Source of update is counter overflow/underflow. + * @retval None. + */ +void TIM_UpdateRequestConfig(TIM_Type *tim, uint32_t source) +{ + REG_WRITE_MASK(tim->CR1, TIM_CR1_URS_Msk, source); +} + +/** + * @brief Enables or disables the tim's Hall sensor interface. + * @param tim: select the TIM peripheral. + * @param state: new state of the tim Hall sensor interface. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void TIM_SelectHallSensor(TIM_Type *tim, FunctionalState state) +{ + (state) ? \ + (tim->CR2 |= (0x01U << TIM_CR2_TI1S_Pos)) : \ + (tim->CR2 &= ~(0x01U << TIM_CR2_TI1S_Pos)); +} + +/** + * @brief Selects the tim's One Pulse Mode. + * @param tim: select the TIM peripheral. + * @param mode: specifies the OPM Mode to be used. + * This parameter can be one of the following values: + * @arg TIM_OPMode_Repetitive + * @arg TIM_OPMode_Single + * @retval None. + */ +void TIM_SelectOnePulseMode(TIM_Type *tim, uint32_t mode) +{ + REG_WRITE_MASK(tim->CR1, TIM_CR1_OPM_Msk, mode); +} + +/** + * @brief Selects the tim Trigger Output Mode. + * @param tim:select the TIM peripheral. + * @param source: specifies the Trigger Output source. + * This paramter can be one of the following values: + * - For all tim + * @arg TIM_TRIGSource_Reset : The UG bit in the TIM_EGR register is used as the trigger output (TRIG). + * @arg TIM_TRIGSource_Enable: The Counter Enable CEN is used as the trigger output (TRIG). + * @arg TIM_TRIGSource_Update: The update event is selected as the trigger output (TRIG). + * @arg TIM_TRIGSource_OC1 : The trigger output sends a positive pulse when the CC1IF flag is to be set, as soon as a capture or compare match occurs (TRIG). + * @arg TIM_TRIGSource_OC1REF: OC1REF signal is used as the trigger output (TRIG). + * @arg TIM_TRIGSource_OC2REF: OC2REF signal is used as the trigger output (TRIG). + * @arg TIM_TRIGSource_OC3REF: OC3REF signal is used as the trigger output (TRIG). + * @arg TIM_TRIGSource_OC4REF: OC4REF signal is used as the trigger output (TRIG). + * + * @retval None. + */ +void TIM_SelectOutputTrigger(TIM_Type *tim, uint32_t source) +{ + REG_WRITE_MASK(tim->CR2, TIM_CR2_MMS_Msk, source); +} + +/** + * @brief Selects the tim Slave Mode. + * @param tim: select the TIM peripheral. + * @param mode: specifies the Timer Slave Mode. + * @arg TIM_SlaveMode_Reset : Rising edge of the selected trigger signal (TRGI) re-initialize the counter and triggers an update of the registers. + * @arg TIM_SlaveMode_Gated : The counter clock is enabled when the trigger signal (TRGI) is high. + * @arg TIM_SlaveMode_Trigger : The counter starts at a rising edge of the trigger TRGI. + * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter. + * @retval None. + */ +void TIM_SelectSlaveMode(TIM_Type *tim, uint32_t mode) +{ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_SMS_Msk, mode); +} + +/** + * @brief Sets or Resets the tim Master/Slave Mode. + * @param tim: select the TIM peripheral. + * @param mode: specifies the Timer Master Slave Mode. + * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer and its slaves (through TRIG). + * @arg TIM_MasterSlaveMode_Disable: No action + * @retval None. + */ +void TIM_SelectMasterSlaveMode(TIM_Type *tim, uint32_t mode) +{ + REG_WRITE_MASK(tim->SMCR, TIM_SMCR_MSM_Msk, mode); +} + +/** + * @brief Sets the tim Counter Register value + * @param tim: select the TIM peripheral. + * @param auto_reload: specifies the Counter register new value. + * @retval None. + */ +void TIM_SetAutoreload(TIM_Type *tim, uint16_t auto_reload) +{ + tim->ARR = auto_reload; +} + +/** + * @brief Sets the tim Counter Register value + * @param tim: select the TIM peripheral. + * @param counter: specifies the Counter register new value. + * @retval None. + */ +void TIM_SetCounter(TIM_Type *tim, uint32_t counter) +{ + tim->CNT = counter; +} + +/** + * @brief Sets the tim Clock Division value. + * @param tim: select + * the TIM peripheral. + * @param clock_div: specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CKD_DIV_1: TDTS = Tck_tim + * @arg TIM_CKD_DIV_2: TDTS = 2 * Tck_tim + * @arg TIM_CKD_DIV_4: TDTS = 4 * Tck_tim + * @retval None. + */ +void TIM_SetClockDivision(TIM_Type *tim, uint32_t clock_div) +{ + REG_WRITE_MASK(tim->CR1, TIM_CR1_CKD_Msk, clock_div); +} + +/** + * @brief Sets the tim Capture Compare1 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare1 register new value. + * @retval None. + */ +void TIM_SetCompare1(TIM_Type *tim, uint32_t compare) +{ + tim->CCR1 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Capture Compare2 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare2 register new value. + * @retval None. + */ +void TIM_SetCompare2(TIM_Type *tim, uint32_t compare) +{ + tim->CCR2 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Capture Compare3 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare3 register new value. + * @retval None. + */ +void TIM_SetCompare3(TIM_Type *tim, uint32_t compare) +{ + tim->CCR3 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Capture Compare4 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare4 register new value. + * @retval None. + */ +void TIM_SetCompare4(TIM_Type *tim, uint32_t compare) +{ + tim->CCR4 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Downwards Compare1 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare1 register new value. + * @retval None. + */ +void TIM_SetDownCompare1(TIM_Type *tim, uint32_t compare) +{ + tim->CCDR1 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Downwards Compare2 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare2 register new value. + * @retval None. + */ +void TIM_SetDownCompare2(TIM_Type *tim, uint32_t compare) +{ + tim->CCDR2 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Downwards Compare3 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare3 register new value. + * @retval None. + */ +void TIM_SetDownCompare3(TIM_Type *tim, uint32_t compare) +{ + tim->CCDR3 = (uint16_t)compare; +} + +/** + * @brief Sets the tim Downwards Compare4 Register value + * @param tim: select the TIM peripheral. + * @param compare: specifies the Capture Compare4 register new value. + * @retval None. + */ +void TIM_SetDownCompare4(TIM_Type *tim, uint32_t compare) +{ + tim->CCDR4 = (uint16_t)compare; +} + +/** + * @brief Gets the tim Input Capture 1 value. + * @param tim: select the TIM peripheral. + * @retval Value: Capture Compare 1 Register value. + */ +uint32_t TIM_GetCapture1(TIM_Type *tim) +{ + return (tim->CCR1); +} + +/** + * @brief Gets the tim Input Capture 2 value. + * @param tim: select the TIM peripheral. + * @retval Value: Capture Compare 2 Register value. + */ +uint32_t TIM_GetCapture2(TIM_Type *tim) +{ + return (tim->CCR2); +} + +/** + * @brief Gets the tim Input Capture 3 value. + * @param tim: select the TIM peripheral. + * @retval Value: Capture Compare 3 Register value. + */ +uint32_t TIM_GetCapture3(TIM_Type *tim) +{ + return (tim->CCR3); +} + +/** + * @brief Gets the tim Input Capture 4 value. + * @param tim: select the TIM peripheral. + * @retval Value: Capture Compare 4 Register value. + */ +uint32_t TIM_GetCapture4(TIM_Type *tim) +{ + return (tim->CCR4); +} + + + +/** + * @brief Gets the tim Counter value. + * @param tim: select the TIM peripheral. + * @retval Value: Counter Register value. + */ +uint32_t TIM_GetCounter(TIM_Type *tim) +{ + return (tim->CNT); +} + +/** + * @brief Gets the tim Prescaler value. + * @param tim: select the TIM peripheral. + * @retval Value: Prescaler Register value. + */ +uint16_t TIM_GetPrescaler(TIM_Type *tim) +{ + return (tim->PSC); +} + +/** + * @brief Checks whether the specified TIM flag is set or not. + * @param tim: select the TIM peripheral. + * @param flag: specifies the flag to check. + * This parameter can be one of the following values: + * @arg TIM_FLAG_Update: TIM update Flag + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag + * @arg TIM_FLAG_COM: TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break: TIM Break Flag + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag + * @retval State: The new state of TIM_FLAG (SET or RESET). + */ +FlagStatus TIM_GetFlagStatus(TIM_Type *tim, uint32_t flag) +{ + return ((tim->SR &flag) ? SET : RESET); +} + +/** + * @brief Clears the tim's pending flags. + * @param tim: select the TIM peripheral. + * @param flag: specifies the flag bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_FLAG_Update: TIM update Flag + * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag + * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag + * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag + * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag + * @arg TIM_FLAG_COM: TIM Commutation Flag + * @arg TIM_FLAG_Trigger: TIM Trigger Flag + * @arg TIM_FLAG_Break: TIM Break Flag + * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 overcapture Flag + * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 overcapture Flag + * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 overcapture Flag + * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 overcapture Flag + * @retval None. + */ +void TIM_ClearFlag(TIM_Type *tim, uint32_t flag) +{ + tim->SR &= ~flag; +} + +/** + * @brief Checks whether the TIM interrupt has occurred or not. + * @param tim: select the TIM peripheral. + * @param it: specifies the TIM interrupt source to check. + * This parameter can be one of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * @retval State: The new state of the TIM_IT(SET or RESET). + */ +ITStatus TIM_GetITStatus(TIM_Type *tim, uint32_t it) +{ + return (((tim->SR &it) && (tim->DIER &it)) ? SET : RESET); +} + +/** + * @brief Clears the tim's interrupt pending bits. + * @param tim: select the TIM peripheral. + * @param it: specifies the pending bit to clear. + * This parameter can be any combination of the following values: + * @arg TIM_IT_Update: TIM update Interrupt source + * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source + * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source + * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source + * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source + * @arg TIM_IT_COM: TIM Commutation Interrupt source + * @arg TIM_IT_Trigger: TIM Trigger Interrupt source + * @arg TIM_IT_Break: TIM Break Interrupt source + * @note + * - TIM14, TIM16 and TIM17 can have TIM_IT_Update or TIM_IT_CC1. + * - TIM_IT_Break is used only with TIM1 and TIM8. + * - TIM_IT_COM is used only with TIM1, TIM8, TIM16 and TIM17. + * @retval None. + */ +void TIM_ClearITPendingBit(TIM_Type *tim, uint32_t it) +{ + tim->SR &= ~it; +} + +/** + * @brief Checks whether the specified TIM flag is set or not. + * @param tim: select the TIM peripheral. + * @retval None. + */ +FlagStatus TIM_GetCountDirection(TIM_Type *tim) +{ + return ((tim->CR1 &TIM_CR1_DIR_Msk) ? SET : RESET); +} + +/** + * @brief Clears or safeguards the OCREF1 signal on an external event + * @param tim: where tim can be 2,EPWM to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC1Ref(TIM_Type *tim, uint16_t TIM_OCClear) +{ + REG_WRITE_MASK(TIM->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC1CE_Msk, TIM_OCClear); +} + +/** + * @brief Clears or safeguards the OCREF2 signal on an external event + * @param tim: where tim can be 2,EPWM to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC2Ref(TIM_Type *tim, uint16_t TIM_OCClear) +{ + REG_WRITE_MASK(TIM->CCMR1_OUTPUT, TIM_CCMR1_OUTPUT_OC2CE_Msk, TIM_OCClear << 8); +} + +/** + * @brief Clears or safeguards the OCREF3 signal on an external event + * @param tim: where tim can be 2,EPWM to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC3Ref(TIM_Type *tim, uint16_t TIM_OCClear) +{ + REG_WRITE_MASK(TIM->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC3CE_Msk, TIM_OCClear); +} + +/** + * @brief Clears or safeguards the OCREF4 signal on an external event + * @param tim: where tim can be 2,EPWM to select the TIM peripheral. + * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit. + * This parameter can be one of the following values: + * @arg TIM_OCClear_Enable: TIM Output clear enable + * @arg TIM_OCClear_Disable: TIM Output clear disable + * @retval None + */ +void TIM_ClearOC4Ref(TIM_Type *tim, uint16_t TIM_OCClear) +{ + REG_WRITE_MASK(TIM->CCMR2_OUTPUT, TIM_CCMR2_OUTPUT_OC4CE_Msk, TIM_OCClear << 8); +} + +#endif /* CONFIG_ENABLE_HAL_TIM2 || CONFIG_ENABLE_HAL_EPWM */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_uart.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_uart.c new file mode 100644 index 0000000..f51ccaa --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_uart.c @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_uart.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/10 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_UART) +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +UART_ErrTypeDef UART_Init(UART_Type *pHUart, UART_InitTypeDef *pInit) +{ + uint32_t pclk = g_SystemCoreClock; + uint32_t baudrate = 0; + + if( pHUart == 0 || pInit == 0 ) + { + return UART_ERR_NULL_POINTER; + } + + if( pHUart == UART0 ) + { + __HAL_SYSCFG_UART0_CLK_ENABLE(); + __HAL_SYSCFG_RESET_UART0(); + } + + REG_WRITE(pHUart->CR, 0x0); + REG_WRITE(pHUart->IE, 0x0); + + UART_ResetRxFIFO(pHUart); + UART_ResetTxFIFO(pHUart); + + /** + * Uart->BR_b.BR should use algorithm to approach target baudrate + */ + baudrate = (pclk + (pInit->BaudRate * 8)) / (pInit->BaudRate * 16); + pHUart->BR = baudrate; + + REG_WRITE_MASK(pHUart->CR, + (UART_CR_MODE_Msk | UART_CR_STOPB_Msk | UART_CR_PAR_Msk | UART_CR_RXEN_Msk), + (pInit->WordLength | pInit->StopBits | pInit->Parity | pInit->Mode)); + + return UART_ERR_OK; +} + +void UART_SendData(UART_Type *pHUart, uint16_t value) +{ + pHUart->DAT_b.DAT = value; + return; +} + +uint16_t UART_ReceiveData(UART_Type *pHUart) +{ + return pHUart->DAT_b.DAT; +} + +UART_ErrTypeDef UART_ITConfig(UART_Type *pHUart, uint32_t flags, uint32_t is_enable) +{ + if( pHUart == 0 ) + return UART_ERR_NULL_POINTER; + + (is_enable) ? + REG_SET_BITS(pHUart->IE, flags) : + REG_CLR_BITS(pHUart->IE, flags); + + return UART_ERR_OK; +} + + + +#endif /* CONFIG_ENABLE_HAL_UART */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_wdg.c b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_wdg.c new file mode 100644 index 0000000..b1176a5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/HAL_Lib/src/hal_wdg.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file hal_wdg.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/10/17 + * @license + * @description + */ + + +#include "hal_device.h" + +#if defined(CONFIG_ENABLE_HAL_WDG) + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +void WDG_StructInit(WDG_InitTypeDef *pInit) +{ + pInit->Counter = 0xFFFFFFFFul; + pInit->ResetMode = WDG_Reset_Disable; + return; +} + +void WDG_Init(WDG_InitTypeDef *pInit) +{ + __HAL_SYSCFG_RESET_WDG(); + __HAL_SYSCFG_WDG_CLK_ENABLE(); + + sys_close_IRQ(WDG_IRQn); + + WDG_Unlock(); + + REG_WRITE(WDG->LOAD, pInit->Counter); + REG_WRITE_MASK(WDG->CR, WDG_CR_RSTE_Msk, pInit->ResetMode); + REG_WRITE(WDG->INTCLR, 0x1ul); + + WDG_Lock(); + + return; +} + +void WDG_DeInit(void) +{ + __HAL_SYSCFG_WDG_CLK_DISABLE(); + __HAL_SYSCFG_RESET_WDG(); + + sys_close_IRQ(WDG_IRQn); + return; +} + +#endif /* CONFIG_ENABLE_HAL_WDG */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ab7b4bcf331e4d8e9910e8189a59d4ece893bd5f GIT binary patch literal 6148 zcmeHK!Ab-%3{7-|0WT|f@Yr8i@B_N*_yv3MD6=C9&eBEMdq2gCAK}5XzvW94Wd;Xt zE372YzBFml>4Rw-BI4z)n-k55s74cHQ6@yplddD1d;(<2(LJyGHl-eeLlOD*imoWp z6WtBJ|J&H#&sXcT*_IuhpS=wOHmPaaKDDsbyVuLdoA-~!*x&u?-#!d;zaZ4b8E^)i z0cXG&*f#@qP1mRUUdZ!11J1y~F(BtdKog9HS+N`)=t>CytY9tzU1|x535L-yE5ZX| z4Fzf_TZzFM4tub9(J(7&II$HUY%6~iFI-kf{!pe9M@8?Q0cT*$z_AWza{piBmzgZ` z$00s)2AqL^#sF8%s##)FcDMf6p4_zo?G{Z$=4DYJ&_|B|4CEZSC{FbU(J?O?W<|*& S_7V>Chd?33J7?ez82AKi_AW*M literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/.DS_Store b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6b4deef4cad669c5c0b619426f1bb4456949209c GIT binary patch literal 6148 zcmeHK%}N6?5T4PB1wjgW@R(QV8^p36Jon;Jc31R}nu7G6m-5(ipUIowWJc-QJqUt` z%s}!@GC$dTut|o9c(Li{L^C3qq6xAnBO=qIrXzDc0dmc;p`IT4moBw=B+*}-l5any zTY9FB6779|PT0~{Q+k{)yS!T0om{-V9(t^D)3hnKuz<62ez)CSk9qaq@LE6Zt#(E+M2AlzBz!~^C19HJZre})YI|I&uGw{iPoDTs_Fd7!cdUT+xB>-@O=_=5rmXMfW z7!8XeED+XEpoX%Q7_8x#59SvQi=u`TTk*lR@<;K)b#>$q)txvhdhZN4149OmbvTpz z{|3LzXpuh*@sTs&4E!?&c+xDJ1vX`O>%sQqt_^7SXd>cQM1epbJOVI~bL6TT)gDBL YUoiLO8@`> literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_compatiable.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_compatiable.h new file mode 100644 index 0000000..0b49812 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_compatiable.h @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_COMPATIABLE_H__ +#define __CORE_COMPATIABLE_H__ +/*! + * @file core_compatiable.h + * @brief ARM compatiable function definitions header file + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +/* ===== ARM Compatiable Functions ===== */ +/** + * \defgroup NMSIS_Core_ARMCompatiable_Functions ARM Compatiable Functions + * \ingroup NMSIS_Core + * \brief A few functions that compatiable with ARM CMSIS-Core. + * \details + * + * Here we provided a few functions that compatiable with ARM CMSIS-Core, + * mostly used in the DSP and NN library. + * @{ + */ +/** \brief Instruction Synchronization Barrier, compatiable with ARM */ +#define __ISB() __RWMB() + +/** \brief Data Synchronization Barrier, compatiable with ARM */ +#define __DSB() __RWMB() + +/** \brief Data Memory Barrier, compatiable with ARM */ +#define __DMB() __RWMB() + +/** \brief LDRT Unprivileged (8 bit), ARM Compatiable */ +#define __LDRBT(ptr) __LB((ptr)) +/** \brief LDRT Unprivileged (16 bit), ARM Compatiable */ +#define __LDRHT(ptr) __LH((ptr)) +/** \brief LDRT Unprivileged (32 bit), ARM Compatiable */ +#define __LDRT(ptr) __LW((ptr)) + +/** \brief STRT Unprivileged (8 bit), ARM Compatiable */ +#define __STRBT(val, ptr) __SB((ptr), (val)) +/** \brief STRT Unprivileged (16 bit), ARM Compatiable */ +#define __STRHT(val, ptr) __SH((ptr), (val)) +/** \brief STRT Unprivileged (32 bit), ARM Compatiable */ +#define __STRT(val, ptr) __SW((ptr), (val)) + +/* ===== Saturation Operations ===== */ +/** + * \brief Signed Saturate + * \details Saturates a signed value. + * \param [in] value Value to be saturated + * \param [in] sat Bit position to saturate to (1..32) + * \return Saturated value + */ +#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) +#define __SSAT(val, sat) __RV_SCLIP32((val), (sat-1)) +#else +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) { + return max; + } else if (val < min) { + return min; + } + } + return val; +} +#endif + +/** + * \brief Unsigned Saturate + * \details Saturates an unsigned value. + * \param [in] value Value to be saturated + * \param [in] sat Bit position to saturate to (0..31) + * \return Saturated value + */ +#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) +#define __USAT(val, sat) __RV_UCLIP32((val), (sat)) +#else +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) { + return max; + } else if (val < 0) { + return 0U; + } + } + return (uint32_t)val; +} +#endif + +/* ===== Data Processing Operations ===== */ +/** + * \brief Reverse byte order (32 bit) + * \details Reverses the byte order in unsigned integer value. + * For example, 0x12345678 becomes 0x78563412. + * \param [in] value Value to reverse + * \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ + uint32_t result; + + result = ((value & 0xff000000) >> 24) + | ((value & 0x00ff0000) >> 8 ) + | ((value & 0x0000ff00) << 8 ) + | ((value & 0x000000ff) << 24); + return result; +} + +/** + * \brief Reverse byte order (16 bit) + * \details Reverses the byte order within each halfword of a word. + * For example, 0x12345678 becomes 0x34127856. + * \param [in] value Value to reverse + * \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + result = ((value & 0xff000000) >> 8) + | ((value & 0x00ff0000) << 8 ) + | ((value & 0x0000ff00) >> 8 ) + | ((value & 0x000000ff) << 8) ; + + return result; +} + +/** + * \brief Reverse byte order (16 bit) + * \details Reverses the byte order in a 16-bit value + * and returns the signed 16-bit result. + * For example, 0x0080 becomes 0x8000. + * \param [in] value Value to reverse + * \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ + int16_t result; + result = ((value & 0xff00) >> 8) | ((value & 0x00ff) << 8); + return result; +} + +/** + * \brief Rotate Right in unsigned value (32 bit) + * \details Rotate Right (immediate) provides the value of + * the contents of a register rotated by a variable number of bits. + * \param [in] op1 Value to rotate + * \param [in] op2 Number of Bits to rotate(0-31) + * \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 = op2 & 0x1F; + if (op2 == 0U) { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + +/** + * \brief Rotate Right in uint32x2 value (64 bit) + * \details Rotate Right (immediate) provides the value of + * the contents of a register rotated by a variable number of bits. + * \param [in] op1 Value to rotate([63:32] and [31:0] rotate separately) + * \param [in] op2 Number of Bits to rotate + * \return Rotated value([63:32] | [31:0]) + */ +__STATIC_FORCEINLINE uint64_t __ROR64(uint64_t op1, uint32_t op2) +{ + op2 = op2 & 0x1F; + if (op2 == 0U) { + return op1; + } + uint32_t tmp1 = (uint32_t)op1; + uint32_t tmp2 = (uint32_t)(op1 >> 32); + return (uint64_t)((tmp1 >> op2) | (tmp1 << (32U - op2))) + | ((uint64_t)((tmp2 >> op2) | (tmp2 << (32U - op2))) << 32); +} + +/** + * \brief Reverse bit order of value + * \details Reverses the bit order of the given value. + * \param [in] value Value to reverse + * \return Reversed value + */ +#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) +#define __RBIT(value) __RV_BITREVI((value), 31) +#else +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif /* defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) */ + +/** + * \brief Count leading zeros + * \details Counts the number of leading zeros of a data value. + * \param [in] data Value to count the leading zeros + * \return number of leading zeros in value + */ +#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) +#define __CLZ(data) __RV_CLZ32(data) +#else +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t data) +{ + uint8_t ret = 0; + uint32_t temp = ~data; + while (temp & 0x80000000) { + temp <<= 1; + ret++; + } + return ret; +} +#endif /* defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) */ + +/** + * \brief Count tailing zero + * \details Return the count of least-significant bit zero.for example, return 3 if x=0bxxx1000 + * \param [in] data Value to count the tailing zeros + * \return number of tailing zeros in value + */ +__STATIC_FORCEINLINE unsigned long __CTZ(unsigned long data) +{ + unsigned long ret = 0; + + while (!(data & 1UL)) { + ret++; + data = data >> 1; + } + + return ret; +} + +/** + * \brief Expand byte to unsigned long value + * \details Expand byte value x to unsigned long value's each byte. + * \param [in] x the byte value to be expand, the input must be uint8_t type + * \return Expanded value in unsigned long + */ +#if __RISCV_XLEN == 32 +#define __EXPD_BYTE(x) ((unsigned long)(((unsigned long)(x) << 0) | \ + ((unsigned long)(x) << 8) | \ + ((unsigned long)(x) << 16) | \ + ((unsigned long)(x) << 24))) +#elif __RISCV_XLEN == 64 +#define __EXPD_BYTE(x) ((unsigned long)(((unsigned long)(x) << 0) | \ + ((unsigned long)(x) << 8) | \ + ((unsigned long)(x) << 16) | \ + ((unsigned long)(x) << 24) | \ + ((unsigned long)(x) << 32) | \ + ((unsigned long)(x) << 40) | \ + ((unsigned long)(x) << 48) | \ + ((unsigned long)(x) << 56))) +#endif + +/** @} */ /* End of Doxygen Group NMSIS_Core_ARMCompatiable_Functions */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_COMPATIABLE_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_base.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_base.h new file mode 100644 index 0000000..0e6d24f --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_base.h @@ -0,0 +1,2245 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_BASE__ +#define __CORE_FEATURE_BASE__ +/*! + * @file core_feature_base.h + * @brief Base core feature API for Nuclei N/NX Core + */ +/* + * Core Base Feature Configuration Macro: + * 1. __HARTID_OFFSET: Optional, define this macro when your cpu system first hart hartid and hart index is different. + * eg. If your cpu system, first hart hartid is 2, hart index is 0, then set this macro to 2 + * + */ +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#include "nmsis_compiler.h" + +/** + * \defgroup NMSIS_Core_Registers Register Define and Type Definitions + * \brief Type definitions and defines for core registers. + * + * @{ + */ +#ifndef __RISCV_XLEN + /** \brief Refer to the width of an integer register in bits(either 32 or 64) */ + #ifndef __riscv_xlen + #define __RISCV_XLEN 32 + #else + #define __RISCV_XLEN __riscv_xlen + #endif +#endif /* __RISCV_XLEN */ + +/** \brief Type of Control and Status Register(CSR), depends on the XLEN defined in RISC-V */ +typedef unsigned long rv_csr_t; + +/** @} */ /* End of Doxygen Group NMSIS_Core_Registers */ +/** + * \defgroup NMSIS_Core_Base_Registers Base Register Define and Type Definitions + * \ingroup NMSIS_Core_Registers + * \brief Type definitions and defines for base core registers. + * + * @{ + */ +/** + * \brief Union type to access MISA CSR register. + */ +typedef union { + struct { + rv_csr_t a:1; /*!< bit: 0 Atomic extension */ + rv_csr_t b:1; /*!< bit: 1 Tentatively reserved for Bit-Manipulation extension */ + rv_csr_t c:1; /*!< bit: 2 Compressed extension */ + rv_csr_t d:1; /*!< bit: 3 Double-precision floating-point extension */ + rv_csr_t e:1; /*!< bit: 4 RV32E base ISA */ + rv_csr_t f:1; /*!< bit: 5 Single-precision floating-point extension */ + rv_csr_t g:1; /*!< bit: 6 Additional standard extensions present */ + rv_csr_t h:1; /*!< bit: 7 Hypervisor extension */ + rv_csr_t i:1; /*!< bit: 8 RV32I/64I/128I base ISA */ + rv_csr_t j:1; /*!< bit: 9 Tentatively reserved for Dynamically Translated Languages extension */ + rv_csr_t _reserved1:1; /*!< bit: 10 Reserved */ + rv_csr_t l:1; /*!< bit: 11 Tentatively reserved for Decimal Floating-Point extension */ + rv_csr_t m:1; /*!< bit: 12 Integer Multiply/Divide extension */ + rv_csr_t n:1; /*!< bit: 13 User-level interrupts supported */ + rv_csr_t _reserved2:1; /*!< bit: 14 Reserved */ + rv_csr_t p:1; /*!< bit: 15 Tentatively reserved for Packed-SIMD extension */ + rv_csr_t q:1; /*!< bit: 16 Quad-precision floating-point extension */ + rv_csr_t _resreved3:1; /*!< bit: 17 Reserved */ + rv_csr_t s:1; /*!< bit: 18 Supervisor mode implemented */ + rv_csr_t t:1; /*!< bit: 19 Tentatively reserved for Transactional Memory extension */ + rv_csr_t u:1; /*!< bit: 20 User mode implemented */ + rv_csr_t v:1; /*!< bit: 21 Tentatively reserved for Vector extension */ + rv_csr_t _reserved4:1; /*!< bit: 22 Reserved */ + rv_csr_t x:1; /*!< bit: 23 Non-standard extensions present */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved5:38; /*!< bit: 24..61 Reserved */ + rv_csr_t mxl:2; /*!< bit: 62..63 Machine XLEN */ +#else + rv_csr_t _reserved5:6; /*!< bit: 24..29 Reserved */ + rv_csr_t mxl:2; /*!< bit: 30..31 Machine XLEN */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MISA_Type; + +/** + * \brief Union type to access MSTATUS CSR register. + */ +typedef union { + struct { +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved0:3; /*!< bit: 0..2 Reserved */ + rv_csr_t mie:1; /*!< bit: 3 Machine mode interrupt enable flag */ + rv_csr_t _reserved1:3; /*!< bit: 4..6 Reserved */ + rv_csr_t mpie:1; /*!< bit: 7 mirror of MIE flag */ + rv_csr_t _reserved2:3; /*!< bit: 8..10 Reserved */ + rv_csr_t mpp:2; /*!< bit: 11..12 mirror of Privilege Mode */ + rv_csr_t fs:2; /*!< bit: 13..14 FS status flag */ + rv_csr_t xs:2; /*!< bit: 15..16 XS status flag */ + rv_csr_t mprv:1; /*!< bit: Machine mode PMP */ + rv_csr_t _reserved3:14; /*!< bit: 18..31 Reserved */ + rv_csr_t uxl:2; /*!< bit: 32..33 user mode xlen */ + rv_csr_t _reserved6:29; /*!< bit: 34..62 Reserved */ + rv_csr_t sd:1; /*!< bit: Dirty status for XS or FS */ +#else + rv_csr_t _reserved0:1; /*!< bit: 0 Reserved */ + rv_csr_t sie:1; /*!< bit: 1 supervisor interrupt enable flag */ + rv_csr_t _reserved1:1; /*!< bit: 2 Reserved */ + rv_csr_t mie:1; /*!< bit: 3 Machine mode interrupt enable flag */ + rv_csr_t _reserved2:1; /*!< bit: 4 Reserved */ + rv_csr_t spie:1; /*!< bit: 3 Supervisor Privilede mode interrupt enable flag */ + rv_csr_t _reserved3:1; /*!< bit: Reserved */ + rv_csr_t mpie:1; /*!< bit: mirror of MIE flag */ + rv_csr_t _reserved4:3; /*!< bit: Reserved */ + rv_csr_t mpp:2; /*!< bit: mirror of Privilege Mode */ + rv_csr_t fs:2; /*!< bit: FS status flag */ + rv_csr_t xs:2; /*!< bit: XS status flag */ + rv_csr_t mprv:1; /*!< bit: Machine mode PMP */ + rv_csr_t sum:1; /*!< bit: Supervisor Mode load and store protection */ + rv_csr_t _reserved6:12; /*!< bit: 19..30 Reserved */ + rv_csr_t sd:1; /*!< bit: Dirty status for XS or FS */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MSTATUS_Type; + +/** + * \brief Union type to access MTVEC CSR register. + */ +typedef union { + struct { + rv_csr_t mode:6; /*!< bit: 0..5 interrupt mode control */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t addr:58; /*!< bit: 6..63 mtvec address */ +#else + rv_csr_t addr:26; /*!< bit: 6..31 mtvec address */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MTVEC_Type; + +/** + * \brief Union type to access MCAUSE CSR register. + */ +typedef union { + struct { + rv_csr_t exccode:12; /*!< bit: 11..0 exception or interrupt code */ + rv_csr_t _reserved0:4; /*!< bit: 15..12 Reserved */ + rv_csr_t mpil:8; /*!< bit: 23..16 Previous interrupt level */ + rv_csr_t _reserved1:3; /*!< bit: 26..24 Reserved */ + rv_csr_t mpie:1; /*!< bit: 27 Interrupt enable flag before enter interrupt */ + rv_csr_t mpp:2; /*!< bit: 29..28 Privilede mode flag before enter interrupt */ + rv_csr_t minhv:1; /*!< bit: 30 Machine interrupt vector table */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved2:32; /*!< bit: 31..62 Reserved */ + rv_csr_t interrupt:1; /*!< bit: 63 trap type. 0 means exception and 1 means interrupt */ +#else + rv_csr_t interrupt:1; /*!< bit: 31 trap type. 0 means exception and 1 means interrupt */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MCAUSE_Type; + +/** + * \brief Union type to access MCOUNTINHIBIT CSR register. + */ +typedef union { + struct { + rv_csr_t cy:1; /*!< bit: 0 1 means disable mcycle counter */ + rv_csr_t _reserved0:1; /*!< bit: 1 Reserved */ + rv_csr_t ir:1; /*!< bit: 2 1 means disable minstret counter */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved1:61; /*!< bit: 3..63 Reserved */ +#else + rv_csr_t _reserved1:29; /*!< bit: 3..31 Reserved */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MCOUNTINHIBIT_Type; + +/** + * \brief Union type to access MSUBM CSR register. + */ +typedef union { + struct { + rv_csr_t _reserved0:6; /*!< bit: 0..5 Reserved */ + rv_csr_t typ:2; /*!< bit: 6..7 current trap type */ + rv_csr_t ptyp:2; /*!< bit: 8..9 previous trap type */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved1:54; /*!< bit: 10..63 Reserved */ +#else + rv_csr_t _reserved1:22; /*!< bit: 10..31 Reserved */ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MSUBM_Type; + +/** + * \brief Union type to access MDCAUSE CSR register. + */ +typedef union { + struct { + rv_csr_t mdcause:3; /*!< bit: 0..2 More detailed exception information as MCAUSE supplement */ + rv_csr_t _reserved0:__RISCV_XLEN-3; /*!< bit: 3..XLEN-1 Reserved */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MDCAUSE_Type; + +/** + * \brief Union type to access MMISC_CTRL CSR register. + */ +typedef union { + struct { + rv_csr_t _reserved0:3; /*!< bit: 0..2 Reserved */ + rv_csr_t bpu:1; /*!< bit: 3 dynamic prediction enable flag */ + rv_csr_t _reserved1:2; /*!< bit: 4..5 Reserved */ + rv_csr_t misalign:1; /*!< bit: 6 misaligned access support flag */ + rv_csr_t zcmt_zcmp:1; /*!< bit: 7 Zc Ext uses the cfdsp of D Ext’s encoding or not */ + rv_csr_t core_buserr:1; /*!< bit: 8 core bus error exception or interrupt */ + rv_csr_t nmi_cause:1; /*!< bit: 9 mnvec control and nmi mcase exccode */ + rv_csr_t imreturn_en:1; /*!< bit: 10 IMRETURN mode of trace */ + rv_csr_t sijump_en:1; /*!< bit: 11 SIJUMP mode of trace */ + rv_csr_t ldspec_en:1; /*!< bit: 12 enable load speculative goes to mem interface */ + rv_csr_t _reserved2:1; /*!< bit: 13 Reserved */ + rv_csr_t dbg_sec:1; /*!< bit: 14 debug access mode */ + rv_csr_t _reserved3:__RISCV_XLEN-15; /*!< bit: 15..XLEN-1 Reserved */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MMISCCTRL_Type; + +typedef CSR_MMISCCTRL_Type CSR_MMISCCTL_Type; + +/** + * \brief Union type to access MCACHE_CTL CSR register. + */ +typedef union { + struct { + rv_csr_t ic_en:1; /*!< I-Cache enable */ + rv_csr_t ic_scpd_mod:1; /*!< Scratchpad mode, 0: Scratchpad as ICache Data RAM, 1: Scratchpad as ILM SRAM */ + rv_csr_t ic_ecc_en:1; /*!< I-Cache ECC enable */ + rv_csr_t ic_ecc_excp_en:1; /*!< I-Cache 2bit ECC error exception enable */ + rv_csr_t ic_rwtecc:1; /*!< Control I-Cache Tag Ram ECC code injection */ + rv_csr_t ic_rwdecc:1; /*!< Control I-Cache Data Ram ECC code injection */ + rv_csr_t ic_pf_en:1; /*!< I-Cache prefetch enable */ + rv_csr_t ic_cancel_en:1; /*!< I-Cache change flow canceling enable control */ + rv_csr_t ic_ecc_chk_en:1; /*!< I-Cache check ECC codes enable */ + rv_csr_t _reserved0:7; + rv_csr_t dc_en:1; /*!< DCache enable */ + rv_csr_t dc_ecc_en:1; /*!< D-Cache ECC enable */ + rv_csr_t dc_ecc_excp_en:1; /*!< D-Cache 2bit ECC error exception enable */ + rv_csr_t dc_rwtecc:1; /*!< Control D-Cache Tag Ram ECC code injection */ + rv_csr_t dc_rwdecc:1; /*!< Control D-Cache Data Ram ECC code injection */ + rv_csr_t dc_ecc_chk_en:1; /*!< D-Cache check ECC codes enable */ + rv_csr_t _reserved1:__RISCV_XLEN-22; + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MCACHECTL_Type; + +/** + * \brief Union type to access MSAVESTATUS CSR register. + */ +typedef union { + struct { + rv_csr_t mpie1:1; /*!< bit: 0 interrupt enable flag of fisrt level NMI/exception nestting */ + rv_csr_t mpp1:2; /*!< bit: 1..2 privilede mode of fisrt level NMI/exception nestting */ + rv_csr_t _reserved0:3; /*!< bit: 3..5 Reserved */ + rv_csr_t ptyp1:2; /*!< bit: 6..7 NMI/exception type of before first nestting */ + rv_csr_t mpie2:1; /*!< bit: 8 interrupt enable flag of second level NMI/exception nestting */ + rv_csr_t mpp2:2; /*!< bit: 9..10 privilede mode of second level NMI/exception nestting */ + rv_csr_t _reserved1:3; /*!< bit: 11..13 Reserved */ + rv_csr_t ptyp2:2; /*!< bit: 14..15 NMI/exception type of before second nestting */ +#if defined(__RISCV_XLEN) && __RISCV_XLEN == 64 + rv_csr_t _reserved2:48; /*!< bit: 16..63 Reserved*/ +#else + rv_csr_t _reserved2:16; /*!< bit: 16..31 Reserved*/ +#endif + } b; /*!< Structure used for bit access */ + rv_csr_t w; /*!< Type used for csr data access */ +} CSR_MSAVESTATUS_Type; + +/** + * \brief Union type to access MILM_CTL CSR register. + */ +typedef union { + struct { + rv_csr_t ilm_en:1; /*!< ILM enable */ + rv_csr_t ilm_ecc_en:1; /*!< ILM ECC eanble */ + rv_csr_t ilm_ecc_excp_en:1; /*!< ILM ECC exception enable */ + rv_csr_t ilm_rwecc:1; /*!< Control mecc_code write to ilm, simulate error injection */ + rv_csr_t ilm_ecc_chk_en:1; /*!< ILM check ECC codes enable */ + rv_csr_t _reserved0:5; /*!< Reserved */ + rv_csr_t ilm_bpa:__RISCV_XLEN-10; /*!< ILM base address */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MILMCTL_Type; + +/** + * \brief Union type to access MDLM_CTL CSR register. + */ +typedef union { + struct { + rv_csr_t dlm_en:1; /*!< DLM enable */ + rv_csr_t dlm_ecc_en:1; /*!< DLM ECC eanble */ + rv_csr_t dlm_ecc_excp_en:1; /*!< DLM ECC exception enable */ + rv_csr_t dlm_rwecc:1; /*!< Control mecc_code write to dlm, simulate error injection */ + rv_csr_t dlm_ecc_chk_en:1; /*!< DLM check ECC codes enable */ + rv_csr_t _reserved0:5; /*!< Reserved */ + rv_csr_t dlm_bpa:__RISCV_XLEN-10; /*!< DLM base address */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MDLMCTL_Type; + +/** + * \brief Union type to access MCFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t tee:1; /*!< TEE present */ + rv_csr_t ecc:1; /*!< ECC present */ + rv_csr_t clic:1; /*!< CLIC present */ + rv_csr_t plic:1; /*!< PLIC present */ + rv_csr_t fio:1; /*!< FIO present */ + rv_csr_t ppi:1; /*!< PPI present */ + rv_csr_t nice:1; /*!< NICE present */ + rv_csr_t ilm:1; /*!< ILM present */ + rv_csr_t dlm:1; /*!< DLM present */ + rv_csr_t icache:1; /*!< ICache present */ + rv_csr_t dcache:1; /*!< DCache present */ + rv_csr_t smp:1; /*!< SMP present */ + rv_csr_t dsp_n1:1; /*!< DSP N1 present */ + rv_csr_t dsp_n2:1; /*!< DSP N2 present */ + rv_csr_t dsp_n3:1; /*!< DSP N3 present */ + rv_csr_t zc_xlcz:1; /*!< Zc and xlcz extension present */ + rv_csr_t iregion:1; /*!< IREGION present */ + rv_csr_t vpu_degree:2; /*!< Indicate the VPU degree of parallel */ + rv_csr_t sec_mode:1; /*!< Smwg extension present */ + rv_csr_t etrace:1; /*!< Etrace present */ + rv_csr_t safety_mecha:2; /*!< Indicate Core's safety mechanism */ + rv_csr_t vnice:1; /*!< VNICE present */ + rv_csr_t _reserved1:__RISCV_XLEN-24; + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MCFGINFO_Type; + +/** + * \brief Union type to access MICFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t set:4; /*!< I-Cache sets per way */ + rv_csr_t way:3; /*!< I-Cache way */ + rv_csr_t lsize:3; /*!< I-Cache line size */ + rv_csr_t _reserved0:6; + rv_csr_t lm_size:5; /*!< ILM size, need to be 2^n size */ + rv_csr_t lm_xonly:1; /*!< ILM Execute only permission */ + rv_csr_t lm_ecc:1; /*!< ILM ECC present */ + rv_csr_t _reserved1:__RISCV_XLEN-23; + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MICFGINFO_Type; + +/** + * \brief Union type to access MDCFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t set:4; /*!< D-Cache sets per way */ + rv_csr_t way:3; /*!< D-Cache way */ + rv_csr_t lsize:3; /*!< D-Cache line size */ + rv_csr_t _reserved0:6; + rv_csr_t lm_size:5; /*!< DLM size, need to be 2^n size */ + rv_csr_t lm_ecc:1; /*!< DLM ECC present */ + rv_csr_t _reserved1:__RISCV_XLEN-22; + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MDCFGINFO_Type; + +/** + * \brief Union type to access MTLBCFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t set:4; /*!< Main TLB sets per way */ + rv_csr_t way:3; /*!< Main TLB ways */ + rv_csr_t lsize:3; /*!< Main TLB line size */ + rv_csr_t ecc:1; /*!< Main TLB supports ECC or not */ + rv_csr_t _reserved0:5; /*!< Reserved 0 */ + rv_csr_t i_size:3; /*!< ITLB size */ + rv_csr_t d_size:3; /*!< DTLB size */ + rv_csr_t _reserved1:__RISCV_XLEN-22; /*!< Reserved 0 */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MTLBCFGINFO_Type; + +/** + * \brief Union type to access MPPICFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t _reserved0:1; /*!< Reserved 1 */ + rv_csr_t ppi_size:5; /*!< PPI size, need to be 2^n size */ + rv_csr_t _reserved1:4; /*!< Reserved 0 */ + rv_csr_t ppi_bpa:__RISCV_XLEN-10; /*!< PPI base address */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MPPICFGINFO_Type; + +/** + * \brief Union type to access MFIOCFG_INFO CSR register. + */ +typedef union { + struct { + rv_csr_t _reserved0:1; /*!< Reserved */ + rv_csr_t fio_size:5; /*!< FIO size, need to be 2^n size */ + rv_csr_t _reserved1:4; /*!< Reserved */ + rv_csr_t fio_bpa:__RISCV_XLEN-10; /*!< FIO base address */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MFIOCFGINFO_Type; + +/** + * \brief Union type to access MECC_LOCK CSR register. + */ +typedef union { + struct { + rv_csr_t ecc_lock:1; /*!< RW permission, ECC Lock configure */ + rv_csr_t _reserved0:__RISCV_XLEN-1; /*!< Reserved */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MECCLOCK_Type; + +/** + * \brief Union type to access MECC_CODE CSR register. + */ +typedef union { + struct { + rv_csr_t code:9; /*!< Used to inject ECC check code */ + rv_csr_t _reserved0:7; /*!< Reserved 0 */ + rv_csr_t ramid:5; /*!< The ID of RAM that has 2bit ECC error, software can clear these bits */ + rv_csr_t _reserved1:3; /*!< Reserved 0 */ + rv_csr_t sramid:5; /*!< The ID of RAM that has 1bit ECC error, software can clear these bits */ + rv_csr_t _reserved2:__RISCV_XLEN-29; /*!< Reserved 0 */ + } b; /*!< Structure used for bit access */ + rv_csr_t d; /*!< Type used for csr data access */ +} CSR_MECCCODE_Type; + +/** @} */ /* End of Doxygen Group NMSIS_Core_Base_Registers */ + +/* ########################### Core Function Access ########################### */ +/** + * \defgroup NMSIS_Core_CSR_Register_Access Core CSR Register Access + * \ingroup NMSIS_Core + * \brief Functions to access the Core CSR Registers + * \details + * + * The following functions or macros provide access to Core CSR registers. + * - \ref NMSIS_Core_CSR_Encoding + * - \ref NMSIS_Core_CSR_Registers + * @{ + */ + + +#ifndef __ASSEMBLY__ + +#ifndef __ICCRISCV__ + +/** + * \brief CSR operation Macro for csrrw instruction. + * \details + * Read the content of csr register to __v, + * then write content of val into csr register, then return __v + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val value to store into the CSR register + * \return the CSR register value before written + */ +#define __RV_CSR_SWAP(csr, val) \ + ({ \ + rv_csr_t __v = (unsigned long)(val); \ + __ASM volatile("csrrw %0, " STRINGIFY(csr) ", %1" \ + : "=r"(__v) \ + : "rK"(__v) \ + : "memory"); \ + __v; \ + }) + +/** + * \brief CSR operation Macro for csrr instruction. + * \details + * Read the content of csr register to __v and return it + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \return the CSR register value + */ +#define __RV_CSR_READ(csr) \ + ({ \ + rv_csr_t __v; \ + __ASM volatile("csrr %0, " STRINGIFY(csr) \ + : "=r"(__v) \ + : \ + : "memory"); \ + __v; \ + }) + +/** + * \brief CSR operation Macro for csrw instruction. + * \details + * Write the content of val to csr register + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val value to store into the CSR register + */ +#define __RV_CSR_WRITE(csr, val) \ + ({ \ + rv_csr_t __v = (rv_csr_t)(val); \ + __ASM volatile("csrw " STRINGIFY(csr) ", %0" \ + : \ + : "rK"(__v) \ + : "memory"); \ + }) + +/** + * \brief CSR operation Macro for csrrs instruction. + * \details + * Read the content of csr register to __v, + * then set csr register to be __v | val, then return __v + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val Mask value to be used wih csrrs instruction + * \return the CSR register value before written + */ +#define __RV_CSR_READ_SET(csr, val) \ + ({ \ + rv_csr_t __v = (rv_csr_t)(val); \ + __ASM volatile("csrrs %0, " STRINGIFY(csr) ", %1" \ + : "=r"(__v) \ + : "rK"(__v) \ + : "memory"); \ + __v; \ + }) + +/** + * \brief CSR operation Macro for csrs instruction. + * \details + * Set csr register to be csr_content | val + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val Mask value to be used wih csrs instruction + */ +#define __RV_CSR_SET(csr, val) \ + ({ \ + rv_csr_t __v = (rv_csr_t)(val); \ + __ASM volatile("csrs " STRINGIFY(csr) ", %0" \ + : \ + : "rK"(__v) \ + : "memory"); \ + }) + +/** + * \brief CSR operation Macro for csrrc instruction. + * \details + * Read the content of csr register to __v, + * then set csr register to be __v & ~val, then return __v + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val Mask value to be used wih csrrc instruction + * \return the CSR register value before written + */ +#define __RV_CSR_READ_CLEAR(csr, val) \ + ({ \ + rv_csr_t __v = (rv_csr_t)(val); \ + __ASM volatile("csrrc %0, " STRINGIFY(csr) ", %1" \ + : "=r"(__v) \ + : "rK"(__v) \ + : "memory"); \ + __v; \ + }) + +/** + * \brief CSR operation Macro for csrc instruction. + * \details + * Set csr register to be csr_content & ~val + * \param csr CSR macro definition defined in + * \ref NMSIS_Core_CSR_Registers, eg. \ref CSR_MSTATUS + * \param val Mask value to be used wih csrc instruction + */ +#define __RV_CSR_CLEAR(csr, val) \ + ({ \ + rv_csr_t __v = (rv_csr_t)(val); \ + __ASM volatile("csrc " STRINGIFY(csr) ", %0" \ + : \ + : "rK"(__v) \ + : "memory"); \ + }) +#else + +#include + +#define __RV_CSR_SWAP __write_csr +#define __RV_CSR_READ __read_csr +#define __RV_CSR_WRITE __write_csr +#define __RV_CSR_READ_SET __set_bits_csr +#define __RV_CSR_SET __set_bits_csr +#define __RV_CSR_READ_CLEAR __clear_bits_csr +#define __RV_CSR_CLEAR __clear_bits_csr + +#endif /* __ICCRISCV__ */ + +#endif /* __ASSEMBLY__ */ + +/** + * \brief switch privilege from machine mode to others. + * \details + * Execute into \ref entry_point in \ref mode(supervisor or user) with given stack + * \param mode privilege mode + * \param stack predefined stack, size should set enough + * \param entry_point a function pointer to execute + */ +__STATIC_FORCEINLINE void __switch_mode(uint8_t mode, uintptr_t stack, void(*entry_point)(void)) +{ + unsigned long val = 0; + + /* Set MPP to the requested privilege mode */ + val = __RV_CSR_READ(CSR_MSTATUS); + val = __RV_INSERT_FIELD(val, MSTATUS_MPP, mode); + + /* Set previous MIE disabled */ + val = __RV_INSERT_FIELD(val, MSTATUS_MPIE, 0); + + __RV_CSR_WRITE(CSR_MSTATUS, val); + + /* Set the entry point in MEPC */ + __RV_CSR_WRITE(CSR_MEPC, (unsigned long)entry_point); + + /* Set the register file */ + __ASM volatile("mv sp, %0" ::"r"(stack)); + + __ASM volatile("mret"); +} + +/** + * \brief Enable IRQ Interrupts + * \details Enables IRQ interrupts by setting the MIE-bit in the MSTATUS Register. + * \remarks + * Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __RV_CSR_SET(CSR_MSTATUS, MSTATUS_MIE); +} + +/** + * \brief Disable IRQ Interrupts + * \details Disables IRQ interrupts by clearing the MIE-bit in the MSTATUS Register. + * \remarks + * Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_MIE); +} + +/** + * \brief Enable External IRQ Interrupts + * \details Enables External IRQ interrupts by setting the MEIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_ext_irq(void) +{ + __RV_CSR_SET(CSR_MIE, MIE_MEIE); +} + +/** + * \brief Disable External IRQ Interrupts + * \details Disables External IRQ interrupts by clearing the MEIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_ext_irq(void) +{ + __RV_CSR_CLEAR(CSR_MIE, MIE_MEIE); +} + +/** + * \brief Enable Timer IRQ Interrupts + * \details Enables Timer IRQ interrupts by setting the MTIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_timer_irq(void) +{ + __RV_CSR_SET(CSR_MIE, MIE_MTIE); +} + +/** + * \brief Disable Timer IRQ Interrupts + * \details Disables Timer IRQ interrupts by clearing the MTIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_timer_irq(void) +{ + __RV_CSR_CLEAR(CSR_MIE, MIE_MTIE); +} + +/** + * \brief Enable software IRQ Interrupts + * \details Enables software IRQ interrupts by setting the MSIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_sw_irq(void) +{ + __RV_CSR_SET(CSR_MIE, MIE_MSIE); +} + +/** + * \brief Disable software IRQ Interrupts + * \details Disables software IRQ interrupts by clearing the MSIE-bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_sw_irq(void) +{ + __RV_CSR_CLEAR(CSR_MIE, MIE_MSIE); +} + +/** + * \brief Disable Core IRQ Interrupt + * \details Disable Core IRQ interrupt by clearing the irq bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_core_irq(uint32_t irq) +{ + __RV_CSR_CLEAR(CSR_MIE, 1 << irq); +} + +/** + * \brief Enable Core IRQ Interrupt + * \details Enable Core IRQ interrupt by setting the irq bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_core_irq(uint32_t irq) +{ + __RV_CSR_SET(CSR_MIE, 1 << irq); +} + +/** + * \brief Get Core IRQ Interrupt Pending status + * \details Get Core IRQ interrupt pending status of irq bit. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE uint32_t __get_core_irq_pending(uint32_t irq) +{ + return ((__RV_CSR_READ(CSR_MIP) >> irq) & 0x1); +} + +/** + * \brief Clear Core IRQ Interrupt Pending status + * \details Clear Core IRQ interrupt pending status of irq bit. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __clear_core_irq_pending(uint32_t irq) +{ + __RV_CSR_SET(CSR_MIP, 1 << irq); +} + +/** + * \brief Enable IRQ Interrupts in supervisor mode + * \details Enables IRQ interrupts by setting the SIE-bit in the SSTATUS Register. + * \remarks + * Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq_s(void) +{ + __RV_CSR_SET(CSR_SSTATUS, SSTATUS_SIE); +} + +/** + * \brief Disable IRQ Interrupts in supervisor mode + * \details Disables IRQ interrupts by clearing the SIE-bit in the SSTATUS Register. + * \remarks + * Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq_s(void) +{ + __RV_CSR_CLEAR(CSR_SSTATUS, SSTATUS_SIE); +} + +/** + * \brief Enable External IRQ Interrupts in supervisor mode + * \details Enables External IRQ interrupts by setting the SEIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_ext_irq_s(void) +{ + __RV_CSR_SET(CSR_SIE, MIE_SEIE); +} + +/** + * \brief Disable External IRQ Interrupts in supervisor mode + * \details Disables External IRQ interrupts by clearing the SEIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_ext_irq_s(void) +{ + __RV_CSR_CLEAR(CSR_SIE, MIE_SEIE); +} + +/** + * \brief Enable Timer IRQ Interrupts in supervisor mode + * \details Enables Timer IRQ interrupts by setting the STIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_timer_irq_s(void) +{ + __RV_CSR_SET(CSR_SIE, MIE_STIE); +} + +/** + * \brief Disable Timer IRQ Interrupts in supervisor mode + * \details Disables Timer IRQ interrupts by clearing the STIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_timer_irq_s(void) +{ + __RV_CSR_CLEAR(CSR_SIE, MIE_STIE); +} + +/** + * \brief Enable software IRQ Interrupts in supervisor mode + * \details Enables software IRQ interrupts by setting the SSIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_sw_irq_s(void) +{ + __RV_CSR_SET(CSR_MIE, MIE_SSIE); +} + +/** + * \brief Disable software IRQ Interrupts in supervisor mode + * \details Disables software IRQ interrupts by clearing the SSIE-bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_sw_irq_s(void) +{ + __RV_CSR_CLEAR(CSR_SIE, MIE_SSIE); +} + +/** + * \brief Disable Core IRQ Interrupt in supervisor mode + * \details Disable Core IRQ interrupt by clearing the irq bit in the SIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __disable_core_irq_s(uint32_t irq) +{ + __RV_CSR_CLEAR(CSR_SIE, 1 << irq); +} + +/** + * \brief Enable Core IRQ Interrupt in supervisor mode + * \details Enable Core IRQ interrupt by setting the irq bit in the MIE Register. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __enable_core_irq_s(uint32_t irq) +{ + __RV_CSR_SET(CSR_SIE, 1 << irq); +} + +/** + * \brief Get Core IRQ Interrupt Pending status in supervisor mode + * \details Get Core IRQ interrupt pending status of irq bit. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE uint32_t __get_core_irq_pending_s(uint32_t irq) +{ + return ((__RV_CSR_READ(CSR_SIP) >> irq) & 0x1); +} + +/** + * \brief Clear Core IRQ Interrupt Pending status in supervisor mode + * \details Clear Core IRQ interrupt pending status of irq bit. + * \remarks + * Can only be executed in Privileged modes, available for plic interrupt mode. + */ +__STATIC_FORCEINLINE void __clear_core_irq_pending_s(uint32_t irq) +{ + __RV_CSR_SET(CSR_SIP, 1 << irq); +} + +/** + * \brief Read whole 64 bits value of mcycle counter + * \details This function will read the whole 64 bits of MCYCLE register + * \return The whole 64 bits value of MCYCLE + * \remarks It will work for both RV32 and RV64 to get full 64bits value of MCYCLE + */ +__STATIC_FORCEINLINE uint64_t __get_rv_cycle(void) +{ +#if __RISCV_XLEN == 32 + volatile uint32_t high0, low, high; + uint64_t full; + + high0 = __RV_CSR_READ(CSR_MCYCLEH); + low = __RV_CSR_READ(CSR_MCYCLE); + high = __RV_CSR_READ(CSR_MCYCLEH); + if (high0 != high) { + low = __RV_CSR_READ(CSR_MCYCLE); + } + full = (((uint64_t)high) << 32) | low; + return full; +#elif __RISCV_XLEN == 64 + return (uint64_t)__RV_CSR_READ(CSR_MCYCLE); +#else // TODO Need cover for XLEN=128 case in future + return (uint64_t)__RV_CSR_READ(CSR_MCYCLE); +#endif +} + +/** + * \brief Set whole 64 bits value of mcycle counter + * \details This function will set the whole 64 bits of MCYCLE register + * \remarks It will work for both RV32 and RV64 to set full 64bits value of MCYCLE + */ +__STATIC_FORCEINLINE void __set_rv_cycle(uint64_t cycle) +{ +#if __RISCV_XLEN == 32 + __RV_CSR_WRITE(CSR_MCYCLE, 0); // prevent carry + __RV_CSR_WRITE(CSR_MCYCLEH, (uint32_t)(cycle >> 32)); + __RV_CSR_WRITE(CSR_MCYCLE, (uint32_t)(cycle)); +#elif __RISCV_XLEN == 64 + __RV_CSR_WRITE(CSR_MCYCLE, cycle); +#else // TODO Need cover for XLEN=128 case in future +#endif +} + +/** + * \brief Read whole 64 bits value of machine instruction-retired counter + * \details This function will read the whole 64 bits of MINSTRET register + * \return The whole 64 bits value of MINSTRET + * \remarks It will work for both RV32 and RV64 to get full 64bits value of MINSTRET + */ +__STATIC_FORCEINLINE uint64_t __get_rv_instret(void) +{ +#if __RISCV_XLEN == 32 + volatile uint32_t high0, low, high; + uint64_t full; + + high0 = __RV_CSR_READ(CSR_MINSTRETH); + low = __RV_CSR_READ(CSR_MINSTRET); + high = __RV_CSR_READ(CSR_MINSTRETH); + if (high0 != high) { + low = __RV_CSR_READ(CSR_MINSTRET); + } + full = (((uint64_t)high) << 32) | low; + return full; +#elif __RISCV_XLEN == 64 + return (uint64_t)__RV_CSR_READ(CSR_MINSTRET); +#else // TODO Need cover for XLEN=128 case in future + return (uint64_t)__RV_CSR_READ(CSR_MINSTRET); +#endif +} + +/** + * \brief Set whole 64 bits value of machine instruction-retired counter + * \details This function will set the whole 64 bits of MINSTRET register + * \remarks It will work for both RV32 and RV64 to set full 64bits value of MINSTRET + */ +__STATIC_FORCEINLINE void __set_rv_instret(uint64_t instret) +{ +#if __RISCV_XLEN == 32 + __RV_CSR_WRITE(CSR_MINSTRET, 0); // prevent carry + __RV_CSR_WRITE(CSR_MINSTRETH, (uint32_t)(instret >> 32)); + __RV_CSR_WRITE(CSR_MINSTRET, (uint32_t)(instret)); +#elif __RISCV_XLEN == 64 + __RV_CSR_WRITE(CSR_MINSTRET, instret); +#else // TODO Need cover for XLEN=128 case in future +#endif +} + +/** + * \brief Read whole 64 bits value of real-time clock + * \details This function will read the whole 64 bits of TIME register + * \return The whole 64 bits value of TIME CSR + * \remarks It will work for both RV32 and RV64 to get full 64bits value of TIME + * \attention only available when user mode available + */ +__STATIC_FORCEINLINE uint64_t __get_rv_time(void) +{ +#if __RISCV_XLEN == 32 + volatile uint32_t high0, low, high; + uint64_t full; + + high0 = __RV_CSR_READ(CSR_TIMEH); + low = __RV_CSR_READ(CSR_TIME); + high = __RV_CSR_READ(CSR_TIMEH); + if (high0 != high) { + low = __RV_CSR_READ(CSR_TIME); + } + full = (((uint64_t)high) << 32) | low; + return full; +#elif __RISCV_XLEN == 64 + return (uint64_t)__RV_CSR_READ(CSR_TIME); +#else // TODO Need cover for XLEN=128 case in future + return (uint64_t)__RV_CSR_READ(CSR_TIME); +#endif +} + +/** + * \brief Get cluster id of current cluster + * \details This function will get cluster id of current cluster in a multiple cluster system + * \return The cluster id of current cluster + * \remarks mhartid bit 15-8 is designed for cluster id in nuclei subsystem reference design + * \attention function is allowed in machine mode only + */ +__STATIC_FORCEINLINE unsigned long __get_cluster_id(void) +{ + unsigned long id; + + id = (__RV_CSR_READ(CSR_MHARTID) >> 8) & 0xFF; + return id; +} + +/** + * \brief Get hart index of current cluster + * \details This function will get hart index of current cluster in a multiple cluster system, + * hart index is hartid - hartid offset, for example if your hartid is 1, and offset is 1, then + * hart index is 0 + * \return The hart index of current cluster + * \attention function is allowed in machine mode only + */ +__STATIC_FORCEINLINE unsigned long __get_hart_index(void) +{ + unsigned long id; +#ifdef __HARTID_OFFSET + id = __RV_CSR_READ(CSR_MHARTID) - __HARTID_OFFSET; +#else + id = __RV_CSR_READ(CSR_MHARTID); +#endif + return id; +} + +/** + * \brief Get hart id of current cluster + * \details This function will get hart id of current cluster in a multiple cluster system + * \return The hart id of current cluster + * \remarks it will return full hartid not part of it for reference subsystem design, + * if your reference subsystem design has hartid offset, please define __HARTID_OFFSET in + * .h + * \attention function is allowed in machine mode only + */ +__STATIC_FORCEINLINE unsigned long __get_hart_id(void) +{ + unsigned long id; + id = __RV_CSR_READ(CSR_MHARTID); + return id; +} + +/** @} */ /* End of Doxygen Group NMSIS_Core_CSR_Register_Access */ + +/* ########################### CPU Intrinsic Functions ########################### */ +/** + * \defgroup NMSIS_Core_CPU_Intrinsic Intrinsic Functions for CPU Intructions + * \ingroup NMSIS_Core + * \brief Functions that generate RISC-V CPU instructions. + * \details + * + * The following functions generate specified RISC-V instructions that cannot be directly accessed by compiler. + * @{ + */ + +/** + * \brief NOP Instruction + * \details + * No Operation does nothing. + * This instruction can be used for code alignment purposes. + */ +__STATIC_FORCEINLINE void __NOP(void) +{ + __ASM volatile("nop"); +} + +/** + * \brief Wait For Interrupt + * \details + * Wait For Interrupt is is executed using CSR_WFE.WFE=0 and WFI instruction. + * It will suspends execution until interrupt, NMI or Debug happened. + * When Core is waked up by interrupt, if + * 1. mstatus.MIE == 1(interrupt enabled), Core will enter ISR code + * 2. mstatus.MIE == 0(interrupt disabled), Core will resume previous execution + */ +__STATIC_FORCEINLINE void __WFI(void) +{ + __RV_CSR_CLEAR(CSR_WFE, WFE_WFE); + __ASM volatile("wfi"); +} + +/** + * \brief Wait For Event + * \details + * Wait For Event is executed using CSR_WFE.WFE=1 and WFI instruction. + * It will suspends execution until event, NMI or Debug happened. + * When Core is waked up, Core will resume previous execution + */ +__STATIC_FORCEINLINE void __WFE(void) +{ + __RV_CSR_SET(CSR_WFE, WFE_WFE); + __ASM volatile("wfi"); + __RV_CSR_CLEAR(CSR_WFE, WFE_WFE); +} + +/** + * \brief Breakpoint Instruction + * \details + * Causes the processor to enter Debug state. + * Debug tools can use this to investigate system state + * when the instruction at a particular address is reached. + */ +__STATIC_FORCEINLINE void __EBREAK(void) +{ + __ASM volatile("ebreak"); +} + +/** + * \brief Environment Call Instruction + * \details + * The ECALL instruction is used to make a service request to + * the execution environment. + */ +__STATIC_FORCEINLINE void __ECALL(void) +{ + __ASM volatile("ecall"); +} + +/** + * \brief WFI Sleep Mode enumeration + */ +typedef enum WFI_SleepMode { + WFI_SHALLOW_SLEEP = 0, /*!< Shallow sleep mode, the core_clk will poweroff */ + WFI_DEEP_SLEEP = 1 /*!< Deep sleep mode, the core_clk and core_ano_clk will poweroff */ +} WFI_SleepMode_Type; + +/** + * \brief Set Sleep mode of WFI + * \details + * Set the SLEEPVALUE CSR register to control the + * WFI Sleep mode. + * \param[in] mode The sleep mode to be set + */ +__STATIC_FORCEINLINE void __set_wfi_sleepmode(WFI_SleepMode_Type mode) +{ + __RV_CSR_WRITE(CSR_SLEEPVALUE, mode); +} + +/** + * \brief Send TX Event + * \details + * Set the CSR TXEVT to control send a TX Event. + * The Core will output signal tx_evt as output event signal. + */ +__STATIC_FORCEINLINE void __TXEVT(void) +{ + __RV_CSR_SET(CSR_TXEVT, 0x1); +} + +/** + * \brief Enable MCYCLE counter + * \details + * Clear the CY bit of MCOUNTINHIBIT to 0 to enable MCYCLE Counter + */ +__STATIC_FORCEINLINE void __enable_mcycle_counter(void) +{ + __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_CY); +} + +/** + * \brief Disable MCYCLE counter + * \details + * Set the CY bit of MCOUNTINHIBIT to 1 to disable MCYCLE Counter + */ +__STATIC_FORCEINLINE void __disable_mcycle_counter(void) +{ + __RV_CSR_SET(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_CY); +} + +/** + * \brief Enable MINSTRET counter + * \details + * Clear the IR bit of MCOUNTINHIBIT to 0 to enable MINSTRET Counter + */ +__STATIC_FORCEINLINE void __enable_minstret_counter(void) +{ + __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_IR); +} + +/** + * \brief Disable MINSTRET counter + * \details + * Set the IR bit of MCOUNTINHIBIT to 1 to disable MINSTRET Counter + */ +__STATIC_FORCEINLINE void __disable_minstret_counter(void) +{ + __RV_CSR_SET(CSR_MCOUNTINHIBIT, MCOUNTINHIBIT_IR); +} + +/** + * \brief Enable selected hardware performance monitor counter + * \param [in] idx the index of the hardware performance monitor counter + * \details + * enable selected hardware performance monitor counter mhpmcounterx. + */ +__STATIC_FORCEINLINE void __enable_mhpm_counter(unsigned long idx) +{ + __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, (1 << idx)); +} + +/** + * \brief Disable selected hardware performance monitor counter + * \param [in] idx the index of the hardware performance monitor counter + * \details + * Disable selected hardware performance monitor counter mhpmcounterx. + */ +__STATIC_FORCEINLINE void __disable_mhpm_counter(unsigned long idx) +{ + __RV_CSR_SET(CSR_MCOUNTINHIBIT, (1 << idx)); +} + +/** + * \brief Enable hardware performance counters with mask + * \param [in] mask mask of selected hardware performance monitor counters + * \details + * enable mhpmcounterx with mask, only the masked ones will be enabled. + * mhpmcounter3-mhpmcount31 are for high performance monitor counters. + */ +__STATIC_FORCEINLINE void __enable_mhpm_counters(unsigned long mask) +{ + __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, mask); +} + +/** + * \brief Disable hardware performance counters with mask + * \param [in] mask mask of selected hardware performance monitor counters + * \details + * Disable mhpmcounterx with mask, only the masked ones will be disabled. + * mhpmcounter3-mhpmcount31 are for high performance monitor counters. + */ +__STATIC_FORCEINLINE void __disable_mhpm_counters(unsigned long mask) +{ + __RV_CSR_SET(CSR_MCOUNTINHIBIT, mask); +} + +/** + * \brief Enable all MCYCLE & MINSTRET & MHPMCOUNTER counter + * \details + * Clear all to zero to enable all counters, + * such as cycle, instret, high performance monitor counters + */ +__STATIC_FORCEINLINE void __enable_all_counter(void) +{ + __RV_CSR_CLEAR(CSR_MCOUNTINHIBIT, 0xFFFFFFFF); +} + +/** + * \brief Disable all MCYCLE & MINSTRET & MHPMCOUNTER counter + * \details + * Set all to one to disable all counters, + * such as cycle, instret, high performance monitor counters + */ +__STATIC_FORCEINLINE void __disable_all_counter(void) +{ + __RV_CSR_SET(CSR_MCOUNTINHIBIT, 0xFFFFFFFF); +} + +/** + * \brief Set event for selected high performance monitor event + * \param [in] idx HPMEVENTx CSR index(3-31) + * \param [in] event HPMEVENTx Register value to set + * \details + * Set event for high performance monitor event register + */ +__STATIC_FORCEINLINE void __set_hpm_event(unsigned long idx, unsigned long event) +{ + switch (idx) { + case 3: __RV_CSR_WRITE(CSR_MHPMEVENT3, event); break; + case 4: __RV_CSR_WRITE(CSR_MHPMEVENT4, event); break; + case 5: __RV_CSR_WRITE(CSR_MHPMEVENT5, event); break; + case 6: __RV_CSR_WRITE(CSR_MHPMEVENT6, event); break; + case 7: __RV_CSR_WRITE(CSR_MHPMEVENT7, event); break; + case 8: __RV_CSR_WRITE(CSR_MHPMEVENT8, event); break; + case 9: __RV_CSR_WRITE(CSR_MHPMEVENT9, event); break; + case 10: __RV_CSR_WRITE(CSR_MHPMEVENT10, event); break; + case 11: __RV_CSR_WRITE(CSR_MHPMEVENT11, event); break; + case 12: __RV_CSR_WRITE(CSR_MHPMEVENT12, event); break; + case 13: __RV_CSR_WRITE(CSR_MHPMEVENT13, event); break; + case 14: __RV_CSR_WRITE(CSR_MHPMEVENT14, event); break; + case 15: __RV_CSR_WRITE(CSR_MHPMEVENT15, event); break; + case 16: __RV_CSR_WRITE(CSR_MHPMEVENT16, event); break; + case 17: __RV_CSR_WRITE(CSR_MHPMEVENT17, event); break; + case 18: __RV_CSR_WRITE(CSR_MHPMEVENT18, event); break; + case 19: __RV_CSR_WRITE(CSR_MHPMEVENT19, event); break; + case 20: __RV_CSR_WRITE(CSR_MHPMEVENT20, event); break; + case 21: __RV_CSR_WRITE(CSR_MHPMEVENT21, event); break; + case 22: __RV_CSR_WRITE(CSR_MHPMEVENT22, event); break; + case 23: __RV_CSR_WRITE(CSR_MHPMEVENT23, event); break; + case 24: __RV_CSR_WRITE(CSR_MHPMEVENT24, event); break; + case 25: __RV_CSR_WRITE(CSR_MHPMEVENT25, event); break; + case 26: __RV_CSR_WRITE(CSR_MHPMEVENT26, event); break; + case 27: __RV_CSR_WRITE(CSR_MHPMEVENT27, event); break; + case 28: __RV_CSR_WRITE(CSR_MHPMEVENT28, event); break; + case 29: __RV_CSR_WRITE(CSR_MHPMEVENT29, event); break; + case 30: __RV_CSR_WRITE(CSR_MHPMEVENT30, event); break; + case 31: __RV_CSR_WRITE(CSR_MHPMEVENT31, event); break; + default: break; + } +} + +/** + * \brief Get event for selected high performance monitor event + * \param [in] idx HPMEVENTx CSR index(3-31) + * \param [in] event HPMEVENTx Register value to set + * \details + * Get high performance monitor event register value + * \return HPMEVENTx Register value + */ +__STATIC_FORCEINLINE unsigned long __get_hpm_event(unsigned long idx) +{ + switch (idx) { + case 3: return __RV_CSR_READ(CSR_MHPMEVENT3); + case 4: return __RV_CSR_READ(CSR_MHPMEVENT4); + case 5: return __RV_CSR_READ(CSR_MHPMEVENT5); + case 6: return __RV_CSR_READ(CSR_MHPMEVENT6); + case 7: return __RV_CSR_READ(CSR_MHPMEVENT7); + case 8: return __RV_CSR_READ(CSR_MHPMEVENT8); + case 9: return __RV_CSR_READ(CSR_MHPMEVENT9); + case 10: return __RV_CSR_READ(CSR_MHPMEVENT10); + case 11: return __RV_CSR_READ(CSR_MHPMEVENT11); + case 12: return __RV_CSR_READ(CSR_MHPMEVENT12); + case 13: return __RV_CSR_READ(CSR_MHPMEVENT13); + case 14: return __RV_CSR_READ(CSR_MHPMEVENT14); + case 15: return __RV_CSR_READ(CSR_MHPMEVENT15); + case 16: return __RV_CSR_READ(CSR_MHPMEVENT16); + case 17: return __RV_CSR_READ(CSR_MHPMEVENT17); + case 18: return __RV_CSR_READ(CSR_MHPMEVENT18); + case 19: return __RV_CSR_READ(CSR_MHPMEVENT19); + case 20: return __RV_CSR_READ(CSR_MHPMEVENT20); + case 21: return __RV_CSR_READ(CSR_MHPMEVENT21); + case 22: return __RV_CSR_READ(CSR_MHPMEVENT22); + case 23: return __RV_CSR_READ(CSR_MHPMEVENT23); + case 24: return __RV_CSR_READ(CSR_MHPMEVENT24); + case 25: return __RV_CSR_READ(CSR_MHPMEVENT25); + case 26: return __RV_CSR_READ(CSR_MHPMEVENT26); + case 27: return __RV_CSR_READ(CSR_MHPMEVENT27); + case 28: return __RV_CSR_READ(CSR_MHPMEVENT28); + case 29: return __RV_CSR_READ(CSR_MHPMEVENT29); + case 30: return __RV_CSR_READ(CSR_MHPMEVENT30); + case 31: return __RV_CSR_READ(CSR_MHPMEVENT31); + default: return 0; + } +} + +/** + * \brief Set value for selected high performance monitor counter + * \param [in] idx HPMCOUNTERx CSR index(3-31) + * \param [in] value HPMCOUNTERx Register value to set + * \details + * Set value for high performance monitor couner register + */ +__STATIC_FORCEINLINE void __set_hpm_counter(unsigned long idx, uint64_t value) +{ + switch (idx) { +#if __RISCV_XLEN == 32 + case 3: __RV_CSR_WRITE(CSR_MHPMCOUNTER3, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER3H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER3, (uint32_t)(value)); break; + case 4: __RV_CSR_WRITE(CSR_MHPMCOUNTER4, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER4H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER4, (uint32_t)(value)); break; + case 5: __RV_CSR_WRITE(CSR_MHPMCOUNTER5, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER5H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER5, (uint32_t)(value)); break; + case 6: __RV_CSR_WRITE(CSR_MHPMCOUNTER6, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER6H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER6, (uint32_t)(value)); break; + case 7: __RV_CSR_WRITE(CSR_MHPMCOUNTER7, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER7H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER7, (uint32_t)(value)); break; + case 8: __RV_CSR_WRITE(CSR_MHPMCOUNTER8, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER8H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER8, (uint32_t)(value)); break; + case 9: __RV_CSR_WRITE(CSR_MHPMCOUNTER9, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER9H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER9, (uint32_t)(value)); break; + case 10: __RV_CSR_WRITE(CSR_MHPMCOUNTER10, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER10H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER10, (uint32_t)(value)); break; + case 11: __RV_CSR_WRITE(CSR_MHPMCOUNTER11, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER11H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER11, (uint32_t)(value)); break; + case 12: __RV_CSR_WRITE(CSR_MHPMCOUNTER12, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER12H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER12, (uint32_t)(value)); break; + case 13: __RV_CSR_WRITE(CSR_MHPMCOUNTER13, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER13H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER13, (uint32_t)(value)); break; + case 14: __RV_CSR_WRITE(CSR_MHPMCOUNTER14, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER14H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER14, (uint32_t)(value)); break; + case 15: __RV_CSR_WRITE(CSR_MHPMCOUNTER15, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER15H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER15, (uint32_t)(value)); break; + case 16: __RV_CSR_WRITE(CSR_MHPMCOUNTER16, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER16H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER16, (uint32_t)(value)); break; + case 17: __RV_CSR_WRITE(CSR_MHPMCOUNTER17, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER17H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER17, (uint32_t)(value)); break; + case 18: __RV_CSR_WRITE(CSR_MHPMCOUNTER18, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER18H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER18, (uint32_t)(value)); break; + case 19: __RV_CSR_WRITE(CSR_MHPMCOUNTER19, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER19H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER19, (uint32_t)(value)); break; + case 20: __RV_CSR_WRITE(CSR_MHPMCOUNTER20, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER20H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER20, (uint32_t)(value)); break; + case 21: __RV_CSR_WRITE(CSR_MHPMCOUNTER21, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER21H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER21, (uint32_t)(value)); break; + case 22: __RV_CSR_WRITE(CSR_MHPMCOUNTER22, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER22H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER22, (uint32_t)(value)); break; + case 23: __RV_CSR_WRITE(CSR_MHPMCOUNTER23, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER23H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER23, (uint32_t)(value)); break; + case 24: __RV_CSR_WRITE(CSR_MHPMCOUNTER24, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER24H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER24, (uint32_t)(value)); break; + case 25: __RV_CSR_WRITE(CSR_MHPMCOUNTER25, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER25H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER25, (uint32_t)(value)); break; + case 26: __RV_CSR_WRITE(CSR_MHPMCOUNTER26, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER26H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER26, (uint32_t)(value)); break; + case 27: __RV_CSR_WRITE(CSR_MHPMCOUNTER27, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER27H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER27, (uint32_t)(value)); break; + case 28: __RV_CSR_WRITE(CSR_MHPMCOUNTER28, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER28H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER28, (uint32_t)(value)); break; + case 29: __RV_CSR_WRITE(CSR_MHPMCOUNTER29, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER29H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER29, (uint32_t)(value)); break; + case 30: __RV_CSR_WRITE(CSR_MHPMCOUNTER30, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER30H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER30, (uint32_t)(value)); break; + case 31: __RV_CSR_WRITE(CSR_MHPMCOUNTER31, 0); // prevent carry + __RV_CSR_WRITE(CSR_MHPMCOUNTER31H, (uint32_t)(value >> 32)); + __RV_CSR_WRITE(CSR_MHPMCOUNTER31, (uint32_t)(value)); break; + +#elif __RISCV_XLEN == 64 + case 3: __RV_CSR_WRITE(CSR_MHPMCOUNTER3, (value)); break; + case 4: __RV_CSR_WRITE(CSR_MHPMCOUNTER4, (value)); break; + case 5: __RV_CSR_WRITE(CSR_MHPMCOUNTER5, (value)); break; + case 6: __RV_CSR_WRITE(CSR_MHPMCOUNTER6, (value)); break; + case 7: __RV_CSR_WRITE(CSR_MHPMCOUNTER7, (value)); break; + case 8: __RV_CSR_WRITE(CSR_MHPMCOUNTER8, (value)); break; + case 9: __RV_CSR_WRITE(CSR_MHPMCOUNTER9, (value)); break; + case 10: __RV_CSR_WRITE(CSR_MHPMCOUNTER10, (value)); break; + case 11: __RV_CSR_WRITE(CSR_MHPMCOUNTER11, (value)); break; + case 12: __RV_CSR_WRITE(CSR_MHPMCOUNTER12, (value)); break; + case 13: __RV_CSR_WRITE(CSR_MHPMCOUNTER13, (value)); break; + case 14: __RV_CSR_WRITE(CSR_MHPMCOUNTER14, (value)); break; + case 15: __RV_CSR_WRITE(CSR_MHPMCOUNTER15, (value)); break; + case 16: __RV_CSR_WRITE(CSR_MHPMCOUNTER16, (value)); break; + case 17: __RV_CSR_WRITE(CSR_MHPMCOUNTER17, (value)); break; + case 18: __RV_CSR_WRITE(CSR_MHPMCOUNTER18, (value)); break; + case 19: __RV_CSR_WRITE(CSR_MHPMCOUNTER19, (value)); break; + case 20: __RV_CSR_WRITE(CSR_MHPMCOUNTER20, (value)); break; + case 21: __RV_CSR_WRITE(CSR_MHPMCOUNTER21, (value)); break; + case 22: __RV_CSR_WRITE(CSR_MHPMCOUNTER22, (value)); break; + case 23: __RV_CSR_WRITE(CSR_MHPMCOUNTER23, (value)); break; + case 24: __RV_CSR_WRITE(CSR_MHPMCOUNTER24, (value)); break; + case 25: __RV_CSR_WRITE(CSR_MHPMCOUNTER25, (value)); break; + case 26: __RV_CSR_WRITE(CSR_MHPMCOUNTER26, (value)); break; + case 27: __RV_CSR_WRITE(CSR_MHPMCOUNTER27, (value)); break; + case 28: __RV_CSR_WRITE(CSR_MHPMCOUNTER28, (value)); break; + case 29: __RV_CSR_WRITE(CSR_MHPMCOUNTER29, (value)); break; + case 30: __RV_CSR_WRITE(CSR_MHPMCOUNTER30, (value)); break; + case 31: __RV_CSR_WRITE(CSR_MHPMCOUNTER31, (value)); break; + +#else +#endif + default: break; + } +} + +/** + * \brief Get value of selected high performance monitor couner + * \param [in] idx HPMCOUNTERx CSR index(3-31) + * \param [in] event HPMCOUNTERx Register value to set + * \details + * Get high performance monitor counter register value + * \return HPMCOUNTERx Register value + */ +__STATIC_FORCEINLINE unsigned long __get_hpm_counter(unsigned long idx) +{ +#if __RISCV_XLEN == 32 + volatile uint32_t high0, low, high; + uint64_t full; + + switch (idx) { + case 0: return __get_rv_cycle(); + case 2: return __get_rv_instret(); + case 3: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER3H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER3); + high = __RV_CSR_READ(CSR_MHPMCOUNTER3H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER3); } + full = (((uint64_t)high) << 32) | low; return full; + case 4: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER4H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER4); + high = __RV_CSR_READ(CSR_MHPMCOUNTER4H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER4); } + full = (((uint64_t)high) << 32) | low; return full; + case 5: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER5H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER5); + high = __RV_CSR_READ(CSR_MHPMCOUNTER5H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER5); } + full = (((uint64_t)high) << 32) | low; return full; + case 6: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER6H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER6); + high = __RV_CSR_READ(CSR_MHPMCOUNTER6H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER6); } + full = (((uint64_t)high) << 32) | low; return full; + case 7: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER7H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER7); + high = __RV_CSR_READ(CSR_MHPMCOUNTER7H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER7); } + full = (((uint64_t)high) << 32) | low; return full; + case 8: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER8H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER8); + high = __RV_CSR_READ(CSR_MHPMCOUNTER8H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER8); } + full = (((uint64_t)high) << 32) | low; return full; + case 9: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER9H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER9); + high = __RV_CSR_READ(CSR_MHPMCOUNTER9H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER9); } + full = (((uint64_t)high) << 32) | low; return full; + case 10: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER10H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER10); + high = __RV_CSR_READ(CSR_MHPMCOUNTER10H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER10); } + full = (((uint64_t)high) << 32) | low; return full; + case 11: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER11H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER11); + high = __RV_CSR_READ(CSR_MHPMCOUNTER11H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER11); } + full = (((uint64_t)high) << 32) | low; return full; + case 12: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER12H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER12); + high = __RV_CSR_READ(CSR_MHPMCOUNTER12H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER12); } + full = (((uint64_t)high) << 32) | low; return full; + case 13: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER13H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER13); + high = __RV_CSR_READ(CSR_MHPMCOUNTER13H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER13); } + full = (((uint64_t)high) << 32) | low; return full; + case 14: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER14H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER14); + high = __RV_CSR_READ(CSR_MHPMCOUNTER14H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER14); } + full = (((uint64_t)high) << 32) | low; return full; + case 15: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER15H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER15); + high = __RV_CSR_READ(CSR_MHPMCOUNTER15H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER15); } + full = (((uint64_t)high) << 32) | low; return full; + case 16: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER16H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER16); + high = __RV_CSR_READ(CSR_MHPMCOUNTER16H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER16); } + full = (((uint64_t)high) << 32) | low; return full; + case 17: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER17H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER17); + high = __RV_CSR_READ(CSR_MHPMCOUNTER17H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER17); } + full = (((uint64_t)high) << 32) | low; return full; + case 18: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER18H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER18); + high = __RV_CSR_READ(CSR_MHPMCOUNTER18H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER18); } + full = (((uint64_t)high) << 32) | low; return full; + case 19: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER19H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER19); + high = __RV_CSR_READ(CSR_MHPMCOUNTER19H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER19); } + full = (((uint64_t)high) << 32) | low; return full; + case 20: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER20H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER20); + high = __RV_CSR_READ(CSR_MHPMCOUNTER20H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER20); } + full = (((uint64_t)high) << 32) | low; return full; + case 21: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER21H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER21); + high = __RV_CSR_READ(CSR_MHPMCOUNTER21H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER21); } + full = (((uint64_t)high) << 32) | low; return full; + case 22: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER22H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER22); + high = __RV_CSR_READ(CSR_MHPMCOUNTER22H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER22); } + full = (((uint64_t)high) << 32) | low; return full; + case 23: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER23H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER23); + high = __RV_CSR_READ(CSR_MHPMCOUNTER23H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER23); } + full = (((uint64_t)high) << 32) | low; return full; + case 24: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER24H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER24); + high = __RV_CSR_READ(CSR_MHPMCOUNTER24H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER24); } + full = (((uint64_t)high) << 32) | low; return full; + case 25: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER25H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER25); + high = __RV_CSR_READ(CSR_MHPMCOUNTER25H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER25); } + full = (((uint64_t)high) << 32) | low; return full; + case 26: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER26H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER26); + high = __RV_CSR_READ(CSR_MHPMCOUNTER26H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER26); } + full = (((uint64_t)high) << 32) | low; return full; + case 27: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER27H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER27); + high = __RV_CSR_READ(CSR_MHPMCOUNTER27H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER27); } + full = (((uint64_t)high) << 32) | low; return full; + case 28: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER28H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER28); + high = __RV_CSR_READ(CSR_MHPMCOUNTER28H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER28); } + full = (((uint64_t)high) << 32) | low; return full; + case 29: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER29H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER29); + high = __RV_CSR_READ(CSR_MHPMCOUNTER29H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER29); } + full = (((uint64_t)high) << 32) | low; return full; + case 30: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER30H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER30); + high = __RV_CSR_READ(CSR_MHPMCOUNTER30H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER30); } + full = (((uint64_t)high) << 32) | low; return full; + case 31: high0 = __RV_CSR_READ(CSR_MHPMCOUNTER31H); + low = __RV_CSR_READ(CSR_MHPMCOUNTER31); + high = __RV_CSR_READ(CSR_MHPMCOUNTER31H); + if (high0 != high) { low = __RV_CSR_READ(CSR_MHPMCOUNTER31); } + full = (((uint64_t)high) << 32) | low; return full; + +#elif __RISCV_XLEN == 64 + switch (idx) { + case 0: return __get_rv_cycle(); + case 2: return __get_rv_instret(); + case 3: return __RV_CSR_READ(CSR_MHPMCOUNTER3); + case 4: return __RV_CSR_READ(CSR_MHPMCOUNTER4); + case 5: return __RV_CSR_READ(CSR_MHPMCOUNTER5); + case 6: return __RV_CSR_READ(CSR_MHPMCOUNTER6); + case 7: return __RV_CSR_READ(CSR_MHPMCOUNTER7); + case 8: return __RV_CSR_READ(CSR_MHPMCOUNTER8); + case 9: return __RV_CSR_READ(CSR_MHPMCOUNTER9); + case 10: return __RV_CSR_READ(CSR_MHPMCOUNTER10); + case 11: return __RV_CSR_READ(CSR_MHPMCOUNTER11); + case 12: return __RV_CSR_READ(CSR_MHPMCOUNTER12); + case 13: return __RV_CSR_READ(CSR_MHPMCOUNTER13); + case 14: return __RV_CSR_READ(CSR_MHPMCOUNTER14); + case 15: return __RV_CSR_READ(CSR_MHPMCOUNTER15); + case 16: return __RV_CSR_READ(CSR_MHPMCOUNTER16); + case 17: return __RV_CSR_READ(CSR_MHPMCOUNTER17); + case 18: return __RV_CSR_READ(CSR_MHPMCOUNTER18); + case 19: return __RV_CSR_READ(CSR_MHPMCOUNTER19); + case 20: return __RV_CSR_READ(CSR_MHPMCOUNTER20); + case 21: return __RV_CSR_READ(CSR_MHPMCOUNTER21); + case 22: return __RV_CSR_READ(CSR_MHPMCOUNTER22); + case 23: return __RV_CSR_READ(CSR_MHPMCOUNTER23); + case 24: return __RV_CSR_READ(CSR_MHPMCOUNTER24); + case 25: return __RV_CSR_READ(CSR_MHPMCOUNTER25); + case 26: return __RV_CSR_READ(CSR_MHPMCOUNTER26); + case 27: return __RV_CSR_READ(CSR_MHPMCOUNTER27); + case 28: return __RV_CSR_READ(CSR_MHPMCOUNTER28); + case 29: return __RV_CSR_READ(CSR_MHPMCOUNTER29); + case 30: return __RV_CSR_READ(CSR_MHPMCOUNTER30); + case 31: return __RV_CSR_READ(CSR_MHPMCOUNTER31); + +#else + switch (idx) { +#endif + default: return 0; + } +} + +/** + * \brief Set exceptions delegation to S mode + * \details Set certain exceptions of supervisor mode or user mode + * delegated from machined mode to supervisor mode. + * \remarks + * Exception should trigger in supervisor mode or user mode. + */ +__STATIC_FORCEINLINE void __set_medeleg(unsigned long mask) +{ + __RV_CSR_WRITE(CSR_MEDELEG, mask); +} + +/** + * \brief Execute fence instruction, p -> pred, s -> succ + * \details + * the FENCE instruction ensures that all memory accesses from instructions preceding + * the fence in program order (the `predecessor set`) appear earlier in the global memory order than + * memory accesses from instructions appearing after the fence in program order (the `successor set`). + * For details, please refer to The RISC-V Instruction Set Manual + * \param p predecessor set, such as iorw, rw, r, w + * \param s successor set, such as iorw, rw, r, w + **/ +#define __FENCE(p, s) __ASM volatile ("fence " #p "," #s : : : "memory") + +/** + * \brief Fence.i Instruction + * \details + * The FENCE.I instruction is used to synchronize the instruction + * and data streams. + */ +__STATIC_FORCEINLINE void __FENCE_I(void) +{ + __ASM volatile("fence.i"); +} + +/** \brief Read & Write Memory barrier */ +#define __RWMB() __FENCE(iorw,iorw) + +/** \brief Read Memory barrier */ +#define __RMB() __FENCE(ir,ir) + +/** \brief Write Memory barrier */ +#define __WMB() __FENCE(ow,ow) + +/** \brief SMP Read & Write Memory barrier */ +#define __SMP_RWMB() __FENCE(rw,rw) + +/** \brief SMP Read Memory barrier */ +#define __SMP_RMB() __FENCE(r,r) + +/** \brief SMP Write Memory barrier */ +#define __SMP_WMB() __FENCE(w,w) + +/** \brief CPU relax for busy loop */ +#define __CPU_RELAX() __ASM volatile ("" : : : "memory") + + +/* ===== Load/Store Operations ===== */ +/** + * \brief Load 8bit value from address (8 bit) + * \details Load 8 bit value. + * \param [in] addr Address pointer to data + * \return value of type uint8_t at (*addr) + */ +__STATIC_FORCEINLINE uint8_t __LB(volatile void *addr) +{ + uint8_t result; + + __ASM volatile ("lb %0, 0(%1)" : "=r" (result) : "r" (addr)); + return result; +} + +/** + * \brief Load 16bit value from address (16 bit) + * \details Load 16 bit value. + * \param [in] addr Address pointer to data + * \return value of type uint16_t at (*addr) + */ +__STATIC_FORCEINLINE uint16_t __LH(volatile void *addr) +{ + uint16_t result; + + __ASM volatile ("lh %0, 0(%1)" : "=r" (result) : "r" (addr)); + return result; +} + +/** + * \brief Load 32bit value from address (32 bit) + * \details Load 32 bit value. + * \param [in] addr Address pointer to data + * \return value of type uint32_t at (*addr) + */ +__STATIC_FORCEINLINE uint32_t __LW(volatile void *addr) +{ + uint32_t result; + + __ASM volatile ("lw %0, 0(%1)" : "=r" (result) : "r" (addr)); + return result; +} + +#if __RISCV_XLEN != 32 +/** + * \brief Load 64bit value from address (64 bit) + * \details Load 64 bit value. + * \param [in] addr Address pointer to data + * \return value of type uint64_t at (*addr) + * \remarks RV64 only macro + */ +__STATIC_FORCEINLINE uint64_t __LD(volatile void *addr) +{ + uint64_t result; + __ASM volatile ("ld %0, 0(%1)" : "=r" (result) : "r" (addr)); + return result; +} +#endif + +/** + * \brief Write 8bit value to address (8 bit) + * \details Write 8 bit value. + * \param [in] addr Address pointer to data + * \param [in] val Value to set + */ +__STATIC_FORCEINLINE void __SB(volatile void *addr, uint8_t val) +{ + __ASM volatile ("sb %0, 0(%1)" : : "r" (val), "r" (addr)); +} + +/** + * \brief Write 16bit value to address (16 bit) + * \details Write 16 bit value. + * \param [in] addr Address pointer to data + * \param [in] val Value to set + */ +__STATIC_FORCEINLINE void __SH(volatile void *addr, uint16_t val) +{ + __ASM volatile ("sh %0, 0(%1)" : : "r" (val), "r" (addr)); +} + +/** + * \brief Write 32bit value to address (32 bit) + * \details Write 32 bit value. + * \param [in] addr Address pointer to data + * \param [in] val Value to set + */ +__STATIC_FORCEINLINE void __SW(volatile void *addr, uint32_t val) +{ + __ASM volatile ("sw %0, 0(%1)" : : "r" (val), "r" (addr)); +} + +#if __RISCV_XLEN != 32 +/** + * \brief Write 64bit value to address (64 bit) + * \details Write 64 bit value. + * \param [in] addr Address pointer to data + * \param [in] val Value to set + */ +__STATIC_FORCEINLINE void __SD(volatile void *addr, uint64_t val) +{ + __ASM volatile ("sd %0, 0(%1)" : : "r" (val), "r" (addr)); +} +#endif + +/** + * \brief Compare and Swap 32bit value using LR and SC + * \details Compare old value with memory, if identical, + * store new value in memory. Return the initial value in memory. + * Success is indicated by comparing return value with OLD. + * memory address, return 0 if successful, otherwise return !0 + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] oldval Old value of the data in address + * \param [in] newval New value to be stored into the address + * \return return the initial value in memory + */ +__STATIC_FORCEINLINE uint32_t __CAS_W(volatile uint32_t *addr, uint32_t oldval, uint32_t newval) +{ + uint32_t result; + uint32_t rc; + + __ASM volatile ( \ + "0: lr.w %0, %2 \n" \ + " bne %0, %z3, 1f \n" \ + " sc.w %1, %z4, %2 \n" \ + " bnez %1, 0b \n" \ + "1:\n" \ + : "=&r"(result), "=&r"(rc), "+A"(*addr) \ + : "r"(oldval), "r"(newval) \ + : "memory"); + return result; +} + +/** + * \brief Atomic Swap 32bit value into memory + * \details Atomically swap new 32bit value into memory using amoswap.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] newval New value to be stored into the address + * \return return the original value in memory + */ +__STATIC_FORCEINLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval) +{ + uint32_t result; + + __ASM volatile ("amoswap.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); + return result; +} + +/** + * \brief Atomic Add with 32bit value + * \details Atomically ADD 32bit value with value in memory using amoadd.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be ADDed + * \return return memory value + add value + */ +__STATIC_FORCEINLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amoadd.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic And with 32bit value + * \details Atomically AND 32bit value with value in memory using amoand.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be ANDed + * \return return memory value & and value + */ +__STATIC_FORCEINLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amoand.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic OR with 32bit value + * \details Atomically OR 32bit value with value in memory using amoor.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be ORed + * \return return memory value | and value + */ +__STATIC_FORCEINLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amoor.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic XOR with 32bit value + * \details Atomically XOR 32bit value with value in memory using amoxor.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be XORed + * \return return memory value ^ and value + */ +__STATIC_FORCEINLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amoxor.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic unsigned MAX with 32bit value + * \details Atomically unsigned max compare 32bit value with value in memory using amomaxu.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be compared + * \return return the bigger value + */ +__STATIC_FORCEINLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value) +{ + uint32_t result; + + __ASM volatile ("amomaxu.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic signed MAX with 32bit value + * \details Atomically signed max compare 32bit value with value in memory using amomax.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be compared + * \return the bigger value + */ +__STATIC_FORCEINLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amomax.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic unsigned MIN with 32bit value + * \details Atomically unsigned min compare 32bit value with value in memory using amominu.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be compared + * \return the smaller value + */ +__STATIC_FORCEINLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value) +{ + uint32_t result; + + __ASM volatile ("amominu.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic signed MIN with 32bit value + * \details Atomically signed min compare 32bit value with value in memory using amomin.d. + * \param [in] addr Address pointer to data, address need to be 4byte aligned + * \param [in] value value to be compared + * \return the smaller value + */ +__STATIC_FORCEINLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __ASM volatile ("amomin.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +#if __RISCV_XLEN == 64 +/** + * \brief Compare and Swap 64bit value using LR and SC + * \details Compare old value with memory, if identical, + * store new value in memory. Return the initial value in memory. + * Success is indicated by comparing return value with OLD. + * memory address, return 0 if successful, otherwise return !0 + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] oldval Old value of the data in address + * \param [in] newval New value to be stored into the address + * \return return the initial value in memory + */ +__STATIC_FORCEINLINE uint64_t __CAS_D(volatile uint64_t *addr, uint64_t oldval, uint64_t newval) +{ + uint64_t result; + uint64_t rc; + + __ASM volatile ( \ + "0: lr.d %0, %2 \n" \ + " bne %0, %z3, 1f \n" \ + " sc.d %1, %z4, %2 \n" \ + " bnez %1, 0b \n" \ + "1:\n" \ + : "=&r"(result), "=&r"(rc), "+A"(*addr) \ + : "r"(oldval), "r"(newval) \ + : "memory"); + return result; +} + +/** + * \brief Atomic Swap 64bit value into memory + * \details Atomically swap new 64bit value into memory using amoswap.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] newval New value to be stored into the address + * \return return the original value in memory + */ +__STATIC_FORCEINLINE uint64_t __AMOSWAP_D(volatile uint64_t *addr, uint64_t newval) +{ + uint64_t result; + + __ASM volatile ("amoswap.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); + return result; +} + +/** + * \brief Atomic Add with 64bit value + * \details Atomically ADD 64bit value with value in memory using amoadd.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be ADDed + * \return return memory value + add value + */ +__STATIC_FORCEINLINE int64_t __AMOADD_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amoadd.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic And with 64bit value + * \details Atomically AND 64bit value with value in memory using amoand.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be ANDed + * \return return memory value & and value + */ +__STATIC_FORCEINLINE int64_t __AMOAND_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amoand.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic OR with 64bit value + * \details Atomically OR 64bit value with value in memory using amoor.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be ORed + * \return return memory value | and value + */ +__STATIC_FORCEINLINE int64_t __AMOOR_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amoor.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic XOR with 64bit value + * \details Atomically XOR 64bit value with value in memory using amoxor.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be XORed + * \return return memory value ^ and value + */ +__STATIC_FORCEINLINE int64_t __AMOXOR_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amoxor.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic unsigned MAX with 64bit value + * \details Atomically unsigned max compare 64bit value with value in memory using amomaxu.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be compared + * \return return the bigger value + */ +__STATIC_FORCEINLINE uint64_t __AMOMAXU_D(volatile uint64_t *addr, uint64_t value) +{ + uint64_t result; + + __ASM volatile ("amomaxu.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic signed MAX with 64bit value + * \details Atomically signed max compare 64bit value with value in memory using amomax.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be compared + * \return the bigger value + */ +__STATIC_FORCEINLINE int64_t __AMOMAX_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amomax.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic unsigned MIN with 64bit value + * \details Atomically unsigned min compare 64bit value with value in memory using amominu.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be compared + * \return the smaller value + */ +__STATIC_FORCEINLINE uint64_t __AMOMINU_D(volatile uint64_t *addr, uint64_t value) +{ + uint64_t result; + + __ASM volatile ("amominu.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/** + * \brief Atomic signed MIN with 64bit value + * \details Atomically signed min compare 64bit value with value in memory using amomin.d. + * \param [in] addr Address pointer to data, address need to be 8byte aligned + * \param [in] value value to be compared + * \return the smaller value + */ +__STATIC_FORCEINLINE int64_t __AMOMIN_D(volatile int64_t *addr, int64_t value) +{ + int64_t result; + + __ASM volatile ("amomin.d %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} +#endif /* __RISCV_XLEN == 64 */ + +/** @} */ /* End of Doxygen Group NMSIS_Core_CPU_Intrinsic */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_BASE__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_bitmanip.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_bitmanip.h new file mode 100644 index 0000000..3922d12 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_bitmanip.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_BITMANIP__ +#define __CORE_FEATURE_BITMANIP__ + +/*! + * @file core_feature_bitmanip.h + * @brief Bitmanipulation feature API header file for Nuclei N/NX Core + */ +/* + * Bitmanipulation Feature Configuration Macro: + * 1. __BITMANIP_PRESENT: Define whether Bitmanipulation Unit is present or not + * * 0: Not present + * * 1: Present + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__BITMANIP_PRESENT) && (__BITMANIP_PRESENT == 1) + +/* ########################### CPU Bitmanipulation Intrinsic Functions ########################### */ +/** + * \defgroup NMSIS_Core_Bitmanip_Intrinsic Intrinsic Functions for Bitmanipulation Instructions + * \ingroup NMSIS_Core + * \brief Functions that generate RISC-V Bitmanipulation instructions. + * \details + * + * RISC-V Bitmanipulation Intrinsic APIs are provided directly through compiler generated intrinsic function. + * + * This intrinsic function support in compiler is introduced in nuclei riscv gcc 10.2. + * + * API header file can be found in lib/gcc/riscv-nuclei-elf//include/rvintrin.h + * + * For Nuclei GCC 13/Clang 17, this intrinsic header no longer existed, please take care. + * + * @{ + */ +/** @} */ /* End of Doxygen Group NMSIS_Core_Bitmanip_Intrinsic */ + +#if defined(__INC_INTRINSIC_API) && (__INC_INTRINSIC_API == 1) +// deleted in gcc13, you can directly use b extension intrinisc api +//#include +#endif + +#endif /* defined(__BITMANIP_PRESENT) && (__BITMANIP_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_FEATURE_BITMANIP__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cache.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cache.h new file mode 100644 index 0000000..f16445f --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cache.h @@ -0,0 +1,1517 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_CACHE_H__ +#define __CORE_FEATURE_CACHE_H__ +/*! + * @file core_feature_cache.h + * @brief Cache feature API header file for Nuclei N/NX Core + */ +/* + * Cache Feature Configuration Macro: + * 1. __ICACHE_PRESENT: Define whether I-Cache Unit is present or not. + * * 0: Not present + * * 1: Present + * 2. __DCACHE_PRESENT: Define whether D-Cache Unit is present or not. + * * 0: Not present + * * 1: Present + * 3. __CCM_PRESENT: Define whether Nuclei Cache Control and Maintainence(CCM) Unit is present or not. + * * 0: Not present + * * 1: Present + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + + +#if defined(__CCM_PRESENT) && (__CCM_PRESENT == 1) + +/* ########################## Cache functions #################################### */ +/** + * \defgroup NMSIS_Core_Cache Cache Functions + * \brief Functions that configure Instruction and Data Cache. + * @{ + * + * Nuclei provide Cache Control and Maintainence(CCM) for software to control and maintain + * the internal L1 I/D Cache of the RISC-V Core, software can manage the cache flexibly to + * meet the actual application scenarios. + * + * The CCM operations have 3 types: by single address, by all and flush pipeline. + * The CCM operations are done via CSR registers, M/S/U mode has its own CSR registers to + * do CCM operations. By default, CCM operations are not allowed in S/U mode, you can execute + * \ref EnableSUCCM in M-Mode to enable it. + * + * * API names started with M, such as \ref MInvalICacheLine must be called in M-Mode only. + * * API names started with S, such as \ref SInvalICacheLine should be called in S-Mode. + * * API names started with U, such as \ref UInvalICacheLine should be called in U-Mode. + * + */ + + +/** + * \brief Cache CCM Operation Fail Info + */ +typedef enum CCM_OP_FINFO { + CCM_OP_SUCCESS = 0x0, /*!< Lock Succeed */ + CCM_OP_EXCEED_ERR = 0x1, /*!< Exceed the the number of lockable ways(N-Way I/D-Cache, lockable is N-1) */ + CCM_OP_PERM_CHECK_ERR = 0x2, /*!< PMP/sPMP/Page-Table X(I-Cache)/R(D-Cache) permission check failed, or belong to Device/Non-Cacheable address range */ + CCM_OP_REFILL_BUS_ERR = 0x3, /*!< Refill has Bus Error */ + CCM_OP_ECC_ERR = 0x4 /*!< Deprecated, ECC Error, this error code is removed in later Nuclei CCM RTL design, please don't use it */ +} CCM_OP_FINFO_Type; + +/** + * \brief Cache CCM Command Types + */ +typedef enum CCM_CMD { + CCM_DC_INVAL = 0x0, /*!< Unlock and invalidate D-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_DC_WB = 0x1, /*!< Flush the specific D-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_DC_WBINVAL = 0x2, /*!< Unlock, flush and invalidate the specific D-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_DC_LOCK = 0x3, /*!< Lock the specific D-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_DC_UNLOCK = 0x4, /*!< Unlock the specific D-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_DC_WBINVAL_ALL = 0x6, /*!< Unlock and flush and invalidate all the valid and dirty D-Cache lines */ + CCM_DC_WB_ALL = 0x7, /*!< Flush all the valid and dirty D-Cache lines */ + CCM_DC_INVAL_ALL = 0x17, /*!< Unlock and invalidate all the D-Cache lines */ + CCM_IC_INVAL = 0x8, /*!< Unlock and invalidate I-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_IC_LOCK = 0xb, /*!< Lock the specific I-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_IC_UNLOCK = 0xc, /*!< Unlock the specific I-Cache line specified by CSR CCM_XBEGINADDR */ + CCM_IC_INVAL_ALL = 0xd /*!< Unlock and invalidate all the I-Cache lines */ +} CCM_CMD_Type; + +/** + * \brief Cache Information Type + */ +typedef struct CacheInfo { + uint32_t linesize; /*!< Cache Line size in bytes */ + uint32_t ways; /*!< Cache ways */ + uint32_t setperway; /*!< Cache set per way */ + uint32_t size; /*!< Cache total size in bytes */ +} CacheInfo_Type; + +#if __riscv_xlen == 32 +#define CCM_SUEN_SUEN_Msk (0xFFFFFFFFUL) /*!< CSR CCM_SUEN: SUEN Mask */ +#else +#define CCM_SUEN_SUEN_Msk (0xFFFFFFFFFFFFFFFFUL) /*!< CSR CCM_SUEN: SUEN Mask */ +#endif + +/** + * \brief Enable CCM operation in Supervisor/User Mode + * \details + * This function enable CCM operation in Supervisor/User Mode. + * If enabled, CCM operations in supervisor/user mode will + * be allowed. + * \remarks + * - This function can be called in M-Mode only. + * \sa + * - \ref DisableSUCCM +*/ +__STATIC_FORCEINLINE void EnableSUCCM(void) +{ + __RV_CSR_SET(CSR_CCM_SUEN, CCM_SUEN_SUEN_Msk); +} + +/** + * \brief Disable CCM operation in Supervisor/User Mode + * \details + * This function disable CCM operation in Supervisor/User Mode. + * If not enabled, CCM operations in supervisor/user mode will + * trigger a *illegal intruction* exception. + * \remarks + * - This function can be called in M-Mode only. + * \sa + * - \ref EnableSUCCM +*/ +__STATIC_FORCEINLINE void DisableSUCCM(void) +{ + __RV_CSR_CLEAR(CSR_CCM_SUEN, CCM_SUEN_SUEN_Msk); +} + +/** + * \brief Flush pipeline after CCM operation + * \details + * This function is used to flush pipeline after CCM operations + * on Cache, it will ensure latest instructions or data can be + * seen by pipeline. + * \remarks + * - This function can be called in M/S/U-Mode only. +*/ +__STATIC_FORCEINLINE void FlushPipeCCM(void) +{ + __RV_CSR_WRITE(CSR_CCM_FPIPE, 0x1); +} +/** @} */ /* End of Doxygen Group NMSIS_Core_Cache */ +#endif + +#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1) + +/** + * \defgroup NMSIS_Core_ICache I-Cache Functions + * \ingroup NMSIS_Core_Cache + * \brief Functions that configure Instruction Cache. + * @{ + */ + +/** + * \brief Check ICache Unit Present or Not + * \details + * This function check icache unit present or not via mcfg_info csr + * \remarks + * - This function might not work for some old nuclei processors + * - Please make sure the version of your nuclei processor contain ICACHE bit in mcfg_info + * \return 1 if present otherwise 0 +*/ +__STATIC_FORCEINLINE int32_t ICachePresent(void) +{ + if (__RV_CSR_READ(CSR_MCFG_INFO) & MCFG_INFO_ICACHE) { + return 1; + } + return 0; +} + +/** + * \brief Enable ICache + * \details + * This function enable I-Cache + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control I Cache enable. + * \sa + * - \ref DisableICache +*/ +__STATIC_FORCEINLINE void EnableICache(void) +{ + __RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_IC_EN); +} + +/** + * \brief Disable ICache + * \details + * This function Disable I-Cache + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control I Cache enable. + * \sa + * - \ref EnableICache + */ +__STATIC_FORCEINLINE void DisableICache(void) +{ + __RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_IC_EN); +} + +/** + * \brief Enable ICache ECC + * \details + * This function enable I-Cache ECC + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control I Cache ECC enable. + * \sa + * - \ref DisableICacheECC +*/ +__STATIC_FORCEINLINE void EnableICacheECC(void) +{ + __RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_IC_ECC_EN); +} + +/** + * \brief Disable ICache ECC + * \details + * This function disable I-Cache ECC + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control I Cache ECC enable. + * \sa + * - \ref EnableICacheECC +*/ +__STATIC_FORCEINLINE void DisableICacheECC(void) +{ + __RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_IC_ECC_EN); +} + +#if defined(__CCM_PRESENT) && (__CCM_PRESENT == 1) +/** + * \brief Get I-Cache Information + * \details + * This function get I-Cache Information + * \remarks + * - This function can be called in M-Mode only. + * - You can use this function in combination with cache lines operations + * \sa + * - \ref GetDCacheInfo + */ +__STATIC_FORCEINLINE int32_t GetICacheInfo(CacheInfo_Type *info) +{ + if (info == NULL) { + return -1; + } + CSR_MICFGINFO_Type csr_ccfg; + csr_ccfg.d = __RV_CSR_READ(CSR_MICFG_INFO); + info->setperway = (1 << csr_ccfg.b.set) << 3; + info->ways = (1 + csr_ccfg.b.way); + if (csr_ccfg.b.lsize == 0) { + info->linesize = 0; + } else { + info->linesize = (1 << (csr_ccfg.b.lsize - 1)) << 3; + } + info->size = info->setperway * info->ways * info->linesize; + return 0; +} + +/** + * \brief Invalidate one I-Cache line specified by address in M-Mode + * \details + * This function unlock and invalidate one I-Cache line specified + * by the address. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void MInvalICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_INVAL); +} + +/** + * \brief Invalidate several I-Cache lines specified by address in M-Mode + * \details + * This function unlock and invalidate several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void MInvalICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_INVAL); + } + } +} + +/** + * \brief Invalidate one I-Cache line specified by address in S-Mode + * \details + * This function unlock and invalidate one I-Cache line specified + * by the address. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void SInvalICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_INVAL); +} + +/** + * \brief Invalidate several I-Cache lines specified by address in S-Mode + * \details + * This function unlock and invalidate several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void SInvalICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_INVAL); + } + } +} + +/** + * \brief Invalidate one I-Cache line specified by address in U-Mode + * \details + * This function unlock and invalidate one I-Cache line specified + * by the address. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void UInvalICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_INVAL); +} + +/** + * \brief Invalidate several I-Cache lines specified by address in U-Mode + * \details + * This function unlock and invalidate several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_INVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void UInvalICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_INVAL); + } + } +} + +/** + * \brief Lock one I-Cache line specified by address in M-Mode + * \details + * This function lock one I-Cache line specified by the address. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long MLockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_LOCK); + return __RV_CSR_READ(CSR_CCM_MDATA); +} + +/** + * \brief Lock several I-Cache lines specified by address in M-Mode + * \details + * This function lock several I-Cache lines specified by the address + * and line count. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long MLockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_MDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Lock one I-Cache line specified by address in S-Mode + * \details + * This function lock one I-Cache line specified by the address. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long SLockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_LOCK); + return __RV_CSR_READ(CSR_CCM_SDATA); +} + +/** + * \brief Lock several I-Cache lines specified by address in S-Mode + * \details + * This function lock several I-Cache lines specified by the address + * and line count. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long SLockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_SDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Lock one I-Cache line specified by address in U-Mode + * \details + * This function lock one I-Cache line specified by the address. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long ULockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_LOCK); + return __RV_CSR_READ(CSR_CCM_UDATA); +} + +/** + * \brief Lock several I-Cache lines specified by address in U-Mode + * \details + * This function lock several I-Cache lines specified by the address + * and line count. + * Command \ref CCM_IC_LOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long ULockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_UDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Unlock one I-Cache line specified by address in M-Mode + * \details + * This function unlock one I-Cache line specified by the address. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void MUnlockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_UNLOCK); +} + +/** + * \brief Unlock several I-Cache lines specified by address in M-Mode + * \details + * This function unlock several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void MUnlockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_UNLOCK); + } + } +} + +/** + * \brief Unlock one I-Cache line specified by address in S-Mode + * \details + * This function unlock one I-Cache line specified by the address. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void SUnlockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_UNLOCK); +} + +/** + * \brief Unlock several I-Cache lines specified by address in S-Mode + * \details + * This function unlock several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void SUnlockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_UNLOCK); + } + } +} + +/** + * \brief Unlock one I-Cache line specified by address in U-Mode + * \details + * This function unlock one I-Cache line specified by the address. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void UUnlockICacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_UNLOCK); +} + +/** + * \brief Unlock several I-Cache lines specified by address in U-Mode + * \details + * This function unlock several I-Cache lines specified + * by the address and line count. + * Command \ref CCM_IC_UNLOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void UUnlockICacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_UNLOCK); + } + } +} + +/** + * \brief Invalidate all I-Cache lines in M-Mode + * \details + * This function invalidate all I-Cache lines. + * Command \ref CCM_IC_INVAL_ALL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void MInvalICache(void) +{ + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_IC_INVAL_ALL); +} + +/** + * \brief Invalidate all I-Cache lines in S-Mode + * \details + * This function invalidate all I-Cache lines. + * Command \ref CCM_IC_INVAL_ALL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void SInvalICache(void) +{ + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_IC_INVAL_ALL); +} + +/** + * \brief Invalidate all I-Cache lines in U-Mode + * \details + * This function invalidate all I-Cache lines. + * Command \ref CCM_IC_INVAL_ALL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void UInvalICache(void) +{ + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_IC_INVAL_ALL); +} +#endif /* defined(__CCM_PRESENT) && (__CCM_PRESENT == 1) */ +/** @} */ /* End of Doxygen Group NMSIS_Core_ICache */ +#endif /* defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1) */ + +#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1) +/** + * \defgroup NMSIS_Core_DCache D-Cache Functions + * \ingroup NMSIS_Core_Cache + * \brief Functions that configure Data Cache. + * @{ + */ + +/** + * \brief Check DCache Unit Present or Not + * \details + * This function check dcache unit present or not via mcfg_info csr + * \remarks + * - This function might not work for some old nuclei processors + * - Please make sure the version of your nuclei processor contain DCACHE bit in mcfg_info + * \return 1 if present otherwise 0 +*/ +__STATIC_FORCEINLINE int32_t DCachePresent(void) +{ + if (__RV_CSR_READ(CSR_MCFG_INFO) & MCFG_INFO_DCACHE) { + return 1; + } + return 0; +} + +/** + * \brief Enable DCache + * \details + * This function enable D-Cache + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control D Cache enable. + * \sa + * - \ref DisableDCache +*/ +__STATIC_FORCEINLINE void EnableDCache(void) +{ + __RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_DC_EN); +} + +/** + * \brief Disable DCache + * \details + * This function Disable D-Cache + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control D Cache enable. + * \sa + * - \ref EnableDCache + */ +__STATIC_FORCEINLINE void DisableDCache(void) +{ + __RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_DC_EN); +} + +/** + * \brief Enable DCache ECC + * \details + * This function enable D-Cache ECC + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control D Cache ECC enable. + * \sa + * - \ref DisableDCacheECC +*/ +__STATIC_FORCEINLINE void EnableDCacheECC(void) +{ + __RV_CSR_SET(CSR_MCACHE_CTL, MCACHE_CTL_DC_ECC_EN); +} + +/** + * \brief Disable DCache ECC + * \details + * This function disable D-Cache ECC + * \remarks + * - This function can be called in M-Mode only. + * - This \ref CSR_MCACHE_CTL register control D Cache ECC enable. + * \sa + * - \ref EnableDCacheECC +*/ +__STATIC_FORCEINLINE void DisableDCacheECC(void) +{ + __RV_CSR_CLEAR(CSR_MCACHE_CTL, MCACHE_CTL_DC_ECC_EN); +} + +#if defined(__CCM_PRESENT) && (__CCM_PRESENT == 1) +/** + * \brief Get D-Cache Information + * \details + * This function get D-Cache Information + * \remarks + * - This function can be called in M-Mode only. + * - You can use this function in combination with cache lines operations + * \sa + * - \ref GetICacheInfo + */ +__STATIC_FORCEINLINE int32_t GetDCacheInfo(CacheInfo_Type *info) +{ + if (info == NULL) { + return -1; + } + CSR_MDCFGINFO_Type csr_ccfg; + csr_ccfg.d = __RV_CSR_READ(CSR_MDCFG_INFO); + info->setperway = (1 << csr_ccfg.b.set) << 3; + info->ways = (1 + csr_ccfg.b.way); + if (csr_ccfg.b.lsize == 0) { + info->linesize = 0; + } else { + info->linesize = (1 << (csr_ccfg.b.lsize - 1)) << 3; + } + info->size = info->setperway * info->ways * info->linesize; + return 0; +} + +/** + * \brief Invalidate one D-Cache line specified by address in M-Mode + * \details + * This function unlock and invalidate one D-Cache line specified + * by the address. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void MInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_INVAL); +} + +/** + * \brief Invalidate several D-Cache lines specified by address in M-Mode + * \details + * This function unlock and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void MInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_INVAL); + } + } +} + +/** + * \brief Invalidate one D-Cache line specified by address in S-Mode + * \details + * This function unlock and invalidate one D-Cache line specified + * by the address. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void SInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_INVAL); +} + +/** + * \brief Invalidate several D-Cache lines specified by address in S-Mode + * \details + * This function unlock and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void SInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_INVAL); + } + } +} + +/** + * \brief Invalidate one D-Cache line specified by address in U-Mode + * \details + * This function unlock and invalidate one D-Cache line specified + * by the address. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void UInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_INVAL); +} + +/** + * \brief Invalidate several D-Cache lines specified by address in U-Mode + * \details + * This function unlock and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_INVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + * \param [in] cnt count of cache lines to be invalidated + */ +__STATIC_FORCEINLINE void UInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_INVAL); + } + } +} + +/** + * \brief Flush one D-Cache line specified by address in M-Mode + * \details + * This function flush one D-Cache line specified by the address. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void MFlushDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WB); +} + +/** + * \brief Flush several D-Cache lines specified by address in M-Mode + * \details + * This function flush several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed + * \param [in] cnt count of cache lines to be flushed + */ +__STATIC_FORCEINLINE void MFlushDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WB); + } + } +} + +/** + * \brief Flush one D-Cache line specified by address in S-Mode + * \details + * This function flush one D-Cache line specified by the address. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void SFlushDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WB); +} + +/** + * \brief Flush several D-Cache lines specified by address in S-Mode + * \details + * This function flush several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed + * \param [in] cnt count of cache lines to be flushed + */ +__STATIC_FORCEINLINE void SFlushDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WB); + } + } +} + +/** + * \brief Flush one D-Cache line specified by address in U-Mode + * \details + * This function flush one D-Cache line specified by the address. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void UFlushDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WB); +} + +/** + * \brief Flush several D-Cache lines specified by address in U-Mode + * \details + * This function flush several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WB is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed + * \param [in] cnt count of cache lines to be flushed + */ +__STATIC_FORCEINLINE void UFlushDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WB); + } + } +} + +/** + * \brief Flush and invalidate one D-Cache line specified by address in M-Mode + * \details + * This function flush and invalidate one D-Cache line specified by the address. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed and invalidated + */ +__STATIC_FORCEINLINE void MFlushInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WBINVAL); +} + +/** + * \brief Flush and invalidate several D-Cache lines specified by address in M-Mode + * \details + * This function flush and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed and invalidated + * \param [in] cnt count of cache lines to be flushed and invalidated + */ +__STATIC_FORCEINLINE void MFlushInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WBINVAL); + } + } +} + +/** + * \brief Flush and invalidate one D-Cache line specified by address in S-Mode + * \details + * This function flush and invalidate one D-Cache line specified by the address. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed and invalidated + */ +__STATIC_FORCEINLINE void SFlushInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WBINVAL); +} + +/** + * \brief Flush and invalidate several D-Cache lines specified by address in S-Mode + * \details + * This function flush and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed and invalidated + * \param [in] cnt count of cache lines to be flushed and invalidated + */ +__STATIC_FORCEINLINE void SFlushInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WBINVAL); + } + } +} + +/** + * \brief Flush and invalidate one D-Cache line specified by address in U-Mode + * \details + * This function flush and invalidate one D-Cache line specified by the address. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed and invalidated + */ +__STATIC_FORCEINLINE void UFlushInvalDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WBINVAL); +} + +/** + * \brief Flush and invalidate several D-Cache lines specified by address in U-Mode + * \details + * This function flush and invalidate several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_WBINVAL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed and invalidated + * \param [in] cnt count of cache lines to be flushed and invalidated + */ +__STATIC_FORCEINLINE void UFlushInvalDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WBINVAL); + } + } +} + +/** + * \brief Lock one D-Cache line specified by address in M-Mode + * \details + * This function lock one D-Cache line specified by the address. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long MLockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_LOCK); + return __RV_CSR_READ(CSR_CCM_MDATA); +} + +/** + * \brief Lock several D-Cache lines specified by address in M-Mode + * \details + * This function lock several D-Cache lines specified by the address + * and line count. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long MLockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_MDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Lock one D-Cache line specified by address in S-Mode + * \details + * This function lock one D-Cache line specified by the address. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long SLockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_LOCK); + return __RV_CSR_READ(CSR_CCM_SDATA); +} + +/** + * \brief Lock several D-Cache lines specified by address in S-Mode + * \details + * This function lock several D-Cache lines specified by the address + * and line count. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long SLockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_SDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Lock one D-Cache line specified by address in U-Mode + * \details + * This function lock one D-Cache line specified by the address. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long ULockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_LOCK); + return __RV_CSR_READ(CSR_CCM_UDATA); +} + +/** + * \brief Lock several D-Cache lines specified by address in U-Mode + * \details + * This function lock several D-Cache lines specified by the address + * and line count. + * Command \ref CCM_DC_LOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be locked + * \param [in] cnt count of cache lines to be locked + * \return result of CCM lock operation, see enum \ref CCM_OP_FINFO + */ +__STATIC_FORCEINLINE unsigned long ULockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + unsigned long fail_info = CCM_OP_SUCCESS; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_LOCK); + fail_info = __RV_CSR_READ(CSR_CCM_UDATA); + if (CCM_OP_SUCCESS != fail_info) { + return fail_info; + } + } + } + return CCM_OP_SUCCESS; +} + +/** + * \brief Unlock one D-Cache line specified by address in M-Mode + * \details + * This function unlock one D-Cache line specified by the address. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void MUnlockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_UNLOCK); +} + +/** + * \brief Unlock several D-Cache lines specified by address in M-Mode + * \details + * This function unlock several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void MUnlockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_MBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_UNLOCK); + } + } +} + +/** + * \brief Unlock one D-Cache line specified by address in S-Mode + * \details + * This function unlock one D-Cache line specified by the address. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void SUnlockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_UNLOCK); +} + +/** + * \brief Unlock several D-Cache lines specified by address in S-Mode + * \details + * This function unlock several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void SUnlockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_SBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_UNLOCK); + } + } +} + +/** + * \brief Unlock one D-Cache line specified by address in U-Mode + * \details + * This function unlock one D-Cache line specified by the address. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be unlocked + */ +__STATIC_FORCEINLINE void UUnlockDCacheLine(unsigned long addr) +{ + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_UNLOCK); +} + +/** + * \brief Unlock several D-Cache lines specified by address in U-Mode + * \details + * This function unlock several D-Cache lines specified + * by the address and line count. + * Command \ref CCM_DC_UNLOCK is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be unlocked + * \param [in] cnt count of cache lines to be unlocked + */ +__STATIC_FORCEINLINE void UUnlockDCacheLines(unsigned long addr, unsigned long cnt) +{ + if (cnt > 0) { + unsigned long i; + __RV_CSR_WRITE(CSR_CCM_UBEGINADDR, addr); + for (i = 0; i < cnt; i++) { + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_UNLOCK); + } + } +} + +/** + * \brief Invalidate all D-Cache lines in M-Mode + * \details + * This function invalidate all D-Cache lines. + * Command \ref CCM_DC_INVAL_ALL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void MInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_INVAL_ALL); +} + +/** + * \brief Invalidate all D-Cache lines in S-Mode + * \details + * This function invalidate all D-Cache lines. + * Command \ref CCM_DC_INVAL_ALL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void SInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_INVAL_ALL); +} + +/** + * \brief Invalidate all D-Cache lines in U-Mode + * \details + * This function invalidate all D-Cache lines. + * In U-Mode, this operation will be automatically + * translated to flush and invalidate operations by hardware. + * Command \ref CCM_DC_INVAL_ALL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be invalidated + */ +__STATIC_FORCEINLINE void UInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_INVAL_ALL); +} + +/** + * \brief Flush all D-Cache lines in M-Mode + * \details + * This function flush all D-Cache lines. + * Command \ref CCM_DC_WB_ALL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void MFlushDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WB_ALL); +} + +/** + * \brief Flush all D-Cache lines in S-Mode + * \details + * This function flush all D-Cache lines. + * Command \ref CCM_DC_WB_ALL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void SFlushDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WB_ALL); +} + +/** + * \brief Flush all D-Cache lines in U-Mode + * \details + * This function flush all D-Cache lines. + * Command \ref CCM_DC_WB_ALL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed + */ +__STATIC_FORCEINLINE void UFlushDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WB_ALL); +} + +/** + * \brief Flush and invalidate all D-Cache lines in M-Mode + * \details + * This function flush and invalidate all D-Cache lines. + * Command \ref CCM_DC_WBINVAL_ALL is written to CSR \ref CSR_CCM_MCOMMAND. + * \remarks + * This function must be executed in M-Mode only. + * \param [in] addr start address to be flushed and locked + */ +__STATIC_FORCEINLINE void MFlushInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_MCOMMAND, CCM_DC_WBINVAL_ALL); +} + +/** + * \brief Flush and invalidate all D-Cache lines in S-Mode + * \details + * This function flush and invalidate all D-Cache lines. + * Command \ref CCM_DC_WBINVAL_ALL is written to CSR \ref CSR_CCM_SCOMMAND. + * \remarks + * This function must be executed in M/S-Mode only. + * \param [in] addr start address to be flushed and locked + */ +__STATIC_FORCEINLINE void SFlushInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_SCOMMAND, CCM_DC_WBINVAL_ALL); +} + +/** + * \brief Flush and invalidate all D-Cache lines in U-Mode + * \details + * This function flush and invalidate all D-Cache lines. + * Command \ref CCM_DC_WBINVAL_ALL is written to CSR \ref CSR_CCM_UCOMMAND. + * \remarks + * This function must be executed in M/S/U-Mode only. + * \param [in] addr start address to be flushed and locked + */ +__STATIC_FORCEINLINE void UFlushInvalDCache(void) +{ + __RV_CSR_WRITE(CSR_CCM_UCOMMAND, CCM_DC_WBINVAL_ALL); +} +#endif /* defined(__CCM_PRESENT) && (__CCM_PRESENT == 1) */ + +/** @} */ /* End of Doxygen Group NMSIS_Core_DCache */ +#endif /* defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_CACHE_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cidu.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cidu.h new file mode 100644 index 0000000..35c9a23 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_cidu.h @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_CIDU_H__ +#define __CORE_FEATURE_CIDU_H__ +/*! + * @file core_feature_cidu.h + * @brief Cluster Interrupt Distribution Unit feature API header file for Nuclei N/NX Core + */ +/* + * CIDU Feature Configuration Macro: + * 1. __CIDU_PRESENT: Define whether Cluster Interrupt Distribution Unit is present or not. + * * 0: Not present + * * 1: Present + * 2. __CIDU_BASEADDR: Define the base address of the CIDU. + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__CIDU_PRESENT) && (__CIDU_PRESENT == 1) + +/* ########################## CIDU functions #################################### */ +/** + * \defgroup NMSIS_Core_CIDU CIDU Functions + * \brief Functions that manage external interrupts, inter core interrupts and semaphores. + * @{ + * + * Nuclei provide Cluster Interrupt Distribution Unit (CIDU) for scenarios that a SMP system is designed for real + * time application or both Linux and real time application, and Nuclei processor core can optionally support CIDU. + * The CIDU is used to distribute external interrupts to the core’s ECLIC, also it provides Inter Core Interrupt (ICI) + * and Semaphores Mechanism. Its features are as follows: + * + * * Support up to 16 Cores in one cluster + * * Support up to 4096 external interrupts sources + * * Support up to 16 Inter Core Interrupts + * * Support 32 Semaphores + * + */ + +#ifndef __CIDU_BASEADDR +/* Base address of CIDU(__CIDU_BASEADDR) should be defined in */ +#error "__CIDU_BASEADDR is not defined, please check!" +#endif + +#define CIDU_BASE __CIDU_BASEADDR +#define CIDU_RECEIVE_INTERRUPT_EN(core_id) (0x1U << core_id) /*!< Indicates the core can receive corresponding interrupt */ + +#define CIDU_CORE_INT_STATUS_OFS 0x0 /*!< Core n Inter Core Interrupt status register base offset */ +#define CIDU_SEMAPHORE_OFS 0x80 /*!< Semaphore n register base offset */ +#define CIDU_ICI_SHADOW_OFS 0x3FFC /*!< ICI Interrupt source core ID and target core ID register offset */ +#define CIDU_INT_INDICATOR_OFS 0x4000 /*!< External interrupt n indicator register base offset */ +#define CIDU_INT_MASK_OFS 0x8000 /*!< External interrupt n mask (mask interrupt n to cores or not when interrupt n indicator on)register base offset */ +#define CIDU_CORE_NUM_OFS 0xC084 /*!< Static configuration core num register offset */ +#define CIDU_INT_NUM_OFS 0xC090 /*!< Static configuration external interrupt number register offset */ + +#define CIDU_CORE_INT_STATUS_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_CORE_INT_STATUS_OFS) + ((n) << 2)) /*!< Core n Inter Core Interrupt status register address */ +#define CIDU_SEMAPHORE_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_SEMAPHORE_OFS) + ((n) << 2)) /*!< Semaphore n register address */ +#define CIDU_ICI_SHADOW_ADDR (unsigned long)((CIDU_BASE) + (CIDU_ICI_SHADOW_OFS)) /*!< ICI Interrupt source core ID and target core ID register address */ +#define CIDU_INT_INDICATOR_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_INT_INDICATOR_OFS) + ((n) << 2)) /*!< External interrupt n indicator register address */ +#define CIDU_INT_MASK_ADDR(n) (unsigned long)((CIDU_BASE) + (CIDU_INT_MASK_OFS) + ((n) << 2)) /*!< External interrupt n mask (mask interrupt n to cores or not when interrupt n indicator on)register address */ +#define CIDU_CORE_NUM_ADDR (unsigned long)((CIDU_BASE) + (CIDU_CORE_NUM_OFS)) /*!< Static configuration core num register address */ +#define CIDU_INT_NUM_ADDR (unsigned long)((CIDU_BASE) + (CIDU_INT_NUM_OFS)) /*!< Static configuration external interrupt number register address */ + + +/* SEND_CORE_ID position in ICI_SHADOW_REG register */ +#define CIDU_ICI_SEND_CORE_ID_POS 16 + +/** + * \brief Get core number in the cluster + * \details + * Indicate the static configuration core num in the cluster. + * \return core number configured + * \remarks + * - In a Nulcei multi-core system, each core has an identifiable serial number, the serial number starts from 0 and is + * continuous, also the number is static. + * - CORE_NUM register is read only. +*/ +__STATIC_FORCEINLINE uint32_t CIDU_GetCoreNum(void) +{ + uint32_t val; + uint32_t* addr = (uint32_t*)CIDU_CORE_NUM_ADDR; + + val = __LW(addr); + return val; +} + +/** + * \brief Get external interrupt number + * \details + * Indicate the static configuration external interrupt number + * \return interrupt number configured + * \remarks + * - INT_NUM register is read only. +*/ +__STATIC_FORCEINLINE uint32_t CIDU_GetIntNum(void) +{ + uint32_t val; + uint32_t* addr = (uint32_t*)CIDU_INT_NUM_ADDR; + + val = __LW(addr); + return val; +} +/** @} */ /* End of Doxygen Group NMSIS_Core_CIDU */ + +/** + * \defgroup NMSIS_Core_Distribute_Interrupt External Interrupt Distribution Functions + * \ingroup NMSIS_Core_CIDU + * \brief Functions that distribute external interrupts to cores. + * @{ + */ + +/** + * \brief Broadcast external interrupt to cores + * \details + * This function broadcasts external interrupt which id is int_id to some/all target cores + * \param [in] int_id external interrupt id + * \param [in] to_cores target cores which can receive interrupt, use bitwise inclusive or + * of \ref CIDU_RECEIVE_INTERRUPT_EN(core_id) + * \remarks + * - External IRQn ID(int_id) is from the hard-wired persperctive, + * which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in + * - By default on reset, only core 0 can receive interrupt which id is int_id +*/ +__STATIC_FORCEINLINE void CIDU_BroadcastExtInterrupt(uint32_t int_id, uint32_t to_cores) +{ + uint32_t* addr = (uint32_t*)CIDU_INT_INDICATOR_ADDR(int_id); + + __SW(addr, (uint32_t)to_cores); +} + +/** + * \brief get broadcast mode status + * \details + * Just query the INTn_INDICATOR register value + * \param [in] int_id external interrupt id + * \return INTn_INDICATOR register value + * \remarks + * - External IRQn ID(int_id) is from the hard-wired persperctive, + * which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in + * - By default on reset, only core 0 can receive interrupt which id is int_id +*/ +__STATIC_FORCEINLINE uint32_t CIDU_GetBroadcastModeStatus(uint32_t int_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_INT_INDICATOR_ADDR(int_id); + + val = __LW(addr); + return val; +} + +/** + * \brief Let the first coming core to first claim the interrupt + * \details + * In external interrupt broadcast mode, make the first coming core to claim this interrupt and then can handle it. + * \param [in] int_id external interrupt id + * \param [in] core_id core id that receive the interrupt + * \return -1 if it fails to claim the interrupt, else it can continue to handle the interrupt + * \remarks + * - External IRQn ID(int_id) is from the hard-wired persperctive, + * which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in . + * - If it fails to claim the interrupt, it should quit the interrupt n's handler of all cores + * - When a core claims the interrupt successfully and has handled it, it must call \ref CIDU_ResetFirstClaimMode to reset the claim. + * \sa + * - \ref CIDU_BroadcastExtInterrupt + * - \ref CIDU_ResetFirstClaimMode +*/ +__STATIC_FORCEINLINE long CIDU_SetFirstClaimMode(uint32_t int_id, uint32_t core_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_INT_MASK_ADDR(int_id); + uint32_t mask = 1 << core_id; + + __SW(addr, mask); + val = __LW(addr); + if (mask == val) { + return 0; + } + return -1; +} + +/** + * \brief Reset the claim mode mask + * \details + * Reset the claim mode mask by Writing the reset value (all 1) to it + * \param [in] int_id external interrupt id + * \remarks + * - External IRQn ID(int_id) is from the hard-wired persperctive, + * which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in + * - When a core claims the interrupt successfully and handle it, it must call \ref CIDU_ResetFirstClaimMode to reset the claim + * \sa + * - \ref CIDU_SetFirstClaimMode +*/ +__STATIC_FORCEINLINE void CIDU_ResetFirstClaimMode(uint32_t int_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_INT_MASK_ADDR(int_id); + + /* clear by writing all 1 */ + __SW(addr, 0xFFFFFFFF); +} + +/** + * \brief Get the claim mask status + * \details + * Get the claim mode staus, each bit[n] indicates whether core n has claimed interrupt successfully, + * 1 means yes, 0 means no. + * \param [in] int_id external interrupt id + * \return claim mode register INTn_MASK value + * \remarks + * - External IRQn ID(int_id) is from the hard-wired persperctive, + * which has an offset mapped to the ECLIC IRQn, see Interrupt Number Definition in + * \sa + * - \ref CIDU_ResetFirstClaimMode + * - \ref CIDU_SetFirstClaimMode +*/ +__STATIC_FORCEINLINE uint32_t CIDU_GetClaimStatus(uint32_t int_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_INT_MASK_ADDR(int_id); + + val = __LW(addr); + return val; +} +/** @} */ /* End of Doxygen Group NMSIS_Core_Distribute_Interrupt */ + +/** + * \defgroup NMSIS_Core_ICI Inter Core Interrupt Functions + * \ingroup NMSIS_Core_CIDU + * \brief Functions that implement Inter Core Interrupt mechanism. + * @{ + * Inter Core Interrupt (ICI) means that one core can send interrupt to another core in a multi-core cluster. CIDU ICI belongs + * to Internal Interrupt. + * + * * CIDU ICI Interrupt ID is fixed to 16. + */ + +/** + * \brief Trigger interrupt to another core in a multi-core cluster + * \details + * When called by core send_core_id, CIDU will trigger ICI to core recv_core_id automatically. + * and core recv_core_id could query \ref CIDU_GetCoreIntSenderId to know the sender. + * \param [in] send_core_id the core id which want to send the inter core interrupt + * \param [in] recv_core_id the core id which will receive the inter core interrupt + * \remarks + * - The core recv_core_id need to call CIDU_ClearInterCoreIntReq to clear the corresponding bit/bits + * of its own COREn_INT_STATUS. + * - It supports that multiple cores call \ref CIDU_TriggerInterCoreInt simultaneously. + * \sa + * - \ref CIDU_GetCoreIntSenderId + * - \ref CIDU_ClearInterCoreIntReq +*/ +__STATIC_FORCEINLINE void CIDU_TriggerInterCoreInt(uint32_t send_core_id, uint32_t recv_core_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_ICI_SHADOW_ADDR; + + val = (uint32_t)(send_core_id << CIDU_ICI_SEND_CORE_ID_POS) | (uint32_t)(recv_core_id); + __SW(addr, (uint32_t)val); +} + +/** + * \brief Core recv_core_id queries out who sends inter core interrupt to itself + * \details + * In the ISR of ICI, receive core can query if bit[n] of this return value is 1, core n sends the current ICI, + * if bit[m] is 1, then core m also sends, etc. + * \param [in] recv_core_id the core id which receives the inter core interrupt + * \return Value that shows sender core's ID n whose bit[n](bit[m] if core m send too, etc.) is 1 + * \remarks + * - If the ICI ISR has finished the job, should call \ref CIDU_ClearInterCoreIntReq to clear the IRQ +*/ +__STATIC_FORCEINLINE uint32_t CIDU_QueryCoreIntSenderMask(uint32_t recv_core_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_CORE_INT_STATUS_ADDR(recv_core_id); + + val = __LW(addr); + return val; +} + +/** + * \brief Clear the corresponding bit/bits of ICI request triggered by sender core + * \details + * Core recv_core_id write 1 to clear the bit send_core_id of the core recv_core_id's COREn_INT_STATUS. + * \param [in] send_core_id the core id which wants to send the inter core interrupt + * \param [in] recv_core_id the core id which will receive the inter core interrupt + * \remarks + * - If the ICI ISR has finished the job of send_core_id_n's ICI, then clear bit send_core_id_n; + * if it has finished send_core_id_n and send_core_id_m's, then should clear both the bits, etc. +*/ +__STATIC_FORCEINLINE void CIDU_ClearInterCoreIntReq(uint32_t send_core_id, uint32_t recv_core_id) +{ + uint32_t val = 0; + uint32_t* addr = (uint32_t*)CIDU_CORE_INT_STATUS_ADDR(recv_core_id); + + val = (uint32_t)(1 << send_core_id); + __SW(addr, val); +} +/** @} */ /* End of Doxygen Group NMSIS_Core_ICI */ + +/** + * \defgroup NMSIS_Core_Semaphore Semaphore Functions + * \ingroup NMSIS_Core_CIDU + * \brief Functions that configure and use semaphores + * @{ + * Semaphore is very useful for multi-core cluster without SMP enable. + * + * * All Cores in the cluster agree on using SEMAPHORE_n register to protect a critical resource (an UART device for example). + * * If Core n wants to access the critical resource, it should try to own the SEMPAPHORE_n register, or else it can’t access the critical resource. + * * When the Core n owns the register SEMPAPHORE_n and finishes the job related the critical resource, then it should + * release the register by writing all 1 to it. + */ + +/** + * \brief Get SEMAPHOREn's value + * \details + * Just query the semaphore n's value + * \param [in] semph_n the semaphore id used to protect a critical resource + * \return register SEMAPHOREn_STATUS value +*/ +__STATIC_FORCEINLINE uint32_t CIDU_GetSemaphoreStatus(uint32_t semph_n) +{ + uint32_t val; + uint32_t* addr = (uint32_t*)CIDU_SEMAPHORE_ADDR(semph_n); + + val = __LW(addr); + return val; +} + +/** + * \brief check SEMAPHOREn's acquired status + * \details + * Query that whether SEMAPHOREn has been acquired by one core successfully. + * \param [in] semph_n the semaphore id used to protect a critical resource + * \param [in] core_id the core id that wants to access the critical resource + * \return 0 if core_id has acquired this semaphore successfully, or else -1 if failed + * \remarks + * - When the core n owns the register SEMPAPHORE_n and finishes the job related the critical resource, + * it should call \ref CIDU_ReleaseSemaphore to release it. + * \sa + * - \ref CIDU_GetSemaphoreStatus + * - \ref CIDU_ReleaseSemaphore +*/ +__STATIC_FORCEINLINE long CIDU_CheckSemaphoreAcquired(uint32_t semph_n, uint32_t core_id) +{ + uint32_t val; + val = CIDU_GetSemaphoreStatus(semph_n); + if (core_id != val) { + return -1; + } + return 0; +} + +/** + * \brief Acquire the SEMAPHOREn + * \details + * Acuqire the SEMAPHOREn, and check the acquired status + * \param [in] semph_n the semaphore id used to protect a critical resource + * \param [in] core_id the core id that wants to access the critical resource + * \return 0 if core_id has acquired this semaphore successfully, or else -1 if failed + * \remarks + * - When the core n owns the register SEMPAPHORE_n and finishes the job related the critical resource, + * it should call \ref CIDU_ReleaseSemaphore to release it. + * \sa + * - \ref CIDU_CheckSemaphoreAcquired + * - \ref CIDU_ReleaseSemaphore +*/ +__STATIC_FORCEINLINE long CIDU_AcquireSemaphore(uint32_t semph_n, uint32_t core_id) +{ + long semaphore_status = -1; + uint32_t* addr = (uint32_t*)CIDU_SEMAPHORE_ADDR(semph_n); + + __SW(addr, core_id); + semaphore_status = CIDU_CheckSemaphoreAcquired(semph_n, core_id); + return semaphore_status; +} + +/** + * \brief Keep acquiring the SEMAPHOREn until it has acquired this semaphore successfully + * \details + * Query that whether SEMAPHOREn has been owned by one core successfully, if not, keep trying. + * \param [in] semph_n the semaphore id used to protect a critical resource + * \param [in] core_id the core id that wants to access the critical resource + * \remarks + * - Core n will block here acquiring, so take care that core should release the semaphore when related job done. + * \sa + * - \ref CIDU_AcquireSemaphore + * - \ref CIDU_ReleaseSemaphore +*/ +__STATIC_FORCEINLINE void CIDU_AcquireSemaphore_Block(uint32_t semph_n, uint32_t core_id) +{ + int32_t semaphore_status = -1; + + while(0 != semaphore_status) { + semaphore_status = CIDU_AcquireSemaphore(semph_n, core_id); + } +} + +/** + * \brief Release the SEMAPHOREn + * \details + * Release the SEMAPHOREn by writing all 1 to SEMAPHOREn register. + * \param [in] semph_n the semaphore id used to protect a critical resource + * \remarks + * - When the core finishes the job related to the critical resource, it should release the corresponding semaphore. + * \sa + * - \ref CIDU_AcquireSemaphore_Block +*/ +__STATIC_FORCEINLINE void CIDU_ReleaseSemaphore(uint32_t semph_n) +{ + uint32_t* addr = (uint32_t*)CIDU_SEMAPHORE_ADDR(semph_n); + + /* Release by writing all 1 */ + __SW(addr, 0xFFFFFFFF); +} +/** @} */ /* End of Doxygen Group NMSIS_Core_Semaphore */ +#endif /* defined(__CIDU_PRESENT) && (__CIDU_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_CIDU_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_dsp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_dsp.h new file mode 100644 index 0000000..60c676c --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_dsp.h @@ -0,0 +1,24934 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_DSP__ +#define __CORE_FEATURE_DSP__ + +/*! + * @file core_feature_dsp.h + * @brief DSP feature API header file for Nuclei N/NX Core + */ +/* + * DSP Feature Configuration Macro: + * 1. __DSP_PRESENT: Define whether Digital Signal Processing Unit(DSP) is present or not + * * 0: Not present + * * 1: Present + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) + +#if defined(__INC_INTRINSIC_API) && (__INC_INTRINSIC_API == 1) +#ifndef __ICCRISCV__ +#include +#endif +#endif + +#ifndef __ICCRISCV__ +/* ########################### CPU SIMD DSP Intrinsic Functions ########################### */ +/** + * \defgroup NMSIS_Core_DSP_Intrinsic Intrinsic Functions for SIMD Instructions + * \ingroup NMSIS_Core + * \brief Functions that generate RISC-V DSP SIMD instructions. + * \details + * + * The following functions generate specified RISC-V SIMD instructions that cannot be directly accessed by compiler. + * * **DSP ISA Extension Instruction Summary** + * + **Shorthand Definitions** + * - r.H == rH1: r[31:16], r.L == r.H0: r[15:0] + * - r.B3: r[31:24], r.B2: r[23:16], r.B1: r[15:8], r.B0: r[7:0] + * - r.B[x]: r[(x*8+7):(x*8+0)] + * - r.H[x]: r[(x*16+7):(x*16+0)] + * - r.W[x]: r[(x*32+31):(x*32+0)] + * - r[xU]: the upper 32-bit of a 64-bit number; xU represents the GPR number that contains this upper part 32-bit value. + * - r[xL]: the lower 32-bit of a 64-bit number; xL represents the GPR number that contains this lower part 32-bit value. + * - r[xU].r[xL]: a 64-bit number that is formed from a pair of GPRs. + * - s>>: signed arithmetic right shift: + * - u>>: unsigned logical right shift + * - SAT.Qn(): Saturate to the range of [-2^n, 2^n-1], if saturation happens, set PSW.OV. + * - SAT.Um(): Saturate to the range of [0, 2^m-1], if saturation happens, set PSW.OV. + * - RUND(): Indicate `rounding`, i.e., add 1 to the most significant discarded bit for right shift or MSW-type multiplication instructions. + * - Sign or Zero Extending functions: + * - SEm(data): Sign-Extend data to m-bit.: + * - ZEm(data): Zero-Extend data to m-bit. + * - ABS(x): Calculate the absolute value of `x`. + * - CONCAT(x,y): Concatinate `x` and `y` to form a value. + * - u<: Unsinged less than comparison. + * - u<=: Unsinged less than & equal comparison. + * - u>: Unsinged greater than comparison. + * - s*: Signed multiplication. + * - u*: Unsigned multiplication. + * + * @{ + */ +/** @} */ /* End of Doxygen Group NMSIS_Core_DSP_Intrinsic */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS SIMD Data Processing Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief SIMD Data Processing Instructions + * \details + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB SIMD 16-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Add/Subtract Instructions + * \details + * Based on the combination of the types of the two 16-bit arithmetic operations, the SIMD 16-bit + * add/subtract instructions can be classified into 6 main categories: Addition (two 16-bit addition), + * Subtraction (two 16-bit subtraction), Crossed Add & Sub (one addition and one subtraction), and + * Crossed Sub & Add (one subtraction and one addition), Straight Add & Sub (one addition and one + * subtraction), and Straight Sub & Add (one subtraction and one addition). + * Based on the way of how an overflow condition is handled, the SIMD 16-bit add/subtract + * instructions can be classified into 5 groups: Wrap-around (dropping overflow), Signed Halving + * (keeping overflow by dropping 1 LSB bit), Unsigned Halving, Signed Saturation (clipping overflow), + * and Unsigned Saturation. + * Together, there are 30 SIMD 16-bit add/subtract instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB SIMD 8-bit Addition & Subtraction Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Addition & Subtraction Instructions + * \details + * Based on the types of the four 8-bit arithmetic operations, the SIMD 8-bit add/subtract instructions + * can be classified into 2 main categories: Addition (four 8-bit addition), and Subtraction (four 8-bit + * subtraction). + * Based on the way of how an overflow condition is handled for singed or unsigned operation, the + * SIMD 8-bit add/subtract instructions can be classified into 5 groups: Wrap-around (dropping + * overflow), Signed Halving (keeping overflow by dropping 1 LSB bit), Unsigned Halving, Signed + * Saturation (clipping overflow), and Unsigned Saturation. + * Together, there are 10 SIMD 8-bit add/subtract instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT SIMD 16-bit Shift Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Shift Instructions + * \details + * there are 14 SIMD 16-bit shift instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT SIMD 8-bit Shift Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Shift Instructions + * \details + * there are 14 SIMD 8-bit shift instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_CMP SIMD 16-bit Compare Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Compare Instructions + * \details + * there are 5 SIMD 16-bit Compare instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP SIMD 8-bit Compare Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Compare Instructions + * \details + * there are 5 SIMD 8-bit Compare instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MULTIPLY SIMD 16-bit Multiply Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Multiply Instructions + * \details + * there are 6 SIMD 16-bit Multiply instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MULTIPLY SIMD 8-bit Multiply Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Multiply Instructions + * \details + * there are 6 SIMD 8-bit Multiply instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC SIMD 16-bit Miscellaneous Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Miscellaneous Instructions + * \details + * there are 10 SIMD 16-bit Misc instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC SIMD 8-bit Miscellaneous Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Miscellaneous Instructions + * \details + * there are 10 SIMD 8-bit Miscellaneous instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK SIMD 8-bit Unpacking Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_DATA_PROCESS + * \brief SIMD 8-bit Unpacking Instructions + * \details + * there are 8 SIMD 8-bit Unpacking instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NON_SIMD Non-SIMD Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief Non-SIMD Instructions + * \details + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU Non-SIMD Q15 saturation ALU Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD + * \brief Non-SIMD Q15 saturation ALU Instructions + * \details + * there are 7 Non-SIMD Q15 saturation ALU Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU Non-SIMD Q31 saturation ALU Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD + * \brief Non-SIMD Q31 saturation ALU Instructions + * \details + * there are Non-SIMD Q31 saturation ALU Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION 32-bit Computation Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD + * \brief 32-bit Computation Instructions + * \details + * there are 8 32-bit Computation Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_OV_FLAG_SC OV (Overflow) flag Set/Clear Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD + * \brief OV (Overflow) flag Set/Clear Instructions + * \details + * The following table lists the user instructions related to Overflow (OV) flag manipulation. there are 2 OV (Overflow) flag Set/Clear Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC Non-SIMD Miscellaneous Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD + * \brief Non-SIMD Miscellaneous Instructions + * \details + * There are 13 Miscellaneous Instructions here. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS Partial-SIMD Data Processing Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief Partial-SIMD Data Processing Instructions + * \details + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_PACK SIMD 16-bit Packing Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief SIMD 16-bit Packing Instructions + * \details + * there are 4 SIMD16-bit Packing Instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC Signed MSW 32x32 Multiply and Add Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief Signed MSW 32x32 Multiply and Add Instructions + * \details + * there are 8 Signed MSW 32x32 Multiply and Add Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC Signed MSW 32x16 Multiply and Add Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief Signed MSW 32x16 Multiply and Add Instructions + * \details + * there are 15 Signed MSW 32x16 Multiply and Add Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB Signed 16-bit Multiply 32-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief Signed 16-bit Multiply 32-bit Add/Subtract Instructions + * \details + * there are 18 Signed 16-bit Multiply 32-bit Add/Subtract Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB Signed 16-bit Multiply 64-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief Signed 16-bit Multiply 64-bit Add/Subtract Instructions + * \details + * there is Signed 16-bit Multiply 64-bit Add/Subtract Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC Partial-SIMD Miscellaneous Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief Partial-SIMD Miscellaneous Instructions + * \details + * there are 7 Partial-SIMD Miscellaneous Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_8B_MULT_32B_ADD 8-bit Multiply with 32-bit Add Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_DATA_PROCESS + * \brief 8-bit Multiply with 32-bit Add Instructions + * \details + * there are 3 8-bit Multiply with 32-bit Add Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_64B_PROFILE 64-bit Profile Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief 64-bit Profile Instructions + * \details + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB 64-bit Addition & Subtraction Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_PROFILE + * \brief 64-bit Addition & Subtraction Instructions + * \details + * there are 10 64-bit Addition & Subtraction Instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB 32-bit Multiply with 64-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_PROFILE + * \brief 32-bit Multiply with 64-bit Add/Subtract Instructions + * \details + * there are 32-bit Multiply 64-bit Add/Subtract Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB Signed 16-bit Multiply with 64-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_PROFILE + * \brief Signed 16-bit Multiply with 64-bit Add/Subtract Instructions + * \details + * there are 10 Signed 16-bit Multiply with 64-bit Add/Subtract Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY RV64 Only Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief RV64 Only Instructions + * \details + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB (RV64 Only) SIMD 32-bit Add/Subtract Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) SIMD 32-bit Add/Subtract Instructions + * \details + * The following tables list instructions that are only present in RV64. + * There are 30 SIMD 32-bit addition or subtraction instructions.there are 4 SIMD16-bit Packing Instructions. + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT (RV64 Only) SIMD 32-bit Shift Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) SIMD 32-bit Shift Instructions + * \details + * there are 14 (RV64 Only) SIMD 32-bit Shift Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC (RV64 Only) SIMD 32-bit Miscellaneous Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) SIMD 32-bit Miscellaneous Instructions + * \details + * there are 5 (RV64 Only) SIMD 32-bit Miscellaneous Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT (RV64 Only) SIMD Q15 Saturating Multiply Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) SIMD Q15 Saturating Multiply Instructions + * \details + * there are 9 (RV64 Only) SIMD Q15 saturating Multiply Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT (RV64 Only) 32-bit Multiply Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) 32-bit Multiply Instructions + * \details + * there is 3 RV64 Only) 32-bit Multiply Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT_ADD (RV64 Only) 32-bit Multiply & Add Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) 32-bit Multiply & Add Instructions + * \details + * there are 3 (RV64 Only) 32-bit Multiply & Add Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC (RV64 Only) 32-bit Parallel Multiply & Add Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) 32-bit Parallel Multiply & Add Instructions + * \details + * there are 12 (RV64 Only) 32-bit Parallel Multiply & Add Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_NON_SIMD_32B_SHIFT (RV64 Only) Non-SIMD 32-bit Shift Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief (RV64 Only) Non-SIMD 32-bit Shift Instructions + * \details + * there are 1 (RV64 Only) Non-SIMD 32-bit Shift Instructions + */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PACK 32-bit Packing Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_ONLY + * \brief 32-bit Packing Instructions + * \details + * There are four 32-bit packing instructions here + */ + +/* ===== Inline Function Start for 3.1. ADD8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief ADD8 (SIMD 8-bit Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * ADD8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit integer element additions simultaneously. + * + * **Description**:\n + * This instruction adds the 8-bit integer elements in Rs1 with the 8-bit integer elements + * in Rs2, and then writes the 8-bit element results to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned addition. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = Rs1.B[x] + Rs2.B[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ADD8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("add8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.1. ADD8 ===== */ + +/* ===== Inline Function Start for 3.2. ADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief ADD16 (SIMD 16-bit Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * ADD16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element additions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit integer elements in Rs1 with the 16-bit integer + * elements in Rs2, and then writes the 16-bit element results to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned addition. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = Rs1.H[x] + Rs2.H[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ADD16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("add16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.2. ADD16 ===== */ + +/* ===== Inline Function Start for 3.3. ADD64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief ADD64 (64-bit Addition) + * \details + * **Type**: 64-bit Profile + * + * **Syntax**:\n + * ~~~ + * ADD64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add two 64-bit signed or unsigned integers. + * + * **RV32 Description**:\n + * This instruction adds the 64-bit integer of an even/odd pair of registers specified + * by Rs1(4,1) with the 64-bit integer of an even/odd pair of registers specified by Rs2(4,1), and then + * writes the 64-bit result to an even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., value d, determines the even/odd pair group of two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction has the same behavior as the ADD instruction in RV64I. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned addition. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * R[t_H].R[t_L] = R[a_H].R[a_L] + R[b_H].R[b_L]; + * RV64: + * Rd = Rs1 + Rs2; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_ADD64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("add64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.3. ADD64 ===== */ + +/* ===== Inline Function Start for 3.4. AVE ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief AVE (Average with Rounding) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * AVE Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Calculate the average of the contents of two general registers. + * + * **Description**:\n + * This instruction calculates the average value of two signed integers stored in Rs1 and + * Rs2, rounds up a half-integer result to the nearest integer, and writes the result to Rd. + * + * **Operations**:\n + * ~~~ + * Sum = CONCAT(Rs1[MSB],Rs1[MSB:0]) + CONCAT(Rs2[MSB],Rs2[MSB:0]) + 1; + * Rd = Sum[(MSB+1):1]; + * for RV32: MSB=31, + * for RV64: MSB=63 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_AVE(long a, long b) +{ + long result; + __ASM volatile("ave %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.4. AVE ===== */ + +/* ===== Inline Function Start for 3.5. BITREV ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief BITREV (Bit Reverse) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * BITREV Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Reverse the bit positions of the source operand within a specified width starting from bit + * 0. The reversed width is a variable from a GPR. + * + * **Description**:\n + * This instruction reverses the bit positions of the content of Rs1. The reversed bit width + * is calculated as Rs2[4:0]+1 (RV32) or Rs2[5:0]+1 (RV64). The upper bits beyond the reversed width + * are filled with zeros. After the bit reverse operation, the result is written to Rd. + * + * **Operations**:\n + * ~~~ + * msb = Rs2[4:0]; (for RV32) + * msb = Rs2[5:0]; (for RV64) + * rev[0:msb] = Rs1[msb:0]; + * Rd = ZE(rev[msb:0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_BITREV(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("bitrev %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.5. BITREV ===== */ + +/* ===== Inline Function Start for 3.6. BITREVI ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief BITREVI (Bit Reverse Immediate) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * (RV32) BITREVI Rd, Rs1, imm[4:0] + * (RV64) BITREVI Rd, Rs1, imm[5:0] + * ~~~ + * + * **Purpose**:\n + * Reverse the bit positions of the source operand within a specified width starting from bit + * 0. The reversed width is an immediate value. + * + * **Description**:\n + * This instruction reverses the bit positions of the content of Rs1. The reversed bit width + * is calculated as imm[4:0]+1 (RV32) or imm[5:0]+1 (RV64). The upper bits beyond the reversed width + * are filled with zeros. After the bit reverse operation, the result is written to Rd. + * + * **Operations**:\n + * ~~~ + * msb = imm[4:0]; (RV32) + * msb = imm[5:0]; (RV64) + * rev[0:msb] = Rs1[msb:0]; + * Rd = ZE(rev[msb:0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_BITREVI(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("bitrevi %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.6. BITREVI ===== */ + +/* ===== Inline Function Start for 3.7. BPICK ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief BPICK (Bit-wise Pick) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * BPICK Rd, Rs1, Rs2, Rc + * ~~~ + * + * **Purpose**:\n + * Select from two source operands based on a bit mask in the third operand. + * + * **Description**:\n + * This instruction selects individual bits from Rs1 or Rs2, based on the bit mask value in + * Rc. If a bit in Rc is 1, the corresponding bit is from Rs1; otherwise, the corresponding bit is from Rs2. + * The selection results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd[x] = Rc[x]? Rs1[x] : Rs2[x]; + * for RV32, x=31...0 + * for RV64, x=63...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \param [in] c unsigned long type of value stored in c + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_BPICK(unsigned long a, unsigned long b, unsigned long c) +{ + unsigned long result; + __ASM volatile("bpick %0, %1, %2, %3" : "=r"(result) : "r"(a), "r"(b), "r"(c)); + return result; +} +/* ===== Inline Function End for 3.7. BPICK ===== */ + +/* ===== Inline Function Start for 3.8. CLROV ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_OV_FLAG_SC + * \brief CLROV (Clear OV flag) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * CLROV # pseudo mnemonic + * ~~~ + * + * **Purpose**:\n + * This pseudo instruction is an alias to `CSRRCI x0, ucode, 1` instruction. + * + * + */ +__STATIC_FORCEINLINE void __RV_CLROV(void) +{ + __ASM volatile("clrov "); +} +/* ===== Inline Function End for 3.8. CLROV ===== */ + +/* ===== Inline Function Start for 3.9. CLRS8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief CLRS8 (SIMD 8-bit Count Leading Redundant Sign) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLRS8 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of redundant sign bits of the 8-bit elements of a general register. + * + * **Description**:\n + * Starting from the bits next to the sign bits of the 8-bit elements of Rs1, this instruction + * counts the number of redundant sign bits and writes the result to the corresponding 8-bit elements + * of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.B[x]; + * cnt[x] = 0; + * for (i = 6 to 0) { + * if (snum[x](i) == snum[x](7)) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.B[x] = cnt[x]; + * for RV32: x=3...0 + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLRS8(unsigned long a) +{ + unsigned long result; + __ASM volatile("clrs8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.9. CLRS8 ===== */ + +/* ===== Inline Function Start for 3.10. CLRS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief CLRS16 (SIMD 16-bit Count Leading Redundant Sign) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLRS16 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of redundant sign bits of the 16-bit elements of a general register. + * + * **Description**:\n + * Starting from the bits next to the sign bits of the 16-bit elements of Rs1, this + * instruction counts the number of redundant sign bits and writes the result to the corresponding 16- + * bit elements of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.H[x]; + * cnt[x] = 0; + * for (i = 14 to 0) { + * if (snum[x](i) == snum[x](15)) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.H[x] = cnt[x]; + * for RV32: x=1...0 + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLRS16(unsigned long a) +{ + unsigned long result; + __ASM volatile("clrs16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.10. CLRS16 ===== */ + +/* ===== Inline Function Start for 3.11. CLRS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief CLRS32 (SIMD 32-bit Count Leading Redundant Sign) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLRS32 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of redundant sign bits of the 32-bit elements of a general register. + * + * **Description**:\n + * Starting from the bits next to the sign bits of the 32-bit elements of Rs1, this + * instruction counts the number of redundant sign bits and writes the result to the corresponding 32- + * bit elements of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.W[x]; + * cnt[x] = 0; + * for (i = 30 to 0) { + * if (snum[x](i) == snum[x](31)) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.W[x] = cnt[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLRS32(unsigned long a) +{ + unsigned long result; + __ASM volatile("clrs32 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.11. CLRS32 ===== */ + +/* ===== Inline Function Start for 3.12. CLO8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief CLO8 (SIMD 8-bit Count Leading One) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLO8 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading one bits of the 8-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 8-bit elements of Rs1, this instruction + * counts the number of leading one bits and writes the results to the corresponding 8-bit elements of + * Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.B[x]; + * cnt[x] = 0; + * for (i = 7 to 0) { + * if (snum[x](i) == 1) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.B[x] = cnt[x]; + * for RV32: x=3...0 + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLO8(unsigned long a) +{ + unsigned long result; + __ASM volatile("clo8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.12. CLO8 ===== */ + +/* ===== Inline Function Start for 3.13. CLO16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief CLO16 (SIMD 16-bit Count Leading One) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLO16 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading one bits of the 16-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 16-bit elements of Rs1, this instruction + * counts the number of leading one bits and writes the results to the corresponding 16-bit elements + * of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.H[x]; + * cnt[x] = 0; + * for (i = 15 to 0) { + * if (snum[x](i) == 1) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.H[x] = cnt[x]; + * for RV32: x=1...0 + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLO16(unsigned long a) +{ + unsigned long result; + __ASM volatile("clo16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.13. CLO16 ===== */ + +/* ===== Inline Function Start for 3.14. CLO32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief CLO32 (SIMD 32-bit Count Leading One) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLO32 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading one bits of the 32-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 32-bit elements of Rs1, this instruction + * counts the number of leading one bits and writes the results to the corresponding 32-bit elements + * of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.W[x]; + * cnt[x] = 0; + * for (i = 31 to 0) { + * if (snum[x](i) == 1) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.W[x] = cnt[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLO32(unsigned long a) +{ + unsigned long result; + __ASM volatile("clo32 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.14. CLO32 ===== */ + +/* ===== Inline Function Start for 3.15. CLZ8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief CLZ8 (SIMD 8-bit Count Leading Zero) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLZ8 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading zero bits of the 8-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 8-bit elements of Rs1, this instruction + * counts the number of leading zero bits and writes the results to the corresponding 8-bit elements of + * Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.B[x]; + * cnt[x] = 0; + * for (i = 7 to 0) { + * if (snum[x](i) == 0) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.B[x] = cnt[x]; + * for RV32: x=3...0 + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLZ8(unsigned long a) +{ + unsigned long result; + __ASM volatile("clz8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.15. CLZ8 ===== */ + +/* ===== Inline Function Start for 3.16. CLZ16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief CLZ16 (SIMD 16-bit Count Leading Zero) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLZ16 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading zero bits of the 16-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 16-bit elements of Rs1, this instruction + * counts the number of leading zero bits and writes the results to the corresponding 16-bit elements + * of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.H[x]; + * cnt[x] = 0; + * for (i = 15 to 0) { + * if (snum[x](i) == 0) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.H[x] = cnt[x]; + * for RV32: x=1...0 + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLZ16(unsigned long a) +{ + unsigned long result; + __ASM volatile("clz16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.16. CLZ16 ===== */ + +/* ===== Inline Function Start for 3.17. CLZ32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief CLZ32 (SIMD 32-bit Count Leading Zero) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CLZ32 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Count the number of leading zero bits of the 32-bit elements of a general register. + * + * **Description**:\n + * Starting from the most significant bits of the 32-bit elements of Rs1, this instruction + * counts the number of leading zero bits and writes the results to the corresponding 32-bit elements + * of Rd. + * + * **Operations**:\n + * ~~~ + * snum[x] = Rs1.W[x]; + * cnt[x] = 0; + * for (i = 31 to 0) { + * if (snum[x](i) == 0) { + * cnt[x] = cnt[x] + 1; + * } else { + * break; + * } + * } + * Rd.W[x] = cnt[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CLZ32(unsigned long a) +{ + unsigned long result; + __ASM volatile("clz32 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.17. CLZ32 ===== */ + +/* ===== Inline Function Start for 3.18. CMPEQ8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP + * \brief CMPEQ8 (SIMD 8-bit Integer Compare Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CMPEQ8 Rs, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit integer elements equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit integer elements in Rs1 with the 8-bit integer + * elements in Rs2 to see if they are equal. If they are equal, the result is 0xFF; otherwise, the result is + * 0x0. The 8-bit element comparison results are written to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned numbers. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] == Rs2.B[x])? 0xff : 0x0; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CMPEQ8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("cmpeq8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.18. CMPEQ8 ===== */ + +/* ===== Inline Function Start for 3.19. CMPEQ16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_CMP + * \brief CMPEQ16 (SIMD 16-bit Integer Compare Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CMPEQ16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer elements equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit integer elements in Rs1 with the 16-bit integer + * elements in Rs2 to see if they are equal. If they are equal, the result is 0xFFFF; otherwise, the result + * is 0x0. The 16-bit element comparison results are written to Rt. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned numbers. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] == Rs2.H[x])? 0xffff : 0x0; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CMPEQ16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("cmpeq16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.19. CMPEQ16 ===== */ + +/* ===== Inline Function Start for 3.20. CRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief CRAS16 (SIMD 16-bit Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CRAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element addition and 16-bit integer element subtraction in a 32-bit + * chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit integer element in [31:16] of 32-bit chunks in Rs1 with + * the 16-bit integer element in [15:0] of 32-bit chunks in Rs2, and writes the result to [31:16] of 32-bit + * chunks in Rd; at the same time, it subtracts the 16-bit integer element in [31:16] of 32-bit chunks in + * Rs2 from the 16-bit integer element in [15:0] of 32-bit chunks, and writes the result to [15:0] of 32- + * bit chunks in Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = Rs1.W[x][31:16] + Rs2.W[x][15:0]; + * Rd.W[x][15:0] = Rs1.W[x][15:0] - Rs2.W[x][31:16]; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CRAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("cras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.20. CRAS16 ===== */ + +/* ===== Inline Function Start for 3.21. CRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief CRSA16 (SIMD 16-bit Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * CRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element subtraction and 16-bit integer element addition in a 32-bit + * chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit integer element in [15:0] of 32-bit chunks in Rs2 + * from the 16-bit integer element in [31:16] of 32-bit chunks in Rs1, and writes the result to [31:16] of + * 32-bit chunks in Rd; at the same time, it adds the 16-bit integer element in [31:16] of 32-bit chunks + * in Rs2 with the 16-bit integer element in [15:0] of 32-bit chunks in Rs1, and writes the result to + * [15:0] of 32-bit chunks in Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = Rs1.W[x][31:16] - Rs2.W[x][15:0]; + * Rd.W[x][15:0] = Rs1.W[x][15:0] + Rs2.W[x][31:16]; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CRSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("crsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.21. CRSA16 ===== */ + +/* ===== Inline Function Start for 3.22. INSB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief INSB (Insert Byte) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * (RV32) INSB Rd, Rs1, imm[1:0] + * (RV64) INSB Rd, Rs1, imm[2:0] + * ~~~ + * + * **Purpose**:\n + * Insert byte 0 of a 32-bit or 64-bit register into one of the byte elements of another register. + * + * **Description**:\n + * This instruction inserts byte 0 of Rs1 into byte `imm[1:0]` (RV32) or `imm[2:0]` (RV64) + * of Rd. + * + * **Operations**:\n + * ~~~ + * bpos = imm[1:0]; (RV32) + * bpos = imm[2:0]; (RV64) + * Rd.B[bpos] = Rs1.B[0] + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_INSB(t, a, b) \ + ({ \ + unsigned long __t = (unsigned long)(t); \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("insb %0, %1, %2" : "+r"(__t) : "r"(__a), "K"(b)); \ + __t; \ + }) +/* ===== Inline Function End for 3.22. INSB ===== */ + +/* ===== Inline Function Start for 3.23. KABS8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief KABS8 (SIMD 8-bit Saturating Absolute) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KABS8 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of 8-bit signed integer elements simultaneously. + * + * **Description**:\n + * This instruction calculates the absolute value of 8-bit signed integer elements stored + * in Rs1 and writes the element results to Rd. If the input number is 0x80, this instruction generates + * 0x7f as the output and sets the OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.B[x]; + * if (src == 0x80) { + * src = 0x7f; + * OV = 1; + * } else if (src[7] == 1) + * src = -src; + * } + * Rd.B[x] = src; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KABS8(unsigned long a) +{ + unsigned long result; + __ASM volatile("kabs8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.23. KABS8 ===== */ + +/* ===== Inline Function Start for 3.24. KABS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief KABS16 (SIMD 16-bit Saturating Absolute) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KABS16 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of 16-bit signed integer elements simultaneously. + * + * **Description**:\n + * This instruction calculates the absolute value of 16-bit signed integer elements stored + * in Rs1 and writes the element results to Rd. If the input number is 0x8000, this instruction + * generates 0x7fff as the output and sets the OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src == 0x8000) { + * src = 0x7fff; + * OV = 1; + * } else if (src[15] == 1) + * src = -src; + * } + * Rd.H[x] = src; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KABS16(unsigned long a) +{ + unsigned long result; + __ASM volatile("kabs16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.24. KABS16 ===== */ + +/* ===== Inline Function Start for 3.25. KABSW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KABSW (Scalar 32-bit Absolute Value with Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KABSW Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of a signed 32-bit integer in a general register. + * + * **Description**:\n + * This instruction calculates the absolute value of a signed 32-bit integer stored in Rs1. + * The result is sign-extended (for RV64) and written to Rd. This instruction with the minimum + * negative integer input of 0x80000000 will produce a saturated output of maximum positive integer + * of 0x7fffffff and the OV flag will be set to 1. + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[0] >= 0) { + * res = Rs1.W[0]; + * } else { + * If (Rs1.W[0] == 0x80000000) { + * res = 0x7fffffff; + * OV = 1; + * } else { + * res = -Rs1.W[0]; + * } + * } + * Rd = SE32(res); + * ~~~ + * + * \param [in] a signed long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KABSW(signed long a) +{ + unsigned long result; + __ASM volatile("kabsw %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.25. KABSW ===== */ + +/* ===== Inline Function Start for 3.26. KADD8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief KADD8 (SIMD 8-bit Signed Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KADD8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 8-bit signed integer elements in Rs1 with the 8-bit signed + * integer elements in Rs2. If any of the results are beyond the Q7 number range (-2^7 <= Q7 <= 2^7-1), they + * are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.B[x] + Rs2.B[x]; + * if (res[x] > 127) { + * res[x] = 127; + * OV = 1; + * } else if (res[x] < -128) { + * res[x] = -128; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KADD8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kadd8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.26. KADD8 ===== */ + +/* ===== Inline Function Start for 3.27. KADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KADD16 (SIMD 16-bit Signed Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KADD16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer elements in Rs1 with the 16-bit signed + * integer elements in Rs2. If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), + * they are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] + Rs2.H[x]; + * if (res[x] > 32767) { + * res[x] = 32767; + * OV = 1; + * } else if (res[x] < -32768) { + * res[x] = -32768; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KADD16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kadd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.27. KADD16 ===== */ + +/* ===== Inline Function Start for 3.28. KADD64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief KADD64 (64-bit Signed Saturating Addition) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * KADD64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add two 64-bit signed integers. The result is saturated to the Q63 range. + * + * **RV32 Description**:\n + * This instruction adds the 64-bit signed integer of an even/odd pair of registers + * specified by Rs1(4,1) with the 64-bit signed integer of an even/odd pair of registers specified by + * Rs2(4,1). If the 64-bit result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the + * range and the OV bit is set to 1. The saturated result is written to an even/odd pair of registers + * specified by Rd(4,1). + * Rx(4,1), i.e., value d, determines the even/odd pair group of two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction adds the 64-bit signed integer in Rs1 with the 64-bit signed + * integer in Rs2. If the result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the + * range and the OV bit is set to 1. The saturated result is written to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * result = R[a_H].R[a_L] + R[b_H].R[b_L]; + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * R[t_H].R[t_L] = result; + * RV64: + * result = Rs1 + Rs2; + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_KADD64(long long a, long long b) +{ + long long result; + __ASM volatile("kadd64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.28. KADD64 ===== */ + +/* ===== Inline Function Start for 3.29. KADDH ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief KADDH (Signed Addition with Q15 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KADDH Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add the signed lower 32-bit content of two registers with Q15 saturation. + * + * **Description**:\n + * The signed lower 32-bit content of Rs1 is added with the signed lower 32-bit content of + * Rs2. And the result is saturated to the 16-bit signed integer range of [-2^15, 2^15-1] and then sign- + * extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] + Rs2.W[0]; + * if (tmp > 32767) { + * res = 32767; + * OV = 1; + * } else if (tmp < -32768) { + * res = -32768; + * OV = 1 + * } else { + * res = tmp; + * } + * Rd = SE(tmp[15:0]); + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KADDH(int a, int b) +{ + long result; + __ASM volatile("kaddh %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.29. KADDH ===== */ + +/* ===== Inline Function Start for 3.30. KADDW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KADDW (Signed Addition with Q31 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KADDW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add the lower 32-bit signed content of two registers with Q31 saturation. + * + * **Description**:\n + * The lower 32-bit signed content of Rs1 is added with the lower 32-bit signed content of + * Rs2. And the result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1] and then sign- + * extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] + Rs2.W[0]; + * if (tmp > (2^31)-1) { + * res = (2^31)-1; + * OV = 1; + * } else if (tmp < -2^31) { + * res = -2^31; + * OV = 1 + * } else { + * res = tmp; + * } + * Rd = res[31:0]; // RV32 + * Rd = SE(res[31:0]) // RV64 + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KADDW(int a, int b) +{ + long result; + __ASM volatile("kaddw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.30. KADDW ===== */ + +/* ===== Inline Function Start for 3.31. KCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KCRAS16 (SIMD 16-bit Signed Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KCRAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating addition and 16-bit signed integer element + * saturating subtraction in a 32-bit chunk simultaneously. Operands are from crossed positions in 32- + * bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs2; at the same time, it + * subtracts the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs2 from the 16-bit signed + * integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the Q15 number + * range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to [31:16] of 32-bit chunks in Rd for addition and [15:0] of 32-bit chunks in Rd for + * subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][31:16]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KCRAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.31. KCRAS16 ===== */ + +/* ===== Inline Function Start for 3.32. KCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KCRSA16 (SIMD 16-bit Signed Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KCRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating subtraction and 16-bit signed integer element + * saturating addition in a 32-bit chunk simultaneously. Operands are from crossed positions in 32-bit + * chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [15:0] of 32-bit chunks + * in Rs2 from the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1; at the same time, it + * adds the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs2 with the 16-bit signed + * integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the Q15 number + * range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of 32-bit chunks in Rd + * for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][31:16]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KCRSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.32. KCRSA16 ===== */ + +/* ===== Inline Function Start for 3.33.1. KDMBB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMBB (Signed Saturating Double Multiply B16 x B16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result. The result is + * written into the destination register for RV32 or sign-extended to 64-bits and written into the + * destination register for RV64. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then written into Rd (sign-extended in + * RV64). When both the two Q15 inputs are 0x8000, saturation will happen. The result will be + * saturated to 0x7FFFFFFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * } else { + * resQ31 = 0x7FFFFFFF; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * OV = 1; + * } + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMBB(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("kdmbb %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.33.1. KDMBB ===== */ + +/* ===== Inline Function Start for 3.33.2. KDMBT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMBT (Signed Saturating Double Multiply B16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result. The result is + * written into the destination register for RV32 or sign-extended to 64-bits and written into the + * destination register for RV64. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then written into Rd (sign-extended in + * RV64). When both the two Q15 inputs are 0x8000, saturation will happen. The result will be + * saturated to 0x7FFFFFFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * } else { + * resQ31 = 0x7FFFFFFF; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * OV = 1; + * } + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMBT(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("kdmbt %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.33.2. KDMBT ===== */ + +/* ===== Inline Function Start for 3.33.3. KDMTT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMTT (Signed Saturating Double Multiply T16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result. The result is + * written into the destination register for RV32 or sign-extended to 64-bits and written into the + * destination register for RV64. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then written into Rd (sign-extended in + * RV64). When both the two Q15 inputs are 0x8000, saturation will happen. The result will be + * saturated to 0x7FFFFFFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * } else { + * resQ31 = 0x7FFFFFFF; + * Rd = resQ31; // RV32 + * Rd = SE(resQ31); // RV64 + * OV = 1; + * } + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMTT(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("kdmtt %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.33.3. KDMTT ===== */ + +/* ===== Inline Function Start for 3.34.1. KDMABB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMABB (Signed Saturating Double Multiply Addition B16 x B16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMAxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result, add the result + * with the sign-extended lower 32-bit chunk destination register and write the saturated addition + * result into the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then added with the content of Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV flag is set to 1. The result after saturation is written to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMABB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMABT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMATT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * } else { + * resQ31 = 0x7FFFFFFF; + * OV = 1; + * } + * resadd = Rd + resQ31; // RV32 + * resadd = Rd.W[0] + resQ31; // RV64 + * if (resadd > (2^31)-1) { + * resadd = (2^31)-1; + * OV = 1; + * } else if (resadd < -2^31) { + * resadd = -2^31; + * OV = 1; + * } + * Rd = resadd; // RV32 + * Rd = SE(resadd); // RV64 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMABB(long t, unsigned int a, unsigned int b) +{ + __ASM volatile("kdmabb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.34.1. KDMABB ===== */ + +/* ===== Inline Function Start for 3.34.2. KDMABT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMABT (Signed Saturating Double Multiply Addition B16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMAxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result, add the result + * with the sign-extended lower 32-bit chunk destination register and write the saturated addition + * result into the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then added with the content of Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV flag is set to 1. The result after saturation is written to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMABB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMABT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMATT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * } else { + * resQ31 = 0x7FFFFFFF; + * OV = 1; + * } + * resadd = Rd + resQ31; // RV32 + * resadd = Rd.W[0] + resQ31; // RV64 + * if (resadd > (2^31)-1) { + * resadd = (2^31)-1; + * OV = 1; + * } else if (resadd < -2^31) { + * resadd = -2^31; + * OV = 1; + * } + * Rd = resadd; // RV32 + * Rd = SE(resadd); // RV64 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMABT(long t, unsigned int a, unsigned int b) +{ + __ASM volatile("kdmabt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.34.2. KDMABT ===== */ + +/* ===== Inline Function Start for 3.34.3. KDMATT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KDMATT (Signed Saturating Double Multiply Addition T16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KDMAxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then double and saturate the Q31 result, add the result + * with the sign-extended lower 32-bit chunk destination register and write the saturated addition + * result into the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then + * doubled and saturated into a Q31 value. The Q31 value is then added with the content of Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV flag is set to 1. The result after saturation is written to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMABB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMABT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMATT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult = aop * bop; + * resQ31 = Mresult << 1; + * } else { + * resQ31 = 0x7FFFFFFF; + * OV = 1; + * } + * resadd = Rd + resQ31; // RV32 + * resadd = Rd.W[0] + resQ31; // RV64 + * if (resadd > (2^31)-1) { + * resadd = (2^31)-1; + * OV = 1; + * } else if (resadd < -2^31) { + * resadd = -2^31; + * OV = 1; + * } + * Rd = resadd; // RV32 + * Rd = SE(resadd); // RV64 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KDMATT(long t, unsigned int a, unsigned int b) +{ + __ASM volatile("kdmatt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.34.3. KDMATT ===== */ + +/* ===== Inline Function Start for 3.35.1. KHM8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MULTIPLY + * \brief KHM8 (SIMD Signed Saturating Q7 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KHM8 Rd, Rs1, Rs2 + * KHMX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do Q7xQ7 element multiplications simultaneously. The Q14 results are then reduced to Q7 + * numbers again. + * + * **Description**:\n + * For the `KHM8` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 + * with the top 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the bottom 8-bit Q7 content of 16-bit chunks in Rs2. + * For the `KHMX16` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 with the + * bottom 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the top 8-bit Q7 content of 16-bit chunks in Rs2. + * The Q14 results are then right-shifted 7-bits and saturated into Q7 values. The Q7 results are then + * written into Rd. When both the two Q7 inputs of a multiplication are 0x80, saturation will happen. + * The result will be saturated to 0x7F and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * if (is `KHM8`) { + * op1t = Rs1.B[x+1]; op2t = Rs2.B[x+1]; // top + * op1b = Rs1.B[x]; op2b = Rs2.B[x]; // bottom + * } else if (is `KHMX8`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x]; // Rs1 top + * op1b = Rs1.H[x]; op2b = Rs2.H[x+1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x80 != aop | 0x80 != bop) { + * res = (aop s* bop) >> 7; + * } else { + * res= 0x7F; + * OV = 1; + * } + * } + * Rd.H[x/2] = concat(rest, resb); + * for RV32, x=0,2 + * for RV64, x=0,2,4,6 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHM8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khm8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.35.1. KHM8 ===== */ + +/* ===== Inline Function Start for 3.35.2. KHMX8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MULTIPLY + * \brief KHMX8 (SIMD Signed Saturating Crossed Q7 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KHM8 Rd, Rs1, Rs2 + * KHMX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do Q7xQ7 element multiplications simultaneously. The Q14 results are then reduced to Q7 + * numbers again. + * + * **Description**:\n + * For the `KHM8` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 + * with the top 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the bottom 8-bit Q7 content of 16-bit chunks in Rs2. + * For the `KHMX16` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 with the + * bottom 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the top 8-bit Q7 content of 16-bit chunks in Rs2. + * The Q14 results are then right-shifted 7-bits and saturated into Q7 values. The Q7 results are then + * written into Rd. When both the two Q7 inputs of a multiplication are 0x80, saturation will happen. + * The result will be saturated to 0x7F and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * if (is `KHM8`) { + * op1t = Rs1.B[x+1]; op2t = Rs2.B[x+1]; // top + * op1b = Rs1.B[x]; op2b = Rs2.B[x]; // bottom + * } else if (is `KHMX8`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x]; // Rs1 top + * op1b = Rs1.H[x]; op2b = Rs2.H[x+1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x80 != aop | 0x80 != bop) { + * res = (aop s* bop) >> 7; + * } else { + * res= 0x7F; + * OV = 1; + * } + * } + * Rd.H[x/2] = concat(rest, resb); + * for RV32, x=0,2 + * for RV64, x=0,2,4,6 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHMX8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khmx8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.35.2. KHMX8 ===== */ + +/* ===== Inline Function Start for 3.36.1. KHM16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MULTIPLY + * \brief KHM16 (SIMD Signed Saturating Q15 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KHM16 Rd, Rs1, Rs2 + * KHMX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do Q15xQ15 element multiplications simultaneously. The Q30 results are then reduced to + * Q15 numbers again. + * + * **Description**:\n + * For the `KHM16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in + * Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom + * 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content of 32-bit chunks in + * Rs2. + * For the `KHMX16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the + * bottom 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom 16-bit Q15 + * content of 32-bit chunks in Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. + * The Q30 results are then right-shifted 15-bits and saturated into Q15 values. The Q15 results are + * then written into Rd. When both the two Q15 inputs of a multiplication are 0x8000, saturation will + * happen. The result will be saturated to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * if (is `KHM16`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x+1]; // top + * op1b = Rs1.H[x]; op2b = Rs2.H[x]; // bottom + * } else if (is `KHMX16`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x]; // Rs1 top + * op1b = Rs1.H[x]; op2b = Rs2.H[x+1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x8000 != aop | 0x8000 != bop) { + * res = (aop s* bop) >> 15; + * } else { + * res= 0x7FFF; + * OV = 1; + * } + * } + * Rd.W[x/2] = concat(rest, resb); + * for RV32: x=0 + * for RV64: x=0,2 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHM16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khm16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.36.1. KHM16 ===== */ + +/* ===== Inline Function Start for 3.36.2. KHMX16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MULTIPLY + * \brief KHMX16 (SIMD Signed Saturating Crossed Q15 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KHM16 Rd, Rs1, Rs2 + * KHMX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do Q15xQ15 element multiplications simultaneously. The Q30 results are then reduced to + * Q15 numbers again. + * + * **Description**:\n + * For the `KHM16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in + * Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom + * 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content of 32-bit chunks in + * Rs2. + * For the `KHMX16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the + * bottom 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom 16-bit Q15 + * content of 32-bit chunks in Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. + * The Q30 results are then right-shifted 15-bits and saturated into Q15 values. The Q15 results are + * then written into Rd. When both the two Q15 inputs of a multiplication are 0x8000, saturation will + * happen. The result will be saturated to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * if (is `KHM16`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x+1]; // top + * op1b = Rs1.H[x]; op2b = Rs2.H[x]; // bottom + * } else if (is `KHMX16`) { + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x]; // Rs1 top + * op1b = Rs1.H[x]; op2b = Rs2.H[x+1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x8000 != aop | 0x8000 != bop) { + * res = (aop s* bop) >> 15; + * } else { + * res= 0x7FFF; + * OV = 1; + * } + * } + * Rd.W[x/2] = concat(rest, resb); + * for RV32: x=0 + * for RV64: x=0,2 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHMX16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khmx16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.36.2. KHMX16 ===== */ + +/* ===== Inline Function Start for 3.37.1. KHMBB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief KHMBB (Signed Saturating Half Multiply B16 x B16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KHMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 number contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then right-shift 15 bits to turn the Q30 result into a Q15 + * number again and saturate the Q15 result into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then right- + * shifted 15-bits and saturated into a Q15 value. The Q15 value is then sing-extended and written into + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KHMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KHMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KHMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd = SE32(res[15:0]); // Rv32 + * Rd = SE64(res[15:0]); // RV64 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KHMBB(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("khmbb %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.37.1. KHMBB ===== */ + +/* ===== Inline Function Start for 3.37.2. KHMBT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief KHMBT (Signed Saturating Half Multiply B16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KHMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 number contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then right-shift 15 bits to turn the Q30 result into a Q15 + * number again and saturate the Q15 result into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then right- + * shifted 15-bits and saturated into a Q15 value. The Q15 value is then sing-extended and written into + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KHMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KHMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KHMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd = SE32(res[15:0]); // Rv32 + * Rd = SE64(res[15:0]); // RV64 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KHMBT(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("khmbt %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.37.2. KHMBT ===== */ + +/* ===== Inline Function Start for 3.37.3. KHMTT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief KHMTT (Signed Saturating Half Multiply T16 x T16) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KHMxy Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 number contents of two 16-bit data in the corresponding portion + * of the lower 32-bit chunk in registers and then right-shift 15 bits to turn the Q30 result into a Q15 + * number again and saturate the Q15 result into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with + * the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then right- + * shifted 15-bits and saturated into a Q15 value. The Q15 value is then sing-extended and written into + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * aop = Rs1.H[0]; bop = Rs2.H[0]; // KHMBB + * aop = Rs1.H[0]; bop = Rs2.H[1]; // KHMBT + * aop = Rs1.H[1]; bop = Rs2.H[1]; // KHMTT + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd = SE32(res[15:0]); // Rv32 + * Rd = SE64(res[15:0]); // RV64 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KHMTT(unsigned int a, unsigned int b) +{ + long result; + __ASM volatile("khmtt %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.37.3. KHMTT ===== */ + +/* ===== Inline Function Start for 3.38.1. KMABB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMABB (SIMD Saturating Signed Multiply Bottom Halfs & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMABB Rd, Rs1, Rs2 + * KMABT Rd, Rs1, Rs2 + * KMATT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of 32-bit elements in a register with the 16-bit content + * of 32-bit elements in another register and add the result to the content of 32-bit elements in the + * third register. The addition result may be saturated and is written to the third register. + * * KMABB: rd.W[x] + bottom*bottom (per 32-bit element) + * * KMABT rd.W[x] + bottom*top (per 32-bit element) + * * KMATT rd.W[x] + top*top (per 32-bit element) + * + * **Description**:\n + * For the `KMABB` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2. + * For the `KMABT` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2. + * For the `KMATT` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2. + * The multiplication result is added to the content of 32-bit elements in Rd. If the addition result is + * beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to + * 1. The results after saturation are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); // KMABB + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); // KMABT + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]); // KMATT + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMABB(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmabb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.38.1. KMABB ===== */ + +/* ===== Inline Function Start for 3.38.2. KMABT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMABT (SIMD Saturating Signed Multiply Bottom & Top Halfs & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMABB Rd, Rs1, Rs2 + * KMABT Rd, Rs1, Rs2 + * KMATT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of 32-bit elements in a register with the 16-bit content + * of 32-bit elements in another register and add the result to the content of 32-bit elements in the + * third register. The addition result may be saturated and is written to the third register. + * * KMABB: rd.W[x] + bottom*bottom (per 32-bit element) + * * KMABT rd.W[x] + bottom*top (per 32-bit element) + * * KMATT rd.W[x] + top*top (per 32-bit element) + * + * **Description**:\n + * For the `KMABB` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2. + * For the `KMABT` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2. + * For the `KMATT` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2. + * The multiplication result is added to the content of 32-bit elements in Rd. If the addition result is + * beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to + * 1. The results after saturation are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); // KMABB + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); // KMABT + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]); // KMATT + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMABT(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmabt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.38.2. KMABT ===== */ + +/* ===== Inline Function Start for 3.38.3. KMATT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMATT (SIMD Saturating Signed Multiply Top Halfs & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMABB Rd, Rs1, Rs2 + * KMABT Rd, Rs1, Rs2 + * KMATT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of 32-bit elements in a register with the 16-bit content + * of 32-bit elements in another register and add the result to the content of 32-bit elements in the + * third register. The addition result may be saturated and is written to the third register. + * * KMABB: rd.W[x] + bottom*bottom (per 32-bit element) + * * KMABT rd.W[x] + bottom*top (per 32-bit element) + * * KMATT rd.W[x] + top*top (per 32-bit element) + * + * **Description**:\n + * For the `KMABB` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2. + * For the `KMABT` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2. + * For the `KMATT` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2. + * The multiplication result is added to the content of 32-bit elements in Rd. If the addition result is + * beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to + * 1. The results after saturation are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); // KMABB + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); // KMABT + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]); // KMATT + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMATT(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmatt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.38.3. KMATT ===== */ + +/* ===== Inline Function Start for 3.39.1. KMADA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMADA (SIMD Saturating Signed Multiply Two Halfs and Two Adds) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMADA Rd, Rs1, Rs2 + * KMAXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then adds + * the two 32-bit results and 32-bit elements in a third register together. The addition result may be + * saturated. + * * KMADA: rd.W[x] + top*top + bottom*bottom (per 32-bit element) + * * KMAXDA: rd.W[x] + top*bottom + bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMADA instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * For the `KMAXDA` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * bottom 16-bit content of 32-bit elements in Rs2 and then adds the result to the result of multiplying + * the bottom 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit elements in + * Rs2. + * The result is added to the content of 32-bit elements in Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The 32-bit + * results after saturation are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * // KMADA + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]) + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMAXDA + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[0]) + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADA(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmada %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.39.1. KMADA ===== */ + +/* ===== Inline Function Start for 3.39.2. KMAXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMAXDA (SIMD Saturating Signed Crossed Multiply Two Halfs and Two Adds) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMADA Rd, Rs1, Rs2 + * KMAXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then adds + * the two 32-bit results and 32-bit elements in a third register together. The addition result may be + * saturated. + * * KMADA: rd.W[x] + top*top + bottom*bottom (per 32-bit element) + * * KMAXDA: rd.W[x] + top*bottom + bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMADA instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * For the `KMAXDA` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * bottom 16-bit content of 32-bit elements in Rs2 and then adds the result to the result of multiplying + * the bottom 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit elements in + * Rs2. + * The result is added to the content of 32-bit elements in Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The 32-bit + * results after saturation are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * // KMADA + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]) + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMAXDA + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[0]) + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMAXDA(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmaxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.39.2. KMAXDA ===== */ + +/* ===== Inline Function Start for 3.40.1. KMADS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMADS (SIMD Saturating Signed Multiply Two Halfs & Subtract & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMADS Rd, Rs1, Rs2 + * KMADRS Rd, Rs1, Rs2 + * KMAXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the corresponding 32-bit elements in a third register. The addition result may be saturated. + * * KMADS: rd.W[x] + (top*top - bottom*bottom) (per 32-bit element) + * * KMADRS: rd.W[x] + (bottom*bottom - top*top) (per 32-bit element) + * * KMAXDS: rd.W[x] + (top*bottom - bottom*top) (per 32-bit element) + * + * **Description**:\n + * For the `KMADS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * For the `KMADRS` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32- + * bit elements in Rs2. + * For the `KMAXDS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32-bit + * elements in Rs2. + * The subtraction result is then added to the content of the corresponding 32-bit elements in Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV bit is set to 1. The 32-bit results after saturation are written to Rd. The 16-bit contents of Rs1 + * and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * // KMADS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMADRS + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * // KMAXDS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADS(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmads %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.40.1. KMADS ===== */ + +/* ===== Inline Function Start for 3.40.2. KMADRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMADRS (SIMD Saturating Signed Multiply Two Halfs & Reverse Subtract & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMADS Rd, Rs1, Rs2 + * KMADRS Rd, Rs1, Rs2 + * KMAXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the corresponding 32-bit elements in a third register. The addition result may be saturated. + * * KMADS: rd.W[x] + (top*top - bottom*bottom) (per 32-bit element) + * * KMADRS: rd.W[x] + (bottom*bottom - top*top) (per 32-bit element) + * * KMAXDS: rd.W[x] + (top*bottom - bottom*top) (per 32-bit element) + * + * **Description**:\n + * For the `KMADS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * For the `KMADRS` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32- + * bit elements in Rs2. + * For the `KMAXDS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32-bit + * elements in Rs2. + * The subtraction result is then added to the content of the corresponding 32-bit elements in Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV bit is set to 1. The 32-bit results after saturation are written to Rd. The 16-bit contents of Rs1 + * and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * // KMADS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMADRS + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * // KMAXDS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADRS(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmadrs %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.40.2. KMADRS ===== */ + +/* ===== Inline Function Start for 3.40.3. KMAXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMAXDS (SIMD Saturating Signed Crossed Multiply Two Halfs & Subtract & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMADS Rd, Rs1, Rs2 + * KMADRS Rd, Rs1, Rs2 + * KMAXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the corresponding 32-bit elements in a third register. The addition result may be saturated. + * * KMADS: rd.W[x] + (top*top - bottom*bottom) (per 32-bit element) + * * KMADRS: rd.W[x] + (bottom*bottom - top*top) (per 32-bit element) + * * KMAXDS: rd.W[x] + (top*bottom - bottom*top) (per 32-bit element) + * + * **Description**:\n + * For the `KMADS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * For the `KMADRS` instruction, it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32- + * bit elements in Rs2. + * For the `KMAXDS` instruction, it multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32-bit + * elements in Rs2. + * The subtraction result is then added to the content of the corresponding 32-bit elements in Rd. If the + * addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and + * the OV bit is set to 1. The 32-bit results after saturation are written to Rd. The 16-bit contents of Rs1 + * and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * // KMADS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMADRS + * res[x] = Rd.W[x] + (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * // KMAXDS + * res[x] = Rd.W[x] + (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMAXDS(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmaxds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.40.3. KMAXDS ===== */ + +/* ===== Inline Function Start for 3.41. KMAR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief KMAR64 (Signed Multiply and Saturating Add to 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * KMAR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed elements in two registers and add the 64-bit multiplication + * results to the 64-bit signed data of a pair of registers (RV32) or a register (RV64). The result is + * saturated to the Q63 range and written back to the pair of registers (RV32) or the register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit signed data of Rs1 with that of Rs2. It adds + * the 64-bit multiplication result to the 64-bit signed data of an even/odd pair of registers specified by + * Rd(4,1) with unlimited precision. If the 64-bit addition result is beyond the Q63 number range (-2^63 <= + * Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The saturated result is written back + * to the even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., value d, determines the even/odd pair group of two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit signed elements of Rs1 with that of Rs2. It + * adds the 64-bit multiplication results to the 64-bit signed data of Rd with unlimited precision. If the + * 64-bit addition result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range + * and the OV bit is set to 1. The saturated result is written back to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * result = R[t_H].R[t_L] + (Rs1 * Rs2); + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * R[t_H].R[t_L] = result; + * RV64: + * // `result` has unlimited precision + * result = Rd + (Rs1.W[0] * Rs2.W[0]) + (Rs1.W[1] * Rs2.W[1]); + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_KMAR64(long long t, long a, long b) +{ + __ASM volatile("kmar64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.41. KMAR64 ===== */ + +/* ===== Inline Function Start for 3.42.1. KMDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMDA (SIMD Signed Multiply Two Halfs and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMDA Rd, Rs1, Rs2 + * KMXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * adds the two 32-bit results together. The addition result may be saturated. + * * KMDA: top*top + bottom*bottom (per 32-bit element) + * * KMXDA: top*bottom + bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32- + * bit elements of Rs2. + * For the `KMXDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of the + * 32-bit elements of Rs2. + * The addition result is checked for saturation. If saturation happens, the result is saturated to 2^31-1. + * The final results are written to Rd. The 16-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * if Rs1.W[x] != 0x80008000) or (Rs2.W[x] != 0x80008000 { // KMDA Rd.W[x] = Rs1.W[x].H[1] * + * Rs2.W[x].H[1]) + (Rs1.W[x].H[0] * Rs2.W[x].H[0]; // KMXDA Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[0]) + * + (Rs1.W[x].H[0] * Rs2.W[x].H[1]; } else { Rd.W[x] = 0x7fffffff; OV = 1; } for RV32: x=0 for RV64: + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMDA(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("kmda %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.42.1. KMDA ===== */ + +/* ===== Inline Function Start for 3.42.2. KMXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMXDA (SIMD Signed Crossed Multiply Two Halfs and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMDA Rd, Rs1, Rs2 + * KMXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * adds the two 32-bit results together. The addition result may be saturated. + * * KMDA: top*top + bottom*bottom (per 32-bit element) + * * KMXDA: top*bottom + bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32- + * bit elements of Rs2. + * For the `KMXDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of the + * 32-bit elements of Rs2. + * The addition result is checked for saturation. If saturation happens, the result is saturated to 2^31-1. + * The final results are written to Rd. The 16-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * if Rs1.W[x] != 0x80008000) or (Rs2.W[x] != 0x80008000 { // KMDA Rd.W[x] = Rs1.W[x].H[1] * + * Rs2.W[x].H[1]) + (Rs1.W[x].H[0] * Rs2.W[x].H[0]; // KMXDA Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[0]) + * + (Rs1.W[x].H[0] * Rs2.W[x].H[1]; } else { Rd.W[x] = 0x7fffffff; OV = 1; } for RV32: x=0 for RV64: + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMXDA(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("kmxda %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.42.2. KMXDA ===== */ + +/* ===== Inline Function Start for 3.43.1. KMMAC ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KMMAC (SIMD Saturating MSW Signed Multiply Word and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAC Rd, Rs1, Rs2 + * KMMAC.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers and add the most significant + * 32-bit results with the signed 32-bit integer elements of a third register. The addition results are + * saturated first and then written back to the third register. The `.u` form performs an additional + * rounding up operation on the multiplication results before adding the most significant 32-bit part + * of the results. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and adds the most significant 32-bit multiplication results with the signed 32-bit elements of Rd. If + * the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range + * and the OV bit is set to 1. The results after saturation are written to Rd. The `.u` form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][63:32]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAC(long t, long a, long b) +{ + __ASM volatile("kmmac %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.43.1. KMMAC ===== */ + +/* ===== Inline Function Start for 3.43.2. KMMAC.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KMMAC.u (SIMD Saturating MSW Signed Multiply Word and Add with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAC Rd, Rs1, Rs2 + * KMMAC.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers and add the most significant + * 32-bit results with the signed 32-bit integer elements of a third register. The addition results are + * saturated first and then written back to the third register. The `.u` form performs an additional + * rounding up operation on the multiplication results before adding the most significant 32-bit part + * of the results. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and adds the most significant 32-bit multiplication results with the signed 32-bit elements of Rd. If + * the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range + * and the OV bit is set to 1. The results after saturation are written to Rd. The `.u` form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][63:32]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAC_U(long t, long a, long b) +{ + __ASM volatile("kmmac.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.43.2. KMMAC.u ===== */ + +/* ===== Inline Function Start for 3.44.1. KMMAWB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWB (SIMD Saturating MSW Signed Multiply Word and Bottom Half and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWB Rd, Rs1, Rs2 + * KMMAWB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register and add the most significant 32-bit results with + * the corresponding signed 32-bit elements of a third register. The addition result is written to the + * corresponding 32-bit elements of the third register. The `.u` form rounds up the multiplication + * results from the most significant discarded bit before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed bottom 16-bit content + * of the corresponding 32-bit elements of Rs2 and adds the most significant 32-bit multiplication + * results with the corresponding signed 32-bit elements of Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results + * after saturation are written to the corresponding 32-bit elements of Rd. The `.u` form of the + * instruction rounds up the most significant 32-bit of the 48-bit multiplication results by adding a 1 to + * bit 15 of the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][47:16]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWB(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.44.1. KMMAWB ===== */ + +/* ===== Inline Function Start for 3.44.2. KMMAWB.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWB.u (SIMD Saturating MSW Signed Multiply Word and Bottom Half and Add with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWB Rd, Rs1, Rs2 + * KMMAWB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register and add the most significant 32-bit results with + * the corresponding signed 32-bit elements of a third register. The addition result is written to the + * corresponding 32-bit elements of the third register. The `.u` form rounds up the multiplication + * results from the most significant discarded bit before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed bottom 16-bit content + * of the corresponding 32-bit elements of Rs2 and adds the most significant 32-bit multiplication + * results with the corresponding signed 32-bit elements of Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results + * after saturation are written to the corresponding 32-bit elements of Rd. The `.u` form of the + * instruction rounds up the most significant 32-bit of the 48-bit multiplication results by adding a 1 to + * bit 15 of the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][47:16]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWB_U(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawb.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.44.2. KMMAWB.u ===== */ + +/* ===== Inline Function Start for 3.45.1. KMMAWB2 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWB2 (SIMD Saturating MSW Signed Multiply Word and Bottom Half & 2 and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWB2 Rd, Rs1, Rs2 + * KMMAWB2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and add the + * saturated most significant 32-bit results with the corresponding signed 32-bit elements of a third + * register. The saturated addition result is written to the corresponding 32-bit elements of the third + * register. The `.u` form rounds up the multiplication results from the most significant discarded bit + * before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed bottom 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * adds the saturated most significant 32-bit Q31 multiplication results with the corresponding signed + * 32-bit elements of Rd. If the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to the + * corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the most significant + * 32-bit of the 48-bit Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of + * the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[0] == 0x8000)) { + * addop.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[0]; + * if (`.u` form) { + * Mres[x][47:14] = Mres[x][47:14] + 1; + * } + * addop.W[x] = Mres[x][46:15]; // doubling + * } + * res[x] = Rd.W[x] + addop.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWB2(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawb2 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.45.1. KMMAWB2 ===== */ + +/* ===== Inline Function Start for 3.45.2. KMMAWB2.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWB2.u (SIMD Saturating MSW Signed Multiply Word and Bottom Half & 2 and Add with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWB2 Rd, Rs1, Rs2 + * KMMAWB2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and add the + * saturated most significant 32-bit results with the corresponding signed 32-bit elements of a third + * register. The saturated addition result is written to the corresponding 32-bit elements of the third + * register. The `.u` form rounds up the multiplication results from the most significant discarded bit + * before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed bottom 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * adds the saturated most significant 32-bit Q31 multiplication results with the corresponding signed + * 32-bit elements of Rd. If the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to the + * corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the most significant + * 32-bit of the 48-bit Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of + * the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[0] == 0x8000)) { + * addop.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[0]; + * if (`.u` form) { + * Mres[x][47:14] = Mres[x][47:14] + 1; + * } + * addop.W[x] = Mres[x][46:15]; // doubling + * } + * res[x] = Rd.W[x] + addop.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWB2_U(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawb2.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.45.2. KMMAWB2.u ===== */ + +/* ===== Inline Function Start for 3.46.1. KMMAWT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWT (SIMD Saturating MSW Signed Multiply Word and Top Half and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWT Rd, Rs1, Rs2 + * KMMAWT.u Rd Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the signed top 16-bit of the + * corresponding 32-bit elements of another register and add the most significant 32-bit results with + * the corresponding signed 32-bit elements of a third register. The addition results are written to the + * corresponding 32-bit elements of the third register. The `.u` form rounds up the multiplication + * results from the most significant discarded bit before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed top 16-bit of the + * corresponding 32-bit elements of Rs2 and adds the most significant 32-bit multiplication results + * with the corresponding signed 32-bit elements of Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results + * after saturation are written to the corresponding 32-bit elements of Rd. The `.u` form of the + * instruction rounds up the most significant 32-bit of the 48-bit multiplication results by adding a 1 to + * bit 15 of the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][47:16]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWT(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.46.1. KMMAWT ===== */ + +/* ===== Inline Function Start for 3.46.2. KMMAWT.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWT.u (SIMD Saturating MSW Signed Multiply Word and Top Half and Add with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWT Rd, Rs1, Rs2 + * KMMAWT.u Rd Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the signed top 16-bit of the + * corresponding 32-bit elements of another register and add the most significant 32-bit results with + * the corresponding signed 32-bit elements of a third register. The addition results are written to the + * corresponding 32-bit elements of the third register. The `.u` form rounds up the multiplication + * results from the most significant discarded bit before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed top 16-bit of the + * corresponding 32-bit elements of Rs2 and adds the most significant 32-bit multiplication results + * with the corresponding signed 32-bit elements of Rd. If the addition result is beyond the Q31 + * number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results + * after saturation are written to the corresponding 32-bit elements of Rd. The `.u` form of the + * instruction rounds up the most significant 32-bit of the 48-bit multiplication results by adding a 1 to + * bit 15 of the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * res[x] = Rd.W[x] + Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] + Mres[x][47:16]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWT_U(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawt.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.46.2. KMMAWT.u ===== */ + +/* ===== Inline Function Start for 3.47.1. KMMAWT2 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWT2 (SIMD Saturating MSW Signed Multiply Word and Top Half & 2 and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWT2 Rd, Rs1, Rs2 + * KMMAWT2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and add the + * saturated most significant 32-bit results with the corresponding signed 32-bit elements of a third + * register. The saturated addition result is written to the corresponding 32-bit elements of the third + * register. The `.u` form rounds up the multiplication results from the most significant discarded bit + * before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed top 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * adds the saturated most significant 32-bit Q31 multiplication results with the corresponding signed + * 32-bit elements of Rd. If the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to the + * corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the most significant + * 32-bit of the 48-bit Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of + * the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[1] == 0x8000)) { + * addop.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[1]; + * if (`.u` form) { + * Mres[x][47:14] = Mres[x][47:14] + 1; + * } + * addop.W[x] = Mres[x][46:15]; // doubling + * } + * res[x] = Rd.W[x] + addop.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWT2(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawt2 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.47.1. KMMAWT2 ===== */ + +/* ===== Inline Function Start for 3.47.2. KMMAWT2.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMAWT2.u (SIMD Saturating MSW Signed Multiply Word and Top Half & 2 and Add with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMAWT2 Rd, Rs1, Rs2 + * KMMAWT2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and add the + * saturated most significant 32-bit results with the corresponding signed 32-bit elements of a third + * register. The saturated addition result is written to the corresponding 32-bit elements of the third + * register. The `.u` form rounds up the multiplication results from the most significant discarded bit + * before the addition operations. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed top 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * adds the saturated most significant 32-bit Q31 multiplication results with the corresponding signed + * 32-bit elements of Rd. If the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to the + * corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the most significant + * 32-bit of the 48-bit Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of + * the result before the addition operations. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[1] == 0x8000)) { + * addop.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[1]; + * if (`.u` form) { + * Mres[x][47:14] = Mres[x][47:14] + 1; + * } + * addop.W[x] = Mres[x][46:15]; // doubling + * } + * res[x] = Rd.W[x] + addop.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMAWT2_U(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmmawt2.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.47.2. KMMAWT2.u ===== */ + +/* ===== Inline Function Start for 3.48.1. KMMSB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KMMSB (SIMD Saturating MSW Signed Multiply Word and Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMSB Rd, Rs1, Rs2 + * KMMSB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers and subtract the most + * significant 32-bit results from the signed 32-bit elements of a third register. The subtraction results + * are written to the third register. The `.u` form performs an additional rounding up operation on + * the multiplication results before subtracting the most significant 32-bit part of the results. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and subtracts the most significant 32-bit multiplication results from the signed 32-bit elements of + * Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the + * range and the OV bit is set to 1. The results after saturation are written to Rd. The `.u` form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * res[x] = Rd.W[x] - Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] - Mres[x][63:32]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMSB(long t, long a, long b) +{ + __ASM volatile("kmmsb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.48.1. KMMSB ===== */ + +/* ===== Inline Function Start for 3.48.2. KMMSB.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KMMSB.u (SIMD Saturating MSW Signed Multiply Word and Subtraction with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMSB Rd, Rs1, Rs2 + * KMMSB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers and subtract the most + * significant 32-bit results from the signed 32-bit elements of a third register. The subtraction results + * are written to the third register. The `.u` form performs an additional rounding up operation on + * the multiplication results before subtracting the most significant 32-bit part of the results. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and subtracts the most significant 32-bit multiplication results from the signed 32-bit elements of + * Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the + * range and the OV bit is set to 1. The results after saturation are written to Rd. The `.u` form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * res[x] = Rd.W[x] - Round[x][32:1]; + * } else { + * res[x] = Rd.W[x] - Mres[x][63:32]; + * } + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMSB_U(long t, long a, long b) +{ + __ASM volatile("kmmsb.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.48.2. KMMSB.u ===== */ + +/* ===== Inline Function Start for 3.49.1. KMMWB2 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMWB2 (SIMD Saturating MSW Signed Multiply Word and Bottom Half & 2) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMWB2 Rd, Rs1, Rs2 + * KMMWB2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and write the + * saturated most significant 32-bit results to the corresponding 32-bit elements of a register. The `.u` + * form rounds up the results from the most significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed bottom 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * writes the saturated most significant 32-bit Q31 multiplication results to the corresponding 32-bit + * elements of Rd. The `.u` form of the instruction rounds up the most significant 32-bit of the 48-bit + * Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of the results. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[0] == 0x8000)) { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][46:14] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][46:15]; + * } + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMWB2(long a, unsigned long b) +{ + long result; + __ASM volatile("kmmwb2 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.49.1. KMMWB2 ===== */ + +/* ===== Inline Function Start for 3.49.2. KMMWB2.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMWB2.u (SIMD Saturating MSW Signed Multiply Word and Bottom Half & 2 with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMWB2 Rd, Rs1, Rs2 + * KMMWB2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and write the + * saturated most significant 32-bit results to the corresponding 32-bit elements of a register. The `.u` + * form rounds up the results from the most significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed bottom 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * writes the saturated most significant 32-bit Q31 multiplication results to the corresponding 32-bit + * elements of Rd. The `.u` form of the instruction rounds up the most significant 32-bit of the 48-bit + * Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of the results. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[0] == 0x8000)) { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][46:14] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][46:15]; + * } + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMWB2_U(long a, unsigned long b) +{ + long result; + __ASM volatile("kmmwb2.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.49.2. KMMWB2.u ===== */ + +/* ===== Inline Function Start for 3.50.1. KMMWT2 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMWT2 (SIMD Saturating MSW Signed Multiply Word and Top Half & 2) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMWT2 Rd, Rs1, Rs2 + * KMMWT2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and write the + * saturated most significant 32-bit results to the corresponding 32-bit elements of a register. The `.u` + * form rounds up the results from the most significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed top 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * writes the saturated most significant 32-bit Q31 multiplication results to the corresponding 32-bit + * elements of Rd. The `.u` form of the instruction rounds up the most significant 32-bit of the 48-bit + * Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of the results. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[1] == 0x8000)) { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][46:14] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][46:15]; + * } + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMWT2(long a, unsigned long b) +{ + long result; + __ASM volatile("kmmwt2 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.50.1. KMMWT2 ===== */ + +/* ===== Inline Function Start for 3.50.2. KMMWT2.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief KMMWT2.u (SIMD Saturating MSW Signed Multiply Word and Top Half & 2 with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMMWT2 Rd, Rs1, Rs2 + * KMMWT2.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, double the multiplication results and write the + * saturated most significant 32-bit results to the corresponding 32-bit elements of a register. The `.u` + * form rounds up the results from the most significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit Q31 elements of Rs1 with the signed top 16-bit Q15 + * content of the corresponding 32-bit elements of Rs2, doubles the Q46 results to Q47 numbers and + * writes the saturated most significant 32-bit Q31 multiplication results to the corresponding 32-bit + * elements of Rd. The `.u` form of the instruction rounds up the most significant 32-bit of the 48-bit + * Q47 multiplication results by adding a 1 to bit 15 (i.e., bit 14 before doubling) of the results. + * + * **Operations**:\n + * ~~~ + * if ((Rs1.W[x] == 0x80000000) & (Rs2.W[x].H[1] == 0x8000)) { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } else { + * Mres[x][47:0] = Rs1.W[x] s* Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][46:14] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][46:15]; + * } + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMMWT2_U(long a, unsigned long b) +{ + long result; + __ASM volatile("kmmwt2.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.50.2. KMMWT2.u ===== */ + +/* ===== Inline Function Start for 3.51.1. KMSDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMSDA (SIMD Saturating Signed Multiply Two Halfs & Add & Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMSDA Rd, Rs1, Rs2 + * KMSXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * subtracts the two 32-bit results from the corresponding 32-bit elements of a third register. The + * subtraction result may be saturated. + * * KMSDA: rd.W[x] - top*top - bottom*bottom (per 32-bit element) + * * KMSXDA: rd.W[x] - top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMSDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * For the `KMSXDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of the + * 32-bit elements of Rs1 with the bottom 16-bit content of the 32-bit elements of Rs2. + * The two 32-bit multiplication results are then subtracted from the content of the corresponding 32- + * bit elements of Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to Rd. The + * 16-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * // KMSDA + * res[x] = Rd.W[x] - (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMSXDA + * res[x] = Rd.W[x] - (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMSDA(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmsda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.51.1. KMSDA ===== */ + +/* ===== Inline Function Start for 3.51.2. KMSXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief KMSXDA (SIMD Saturating Signed Crossed Multiply Two Halfs & Add & Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KMSDA Rd, Rs1, Rs2 + * KMSXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * subtracts the two 32-bit results from the corresponding 32-bit elements of a third register. The + * subtraction result may be saturated. + * * KMSDA: rd.W[x] - top*top - bottom*bottom (per 32-bit element) + * * KMSXDA: rd.W[x] - top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `KMSDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * For the `KMSXDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of the + * 32-bit elements of Rs1 with the bottom 16-bit content of the 32-bit elements of Rs2. + * The two 32-bit multiplication results are then subtracted from the content of the corresponding 32- + * bit elements of Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is + * saturated to the range and the OV bit is set to 1. The results after saturation are written to Rd. The + * 16-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * // KMSDA + * res[x] = Rd.W[x] - (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * // KMSXDA + * res[x] = Rd.W[x] - (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMSXDA(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmsxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.51.2. KMSXDA ===== */ + +/* ===== Inline Function Start for 3.52. KMSR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief KMSR64 (Signed Multiply and Saturating Subtract from 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * KMSR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed elements in two registers and subtract the 64-bit multiplication + * results from the 64-bit signed data of a pair of registers (RV32) or a register (RV64). The result is + * saturated to the Q63 range and written back to the pair of registers (RV32) or the register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit signed data of Rs1 with that of Rs2. It + * subtracts the 64-bit multiplication result from the 64-bit signed data of an even/odd pair of registers + * specified by Rd(4,1) with unlimited precision. If the 64-bit subtraction result is beyond the Q63 + * number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The saturated + * result is written back to the even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit signed elements of Rs1 with that of Rs2. It + * subtracts the 64-bit multiplication results from the 64-bit signed data in Rd with unlimited + * precision. If the 64-bit subtraction result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is + * saturated to the range and the OV bit is set to 1. The saturated result is written back to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * result = R[t_H].R[t_L] - (Rs1 * Rs2); + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * R[t_H].R[t_L] = result; + * RV64: + * // `result` has unlimited precision + * result = Rd - (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_KMSR64(long long t, long a, long b) +{ + __ASM volatile("kmsr64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.52. KMSR64 ===== */ + +/* ===== Inline Function Start for 3.53. KSLLW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KSLLW (Saturating Shift Left Logical for Word) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSLLW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do logical left shift operation with saturation on a 32-bit word. The shift amount is a + * variable from a GPR. + * + * **Description**:\n + * The first word data in Rs1 is left-shifted logically. The shifted out bits are filled with + * zero and the shift amount is specified by the low-order 5-bits of the value in the Rs2 register. Any + * shifted value greater than 2^31-1 is saturated to 2^31-1. Any shifted value smaller than -2^31 is saturated + * to -2^31. And the saturated result is sign-extended and written to Rd. If any saturation is performed, + * set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * res[(31+sa):0] = Rs1.W[0] << sa; + * if (res > (2^31)-1) { + * res = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res = 0x80000000; OV = 1; + * } + * Rd[31:0] = res[31:0]; // RV32 + * Rd[63:0] = SE(res[31:0]); // RV64 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KSLLW(long a, unsigned int b) +{ + long result; + __ASM volatile("ksllw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.53. KSLLW ===== */ + +/* ===== Inline Function Start for 3.54. KSLLIW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KSLLIW (Saturating Shift Left Logical Immediate for Word) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSLLIW Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do logical left shift operation with saturation on a 32-bit word. The shift amount is an + * immediate value. + * + * **Description**:\n + * The first word data in Rs1 is left-shifted logically. The shifted out bits are filled with + * zero and the shift amount is specified by the imm5u constant. Any shifted value greater than 2^31-1 is + * saturated to 2^31-1. Any shifted value smaller than -2^31 is saturated to -2^31. And the saturated result is + * sign-extended and written to Rd. If any saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = imm5u; + * res[(31+sa):0] = Rs1.W[0] << sa; + * if (res > (2^31)-1) { + * res = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res = 0x80000000; OV = 1; + * } + * Rd[31:0] = res[31:0]; // RV32 + * Rd[63:0] = SE(res[31:0]); // RV64 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +#define __RV_KSLLIW(a, b) \ + ({ \ + long result; \ + long __a = (long)(a); \ + __ASM volatile("kslliw %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.54. KSLLIW ===== */ + +/* ===== Inline Function Start for 3.55. KSLL8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief KSLL8 (SIMD 8-bit Saturating Shift Left Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLL8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is a variable from a GPR. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the low-order 3-bits of the value in the Rs2 register. + * Any shifted value greater than 2^7-1 is saturated to 2^7-1. Any shifted value smaller than -2^7 is + * saturated to -2^7. And the saturated results are written to Rd. If any saturation is performed, set OV + * bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * if (sa != 0) { + * res[(7+sa):0] = Rs1.B[x] << sa; + * if (res > (2^7)-1) { + * res = 0x7f; OV = 1; + * } else if (res < -2^7) { + * res = 0x80; OV = 1; + * } + * Rd.B[x] = res[7:0]; + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLL8(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ksll8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.55. KSLL8 ===== */ + +/* ===== Inline Function Start for 3.56. KSLLI8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief KSLLI8 (SIMD 8-bit Saturating Shift Left Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLLI8 Rd, Rs1, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is an immediate value. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the imm3u constant. Any shifted value greater than + * 2^7-1 is saturated to 2^7-1. Any shifted value smaller than -2^7 is saturated to -2^7. And the saturated + * results are written to Rd. If any saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * if (sa != 0) { + * res[(7+sa):0] = Rs1.B[x] << sa; + * if (res > (2^7)-1) { + * res = 0x7f; OV = 1; + * } else if (res < -2^7) { + * res = 0x80; OV = 1; + * } + * Rd.B[x] = res[7:0]; + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_KSLLI8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("kslli8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.56. KSLLI8 ===== */ + +/* ===== Inline Function Start for 3.57. KSLL16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief KSLL16 (SIMD 16-bit Saturating Shift Left Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLL16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is a variable from a GPR. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the low-order 4-bits of the value in the Rs2 register. + * Any shifted value greater than 2^15-1 is saturated to 2^15-1. Any shifted value smaller than -2^15 is + * saturated to -2^15. And the saturated results are written to Rd. If any saturation is performed, set OV + * bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa != 0) { + * res[(15+sa):0] = Rs1.H[x] << sa; + * if (res > (2^15)-1) { + * res = 0x7fff; OV = 1; + * } else if (res < -2^15) { + * res = 0x8000; OV = 1; + * } + * Rd.H[x] = res[15:0]; + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLL16(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ksll16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.57. KSLL16 ===== */ + +/* ===== Inline Function Start for 3.58. KSLLI16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief KSLLI16 (SIMD 16-bit Saturating Shift Left Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLLI16 Rd, Rs1, imm4u + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is an immediate value. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the imm4u constant. Any shifted value greater than + * 2^15-1 is saturated to 2^15-1. Any shifted value smaller than -2^15 is saturated to -2^15. And the saturated + * results are written to Rd. If any saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = imm4u[3:0]; + * if (sa != 0) { + * res[(15+sa):0] = Rs1.H[x] << sa; + * if (res > (2^15)-1) { + * res = 0x7fff; OV = 1; + * } else if (res < -2^15) { + * res = 0x8000; OV = 1; + * } + * Rd.H[x] = res[15:0]; + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_KSLLI16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("kslli16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.58. KSLLI16 ===== */ + +/* ===== Inline Function Start for 3.59.1. KSLRA8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief KSLRA8 (SIMD 8-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLRA8 Rd, Rs1, Rs2 + * KSLRA8.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q7 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 8-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[3:0]. Rs2[3:0] is in the signed range of [-2^3, 2^3-1]. A positive Rs2[3:0] means + * logical left shift and a negative Rs2[3:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[3:0]. However, the behavior of `Rs2[3:0]==-2^3 (0x8)` is defined to be + * equivalent to the behavior of `Rs2[3:0]==-(2^3-1) (0x9)`. + * The left-shifted results are saturated to the 8-bit signed integer range of [-2^7, 2^7-1]. For the `.u` form + * of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:4] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[3:0] < 0) { + * sa = -Rs2[3:0]; + * sa = (sa == 8)? 7 : sa; + * if (`.u` form) { + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { + * Rd.B[x] = SE8(Rs1.B[x][7:sa]); + * } + * } else { + * sa = Rs2[2:0]; + * res[(7+sa):0] = Rs1.B[x] <<(logic) sa; + * if (res > (2^7)-1) { + * res[7:0] = 0x7f; OV = 1; + * } else if (res < -2^7) { + * res[7:0] = 0x80; OV = 1; + * } + * Rd.B[x] = res[7:0]; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA8(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.59.1. KSLRA8 ===== */ + +/* ===== Inline Function Start for 3.59.2. KSLRA8.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief KSLRA8.u (SIMD 8-bit Shift Left Logical with Saturation or Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLRA8 Rd, Rs1, Rs2 + * KSLRA8.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q7 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 8-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[3:0]. Rs2[3:0] is in the signed range of [-2^3, 2^3-1]. A positive Rs2[3:0] means + * logical left shift and a negative Rs2[3:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[3:0]. However, the behavior of `Rs2[3:0]==-2^3 (0x8)` is defined to be + * equivalent to the behavior of `Rs2[3:0]==-(2^3-1) (0x9)`. + * The left-shifted results are saturated to the 8-bit signed integer range of [-2^7, 2^7-1]. For the `.u` form + * of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:4] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[3:0] < 0) { + * sa = -Rs2[3:0]; + * sa = (sa == 8)? 7 : sa; + * if (`.u` form) { + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { + * Rd.B[x] = SE8(Rs1.B[x][7:sa]); + * } + * } else { + * sa = Rs2[2:0]; + * res[(7+sa):0] = Rs1.B[x] <<(logic) sa; + * if (res > (2^7)-1) { + * res[7:0] = 0x7f; OV = 1; + * } else if (res < -2^7) { + * res[7:0] = 0x80; OV = 1; + * } + * Rd.B[x] = res[7:0]; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA8_U(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra8.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.59.2. KSLRA8.u ===== */ + +/* ===== Inline Function Start for 3.60.1. KSLRA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief KSLRA16 (SIMD 16-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLRA16 Rd, Rs1, Rs2 + * KSLRA16.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q15 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 16-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[4:0]. Rs2[4:0] is in the signed range of [-2^4, 2^4-1]. A positive Rs2[4:0] means + * logical left shift and a negative Rs2[4:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[4:0]. However, the behavior of `Rs2[4:0]==-2^4 (0x10)` is defined to be + * equivalent to the behavior of `Rs2[4:0]==-(2^4-1) (0x11)`. + * The left-shifted results are saturated to the 16-bit signed integer range of [-2^15, 2^15-1]. For the `.u` + * form of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:5] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[4:0] < 0) { + * sa = -Rs2[4:0]; + * sa = (sa == 16)? 15 : sa; + * if (`.u` form) { + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } + * } else { + * sa = Rs2[3:0]; + * res[(15+sa):0] = Rs1.H[x] <<(logic) sa; + * if (res > (2^15)-1) { + * res[15:0] = 0x7fff; OV = 1; + * } else if (res < -2^15) { + * res[15:0] = 0x8000; OV = 1; + * } + * d.H[x] = res[15:0]; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA16(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.60.1. KSLRA16 ===== */ + +/* ===== Inline Function Start for 3.60.2. KSLRA16.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief KSLRA16.u (SIMD 16-bit Shift Left Logical with Saturation or Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSLRA16 Rd, Rs1, Rs2 + * KSLRA16.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q15 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 16-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[4:0]. Rs2[4:0] is in the signed range of [-2^4, 2^4-1]. A positive Rs2[4:0] means + * logical left shift and a negative Rs2[4:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[4:0]. However, the behavior of `Rs2[4:0]==-2^4 (0x10)` is defined to be + * equivalent to the behavior of `Rs2[4:0]==-(2^4-1) (0x11)`. + * The left-shifted results are saturated to the 16-bit signed integer range of [-2^15, 2^15-1]. For the `.u` + * form of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:5] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[4:0] < 0) { + * sa = -Rs2[4:0]; + * sa = (sa == 16)? 15 : sa; + * if (`.u` form) { + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } + * } else { + * sa = Rs2[3:0]; + * res[(15+sa):0] = Rs1.H[x] <<(logic) sa; + * if (res > (2^15)-1) { + * res[15:0] = 0x7fff; OV = 1; + * } else if (res < -2^15) { + * res[15:0] = 0x8000; OV = 1; + * } + * d.H[x] = res[15:0]; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA16_U(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra16.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.60.2. KSLRA16.u ===== */ + +/* ===== Inline Function Start for 3.61. KSLRAW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KSLRAW (Shift Left Logical with Q31 Saturation or Shift Right Arithmetic) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSLRAW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a logical left (positive) or arithmetic right (negative) shift operation with Q31 + * saturation for the left shift on a 32-bit data. + * + * **Description**:\n + * The lower 32-bit content of Rs1 is left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[5:0]. Rs2[5:0] is in the signed range of [-25, 25-1]. A positive Rs2[5:0] means + * logical left shift and a negative Rs2[5:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[5:0] clamped to the actual shift range of [0, 31]. + * The left-shifted result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1]. After the shift + * operation, the final result is bit-31 sign-extended and written to Rd. If any saturation happens, this + * instruction sets the OV flag. The value of Rs2[31:6] will not affected the operation of this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[5:0] < 0) { + * sa = -Rs2[5:0]; + * sa = (sa == 32)? 31 : sa; + * res[31:0] = Rs1.W[0] >>(arith) sa; + * } else { + * sa = Rs2[5:0]; + * tmp = Rs1.W[0] <<(logic) sa; + * if (tmp > (2^31)-1) { + * res[31:0] = (2^31)-1; + * OV = 1; + * } else if (tmp < -2^31) { + * res[31:0] = -2^31; + * OV = 1 + * } else { + * res[31:0] = tmp[31:0]; + * } + * } + * Rd = res[31:0]; // RV32 + * Rd = SE64(res[31:0]); // RV64 + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KSLRAW(int a, int b) +{ + long result; + __ASM volatile("kslraw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.61. KSLRAW ===== */ + +/* ===== Inline Function Start for 3.62. KSLRAW.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KSLRAW.u (Shift Left Logical with Q31 Saturation or Rounding Shift Right Arithmetic) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSLRAW.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a logical left (positive) or arithmetic right (negative) shift operation with Q31 + * saturation for the left shift and a rounding up operation for the right shift on a 32-bit data. + * + * **Description**:\n + * The lower 32-bit content of Rs1 is left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[5:0]. Rs2[5:0] is in the signed range of [-25, 25-1]. A positive Rs2[5:0] means + * logical left shift and a negative Rs2[5:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[5:0] clamped to the actual shift range of [0, 31]. + * The left-shifted result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1]. The right-shifted + * result is added a 1 to the most significant discarded bit position for rounding effect. After the shift, + * saturation, or rounding, the final result is bit-31 sign-extended and written to Rd. If any saturation + * happens, this instruction sets the OV flag. The value of Rs2[31:6] will not affect the operation of this + * instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[5:0] < 0) { + * sa = -Rs2[5:0]; + * sa = (sa == 32)? 31 : sa; + * res[31:-1] = SE33(Rs1[31:(sa-1)]) + 1; + * rst[31:0] = res[31:0]; + * } else { + * sa = Rs2[5:0]; + * tmp = Rs1.W[0] <<(logic) sa; + * if (tmp > (2^31)-1) { + * rst[31:0] = (2^31)-1; + * OV = 1; + * } else if (tmp < -2^31) { + * rst[31:0] = -2^31; + * OV = 1 + * } else { + * rst[31:0] = tmp[31:0]; + * } + * } + * Rd = rst[31:0]; // RV32 + * Rd = SE64(rst[31:0]); // RV64 + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KSLRAW_U(int a, int b) +{ + long result; + __ASM volatile("kslraw.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.62. KSLRAW.u ===== */ + +/* ===== Inline Function Start for 3.63. KSTAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KSTAS16 (SIMD 16-bit Signed Saturating Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSTAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating addition and 16-bit signed integer element + * saturating subtraction in a 32-bit chunk simultaneously. Operands are from corresponding + * positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs2; at the same time, it + * subtracts the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs2 from the 16-bit signed + * integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the Q15 number + * range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to [31:16] of 32-bit chunks in Rd for addition and [15:0] of 32-bit chunks in Rd for + * subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][15:0]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSTAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kstas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.63. KSTAS16 ===== */ + +/* ===== Inline Function Start for 3.64. KSTSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KSTSA16 (SIMD 16-bit Signed Saturating Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSTSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating subtraction and 16-bit signed integer element + * saturating addition in a 32-bit chunk simultaneously. Operands are from corresponding positions in + * 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [31:16] of 32-bit chunks + * in Rs2 from the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1; at the same time, it + * adds the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs2 with the 16-bit signed integer + * element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the Q15 number range (-2^15 + * <= Q15 <= 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated results are + * written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of 32-bit chunks in Rd for + * addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][15:0]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSTSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kstsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.64. KSTSA16 ===== */ + +/* ===== Inline Function Start for 3.65. KSUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief KSUB8 (SIMD 8-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSUB8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 8-bit signed integer elements in Rs2 from the 8-bit + * signed integer elements in Rs1. If any of the results are beyond the Q7 number range (-2^7 <= Q7 <= 27 + * -1), they are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.B[x] - Rs2.B[x]; + * if (res[x] > (2^7)-1) { + * res[x] = (2^7)-1; + * OV = 1; + * } else if (res[x] < -2^7) { + * res[x] = -2^7; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSUB8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ksub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.65. KSUB8 ===== */ + +/* ===== Inline Function Start for 3.66. KSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief KSUB16 (SIMD 16-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KSUB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer elements in Rs2 from the 16-bit + * signed integer elements in Rs1. If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= + * 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] - Rs2.H[x]; + * if (res[x] > (2^15)-1) { + * res[x] = (2^15)-1; + * OV = 1; + * } else if (res[x] < -2^15) { + * res[x] = -2^15; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSUB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ksub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.66. KSUB16 ===== */ + +/* ===== Inline Function Start for 3.67. KSUB64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief KSUB64 (64-bit Signed Saturating Subtraction) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * KSUB64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a 64-bit signed integer subtraction. The result is saturated to the Q63 range. + * + * **RV32 Description**:\n + * This instruction subtracts the 64-bit signed integer of an even/odd pair of + * registers specified by Rs2(4,1) from the 64-bit signed integer of an even/odd pair of registers + * specified by Rs1(4,1). If the 64-bit result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is + * saturated to the range and the OV bit is set to 1. The saturated result is then written to an even/odd + * pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * This instruction subtracts the 64-bit signed integer of Rs2 from the 64-bit signed + * integer of Rs1. If the 64-bit result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated + * to the range and the OV bit is set to 1. The saturated result is then written to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * result = R[a_H].R[a_L] - R[b_H].R[b_L]; + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * R[t_H].R[t_L] = result; + * RV64: + * result = Rs1 - Rs2; + * if (result > (2^63)-1) { + * result = (2^63)-1; OV = 1; + * } else if (result < -2^63) { + * result = -2^63; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_KSUB64(long long a, long long b) +{ + long long result; + __ASM volatile("ksub64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.67. KSUB64 ===== */ + +/* ===== Inline Function Start for 3.68. KSUBH ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief KSUBH (Signed Subtraction with Q15 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSUBH Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract the signed lower 32-bit content of two registers with Q15 saturation. + * + * **Description**:\n + * The signed lower 32-bit content of Rs2 is subtracted from the signed lower 32-bit + * content of Rs1. And the result is saturated to the 16-bit signed integer range of [-2^15, 2^15-1] and then + * sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] - Rs2.W[0]; + * if (tmp > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (tmp < -2^15) { + * res = -2^15; + * OV = 1 + * } else { + * res = tmp; + * } + * Rd = SE(res[15:0]); + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KSUBH(int a, int b) +{ + long result; + __ASM volatile("ksubh %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.68. KSUBH ===== */ + +/* ===== Inline Function Start for 3.69. KSUBW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief KSUBW (Signed Subtraction with Q31 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * KSUBW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract the signed lower 32-bit content of two registers with Q31 saturation. + * + * **Description**:\n + * The signed lower 32-bit content of Rs2 is subtracted from the signed lower 32-bit + * content of Rs1. And the result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1] and then + * sign-extened and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] - Rs2.W[0]; + * if (tmp > (2^31)-1) { + * res = (2^31)-1; + * OV = 1; + * } else if (tmp < -2^31) { + * res = -2^31; + * OV = 1 + * } else { + * res = tmp; + * } + * Rd = res[31:0]; // RV32 + * Rd = SE(res[31:0]); // RV64 + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KSUBW(int a, int b) +{ + long result; + __ASM volatile("ksubw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.69. KSUBW ===== */ + +/* ===== Inline Function Start for 3.70.1. KWMMUL ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KWMMUL (SIMD Saturating MSW Signed Multiply Word & Double) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KWMMUL Rd, Rs1, Rs2 + * KWMMUL.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers, shift the results left 1-bit, + * saturate, and write the most significant 32-bit results to a register. The `.u` form additionally + * rounds up the multiplication results from the most signification discarded bit. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2. It then shifts + * the multiplication results one bit to the left and takes the most significant 32-bit results. If the + * shifted result is greater than 2^31-1, it is saturated to 2^31-1 and the OV flag is set to 1. The final element + * result is written to Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The `.u` + * form of the instruction additionally rounds up the 64-bit multiplication results by adding a 1 to bit + * 30 before the shift and saturation operations. + * + * **Operations**:\n + * ~~~ + * if ((0x80000000 != Rs1.W[x]) | (0x80000000 != Rs2.W[x])) { + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][33:0] = Mres[x][63:30] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][62:31]; + * } + * } else { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KWMMUL(long a, long b) +{ + long result; + __ASM volatile("kwmmul %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.70.1. KWMMUL ===== */ + +/* ===== Inline Function Start for 3.70.2. KWMMUL.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief KWMMUL.u (SIMD Saturating MSW Signed Multiply Word & Double with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * KWMMUL Rd, Rs1, Rs2 + * KWMMUL.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of two registers, shift the results left 1-bit, + * saturate, and write the most significant 32-bit results to a register. The `.u` form additionally + * rounds up the multiplication results from the most signification discarded bit. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2. It then shifts + * the multiplication results one bit to the left and takes the most significant 32-bit results. If the + * shifted result is greater than 2^31-1, it is saturated to 2^31-1 and the OV flag is set to 1. The final element + * result is written to Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The `.u` + * form of the instruction additionally rounds up the 64-bit multiplication results by adding a 1 to bit + * 30 before the shift and saturation operations. + * + * **Operations**:\n + * ~~~ + * if ((0x80000000 != Rs1.W[x]) | (0x80000000 != Rs2.W[x])) { + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][33:0] = Mres[x][63:30] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][62:31]; + * } + * } else { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KWMMUL_U(long a, long b) +{ + long result; + __ASM volatile("kwmmul.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.70.2. KWMMUL.u ===== */ + +/* ===== Inline Function Start for 3.71. MADDR32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief MADDR32 (Multiply and Add to 32-Bit Word) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MADDR32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit contents of two registers and add the lower 32-bit multiplication result + * to the 32-bit content of a destination register. Write the final result back to the destination register. + * + * **Description**:\n + * This instruction multiplies the lower 32-bit content of Rs1 with that of Rs2. It adds the + * lower 32-bit multiplication result to the lower 32-bit content of Rd and writes the final result (RV32) + * or sign-extended result (RV64) back to Rd. The contents of Rs1 and Rs2 can be either signed or + * unsigned integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mresult = Rs1 * Rs2; + * Rd = Rd + Mresult.W[0]; + * RV64: + * Mresult = Rs1.W[0] * Rs2.W[0]; + * tres[31:0] = Rd.W[0] + Mresult.W[0]; + * Rd = SE64(tres[31:0]); + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_MADDR32(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("maddr32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.71. MADDR32 ===== */ + +/* ===== Inline Function Start for 3.72. MAXW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief MAXW (32-bit Signed Word Maximum) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MAXW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Get the larger value from the 32-bit contents of two general registers. + * + * **Description**:\n + * This instruction compares two signed 32-bit integers stored in Rs1 and Rs2, picks the + * larger value as the result, and writes the result to Rd. + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[0] >= Rs2.W[0]) { + * Rd = SE(Rs1.W[0]); + * } else { + * Rd = SE(Rs2.W[0]); + * } + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_MAXW(int a, int b) +{ + long result; + __ASM volatile("maxw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.72. MAXW ===== */ + +/* ===== Inline Function Start for 3.73. MINW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief MINW (32-bit Signed Word Minimum) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MINW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Get the smaller value from the 32-bit contents of two general registers. + * + * **Description**:\n + * This instruction compares two signed 32-bit integers stored in Rs1 and Rs2, picks the + * smaller value as the result, and writes the result to Rd. + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[0] >= Rs2.W[0]) { Rd = SE(Rs2.W[0]); } else { Rd = SE(Rs1.W[0]); } + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_MINW(int a, int b) +{ + long result; + __ASM volatile("minw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.73. MINW ===== */ + +/* ===== Inline Function Start for 3.74. MSUBR32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief MSUBR32 (Multiply and Subtract from 32-Bit Word) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MSUBR32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit contents of two registers and subtract the lower 32-bit multiplication + * result from the 32-bit content of a destination register. Write the final result back to the destination + * register. + * + * **Description**:\n + * This instruction multiplies the lower 32-bit content of Rs1 with that of Rs2, subtracts + * the lower 32-bit multiplication result from the lower 32-bit content of Rd, then writes the final + * result (RV32) or sign-extended result (RV64) back to Rd. The contents of Rs1 and Rs2 can be either + * signed or unsigned integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mresult = Rs1 * Rs2; + * Rd = Rd - Mresult.W[0]; + * RV64: + * Mresult = Rs1.W[0] * Rs2.W[0]; + * tres[31:0] = Rd.W[0] - Mresult.W[0]; + * Rd = SE64(tres[31:0]); + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_MSUBR32(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("msubr32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.74. MSUBR32 ===== */ + +/* ===== Inline Function Start for 3.75. MULR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief MULR64 (Multiply Word Unsigned to 64-bit Data) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MULR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit unsigned integer contents of two registers and write the 64-bit result. + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit content of Rs1 with that of Rs2 and writes the 64-bit + * multiplication result to an even/odd pair of registers containing Rd. Rd(4,1) index d determines the + * even/odd pair group of the two registers. Specifically, the register pair includes register 2d and + * 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * The lower 32-bit contents of Rs1 and Rs2 are treated as unsigned integers. + * + * **RV64 Description**:\n + * This instruction multiplies the lower 32-bit content of Rs1 with that of Rs2 and writes the 64-bit + * multiplication result to Rd. + * The lower 32-bit contents of Rs1 and Rs2 are treated as unsigned integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mresult = CONCAT(1`b0,Rs1) u* CONCAT(1`b0,Rs2); + * R[Rd(4,1).1(0)][31:0] = Mresult[63:32]; + * R[Rd(4,1).0(0)][31:0] = Mresult[31:0]; + * RV64: + * Rd = Mresult[63:0]; + * Mresult = CONCAT(1`b0,Rs1.W[0]) u* CONCAT(1`b0,Rs2.W[0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_MULR64(unsigned long a, unsigned long b) +{ + unsigned long long result; + __ASM volatile("mulr64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.75. MULR64 ===== */ + +/* ===== Inline Function Start for 3.76. MULSR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief MULSR64 (Multiply Word Signed to 64-bit Data) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * MULSR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed integer contents of two registers and write the 64-bit result. + * + * **RV32 Description**:\n + * This instruction multiplies the lower 32-bit content of Rs1 with the lower 32-bit content of Rs2 and + * writes the 64-bit multiplication result to an even/odd pair of registers containing Rd. Rd(4,1) index d + * determines the even/odd pair group of the two registers. Specifically, the register pair includes + * register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * The lower 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **RV64 Description**:\n + * This instruction multiplies the lower 32-bit content of Rs1 with the lower 32-bit content of Rs2 and + * writes the 64-bit multiplication result to Rd. + * The lower 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mresult = Ra s* Rb; + * R[Rd(4,1).1(0)][31:0] = Mresult[63:32]; + * R[Rd(4,1).0(0)][31:0] = Mresult[31:0]; + * RV64: + * Mresult = Ra.W[0] s* Rb.W[0]; + * Rd = Mresult[63:0]; + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_MULSR64(long a, long b) +{ + long long result; + __ASM volatile("mulsr64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.76. MULSR64 ===== */ + +/* ===== Inline Function Start for 3.77. PBSAD ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief PBSAD (Parallel Byte Sum of Absolute Difference) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PBSAD Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Calculate the sum of absolute difference of unsigned 8-bit data elements. + * + * **Description**:\n + * This instruction subtracts the un-signed 8-bit elements of Rs2 from those of Rs1. Then + * it adds the absolute value of each difference together and writes the result to Rd. + * + * **Operations**:\n + * ~~~ + * absdiff[x] = ABS(Rs1.B[x] - Rs2.B[x]); + * Rd = SUM(absdiff[x]); + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PBSAD(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pbsad %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.77. PBSAD ===== */ + +/* ===== Inline Function Start for 3.78. PBSADA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief PBSADA (Parallel Byte Sum of Absolute Difference Accum) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PBSADA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Calculate the sum of absolute difference of four unsigned 8-bit data elements and + * accumulate it into a register. + * + * **Description**:\n + * This instruction subtracts the un-signed 8-bit elements of Rs2 from those of Rs1. It + * then adds the absolute value of each difference together along with the content of Rd and writes the + * accumulated result back to Rd. + * + * **Operations**:\n + * ~~~ + * absdiff[x] = ABS(Rs1.B[x] - Rs2.B[x]); + * Rd = Rd + SUM(absdiff[x]); + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PBSADA(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("pbsada %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.78. PBSADA ===== */ + +/* ===== Inline Function Start for 3.79.1. PKBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_PACK + * \brief PKBB16 (Pack Two 16-bit Data from Both Bottom Half) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PKBB16 Rd, Rs1, Rs2 + * PKBT16 Rd, Rs1, Rs2 + * PKTT16 Rd, Rs1, Rs2 + * PKTB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBB16: bottom.bottom + * * PKBT16 bottom.top + * * PKTT16 top.top + * * PKTB16 top.bottom + * + * **Description**:\n + * (PKBB16) moves Rs1.W[x][15:0] to Rd.W[x][31:16] and moves Rs2.W[x] [15:0] to + * Rd.W[x] [15:0]. + * (PKBT16) moves Rs1.W[x] [15:0] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTT16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTB16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][15:0]); // PKBB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][31:16]); // PKBT16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][15:0]); // PKTB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][31:16]); // PKTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKBB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pkbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.79.1. PKBB16 ===== */ + +/* ===== Inline Function Start for 3.79.2. PKBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_PACK + * \brief PKBT16 (Pack Two 16-bit Data from Bottom and Top Half) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PKBB16 Rd, Rs1, Rs2 + * PKBT16 Rd, Rs1, Rs2 + * PKTT16 Rd, Rs1, Rs2 + * PKTB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBB16: bottom.bottom + * * PKBT16 bottom.top + * * PKTT16 top.top + * * PKTB16 top.bottom + * + * **Description**:\n + * (PKBB16) moves Rs1.W[x][15:0] to Rd.W[x][31:16] and moves Rs2.W[x] [15:0] to + * Rd.W[x] [15:0]. + * (PKBT16) moves Rs1.W[x] [15:0] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTT16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTB16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][15:0]); // PKBB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][31:16]); // PKBT16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][15:0]); // PKTB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][31:16]); // PKTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKBT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pkbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.79.2. PKBT16 ===== */ + +/* ===== Inline Function Start for 3.79.3. PKTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_PACK + * \brief PKTT16 (Pack Two 16-bit Data from Both Top Half) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PKBB16 Rd, Rs1, Rs2 + * PKBT16 Rd, Rs1, Rs2 + * PKTT16 Rd, Rs1, Rs2 + * PKTB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBB16: bottom.bottom + * * PKBT16 bottom.top + * * PKTT16 top.top + * * PKTB16 top.bottom + * + * **Description**:\n + * (PKBB16) moves Rs1.W[x][15:0] to Rd.W[x][31:16] and moves Rs2.W[x] [15:0] to + * Rd.W[x] [15:0]. + * (PKBT16) moves Rs1.W[x] [15:0] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTT16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTB16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][15:0]); // PKBB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][31:16]); // PKBT16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][15:0]); // PKTB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][31:16]); // PKTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKTT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pktt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.79.3. PKTT16 ===== */ + +/* ===== Inline Function Start for 3.79.4. PKTB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_PACK + * \brief PKTB16 (Pack Two 16-bit Data from Top and Bottom Half) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * PKBB16 Rd, Rs1, Rs2 + * PKBT16 Rd, Rs1, Rs2 + * PKTT16 Rd, Rs1, Rs2 + * PKTB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBB16: bottom.bottom + * * PKBT16 bottom.top + * * PKTT16 top.top + * * PKTB16 top.bottom + * + * **Description**:\n + * (PKBB16) moves Rs1.W[x][15:0] to Rd.W[x][31:16] and moves Rs2.W[x] [15:0] to + * Rd.W[x] [15:0]. + * (PKBT16) moves Rs1.W[x] [15:0] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTT16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * (PKTB16) moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][15:0]); // PKBB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][31:16]); // PKBT16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][15:0]); // PKTB16 + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][31:16]); // PKTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKTB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pktb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.79.4. PKTB16 ===== */ + +/* ===== Inline Function Start for 3.80. RADD8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief RADD8 (SIMD 8-bit Signed Halving Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RADD8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer element additions simultaneously. The element results are halved + * to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 8-bit signed integer elements in Rs1 with the 8-bit signed + * integer elements in Rs2. The results are first arithmetically right-shifted by 1 bit and then written to + * Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7F, Rs2 = 0x7F, Rd = 0x7F + * * Rs1 = 0x80, Rs2 = 0x80, Rd = 0x80 + * * Rs1 = 0x40, Rs2 = 0x80, Rd = 0xE0 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] + Rs2.B[x]) s>> 1; for RV32: x=3...0, for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RADD8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("radd8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.80. RADD8 ===== */ + +/* ===== Inline Function Start for 3.81. RADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RADD16 (SIMD 16-bit Signed Halving Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RADD16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element additions simultaneously. The results are halved to avoid + * overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer elements in Rs1 with the 16-bit signed + * integer elements in Rs2. The results are first arithmetically right-shifted by 1 bit and then written to + * Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7FFF, Rs2 = 0x7FFF, Rd = 0x7FFF + * * Rs1 = 0x8000, Rs2 = 0x8000, Rd = 0x8000 + * * Rs1 = 0x4000, Rs2 = 0x8000, Rd = 0xE000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] + Rs2.H[x]) s>> 1; for RV32: x=1...0, for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RADD16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("radd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.81. RADD16 ===== */ + +/* ===== Inline Function Start for 3.82. RADD64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief RADD64 (64-bit Signed Halving Addition) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * RADD64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add two 64-bit signed integers. The result is halved to avoid overflow or saturation. + * + * **RV32 Description**:\n + * This instruction adds the 64-bit signed integer of an even/odd pair of registers + * specified by Rs1(4,1) with the 64-bit signed integer of an even/odd pair of registers specified by + * Rs2(4,1). The 64-bit addition result is first arithmetically right-shifted by 1 bit and then written to an + * even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., value d, determines the even/odd pair group of two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction adds the 64-bit signed integer in Rs1 with the 64-bit signed + * integer in Rs2. The 64-bit addition result is first arithmetically right-shifted by 1 bit and then + * written to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * R[t_H].R[t_L] = (R[a_H].R[a_L] + R[b_H].R[b_L]) s>> 1; + * RV64: + * Rd = (Rs1 + Rs2) s>> 1; + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_RADD64(long long a, long long b) +{ + long long result; + __ASM volatile("radd64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.82. RADD64 ===== */ + +/* ===== Inline Function Start for 3.83. RADDW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief RADDW (32-bit Signed Halving Addition) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * RADDW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add 32-bit signed integers and the results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the first 32-bit signed integer in Rs1 with the first 32-bit signed + * integer in Rs2. The result is first arithmetically right-shifted by 1 bit and then sign-extended and + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7FFFFFFF, Rs2 = 0x7FFFFFFF, Rd = 0x7FFFFFFF + * * Rs1 = 0x80000000, Rs2 = 0x80000000, Rd = 0x80000000 + * * Rs1 = 0x40000000, Rs2 = 0x80000000, Rd = 0xE0000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * RV32: + * Rd[31:0] = (Rs1[31:0] + Rs2[31:0]) s>> 1; + * RV64: + * resw[31:0] = (Rs1[31:0] + Rs2[31:0]) s>> 1; + * Rd[63:0] = SE(resw[31:0]); + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_RADDW(int a, int b) +{ + long result; + __ASM volatile("raddw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.83. RADDW ===== */ + +/* ===== Inline Function Start for 3.84. RCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RCRAS16 (SIMD 16-bit Signed Halving Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RCRAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element addition and 16-bit signed integer element subtraction in + * a 32-bit chunk simultaneously. Operands are from crossed positions in 32-bit chunks. The results + * are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs2, and subtracts the 16-bit + * signed integer element in [31:16] of 32-bit chunks in Rs2 from the 16-bit signed integer element in + * [15:0] of 32-bit chunks in Rs1. The element results are first arithmetically right-shifted by 1 bit and + * then written to [31:16] of 32-bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `RADD16` and `RSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] + Rs2.W[x][15:0]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] - Rs2.W[x][31:16]) s>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RCRAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.84. RCRAS16 ===== */ + +/* ===== Inline Function Start for 3.85. RCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RCRSA16 (SIMD 16-bit Signed Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RCRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtraction and 16-bit signed integer element addition in + * a 32-bit chunk simultaneously. Operands are from crossed positions in 32-bit chunks. The results + * are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [15:0] of 32-bit chunks + * in Rs2 from the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1, and adds the 16-bit + * signed element integer in [15:0] of 32-bit chunks in Rs1 with the 16-bit signed integer element in + * [31:16] of 32-bit chunks in Rs2. The two results are first arithmetically right-shifted by 1 bit and + * then written to [31:16] of 32-bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `RADD16` and `RSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] - Rs2.W[x][15:0]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] + Rs2.W[x][31:16]) s>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RCRSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.85. RCRSA16 ===== */ + +/* ===== Inline Function Start for 3.86. RDOV ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_OV_FLAG_SC + * \brief RDOV (Read OV flag) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * RDOV Rd # pseudo mnemonic + * ~~~ + * + * **Purpose**:\n + * This pseudo instruction is an alias to `CSRR Rd, ucode` instruction which maps to the real + * instruction of `CSRRS Rd, ucode, x0`. + * + * + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RDOV(void) +{ + unsigned long result; + __ASM volatile("rdov %0" : "=r"(result)); + return result; +} +/* ===== Inline Function End for 3.86. RDOV ===== */ + +/* ===== Inline Function Start for 3.87. RSTAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RSTAS16 (SIMD 16-bit Signed Halving Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RSTAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element addition and 16-bit signed integer element subtraction in + * a 32-bit chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. The + * results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs2, and subtracts the 16-bit + * signed integer element in [15:0] of 32-bit chunks in Rs2 from the 16-bit signed integer element in + * [15:0] of 32-bit chunks in Rs1. The element results are first arithmetically right-shifted by 1 bit and + * then written to [31:16] of 32-bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `RADD16` and `RSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] + Rs2.W[x][31:16]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] - Rs2.W[x][15:0]) s>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSTAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rstas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.87. RSTAS16 ===== */ + +/* ===== Inline Function Start for 3.88. RSTSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RSTSA16 (SIMD 16-bit Signed Halving Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RSTSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtraction and 16-bit signed integer element addition in + * a 32-bit chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. The + * results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [31:16] of 32-bit chunks + * in Rs2 from the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1, and adds the 16-bit + * signed element integer in [15:0] of 32-bit chunks in Rs1 with the 16-bit signed integer element in + * [15:0] of 32-bit chunks in Rs2. The two results are first arithmetically right-shifted by 1 bit and then + * written to [31:16] of 32-bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `RADD16` and `RSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] - Rs2.W[x][31:16]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] + Rs2.W[x][15:0]) s>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSTSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rstsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.88. RSTSA16 ===== */ + +/* ===== Inline Function Start for 3.89. RSUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief RSUB8 (SIMD 8-bit Signed Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RSUB8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 8-bit signed integer elements in Rs2 from the 8-bit + * signed integer elements in Rs1. The results are first arithmetically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7F, Rs2 = 0x80, Rd = 0x7F + * * Rs1 = 0x80, Rs2 = 0x7F, Rd = 0x80 + * * Rs1= 0x80, Rs2 = 0x40, Rd = 0xA0 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] - Rs2.B[x]) s>> 1; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSUB8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rsub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.89. RSUB8 ===== */ + +/* ===== Inline Function Start for 3.90. RSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief RSUB16 (SIMD 16-bit Signed Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * RSUB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer elements in Rs2 from the 16-bit + * signed integer elements in Rs1. The results are first arithmetically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFF, Rb = 0x8000, Rt = 0x7FFF + * * Ra = 0x8000, Rb = 0x7FFF, Rt = 0x8000 + * * Ra = 0x8000, Rb = 0x4000, Rt = 0xA000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] - Rs2.H[x]) s>> 1; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSUB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rsub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.90. RSUB16 ===== */ + +/* ===== Inline Function Start for 3.91. RSUB64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief RSUB64 (64-bit Signed Halving Subtraction) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * RSUB64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a 64-bit signed integer subtraction. The result is halved to avoid overflow or + * saturation. + * + * **RV32 Description**:\n + * This instruction subtracts the 64-bit signed integer of an even/odd pair of + * registers specified by Rb(4,1) from the 64-bit signed integer of an even/odd pair of registers + * specified by Ra(4,1). The subtraction result is first arithmetically right-shifted by 1 bit and then + * written to an even/odd pair of registers specified by Rt(4,1). + * Rx(4,1), i.e., value d, determines the even/odd pair group of two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction subtracts the 64-bit signed integer in Rs2 from the 64-bit signed + * integer in Rs1. The 64-bit subtraction result is first arithmetically right-shifted by 1 bit and then + * written to Rd. + * + * **Operations**:\n + * ~~~ + * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * R[t_H].R[t_L] = (R[a_H].R[a_L] - R[b_H].R[b_L]) s>> 1; + * RV64: + * Rd = (Rs1 - Rs2) s>> 1; + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_RSUB64(long long a, long long b) +{ + long long result; + __ASM volatile("rsub64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.91. RSUB64 ===== */ + +/* ===== Inline Function Start for 3.92. RSUBW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief RSUBW (32-bit Signed Halving Subtraction) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * RSUBW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract 32-bit signed integers and the result is halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the first 32-bit signed integer in Rs2 from the first 32-bit + * signed integer in Rs1. The result is first arithmetically right-shifted by 1 bit and then sign-extended + * and written to Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7FFFFFFF, Rs2 = 0x80000000, Rd = 0x7FFFFFFF + * * Rs1 = 0x80000000, Rs2 = 0x7FFFFFFF, Rd = 0x80000000 + * * Rs1 = 0x80000000, Rs2 = 0x40000000, Rd = 0xA0000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * RV32: + * Rd[31:0] = (Rs1[31:0] - Rs2[31:0]) s>> 1; + * RV64: + * resw[31:0] = (Rs1[31:0] - Rs2[31:0]) s>> 1; + * Rd[63:0] = SE(resw[31:0]); + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_RSUBW(int a, int b) +{ + long result; + __ASM volatile("rsubw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.92. RSUBW ===== */ + +/* ===== Inline Function Start for 3.93. SCLIP8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief SCLIP8 (SIMD 8-bit Signed Clip Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCLIP8 Rd, Rs1, imm3u[2:0] + * ~~~ + * + * **Purpose**:\n + * Limit the 8-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 8-bit signed integer elements stored in Rs1 into a signed + * integer range between 2^imm3u-1 and -2^imm3u, and writes the limited results to Rd. For example, if + * imm3u is 3, the 8-bit input values should be saturated between 7 and -8. If saturation is performed, + * set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.B[x]; + * if (src > (2^imm3u)-1) { + * src = (2^imm3u)-1; + * OV = 1; + * } else if (src < -2^imm3u) { + * src = -2^imm3u; + * OV = 1; + * } + * Rd.B[x] = src + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SCLIP8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("sclip8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.93. SCLIP8 ===== */ + +/* ===== Inline Function Start for 3.94. SCLIP16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief SCLIP16 (SIMD 16-bit Signed Clip Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCLIP16 Rd, Rs1, imm4u[3:0] + * ~~~ + * + * **Purpose**:\n + * Limit the 16-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 16-bit signed integer elements stored in Rs1 into a signed + * integer range between 2imm4u-1 and -2imm4u, and writes the limited results to Rd. For example, if + * imm4u is 3, the 16-bit input values should be saturated between 7 and -8. If saturation is performed, + * set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src > (2^imm4u)-1) { + * src = (2^imm4u)-1; + * OV = 1; + * } else if (src < -2^imm4u) { + * src = -2^imm4u; + * OV = 1; + * } + * Rd.H[x] = src + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SCLIP16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("sclip16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.94. SCLIP16 ===== */ + +/* ===== Inline Function Start for 3.95. SCLIP32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief SCLIP32 (SIMD 32-bit Signed Clip Value) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SCLIP32 Rd, Rs1, imm5u[4:0] + * ~~~ + * + * **Purpose**:\n + * Limit the 32-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 32-bit signed integer elements stored in Rs1 into a signed + * integer range between 2imm5u-1 and -2imm5u, and writes the limited results to Rd. For example, if + * imm5u is 3, the 32-bit input values should be saturated between 7 and -8. If saturation is performed, + * set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.W[x]; + * if (src > (2^imm5u)-1) { + * src = (2^imm5u)-1; + * OV = 1; + * } else if (src < -2^imm5u) { + * src = -2^imm5u; + * OV = 1; + * } + * Rd.W[x] = src + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +#define __RV_SCLIP32(a, b) \ + ({ \ + long result; \ + long __a = (long)(a); \ + __ASM volatile("sclip32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.95. SCLIP32 ===== */ + +/* ===== Inline Function Start for 3.96. SCMPLE8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP + * \brief SCMPLE8 (SIMD 8-bit Signed Compare Less Than & Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCMPLE8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer elements less than & equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit signed integer elements in Rs1 with the 8-bit + * signed integer elements in Rs2 to see if the one in Rs1 is less than or equal to the one in Rs2. If it is + * true, the result is 0xFF; otherwise, the result is 0x0. The element comparison results are written to + * Rd + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] {le} Rs2.B[x])? 0xff : 0x0; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SCMPLE8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("scmple8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.96. SCMPLE8 ===== */ + +/* ===== Inline Function Start for 3.97. SCMPLE16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_CMP + * \brief SCMPLE16 (SIMD 16-bit Signed Compare Less Than & Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCMPLE16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements less than & equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit signed integer elements in Rs1 with the 16-bit + * signed integer elements in Rs2 to see if the one in Rs1 is less than or equal to the one in Rs2. If it is + * true, the result is 0xFFFF; otherwise, the result is 0x0. The element comparison results are written + * to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] {le} Rs2.H[x])? 0xffff : 0x0; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SCMPLE16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("scmple16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.97. SCMPLE16 ===== */ + +/* ===== Inline Function Start for 3.98. SCMPLT8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP + * \brief SCMPLT8 (SIMD 8-bit Signed Compare Less Than) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCMPLT8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer elements less than comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit signed integer elements in Rs1 with the 8-bit + * signed integer elements in Rs2 to see if the one in Rs1 is less than the one in Rs2. If it is true, the + * result is 0xFF; otherwise, the result is 0x0. The element comparison results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] < Rs2.B[x])? 0xff : 0x0; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SCMPLT8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("scmplt8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.98. SCMPLT8 ===== */ + +/* ===== Inline Function Start for 3.99. SCMPLT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_CMP + * \brief SCMPLT16 (SIMD 16-bit Signed Compare Less Than) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SCMPLT16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements less than comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit signed integer elements in Rs1 with the two 16- + * bit signed integer elements in Rs2 to see if the one in Rs1 is less than the one in Rs2. If it is true, the + * result is 0xFFFF; otherwise, the result is 0x0. The element comparison results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] < Rs2.H[x])? 0xffff : 0x0; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SCMPLT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("scmplt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.99. SCMPLT16 ===== */ + +/* ===== Inline Function Start for 3.100. SLL8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SLL8 (SIMD 8-bit Shift Left Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SLL8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left shift operations simultaneously. The shift amount is a + * variable from a GPR. + * + * **Description**:\n + * The 8-bit elements in Rs1 are left-shifted logically. And the results are written to Rd. + * The shifted out bits are filled with zero and the shift amount is specified by the low-order 3-bits of + * the value in the Rs2 register. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * Rd.B[x] = Rs1.B[x] << sa; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SLL8(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sll8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.100. SLL8 ===== */ + +/* ===== Inline Function Start for 3.101. SLLI8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SLLI8 (SIMD 8-bit Shift Left Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SLLI8 Rd, Rs1, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left shift operations simultaneously. The shift amount is an + * immediate value. + * + * **Description**:\n + * The 8-bit elements in Rs1 are left-shifted logically. And the results are written to Rd. + * The shifted out bits are filled with zero and the shift amount is specified by the imm3u constant. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * Rd.B[x] = Rs1.B[x] << sa; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SLLI8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("slli8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.101. SLLI8 ===== */ + +/* ===== Inline Function Start for 3.102. SLL16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SLL16 (SIMD 16-bit Shift Left Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SLL16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left shift operations simultaneously. The shift amount is a + * variable from a GPR. + * + * **Description**:\n + * The 16-bit elements in Rs1 are left-shifted logically. And the results are written to Rd. + * The shifted out bits are filled with zero and the shift amount is specified by the low-order 4-bits of + * the value in the Rs2 register. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * Rd.H[x] = Rs1.H[x] << sa; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SLL16(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sll16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.102. SLL16 ===== */ + +/* ===== Inline Function Start for 3.103. SLLI16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SLLI16 (SIMD 16-bit Shift Left Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SLLI16 Rd, Rs1, imm4[3:0] + * ~~~ + * + * **Purpose**:\n + * Do 16-bit element logical left shift operations simultaneously. The shift amount is an + * immediate value. + * + * **Description**:\n + * The 16-bit elements in Rs1 are left-shifted logically. The shifted out bits are filled with + * zero and the shift amount is specified by the imm4[3:0] constant. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm4[3:0]; + * Rd.H[x] = Rs1.H[x] << sa; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SLLI16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("slli16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.103. SLLI16 ===== */ + +/* ===== Inline Function Start for 3.104. SMAL ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMAL (Signed Multiply Halfs & Add 64-bit) + * \details + * **Type**: Partial-SIMD + * + * **Syntax**:\n + * ~~~ + * SMAL Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed bottom 16-bit content of the 32-bit elements of a register with the top + * 16-bit content of the same 32-bit elements of the same register, and add the results with a 64-bit + * value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is written back + * to another even/odd pair of registers (RV32) or a register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the bottom 16-bit content of the lower 32-bit of Rs2 with the top 16-bit + * content of the lower 32-bit of Rs2 and adds the result with the 64-bit value of an even/odd pair of + * registers specified by Rs1(4,1). The 64-bit addition result is written back to an even/odd pair of + * registers specified by Rd(4,1). The 16-bit values of Rs2, and the 64-bit value of the Rs1(4,1) register- + * pair are treated as signed integers. + * Rx(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * This instruction multiplies the bottom 16-bit content of the 32-bit elements of Rs2 with the top 16-bit + * content of the same 32-bit elements of Rs2 and adds the results with the 64-bit value of Rs1. The 64- + * bit addition result is written back to Rd. The 16-bit values of Rs2, and the 64-bit value of Rs1 are + * treated as signed integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mres[31:0] = Rs2.H[1] * Rs2.H[0]; + * Idx0 = CONCAT(Rs1(4,1),1'b0); Idx1 = CONCAT(Rs1(4,1),1'b1); + + * Idx2 = CONCAT(Rd(4,1),1'b0); Idx3 = CONCAT(Rd(4,1),1'b1); + * R[Idx3].R[Idx2] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * RV64: + * Mres[0][31:0] = Rs2.W[0].H[1] * Rs2.W[0].H[0]; + * Mres[1][31:0] = Rs2.W[1].H[1] * Rs2.W[1].H[0]; + * Rd = Rs1 + SE64(Mres[1][31:0]) + SE64(Mres[0][31:0]); + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMAL(long long a, unsigned long b) +{ + long long result; + __ASM volatile("smal %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.104. SMAL ===== */ + +/* ===== Inline Function Start for 3.105.1. SMALBB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALBB (Signed Multiply Bottom Halfs & Add 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALBB Rd, Rs1, Rs2 + * SMALBT Rd, Rs1, Rs2 + * SMALTT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit + * content of the corresponding 32-bit elements of another register and add the results with a 64-bit + * value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is written back + * to the register-pair (RV32) or the register (RV64). + * * SMALBB: rt pair + bottom*bottom (all 32-bit elements) + * * SMALBT rt pair + bottom*top (all 32-bit elements) + * * SMALTT rt pair + top*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2. + * The multiplication result is added with the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mres[31:0] = Rs1.H[0] * Rs2.H[0]; // SMALBB + * Mres[31:0] = Rs1.H[0] * Rs2.H[1]; // SMALBT + * Mres[31:0] = Rs1.H[1] * Rs2.H[1]; // SMALTT + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * RV64: + * // SMALBB + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[0]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[0]; + * // SMALBT + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[1]; + * // SMALTT + * Mres[0][31:0] = Rs1.W[0].H[1] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[1] * Rs2.W[1].H[1]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALBB(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalbb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.105.1. SMALBB ===== */ + +/* ===== Inline Function Start for 3.105.2. SMALBT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALBT (Signed Multiply Bottom Half & Top Half & Add 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALBB Rd, Rs1, Rs2 + * SMALBT Rd, Rs1, Rs2 + * SMALTT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit + * content of the corresponding 32-bit elements of another register and add the results with a 64-bit + * value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is written back + * to the register-pair (RV32) or the register (RV64). + * * SMALBB: rt pair + bottom*bottom (all 32-bit elements) + * * SMALBT rt pair + bottom*top (all 32-bit elements) + * * SMALTT rt pair + top*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2. + * The multiplication result is added with the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mres[31:0] = Rs1.H[0] * Rs2.H[0]; // SMALBB + * Mres[31:0] = Rs1.H[0] * Rs2.H[1]; // SMALBT + * Mres[31:0] = Rs1.H[1] * Rs2.H[1]; // SMALTT + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * RV64: + * // SMALBB + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[0]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[0]; + * // SMALBT + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[1]; + * // SMALTT + * Mres[0][31:0] = Rs1.W[0].H[1] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[1] * Rs2.W[1].H[1]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALBT(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalbt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.105.2. SMALBT ===== */ + +/* ===== Inline Function Start for 3.105.3. SMALTT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALTT (Signed Multiply Top Halfs & Add 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALBB Rd, Rs1, Rs2 + * SMALBT Rd, Rs1, Rs2 + * SMALTT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit + * content of the corresponding 32-bit elements of another register and add the results with a 64-bit + * value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is written back + * to the register-pair (RV32) or the register (RV64). + * * SMALBB: rt pair + bottom*bottom (all 32-bit elements) + * * SMALBT rt pair + bottom*top (all 32-bit elements) + * * SMALTT rt pair + top*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2. + * The multiplication result is added with the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALBB` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMALBT` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMALTT` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * Mres[31:0] = Rs1.H[0] * Rs2.H[0]; // SMALBB + * Mres[31:0] = Rs1.H[0] * Rs2.H[1]; // SMALBT + * Mres[31:0] = Rs1.H[1] * Rs2.H[1]; // SMALTT + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * RV64: + * // SMALBB + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[0]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[0]; + * // SMALBT + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[1]; + * // SMALTT + * Mres[0][31:0] = Rs1.W[0].H[1] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[1] * Rs2.W[1].H[1]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALTT(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smaltt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.105.3. SMALTT ===== */ + +/* ===== Inline Function Start for 3.106.1. SMALDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALDA (Signed Multiply Two Halfs and Two Adds 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALDA Rd, Rs1, Rs2 + * SMALXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * adds the two 32-bit results and the 64-bit value of an even/odd pair of registers together. + * * SMALDA: rt pair+ top*top + bottom*bottom (all 32-bit elements) + * * SMALXDA: rt pair+ top*bottom + bottom*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALDA` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the top 16-bit content of Rs1 with + * the top 16-bit content of Rs2 with unlimited precision. + * For the `SMALXDA` instruction, it multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the bottom 16-bit content of Rs1 + * with the top 16-bit content of Rs2 with unlimited precision. + * The result is added to the 64-bit value of an even/odd pair of registers specified by Rd(4,1). The 64- + * bit addition result is written back to the register-pair. The 16-bit values of Rs1 and Rs2, and the 64- + * bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32- + * bit elements of Rs2 with unlimited precision. + * For the `SMALXDA` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the + * 32-bit elements of Rs2 with unlimited precision. + * The results are added to the 64-bit value of Rd. The 64-bit addition result is written back to Rd. The + * 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * // SMALDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[0]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[1]); + * // SMALXDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[1]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[0]); + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres0[31:0]) + SE64(Mres1[31:0]); + * RV64: + * // SMALDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMALXDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[0]); + * Rd = Rd + SE64(Mres0[0][31:0]) + SE64(Mres1[0][31:0]) + SE64(Mres0[1][31:0]) + + * SE64(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALDA(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.106.1. SMALDA ===== */ + +/* ===== Inline Function Start for 3.106.2. SMALXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALXDA (Signed Crossed Multiply Two Halfs and Two Adds 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALDA Rd, Rs1, Rs2 + * SMALXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * adds the two 32-bit results and the 64-bit value of an even/odd pair of registers together. + * * SMALDA: rt pair+ top*top + bottom*bottom (all 32-bit elements) + * * SMALXDA: rt pair+ top*bottom + bottom*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALDA` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the top 16-bit content of Rs1 with + * the top 16-bit content of Rs2 with unlimited precision. + * For the `SMALXDA` instruction, it multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the bottom 16-bit content of Rs1 + * with the top 16-bit content of Rs2 with unlimited precision. + * The result is added to the 64-bit value of an even/odd pair of registers specified by Rd(4,1). The 64- + * bit addition result is written back to the register-pair. The 16-bit values of Rs1 and Rs2, and the 64- + * bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32- + * bit elements of Rs2 with unlimited precision. + * For the `SMALXDA` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then adds the result to the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the + * 32-bit elements of Rs2 with unlimited precision. + * The results are added to the 64-bit value of Rd. The 64-bit addition result is written back to Rd. The + * 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * RV32: + * // SMALDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[0]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[1]); + * // SMALXDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[1]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[0]); + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres0[31:0]) + SE64(Mres1[31:0]); + * RV64: + * // SMALDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMALXDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[0]); + * Rd = Rd + SE64(Mres0[0][31:0]) + SE64(Mres1[0][31:0]) + SE64(Mres0[1][31:0]) + + * SE64(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALXDA(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.106.2. SMALXDA ===== */ + +/* ===== Inline Function Start for 3.107.1. SMALDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALDS (Signed Multiply Two Halfs & Subtract & Add 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALDS Rd, Rs1, Rs2 + * SMALDRS Rd, Rs1, Rs2 + * SMALXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the 64-bit value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is + * written back to the register-pair. + * * SMALDS: rt pair + (top*top - bottom*bottom) (all 32-bit elements) + * * SMALDRS: rt pair + (bottom*bottom - top*top) (all 32-bit elements) + * * SMALXDS: rt pair + (top*bottom - bottom*top) (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the top 16-bit content of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2 and then subtracts the result from the result of multiplying the bottom 16-bit content of Rs1 + * with the bottom 16-bit content of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the bottom 16-bit content of Rs2. + * The subtraction result is then added to the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content + * of the 32-bit elements of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction results are then added to the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * * RV32: + * Mres[31:0] = (Rs1.H[1] * Rs2.H[1]) - (Rs1.H[0] * Rs2.H[0]); // SMALDS + * Mres[31:0] = (Rs1.H[0] * Rs2.H[0]) - (Rs1.H[1] * Rs2.H[1]); // SMALDRS + * Mres[31:0] = (Rs1.H[1] * Rs2.H[0]) - (Rs1.H[0] * Rs2.H[1]); // SMALXDS + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * * RV64: + * // SMALDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]) - (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[1]) - (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * // SMALDRS + * Mres[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]) - (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[0].H[0]) - (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMALXDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]) - (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[0]) - (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALDS(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.107.1. SMALDS ===== */ + +/* ===== Inline Function Start for 3.107.2. SMALDRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALDRS (Signed Multiply Two Halfs & Reverse Subtract & Add 64- bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALDS Rd, Rs1, Rs2 + * SMALDRS Rd, Rs1, Rs2 + * SMALXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the 64-bit value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is + * written back to the register-pair. + * * SMALDS: rt pair + (top*top - bottom*bottom) (all 32-bit elements) + * * SMALDRS: rt pair + (bottom*bottom - top*top) (all 32-bit elements) + * * SMALXDS: rt pair + (top*bottom - bottom*top) (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the top 16-bit content of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2 and then subtracts the result from the result of multiplying the bottom 16-bit content of Rs1 + * with the bottom 16-bit content of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the bottom 16-bit content of Rs2. + * The subtraction result is then added to the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content + * of the 32-bit elements of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction results are then added to the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * * RV32: + * Mres[31:0] = (Rs1.H[1] * Rs2.H[1]) - (Rs1.H[0] * Rs2.H[0]); // SMALDS + * Mres[31:0] = (Rs1.H[0] * Rs2.H[0]) - (Rs1.H[1] * Rs2.H[1]); // SMALDRS + * Mres[31:0] = (Rs1.H[1] * Rs2.H[0]) - (Rs1.H[0] * Rs2.H[1]); // SMALXDS + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * * RV64: + * // SMALDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]) - (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[1]) - (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * // SMALDRS + * Mres[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]) - (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[0].H[0]) - (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMALXDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]) - (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[0]) - (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALDRS(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smaldrs %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.107.2. SMALDRS ===== */ + +/* ===== Inline Function Start for 3.107.3. SMALXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMALXDS (Signed Crossed Multiply Two Halfs & Subtract & Add 64- bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMALDS Rd, Rs1, Rs2 + * SMALDRS Rd, Rs1, Rs2 + * SMALXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the 64-bit value of an even/odd pair of registers (RV32) or a register (RV64). The addition result is + * written back to the register-pair. + * * SMALDS: rt pair + (top*top - bottom*bottom) (all 32-bit elements) + * * SMALDRS: rt pair + (bottom*bottom - top*top) (all 32-bit elements) + * * SMALXDS: rt pair + (top*bottom - bottom*top) (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the top 16-bit content of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2 and then subtracts the result from the result of multiplying the bottom 16-bit content of Rs1 + * with the bottom 16-bit content of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the bottom 16-bit content of Rs2. + * The subtraction result is then added to the 64-bit value of an even/odd pair of registers specified by + * Rd(4,1). The 64-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and + * Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * For the `SMALDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content + * of the 32-bit elements of Rs2. + * For the `SMALDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMALXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction results are then added to the 64-bit value of Rd. The 64-bit addition result is written + * back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * * RV32: + * Mres[31:0] = (Rs1.H[1] * Rs2.H[1]) - (Rs1.H[0] * Rs2.H[0]); // SMALDS + * Mres[31:0] = (Rs1.H[0] * Rs2.H[0]) - (Rs1.H[1] * Rs2.H[1]); // SMALDRS + * Mres[31:0] = (Rs1.H[1] * Rs2.H[0]) - (Rs1.H[0] * Rs2.H[1]); // SMALXDS + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] + SE64(Mres[31:0]); + * * RV64: + * // SMALDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]) - (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[1]) - (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * // SMALDRS + * Mres[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]) - (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[0].H[0]) - (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMALXDS + * Mres[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]) - (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[0].H[0]) - (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMALXDS(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smalxds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.107.3. SMALXDS ===== */ + +/* ===== Inline Function Start for 3.108. SMAR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief SMAR64 (Signed Multiply and Add to 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMAR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed elements in two registers and add the 64-bit multiplication + * result to the 64-bit signed data of a pair of registers (RV32) or a register (RV64). The result is written + * back to the pair of registers (RV32) or a register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit signed data of Rs1 with that of Rs2. It adds + * the 64-bit multiplication result to the 64-bit signed data of an even/odd pair of registers specified by + * Rd(4,1). The addition result is written back to the even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit signed elements of Rs1 with that of Rs2. It + * adds the 64-bit multiplication results to the 64-bit signed data of Rd. The addition result is written + * back to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H].R[t_L] = R[t_H].R[t_L] + (Rs1 * Rs2); + * * RV64: + * Rd = Rd + (Rs1.W[0] * Rs2.W[0]) + (Rs1.W[1] * Rs2.W[1]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMAR64(long long t, long a, long b) +{ + __ASM volatile("smar64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.108. SMAR64 ===== */ + +/* ===== Inline Function Start for 3.109. SMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_8B_MULT_32B_ADD + * \brief SMAQA (Signed Multiply Four Bytes with 32-bit Adds) + * \details + * **Type**: Partial-SIMD (Reduction) + * + * **Syntax**:\n + * ~~~ + * SMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 8-bit multiplications from 32-bit chunks of two registers; and then adds + * the four 16-bit results and the content of corresponding 32-bit chunks of a third register together. + * + * **Description**:\n + * This instruction multiplies the four signed 8-bit elements of 32-bit chunks of Rs1 with the four + * signed 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the signed + * content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + + * (Rs1.W[x].B[3] s* Rs2.W[x].B[3]) + (Rs1.W[x].B[2] s* Rs2.W[x].B[2]) + + * (Rs1.W[x].B[1] s* Rs2.W[x].B[1]) + (Rs1.W[x].B[0] s* Rs2.W[x].B[0]); + * Rd.W[x] = res[x]; + * for RV32: x=0, + * for RV64: x=1,0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMAQA(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.109. SMAQA ===== */ + +/* ===== Inline Function Start for 3.110. SMAQA.SU ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_8B_MULT_32B_ADD + * \brief SMAQA.SU (Signed and Unsigned Multiply Four Bytes with 32-bit Adds) + * \details + * **Type**: Partial-SIMD (Reduction) + * + * **Syntax**:\n + * ~~~ + * SMAQA.SU Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four `signed x unsigned` 8-bit multiplications from 32-bit chunks of two registers; and + * then adds the four 16-bit results and the content of corresponding 32-bit chunks of a third register + * together. + * + * **Description**:\n + * This instruction multiplies the four signed 8-bit elements of 32-bit chunks of Rs1 with the four + * unsigned 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the + * signed content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + + * (Rs1.W[x].B[3] su* Rs2.W[x].B[3]) + (Rs1.W[x].B[2] su* Rs2.W[x].B[2]) + + * (Rs1.W[x].B[1] su* Rs2.W[x].B[1]) + (Rs1.W[x].B[0] su* Rs2.W[x].B[0]); + * Rd.W[x] = res[x]; + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMAQA_SU(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smaqa.su %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.110. SMAQA.SU ===== */ + +/* ===== Inline Function Start for 3.111. SMAX8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief SMAX8 (SIMD 8-bit Signed Maximum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMAX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit signed integer elements in Rs1 with the 8-bit + * signed integer elements in Rs2 and selects the numbers that is greater than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] > Rs2.B[x])? Rs1.B[x] : Rs2.B[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMAX8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smax8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.111. SMAX8 ===== */ + +/* ===== Inline Function Start for 3.112. SMAX16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief SMAX16 (SIMD 16-bit Signed Maximum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMAX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit signed integer elements in Rs1 with the 16-bit + * signed integer elements in Rs2 and selects the numbers that is greater than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] > Rs2.H[x])? Rs1.H[x] : Rs2.H[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMAX16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smax16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.112. SMAX16 ===== */ + +/* ===== Inline Function Start for 3.113.1. SMBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMBB16 (SIMD Signed Multiply Bottom Half & Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMBB16 Rd, Rs1, Rs2 + * SMBT16 Rd, Rs1, Rs2 + * SMTT16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16- + * bit content of the 32-bit elements of another register and write the result to a third register. + * * SMBB16: W[x].bottom*W[x].bottom + * * SMBT16: W[x].bottom *W[x].top + * * SMTT16: W[x].top * W[x].top + * + * **Description**:\n + * For the `SMBB16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMBT16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMTT16` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[0]; // SMBB16 + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[1]; // SMBT16 + * Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[1]; // SMTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMBB16(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.113.1. SMBB16 ===== */ + +/* ===== Inline Function Start for 3.113.2. SMBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMBT16 (SIMD Signed Multiply Bottom Half & Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMBB16 Rd, Rs1, Rs2 + * SMBT16 Rd, Rs1, Rs2 + * SMTT16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16- + * bit content of the 32-bit elements of another register and write the result to a third register. + * * SMBB16: W[x].bottom*W[x].bottom + * * SMBT16: W[x].bottom *W[x].top + * * SMTT16: W[x].top * W[x].top + * + * **Description**:\n + * For the `SMBB16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMBT16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMTT16` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[0]; // SMBB16 + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[1]; // SMBT16 + * Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[1]; // SMTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMBT16(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.113.2. SMBT16 ===== */ + +/* ===== Inline Function Start for 3.113.3. SMTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMTT16 (SIMD Signed Multiply Top Half & Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMBB16 Rd, Rs1, Rs2 + * SMBT16 Rd, Rs1, Rs2 + * SMTT16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16- + * bit content of the 32-bit elements of another register and write the result to a third register. + * * SMBB16: W[x].bottom*W[x].bottom + * * SMBT16: W[x].bottom *W[x].top + * * SMTT16: W[x].top * W[x].top + * + * **Description**:\n + * For the `SMBB16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * For the `SMBT16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMTT16` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[0]; // SMBB16 + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[1]; // SMBT16 + * Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[1]; // SMTT16 + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMTT16(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smtt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.113.3. SMTT16 ===== */ + +/* ===== Inline Function Start for 3.114.1. SMDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMDS (SIMD Signed Multiply Two Halfs and Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMDS Rd, Rs1, Rs2 + * SMDRS Rd, Rs1, Rs2 + * SMXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. + * * SMDS: top*top - bottom*bottom (per 32-bit element) + * * SMDRS: bottom*bottom - top*top (per 32-bit element) + * * SMXDS: top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `SMDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with + * the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result + * of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the + * 32-bit elements of Rs2. + * For the `SMDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction result is written to the corresponding 32-bit element of Rd. The 16-bit contents of + * multiplication are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * * SMDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * * SMDRS: + * Rd.W[x] = (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * * SMXDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMDS(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smds %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.114.1. SMDS ===== */ + +/* ===== Inline Function Start for 3.114.2. SMDRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMDRS (SIMD Signed Multiply Two Halfs and Reverse Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMDS Rd, Rs1, Rs2 + * SMDRS Rd, Rs1, Rs2 + * SMXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. + * * SMDS: top*top - bottom*bottom (per 32-bit element) + * * SMDRS: bottom*bottom - top*top (per 32-bit element) + * * SMXDS: top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `SMDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with + * the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result + * of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the + * 32-bit elements of Rs2. + * For the `SMDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction result is written to the corresponding 32-bit element of Rd. The 16-bit contents of + * multiplication are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * * SMDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * * SMDRS: + * Rd.W[x] = (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * * SMXDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMDRS(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smdrs %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.114.2. SMDRS ===== */ + +/* ===== Inline Function Start for 3.114.3. SMXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_32B_ADDSUB + * \brief SMXDS (SIMD Signed Crossed Multiply Two Halfs and Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMDS Rd, Rs1, Rs2 + * SMDRS Rd, Rs1, Rs2 + * SMXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * perform a subtraction operation between the two 32-bit results. + * * SMDS: top*top - bottom*bottom (per 32-bit element) + * * SMDRS: bottom*bottom - top*top (per 32-bit element) + * * SMXDS: top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * For the `SMDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with + * the bottom 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result + * of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the + * 32-bit elements of Rs2. + * For the `SMDRS` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of + * the 32-bit elements of Rs2. + * For the `SMXDS` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and then subtracts the result from the + * result of multiplying the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit + * content of the 32-bit elements of Rs2. + * The subtraction result is written to the corresponding 32-bit element of Rd. The 16-bit contents of + * multiplication are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * * SMDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[1]) - (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * * SMDRS: + * Rd.W[x] = (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); + * * SMXDS: + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMXDS(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smxds %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.114.3. SMXDS ===== */ + +/* ===== Inline Function Start for 3.115. SMIN8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief SMIN8 (SIMD 8-bit Signed Minimum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMIN8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer elements finding minimum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit signed integer elements in Rs1 with the 8-bit + * signed integer elements in Rs2 and selects the numbers that is less than the other one. The selected + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] < Rs2.B[x])? Rs1.B[x] : Rs2.B[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMIN8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smin8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.115. SMIN8 ===== */ + +/* ===== Inline Function Start for 3.116. SMIN16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief SMIN16 (SIMD 16-bit Signed Minimum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMIN16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements finding minimum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit signed integer elements in Rs1 with the 16-bit + * signed integer elements in Rs2 and selects the numbers that is less than the other one. The selected + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] < Rs2.H[x])? Rs1.H[x] : Rs2.H[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMIN16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smin16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.116. SMIN16 ===== */ + +/* ===== Inline Function Start for 3.117.1. SMMUL ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief SMMUL (SIMD MSW Signed Multiply Word) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMUL Rd, Rs1, Rs2 + * SMMUL.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed integer elements of two registers and write the most significant + * 32-bit results to the corresponding 32-bit elements of a register. The `.u` form performs an + * additional rounding up operation on the multiplication results before taking the most significant + * 32-bit part of the results. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2 and writes the + * most significant 32-bit multiplication results to the corresponding 32-bit elements of Rd. The 32-bit + * elements of Rs1 and Rs2 are treated as signed integers. The `.u` form of the instruction rounds up + * the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results. + * * For `smmul/RV32` instruction, it is an alias to `mulh/RV32` instruction. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][63:32]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMUL(long a, long b) +{ + long result; + __ASM volatile("smmul %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.117.1. SMMUL ===== */ + +/* ===== Inline Function Start for 3.117.2. SMMUL.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC + * \brief SMMUL.u (SIMD MSW Signed Multiply Word with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMUL Rd, Rs1, Rs2 + * SMMUL.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed integer elements of two registers and write the most significant + * 32-bit results to the corresponding 32-bit elements of a register. The `.u` form performs an + * additional rounding up operation on the multiplication results before taking the most significant + * 32-bit part of the results. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2 and writes the + * most significant 32-bit multiplication results to the corresponding 32-bit elements of Rd. The 32-bit + * elements of Rs1 and Rs2 are treated as signed integers. The `.u` form of the instruction rounds up + * the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results. + * * For `smmul/RV32` instruction, it is an alias to `mulh/RV32` instruction. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] * Rs2.W[x]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][63:31] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][63:32]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMUL_U(long a, long b) +{ + long result; + __ASM volatile("smmul.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.117.2. SMMUL.u ===== */ + +/* ===== Inline Function Start for 3.118.1. SMMWB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief SMMWB (SIMD MSW Signed Multiply Word and Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMWB Rd, Rs1, Rs2 + * SMMWB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, and write the most significant 32-bit results to + * the corresponding 32-bit elements of a register. The `.u` form rounds up the results from the most + * significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed bottom 16-bit content + * of the corresponding 32-bit elements of Rs2 and writes the most significant 32-bit multiplication + * results to the corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the + * most significant 32-bit of the 48-bit multiplication results by adding a 1 to bit 15 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][47:16]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMWB(long a, unsigned long b) +{ + long result; + __ASM volatile("smmwb %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.118.1. SMMWB ===== */ + +/* ===== Inline Function Start for 3.118.2. SMMWB.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief SMMWB.u (SIMD MSW Signed Multiply Word and Bottom Half with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMWB Rd, Rs1, Rs2 + * SMMWB.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the bottom 16-bit of the + * corresponding 32-bit elements of another register, and write the most significant 32-bit results to + * the corresponding 32-bit elements of a register. The `.u` form rounds up the results from the most + * significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed bottom 16-bit content + * of the corresponding 32-bit elements of Rs2 and writes the most significant 32-bit multiplication + * results to the corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the + * most significant 32-bit of the 48-bit multiplication results by adding a 1 to bit 15 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[0]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][47:16]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMWB_U(long a, unsigned long b) +{ + long result; + __ASM volatile("smmwb.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.118.2. SMMWB.u ===== */ + +/* ===== Inline Function Start for 3.119.1. SMMWT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief SMMWT (SIMD MSW Signed Multiply Word and Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMWT Rd, Rs1, Rs2 + * SMMWT.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, and write the most significant 32-bit results to + * the corresponding 32-bit elements of a register. The `.u` form rounds up the results from the most + * significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the top signed 16-bit content of + * the corresponding 32-bit elements of Rs2 and writes the most significant 32-bit multiplication + * results to the corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the + * most significant 32-bit of the 48-bit multiplication results by adding a 1 to bit 15 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][47:16]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMWT(long a, unsigned long b) +{ + long result; + __ASM volatile("smmwt %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.119.1. SMMWT ===== */ + +/* ===== Inline Function Start for 3.119.2. SMMWT.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X16_MAC + * \brief SMMWT.u (SIMD MSW Signed Multiply Word and Top Half with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMMWT Rd, Rs1, Rs2 + * SMMWT.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit integer elements of one register and the top 16-bit of the + * corresponding 32-bit elements of another register, and write the most significant 32-bit results to + * the corresponding 32-bit elements of a register. The `.u` form rounds up the results from the most + * significant discarded bit. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the top signed 16-bit content of + * the corresponding 32-bit elements of Rs2 and writes the most significant 32-bit multiplication + * results to the corresponding 32-bit elements of Rd. The `.u` form of the instruction rounds up the + * most significant 32-bit of the 48-bit multiplication results by adding a 1 to bit 15 of the results. + * + * **Operations**:\n + * ~~~ + * Mres[x][47:0] = Rs1.W[x] * Rs2.W[x].H[1]; + * if (`.u` form) { + * Round[x][32:0] = Mres[x][47:15] + 1; + * Rd.W[x] = Round[x][32:1]; + * } else { + * Rd.W[x] = Mres[x][47:16]; + * } + * for RV32: x=0 + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMMWT_U(long a, unsigned long b) +{ + long result; + __ASM volatile("smmwt.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.119.2. SMMWT.u ===== */ + +/* ===== Inline Function Start for 3.120.1. SMSLDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMSLDA (Signed Multiply Two Halfs & Add & Subtract 64-bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMSLDA Rd, Rs1, Rs2 + * SMSLXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * subtracts the two 32-bit results from the 64-bit value of an even/odd pair of registers (RV32) or a + * register (RV64). The subtraction result is written back to the register-pair. + * * SMSLDA: rd pair - top*top - bottom*bottom (all 32-bit elements) + * * SMSLXDA: rd pair - top*bottom - bottom*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMSLDA` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content Rs2 and multiplies the top 16-bit content of Rs1 with the top 16-bit content of Rs2. + * For the `SMSLXDA` instruction, it multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and multiplies the bottom 16-bit content of Rs1 with the top 16-bit content of Rs2. + * The two multiplication results are subtracted from the 64-bit value of an even/odd pair of registers + * specified by Rd(4,1). The 64-bit subtraction result is written back to the register-pair. The 16-bit + * values of Rs1 and Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * For the `SMSLDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMSLXDA` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the bottom 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * The four multiplication results are subtracted from the 64-bit value of Rd. The 64-bit subtraction + * result is written back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated + * as signed integers. + * + * **Operations**:\n + * ~~~ + * * RV32: + * // SMSLDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[0]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[1]); + * // SMSLXDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[1]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[0]); + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] - SE64(Mres0[31:0]) - SE64(Mres1[31:0]); + * * RV64: + * // SMSLDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMSLXDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[0]); + * Rd = Rd - SE64(Mres0[0][31:0]) - SE64(Mres1[0][31:0]) - SE64(Mres0[1][31:0]) - + * SE64(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMSLDA(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smslda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.120.1. SMSLDA ===== */ + +/* ===== Inline Function Start for 3.120.2. SMSLXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIGNED_16B_MULT_64B_ADDSUB + * \brief SMSLXDA (Signed Crossed Multiply Two Halfs & Add & Subtract 64- bit) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMSLDA Rd, Rs1, Rs2 + * SMSLXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then + * subtracts the two 32-bit results from the 64-bit value of an even/odd pair of registers (RV32) or a + * register (RV64). The subtraction result is written back to the register-pair. + * * SMSLDA: rd pair - top*top - bottom*bottom (all 32-bit elements) + * * SMSLXDA: rd pair - top*bottom - bottom*top (all 32-bit elements) + * + * **RV32 Description**:\n + * For the `SMSLDA` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content Rs2 and multiplies the top 16-bit content of Rs1 with the top 16-bit content of Rs2. + * For the `SMSLXDA` instruction, it multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and multiplies the bottom 16-bit content of Rs1 with the top 16-bit content of Rs2. + * The two multiplication results are subtracted from the 64-bit value of an even/odd pair of registers + * specified by Rd(4,1). The 64-bit subtraction result is written back to the register-pair. The 16-bit + * values of Rs1 and Rs2, and the 64-bit value of the register-pair are treated as signed integers. + * Rd(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * For the `SMSLDA` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * For the `SMSLXDA` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with + * the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the bottom 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * The four multiplication results are subtracted from the 64-bit value of Rd. The 64-bit subtraction + * result is written back to Rd. The 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated + * as signed integers. + * + * **Operations**:\n + * ~~~ + * * RV32: + * // SMSLDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[0]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[1]); + * // SMSLXDA + * Mres0[31:0] = (Rs1.H[0] * Rs2.H[1]); + * Mres1[31:0] = (Rs1.H[1] * Rs2.H[0]); + * Idx0 = CONCAT(Rd(4,1),1'b0); Idx1 = CONCAT(Rd(4,1),1'b1); + * R[Idx1].R[Idx0] = R[Idx1].R[Idx0] - SE64(Mres0[31:0]) - SE64(Mres1[31:0]); + * * RV64: + * // SMSLDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * // SMSLXDA + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[0]); + * Rd = Rd - SE64(Mres0[0][31:0]) - SE64(Mres1[0][31:0]) - SE64(Mres0[1][31:0]) - + * SE64(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMSLXDA(long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("smslxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.120.2. SMSLXDA ===== */ + +/* ===== Inline Function Start for 3.121. SMSR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief SMSR64 (Signed Multiply and Subtract from 64- Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SMSR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit signed elements in two registers and subtract the 64-bit multiplication + * results from the 64-bit signed data of a pair of registers (RV32) or a register (RV64). The result is + * written back to the pair of registers (RV32) or a register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit signed data of Rs1 with that of Rs2. It + * subtracts the 64-bit multiplication result from the 64-bit signed data of an even/odd pair of registers + * specified by Rd(4,1). The subtraction result is written back to the even/odd pair of registers + * specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit signed elements of Rs1 with that of Rs2. It + * subtracts the 64-bit multiplication results from the 64-bit signed data of Rd. The subtraction result is + * written back to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H].R[t_L] = R[t_H].R[t_L] - (Rs1 * Rs2); + * * RV64: + * Rd = Rd - (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a long type of value stored in a + * \param [in] b long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_SMSR64(long long t, long a, long b) +{ + __ASM volatile("smsr64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.121. SMSR64 ===== */ + +/* ===== Inline Function Start for 3.122.1. SMUL8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MULTIPLY + * \brief SMUL8 (SIMD Signed 8-bit Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMUL8 Rd, Rs1, Rs2 + * SMULX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do signed 8-bit multiplications and generate four 16-bit results simultaneously. + * + * **RV32 Description**:\n + * For the `SMUL8` instruction, multiply the 8-bit data elements of Rs1 with the + * corresponding 8-bit data elements of Rs2. + * For the `SMULX8` instruction, multiply the first and second 8-bit data elements of Rs1 with the + * second and first 8-bit data elements of Rs2. At the same time, multiply the third and fourth 8-bit data + * elements of Rs1 with the fourth and third 8-bit data elements of Rs2. + * The four 16-bit results are then written into an even/odd pair of registers specified by Rd(4,1). + * Rd(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the two 16-bit results calculated from the top part of + * Rs1 and the even `2d` register of the pair contains the two 16-bit results calculated from the bottom + * part of Rs1. + * + * **RV64 Description**:\n + * For the `SMUL8` instruction, multiply the 8-bit data elements of Rs1 with the + * corresponding 8-bit data elements of Rs2. + * For the `SMULX8` instruction, multiply the first and second 8-bit data elements of Rs1 with the + * second and first 8-bit data elements of Rs2. At the same time, multiply the third and fourth 8-bit data + * elements of Rs1 with the fourth and third 8-bit data elements of Rs2. + * The four 16-bit results are then written into Rd. The Rd.W[1] contains the two 16-bit results + * calculated from the top part of Rs1 and the Rd.W[0] contains the two 16-bit results calculated from + * the bottom part of Rs1. + * + * **Operations**:\n + * ~~~ + * * RV32: + * if (is `SMUL8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x+1]; // top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x]; // bottom + * } else if (is `SMULX8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x]; // Rs1 top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x+1]; // Rs1 bottom + * } + * rest[x/2] = op1t[x/2] s* op2t[x/2]; + * resb[x/2] = op1b[x/2] s* op2b[x/2]; + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H].H[1] = rest[1]; R[t_H].H[0] = resb[1]; + * R[t_L].H[1] = rest[0]; R[t_L].H[0] = resb[0]; + * x = 0 and 2 + * * RV64: + * if (is `SMUL8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x+1]; // top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x]; // bottom + * } else if (is `SMULX8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x]; // Rs1 top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x+1]; // Rs1 bottom + * } + * rest[x/2] = op1t[x/2] s* op2t[x/2]; + * resb[x/2] = op1b[x/2] s* op2b[x/2]; + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * Rd.W[1].H[1] = rest[1]; Rd.W[1].H[0] = resb[1]; + * Rd.W[0].H[1] = rest[0]; Rd.W[0].H[0] = resb[0]; + * x = 0 and 2 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_SMUL8(unsigned int a, unsigned int b) +{ + unsigned long long result; + __ASM volatile("smul8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.122.1. SMUL8 ===== */ + +/* ===== Inline Function Start for 3.122.2. SMULX8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MULTIPLY + * \brief SMULX8 (SIMD Signed Crossed 8-bit Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMUL8 Rd, Rs1, Rs2 + * SMULX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do signed 8-bit multiplications and generate four 16-bit results simultaneously. + * + * **RV32 Description**:\n + * For the `SMUL8` instruction, multiply the 8-bit data elements of Rs1 with the + * corresponding 8-bit data elements of Rs2. + * For the `SMULX8` instruction, multiply the first and second 8-bit data elements of Rs1 with the + * second and first 8-bit data elements of Rs2. At the same time, multiply the third and fourth 8-bit data + * elements of Rs1 with the fourth and third 8-bit data elements of Rs2. + * The four 16-bit results are then written into an even/odd pair of registers specified by Rd(4,1). + * Rd(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the two 16-bit results calculated from the top part of + * Rs1 and the even `2d` register of the pair contains the two 16-bit results calculated from the bottom + * part of Rs1. + * + * **RV64 Description**:\n + * For the `SMUL8` instruction, multiply the 8-bit data elements of Rs1 with the + * corresponding 8-bit data elements of Rs2. + * For the `SMULX8` instruction, multiply the first and second 8-bit data elements of Rs1 with the + * second and first 8-bit data elements of Rs2. At the same time, multiply the third and fourth 8-bit data + * elements of Rs1 with the fourth and third 8-bit data elements of Rs2. + * The four 16-bit results are then written into Rd. The Rd.W[1] contains the two 16-bit results + * calculated from the top part of Rs1 and the Rd.W[0] contains the two 16-bit results calculated from + * the bottom part of Rs1. + * + * **Operations**:\n + * ~~~ + * * RV32: + * if (is `SMUL8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x+1]; // top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x]; // bottom + * } else if (is `SMULX8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x]; // Rs1 top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x+1]; // Rs1 bottom + * } + * rest[x/2] = op1t[x/2] s* op2t[x/2]; + * resb[x/2] = op1b[x/2] s* op2b[x/2]; + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H].H[1] = rest[1]; R[t_H].H[0] = resb[1]; + * R[t_L].H[1] = rest[0]; R[t_L].H[0] = resb[0]; + * x = 0 and 2 + * * RV64: + * if (is `SMUL8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x+1]; // top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x]; // bottom + * } else if (is `SMULX8`) { + * op1t[x/2] = Rs1.B[x+1]; op2t[x/2] = Rs2.B[x]; // Rs1 top + * op1b[x/2] = Rs1.B[x]; op2b[x/2] = Rs2.B[x+1]; // Rs1 bottom + * } + * rest[x/2] = op1t[x/2] s* op2t[x/2]; + * resb[x/2] = op1b[x/2] s* op2b[x/2]; + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * Rd.W[1].H[1] = rest[1]; Rd.W[1].H[0] = resb[1]; + * Rd.W[0].H[1] = rest[0]; Rd.W[0].H[0] = resb[0]; + * x = 0 and 2 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_SMULX8(unsigned int a, unsigned int b) +{ + unsigned long long result; + __ASM volatile("smulx8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.122.2. SMULX8 ===== */ + +/* ===== Inline Function Start for 3.123.1. SMUL16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MULTIPLY + * \brief SMUL16 (SIMD Signed 16-bit Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMUL16 Rd, Rs1, Rs2 + * SMULX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do signed 16-bit multiplications and generate two 32-bit results simultaneously. + * + * **RV32 Description**:\n + * For the `SMUL16` instruction, multiply the top 16-bit Q15 content of Rs1 with + * the top 16-bit Q15 content of Rs2. At the same time, multiply the bottom 16-bit Q15 content of Rs1 + * with the bottom 16-bit Q15 content of Rs2. + * For the `SMULX16` instruction, multiply the top 16-bit Q15 content of Rs1 with the bottom 16-bit + * Q15 content of Rs2. At the same time, multiply the bottom 16-bit Q15 content of Rs1 with the top 16- + * bit Q15 content of Rs2. + * The two Q30 results are then written into an even/odd pair of registers specified by Rd(4,1). Rd(4,1), + * i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair includes + * register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the 32-bit result calculated from the top part of Rs1 and + * the even `2d` register of the pair contains the 32-bit result calculated from the bottom part of Rs1. + * + * **RV64 Description**:\n + * For the `SMUL16` instruction, multiply the top 16-bit Q15 content of the lower + * 32-bit word in Rs1 with the top 16-bit Q15 content of the lower 32-bit word in Rs2. At the same time, + * multiply the bottom 16-bit Q15 content of the lower 32-bit word in Rs1 with the bottom 16-bit Q15 + * content of the lower 32-bit word in Rs2. + * For the `SMULX16` instruction, multiply the top 16-bit Q15 content of the lower 32-bit word in Rs1 + * with the bottom 16-bit Q15 content of the lower 32-bit word in Rs2. At the same time, multiply the + * bottom 16-bit Q15 content of the lower 32-bit word in Rs1 with the top 16-bit Q15 content of the + * lower 32-bit word in Rs2. + * The two 32-bit Q30 results are then written into Rd. The result calculated from the top 16-bit of the + * lower 32-bit word in Rs1 is written to Rd.W[1]. And the result calculated from the bottom 16-bit of + * the lower 32-bit word in Rs1 is written to Rd.W[0] + * + * **Operations**:\n + * ~~~ + * * RV32: + * if (is `SMUL16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[1]; // top + * op1b = Rs1.H[0]; op2b = Rs2.H[0]; // bottom + * } else if (is `SMULX16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[0]; // Rs1 top + * op1b = Rs1.H[0]; op2b = Rs2.H[1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = aop s* bop; + * } + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H] = rest; + * R[t_L] = resb; + * * RV64: + * if (is `SMUL16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[1]; // top + * op1b = Rs1.H[0]; op2b = Rs2.H[0]; // bottom + * } else if (is `SMULX16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[0]; // Rs1 top + * op1b = Rs1.H[0]; op2b = Rs2.H[1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = aop s* bop; + * } + * Rd.W[1] = rest; + * Rd.W[0] = resb; + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_SMUL16(unsigned int a, unsigned int b) +{ + unsigned long long result; + __ASM volatile("smul16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.123.1. SMUL16 ===== */ + +/* ===== Inline Function Start for 3.123.2. SMULX16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MULTIPLY + * \brief SMULX16 (SIMD Signed Crossed 16-bit Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SMUL16 Rd, Rs1, Rs2 + * SMULX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do signed 16-bit multiplications and generate two 32-bit results simultaneously. + * + * **RV32 Description**:\n + * For the `SMUL16` instruction, multiply the top 16-bit Q15 content of Rs1 with + * the top 16-bit Q15 content of Rs2. At the same time, multiply the bottom 16-bit Q15 content of Rs1 + * with the bottom 16-bit Q15 content of Rs2. + * For the `SMULX16` instruction, multiply the top 16-bit Q15 content of Rs1 with the bottom 16-bit + * Q15 content of Rs2. At the same time, multiply the bottom 16-bit Q15 content of Rs1 with the top 16- + * bit Q15 content of Rs2. + * The two Q30 results are then written into an even/odd pair of registers specified by Rd(4,1). Rd(4,1), + * i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair includes + * register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the 32-bit result calculated from the top part of Rs1 and + * the even `2d` register of the pair contains the 32-bit result calculated from the bottom part of Rs1. + * + * **RV64 Description**:\n + * For the `SMUL16` instruction, multiply the top 16-bit Q15 content of the lower + * 32-bit word in Rs1 with the top 16-bit Q15 content of the lower 32-bit word in Rs2. At the same time, + * multiply the bottom 16-bit Q15 content of the lower 32-bit word in Rs1 with the bottom 16-bit Q15 + * content of the lower 32-bit word in Rs2. + * For the `SMULX16` instruction, multiply the top 16-bit Q15 content of the lower 32-bit word in Rs1 + * with the bottom 16-bit Q15 content of the lower 32-bit word in Rs2. At the same time, multiply the + * bottom 16-bit Q15 content of the lower 32-bit word in Rs1 with the top 16-bit Q15 content of the + * lower 32-bit word in Rs2. + * The two 32-bit Q30 results are then written into Rd. The result calculated from the top 16-bit of the + * lower 32-bit word in Rs1 is written to Rd.W[1]. And the result calculated from the bottom 16-bit of + * the lower 32-bit word in Rs1 is written to Rd.W[0] + * + * **Operations**:\n + * ~~~ + * * RV32: + * if (is `SMUL16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[1]; // top + * op1b = Rs1.H[0]; op2b = Rs2.H[0]; // bottom + * } else if (is `SMULX16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[0]; // Rs1 top + * op1b = Rs1.H[0]; op2b = Rs2.H[1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = aop s* bop; + * } + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H] = rest; + * R[t_L] = resb; + * * RV64: + * if (is `SMUL16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[1]; // top + * op1b = Rs1.H[0]; op2b = Rs2.H[0]; // bottom + * } else if (is `SMULX16`) { + * op1t = Rs1.H[1]; op2t = Rs2.H[0]; // Rs1 top + * op1b = Rs1.H[0]; op2b = Rs2.H[1]; // Rs1 bottom + * } + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = aop s* bop; + * } + * Rd.W[1] = rest; + * Rd.W[0] = resb; + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_SMULX16(unsigned int a, unsigned int b) +{ + unsigned long long result; + __ASM volatile("smulx16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.123.2. SMULX16 ===== */ + +/* ===== Inline Function Start for 3.124. SRA.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief SRA.u (Rounding Shift Right Arithmetic) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SRA.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform an arithmetic right shift operation with rounding. The shift amount is a variable + * from a GPR. + * + * **Description**:\n + * This instruction right-shifts the content of Rs1 arithmetically. The shifted out bits are + * filled with the sign-bit and the shift amount is specified by the low-order 5-bits (RV32) or 6-bits + * (RV64) of the Rs2 register. For the rounding operation, a value of 1 is added to the most significant + * discarded bit of the data to calculate the final result. And the result is written to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * sa = Rs2[4:0]; + * if (sa > 0) { + * res[31:-1] = SE33(Rs1[31:(sa-1)]) + 1; + * Rd = res[31:0]; + * } else { + * Rd = Rs1; + * } + * * RV64: + * sa = Rs2[5:0]; + * if (sa > 0) { + * res[63:-1] = SE65(Rs1[63:(sa-1)]) + 1; + * Rd = res[63:0]; + * } else { + * Rd = Rs1; + * } + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SRA_U(long a, unsigned int b) +{ + long result; + __ASM volatile("sra.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.124. SRA.u ===== */ + +/* ===== Inline Function Start for 3.125. SRAI.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief SRAI.u (Rounding Shift Right Arithmetic Immediate) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SRAI.u Rd, Rs1, imm6u[4:0] (RV32) + * SRAI.u Rd, Rs1, imm6u[5:0] (RV64) + * ~~~ + * + * **Purpose**:\n + * Perform an arithmetic right shift operation with rounding. The shift amount is an + * immediate value. + * + * **Description**:\n + * This instruction right-shifts the content of Rs1 arithmetically. The shifted out bits are + * filled with the sign-bit and the shift amount is specified by the imm6u[4:0] (RV32) or imm6u[5:0] + * (RV64) constant . For the rounding operation, a value of 1 is added to the most significant discarded + * bit of the data to calculate the final result. And the result is written to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * sa = imm6u[4:0]; + * if (sa > 0) { + * res[31:-1] = SE33(Rs1[31:(sa-1)]) + 1; + * Rd = res[31:0]; + * } else { + * Rd = Rs1; + * } + * * RV64: + * sa = imm6u[5:0]; + * if (sa > 0) { + * res[63:-1] = SE65(Rs1[63:(sa-1)]) + 1; + * Rd = res[63:0]; + * } else { + * Rd = Rs1; + * } + * ~~~ + * + * \param [in] a long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +#define __RV_SRAI_U(a, b) \ + ({ \ + long result; \ + long __a = (long)(a); \ + __ASM volatile("srai.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.125. SRAI.u ===== */ + +/* ===== Inline Function Start for 3.126.1. SRA8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRA8 (SIMD 8-bit Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRA8 Rd, Rs1, Rs2 + * SRA8.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 3-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 8-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA8.u + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { // SRA8 + * Rd.B[x] = SE8(Rd.B[x][7:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA8(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sra8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.126.1. SRA8 ===== */ + +/* ===== Inline Function Start for 3.126.2. SRA8.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRA8.u (SIMD 8-bit Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRA8 Rd, Rs1, Rs2 + * SRA8.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 3-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 8-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA8.u + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { // SRA8 + * Rd.B[x] = SE8(Rd.B[x][7:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA8_U(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sra8.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.126.2. SRA8.u ===== */ + +/* ===== Inline Function Start for 3.127.1. SRAI8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRAI8 (SIMD 8-bit Shift Right Arithmetic Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRAI8 Rd, Rs1, imm3u + * SRAI8.u Rd, Rs1, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit element arithmetic right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the imm3u + * constant. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 8-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA8.u + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { // SRA8 + * Rd.B[x] = SE8(Rd.B[x][7:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.127.1. SRAI8 ===== */ + +/* ===== Inline Function Start for 3.127.2. SRAI8.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRAI8.u (SIMD 8-bit Rounding Shift Right Arithmetic Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRAI8 Rd, Rs1, imm3u + * SRAI8.u Rd, Rs1, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit element arithmetic right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the imm3u + * constant. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 8-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA8.u + * res[7:-1] = SE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[7:0]; + * } else { // SRA8 + * Rd.B[x] = SE8(Rd.B[x][7:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI8_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai8.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.127.2. SRAI8.u ===== */ + +/* ===== Inline Function Start for 3.128.1. SRA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRA16 (SIMD 16-bit Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRA16 Rd, Rs1, Rs2 + * SRA16.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 4-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 16-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa != 0) { + * if (`.u` form) { // SRA16.u + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { // SRA16 + * Rd.H[x] = SE16(Rs1.H[x][15:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("sra16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.128.1. SRA16 ===== */ + +/* ===== Inline Function Start for 3.128.2. SRA16.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRA16.u (SIMD 16-bit Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRA16 Rd, Rs1, Rs2 + * SRA16.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 4-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 16-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa != 0) { + * if (`.u` form) { // SRA16.u + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { // SRA16 + * Rd.H[x] = SE16(Rs1.H[x][15:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA16_U(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("sra16.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.128.2. SRA16.u ===== */ + +/* ===== Inline Function Start for 3.129.1. SRAI16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRAI16 (SIMD 16-bit Shift Right Arithmetic Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRAI16 Rd, Rs1, imm4u + * SRAI16.u Rd, Rs1, imm4u + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements arithmetic right shift operations simultaneously. The shift amount is + * an immediate value. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the 16-bit data elements. The shift amount is specified by the + * imm4u constant. For the rounding operation of the `.u` form, a value of 1 is added to the most + * significant discarded bit of each 16-bit data to calculate the final results. And the results are written + * to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm4u[3:0]; + * if (sa > 0) { + * if (`.u` form) { // SRAI16.u + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { // SRAI16 + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.129.1. SRAI16 ===== */ + +/* ===== Inline Function Start for 3.129.2. SRAI16.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRAI16.u (SIMD 16-bit Rounding Shift Right Arithmetic Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRAI16 Rd, Rs1, imm4u + * SRAI16.u Rd, Rs1, imm4u + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements arithmetic right shift operations simultaneously. The shift amount is + * an immediate value. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the 16-bit data elements. The shift amount is specified by the + * imm4u constant. For the rounding operation of the `.u` form, a value of 1 is added to the most + * significant discarded bit of each 16-bit data to calculate the final results. And the results are written + * to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm4u[3:0]; + * if (sa > 0) { + * if (`.u` form) { // SRAI16.u + * res[15:-1] = SE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[15:0]; + * } else { // SRAI16 + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI16_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai16.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.129.2. SRAI16.u ===== */ + +/* ===== Inline Function Start for 3.130.1. SRL8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRL8 (SIMD 8-bit Shift Right Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRL8 Rt, Ra, Rb + * SRL8.u Rt, Ra, Rb + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits are + * filled with zero. The shift amount is specified by the low-order 3-bits of the value in the Rs2 register. + * For the rounding operation of the `.u` form, a value of 1 is added to the most significant discarded + * bit of each 8-bit data element to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRL8.u + * res[8:0] = ZE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[8:1]; + * } else { // SRL8 + * Rd.B[x] = ZE8(Rs1.B[x][7:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL8(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.130.1. SRL8 ===== */ + +/* ===== Inline Function Start for 3.130.2. SRL8.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRL8.u (SIMD 8-bit Rounding Shift Right Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRL8 Rt, Ra, Rb + * SRL8.u Rt, Ra, Rb + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits are + * filled with zero. The shift amount is specified by the low-order 3-bits of the value in the Rs2 register. + * For the rounding operation of the `.u` form, a value of 1 is added to the most significant discarded + * bit of each 8-bit data element to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRL8.u + * res[8:0] = ZE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[8:1]; + * } else { // SRL8 + * Rd.B[x] = ZE8(Rs1.B[x][7:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL8_U(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl8.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.130.2. SRL8.u ===== */ + +/* ===== Inline Function Start for 3.131.1. SRLI8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRLI8 (SIMD 8-bit Shift Right Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRLI8 Rt, Ra, imm3u + * SRLI8.u Rt, Ra, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits are + * filled with zero. The shift amount is specified by the imm3u constant. For the rounding operation of + * the `.u` form, a value of 1 is added to the most significant discarded bit of each 8-bit data element to + * calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRLI8.u + * res[8:0] = ZE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[8:1]; + * } else { // SRLI8 + * Rd.B[x] = ZE8(Rs1.B[x][7:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.131.1. SRLI8 ===== */ + +/* ===== Inline Function Start for 3.131.2. SRLI8.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_SHIFT + * \brief SRLI8.u (SIMD 8-bit Rounding Shift Right Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRLI8 Rt, Ra, imm3u + * SRLI8.u Rt, Ra, imm3u + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 8-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits are + * filled with zero. The shift amount is specified by the imm3u constant. For the rounding operation of + * the `.u` form, a value of 1 is added to the most significant discarded bit of each 8-bit data element to + * calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm3u[2:0]; + * if (sa > 0) { + * if (`.u` form) { // SRLI8.u + * res[8:0] = ZE9(Rs1.B[x][7:sa-1]) + 1; + * Rd.B[x] = res[8:1]; + * } else { // SRLI8 + * Rd.B[x] = ZE8(Rs1.B[x][7:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI8_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli8.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.131.2. SRLI8.u ===== */ + +/* ===== Inline Function Start for 3.132.1. SRL16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRL16 (SIMD 16-bit Shift Right Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRL16 Rt, Ra, Rb + * SRL16.u Rt, Ra, Rb + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical right shift operations simultaneously. The shift amount is a variable from a GPR. The `.u` form performs additional rounding upoperations on the shifted results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the low-order 4-bits of the value in the Rs2 + * register. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 16-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa > 0) { + * if (`.u` form) { // SRL16.u + * res[16:0] = ZE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[16:1]; + * } else { // SRL16 + * Rd.H[x] = ZE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL16(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.132.1. SRL16 ===== */ + +/* ===== Inline Function Start for 3.132.2. SRL16.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRL16.u (SIMD 16-bit Rounding Shift Right Logical) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRL16 Rt, Ra, Rb + * SRL16.u Rt, Ra, Rb + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical right shift operations simultaneously. The shift amount is a variable from a GPR. The `.u` form performs additional rounding upoperations on the shifted results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the low-order 4-bits of the value in the Rs2 + * register. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 16-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa > 0) { + * if (`.u` form) { // SRL16.u + * res[16:0] = ZE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[16:1]; + * } else { // SRL16 + * Rd.H[x] = ZE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL16_U(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl16.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.132.2. SRL16.u ===== */ + +/* ===== Inline Function Start for 3.133.1. SRLI16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRLI16 (SIMD 16-bit Shift Right Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRLI16 Rt, Ra, imm4u + * SRLI16.u Rt, Ra, imm4u + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the imm4u constant. For the rounding + * operation of the `.u` form, a value of 1 is added to the most significant discarded bit of each 16-bit + * data element to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm4u; + * if (sa > 0) { + * if (`.u` form) { // SRLI16.u + * res[16:0] = ZE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[16:1]; + * } else { // SRLI16 + * Rd.H[x] = ZE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.133.1. SRLI16 ===== */ + +/* ===== Inline Function Start for 3.133.2. SRLI16.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_SHIFT + * \brief SRLI16.u (SIMD 16-bit Rounding Shift Right Logical Immediate) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SRLI16 Rt, Ra, imm4u + * SRLI16.u Rt, Ra, imm4u + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the imm4u constant. For the rounding + * operation of the `.u` form, a value of 1 is added to the most significant discarded bit of each 16-bit + * data element to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm4u; + * if (sa > 0) { + * if (`.u` form) { // SRLI16.u + * res[16:0] = ZE17(Rs1.H[x][15:sa-1]) + 1; + * Rd.H[x] = res[16:1]; + * } else { // SRLI16 + * Rd.H[x] = ZE16(Rs1.H[x][15:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI16_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli16.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.133.2. SRLI16.u ===== */ + +/* ===== Inline Function Start for 3.134. STAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief STAS16 (SIMD 16-bit Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * STAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element addition and 16-bit integer element subtraction in a 32-bit + * chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit integer element in [31:16] of 32-bit chunks in Rs1 with + * the 16-bit integer element in [31:16] of 32-bit chunks in Rs2, and writes the result to [31:16] of 32-bit + * chunks in Rd; at the same time, it subtracts the 16-bit integer element in [15:0] of 32-bit chunks in + * Rs2 from the 16-bit integer element in [15:0] of 32-bit chunks, and writes the result to [15:0] of 32- + * bit chunks in Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = Rs1.W[x][31:16] + Rs2.W[x][31:16]; + * Rd.W[x][15:0] = Rs1.W[x][15:0] - Rs2.W[x][15:0]; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_STAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("stas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.134. STAS16 ===== */ + +/* ===== Inline Function Start for 3.135. STSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief STSA16 (SIMD 16-bit Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * STSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element subtraction and 16-bit integer element addition in a 32-bit + * chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit integer element in [31:16] of 32-bit chunks in Rs2 + * from the 16-bit integer element in [31:16] of 32-bit chunks in Rs1, and writes the result to [31:16] of + * 32-bit chunks in Rd; at the same time, it adds the 16-bit integer element in [15:0] of 32-bit chunks in + * Rs2 with the 16-bit integer element in [15:0] of 32-bit chunks in Rs1, and writes the result to [15:0] of + * 32-bit chunks in Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = Rs1.W[x][31:16] - Rs2.W[x][31:16]; + * Rd.W[x][15:0] = Rs1.W[x][15:0] + Rs2.W[x][15:0]; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_STSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("stsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.135. STSA16 ===== */ + +/* ===== Inline Function Start for 3.136. SUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief SUB8 (SIMD 8-bit Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SUB8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit integer element subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 8-bit integer elements in Rs2 from the 8-bit integer + * elements in Rs1, and then writes the result to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned subtraction. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = Rs1.B[x] - Rs2.B[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUB8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("sub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.136. SUB8 ===== */ + +/* ===== Inline Function Start for 3.137. SUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief SUB16 (SIMD 16-bit Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * SUB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 16-bit integer elements in Rs2 from the 16-bit integer + * elements in Rs1, and then writes the result to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned subtraction. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = Rs1.H[x] - Rs2.H[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("sub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.137. SUB16 ===== */ + +/* ===== Inline Function Start for 3.138. SUB64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief SUB64 (64-bit Subtraction) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * SUB64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a 64-bit signed or unsigned integer subtraction. + * + * **RV32 Description**:\n + * This instruction subtracts the 64-bit integer of an even/odd pair of registers + * specified by Rs2(4,1) from the 64-bit integer of an even/odd pair of registers specified by Rs1(4,1), + * and then writes the 64-bit result to an even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * This instruction subtracts the 64-bit integer of Rs2 from the 64-bit integer of Rs1, + * and then writes the 64-bit result to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned subtraction. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * R[t_H].R[t_L] = R[a_H].R[a_L] - R[b_H].R[b_L]; + * * RV64: + * Rd = Rs1 - Rs2; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_SUB64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("sub64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.138. SUB64 ===== */ + +/* ===== Inline Function Start for 3.139.1. SUNPKD810 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief SUNPKD810 (Signed Unpacking Bytes 1 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte *x and byte y* of 32-bit chunks in a register into two 16-bit signed halfwords + * of 32-bit chunks in a register. + * + * **Description**:\n + * For the `SUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit signed halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[y]) + * // SUNPKD810, x=1,y=0 + * // SUNPKD820, x=2,y=0 + * // SUNPKD830, x=3,y=0 + * // SUNPKD831, x=3,y=1 + * // SUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUNPKD810(unsigned long a) +{ + unsigned long result; + __ASM volatile("sunpkd810 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.139.1. SUNPKD810 ===== */ + +/* ===== Inline Function Start for 3.139.2. SUNPKD820 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief SUNPKD820 (Signed Unpacking Bytes 2 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte *x and byte y* of 32-bit chunks in a register into two 16-bit signed halfwords + * of 32-bit chunks in a register. + * + * **Description**:\n + * For the `SUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit signed halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[y]) + * // SUNPKD810, x=1,y=0 + * // SUNPKD820, x=2,y=0 + * // SUNPKD830, x=3,y=0 + * // SUNPKD831, x=3,y=1 + * // SUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUNPKD820(unsigned long a) +{ + unsigned long result; + __ASM volatile("sunpkd820 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.139.2. SUNPKD820 ===== */ + +/* ===== Inline Function Start for 3.139.3. SUNPKD830 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief SUNPKD830 (Signed Unpacking Bytes 3 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte *x and byte y* of 32-bit chunks in a register into two 16-bit signed halfwords + * of 32-bit chunks in a register. + * + * **Description**:\n + * For the `SUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit signed halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[y]) + * // SUNPKD810, x=1,y=0 + * // SUNPKD820, x=2,y=0 + * // SUNPKD830, x=3,y=0 + * // SUNPKD831, x=3,y=1 + * // SUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUNPKD830(unsigned long a) +{ + unsigned long result; + __ASM volatile("sunpkd830 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.139.3. SUNPKD830 ===== */ + +/* ===== Inline Function Start for 3.139.4. SUNPKD831 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief SUNPKD831 (Signed Unpacking Bytes 3 & 1) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte *x and byte y* of 32-bit chunks in a register into two 16-bit signed halfwords + * of 32-bit chunks in a register. + * + * **Description**:\n + * For the `SUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit signed halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[y]) + * // SUNPKD810, x=1,y=0 + * // SUNPKD820, x=2,y=0 + * // SUNPKD830, x=3,y=0 + * // SUNPKD831, x=3,y=1 + * // SUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUNPKD831(unsigned long a) +{ + unsigned long result; + __ASM volatile("sunpkd831 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.139.4. SUNPKD831 ===== */ + +/* ===== Inline Function Start for 3.139.5. SUNPKD832 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief SUNPKD832 (Signed Unpacking Bytes 3 & 2) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte *x and byte y* of 32-bit chunks in a register into two 16-bit signed halfwords + * of 32-bit chunks in a register. + * + * **Description**:\n + * For the `SUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit signed halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[y]) + * // SUNPKD810, x=1,y=0 + * // SUNPKD820, x=2,y=0 + * // SUNPKD830, x=3,y=0 + * // SUNPKD831, x=3,y=1 + * // SUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUNPKD832(unsigned long a) +{ + unsigned long result; + __ASM volatile("sunpkd832 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.139.5. SUNPKD832 ===== */ + +/* ===== Inline Function Start for 3.140. SWAP8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief SWAP8 (Swap Byte within Halfword) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SWAP8 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Swap the bytes within each halfword of a register. + * + * **Description**:\n + * This instruction swaps the bytes within each halfword of Rs1 and writes the result to + * Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = CONCAT(Rs1.H[x][7:0],Rs1.H[x][15:8]); + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SWAP8(unsigned long a) +{ + unsigned long result; + __ASM volatile("swap8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.140. SWAP8 ===== */ + +/* ===== Inline Function Start for 3.141. SWAP16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief SWAP16 (Swap Halfword within Word) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * SWAP16 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Swap the 16-bit halfwords within each word of a register. + * + * **Description**:\n + * This instruction swaps the 16-bit halfwords within each word of Rs1 and writes the + * result to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = CONCAT(Rs1.W[x][15:0],Rs1.H[x][31:16]); + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SWAP16(unsigned long a) +{ + unsigned long result; + __ASM volatile("swap16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.141. SWAP16 ===== */ + +/* ===== Inline Function Start for 3.142. UCLIP8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief UCLIP8 (SIMD 8-bit Unsigned Clip Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCLIP8 Rt, Ra, imm3u + * ~~~ + * + * **Purpose**:\n + * Limit the 8-bit signed elements of a register into an unsigned range simultaneously. + * + * **Description**:\n + * This instruction limits the 8-bit signed elements stored in Rs1 into an unsigned integer + * range between 2^imm3u-1 and 0, and writes the limited results to Rd. For example, if imm3u is 3, the 8- + * bit input values should be saturated between 7 and 0. If saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src > (2^imm3u)-1) { + * src = (2^imm3u)-1; + * OV = 1; + * } else if (src < 0) { + * src = 0; + * OV = 1; + * } + * Rd.H[x] = src; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_UCLIP8(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("uclip8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.142. UCLIP8 ===== */ + +/* ===== Inline Function Start for 3.143. UCLIP16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief UCLIP16 (SIMD 16-bit Unsigned Clip Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCLIP16 Rt, Ra, imm4u + * ~~~ + * + * **Purpose**:\n + * Limit the 16-bit signed elements of a register into an unsigned range simultaneously. + * + * **Description**:\n + * This instruction limits the 16-bit signed elements stored in Rs1 into an unsigned + * integer range between 2imm4u-1 and 0, and writes the limited results to Rd. For example, if imm4u is + * 3, the 16-bit input values should be saturated between 7 and 0. If saturation is performed, set OV bit + * to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src > (2^imm4u)-1) { + * src = (2^imm4u)-1; + * OV = 1; + * } else if (src < 0) { + * src = 0; + * OV = 1; + * } + * Rd.H[x] = src; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_UCLIP16(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("uclip16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.143. UCLIP16 ===== */ + +/* ===== Inline Function Start for 3.144. UCLIP32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_PART_SIMD_MISC + * \brief UCLIP32 (SIMD 32-bit Unsigned Clip Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCLIP32 Rd, Rs1, imm5u[4:0] + * ~~~ + * + * **Purpose**:\n + * Limit the 32-bit signed integer elements of a register into an unsigned range + * simultaneously. + * + * **Description**:\n + * This instruction limits the 32-bit signed integer elements stored in Rs1 into an + * unsigned integer range between 2imm5u-1 and 0, and writes the limited results to Rd. For example, if + * imm5u is 3, the 32-bit input values should be saturated between 7 and 0. If saturation is performed, + * set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.W[x]; + * if (src > (2^imm5u)-1) { + * src = (2^imm5u)-1; + * OV = 1; + * } else if (src < 0) { + * src = 0; + * OV = 1; + * } + * Rd.W[x] = src + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_UCLIP32(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("uclip32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.144. UCLIP32 ===== */ + +/* ===== Inline Function Start for 3.145. UCMPLE8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP + * \brief UCMPLE8 (SIMD 8-bit Unsigned Compare Less Than & Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCMPLE8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer elements less than & equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit unsigned integer elements in Rs1 with the 8-bit + * unsigned integer elements in Rs2 to see if the one in Rs1 is less than or equal to the one in Rs2. If it + * is true, the result is 0xFF; otherwise, the result is 0x0. The four comparison results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] <=u Rs2.B[x])? 0xff : 0x0; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UCMPLE8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ucmple8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.145. UCMPLE8 ===== */ + +/* ===== Inline Function Start for 3.146. UCMPLE16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_CMP + * \brief UCMPLE16 (SIMD 16-bit Unsigned Compare Less Than & Equal) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCMPLE16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer elements less than & equal comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit unsigned integer elements in Rs1 with the 16-bit + * unsigned integer elements in Rs2 to see if the one in Rs1 is less than or equal to the one in Rs2. If it + * is true, the result is 0xFFFF; otherwise, the result is 0x0. The element comparison results are + * written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] <=u Rs2.H[x])? 0xffff : 0x0; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UCMPLE16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ucmple16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.146. UCMPLE16 ===== */ + +/* ===== Inline Function Start for 3.147. UCMPLT8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_CMP + * \brief UCMPLT8 (SIMD 8-bit Unsigned Compare Less Than) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UCMPLT8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer elements less than comparisons simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit unsigned integer elements in Rs1 with the 8-bit + * unsigned integer elements in Rs2 to see if the one in Rs1 is less than the one in Rs2. If it is true, the + * result is 0xFF; otherwise, the result is 0x0. The element comparison results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] (2^8)-1) { + * res[x] = (2^8)-1; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKADD8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukadd8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.149. UKADD8 ===== */ + +/* ===== Inline Function Start for 3.150. UKADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKADD16 (SIMD 16-bit Unsigned Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKADD16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer elements in Rs1 with the 16-bit + * unsigned integer elements in Rs2. If any of the results are beyond the 16-bit unsigned number + * range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] + Rs2.H[x]; + * if (res[x] > (2^16)-1) { + * res[x] = (2^16)-1; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKADD16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukadd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.150. UKADD16 ===== */ + +/* ===== Inline Function Start for 3.151. UKADD64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief UKADD64 (64-bit Unsigned Saturating Addition) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * UKADD64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add two 64-bit unsigned integers. The result is saturated to the U64 range. + * + * **RV32 Description**:\n + * This instruction adds the 64-bit unsigned integer of an even/odd pair of registers + * specified by Rs1(4,1) with the 64-bit unsigned integer of an even/odd pair of registers specified by + * Rs2(4,1). If the 64-bit result is beyond the U64 number range (0 <= U64 <= 2^64-1), it is saturated to the + * range and the OV bit is set to 1. The saturated result is written to an even/odd pair of registers + * specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction adds the 64-bit unsigned integer in Rs1 with the 64-bit unsigned + * integer in Rs2. If the 64-bit result is beyond the U64 number range (0 <= U64 <= 2^64-1), it is saturated to + * the range and the OV bit is set to 1. The saturated result is written to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rt(4,1),1'b0); t_H = CONCAT(Rt(4,1),1'b1); + * a_L = CONCAT(Ra(4,1),1'b0); a_H = CONCAT(Ra(4,1),1'b1); + * b_L = CONCAT(Rb(4,1),1'b0); b_H = CONCAT(Rb(4,1),1'b1); + * result = R[a_H].R[a_L] + R[b_H].R[b_L]; + * if (result > (2^64)-1) { + * result = (2^64)-1; OV = 1; + * } + * R[t_H].R[t_L] = result; + * * RV64: + * result = Rs1 + Rs2; + * if (result > (2^64)-1) { + * result = (2^64)-1; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_UKADD64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("ukadd64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.151. UKADD64 ===== */ + +/* ===== Inline Function Start for 3.152. UKADDH ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief UKADDH (Unsigned Addition with U16 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * UKADDH Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add the unsigned lower 32-bit content of two registers with U16 saturation. + * + * **Description**:\n + * The unsigned lower 32-bit content of Rs1 is added with the unsigned lower 32-bit + * content of Rs2. And the result is saturated to the 16-bit unsigned integer range of [0, 2^16-1] and then + * sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] + Rs2.W[0]; + * if (tmp > (2^16)-1) { + * tmp = (2^16)-1; + * OV = 1; + * } + * Rd = SE(tmp[15:0]); + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKADDH(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ukaddh %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.152. UKADDH ===== */ + +/* ===== Inline Function Start for 3.153. UKADDW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief UKADDW (Unsigned Addition with U32 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * UKADDW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add the unsigned lower 32-bit content of two registers with U32 saturation. + * + * **Description**:\n + * The unsigned lower 32-bit content of Rs1 is added with the unsigned lower 32-bit + * content of Rs2. And the result is saturated to the 32-bit unsigned integer range of [0, 2^32-1] and then + * sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] + Rs2.W[0]; + * if (tmp > (2^32)-1) { + * tmp[31:0] = (2^32)-1; + * OV = 1; + * } + * Rd = tmp[31:0]; // RV32 + * Rd = SE(tmp[31:0]); // RV64 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKADDW(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ukaddw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.153. UKADDW ===== */ + +/* ===== Inline Function Start for 3.154. UKCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKCRAS16 (SIMD 16-bit Unsigned Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKCRAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 16-bit unsigned integer element saturating addition and one 16-bit unsigned + * integer element saturating subtraction in a 32-bit chunk simultaneously. Operands are from crossed + * positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit unsigned integer element in [15:0] of 32-bit chunks in Rs2; at the same time, it + * subtracts the 16-bit unsigned integer element in [31:16] of 32-bit chunks in Rs2 from the 16-bit + * unsigned integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the 16-bit + * unsigned number range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set to 1. + * The saturated results are written to [31:16] of 32-bit chunks in Rd for addition and [15:0] of 32-bit + * chunks in Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][31:16]; + * if (res1 > (2^16)-1) { + * res1 = (2^16)-1; + * OV = 1; + * } + * if (res2 < 0) { + * res2 = 0; + * OV = 1; + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKCRAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.154. UKCRAS16 ===== */ + +/* ===== Inline Function Start for 3.155. UKCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKCRSA16 (SIMD 16-bit Unsigned Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKCRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 16-bit unsigned integer element saturating subtraction and one 16-bit unsigned + * integer element saturating addition in a 32-bit chunk simultaneously. Operands are from crossed + * positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer element in [15:0] of 32-bit + * chunks in Rs2 from the 16-bit unsigned integer element in [31:16] of 32-bit chunks in Rs1; at the + * same time, it adds the 16-bit unsigned integer element in [31:16] of 32-bit chunks in Rs2 with the 16- + * bit unsigned integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the + * 16-bit unsigned number range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set + * to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of + * 32-bit chunks in Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][31:16]; + * if (res1 < 0) { + * res1 = 0; + * OV = 1; + * } else if (res2 > (2^16)-1) { + * res2 = (2^16)-1; + * OV = 1; + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKCRSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.155. UKCRSA16 ===== */ + +/* ===== Inline Function Start for 3.156. UKMAR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief UKMAR64 (Unsigned Multiply and Saturating Add to 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * UKMAR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit unsigned elements in two registers and add the 64-bit multiplication + * results to the 64-bit unsigned data of a pair of registers (RV32) or a register (RV64). The result is + * saturated to the U64 range and written back to the pair of registers (RV32) or the register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit unsigned data of Rs1 with that of Rs2. It + * adds the 64-bit multiplication result to the 64-bit unsigned data of an even/odd pair of registers + * specified by Rd(4,1) with unlimited precision. If the 64-bit addition result is beyond the U64 number + * range (0 <= U64 <= 2^64-1), it is saturated to the range and the OV bit is set to 1. The saturated result is + * written back to the even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit unsigned elements of Rs1 with that of Rs2. + * It adds the 64-bit multiplication results to the 64-bit unsigned data in Rd with unlimited precision. If + * the 64-bit addition result is beyond the U64 number range (0 <= U64 <= 2^64-1), it is saturated to the + * range and the OV bit is set to 1. The saturated result is written back to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * result = R[t_H].R[t_L] + (Rs1 * Rs2); + * if (result > (2^64)-1) { + * result = (2^64)-1; OV = 1; + * } + * R[t_H].R[t_L] = result; + * * RV64: + * // `result` has unlimited precision + * result = Rd + (Rs1.W[0] u* Rs2.W[0]) + (Rs1.W[1] u* Rs2.W[1]); + * if (result > (2^64)-1) { + * result = (2^64)-1; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_UKMAR64(unsigned long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("ukmar64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.156. UKMAR64 ===== */ + +/* ===== Inline Function Start for 3.157. UKMSR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief UKMSR64 (Unsigned Multiply and Saturating Subtract from 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * UKMSR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit unsigned elements in two registers and subtract the 64-bit + * multiplication results from the 64-bit unsigned data of a pair of registers (RV32) or a register (RV64). + * The result is saturated to the U64 range and written back to the pair of registers (RV32) or a register + * (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit unsigned data of Rs1 with that of Rs2. It + * subtracts the 64-bit multiplication result from the 64-bit unsigned data of an even/odd pair of + * registers specified by Rd(4,1) with unlimited precision. If the 64-bit subtraction result is beyond the + * U64 number range (0 <= U64 <= 2^64-1), it is saturated to the range and the OV bit is set to 1. The + * saturated result is written back to the even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit unsigned elements of Rs1 with that of Rs2. + * It subtracts the 64-bit multiplication results from the 64-bit unsigned data of Rd with unlimited + * precision. If the 64-bit subtraction result is beyond the U64 number range (0 <= U64 <= 2^64-1), it is + * saturated to the range and the OV bit is set to 1. The saturated result is written back to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * result = R[t_H].R[t_L] - (Rs1 u* Rs2); + * if (result < 0) { + * result = 0; OV = 1; + * } + * R[t_H].R[t_L] = result; + * * RV64: + * // `result` has unlimited precision + * result = Rd - (Rs1.W[0] u* Rs2.W[0]) - (Rs1.W[1] u* Rs2.W[1]); + * if (result < 0) { + * result = 0; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_UKMSR64(unsigned long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("ukmsr64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.157. UKMSR64 ===== */ + +/* ===== Inline Function Start for 3.158. UKSTAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKSTAS16 (SIMD 16-bit Unsigned Saturating Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKSTAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 16-bit unsigned integer element saturating addition and one 16-bit unsigned + * integer element saturating subtraction in a 32-bit chunk simultaneously. Operands are from + * corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer element in [31:16] of 32-bit chunks in + * Rs1 with the 16-bit unsigned integer element in [31:16] of 32-bit chunks in Rs2; at the same time, it + * subtracts the 16-bit unsigned integer element in [15:0] of 32-bit chunks in Rs2 from the 16-bit + * unsigned integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the 16-bit + * unsigned number range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set to 1. + * The saturated results are written to [31:16] of 32-bit chunks in Rd for addition and [15:0] of 32-bit + * chunks in Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][15:0]; + * if (res1 > (2^16)-1) { + * res1 = (2^16)-1; + * OV = 1; + * } + * if (res2 < 0) { + * res2 = 0; + * OV = 1; + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSTAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukstas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.158. UKSTAS16 ===== */ + +/* ===== Inline Function Start for 3.159. UKSTSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKSTSA16 (SIMD 16-bit Unsigned Saturating Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKSTSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 16-bit unsigned integer element saturating subtraction and one 16-bit unsigned + * integer element saturating addition in a 32-bit chunk simultaneously. Operands are from + * corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer element in [31:16] of 32-bit + * chunks in Rs2 from the 16-bit unsigned integer element in [31:16] of 32-bit chunks in Rs1; at the + * same time, it adds the 16-bit unsigned integer element in [15:0] of 32-bit chunks in Rs2 with the 16- + * bit unsigned integer element in [15:0] of 32-bit chunks in Rs1. If any of the results are beyond the + * 16-bit unsigned number range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set + * to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of + * 32-bit chunks in Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][15:0]; + * if (res1 < 0) { + * res1 = 0; + * OV = 1; + * } else if (res2 > (2^16)-1) { + * res2 = (2^16)-1; + * OV = 1; + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSTSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukstsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.159. UKSTSA16 ===== */ + +/* ===== Inline Function Start for 3.160. UKSUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief UKSUB8 (SIMD 8-bit Unsigned Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKSUB8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 8-bit unsigned integer elements in Rs2 from the 8-bit + * unsigned integer elements in Rs1. If any of the results are beyond the 8-bit unsigned number range + * (0 <= RES <= 28-1), they are saturated to the range and the OV bit is set to 1. The saturated results are + * written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.B[x] - Rs2.B[x]; + * if (res[x] < 0) { + * res[x] = 0; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSUB8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uksub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.160. UKSUB8 ===== */ + +/* ===== Inline Function Start for 3.161. UKSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief UKSUB16 (SIMD 16-bit Unsigned Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UKSUB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer elements in Rs2 from the 16-bit + * unsigned integer elements in Rs1. If any of the results are beyond the 16-bit unsigned number + * range (0 <= RES <= 2^16-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] - Rs2.H[x]; + * if (res[x] < 0) { + * res[x] = 0; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSUB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uksub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.161. UKSUB16 ===== */ + +/* ===== Inline Function Start for 3.162. UKSUB64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief UKSUB64 (64-bit Unsigned Saturating Subtraction) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * UKSUB64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a 64-bit signed integer subtraction. The result is saturated to the U64 range. + * + * **RV32 Description**:\n + * This instruction subtracts the 64-bit unsigned integer of an even/odd pair of + * registers specified by Rs2(4,1) from the 64-bit unsigned integer of an even/odd pair of registers + * specified by Rs1(4,1). If the 64-bit result is beyond the U64 number range (0 <= U64 <= 2^64-1), it is + * saturated to the range and the OV bit is set to 1. The saturated result is then written to an even/odd + * pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the operand and the even `2d` + * register of the pair contains the low 32-bit of the operand. + * + * **RV64 Description**:\n + * This instruction subtracts the 64-bit unsigned integer of Rs2 from the 64-bit + * unsigned integer of an even/odd pair of Rs1. If the 64-bit result is beyond the U64 number range (0 <= + * U64 <= 2^64-1), it is saturated to the range and the OV bit is set to 1. The saturated result is then written + * to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * a_L = CONCAT(Rs1(4,1),1'b0); a_H = CONCAT(Rs1(4,1),1'b1); + * b_L = CONCAT(Rs2(4,1),1'b0); b_H = CONCAT(Rs2(4,1),1'b1); + * result = R[a_H].R[a_L] - R[b_H].R[b_L]; + * if (result < 0) { + * result = 0; OV = 1; + * } + * R[t_H].R[t_L] = result; + * * RV64 + * result = Rs1 - Rs2; + * if (result < 0) { + * result = 0; OV = 1; + * } + * Rd = result; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_UKSUB64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("uksub64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.162. UKSUB64 ===== */ + +/* ===== Inline Function Start for 3.163. UKSUBH ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q15_SAT_ALU + * \brief UKSUBH (Unsigned Subtraction with U16 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * UKSUBH Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract the unsigned lower 32-bit content of two registers with U16 saturation. + * + * **Description**:\n + * The unsigned lower 32-bit content of Rs2 is subtracted from the unsigned lower 32-bit + * content of Rs1. And the result is saturated to the 16-bit unsigned integer range of [0, 2^16-1] and then + * sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] - Rs2.W[0]; + * if (tmp > (2^16)-1) { + * tmp = (2^16)-1; + * OV = 1; + * } + * else if (tmp < 0) { + * tmp = 0; + * OV = 1; + * } + * Rd = SE(tmp[15:0]); + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSUBH(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("uksubh %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.163. UKSUBH ===== */ + +/* ===== Inline Function Start for 3.164. UKSUBW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU + * \brief UKSUBW (Unsigned Subtraction with U32 Saturation) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * UKSUBW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract the unsigned lower 32-bit content of two registers with unsigned 32-bit + * saturation. + * + * **Description**:\n + * The unsigned lower 32-bit content of Rs2 is subtracted from the unsigned lower 32-bit + * content of Rs1. And the result is saturated to the 32-bit unsigned integer range of [0, 2^32-1] and then + * sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag. + * + * **Operations**:\n + * ~~~ + * tmp = Rs1.W[0] - Rs2.W[0]; + * if (tmp < 0) { + * tmp[31:0] = 0; + * OV = 1; + * } + * Rd = tmp[31:0]; // RV32 + * Rd = SE(tmp[31:0]); // RV64 + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSUBW(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("uksubw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.164. UKSUBW ===== */ + +/* ===== Inline Function Start for 3.165. UMAR64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_MULT_64B_ADDSUB + * \brief UMAR64 (Unsigned Multiply and Add to 64-Bit Data) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * UMAR64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the 32-bit unsigned elements in two registers and add the 64-bit multiplication + * results to the 64-bit unsigned data of a pair of registers (RV32) or a register (RV64). The result is + * written back to the pair of registers (RV32) or a register (RV64). + * + * **RV32 Description**:\n + * This instruction multiplies the 32-bit unsigned data of Rs1 with that of Rs2. It + * adds the 64-bit multiplication result to the 64-bit unsigned data of an even/odd pair of registers + * specified by Rd(4,1). The addition result is written back to the even/odd pair of registers specified by + * Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction multiplies the 32-bit unsigned elements of Rs1 with that of Rs2. + * It adds the 64-bit multiplication results to the 64-bit unsigned data of Rd. The addition result is + * written back to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rd(4,1),1'b0); t_H = CONCAT(Rd(4,1),1'b1); + * R[t_H].R[t_L] = R[t_H].R[t_L] + (Rs1 * Rs2); + * * RV64: + * Rd = Rd + (Rs1.W[0] u* Rs2.W[0]) + (Rs1.W[1] u* Rs2.W[1]); + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_UMAR64(unsigned long long t, unsigned long a, unsigned long b) +{ + __ASM volatile("umar64 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.165. UMAR64 ===== */ + +/* ===== Inline Function Start for 3.166. UMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_8B_MULT_32B_ADD + * \brief UMAQA (Unsigned Multiply Four Bytes with 32- bit Adds) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * UMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four unsigned 8-bit multiplications from 32-bit chunks of two registers; and then adds + * the four 16-bit results and the content of corresponding 32-bit chunks of a third register together. + * + * **Description**:\n + * This instruction multiplies the four unsigned 8-bit elements of 32-bit chunks of Rs1 with the four + * unsigned 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the + * unsigned content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rd.W[x] + (Rs1.W[x].B[3] u* Rs2.W[x].B[3]) + + * (Rs1.W[x].B[2] u* Rs2.W[x].B[2]) + (Rs1.W[x].B[1] u* Rs2.W[x].B[1]) + + * (Rs1.W[x].B[0] u* Rs2.W[x].B[0]); + * Rd.W[x] = res[x]; + * for RV32: x=0, + * for RV64: x=1...0 + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UMAQA(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("umaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 3.166. UMAQA ===== */ + +/* ===== Inline Function Start for 3.167. UMAX8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief UMAX8 (SIMD 8-bit Unsigned Maximum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UMAX8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit unsigned integer elements in Rs1 with the four 8- + * bit unsigned integer elements in Rs2 and selects the numbers that is greater than the other one. The + * two selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] >u Rs2.B[x])? Rs1.B[x] : Rs2.B[x]; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UMAX8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("umax8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.167. UMAX8 ===== */ + +/* ===== Inline Function Start for 3.168. UMAX16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_MISC + * \brief UMAX16 (SIMD 16-bit Unsigned Maximum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UMAX16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 16-bit unsigned integer elements in Rs1 with the 16-bit + * unsigned integer elements in Rs2 and selects the numbers that is greater than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] >u Rs2.H[x])? Rs1.H[x] : Rs2.H[x]; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UMAX16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("umax16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.168. UMAX16 ===== */ + +/* ===== Inline Function Start for 3.169. UMIN8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_MISC + * \brief UMIN8 (SIMD 8-bit Unsigned Minimum) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * UMIN8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer elements finding minimum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 8-bit unsigned integer elements in Rs1 with the 8-bit + * unsigned integer elements in Rs2 and selects the numbers that is less than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] > 1; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URADD8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uradd8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.174. URADD8 ===== */ + +/* ===== Inline Function Start for 3.175. URADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URADD16 (SIMD 16-bit Unsigned Halving Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URADD16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element additions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer elements in Rs1 with the 16-bit + * unsigned integer elements in Rs2. The results are first logically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFF, Rb = 0x7FFF Rt = 0x7FFF + * * Ra = 0x8000, Rb = 0x8000 Rt = 0x8000 + * * Ra = 0x4000, Rb = 0x8000 Rt = 0x6000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] + Rs2.H[x]) u>> 1; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URADD16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uradd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.175. URADD16 ===== */ + +/* ===== Inline Function Start for 3.176. URADD64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief URADD64 (64-bit Unsigned Halving Addition) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * URADD64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add two 64-bit unsigned integers. The result is halved to avoid overflow or saturation. + * + * **RV32 Description**:\n + * This instruction adds the 64-bit unsigned integer of an even/odd pair of registers + * specified by Rs1(4,1) with the 64-bit unsigned integer of an even/odd pair of registers specified by + * Rs2(4,1). The 64-bit addition result is first logically right-shifted by 1 bit and then written to an + * even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction adds the 64-bit unsigned integer in Rs1 with the 64-bit unsigned + * integer Rs2. The 64-bit addition result is first logically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rt(4,1),1'b0); t_H = CONCAT(Rt(4,1),1'b1); + * a_L = CONCAT(Ra(4,1),1'b0); a_H = CONCAT(Ra(4,1),1'b1); + * b_L = CONCAT(Rb(4,1),1'b0); b_H = CONCAT(Rb(4,1),1'b1); + * R[t_H].R[t_L] = (R[a_H].R[a_L] + R[b_H].R[b_L]) u>> 1; + * * RV64: + * Rd = (Rs1 + Rs2) u>> 1; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_URADD64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("uradd64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.176. URADD64 ===== */ + +/* ===== Inline Function Start for 3.177. URADDW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief URADDW (32-bit Unsigned Halving Addition) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * URADDW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Add 32-bit unsigned integers and the results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the first 32-bit unsigned integer in Rs1 with the first 32-bit + * unsigned integer in Rs2. The result is first logically right-shifted by 1 bit and then sign-extended and + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFFFFFF, Rb = 0x7FFFFFFF Rt = 0x7FFFFFFF + * * Ra = 0x80000000, Rb = 0x80000000 Rt = 0x80000000 + * * Ra = 0x40000000, Rb = 0x80000000 Rt = 0x60000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * * RV32: + * Rd[31:0] = (Rs1[31:0] + Rs2[31:0]) u>> 1; + * * RV64: + * resw[31:0] = (Rs1[31:0] + Rs2[31:0]) u>> 1; + * Rd[63:0] = SE(resw[31:0]); + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URADDW(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("uraddw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.177. URADDW ===== */ + +/* ===== Inline Function Start for 3.178. URCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URCRAS16 (SIMD 16-bit Unsigned Halving Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URCRAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element addition and 16-bit unsigned integer element + * subtraction in a 32-bit chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs1 + * with the 16-bit unsigned integer in [15:0] of 32-bit chunks in Rs2, and subtracts the 16-bit unsigned + * integer in [31:16] of 32-bit chunks in Rs2 from the 16-bit unsigned integer in [15:0] of 32-bit chunks + * in Rs1. The element results are first logically right-shifted by 1 bit and then written to [31:16] of 32- + * bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `URADD16` and `URSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] + Rs2.W[x][15:0]) u>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] - Rs2.W[x][31:16]) u>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URCRAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.178. URCRAS16 ===== */ + +/* ===== Inline Function Start for 3.179. URCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URCRSA16 (SIMD 16-bit Unsigned Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URCRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element subtraction and 16-bit unsigned integer element + * addition in a 32-bit chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer in [15:0] of 32-bit chunks in Rs2 + * from the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs1, and adds the 16-bit unsigned + * integer in [15:0] of 32-bit chunks in Rs1 with the 16-bit unsigned integer in [31:16] of 32-bit chunks + * in Rs2. The two results are first logically right-shifted by 1 bit and then written to [31:16] of 32-bit + * chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `URADD16` and `URSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] - Rs2.W[x][15:0]) u>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] + Rs2.W[x][31:16]) u>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URCRSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.179. URCRSA16 ===== */ + +/* ===== Inline Function Start for 3.180. URSTAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URSTAS16 (SIMD 16-bit Unsigned Halving Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URSTAS16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element addition and 16-bit unsigned integer element + * subtraction in a 32-bit chunk simultaneously. Operands are from corresponding positions in 32-bit + * chunks. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs1 + * with the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs2, and subtracts the 16-bit unsigned + * integer in [15:0] of 32-bit chunks in Rs2 from the 16-bit unsigned integer in [15:0] of 32-bit chunks + * in Rs1. The element results are first logically right-shifted by 1 bit and then written to [31:16] of 32- + * bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `URADD16` and `URSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] + Rs2.W[x][31:16]) u>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] - Rs2.W[x][15:0]) u>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSTAS16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urstas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.180. URSTAS16 ===== */ + +/* ===== Inline Function Start for 3.181. URSTSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URSTSA16 (SIMD 16-bit Unsigned Halving Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URCRSA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element subtraction and 16-bit unsigned integer element + * addition in a 32-bit chunk simultaneously. Operands are from corresponding positions in 32-bit + * chunks. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs2 + * from the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs1, and adds the 16-bit unsigned + * integer in [15:0] of 32-bit chunks in Rs1 with the 16-bit unsigned integer in [15:0] of 32-bit chunks in + * Rs2. The two results are first logically right-shifted by 1 bit and then written to [31:16] of 32-bit + * chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Examples**:\n + * ~~~ + * Please see `URADD16` and `URSUB16` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] - Rs2.W[x][31:16]) u>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] + Rs2.W[x][15:0]) u>> 1; + * for RV32, x=0 + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSTSA16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urstsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.181. URSTSA16 ===== */ + +/* ===== Inline Function Start for 3.182. URSUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_ADDSUB + * \brief URSUB8 (SIMD 8-bit Unsigned Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URSUB8 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 8-bit unsigned integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 8-bit unsigned integer elements in Rs2 from the 8-bit + * unsigned integer elements in Rs1. The results are first logically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7F, Rb = 0x80 Rt = 0xFF + * * Ra = 0x80, Rb = 0x7F Rt = 0x00 + * * Ra = 0x80, Rb = 0x40 Rt = 0x20 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.B[x] = (Rs1.B[x] - Rs2.B[x]) u>> 1; + * for RV32: x=3...0, + * for RV64: x=7...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSUB8(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ursub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.182. URSUB8 ===== */ + +/* ===== Inline Function Start for 3.183. URSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_16B_ADDSUB + * \brief URSUB16 (SIMD 16-bit Unsigned Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * URSUB16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 16-bit unsigned integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit unsigned integer elements in Rs2 from the 16-bit + * unsigned integer elements in Rs1. The results are first logically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFF, Rb = 0x8000 Rt = 0xFFFF + * * Ra = 0x8000, Rb = 0x7FFF Rt = 0x0000 + * * Ra = 0x8000, Rb = 0x4000 Rt = 0x2000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] - Rs2.H[x]) u>> 1; + * for RV32: x=1...0, + * for RV64: x=3...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSUB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ursub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.183. URSUB16 ===== */ + +/* ===== Inline Function Start for 3.184. URSUB64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_64B_ADDSUB + * \brief URSUB64 (64-bit Unsigned Halving Subtraction) + * \details + * **Type**: DSP (64-bit Profile) + * + * **Syntax**:\n + * ~~~ + * URSUB64 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Perform a 64-bit unsigned integer subtraction. The result is halved to avoid overflow or + * saturation. + * + * **RV32 Description**:\n + * This instruction subtracts the 64-bit unsigned integer of an even/odd pair of + * registers specified by Rs2(4,1) from the 64-bit unsigned integer of an even/odd pair of registers + * specified by Rs1(4,1). The subtraction result is first logically right-shifted by 1 bit and then written + * to an even/odd pair of registers specified by Rd(4,1). + * Rx(4,1), i.e., d, determines the even/odd pair group of two registers. Specifically, the register pair + * includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the result and the even `2d` register + * of the pair contains the low 32-bit of the result. + * + * **RV64 Description**:\n + * This instruction subtracts the 64-bit unsigned integer in Rs2 from the 64-bit + * unsigned integer in Rs1. The subtraction result is first logically right-shifted by 1 bit and then + * written to Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * t_L = CONCAT(Rt(4,1),1'b0); t_H = CONCAT(Rt(4,1),1'b1); + * a_L = CONCAT(Ra(4,1),1'b0); a_H = CONCAT(Ra(4,1),1'b1); + * b_L = CONCAT(Rb(4,1),1'b0); b_H = CONCAT(Rb(4,1),1'b1); + * R[t_H].R[t_L] = (R[a_H].R[a_L] - R[b_H].R[b_L]) u>> 1; + * * RV64: + * Rd = (Rs1 - Rs2) u>> 1; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_URSUB64(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("ursub64 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.184. URSUB64 ===== */ + +/* ===== Inline Function Start for 3.185. URSUBW ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_32B_COMPUTATION + * \brief URSUBW (32-bit Unsigned Halving Subtraction) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * URSUBW Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Subtract 32-bit unsigned integers and the result is halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the first 32-bit signed integer in Rs2 from the first 32-bit + * signed integer in Rs1. The result is first logically right-shifted by 1 bit and then sign-extended and + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFFFFFF, Rb = 0x80000000 Rt = 0xFFFFFFFF + * * Ra = 0x80000000, Rb = 0x7FFFFFFF Rt = 0x00000000 + * * Ra = 0x80000000, Rb = 0x40000000 Rt = 0x20000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * * RV32: + * Rd[31:0] = (Rs1[31:0] - Rs2[31:0]) u>> 1; + * * RV64: + * resw[31:0] = (Rs1[31:0] - Rs2[31:0]) u>> 1; + * Rd[63:0] = SE(resw[31:0]); + * ~~~ + * + * \param [in] a unsigned int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSUBW(unsigned int a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ursubw %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.185. URSUBW ===== */ + +/* ===== Inline Function Start for 3.186. WEXTI ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief WEXTI (Extract Word from 64-bit Immediate) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * WEXTI Rd, Rs1, #LSBloc + * ~~~ + * + * **Purpose**:\n + * Extract a 32-bit word from a 64-bit value stored in an even/odd pair of registers (RV32) or + * a register (RV64) starting from a specified immediate LSB bit position. + * + * **RV32 Description**:\n + * This instruction extracts a 32-bit word from a 64-bit value of an even/odd pair of registers specified + * by Rs1(4,1) starting from a specified immediate LSB bit position, #LSBloc. The extracted word is + * written to Rd. + * Rs1(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the 64-bit value and the even `2d` + * register of the pair contains the low 32-bit of the 64-bit value. + * + * **RV64 Description**:\n + * This instruction extracts a 32-bit word from a 64-bit value in Rs1 starting from a specified + * immediate LSB bit position, #LSBloc. The extracted word is sign-extended and written to lower 32- + * bit of Rd. + * + * **Operations**:\n + * ~~~ + * * RV32: + * Idx0 = CONCAT(Rs1(4,1),1'b0); Idx1 = CONCAT(Rs2(4,1),1'b1); + * src[63:0] = Concat(R[Idx1], R[Idx0]); + * Rd = src[31+LSBloc:LSBloc]; + * * RV64: + * ExtractW = Rs1[31+LSBloc:LSBloc]; + * Rd = SE(ExtractW) + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_WEXTI(a, b) \ + ({ \ + unsigned long result; \ + long long __a = (long long)(a); \ + __ASM volatile("wexti %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 3.186. WEXTI ===== */ + +/* ===== Inline Function Start for 3.187. WEXT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NON_SIMD_MISC + * \brief WEXT (Extract Word from 64-bit) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * WEXT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Extract a 32-bit word from a 64-bit value stored in an even/odd pair of registers (RV32) or + * a register (RV64) starting from a specified LSB bit position in a register. + * + * **RV32 Description**:\n + * This instruction extracts a 32-bit word from a 64-bit value of an even/odd pair of registers specified + * by Rs1(4,1) starting from a specified LSB bit position, specified in Rs2[4:0]. The extracted word is + * written to Rd. + * Rs1(4,1), i.e., d, determines the even/odd pair group of the two registers. Specifically, the register + * pair includes register 2d and 2d+1. + * The odd `2d+1` register of the pair contains the high 32-bit of the 64-bit value and the even `2d` + * register of the pair contains the low 32-bit of the 64-bit value. + * + * **Operations**:\n + * ~~~ + * * RV32: + * Idx0 = CONCAT(Rs1(4,1),1'b0); Idx1 = CONCAT(Rs1(4,1),1'b1); + * src[63:0] = Concat(R[Idx1], R[Idx0]); + * LSBloc = Rs2[4:0]; + * Rd = src[31+LSBloc:LSBloc]; + * * RV64: + * LSBloc = Rs2[4:0]; + * ExtractW = Rs1[31+LSBloc:LSBloc]; + * Rd = SE(ExtractW) + * ~~~ + * + * \param [in] a long long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_WEXT(long long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("wext %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 3.187. WEXT ===== */ + +/* ===== Inline Function Start for 3.188.1. ZUNPKD810 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief ZUNPKD810 (Unsigned Unpacking Bytes 1 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * ZUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte x and byte y of 32-bit chunks in a register into two 16-bit unsigned + * halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `ZUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit unsigned halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = ZE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = ZE16(Rs1.W[m].B[y]) + * // ZUNPKD810, x=1,y=0 + * // ZUNPKD820, x=2,y=0 + * // ZUNPKD830, x=3,y=0 + * // ZUNPKD831, x=3,y=1 + * // ZUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ZUNPKD810(unsigned long a) +{ + unsigned long result; + __ASM volatile("zunpkd810 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.188.1. ZUNPKD810 ===== */ + +/* ===== Inline Function Start for 3.188.2. ZUNPKD820 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief ZUNPKD820 (Unsigned Unpacking Bytes 2 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * ZUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte x and byte y of 32-bit chunks in a register into two 16-bit unsigned + * halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `ZUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit unsigned halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = ZE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = ZE16(Rs1.W[m].B[y]) + * // ZUNPKD810, x=1,y=0 + * // ZUNPKD820, x=2,y=0 + * // ZUNPKD830, x=3,y=0 + * // ZUNPKD831, x=3,y=1 + * // ZUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ZUNPKD820(unsigned long a) +{ + unsigned long result; + __ASM volatile("zunpkd820 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.188.2. ZUNPKD820 ===== */ + +/* ===== Inline Function Start for 3.188.3. ZUNPKD830 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief ZUNPKD830 (Unsigned Unpacking Bytes 3 & 0) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * ZUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte x and byte y of 32-bit chunks in a register into two 16-bit unsigned + * halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `ZUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit unsigned halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = ZE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = ZE16(Rs1.W[m].B[y]) + * // ZUNPKD810, x=1,y=0 + * // ZUNPKD820, x=2,y=0 + * // ZUNPKD830, x=3,y=0 + * // ZUNPKD831, x=3,y=1 + * // ZUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ZUNPKD830(unsigned long a) +{ + unsigned long result; + __ASM volatile("zunpkd830 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.188.3. ZUNPKD830 ===== */ + +/* ===== Inline Function Start for 3.188.4. ZUNPKD831 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief ZUNPKD831 (Unsigned Unpacking Bytes 3 & 1) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * ZUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte x and byte y of 32-bit chunks in a register into two 16-bit unsigned + * halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `ZUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit unsigned halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = ZE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = ZE16(Rs1.W[m].B[y]) + * // ZUNPKD810, x=1,y=0 + * // ZUNPKD820, x=2,y=0 + * // ZUNPKD830, x=3,y=0 + * // ZUNPKD831, x=3,y=1 + * // ZUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ZUNPKD831(unsigned long a) +{ + unsigned long result; + __ASM volatile("zunpkd831 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.188.4. ZUNPKD831 ===== */ + +/* ===== Inline Function Start for 3.188.5. ZUNPKD832 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_SIMD_8B_UNPACK + * \brief ZUNPKD832 (Unsigned Unpacking Bytes 3 & 2) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * ZUNPKD8xy Rd, Rs1 + * xy = {10, 20, 30, 31, 32} + * ~~~ + * + * **Purpose**:\n + * Unpack byte x and byte y of 32-bit chunks in a register into two 16-bit unsigned + * halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `ZUNPKD8(x)(*y*)` instruction, it unpacks byte *x and byte y* of 32-bit chunks in Rs1 into + * two 16-bit unsigned halfwords and writes the results to the top part and the bottom part of 32-bit + * chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = ZE16(Rs1.W[m].B[x]) + * Rd.W[m].H[0] = ZE16(Rs1.W[m].B[y]) + * // ZUNPKD810, x=1,y=0 + * // ZUNPKD820, x=2,y=0 + * // ZUNPKD830, x=3,y=0 + * // ZUNPKD831, x=3,y=1 + * // ZUNPKD832, x=3,y=2 + * for RV32: m=0, + * for RV64: m=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ZUNPKD832(unsigned long a) +{ + unsigned long result; + __ASM volatile("zunpkd832 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 3.188.5. ZUNPKD832 ===== */ + +#if (__RISCV_XLEN == 64) || defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__) + +/* ===== Inline Function Start for 4.1. ADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief ADD32 (SIMD 32-bit Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * ADD32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element additions simultaneously. + * + * **Description**:\n + * This instruction adds the 32-bit integer elements in Rs1 with the 32-bit integer + * elements in Rs2, and then writes the 32-bit element results to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned addition. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x] + Rs2.W[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_ADD32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("add32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.1. ADD32 ===== */ + +/* ===== Inline Function Start for 4.2. CRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief CRAS32 (SIMD 32-bit Cross Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * CRAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element addition and 32-bit integer element subtraction in a 64-bit + * chunk simultaneously. Operands are from crossed 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit + * integer element in [31:0] of Rs2, and writes the result to [63:32] of Rd; at the same time, it subtracts + * the 32-bit integer element in [63:32] of Rs2 from the 32-bit integer element in [31:0] of Rs1, and + * writes the result to [31:0] of Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] + Rs2.W[0]; + * Rd.W[0] = Rs1.W[0] - Rs2.W[1]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CRAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("cras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.2. CRAS32 ===== */ + +/* ===== Inline Function Start for 4.3. CRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief CRSA32 (SIMD 32-bit Cross Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * CRSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtraction and 32-bit integer element addition in a 64-bit + * chunk simultaneously. Operands are from crossed 32-bit elements. + * *Description: * + * This instruction subtracts the 32-bit integer element in [31:0] of Rs2 from the 32-bit integer element + * in [63:32] of Rs1, and writes the result to [63:32] of Rd; at the same time, it adds the 32-bit integer + * element in [31:0] of Rs1 with the 32-bit integer element in [63:32] of Rs2, and writes the result to + * [31:0] of Rd + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] - Rs2.W[0]; + * Rd.W[0] = Rs1.W[0] + Rs2.W[1]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_CRSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("crsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.3. CRSA32 ===== */ + +/* ===== Inline Function Start for 4.4. KABS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC + * \brief KABS32 (Scalar 32-bit Absolute Value with Saturation) + * \details + * **Type**: DSP (RV64 Only) +24 20 +19 15 +14 12 +11 7 +KABS32 +10010 +Rs1 +000 +Rd +6 0 +GE80B +1111111 + * + * **Syntax**:\n + * ~~~ + * KABS32 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of signed 32-bit integer elements in a general register. + * + * **Description**:\n + * This instruction calculates the absolute value of signed 32-bit integer elements stored + * in Rs1. The results are written to Rd. This instruction with the minimum negative integer input of + * 0x80000000 will produce a saturated output of maximum positive integer of 0x7fffffff and the OV + * flag will be set to 1. + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[x] >= 0) { + * res[x] = Rs1.W[x]; + * } else { + * If (Rs1.W[x] == 0x80000000) { + * res[x] = 0x7fffffff; + * OV = 1; + * } else { + * res[x] = -Rs1.W[x]; + * } + * } + * Rd.W[x] = res[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KABS32(unsigned long a) +{ + unsigned long result; + __ASM volatile("kabs32 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for 4.4. KABS32 ===== */ + +/* ===== Inline Function Start for 4.5. KADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KADD32 (SIMD 32-bit Signed Saturating Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KADD32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer elements in Rs1 with the 32-bit signed + * integer elements in Rs2. If any of the results are beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), + * they are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] + Rs2.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KADD32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kadd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.5. KADD32 ===== */ + +/* ===== Inline Function Start for 4.6. KCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KCRAS32 (SIMD 32-bit Signed Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIM (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KCRAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating addition and 32-bit signed integer element + * saturating subtraction in a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit + * integer element in [31:0] of Rs2; at the same time, it subtracts the 32-bit integer element in [63:32] of + * Rs2 from the 32-bit integer element in [31:0] of Rs1. If any of the results are beyond the Q31 number + * range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to [63:32] of Rd for addition and [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] + Rs2.W[0]; + * res[0] = Rs1.W[0] - Rs2.W[1]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KCRAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.6. KCRAS32 ===== */ + +/* ===== Inline Function Start for 4.7. KCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KCRSA32 (SIMD 32-bit Signed Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KCRSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating subtraction and 32-bit signed integer element + * saturating addition in a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. + * *Description: * + * This instruction subtracts the 32-bit integer element in [31:0] of Rs2 from the 32-bit integer element + * in [63:32] of Rs1; at the same time, it adds the 32-bit integer element in [31:0] of Rs1 with the 32-bit + * integer element in [63:32] of Rs2. If any of the results are beyond the Q31 number range (-2^31 <= Q31 + * <= 2^31-1), they are saturated to the range and the OV bit is set to 1. The saturated results are written to + * [63:32] of Rd for subtraction and [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] - Rs2.W[0]; + * res[0] = Rs1.W[0] + Rs2.W[1]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KCRSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.7. KCRSA32 ===== */ + +/* ===== Inline Function Start for 4.8.1. KDMBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMBB16 (SIMD Signed Saturating Double Multiply B16 x B16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results into the 32-bit chunks + * in the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portions in Rs2. The Q30 results are then doubled and + * saturated into Q31 values. The Q31 values are then written into the 32-bit chunks in Rd. When both + * the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated to 0x7FFFFFFF + * and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KDMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * Rd.W[z] = resQ31[z]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMBB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kdmbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.8.1. KDMBB16 ===== */ + +/* ===== Inline Function Start for 4.8.2. KDMBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMBT16 (SIMD Signed Saturating Double Multiply B16 x T16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results into the 32-bit chunks + * in the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portions in Rs2. The Q30 results are then doubled and + * saturated into Q31 values. The Q31 values are then written into the 32-bit chunks in Rd. When both + * the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated to 0x7FFFFFFF + * and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KDMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * Rd.W[z] = resQ31[z]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMBT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kdmbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.8.2. KDMBT16 ===== */ + +/* ===== Inline Function Start for 4.8.3. KDMTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMTT16 (SIMD Signed Saturating Double Multiply T16 x T16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results into the 32-bit chunks + * in the destination register. If saturation happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portions in Rs2. The Q30 results are then doubled and + * saturated into Q31 values. The Q31 values are then written into the 32-bit chunks in Rd. When both + * the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated to 0x7FFFFFFF + * and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KDMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * Rd.W[z] = resQ31[z]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMTT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kdmtt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.8.3. KDMTT16 ===== */ + +/* ===== Inline Function Start for 4.9.1. KDMABB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMABB16 (SIMD Signed Saturating Double Multiply Addition B16 x B16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMAxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results, add the results with + * the values of the corresponding 32-bit chunks from the destination register and write the saturated + * addition results back into the corresponding 32-bit chunks of the destination register. If saturation + * happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the corresponding 32-bit portions in Rs2. The Q30 results are then + * doubled and saturated into Q31 values. The Q31 values are then added with the content of the + * corresponding 32-bit portions of Rd. If the addition results are beyond the Q31 number range (-2^31 <= + * Q31 <= 2^31-1), they are saturated to the range and the OV flag is set to 1. The results after saturation + * are written back to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * // KDMABB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMABT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMATT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * resadd[z] = Rd.W[z] + resQ31[z]; + * if (resadd[z] > (2^31)-1) { + * resadd[z] = (2^31)-1; + * OV = 1; + * } else if (resadd[z] < -2^31) { + * resadd[z] = -2^31; + * OV = 1; + * } + * Rd.W[z] = resadd[z]; + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMABB16(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kdmabb16 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.9.1. KDMABB16 ===== */ + +/* ===== Inline Function Start for 4.9.2. KDMABT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMABT16 (SIMD Signed Saturating Double Multiply Addition B16 x T16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMAxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results, add the results with + * the values of the corresponding 32-bit chunks from the destination register and write the saturated + * addition results back into the corresponding 32-bit chunks of the destination register. If saturation + * happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the corresponding 32-bit portions in Rs2. The Q30 results are then + * doubled and saturated into Q31 values. The Q31 values are then added with the content of the + * corresponding 32-bit portions of Rd. If the addition results are beyond the Q31 number range (-2^31 <= + * Q31 <= 2^31-1), they are saturated to the range and the OV flag is set to 1. The results after saturation + * are written back to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * // KDMABB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMABT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMATT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * resadd[z] = Rd.W[z] + resQ31[z]; + * if (resadd[z] > (2^31)-1) { + * resadd[z] = (2^31)-1; + * OV = 1; + * } else if (resadd[z] < -2^31) { + * resadd[z] = -2^31; + * OV = 1; + * } + * Rd.W[z] = resadd[z]; + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMABT16(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kdmabt16 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.9.2. KDMABT16 ===== */ + +/* ===== Inline Function Start for 4.9.3. KDMATT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KDMATT16 (SIMD Signed Saturating Double Multiply Addition T16 x T16) + * \details + * **Type**: SIMD (RV64 only) + * + * **Syntax**:\n + * ~~~ + * KDMAxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then double and saturate the Q31 results, add the results with + * the values of the corresponding 32-bit chunks from the destination register and write the saturated + * addition results back into the corresponding 32-bit chunks of the destination register. If saturation + * happens, an overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the corresponding 32-bit portions in Rs2. The Q30 results are then + * doubled and saturated into Q31 values. The Q31 values are then added with the content of the + * corresponding 32-bit portions of Rd. If the addition results are beyond the Q31 number range (-2^31 <= + * Q31 <= 2^31-1), they are saturated to the range and the OV flag is set to 1. The results after saturation + * are written back to Rd. + * When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be + * set. + * + * **Operations**:\n + * ~~~ + * // KDMABB16: (x,y,z)=(0,0,0),(2,2,1) + * // KDMABT16: (x,y,z)=(0,1,0),(2,3,1) + * // KDMATT16: (x,y,z)=(1,1,0),(3,3,1) + * aop[z] = Rs1.H[x]; bop[z] = Rs2.H[y]; + * If (0x8000 != aop[z] | 0x8000 != bop[z]) { + * Mresult[z] = aop[z] * bop[z]; + * resQ31[z] = Mresult[z] << 1; + * } else { + * resQ31[z] = 0x7FFFFFFF; + * OV = 1; + * } + * resadd[z] = Rd.W[z] + resQ31[z]; + * if (resadd[z] > (2^31)-1) { + * resadd[z] = (2^31)-1; + * OV = 1; + * } else if (resadd[z] < -2^31) { + * resadd[z] = -2^31; + * OV = 1; + * } + * Rd.W[z] = resadd[z]; + * ~~~ + * + * \param [in] t unsigned long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KDMATT16(unsigned long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kdmatt16 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.9.3. KDMATT16 ===== */ + +/* ===== Inline Function Start for 4.10.1. KHMBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KHMBB16 (SIMD Signed Saturating Half Multiply B16 x B16) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KHMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then right-shift 15 bits to turn the Q30 results into Q15 + * numbers again and saturate the Q15 results into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portion in Rs2. The Q30 results are then right-shifted 15- + * bits and saturated into Q15 values. The 32-bit Q15 values are then written into the 32-bit chunks in + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KHMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KHMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KHMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop = Rs1.H[x]; bop = Rs2.H[y]; + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd.W[z] = SE32(res[15:0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHMBB16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khmbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.10.1. KHMBB16 ===== */ + +/* ===== Inline Function Start for 4.10.2. KHMBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KHMBT16 (SIMD Signed Saturating Half Multiply B16 x T16) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KHMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then right-shift 15 bits to turn the Q30 results into Q15 + * numbers again and saturate the Q15 results into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portion in Rs2. The Q30 results are then right-shifted 15- + * bits and saturated into Q15 values. The 32-bit Q15 values are then written into the 32-bit chunks in + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KHMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KHMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KHMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop = Rs1.H[x]; bop = Rs2.H[y]; + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd.W[z] = SE32(res[15:0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHMBT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khmbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.10.2. KHMBT16 ===== */ + +/* ===== Inline Function Start for 4.10.3. KHMTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_Q15_SAT_MULT + * \brief KHMTT16 (SIMD Signed Saturating Half Multiply T16 x T16) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KHMxy16 Rd, Rs1, Rs2 (xy = BB, BT, TT) + * ~~~ + * + * **Purpose**:\n + * Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion + * of the 32-bit chunks in registers and then right-shift 15 bits to turn the Q30 results into Q15 + * numbers again and saturate the Q15 results into the destination register. If saturation happens, an + * overflow flag OV will be set. + * + * **Description**:\n + * Multiply the top or bottom 16-bit Q15 content of the 32-bit portions in Rs1 with the top + * or bottom 16-bit Q15 content of the 32-bit portion in Rs2. The Q30 results are then right-shifted 15- + * bits and saturated into Q15 values. The 32-bit Q15 values are then written into the 32-bit chunks in + * Rd. When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated + * to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * // KHMBB16: (x,y,z)=(0,0,0),(2,2,1) + * // KHMBT16: (x,y,z)=(0,1,0),(2,3,1) + * // KHMTT16: (x,y,z)=(1,1,0),(3,3,1) + * aop = Rs1.H[x]; bop = Rs2.H[y]; + * If (0x8000 != aop | 0x8000 != bop) { + * Mresult[31:0] = aop * bop; + * res[15:0] = Mresult[30:15]; + * } else { + * res[15:0] = 0x7FFF; + * OV = 1; + * } + * Rd.W[z] = SE32(res[15:0]); + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KHMTT16(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("khmtt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.10.3. KHMTT16 ===== */ + +/* ===== Inline Function Start for 4.11.1. KMABB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT_ADD + * \brief KMABB32 (Saturating Signed Multiply Bottom Words & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMABB32 Rd, Rs1, Rs2 + * KMABT32 Rd, Rs1, Rs2 + * KMATT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register + * and add the result to the content of 64-bit data in the third register. The addition result may be + * saturated and is written to the third register. + * * KMABB32: rd + bottom*bottom + * * KMABT32: rd + bottom*top + * * KMATT32: rd + top*top + * + * **Description**:\n + * For the `KMABB32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2. + * For the `KMABT32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * For the `KMATT32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond + * the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The + * result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[0] * Rs2.W[0]); // KMABB32 + * res = Rd + (Rs1.W[0] * Rs2.W[1]); // KMABT32 + * res = Rd + (Rs1.W[1] * Rs2.W[1]); // KMATT32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * *Exceptions:* None + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMABB32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmabb32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.11.1. KMABB32 ===== */ + +/* ===== Inline Function Start for 4.11.2. KMABT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT_ADD + * \brief KMABT32 (Saturating Signed Multiply Bottom & Top Words & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMABB32 Rd, Rs1, Rs2 + * KMABT32 Rd, Rs1, Rs2 + * KMATT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register + * and add the result to the content of 64-bit data in the third register. The addition result may be + * saturated and is written to the third register. + * * KMABB32: rd + bottom*bottom + * * KMABT32: rd + bottom*top + * * KMATT32: rd + top*top + * + * **Description**:\n + * For the `KMABB32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2. + * For the `KMABT32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * For the `KMATT32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond + * the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The + * result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[0] * Rs2.W[0]); // KMABB32 + * res = Rd + (Rs1.W[0] * Rs2.W[1]); // KMABT32 + * res = Rd + (Rs1.W[1] * Rs2.W[1]); // KMATT32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * *Exceptions:* None + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMABT32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmabt32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.11.2. KMABT32 ===== */ + +/* ===== Inline Function Start for 4.11.3. KMATT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT_ADD + * \brief KMATT32 (Saturating Signed Multiply Top Words & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMABB32 Rd, Rs1, Rs2 + * KMABT32 Rd, Rs1, Rs2 + * KMATT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register + * and add the result to the content of 64-bit data in the third register. The addition result may be + * saturated and is written to the third register. + * * KMABB32: rd + bottom*bottom + * * KMABT32: rd + bottom*top + * * KMATT32: rd + top*top + * + * **Description**:\n + * For the `KMABB32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2. + * For the `KMABT32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * For the `KMATT32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2. + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond + * the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The + * result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[0] * Rs2.W[0]); // KMABB32 + * res = Rd + (Rs1.W[0] * Rs2.W[1]); // KMABT32 + * res = Rd + (Rs1.W[1] * Rs2.W[1]); // KMATT32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * *Exceptions:* None + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMATT32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmatt32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.11.3. KMATT32 ===== */ + +/* ===== Inline Function Start for 4.12.1. KMADA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMADA32 (Saturating Signed Multiply Two Words and Two Adds) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMADA32 Rd, Rs1, Rs2 + * KMAXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from 32-bit data in two registers; and then adds the + * two 64-bit results and 64-bit data in a third register together. The addition result may be saturated. + * * KMADA32: rd + top*top + bottom*bottom + * * KMAXDA32: rd + top*bottom + bottom*top + * + * **Description**:\n + * For the `KMADA32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32- + * bit element in Rs2 and then adds the result to the result of multiplying the top 32-bit element in Rs1 + * with the top 32-bit element in Rs2. It is actually an alias of the `KMAR64` instruction. + * For the `KMAXDA32` instruction, it multiplies the top 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then adds the result to the result of multiplying the bottom 32-bit element in Rs1 + * with the top 32-bit element in Rs2. + * The result is added to the content of 64-bit data in Rd. If the addition result is beyond the Q63 + * number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The 64-bit + * result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.w[1]) + (Rs1.W[0] * Rs2.W[0]); // KMADA32 + * res = Rd + (Rs1.W[1] * Rs2.W[0]) + (Rs1.W[0] * Rs2.W[1]); // KMAXDA32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADA32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmada32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.12.1. KMADA32 ===== */ + +/* ===== Inline Function Start for 4.12.2. KMAXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMAXDA32 (Saturating Signed Crossed Multiply Two Words and Two Adds) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMADA32 Rd, Rs1, Rs2 + * KMAXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from 32-bit data in two registers; and then adds the + * two 64-bit results and 64-bit data in a third register together. The addition result may be saturated. + * * KMADA32: rd + top*top + bottom*bottom + * * KMAXDA32: rd + top*bottom + bottom*top + * + * **Description**:\n + * For the `KMADA32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32- + * bit element in Rs2 and then adds the result to the result of multiplying the top 32-bit element in Rs1 + * with the top 32-bit element in Rs2. It is actually an alias of the `KMAR64` instruction. + * For the `KMAXDA32` instruction, it multiplies the top 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then adds the result to the result of multiplying the bottom 32-bit element in Rs1 + * with the top 32-bit element in Rs2. + * The result is added to the content of 64-bit data in Rd. If the addition result is beyond the Q63 + * number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The 64-bit + * result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.w[1]) + (Rs1.W[0] * Rs2.W[0]); // KMADA32 + * res = Rd + (Rs1.W[1] * Rs2.W[0]) + (Rs1.W[0] * Rs2.W[1]); // KMAXDA32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMAXDA32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmaxda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.12.2. KMAXDA32 ===== */ + +/* ===== Inline Function Start for 4.13.1. KMDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMDA32 (Signed Multiply Two Words and Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMDA32 Rd, Rs1, Rs2 + * KMXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the 32-bit element of two registers; and then + * adds the two 64-bit results together. The addition result may be saturated. + * * KMDA32: top*top + bottom*bottom + * * KMXDA32: top*bottom + bottom*top + * + * **Description**:\n + * For the `KMDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the top 32-bit element of Rs2. + * For the `KMXDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the bottom 32-bit element of Rs2. + * The addition result is checked for saturation. If saturation happens, the result is saturated to 2^63-1. + * The final result is written to Rd. The 32-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * if ((Rs1 != 0x8000000080000000) or (Rs2 != 0x8000000080000000)) { + * Rd = (Rs1.W[1] * Rs2.W[1]) + (Rs1.W[0] * Rs2.W[0]); // KMDA32 + * Rd = (Rs1.W[1] * Rs2.W[0]) + (Rs1.W[0] * Rs2.W[1]); // KMXDA32 + * } else { + * Rd = 0x7fffffffffffffff; + * OV = 1; + * } + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMDA32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("kmda32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.13.1. KMDA32 ===== */ + +/* ===== Inline Function Start for 4.13.2. KMXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMXDA32 (Signed Crossed Multiply Two Words and Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMDA32 Rd, Rs1, Rs2 + * KMXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the 32-bit element of two registers; and then + * adds the two 64-bit results together. The addition result may be saturated. + * * KMDA32: top*top + bottom*bottom + * * KMXDA32: top*bottom + bottom*top + * + * **Description**:\n + * For the `KMDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the top 32-bit element of Rs2. + * For the `KMXDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the bottom 32-bit element of Rs2. + * The addition result is checked for saturation. If saturation happens, the result is saturated to 2^63-1. + * The final result is written to Rd. The 32-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * if ((Rs1 != 0x8000000080000000) or (Rs2 != 0x8000000080000000)) { + * Rd = (Rs1.W[1] * Rs2.W[1]) + (Rs1.W[0] * Rs2.W[0]); // KMDA32 + * Rd = (Rs1.W[1] * Rs2.W[0]) + (Rs1.W[0] * Rs2.W[1]); // KMXDA32 + * } else { + * Rd = 0x7fffffffffffffff; + * OV = 1; + * } + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMXDA32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("kmxda32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.13.2. KMXDA32 ===== */ + +/* ===== Inline Function Start for 4.14.1. KMADS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMADS32 (Saturating Signed Multiply Two Words & Subtract & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMADS32 Rd, Rs1, Rs2 + * KMADRS32 Rd, Rs1, Rs2 + * KMAXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 64-bit results. Then add the subtraction result to + * 64-bit data in a third register. The addition result may be saturated. + * * KMADS32: rd + (top*top - bottom*bottom) + * * KMADRS32: rd + (bottom*bottom - top*top) + * * KMAXDS32: rd + (top*bottom - bottom*top) + * + * **Description**:\n + * For the `KMADS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the top 32-bit element in Rs2. + * For the `KMADRS32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element in Rs1 with the bottom 32-bit element in Rs2. + * For the `KMAXDS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the bottom 32-bit element in Rs2. + * The subtraction result is then added to the content of 64-bit data in Rd. If the addition result is + * beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to + * 1. The 64-bit result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated + * as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // KMADS32 + * res = Rd + (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // KMADRS32 + * res = Rd + (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // KMAXDS32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADS32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmads32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.14.1. KMADS32 ===== */ + +/* ===== Inline Function Start for 4.14.2. KMADRS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMADRS32 (Saturating Signed Multiply Two Words & Reverse Subtract & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMADS32 Rd, Rs1, Rs2 + * KMADRS32 Rd, Rs1, Rs2 + * KMAXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 64-bit results. Then add the subtraction result to + * 64-bit data in a third register. The addition result may be saturated. + * * KMADS32: rd + (top*top - bottom*bottom) + * * KMADRS32: rd + (bottom*bottom - top*top) + * * KMAXDS32: rd + (top*bottom - bottom*top) + * + * **Description**:\n + * For the `KMADS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the top 32-bit element in Rs2. + * For the `KMADRS32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element in Rs1 with the bottom 32-bit element in Rs2. + * For the `KMAXDS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the bottom 32-bit element in Rs2. + * The subtraction result is then added to the content of 64-bit data in Rd. If the addition result is + * beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to + * 1. The 64-bit result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated + * as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // KMADS32 + * res = Rd + (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // KMADRS32 + * res = Rd + (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // KMAXDS32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMADRS32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmadrs32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.14.2. KMADRS32 ===== */ + +/* ===== Inline Function Start for 4.14.3. KMAXDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMAXDS32 (Saturating Signed Crossed Multiply Two Words & Subtract & Add) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMADS32 Rd, Rs1, Rs2 + * KMADRS32 Rd, Rs1, Rs2 + * KMAXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 64-bit results. Then add the subtraction result to + * 64-bit data in a third register. The addition result may be saturated. + * * KMADS32: rd + (top*top - bottom*bottom) + * * KMADRS32: rd + (bottom*bottom - top*top) + * * KMAXDS32: rd + (top*bottom - bottom*top) + * + * **Description**:\n + * For the `KMADS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the top 32-bit element in Rs2. + * For the `KMADRS32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element in Rs1 with the bottom 32-bit element in Rs2. + * For the `KMAXDS32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the bottom 32-bit element in Rs2. + * The subtraction result is then added to the content of 64-bit data in Rd. If the addition result is + * beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to + * 1. The 64-bit result after saturation is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated + * as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // KMADS32 + * res = Rd + (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // KMADRS32 + * res = Rd + (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // KMAXDS32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMAXDS32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmaxds32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.14.3. KMAXDS32 ===== */ + +/* ===== Inline Function Start for 4.15.1. KMSDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMSDA32 (Saturating Signed Multiply Two Words & Add & Subtract) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMSDA32 Rd, Rs1, Rs2 + * KMSXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the 32-bit element of two registers; and then + * subtracts the two 64-bit results from a third register. The subtraction result may be saturated. + * * KMSDA: rd - top*top - bottom*bottom + * * KMSXDA: rd - top*bottom - bottom*top + * + * **Description**:\n + * For the `KMSDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. + * For the `KMSXDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the bottom 32-bit element of Rs2. + * The two 64-bit multiplication results are then subtracted from the content of Rd. If the subtraction + * result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit + * is set to 1. The result after saturation is written to Rd. The 32-bit contents are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * res = Rd - (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // KMSDA32 + * res = Rd - (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // KMSXDA32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMSDA32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmsda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.15.1. KMSDA32 ===== */ + +/* ===== Inline Function Start for 4.15.2. KMSXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief KMSXDA32 (Saturating Signed Crossed Multiply Two Words & Add & Subtract) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KMSDA32 Rd, Rs1, Rs2 + * KMSXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the 32-bit element of two registers; and then + * subtracts the two 64-bit results from a third register. The subtraction result may be saturated. + * * KMSDA: rd - top*top - bottom*bottom + * * KMSXDA: rd - top*bottom - bottom*top + * + * **Description**:\n + * For the `KMSDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. + * For the `KMSXDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the bottom 32-bit element of Rs2. + * The two 64-bit multiplication results are then subtracted from the content of Rd. If the subtraction + * result is beyond the Q63 number range (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit + * is set to 1. The result after saturation is written to Rd. The 32-bit contents are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * res = Rd - (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // KMSDA32 + * res = Rd - (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // KMSXDA32 + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long type of value stored in t + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_KMSXDA32(long t, unsigned long a, unsigned long b) +{ + __ASM volatile("kmsxda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for 4.15.2. KMSXDA32 ===== */ + +/* ===== Inline Function Start for 4.16. KSLL32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief KSLL32 (SIMD 32-bit Saturating Shift Left Logical) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSLL32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is a variable from a GPR. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the low-order 5-bits of the value in the Rs2 register. + * Any shifted value greater than 2^31-1 is saturated to 2^31-1. Any shifted value smaller than -2^31 is + * saturated to -2^31. And the saturated results are written to Rd. If any saturation is performed, set OV + * bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * if (sa != 0) { + * res[(31+sa):0] = Rs1.W[x] << sa; + * if (res > (2^31)-1) { + * res = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res = 0x80000000; OV = 1; + * } + * Rd.W[x] = res[31:0]; + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLL32(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("ksll32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.16. KSLL32 ===== */ + +/* ===== Inline Function Start for 4.17. KSLLI32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief KSLLI32 (SIMD 32-bit Saturating Shift Left Logical Immediate) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSLLI32 Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical left shift operations with saturation simultaneously. The shift + * amount is an immediate value. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are left-shifted logically. The shifted out bits are filled + * with zero and the shift amount is specified by the imm5u constant. Any shifted value greater than + * 2^31-1 is saturated to 2^31-1. Any shifted value smaller than -2^31 is saturated to -2^31. And the saturated + * results are written to Rd. If any saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * if (sa != 0) { + * res[(31+sa):0] = Rs1.W[x] << sa; + * if (res > (2^31)-1) { + * res = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res = 0x80000000; OV = 1; + * } + * Rd.W[x] = res[31:0]; + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_KSLLI32(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("kslli32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.17. KSLLI32 ===== */ + +/* ===== Inline Function Start for 4.18.1. KSLRA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief KSLRA32 (SIMD 32-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSLRA32 Rd, Rs1, Rs2 + * KSLRA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q31 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 32-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[5:0]. Rs2[5:0] is in the signed range of [-25, 25-1]. A positive Rs2[5:0] means + * logical left shift and a negative Rs2[5:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[5:0]. However, the behavior of `Rs2[5:0]==-25 (0x20)` is defined to be + * equivalent to the behavior of `Rs2[5:0]==-(25-1) (0x21)`. + * The left-shifted results are saturated to the 32-bit signed integer range of [-2^31, 2^31-1]. For the `.u` + * form of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:6] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[5:0] < 0) { + * sa = -Rs2[5:0]; + * sa = (sa == 32)? 31 : sa; + * if (`.u` form) { + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * } else { + * Rd.W[x] = SE32(Rs1.W[x][31:sa]); + * } + * } else { + * sa = Rs2[4:0]; + * res[(31+sa):0] = Rs1.W[x] <<(logic) sa; + * if (res > (2^31)-1) { + * res[31:0] = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res[31:0] = 0x80000000; OV = 1; + * } + * Rd.W[x] = res[31:0]; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA32(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.18.1. KSLRA32 ===== */ + +/* ===== Inline Function Start for 4.18.2. KSLRA32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief KSLRA32.u (SIMD 32-bit Shift Left Logical with Saturation or Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSLRA32 Rd, Rs1, Rs2 + * KSLRA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q31 saturation for the left shift. The `.u` form performs additional rounding up operations for the + * right shift. + * + * **Description**:\n + * The 32-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[5:0]. Rs2[5:0] is in the signed range of [-25, 25-1]. A positive Rs2[5:0] means + * logical left shift and a negative Rs2[5:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[5:0]. However, the behavior of `Rs2[5:0]==-25 (0x20)` is defined to be + * equivalent to the behavior of `Rs2[5:0]==-(25-1) (0x21)`. + * The left-shifted results are saturated to the 32-bit signed integer range of [-2^31, 2^31-1]. For the `.u` + * form of the instruction, the right-shifted results are added a 1 to the most significant discarded bit + * position for rounding effect. After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:6] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[5:0] < 0) { + * sa = -Rs2[5:0]; + * sa = (sa == 32)? 31 : sa; + * if (`.u` form) { + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * } else { + * Rd.W[x] = SE32(Rs1.W[x][31:sa]); + * } + * } else { + * sa = Rs2[4:0]; + * res[(31+sa):0] = Rs1.W[x] <<(logic) sa; + * if (res > (2^31)-1) { + * res[31:0] = 0x7fffffff; OV = 1; + * } else if (res < -2^31) { + * res[31:0] = 0x80000000; OV = 1; + * } + * Rd.W[x] = res[31:0]; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSLRA32_U(unsigned long a, int b) +{ + unsigned long result; + __ASM volatile("kslra32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.18.2. KSLRA32.u ===== */ + +/* ===== Inline Function Start for 4.19. KSTAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KSTAS32 (SIMD 32-bit Signed Saturating Straight Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSTAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating addition and 32-bit signed integer element + * saturating subtraction in a 64-bit chunk simultaneously. Operands are from corresponding 32-bit + * elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit + * integer element in [63:32] of Rs2; at the same time, it subtracts the 32-bit integer element in [31:0] of + * Rs2 from the 32-bit integer element in [31:0] of Rs1. If any of the results are beyond the Q31 number + * range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to [63:32] of Rd for addition and [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] + Rs2.W[1]; + * res[0] = Rs1.W[0] - Rs2.W[0]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSTAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kstas32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.19. KSTAS32 ===== */ + +/* ===== Inline Function Start for 4.20. KSTSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KSTSA32 (SIMD 32-bit Signed Saturating Straight Subtraction & Addition) + * \details + * **Type**: SIM (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSTSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating subtraction and 32-bit signed integer element + * saturating addition in a 64-bit chunk simultaneously. Operands are from corresponding 32-bit + * elements. + * *Description: * + * This instruction subtracts the 32-bit integer element in [63:32] of Rs2 from the 32-bit integer + * element in [63:32] of Rs1; at the same time, it adds the 32-bit integer element in [31:0] of Rs1 with + * the 32-bit integer element in [31:0] of Rs2. If any of the results are beyond the Q31 number range ( + * -2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV bit is set to 1. The saturated results are + * written to [63:32] of Rd for subtraction and [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] - Rs2.W[1]; + * res[0] = Rs1.W[0] + Rs2.W[0]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * for RV64, x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSTSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("kstsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.20. KSTSA32 ===== */ + +/* ===== Inline Function Start for 4.21. KSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief KSUB32 (SIMD 32-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * KSUB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer elements in Rs2 from the 32-bit + * signed integer elements in Rs1. If any of the results are beyond the Q31 number range (-2^31 <= Q31 <= + * 2^31-1), they are saturated to the range and the OV bit is set to 1. The saturated results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] - Rs2.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_KSUB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ksub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.21. KSUB32 ===== */ + +/* ===== Inline Function Start for 4.22.1. PKBB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PACK + * \brief PKBB32 (Pack Two 32-bit Data from Both Bottom Half) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * PKBB32 Rd, Rs1, Rs2 + * PKBT32 Rd, Rs1, Rs2 + * PKTT32 Rd, Rs1, Rs2 + * PKTB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * PKBB32: bottom.bottom + * * PKBT32: bottom.top + * * PKTT32: top.top + * * PKTB32: top.bottom + * + * **Description**:\n + * (PKBB32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * (PKBT32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTT32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTB32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*0*_]); // PKBB32 + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*1*_]); // PKBT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*1*_]); // PKTT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*0*_]); // PKTB32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKBB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pkbb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.22.1. PKBB32 ===== */ + +/* ===== Inline Function Start for 4.22.2. PKBT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PACK + * \brief PKBT32 (Pack Two 32-bit Data from Bottom and Top Half) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * PKBB32 Rd, Rs1, Rs2 + * PKBT32 Rd, Rs1, Rs2 + * PKTT32 Rd, Rs1, Rs2 + * PKTB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * PKBB32: bottom.bottom + * * PKBT32: bottom.top + * * PKTT32: top.top + * * PKTB32: top.bottom + * + * **Description**:\n + * (PKBB32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * (PKBT32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTT32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTB32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*0*_]); // PKBB32 + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*1*_]); // PKBT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*1*_]); // PKTT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*0*_]); // PKTB32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKBT32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pkbt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.22.2. PKBT32 ===== */ + +/* ===== Inline Function Start for 4.22.3. PKTT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PACK + * \brief PKTT32 (Pack Two 32-bit Data from Both Top Half) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * PKBB32 Rd, Rs1, Rs2 + * PKBT32 Rd, Rs1, Rs2 + * PKTT32 Rd, Rs1, Rs2 + * PKTB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * PKBB32: bottom.bottom + * * PKBT32: bottom.top + * * PKTT32: top.top + * * PKTB32: top.bottom + * + * **Description**:\n + * (PKBB32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * (PKBT32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTT32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTB32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*0*_]); // PKBB32 + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*1*_]); // PKBT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*1*_]); // PKTT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*0*_]); // PKTB32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKTT32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pktt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.22.3. PKTT32 ===== */ + +/* ===== Inline Function Start for 4.22.4. PKTB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PACK + * \brief PKTB32 (Pack Two 32-bit Data from Top and Bottom Half) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * PKBB32 Rd, Rs1, Rs2 + * PKBT32 Rd, Rs1, Rs2 + * PKTT32 Rd, Rs1, Rs2 + * PKTB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * PKBB32: bottom.bottom + * * PKBT32: bottom.top + * * PKTT32: top.top + * * PKTB32: top.bottom + * + * **Description**:\n + * (PKBB32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * (PKBT32) moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTT32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * (PKTB32) moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*0*_]); // PKBB32 + * Rd = CONCAT(Rs1.W[_*0*_], Rs2.W[_*1*_]); // PKBT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*1*_]); // PKTT32 + * Rd = CONCAT(Rs1.W[_*1*_], Rs2.W[_*0*_]); // PKTB32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_PKTB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("pktb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.22.4. PKTB32 ===== */ + +/* ===== Inline Function Start for 4.23. RADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RADD32 (SIMD 32-bit Signed Halving Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RADD32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element additions simultaneously. The results are halved to avoid + * overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer elements in Rs1 with the 32-bit signed + * integer elements in Rs2. The results are first arithmetically right-shifted by 1 bit and then written to + * Rd. + * + * **Examples**:\n + * ~~~ + * * Rs1 = 0x7FFFFFFF, Rs2 = 0x7FFFFFFF Rd = 0x7FFFFFFF + * * Rs1 = 0x80000000, Rs2 = 0x80000000 Rd = 0x80000000 + * * Rs1 = 0x40000000, Rs2 = 0x80000000 Rd = 0xE0000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] + Rs2.W[x]) s>> 1; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RADD32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("radd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.23. RADD32 ===== */ + +/* ===== Inline Function Start for 4.24. RCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RCRAS32 (SIMD 32-bit Signed Halving Cross Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RCRAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element addition and 32-bit signed integer element subtraction in + * a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer element in [63:32] of Rs1 with the 32-bit + * signed integer element in [31:0] of Rs2, and subtracts the 32-bit signed integer element in [63:32] of + * Rs2 from the 32-bit signed integer element in [31:0] of Rs1. The element results are first + * arithmetically right-shifted by 1 bit and then written to [63:32] of Rd for addition and [31:0] of Rd + * for subtraction. + * + * **Examples**:\n + * ~~~ + * Please see `RADD32` and `RSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] + Rs2.W[0]) s>> 1; + * Rd.W[0] = (Rs1.W[0] - Rs2.W[1]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RCRAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.24. RCRAS32 ===== */ + +/* ===== Inline Function Start for 4.25. RCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RCRSA32 (SIMD 32-bit Signed Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RCRSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element subtraction and 32-bit signed integer element addition in + * a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer element in [31:0] of Rs2 from the + * 32-bit signed integer element in [63:32] of Rs1, and adds the 32-bit signed element integer in [31:0] + * of Rs1 with the 32-bit signed integer element in [63:32] of Rs2. The two results are first + * arithmetically right-shifted by 1 bit and then written to [63:32] of Rd for subtraction and [31:0] of + * Rd for addition. + * + * **Examples**:\n + * ~~~ + * Please see `RADD32` and `RSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] - Rs2.W[0]) s>> 1; + * Rd.W[0] = (Rs1.W[0] + Rs2.W[1]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RCRSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.25. RCRSA32 ===== */ + +/* ===== Inline Function Start for 4.26. RSTAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RSTAS32 (SIMD 32-bit Signed Halving Straight Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RSTAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element addition and 32-bit signed integer element subtraction in + * a 64-bit chunk simultaneously. Operands are from corresponding 32-bit elements. The results are + * halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer element in [63:32] of Rs1 with the 32-bit + * signed integer element in [63:32] of Rs2, and subtracts the 32-bit signed integer element in [31:0] of + * Rs2 from the 32-bit signed integer element in [31:0] of Rs1. The element results are first + * arithmetically right-shifted by 1 bit and then written to [63:32] of Rd for addition and [31:0] of Rd + * for subtraction. + * + * **Examples**:\n + * ~~~ + * Please see `RADD32` and `RSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] + Rs2.W[1]) s>> 1; + * Rd.W[0] = (Rs1.W[0] - Rs2.W[0]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSTAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rstas32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.26. RSTAS32 ===== */ + +/* ===== Inline Function Start for 4.27. RSTSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RSTSA32 (SIMD 32-bit Signed Halving Straight Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RSTSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element subtraction and 32-bit signed integer element addition in + * a 64-bit chunk simultaneously. Operands are from corresponding 32-bit elements. The results are + * halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer element in [63:32] of Rs2 from the + * 32-bit signed integer element in [63:32] of Rs1, and adds the 32-bit signed element integer in [31:0] + * of Rs1 with the 32-bit signed integer element in [31:0] of Rs2. The two results are first arithmetically + * right-shifted by 1 bit and then written to [63:32] of Rd for subtraction and [31:0] of Rd for addition. + * + * **Examples**:\n + * ~~~ + * Please see `RADD32` and `RSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] - Rs2.W[1]) s>> 1; + * Rd.W[0] = (Rs1.W[0] + Rs2.W[0]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSTSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rstsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.27. RSTSA32 ===== */ + +/* ===== Inline Function Start for 4.28. RSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief RSUB32 (SIMD 32-bit Signed Halving Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * RSUB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer elements in Rs2 from the 32-bit + * signed integer elements in Rs1. The results are first arithmetically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFFFFFF, Rb = 0x80000000 Rt = 0x7FFFFFFF + * * Ra = 0x80000000, Rb = 0x7FFFFFFF Rt = 0x80000000 + * * Ra = 0x80000000, Rb = 0x40000000 Rt = 0xA0000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] - Rs2.W[x]) s>> 1; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_RSUB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("rsub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.28. RSUB32 ===== */ + +/* ===== Inline Function Start for 4.29. SLL32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SLL32 (SIMD 32-bit Shift Left Logical) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SLL32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical left shift operations simultaneously. The shift amount is a + * variable from a GPR. + * + * **Description**:\n + * The 32-bit elements in Rs1 are left-shifted logically. And the results are written to Rd. + * The shifted out bits are filled with zero and the shift amount is specified by the low-order 5-bits of + * the value in the Rs2 register. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * Rd.W[x] = Rs1.W[x] << sa; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SLL32(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sll32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.29. SLL32 ===== */ + +/* ===== Inline Function Start for 4.30. SLLI32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SLLI32 (SIMD 32-bit Shift Left Logical Immediate) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SLLI32 Rd, Rs1, imm5u[4:0] + * ~~~ + * + * **Purpose**:\n + * Do 32-bit element logical left shift operations simultaneously. The shift amount is an + * immediate value. + * + * **Description**:\n + * The 32-bit elements in Rs1 are left-shifted logically. The shifted out bits are filled with + * zero and the shift amount is specified by the imm5u[4:0] constant. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * Rd.W[x] = Rs1.W[x] << sa; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SLLI32(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("slli32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.30. SLLI32 ===== */ + +/* ===== Inline Function Start for 4.31. SMAX32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC + * \brief SMAX32 (SIMD 32-bit Signed Maximum) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMAX32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 32-bit signed integer elements in Rs1 with the 32-bit + * signed integer elements in Rs2 and selects the numbers that is greater than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] > Rs2.W[x])? Rs1.W[x] : Rs2.W[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMAX32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smax32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.31. SMAX32 ===== */ + +/* ===== Inline Function Start for 4.32.1. SMBB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT + * \brief SMBB32 (Signed Multiply Bottom Word & Bottom Word) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMBB32 Rd, Rs1, Rs2 + * SMBT32 Rd, Rs1, Rs2 + * SMTT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another + * register and write the 64-bit result to a third register. + * * SMBB32: bottom*bottom + * * SMBT32: bottom*top + * * SMTT32: top*top + * + * **Description**:\n + * For the `SMBB32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2. It is actually an alias of `MULSR64` instruction. + * For the `SMBT32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2. + * For the `SMTT32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit element + * of Rs2. + * The 64-bit multiplication result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[0] * Rs2.W[0]; // SMBB32 res = Rs1.W[0] * Rs2.w[1]; // SMBT32 res = Rs1.W[1] * Rs2.W[1]; + * // SMTT32 Rd = res; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMBB32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smbb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.32.1. SMBB32 ===== */ + +/* ===== Inline Function Start for 4.32.2. SMBT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT + * \brief SMBT32 (Signed Multiply Bottom Word & Top Word) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMBB32 Rd, Rs1, Rs2 + * SMBT32 Rd, Rs1, Rs2 + * SMTT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another + * register and write the 64-bit result to a third register. + * * SMBB32: bottom*bottom + * * SMBT32: bottom*top + * * SMTT32: top*top + * + * **Description**:\n + * For the `SMBB32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2. It is actually an alias of `MULSR64` instruction. + * For the `SMBT32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2. + * For the `SMTT32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit element + * of Rs2. + * The 64-bit multiplication result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[0] * Rs2.W[0]; // SMBB32 res = Rs1.W[0] * Rs2.w[1]; // SMBT32 res = Rs1.W[1] * Rs2.W[1]; + * // SMTT32 Rd = res; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMBT32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smbt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.32.2. SMBT32 ===== */ + +/* ===== Inline Function Start for 4.32.3. SMTT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_MULT + * \brief SMTT32 (Signed Multiply Top Word & Top Word) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMBB32 Rd, Rs1, Rs2 + * SMBT32 Rd, Rs1, Rs2 + * SMTT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another + * register and write the 64-bit result to a third register. + * * SMBB32: bottom*bottom + * * SMBT32: bottom*top + * * SMTT32: top*top + * + * **Description**:\n + * For the `SMBB32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2. It is actually an alias of `MULSR64` instruction. + * For the `SMBT32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2. + * For the `SMTT32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit element + * of Rs2. + * The 64-bit multiplication result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as + * signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[0] * Rs2.W[0]; // SMBB32 res = Rs1.W[0] * Rs2.w[1]; // SMBT32 res = Rs1.W[1] * Rs2.W[1]; + * // SMTT32 Rd = res; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMTT32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smtt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.32.3. SMTT32 ===== */ + +/* ===== Inline Function Start for 4.33.1. SMDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief SMDS32 (Signed Multiply Two Words and Subtract) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMDS32 Rd, Rs1, Rs2 + * SMDRS32 Rd, Rs1, Rs2 + * SMXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the l 32-bit element of two registers; and then + * perform a subtraction operation between the two 64-bit results. + * * SMDS32: top*top - bottom*bottom + * * SMDRS32: bottom*bottom - top*top + * * SMXDS32: top*bottom - bottom*top + * + * **Description**:\n + * For the `SMDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the top 32-bit element of Rs2. + * For the `SMDRS32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element of Rs1 with the bottom 32-bit element of Rs2. + * For the `SMXDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the bottom 32-bit element of Rs2. + * The subtraction result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rt = (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // SMDS32 + * Rt = (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // SMDRS32 + * Rt = (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // SMXDS32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMDS32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smds32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.33.1. SMDS32 ===== */ + +/* ===== Inline Function Start for 4.33.2. SMDRS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief SMDRS32 (Signed Multiply Two Words and Reverse Subtract) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMDS32 Rd, Rs1, Rs2 + * SMDRS32 Rd, Rs1, Rs2 + * SMXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the l 32-bit element of two registers; and then + * perform a subtraction operation between the two 64-bit results. + * * SMDS32: top*top - bottom*bottom + * * SMDRS32: bottom*bottom - top*top + * * SMXDS32: top*bottom - bottom*top + * + * **Description**:\n + * For the `SMDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the top 32-bit element of Rs2. + * For the `SMDRS32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element of Rs1 with the bottom 32-bit element of Rs2. + * For the `SMXDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the bottom 32-bit element of Rs2. + * The subtraction result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rt = (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // SMDS32 + * Rt = (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // SMDRS32 + * Rt = (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // SMXDS32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMDRS32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smdrs32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.33.2. SMDRS32 ===== */ + +/* ===== Inline Function Start for 4.33.3. SMXDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_32B_PARALLEL_MAC + * \brief SMXDS32 (Signed Crossed Multiply Two Words and Subtract) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMDS32 Rd, Rs1, Rs2 + * SMDRS32 Rd, Rs1, Rs2 + * SMXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the l 32-bit element of two registers; and then + * perform a subtraction operation between the two 64-bit results. + * * SMDS32: top*top - bottom*bottom + * * SMDRS32: bottom*bottom - top*top + * * SMXDS32: top*bottom - bottom*top + * + * **Description**:\n + * For the `SMDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the top 32-bit element of Rs2. + * For the `SMDRS32` instruction, it multiplies the top 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element of Rs1 with the bottom 32-bit element of Rs2. + * For the `SMXDS32` instruction, it multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the bottom 32-bit element of Rs2. + * The subtraction result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed + * integers. + * + * **Operations**:\n + * ~~~ + * Rt = (Rs1.W[1] * Rs2.W[1]) - (Rs1.W[0] * Rs2.W[0]); // SMDS32 + * Rt = (Rs1.W[0] * Rs2.W[0]) - (Rs1.W[1] * Rs2.W[1]); // SMDRS32 + * Rt = (Rs1.W[1] * Rs2.W[0]) - (Rs1.W[0] * Rs2.W[1]); // SMXDS32 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_SMXDS32(unsigned long a, unsigned long b) +{ + long result; + __ASM volatile("smxds32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.33.3. SMXDS32 ===== */ + +/* ===== Inline Function Start for 4.34. SMIN32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC + * \brief SMIN32 (SIMD 32-bit Signed Minimum) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SMIN32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer elements finding minimum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 32-bit signed integer elements in Rs1 with the 32-bit + * signed integer elements in Rs2 and selects the numbers that is less than the other one. The selected + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] < Rs2.W[x])? Rs1.W[x] : Rs2.W[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SMIN32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("smin32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.34. SMIN32 ===== */ + +/* ===== Inline Function Start for 4.35.1. SRA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRA32 (SIMD 32-bit Shift Right Arithmetic) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRA32 Rd, Rs1, Rs2 + * SRA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 5-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 32-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA32.u + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRA32 + * Rd.W[x] = SE32(Rs1.W[x][31:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA32(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.35.1. SRA32 ===== */ + +/* ===== Inline Function Start for 4.35.2. SRA32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRA32.u (SIMD 32-bit Rounding Shift Right Arithmetic) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRA32 Rd, Rs1, Rs2 + * SRA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit element arithmetic right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the data elements. The shift amount is specified by the low-order + * 5-bits of the value in the Rs2 register. For the rounding operation of the `.u` form, a value of 1 is + * added to the most significant discarded bit of each 32-bit data element to calculate the final results. + * And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA32.u + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRA32 + * Rd.W[x] = SE32(Rs1.W[x][31:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRA32_U(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("sra32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.35.2. SRA32.u ===== */ + +/* ===== Inline Function Start for 4.36.1. SRAI32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRAI32 (SIMD 32-bit Shift Right Arithmetic Immediate) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRAI32 Rd, Rs1, imm5u + * SRAI32.u Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements arithmetic right shift operations simultaneously. The shift amount is + * an immediate value. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the 32-bit data elements. The shift amount is specified by the + * imm5u constant. For the rounding operation of the `.u` form, a value of 1 is added to the most + * significant discarded bit of each 32-bit data to calculate the final results. And the results are written + * to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRAI32.u + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRAI32 + * Rd.W[x] = SE32(Rs1.W[x][31:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI32(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.36.1. SRAI32 ===== */ + +/* ===== Inline Function Start for 4.36.2. SRAI32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRAI32.u (SIMD 32-bit Rounding Shift Right Arithmetic Immediate) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRAI32 Rd, Rs1, imm5u + * SRAI32.u Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements arithmetic right shift operations simultaneously. The shift amount is + * an immediate value. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out + * bits are filled with the sign-bit of the 32-bit data elements. The shift amount is specified by the + * imm5u constant. For the rounding operation of the `.u` form, a value of 1 is added to the most + * significant discarded bit of each 32-bit data to calculate the final results. And the results are written + * to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRAI32.u + * res[31:-1] = SE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRAI32 + * Rd.W[x] = SE32(Rs1.W[x][31:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRAI32_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srai32.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.36.2. SRAI32.u ===== */ + +/* ===== Inline Function Start for 4.37. SRAIW.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_NON_SIMD_32B_SHIFT + * \brief SRAIW.u (Rounding Shift Right Arithmetic Immediate Word) + * \details + * **Type**: DSP (RV64 only) + * + * **Syntax**:\n + * ~~~ + * SRAIW.u Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Perform a 32-bit arithmetic right shift operation with rounding. The shift amount is an + * immediate value. + * + * **Description**:\n + * This instruction right-shifts the lower 32-bit content of Rs1 arithmetically. The shifted + * out bits are filled with the sign-bit Rs1(31) and the shift amount is specified by the imm5u constant. + * For the rounding operation, a value of 1 is added to the most significant discarded bit of the data to + * calculate the final result. And the result is sign-extended and written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u; + * if (sa != 0) { + * res[31:-1] = SE33(Rs1[31:(sa-1)]) + 1; + * Rd = SE32(res[31:0]); + * } else { + * Rd = SE32(Rs1.W[0]); + * } + * ~~~ + * + * \param [in] a int type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in long type + */ +#define __RV_SRAIW_U(a, b) \ + ({ \ + long result; \ + int __a = (int)(a); \ + __ASM volatile("sraiw.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.37. SRAIW.u ===== */ + +/* ===== Inline Function Start for 4.38.1. SRL32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRL32 (SIMD 32-bit Shift Right Logical) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRL32 Rd, Rs1, Rs2 + * SRL32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit element logical right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the low-order 5-bits of the value in the Rs2 + * register. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 32-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA32.u + * res[31:-1] = ZE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRA32 + * Rd.W[x] = ZE32(Rs1.W[x][31:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL32(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.38.1. SRL32 ===== */ + +/* ===== Inline Function Start for 4.38.2. SRL32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRL32.u (SIMD 32-bit Rounding Shift Right Logical) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRL32 Rd, Rs1, Rs2 + * SRL32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit element logical right shift operations simultaneously. The shift amount is a + * variable from a GPR. The `.u` form performs additional rounding up operations on the shifted + * results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the low-order 5-bits of the value in the Rs2 + * register. For the rounding operation of the `.u` form, a value of 1 is added to the most significant + * discarded bit of each 32-bit data element to calculate the final results. And the results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRA32.u + * res[31:-1] = ZE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRA32 + * Rd.W[x] = ZE32(Rs1.W[x][31:sa]) + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SRL32_U(unsigned long a, unsigned int b) +{ + unsigned long result; + __ASM volatile("srl32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.38.2. SRL32.u ===== */ + +/* ===== Inline Function Start for 4.39.1. SRLI32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRLI32 (SIMD 32-bit Shift Right Logical Immediate) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRLI32 Rd, Rs1, imm5u + * SRLI32.u Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the imm5u constant. For the rounding + * operation of the `.u` form, a value of 1 is added to the most significant discarded bit of each 32-bit + * data to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRLI32.u + * res[31:-1] = ZE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRLI32 + * Rd.W[x] = ZE32(Rs1.W[x][31:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI32(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.39.1. SRLI32 ===== */ + +/* ===== Inline Function Start for 4.39.2. SRLI32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_SHIFT + * \brief SRLI32.u (SIMD 32-bit Rounding Shift Right Logical Immediate) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SRLI32 Rd, Rs1, imm5u + * SRLI32.u Rd, Rs1, imm5u + * ~~~ + * + * **Purpose**:\n + * Do 32-bit elements logical right shift operations simultaneously. The shift amount is an + * immediate value. The `.u` form performs additional rounding up operations on the shifted results. + * + * **Description**:\n + * The 32-bit data elements in Rs1 are right-shifted logically, that is, the shifted out bits + * are filled with zero. The shift amount is specified by the imm5u constant. For the rounding + * operation of the `.u` form, a value of 1 is added to the most significant discarded bit of each 32-bit + * data to calculate the final results. And the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = imm5u[4:0]; + * if (sa > 0) { + * if (`.u` form) { // SRLI32.u + * res[31:-1] = ZE33(Rs1.W[x][31:sa-1]) + 1; + * Rd.W[x] = res[31:0]; + * else { // SRLI32 + * Rd.W[x] = ZE32(Rs1.W[x][31:sa]); + * } + * } else { + * Rd = Rs1; + * } + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned int type of value stored in b + * \return value stored in unsigned long type + */ +#define __RV_SRLI32_U(a, b) \ + ({ \ + unsigned long result; \ + unsigned long __a = (unsigned long)(a); \ + __ASM volatile("srli32.u %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for 4.39.2. SRLI32.u ===== */ + +/* ===== Inline Function Start for 4.40. STAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief STAS32 (SIMD 32-bit Straight Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * STAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element addition and 32-bit integer element subtraction in a 64-bit + * chunk simultaneously. Operands are from corresponding 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit + * integer element in [63:32] of Rs2, and writes the result to [63:32] of Rd; at the same time, it subtracts + * the 32-bit integer element in [31:0] of Rs2 from the 32-bit integer element in [31:0] of Rs1, and + * writes the result to [31:0] of Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] + Rs2.W[1]; + * Rd.W[0] = Rs1.W[0] - Rs2.W[0]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_STAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("stas32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.40. STAS32 ===== */ + +/* ===== Inline Function Start for 4.41. STSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief STSA32 (SIMD 32-bit Straight Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * STSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtraction and 32-bit integer element addition in a 64-bit + * chunk simultaneously. Operands are from corresponding 32-bit elements. + * *Description: * + * This instruction subtracts the 32-bit integer element in [63:32] of Rs2 from the 32-bit integer + * element in [63:32] of Rs1, and writes the result to [63:32] of Rd; at the same time, it adds the 32-bit + * integer element in [31:0] of Rs1 with the 32-bit integer element in [31:0] of Rs2, and writes the result + * to [31:0] of Rd + * + * **Note**:\n + * This instruction can be used for either signed or unsigned operations. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] - Rs2.W[1]; + * Rd.W[0] = Rs1.W[0] + Rs2.W[0]; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_STSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("stsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.41. STSA32 ===== */ + +/* ===== Inline Function Start for 4.42. SUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief SUB32 (SIMD 32-bit Subtraction) + * \details + * **Type**: DSP (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * SUB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 32-bit integer elements in Rs2 from the 32-bit integer + * elements in Rs1, and then writes the results to Rd. + * + * **Note**:\n + * This instruction can be used for either signed or unsigned subtraction. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x] - Rs2.W[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_SUB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("sub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.42. SUB32 ===== */ + +/* ===== Inline Function Start for 4.43. UKADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKADD32 (SIMD 32-bit Unsigned Saturating Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKADD32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 32-bit unsigned integer elements in Rs1 with the 32-bit + * unsigned integer elements in Rs2. If any of the results are beyond the 32-bit unsigned number + * range (0 <= RES <= 2^32-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] + Rs2.W[x]; + * if (res[x] > (2^32)-1) { + * res[x] = (2^32)-1; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKADD32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukadd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.43. UKADD32 ===== */ + +/* ===== Inline Function Start for 4.44. UKCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKCRAS32 (SIMD 32-bit Unsigned Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKCRAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 32-bit unsigned integer element saturating addition and one 32-bit unsigned + * integer element saturating subtraction in a 64-bit chunk simultaneously. Operands are from crossed + * 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit unsigned integer element in [63:32] of Rs1 with the 32- + * bit unsigned integer element in [31:0] of Rs2; at the same time, it subtracts the 32-bit unsigned + * integer element in [63:32] of Rs2 from the 32-bit unsigned integer element in [31:0] Rs1. If any of the + * results are beyond the 32-bit unsigned number range (0 <= RES <= 2^32-1), they are saturated to the + * range and the OV bit is set to 1. The saturated results are written to [63:32] of Rd for addition and + * [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[1] + Rs2.W[0]; + * res2 = Rs1.W[0] - Rs2.W[1]; + * if (res1 > (2^32)-1) { + * res1 = (2^32)-1; + * OV = 1; + * } + * if (res2 < 0) { + * res2 = 0; + * OV = 1; + * } + * Rd.W[1] = res1; + * Rd.W[0] = res2; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKCRAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.44. UKCRAS32 ===== */ + +/* ===== Inline Function Start for 4.45. UKCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKCRSA32 (SIMD 32-bit Unsigned Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKCRSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 32-bit unsigned integer element saturating subtraction and one 32-bit unsigned + * integer element saturating addition in a 64-bit chunk simultaneously. Operands are from crossed + * 32-bit elements. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer element in [31:0] of Rs2 from the + * 32-bit unsigned integer element in [63:32] of Rs1; at the same time, it adds the 32-bit unsigned + * integer element in [63:32] of Rs2 with the 32-bit unsigned integer element in [31:0] Rs1. If any of the + * results are beyond the 32-bit unsigned number range (0 <= RES <= 2^32-1), they are saturated to the + * range and the OV bit is set to 1. The saturated results are written to [63:32] of Rd for subtraction and + * [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[1] - Rs2.W[0]; + * res2 = Rs1.W[0] + Rs2.W[1]; + * if (res1 < 0) { + * res1 = 0; + * OV = 1; + * } else if (res2 > (2^32)-1) { + * res2 = (2^32)-1; + * OV = 1; + * } + * Rd.W[1] = res1; + * Rd.W[0] = res2; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKCRSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.45. UKCRSA32 ===== */ + +/* ===== Inline Function Start for 4.46. UKSTAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKSTAS32 (SIMD 32-bit Unsigned Saturating Straight Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKSTAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 32-bit unsigned integer element saturating addition and one 32-bit unsigned + * integer element saturating subtraction in a 64-bit chunk simultaneously. Operands are from + * corresponding 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit unsigned integer element in [63:32] of Rs1 with the 32- + * bit unsigned integer element in [63:32] of Rs2; at the same time, it subtracts the 32-bit unsigned + * integer element in [31:0] of Rs2 from the 32-bit unsigned integer element in [31:0] Rs1. If any of the + * results are beyond the 32-bit unsigned number range (0 <= RES <= 2^32-1), they are saturated to the + * range and the OV bit is set to 1. The saturated results are written to [63:32] of Rd for addition and + * [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[1] + Rs2.W[1]; + * res2 = Rs1.W[0] - Rs2.W[0]; + * if (res1 > (2^32)-1) { + * res1 = (2^32)-1; + * OV = 1; + * } + * if (res2 < 0) { + * res2 = 0; + * OV = 1; + * } + * Rd.W[1] = res1; + * Rd.W[0] = res2; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSTAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukstas32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.46. UKSTAS32 ===== */ + +/* ===== Inline Function Start for 4.47. UKSTSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKSTSA32 (SIMD 32-bit Unsigned Saturating Straight Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKSTSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do one 32-bit unsigned integer element saturating subtraction and one 32-bit unsigned + * integer element saturating addition in a 64-bit chunk simultaneously. Operands are from + * corresponding 32-bit elements. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer element in [63:32] of Rs2 from + * the 32-bit unsigned integer element in [63:32] of Rs1; at the same time, it adds the 32-bit unsigned + * integer element in [31:0] of Rs2 with the 32-bit unsigned integer element in [31:0] Rs1. If any of the + * results are beyond the 32-bit unsigned number range (0 <= RES <= 2^32-1), they are saturated to the + * range and the OV bit is set to 1. The saturated results are written to [63:32] of Rd for subtraction and + * [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[1] - Rs2.W[1]; + * res2 = Rs1.W[0] + Rs2.W[0]; + * if (res1 < 0) { + * res1 = 0; + * OV = 1; + * } else if (res2 > (2^32)-1) { + * res2 = (2^32)-1; + * OV = 1; + * } + * Rd.W[1] = res1; + * Rd.W[0] = res2; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSTSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ukstsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.47. UKSTSA32 ===== */ + +/* ===== Inline Function Start for 4.48. UKSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief UKSUB32 (SIMD 32-bit Unsigned Saturating Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UKSUB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer elements in Rs2 from the 32-bit + * unsigned integer elements in Rs1. If any of the results are beyond the 32-bit unsigned number + * range (0 <= RES <= 2^32-1), they are saturated to the range and the OV bit is set to 1. The saturated + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] - Rs2.W[x]; + * if (res[x] < 0) { + * res[x] = 0; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UKSUB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uksub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.48. UKSUB32 ===== */ + +/* ===== Inline Function Start for 4.49. UMAX32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC + * \brief UMAX32 (SIMD 32-bit Unsigned Maximum) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UMAX32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer elements finding maximum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 32-bit unsigned integer elements in Rs1 with the 32-bit + * unsigned integer elements in Rs2 and selects the numbers that is greater than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] u> Rs2.W[x])? Rs1.W[x] : Rs2.W[x]; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_UMAX32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("umax32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.49. UMAX32 ===== */ + +/* ===== Inline Function Start for 4.50. UMIN32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_MISC + * \brief UMIN32 (SIMD 32-bit Unsigned Minimum) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * UMIN32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer elements finding minimum operations simultaneously. + * + * **Description**:\n + * This instruction compares the 32-bit unsigned integer elements in Rs1 with the 32-bit + * unsigned integer elements in Rs2 and selects the numbers that is less than the other one. The + * selected results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] > 1; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URADD32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("uradd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.51. URADD32 ===== */ + +/* ===== Inline Function Start for 4.52. URCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief URCRAS32 (SIMD 32-bit Unsigned Halving Cross Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * URCRAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element addition and 32-bit unsigned integer element + * subtraction in a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. The + * results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit unsigned integer element in [63:32] of Rs1 with the 32- + * bit unsigned integer element in [31:0] of Rs2, and subtracts the 32-bit unsigned integer element in + * [63:32] of Rs2 from the 32-bit unsigned integer element in [31:0] of Rs1. The element results are first + * logically right-shifted by 1 bit and then written to [63:32] of Rd for addition and [31:0] of Rd for + * subtraction. + * + * **Examples**:\n + * ~~~ + * Please see `URADD32` and `URSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] + Rs2.W[0]) u>> 1; + * Rd.W[0] = (Rs1.W[0] - Rs2.W[1]) u>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URCRAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.52. URCRAS32 ===== */ + +/* ===== Inline Function Start for 4.53. URCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief URCRSA32 (SIMD 32-bit Unsigned Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * URCRSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element subtraction and 32-bit unsigned integer element + * addition in a 64-bit chunk simultaneously. Operands are from crossed 32-bit elements. The results + * are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer element in [31:0] of Rs2 from the + * 32-bit unsigned integer element in [63:32] of Rs1, and adds the 32-bit unsigned element integer in + * [31:0] of Rs1 with the 32-bit unsigned integer element in [63:32] of Rs2. The two results are first + * logically right-shifted by 1 bit and then written to [63:32] of Rd for subtraction and [31:0] of Rd for + * addition. + * + * **Examples**:\n + * ~~~ + * Please see `URADD32` and `URSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] - Rs2.W[0]) u>> 1; + * Rd.W[0] = (Rs1.W[0] + Rs2.W[1]) u>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URCRSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.53. URCRSA32 ===== */ + +/* ===== Inline Function Start for 4.54. URSTAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief URSTAS32 (SIMD 32-bit Unsigned Halving Straight Addition & Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * URSTAS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element addition and 32-bit unsigned integer element + * subtraction in a 64-bit chunk simultaneously. Operands are from corresponding 32-bit elements. + * The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit unsigned integer element in [63:32] of Rs1 with the 32- + * bit unsigned integer element in [63:32] of Rs2, and subtracts the 32-bit unsigned integer element in + * [31:0] of Rs2 from the 32-bit unsigned integer element in [31:0] of Rs1. The element results are first + * logically right-shifted by 1 bit and then written to [63:32] of Rd for addition and [31:0] of Rd for + * subtraction. + * + * **Examples**:\n + * ~~~ + * Please see `URADD32` and `URSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] + Rs2.W[1]) u>> 1; + * Rd.W[0] = (Rs1.W[0] - Rs2.W[0]) u>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSTAS32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urstas32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.54. URSTAS32 ===== */ + +/* ===== Inline Function Start for 4.55. URSTSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief URSTSA32 (SIMD 32-bit Unsigned Halving Straight Subtraction & Addition) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * URSTSA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element subtraction and 32-bit unsigned integer element + * addition in a 64-bit chunk simultaneously. Operands are from corresponding 32-bit elements. The + * results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer element in [63:32] of Rs2 from + * the 32-bit unsigned integer element in [63:32] of Rs1, and adds the 32-bit unsigned element integer + * in [31:0] of Rs1 with the 32-bit unsigned integer element in [31:0] of Rs2. The two results are first + * logically right-shifted by 1 bit and then written to [63:32] of Rd for subtraction and [31:0] of Rd for + * addition. + * + * **Examples**:\n + * ~~~ + * Please see `URADD32` and `URSUB32` instructions. + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] - Rs2.W[1]) u>> 1; + * Rd.W[0] = (Rs1.W[0] + Rs2.W[0]) u>> 1; + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSTSA32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("urstsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.55. URSTSA32 ===== */ + +/* ===== Inline Function Start for 4.56. URSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_RV64_SIMD_32B_ADDSUB + * \brief URSUB32 (SIMD 32-bit Unsigned Halving Subtraction) + * \details + * **Type**: SIMD (RV64 Only) + * + * **Syntax**:\n + * ~~~ + * URSUB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do 32-bit unsigned integer element subtractions simultaneously. The results are halved to + * avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit unsigned integer elements in Rs2 from the 32-bit + * unsigned integer elements in Rs1. The results are first logically right-shifted by 1 bit and then + * written to Rd. + * + * **Examples**:\n + * ~~~ + * * Ra = 0x7FFFFFFF, Rb = 0x80000000, Rt = 0xFFFFFFFF + * * Ra = 0x80000000, Rb = 0x7FFFFFFF, Rt = 0x00000000 + * * Ra = 0x80000000, Rb = 0x40000000, Rt = 0x20000000 + * ~~~ + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] - Rs2.W[x]) u>> 1; + * for RV64: x=1...0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_URSUB32(unsigned long a, unsigned long b) +{ + unsigned long result; + __ASM volatile("ursub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for 4.56. URSUB32 ===== */ + +#endif /* __RISCV_XLEN == 64 */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default Nuclei Default SIMD DSP Additional Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief (RV32 & RV64)Nuclei Customized DSP Instructions + * \details This is Nuclei customized DSP instructions for both RV32 and RV64 + */ + +/* ===== Inline Function Start for EXPD80 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD80 (Expand and Copy Byte 0 to 32bit(when rv32) or 64bit(when rv64)) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD80 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * When rv32, Copy 8-bit data from 32-bit chunks into 4 bytes in a register. + * When rv64, Copy 8-bit data from 64-bit chunks into 8 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[0][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[0][7:0], Rs1.B[0][7:0], Rs1.B[0][7:0], Rs1.B[0][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD80(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd80 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD80 ===== */ + +/* ===== Inline Function Start for EXPD81 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD81 (Expand and Copy Byte 1 to 32bit(rv32) or 64bit(when rv64)) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD81 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Copy 8-bit data from 32-bit chunks into 4 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[1][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[1][7:0], Rs1.B[1][7:0], Rs1.B[1][7:0], Rs1.B[1][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD81(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd81 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD81 ===== */ + +/* ===== Inline Function Start for EXPD82 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD82 (Expand and Copy Byte 2 to 32bit(rv32) or 64bit(when rv64)) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD82 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Copy 8-bit data from 32-bit chunks into 4 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[2][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[2][7:0], Rs1.B[2][7:0], Rs1.B[2][7:0], Rs1.B[2][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD82(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd82 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD82 ===== */ + +/* ===== Inline Function Start for EXPD83 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD83 (Expand and Copy Byte 3 to 32bit(rv32) or 64bit(when rv64)) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD83 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Copy 8-bit data from 32-bit chunks into 4 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[3][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[3][7:0], Rs1.B[3][7:0], Rs1.B[3][7:0], Rs1.B[3][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD83(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd83 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD83 ===== */ + +#if (__RISCV_XLEN == 64) +/* ===== Inline Function Start for EXPD84 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD84 (Expand and Copy Byte 4 to 64bit) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD84 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Only RV64, copy 8-bit data from 64-bit chunks into 8 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[4][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[4][7:0], Rs1.B[4][7:0], Rs1.B[4][7:0], Rs1.B[4][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD84(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd84 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD84 ===== */ + +/* ===== Inline Function Start for EXPD85 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD85 (Expand and Copy Byte 5 to 64bit) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD85 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Only RV64, copy 8-bit data from 64-bit chunks into 8 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[5][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[5][7:0], Rs1.B[5][7:0], Rs1.B[5][7:0], Rs1.B[5][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD85(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd85 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD85 ===== */ + +/* ===== Inline Function Start for EXPD86 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD86 (Expand and Copy Byte 6 to 64bit) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD86 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Only RV64, copy 8-bit data from 64-bit chunks into 8 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[6][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[6][7:0], Rs1.B[6][7:0], Rs1.B[6][7:0], Rs1.B[6][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD86(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd86 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD86 ===== */ + +/* ===== Inline Function Start for EXPD87 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_Default + * \brief EXPD87 (Expand and Copy Byte 7 to 64bit) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * EXPD87 Rd, Rs1 + * ~~~ + * + * **Purpose**:\n + * Only RV64, copy 8-bit data from 64-bit chunks into 8 bytes in a register. + * + * **Description**:\n + * Moves Rs1.B[7][7:0] to Rd.[0][7:0], Rd.[1][7:0], Rd.[2][7:0], Rd.[3][7:0] + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.B[7][7:0], Rs1.B[7][7:0], Rs1.B[7][7:0], Rs1.B[7][7:0]); + * for RV32: x=0 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_EXPD87(unsigned long a) +{ + unsigned long result; + __ASM volatile("expd87 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for EXPD87 ===== */ +#endif /* __RISCV_XLEN == 64 */ + +#if (__RISCV_XLEN == 32) || defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__) +/* XXXXX Nuclei Extended DSP Instructions for RV32 XXXXX */ + +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 Nuclei N1 SIMD DSP Additional Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief (RV32 only)Nuclei Customized N1 DSP Instructions + * \details This is Nuclei customized DSP N1 instructions only for RV32 + */ +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 Nuclei N2 SIMD DSP Additional Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief (RV32 only)Nuclei Customized N2 DSP Instructions + * \details This is Nuclei customized DSP N2 instructions only for RV32 + */ +/** + * \defgroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 Nuclei N3 SIMD DSP Additional Instructions + * \ingroup NMSIS_Core_DSP_Intrinsic + * \brief (RV32 only)Nuclei Customized N3 DSP Instructions + * \details This is Nuclei customized DSP N3 instructions only for RV32 + */ + +/* ===== Inline Function Start for DKHM8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKHM8 (64-bit SIMD Signed Saturating Q7 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKHM8 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do Q7xQ7 element multiplications simultaneously. The Q14 results are then reduced to Q7 + * numbers again. + * + * **Description**:\n + * For the `DKHM8` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 + * with the top 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the bottom 8-bit Q7 content of 16-bit chunks in Rs2. + * + * The Q14 results are then right-shifted 7-bits and saturated into Q7 values. The Q7 results are then + * written into Rd. When both the two Q7 inputs of a multiplication are 0x80, saturation will happen. + * The result will be saturated to 0x7F and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.B[x+1]; op2t = Rs2.B[x+1]; // top + * op1b = Rs1.B[x]; op2b = Rs2.B[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x80 != aop | 0x80 != bop) { + * res = (aop s* bop) >> 7; + * } else { + * res= 0x7F; + * OV = 1; + * } + * } + * Rd.H[x/2] = concat(rest, resb); + * for RV32, x=0,2,4,6 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKHM8(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkhm8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKHM8 ===== */ + +/* ===== Inline Function Start for DKHM16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKHM16 (64-bit SIMD Signed Saturating Q15 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKHM16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do Q15xQ15 element multiplications simultaneously. The Q30 results are then reduced to + * Q15 numbers again. + * + * **Description**:\n + * For the `DKHM16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in + * Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom + * 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content of 32-bit chunks in + * Rs2. + * + * The Q30 results are then right-shifted 15-bits and saturated into Q15 values. The Q15 results are + * then written into Rd. When both the two Q15 inputs of a multiplication are 0x8000, saturation will + * happen. The result will be saturated to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x+1]; // top + * op1b = Rs1.H[x]; op2b = Rs2.H[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x8000 != aop | 0x8000 != bop) { + * res = (aop s* bop) >> 15; + * } else { + * res= 0x7FFF; + * OV = 1; + * } + * } + * Rd.W[x/2] = concat(rest, resb); + * for RV32: x=0, 2 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKHM16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkhm16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKHM16 ===== */ + +/* ===== Inline Function Start for DKABS8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKABS8 (64-bit SIMD 8-bit Saturating Absolute) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKABS8 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of 8-bit signed integer elements simultaneously. + * + * **Description**:\n + * This instruction calculates the absolute value of 8-bit signed integer elements stored + * in Rs1 and writes the element results to Rd. If the input number is 0x80, this instruction generates + * 0x7f as the output and sets the OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.B[x]; + * if (src == 0x80) { + * src = 0x7f; + * OV = 1; + * } else if (src[7] == 1) + * src = -src; + * } + * Rd.B[x] = src; + * for RV32: x=7...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKABS8(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dkabs8 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DKABS8 ===== */ + +/* ===== Inline Function Start for DKABS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKABS16 (64-bit SIMD 16-bit Saturating Absolute) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKABS16 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of 16-bit signed integer elements simultaneously. + * + * **Description**:\n + * This instruction calculates the absolute value of 16-bit signed integer elements stored + * in Rs1 and writes the element results to Rd. If the input number is 0x8000, this instruction + * generates 0x7fff as the output and sets the OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src == 0x8000) { + * src = 0x7fff; + * OV = 1; + * } else if (src[15] == 1) + * src = -src; + * } + * Rd.H[x] = src; + * for RV32: x=3...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKABS16(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dkabs16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DKABS16 ===== */ + +/* ===== Inline Function Start for DKSLRA8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKSLRA8 (64-bit SIMD 8-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSLRA8 Rd, Rs1, Rs2 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 8-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q7 saturation for the left shift. + * + * **Description**:\n + * The 8-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[3:0]. Rs2[3:0] is in the signed range of [-2^3, 2^3-1]. A positive Rs2[3:0] means + * logical left shift and a negative Rs2[3:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[3:0]. However, the behavior of `Rs2[3:0]==-2^3 (0x8)` is defined to be + * equivalent to the behavior of `Rs2[3:0]==-(2^3-1) (0x9)`. + * The left-shifted results are saturated to the 8-bit signed integer range of [-2^7, 2^7-1]. + * If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:4] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[3:0] < 0) { + * sa = -Rs2[3:0]; + * sa = (sa == 8)? 7 : sa; + * Rd.B[x] = SE8(Rs1.B[x][7:sa]); + * } else { + * sa = Rs2[2:0]; + * res[(7+sa):0] = Rs1.B[x] <<(logic) sa; + * if (res > (2^7)-1) { + * res[7:0] = 0x7f; OV = 1; + * } else if (res < -2^7) { + * res[7:0] = 0x80; OV = 1; + * } + * Rd.B[x] = res[7:0]; + * } + * for RV32: x=7...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSLRA8(unsigned long long a, int b) +{ + unsigned long long result; + __ASM volatile("dkslra8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSLRA8 ===== */ + +/* ===== Inline Function Start for DKSLRA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKSLRA16 (64-bit SIMD 16-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSLRA16 Rd, Rs1, Rs2 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit elements logical left (positive) or arithmetic right (negative) shift operation with + * Q15 saturation for the left shift. + * + * **Description**:\n + * The 16-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically + * based on the value of Rs2[4:0]. Rs2[4:0] is in the signed range of [-2^4, 2^4-1]. A positive Rs2[4:0] means + * logical left shift and a negative Rs2[4:0] means arithmetic right shift. The shift amount is the + * absolute value of Rs2[4:0]. However, the behavior of `Rs2[4:0]==-2^4 (0x10)` is defined to be + * equivalent to the behavior of `Rs2[4:0]==-(2^4-1) (0x11)`. + * The left-shifted results are saturated to the 16-bit signed integer range of [-2^15, 2^15-1]. + * After the shift, saturation, or rounding, the final results are written to + * Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:5] will not affect + * this instruction. + * + * **Operations**:\n + * ~~~ + * if (Rs2[4:0] < 0) { + * sa = -Rs2[4:0]; + * sa = (sa == 16)? 15 : sa; + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } else { + * sa = Rs2[3:0]; + * res[(15+sa):0] = Rs1.H[x] <<(logic) sa; + * if (res > (2^15)-1) { + * res[15:0] = 0x7fff; OV = 1; + * } else if (res < -2^15) { + * res[15:0] = 0x8000; OV = 1; + * } + * d.H[x] = res[15:0]; + * } + * for RV32: x=3...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSLRA16(unsigned long long a, int b) +{ + unsigned long long result; + __ASM volatile("dkslra16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSLRA16 ===== */ + +/* ===== Inline Function Start for DKADD8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKADD8 (64-bit SIMD 8-bit Signed Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKADD8 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 8-bit signed integer elements in Rs1 with the 8-bit signed + * integer elements in Rs2. If any of the results are beyond the Q7 number range (-2^7 <= Q7 <= 2^7-1), they + * are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.B[x] + Rs2.B[x]; + * if (res[x] > 127) { + * res[x] = 127; + * OV = 1; + * } else if (res[x] < -128) { + * res[x] = -128; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=7...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKADD8(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkadd8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKADD8 ===== */ + +/* ===== Inline Function Start for DKADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKADD16 (64-bit SIMD 16-bit Signed Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKADD16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer elements in Rs1 with the 16-bit signed + * integer elements in Rs2. If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), + * they are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] + Rs2.H[x]; + * if (res[x] > 32767) { + * res[x] = 32767; + * OV = 1; + * } else if (res[x] < -32768) { + * res[x] = -32768; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=3...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKADD16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkadd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKADD16 ===== */ + +/* ===== Inline Function Start for DKSUB8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKSUB8 (64-bit SIMD 8-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSUB8 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 8-bit signed elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 8-bit signed integer elements in Rs2 from the 8-bit + * signed integer elements in Rs1. If any of the results are beyond the Q7 number range (-2^7 <= Q7 <= 2^7-1), + * they are saturated to the range and the OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.B[x] - Rs2.B[x]; + * if (res[x] > (2^7)-1) { + * res[x] = (2^7)-1; + * OV = 1; + * } else if (res[x] < -2^7) { + * res[x] = -2^7; + * OV = 1; + * } + * Rd.B[x] = res[x]; + * for RV32: x=7...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSUB8(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dksub8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSUB8 ===== */ + +/* ===== Inline Function Start for DKSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N1 + * \brief DKSUB16 (64-bit SIMD 16-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSUB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer elements saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer elements in Rs2 from the 16-bit + * signed integer elements in Rs1. If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= + * 2^15-1), they are saturated to the range and the OV bit is set to 1. The saturated results are written to + * Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.H[x] - Rs2.H[x]; + * if (res[x] > (2^15)-1) { + * res[x] = (2^15)-1; + * OV = 1; + * } else if (res[x] < -2^15) { + * res[x] = -2^15; + * OV = 1; + * } + * Rd.H[x] = res[x]; + * for RV32: x=3...0, + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSUB16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dksub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSUB16 ===== */ + +/* ===== Inline Function Start for DKHMX8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKHMX8 (64-bit SIMD Signed Crossed Saturating Q7 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKHMX8 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do Q7xQ7 element crossed multiplications simultaneously. The Q15 results are then reduced to Q7 numbers again. + * + * **Description**:\n + * For the `KHM8` instruction, multiply the top 8-bit Q7 content of 16-bit chunks in Rs1 with the + * bottom 8-bit Q7 content of 16-bit chunks in Rs2. At the same time, multiply the bottom 8-bit Q7 + * content of 16-bit chunks in Rs1 with the top 8-bit Q7 content of 16-bit chunks in Rs2. + * + * The Q14 results are then right-shifted 7-bits and saturated into Q7 values. The Q7 results are then + * written into Rd. When both the two Q7 inputs of a multiplication are 0x80, saturation will happen. + * The result will be saturated to 0x7F and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.B[x+1]; op2t = Rs2.B[x]; // top + * op1b = Rs1.B[x]; op2b = Rs2.B[x+1]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x80 != aop | 0x80 != bop) { + * res = (aop s* bop) >> 7; + * } else { + * res= 0x7F; + * OV = 1; + * } + * } + * Rd.H[x/2] = concat(rest, resb); + * for RV32, x=0,2,4,6 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKHMX8(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkhmx8 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKHMX8 ===== */ + +/* ===== Inline Function Start for DKHMX16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKHMX16 (64-bit SIMD Signed Crossed Saturating Q15 Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKHMX16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do Q15xQ15 element crossed multiplications simultaneously. The Q31 results are then reduced to Q15 numbers again. + * + * **Description**:\n + * For the `KHMX16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the + * bottom 16-bit Q15 content of 32-bit chunks in Rs2. At the same time, multiply the bottom 16-bit Q15 + * content of 32-bit chunks in Rs1 with the top 16-bit Q15 content of 32-bit chunks in Rs2. + * + * The Q30 results are then right-shifted 15-bits and saturated into Q15 values. The Q15 results are + * then written into Rd. When both the two Q15 inputs of a multiplication are 0x8000, saturation will + * happen. The result will be saturated to 0x7FFF and the overflow flag OV will be set. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.H[x+1]; op2t = Rs2.H[x]; // top + * op1b = Rs1.H[x]; op2b = Rs2.H[x+1]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * if (0x8000 != aop | 0x8000 != bop) { + * res = (aop s* bop) >> 15; + * } else { + * res= 0x7FFF; + * OV = 1; + * } + * } + * Rd.W[x/2] = concat(rest, resb); + * for RV32, x=0,2 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKHMX16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkhmx16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKHMX16 ===== */ + +/* ===== Inline Function Start for DSMMUL ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMMUL (64-bit MSW 32x32 Signed Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMMUL Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element signed multiplications simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2 and writes the + * most significant 32-bit multiplication results to the corresponding 32-bit elements of Rd. The 32-bit + * elements of Rs1 and Rs2 are treated as signed integers. The .u form of the instruction rounds up + * the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = (aop s* bop)[63:32]; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMMUL(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsmmul %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMMUL ===== */ + +/* ===== Inline Function Start for DSMMUL.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMMUL.u (64-bit MSW 32x32 Unsigned Multiply) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMMUL.u Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element unsigned multiplications simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2 and writes the + * most significant 32-bit multiplication results to the corresponding 32-bit elements of Rd. The 32-bit + * elements of Rs1 and Rs2 are treated as unsigned integers. The .u form of the instruction rounds up + * the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = RUND(aop u* bop)[63:32]; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMMUL_U(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsmmul.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMMUL.u ===== */ + +/* ===== Inline Function Start for DKWMMUL ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKWMMUL (64-bit MSW 32x32 Signed Multiply & Double) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKWMMUL Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element signed multiplications simultaneously and double. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2. It then shifts + * the multiplication results one bit to the left and takes the most significant 32-bit results. If the + * shifted result is greater than 2^31-1, it is saturated to 2^31-1 and the OV flag is set to 1. The final element + * result is written to Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The .u + * form of the instruction additionally rounds up the 64-bit multiplication results by adding a 1 to bit + * 30 before the shift and saturation operations. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = sat.q31((aop s* bop) << 1)[63:32]; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKWMMUL(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkwmmul %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKWMMUL ===== */ + +/* ===== Inline Function Start for DKWMMUL.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKWMMUL.u (64-bit MSW 32x32 Unsigned Multiply & Double) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKWMMUL.u Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element unsigned multiplications simultaneously and double. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2. It then shifts + * the multiplication results one bit to the left and takes the most significant 32-bit results. If the + * shifted result is greater than 2^31-1, it is saturated to 2^31-1 and the OV flag is set to 1. The final element + * result is written to Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The .u + * form of the instruction additionally rounds up the 64-bit multiplication results by adding a 1 to bit + * 30 before the shift and saturation operations. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * for ((aop,bop,res) in [(op1t,op2t,rest), (op1b,op2b,resb)]) { + * res = sat.q31(RUND(aop u* bop) << 1)[63:32]; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKWMMUL_U(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkwmmul.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKWMMUL.u ===== */ + +/* ===== Inline Function Start for DKABS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKABS32 (64-bit SIMD 32-bit Saturating Absolute) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKABS32 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Get the absolute value of 32-bit signed integer elements simultaneously. + * + * **Description**:\n + * This instruction calculates the absolute value of 32-bit signed integer elements stored in Rs1 and writes the element + * results to Rd. If the input number is 0x8000_0000, this instruction generates 0x7fff_ffff as the output and sets the OV + * bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.W[x]; + * if (src == 0x8000_0000) { + * src = 0x7fff_ffff; + * OV = 1; + * } else if (src[31] == 1) + * src = -src; + * } + * Rd.W[x] = src; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKABS32(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dkabs32 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DKABS32 ===== */ + +/* ===== Inline Function Start for DKSLRA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKSLRA32 (64-bit SIMD 32-bit Shift Left Logical with Saturation or Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSLRA32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 31-bit elements logical left (positive) or arithmetic right (negative) shift operation with Q31 saturation for the left shift. + * + * **Description**:\n + * The 31-bit data elements of Rs1 are left-shifted logically or right-shifted arithmetically based on the value of Rs2[5:0]. + * Rs2[5:0] is in the signed range of [-2^5, 2^5-1]. A positive Rs2[5:0] means logical left shift and a negative Rs2[4:0] + * means arithmetic right shift. The shift amount is the absolute value of Rs2[5:0]. However, the behavior of Rs2[5:0]==- + * 2^5 (0x20) is defined to be equivalent to the behavior of Rs2[5:0]==-(2^5-1) (0x21). + * + * **Operations**:\n + * ~~~ + * if (Rs2[5:0] < 0) { + * sa = -Rs2[5:0]; + * sa = (sa == 32)? 31 : sa; + * Rd.W[x] = SE32(Rs1.W[x][31:sa]); + * } else { + * sa = Rs2[4:0]; + * res[(31+sa):0] = Rs1.W[x] <<(logic) sa; + * if (res > (2^31)-1) { + * res[31:0] = 0x7fff_ffff; OV = 1; + * } else if (res < -2^31) { + * res[31:0] = 0x8000_0000; OV = 1; + * } + * Rd.W[x] = res[31:0]; + * } + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b int type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSLRA32(unsigned long long a, int b) +{ + unsigned long long result; + __ASM volatile("dkslra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSLRA32 ===== */ + +/* ===== Inline Function Start for DKADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKADD32(64-bit SIMD 32-bit Signed Saturating Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKADD32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating additions simultaneously. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer elements in Rs1 with the 32-bit signed integer elements in Rs2. If any + * of the results are beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV + * bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] + Rs2.W[x]; + * if (res[x] > 0x7fff_ffff) { + * res[x] = 0x7fff_ffff; + * OV = 1; + * } else if (res[x] < 0x8000_0000) { + * res[x] = 0x8000_0000; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKADD32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkadd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKADD32 ===== */ + +/* ===== Inline Function Start for DKSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKSUB32 (64-bit SIMD 32-bit Signed Saturating Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSUB32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer elements in Rs2 from the 32-bit signed integer elements in Rs1. If + * any of the results are beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the + * OV bit is set to 1. The saturated results are written to Rd. + * + * **Operations**:\n + * ~~~ + * res[x] = Rs1.W[x] - Rs2.W[x]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res[x] < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[x] = res[x]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSUB32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dksub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSUB32 ===== */ + +/* ===== Inline Function Start for DRADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRADD16 (64-bit SIMD 16-bit Halving Signed Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRADD16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element additions simultaneously. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer elements in Rs1 with the 16-bit signed integer elements in Rs2. The results + * are first arithmetically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = [(Rs1.H[x]) + (Rs2.H[x])] s>> 1; + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRADD16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dradd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRADD16 ===== */ + +/* ===== Inline Function Start for DSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUB16 (64-bit SIMD 16-bit Halving Signed Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element subtractions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer elements in Rs1 with the 16-bit signed integer elements in Rs2. The results + * are first arithmetically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = [(Rs1.H[x]) - (Rs2.H[x])] ; + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUB16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSUB16 ===== */ + +/* ===== Inline Function Start for DRADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRADD32 (64-bit SIMD 32-bit Halving Signed Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRADD32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element additions simultaneously. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer elements in Rs1 with the 32-bit signed integer elements in Rs2. The results + * are first arithmetically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = [(Rs1.W[x]) + (Rs2.W[x])] s>> 1; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRADD32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dradd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRADD32 ===== */ + +/* ===== Inline Function Start for DSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUB32 (64-bit SIMD 32-bit Halving Signed Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUB32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtractions simultaneously. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer elements in Rs2 from the 32-bit signed integer elements in Rs1 . The + * results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = [(Rs1.E[x]) - (Rs2.E[x])] ; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUB32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSUB32 ===== */ + +/* ===== Inline Function Start for DMSR16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DMSR16 (Signed Multiply Halfs with Right Shift 16-bit and Cross Multiply Halfs with Right Shift 16-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DMSR16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications and cross multiplications from the 16-bit elements of two registers; and each multiplications performs a right shift operation. + * + * **Description**:\n + * For the `DMSR16` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the top 16-bit Q15 content + * of 32-bit chunks in Rs2, multiply the bottom 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content + * of 32-bit chunks in Rs2. + * At the same time, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom16-bit Q15 content of 32-bit + * chunks in Rs2 and multiply the bottom16-bit Q15 content of 32-bit chunks in Rs1 with the top16-bit Q15 content of 32-bit + * chunks in Rs2. The Q31 results are then right-shifted 16-bits and clipped to Q15 values. The Q15 results are then written + * into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[0] = (Rs1.H[0] s* Rs2.H[0]) s>> 16 + * Rd.H[1] = (Rs1.H[1] s* Rs2.H[1]) s>> 16 + * Rd.H[2] = (Rs1.H[1] s* Rs2.H[0]) s>> 16 + * Rd.H[3] = (Rs1.H[0] s* Rs2.H[1]) s>> 16 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DMSR16(unsigned long a, unsigned long b) +{ + unsigned long long result; + __ASM volatile("dmsr16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DMSR16 ===== */ + +/* ===== Inline Function Start for DMSR17 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DMSR17 (Signed Multiply Halfs with Right Shift 17-bit and Cross Multiply Halfs with Right Shift 17-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DMSR17 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications and cross multiplications from the 16-bit elements of two registers; + * and each multiplications performs a right shift operation. + * + * **Description**:\n + * For the `DMSR17` instruction, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the top 16-bit Q15 content + * of 32-bit chunks in Rs2, multiply the bottom 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content + * of 32-bit chunks in Rs2. + * At the same time, multiply the top 16-bit Q15 content of 32-bit chunks in Rs1 with the bottom 16-bit Q15 content of 32-bit + * chunks in Rs2 and multiply the bottom 16-bit Q15 content of 32-bit chunks in Rs1 with the top 16-bit Q15 content of 32-bit + * chunks in Rs2. The Q31 results are then right-shifted 17-bits and clipped to Q15 values. The Q15 results are then written + * into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[0] = (Rs1.H[0] s* Rs2.H[0]) s>> 17 + * Rd.H[1] = (Rs1.H[1] s* Rs2.H[1]) s>> 17 + * Rd.H[2] = (Rs1.H[1] s* Rs2.H[0]) s>> 17 + * Rd.H[3] = (Rs1.H[0] s* Rs2.H[1]) s>> 17 + * ~~~ + * + * \param [in] a unsigned long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DMSR17(unsigned long a, unsigned long b) +{ + unsigned long long result; + __ASM volatile("dmsr17 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DMSR17 ===== */ + +/* ===== Inline Function Start for DMSR33 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DMSR33 (Signed Multiply with Right Shift 33-bit and Cross Multiply with Right Shift 33-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DMSR33 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit multiplications from the 32-bit elements of two registers, and each multiplications performs a right + * shift operation. + * + * **Description**:\n + * For the `DMSR33` instruction, multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with the top 32-bit Q31 content + * of 64-bit chunks in Rs2. At the same time, multiply the bottom 32-bit Q31 content of 64bit chunks in Rs1 with the bottom + * 32-bit Q31 content of 64-bit. + * The Q64 results are then right-shifted 33-bits and clipped to Q31 values. The Q31 results are then written into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[0] = (Rs1.W[0] s* Rs2.W[0]) s>> 33 + * Rd.W[1] = (Rs1.W[1] s* Rs2.W[1]) s>> 33 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DMSR33(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dmsr33 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DMSR33 ===== */ + +/* ===== Inline Function Start for DMXSR33 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DMXSR33 (Signed Multiply with Right Shift 33-bit and Cross Multiply with Right Shift 33-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DMXSR33 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do two signed 32-bit cross multiplications from the 32-bit elements of two registers, and each multiplications performs a + * right shift operation. + * + * **Description**:\n + * For the `DMXSR33` instruction, multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with the bottom 32-bit Q31 + * content of 64-bit chunks in Rs2. At the same time, multiply the bottom 32-bit Q31 content of 64-bit chunks in Rs1 with + * the top 32-bit Q31 content of 64-bit chunks in Rs2. + * The Q63 results are then right-shifted 33-bits and clipped to Q31 values. The Q31 results are then written into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[0] = (Rs1.W[0] s* Rs2.W[1]) s>> 33 + * Rd.W[1] = (Rs1.W[1] s* Rs2.W[0]) s>> 33 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DMXSR33(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dmxsr33 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DMXSR33 ===== */ + +/* ===== Inline Function Start for DREDAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DREDAS16 (Reduced Addition and Reduced Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DREDAS16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do halfs reduced subtraction and halfs reduced addition from a register. The result is written to Rd. + * + * **Description**:\n + * For the `DREDAS16` instruction, subtract the top 16-bit Q15 element from the bottom 16-bit Q15 element of the bottom + * 32-bit Q31 content of 64-bit chunks in Rs1. At the same time, add the the top16-bit Q15 element with the bottom16-bit + * Q15 element of the top 32-bit Q31 content of 64-bit chunks in Rs1. The two Q15 results are then written into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[0] = Rs1.H[0] - Rs1.H[1] + * Rd.H[1] = Rs1.H[2] + Rs1.H[3] + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_DREDAS16(unsigned long long a) +{ + unsigned long result; + __ASM volatile("dredas16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DREDAS16 ===== */ + +/* ===== Inline Function Start for DREDSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DREDSA16 (Reduced Subtraction and Reduced Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DREDSA16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do halfs reduced subtraction and halfs reduced addition from a register. The result is written to Rd. + * + * **Description**:\n + * For the `DREDSA16` instruction, add the top 16-bit Q15 element from the bottom 16-bit Q15 element of the bottom 32-bit Q31 content of 64-bit chunks in Rs1. At the same time, subtract the the top16-bit Q15 element with the bottom16-bit Q15 element of the top 32-bit Q31 content of 64-bit chunks in Rs1. The two Q15 results are then written into Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[0] = Rs1.H[0] + Rs1.H[1] + * Rd.H[1] = Rs1.H[2] - Rs1.H[3] + * ~~~ + * + * \param [in] a unsigned long longtype of value stored in a + * \return value stored in unsigned long type + */ +__STATIC_FORCEINLINE unsigned long __RV_DREDSA16(unsigned long long a) +{ + unsigned long result; + __ASM volatile("dredsa16 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DREDSA16 ===== */ + +/* ===== Inline Function Start for DKCLIP64 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKCLIP64 (64-bit Clipped to 16-bit Saturation Value) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKCLIP64 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 15-bit element arithmetic right shift operations and limit result into 32-bit int,then do saturate operation to 16-bit and + * clip result to 16-bit Q15. + * + * **Description**:\n + * For the `DKCLIP64` instruction, shift the input 15 bits to the right and data convert the result to 32-bit int type, after + * which the input is saturated to limit the data to between 2^15-1 and -2^15. the result is converted to 16-bits q15 type. The + * final results are written to Rd. + * + * **Operations**:\n + * ~~~ + * const int32_t max = (int32_t)((1U << 15U) - 1U); + * const int32_t min = -1 - max ; + * int32_t val = (int32_t)(Rs s>> 15); + * if (val > max) { + * Rd = max; + * } else if (val < min) { + * Rd = min; + * } else { + * Rd = (int16_t)val; + * } + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in int16_t type + */ +__STATIC_FORCEINLINE int16_t __RV_DKCLIP64(unsigned long long a) +{ + int16_t result; + __ASM volatile("dkclip64 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DKCLIP64 ===== */ + +/* ===== Inline Function Start for DKMDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKMDA (Signed Multiply Two Halfs and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMDA Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then adds the two 32-bit results together. + * The addition result may be saturated. + * + * **Description**:\n + * This instruction multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of the + * 32-bit elements of Rs2 and then adds the result to the result of multiplying the top 16-bit content of the 32-bit elements of + * Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * The addition result is checked for saturation. If saturation happens, the result is saturated to 2^31-1 The final results are + * written to Rd. The 16-bit contents are treated as signed integers + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[x] != 0x80008000) or (Rs2.W[x] != 0x80008000){ + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[1]) + (Rs1.W[x].H[0] * Rs2.W[x].H[0]); + * } else { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMDA(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkmda %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKMDA ===== */ + +/* ===== Inline Function Start for DKMXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKMXDA (Signed Crossed Multiply Two Halfs and Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then adds the two 32-bit results together. + * The addition result may be saturated. + * * DKMXDA: top*bottom + top*bottom (per 32-bit element) + * + * **Description**:\n + * This instruction multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit + * elements of Rs2 and then adds the result to the result of multiplying the top 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2. + * The addition result is checked for saturation.If saturation happens, the result is saturated to 2^31-1 The final results are + * written to Rd. The 16-bit contents are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * if (Rs1.W[x] != 0x80008000) or (Rs2.W[x] != 0x80008000){ + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[0]) + (Rs1.W[x].H[0] * Rs2.W[x].H[1]); + * } else { + * Rd.W[x] = 0x7fffffff; + * OV = 1; + * } + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMXDA(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkmxda %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKMXDA ===== */ + +/* ===== Inline Function Start for DSMDRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMDRS (Signed Multiply Two Halfs and Reverse Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMDRS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then perform a subtraction operation + * between the two 32-bit results. + * * DSMDRS: bottom*bottom - top*top (per 32-bit element) + * + * **Description**:\n + * This instruction multiplies the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit + * elements of Rs2 and then subtracts the result from the result of multiplying the bottom 16-bit content of the 32-bit elements + * of Rs1 with the bottom 16-bit content of the 32-bit elements of Rs2. + * The subtraction result is written to the corresponding 32-bit element of Rd (The 16-bit contents of multiplication are + * treated as signed integers). + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x].H[0] * Rs2.W[x].H[0]) - (Rs1.W[x].H[1] * Rs2.W[x].H[1]); x = 1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMDRS(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsmdrs %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMDRS ===== */ + +/* ===== Inline Function Start for DSMXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMXDS (Signed Crossed Multiply Two Halfs and Subtract) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications from the 32-bit elements of two registers; and then perform a subtraction operation + * between the two 32-bit results. + * * DSMXDS: top*bottom - bottom*top (per 32-bit element) + * + * **Description**:\n + * This instruction multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit + * elements of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of the 32-bit elements + * of Rs1 with the bottom 16-bit content of the 32-bit elements of Rs2. + * The subtraction result is written to the corresponding 32-bit element of Rd. The 16-bit contents of multiplication are + * treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x].H[1] * Rs2.W[x].H[0]) - (Rs1.W[x].H[0] * Rs2.W[x].H[1]); x = 1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMXDS(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsmxds %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMXDS ===== */ + +/* ===== Inline Function Start for DSMBB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBB32 (Signed Multiply Bottom Word & Bottom Word) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register and write the 64-bit result to a third register. + * * DSMBB32: bottom*bottom + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit element of Rs2. The 64-bit multiplication result is written to Rd. + * The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]); + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBB32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBB32 ===== */ + +/* ===== Inline Function Start for DSMBB32.sra14 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBB32.sra14 (Signed Crossed Multiply Two Halfs and Subtract with Right Shift 14) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBB32.sra14 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register, then right shift 14- + * bit,finally write the 64-bit result to a third register. + * * DSMBB32.sra14: bottom*bottom s>> 14 + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit element of Rs2. The 64-bit multiplication result is written to Rd after right shift 14-bit. + * The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]) s>> 14; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBB32_SRA14(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbb32.sra14 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBB32.sra14 ===== */ + +/* ===== Inline Function Start for DSMBB32.sra32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBB32.sra32 (Signed Crossed Multiply Two Halfs and Subtract with Right Shift 32) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBB32.sra32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register, then right shift 32- + * bit,finally write the 64-bit result to a third register. + * * DSMBB32.sra32: bottom*bottom s >> 32 + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit element of Rs2. + * The 64-bit multiplication result is written to Rd after right shift 32-bit. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]) s>> 32; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBB32_SRA32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbb32.sra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBB32.sra32 ===== */ + +/* ===== Inline Function Start for DSMBT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief SMBT32 (Signed Multiply Bottom Word & Top Word) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBT32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register and write the 64-bit + * result to a third register. + * * DSMBT32: bottom*top + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]); + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBT32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBT32 ===== */ + +/* ===== Inline Function Start for DSMBT32.sra14 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBT32.sra14 (Signed Multiply Bottom Word & Top Word with Right Shift 14) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBT32.sra14 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register, then right shift 14- + * bit,finally write the 64-bit result to a third register. + * * DSMBT32.sra14: bottom*bottom s>> 14 + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd after right shift 14-bit. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]) s>> 14; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBT32_SRA14(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbt32.sra14 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBT32.sra14 ===== */ + +/* ===== Inline Function Start for DSMBT32.sra32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBT32.sra32 (Signed Crossed Multiply Two Halfs and Subtract with Right Shift 32) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBT32.sra32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register, then right shift 32- + * bit,finally write the 64-bit result to a third register. + * * DSMBT32.sra32: bottom*bottom s>> 32 + * + * **Description**:\n + * This instruction multiplies the bottom 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd after right shift 32-bit. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = (Rs1.W[0] * Rs2.W[0]) s>> 14; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMBT32_SRA32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmbt32.sra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBT32.sra32 ===== */ + +/* ===== Inline Function Start for DSMTT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMTT32 (Signed Multiply Top Word & Top Word) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMTT32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register and write the 64-bit + * result to a third register. + * * DSMTT32: top*top + * + * **Description**:\n + * This instruction multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[1] * Rs2.W[1]; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMTT32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmtt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMTT32 ===== */ + +/* ===== Inline Function Start for DSMTT32.sra14 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMTT32.sra14 (Signed Multiply Top Word & Top Word with Right Shift 14-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMTT32.sra14 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register,then right shift 14-bit, + * finally write the 64-bit result to a third register. + * * DSMTT32.sra14: top*top s>> 14 + * + * **Description**:\n + * This instruction multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd after right shift 14-bit. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[1] * Rs2.W[1] >> 14; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMTT32_SRA14(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmtt32.sra14 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMTT32.sra14 ===== */ + +/* ===== Inline Function Start for DSMTT32.sra32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMTT32.sra32 (Signed Multiply Top Word & Top Word with Right Shift 32-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMTT32.sra32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element of a register with the signed 32-bit element of another register,then right shift 32-bit, + * finally write the 64-bit result to a third register. + * * DSMTT32.sra32: top*top s>> 32 + * + * **Description**:\n + * This instruction multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. The 64-bit multiplication + * result is written to Rd after right shift 32-bit. The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rs1.W[1] * Rs2.W[1] >> 32; + * Rd = res; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMTT32_SRA32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmtt32.sra32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMTT32.sra32 ===== */ + +/* ===== Inline Function Start for DPKBB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKBB32 (Pack Two 32-bit Data from Both Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKBB32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * DPKBB32: bottom.bottom + * + * **Description**:\n + * This instruction moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[0], Rs2.W[0]); + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKBB32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpkbb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKBB32 ===== */ + +/* ===== Inline Function Start for DPKBT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKBT32 (Pack Two 32-bit Data from Bottom and Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKBT32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * DPKBT32: bottom.top + * + * **Description**:\n + * This instruction moves Rs1.W[0] to Rd.W[1] and moves Rs2.W[1] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[0], Rs2.W[1]); + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKBT32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpkbt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKBT32 ===== */ + +/* ===== Inline Function Start for DPKTT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKTT32 (Pack Two 32-bit Data from Both Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKTT32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * DPKTT32: top.top + * + * **Description**:\n + * This instruction moves Rs1.W[1] to Rd.W[0] and moves Rs2.W[1] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[1], Rs2.W[1]); + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKTT32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpktt32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKTT32 ===== */ + +/* ===== Inline Function Start for DPKTB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKTB32 (Pack Two 32-bit Data from Top and Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKTB32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 32-bit data from 64-bit chunks in two registers. + * * DPKTB32: top.bottom + * + * **Description**:\n + * This instruction moves Rs1.W[1] to Rd.W[1] and moves Rs2.W[0] to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W[1], Rs2.W[0]); + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKTB32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpktb32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKTB32 ===== */ + +/* ===== Inline Function Start for DPKTB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKTB16 (Pack Two 32-bit Data from Top and Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKTB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * DPKTB16: top.bottom + * + * **Description**:\n + * This instruction moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][15:0]); + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKTB16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpktb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKTB16 ===== */ + +/* ===== Inline Function Start for DPKBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKBB16 (Pack Two 16-bit Data from Both Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKBB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBB16: bottom.bottom + * + * **Description**:\n + * This instruction moves Rs1.W[x][15:0] to Rd.W[x][31:16] and moves Rs2.W[x] [15:0] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][15:0]); + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKBB16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpkbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKBB16 ===== */ + +/* ===== Inline Function Start for DPKBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKBT16 (Pack Two 16-bit Data from Bottom and Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKBT16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKBT16: bottom.top + * + * **Description**:\n + * This instruction moves Rs1.W[x] [15:0] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][15:0], Rs2.W[x][31:16]); + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKBT16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpkbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKBT16 ===== */ + +/* ===== Inline Function Start for DPKTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPKTT16 (Pack Two 16-bit Data from Both Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPKTT16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Pack 16-bit data from 32-bit chunks in two registers. + * * PKTT16 top.top + * + * **Description**:\n + * This instruction moves Rs1.W[x] [31:16] to Rd.W[x] [31:16] and moves Rs2.W[x] [31:16] to Rd.W[x] [15:0]. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:0] = CONCAT(Rs1.W[x][31:16], Rs2.W[x][31:16]); + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPKTT16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dpktt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPKTT16 ===== */ + +/* ===== Inline Function Start for DSRA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSRA16 (SIMD 16-bit Shift Right Arithmetic) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSRA16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit element arithmetic right shift operations simultaneously. The shift amount is a variable from a GPR. + * + * **Description**:\n + * The 16-bit data elements in Rs1 are right-shifted arithmetically, that is, the shifted out bits are filled with the sign-bit of + * the data elements. The shift amount is specified by the low-order 4-bits of the value in the Rs2 register. And the results + * are written to Rd. + * + * **Operations**:\n + * ~~~ + * sa = Rs2[3:0]; + * if (sa != 0) + * { + * Rd.H[x] = SE16(Rs1.H[x][15:sa]); + * } else { + * Rd = Rs1; + * } + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSRA16(unsigned long long a, unsigned long b) +{ + unsigned long long result; + __ASM volatile("dsra16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSRA16 ===== */ + +/* ===== Inline Function Start for DADD16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DADD16 (16-bit Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DADD16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit integer element additions simultaneously. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer elements in Rs1 with the 16-bit unsigned integer elements in Rs2. And + * the results are written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = Rs1.H[x] + Rs2.H[x]; + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DADD16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dadd16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DADD16 ===== */ + +/* ===== Inline Function Start for DADD32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DADD32 (32-bit Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DADD32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element additions simultaneously. + * + * **Description**:\n + * This instruction adds the 32-bit integer elements in Rs1 with the 32-bit integer elements in Rs2, and then writes the 32-bit + * element results to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x] + Rs2.W[x]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DADD32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dadd32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DADD32 ===== */ + +/* ===== Inline Function Start for DSMBB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBB16 (Signed Multiply Bottom Half & Bottom Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16-bit content of the 32-bit elements + * of another register and write the result to a third register. + * * DSMBB16: W[x].bottom*W[x].bottom + * + * **Description**:\n + * For the `DSMBB16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the bottom + * 16-bit content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[0]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMBB16(unsigned long long a, unsigned long long b) /* pass */ +{ + unsigned long long result; + __ASM volatile("dsmbb16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBB16 ===== */ + +/* ===== Inline Function Start for DSMBT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMBT16 (Signed Multiply Bottom Half & Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMBT16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16-bit content of the 32-bit + * elements of another register and write the result to a third register. + * * DSMBT16: W[x].bottom *W[x].top + * + * **Description**:\n + * For the `DSMBT16` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit + * content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[0] * Rs2.W[x].H[1]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMBT16(unsigned long long a, unsigned long long b) /* pass */ +{ + unsigned long long result; + __ASM volatile("dsmbt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMBT16 ===== */ + +/* ===== Inline Function Start for DSMTT16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSMTT16 (Signed Multiply Top Half & Top Half) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMTT16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the signed 16-bit content of the 32-bit + * elements of another register and write the result to a third register. + * * DSMTT16: W[x].top * W[x].top + * + * **Description**:\n + * For the `DSMTT16` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit + * content of the 32-bit elements of Rs2. + * The multiplication results are written to Rd. The 16-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = Rs1.W[x].H[1] * Rs2.W[x].H[1]; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMTT16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dsmtt16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMTT16 ===== */ + +/* ===== Inline Function Start for DRCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRCRSA16 (16-bit Signed Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRCRSA16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtraction and 16-bit signed integer element addition in a 32-bit chunk simultaneously. + * Operands are from crossed positions in 32-bit chunks. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer in [31:16] of 32-bit chunks in Rs1 with the 16-bit signed integer in + * [15:0] of 32-bit chunks in Rs2, and adds the 16-bit signed integer in [31:16] of 32-bit chunks in Rs2 from the 16-bit signed + * integer in [15:0] of 32-bit chunks in Rs1. The element results are first logically right-shifted by 1 bit and then written to + * [31:16] of 32- bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] - Rs2.W[x][15:0]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] + Rs2.W[x][31:16]) s>> 1; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRCRSA16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("drcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRCRSA16 ===== */ + +/* ===== Inline Function Start for DRCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRCRSA32 (32-bit Signed Halving Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRCRSA32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element subtraction and 32-bit signed integer element addition in a 64-bit chunk simultaneously. + * Operands are from crossed 32-bit elements. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer element in [63:32] of Rs1 with the 32-bit signed integer element in + * [31:0] of Rs2, and adds the 32-bit signed integer element in [63:32] of Rs2 from the 32-bit signed integer element in [31:0] + * of Rs1. The element results are first arithmetically right-shifted by 1 bit and then written to [63:32] of Rd for addition and + * [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] - Rs2.W[0]) s>> 1; + * Rd.W[0] = (Rs1.W[0] + Rs2.W[1]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRCRSA32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("drcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRCRSA32 ===== */ + +/* ===== Inline Function Start for DRCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRCRAS16 (16-bit Signed Halving Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRCRAS16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtraction and 16-bit signed integer element addition in a 32-bit chunk simultaneously. + * Operands are from crossed positions in 32-bit chunks. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs1 with the 16-bit unsigned integer in + * [15:0] of 32-bit chunks in Rs2, and subtracts the 16-bit unsigned integer in [31:16] of 32-bit chunks in Rs2 from the 16-bit + * unsigned integer in [15:0] of 32-bit chunks in Rs1. The element results are first logically right-shifted by 1 bit and then + * written to [31:16] of 32-bit chunks in Rd and [15:0] of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x][31:16] = (Rs1.W[x][31:16] + Rs2.W[x][15:0]) s>> 1; + * Rd.W[x][15:0] = (Rs1.W[x][15:0] - Rs2.W[x][31:16]) s>> 1; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRCRAS16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("drcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRCRAS16 ===== */ + +/* ===== Inline Function Start for DRCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRCRAS32 (32-bit Signed Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRCRAS32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element addition and 32-bit signed integer element subtraction in a 64-bit chunk simultaneously. + * Operands are from crossed 32-bit elements. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction adds the 32-bit signed integer element in [63:32] of Rs1 with the 32-bit signed integer element in [31:0] + * of Rs2, and subtracts the 32-bit signed integer element in [63:32] of Rs2 from the 32-bit signed integer element in [31:0] + * of Rs1. The element results are first arithmetically right-shifted by 1 bit and then written to [63:32] of Rd for addition + * and [31:0] of Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = (Rs1.W[1] + Rs2.W[0]) s>> 1; + * Rd.W[0] = (Rs1.W[0] - Rs2.W[1]) s>> 1; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRCRAS32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("DRCRAS32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRCRAS32 ===== */ + +/* ===== Inline Function Start for DKCRAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKCRAS16 (16-bit Signed Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKCRAS16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating addition and 16-bit signed integer element saturating subtraction in a 32-bit + * chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1 with the 16-bit signed integer + * element in [15:0] of 32-bit chunks in Rs2; at the same time, it subtracts the 16-bit signed integer element in [31:16] of + * 32-bit chunks in Rs2 from the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs1. + * If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV + * bit is set to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of 32-bit chunks + * in Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][31:16]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKCRAS16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkcras16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKCRAS16 ===== */ + +/* ===== Inline Function Start for DKCRSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKCRSA16 (16-bit Signed Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKCRSA16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating subtraction and 16-bit signed integer element saturating addition in a 32-bit + * chunk simultaneously. Operands are from crossed positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs2 from the 16-bit signed integer + * element in [31:16] of 32-bit chunks in Rs1; at the same time, it adds the 16-bit signed integer element in [31:16] of 32-bit + * chunks in Rs2 with the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs1. + * If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV + * bit is set to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for addition and [15:0] of 32-bit chunks + * in Rd for subtraction. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][15:0]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][31:16]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKCRSA16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkcrsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKCRSA16 ===== */ + +/* ===== Inline Function Start for DRSUB16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRSUB16 (16-bit Signed Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRSUB16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element subtractions simultaneously. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer elements in Rs2 from the 16-bit signed integer elements in Rs1. The + * results are first arithmetically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.H[x] = (Rs1.H[x] - Rs2.H[x]) s>> 1; + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRSUB16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("drsub16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRSUB16 ===== */ + +/* ===== Inline Function Start for DSTSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSTSA32 (32-bit Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSTSA32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtraction and 32-bit integer element addition in a 64-bit chunk simultaneously. Operands are + * from corresponding 32-bit elements. + * + * **Description**:\n + * This instruction subtracts the 32-bit integer element in [63:32] of Rs2 from the 32-bit integer element in [63:32] of Rs1, + * and writes the result to [63:32] of Rd; at the same time, it adds the 32-bit integer element in [31:0] of Rs1 with the 32-bit + * integer element in [31:0] of Rs2, and writes the result to [31:0] of Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] - Rs2.W[1]; + * Rd.W[0] = Rs1.W[0] + Rs2.W[0]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSTSA32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dstsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSTSA32 ===== */ + +/* ===== Inline Function Start for DSTAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSTAS32 (SIMD 32-bit Straight Addition & Subtractionn) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSTAS32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element addition and 32-bit integer element subtraction in a 64-bit chunk simultaneously. Operands are + * from corresponding 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit integer element in [63:32] of Rs2, + * and writes the result to [63:32] of Rd; at the same time, it subtracts the 32-bit integer element in [31:0] of Rs2 + * from the 32-bit integer element in [31:0] of Rs1, and writes the result to [31:0] of Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[1] = Rs1.W[1] + Rs2.W[1]; + * Rd.W[0] = Rs1.W[0] - Rs2.W[0]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSTAS32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("DSTAS32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSTAS32 ===== */ + +/* ===== Inline Function Start for DKCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKCRSA32 (32-bit Signed Saturating Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKCRSA32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating subtraction and 32-bit signed integer element saturating addition in a 64-bit + * chunk simultaneously. Operands are from crossed 32-bit elements. + * + * **Description**:\n + * This instruction subtracts the 32-bit integer element in [31:0] of Rs2 from the 32-bit integer element in [63:32] of Rs1; at + * the same time, it adds the 32-bit integer element in [31:0] of Rs1 with the 32-bit integer element in [63:32] of Rs2. If any + * of the results are beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV bit is + * set to 1. The saturated results are written to [63:32] of Rd for subtraction and [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] - Rs2.W[0]; + * res[0] = Rs1.W[0] + Rs2.W[1]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKCRSA32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKCRSA32 ===== */ + +/* ===== Inline Function Start for DKCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKCRAS32 (32-bit Signed Saturating Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKCRAS32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element saturating subtraction and 32-bit signed integer element saturating addition in a 64-bit + * chunk simultaneously. Operands are from crossed 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [31:0] of Rs2 from the 32-bit integer element in [63:32] of Rs1; at the + * same time, it subtracts the 32-bit integer element in [31:0] of Rs1 with the 32-bit integer element in [63:32] of Rs2. If any + * of the results are beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), they are saturated to the range and the OV bit is + * set to 1. The saturated results are written to [63:32] of Rd for subtraction and [31:0] of Rd for addition. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] + Rs2.W[0]; + * res[0] = Rs1.W[0] - Rs2.W[1]; + * if (res[x] > (2^31)-1) { + * res[x] = (2^31)-1; + * OV = 1; + * } else if (res < -2^31) { + * res[x] = -2^31; + * OV = 1; + * } + * Rd.W[1] = res[1]; + * Rd.W[0] = res[0]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKCRAS32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKCRAS32 ===== */ + +/* ===== Inline Function Start for DCRSA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DCRSA32 (32-bit Cross Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DCRSA32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element subtraction and 32-bit integer element addition in a 64-bit chunk simultaneously. Operands are + * from crossed 32-bit elements. + * + * **Description**:\n + * This instruction adds the 32-bit integer element in [63:32] of Rs1 with the 32-bit integer element in [31:0] of Rs2, and + * writes the result to [63:32] of Rd; at the same time, it subtracts the 32-bit integer element in [63:32] of Rs2 from the 32-bit + * integer element in [31:0] of Rs1, and writes the result to [31:0] of Rd. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] - Rs2.W[0]; + * res[0] = Rs1.W[0] + Rs2.W[1]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DCRSA32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dcrsa32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DCRSA32 ===== */ + +/* ===== Inline Function Start for DCRAS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DCRAS32 (32-bit Cross Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DCRAS32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit integer element addition and 32-bit integer element subtraction in a 64-bit chunk simultaneously. Operands are + * from crossed 32-bit elements. + * + * **Description**:\n + * This instruction subtracts the 32-bit integer element in [63:32] of Rs1 with the 32-bit integer element in [31:0] of Rs2, and + * writes the result to [63:32] of Rd; at the same time, it adds the 32-bit integer element in [63:32] of Rs2 from the 32-bit + * integer element in [31:0] of Rs1, and writes the result to [31:0] of Rd. + * + * **Operations**:\n + * ~~~ + * res[1] = Rs1.W[1] - Rs2.W[0]; + * res[0] = Rs1.W[0] + Rs2.W[1]; + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DCRAS32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dcras32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DCRAS32 ===== */ + +/* ===== Inline Function Start for DKSTSA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKSTSA16 (16-bit Signed Saturating Straight Subtraction & Addition) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSTSA16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating subtraction and 16-bit signed integer element saturating addition in a 32-bit + * chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction subtracts the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs2 from the 16-bit signed integer + * element in [31:16] of 32-bit chunks in Rs1; at the same time, it adds the 16-bit signed integer element in [15:0] of 32-bit + * chunks in Rs2 with the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs1. + * If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV + * bit is set to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of 32-bit chunks + * in Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] - Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] + Rs2.W[x][15:0]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSTSA16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkstsa16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSTSA16 ===== */ + +/* ===== Inline Function Start for DKSTAS16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DKSTAS16 (16-bit Signed Saturating Straight Addition & Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSTAS16 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 16-bit signed integer element saturating addition and 16-bit signed integer element saturating subtraction in a 32-bit + * chunk simultaneously. Operands are from corresponding positions in 32-bit chunks. + * + * **Description**:\n + * This instruction adds the 16-bit signed integer element in [31:16] of 32-bit chunks in Rs1 with the 16-bit signed integer + * element in [31:16] of 32-bit chunks in Rs2; at the same time, it subtracts the 16-bit signed integer element in [15:0] of + * 32-bit chunks in Rs2 from the 16-bit signed integer element in [15:0] of 32-bit chunks in Rs1. + * If any of the results are beyond the Q15 number range (-2^15 <= Q15 <= 2^15-1), they are saturated to the range and the OV + * bit is set to 1. The saturated results are written to [31:16] of 32-bit chunks in Rd for subtraction and [15:0] of 32-bit chunks + * in Rd for addition. + * + * **Operations**:\n + * ~~~ + * res1 = Rs1.W[x][31:16] + Rs2.W[x][31:16]; + * res2 = Rs1.W[x][15:0] - Rs2.W[x][15:0]; + * for (res in [res1, res2]) { + * if (res > (2^15)-1) { + * res = (2^15)-1; + * OV = 1; + * } else if (res < -2^15) { + * res = -2^15; + * OV = 1; + * } + * } + * Rd.W[x][31:16] = res1; + * Rd.W[x][15:0] = res2; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSTAS16(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("dkstas16 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKSTAS16 ===== */ + +/* ===== Inline Function Start for DSCLIP8 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSCLIP8 (8-bit Signed Saturation and Clip) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSCLIP8 Rd, Rs1, imm3u[2:0] + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Limit the 8-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 8-bit signed integer elements stored in Rs1 into a signed integer range between -2^imm3u and + * 2^imm3u-1, and writes the limited results to Rd. For example, if imm3u is 3, the 8-bit input values should be saturated + * between 7 and -8. If saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.B[x]; + * if (src > (2^imm3u)-1) { + * src = (2^imm3u)-1; + * OV = 1; + * } else if (src < -2^imm3u) { + * src = -2^imm3u; + * OV = 1; + * } + * Rd.B[x] = src + * x=7...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +#define __RV_DSCLIP8(a, b) \ + ({ \ + unsigned long long result; \ + unsigned long long __a = (unsigned long long)(a); \ + __ASM volatile("dsclip8 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for DSCLIP8 ===== */ + +/* ===== Inline Function Start for DSCLIP16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSCLIP16 (16-bit Signed Saturation and Clip) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSCLIP16 Rd, Rs1, imm4u[3:0] + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Limit the 16-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 16-bit signed integer elements stored in Rs1 into a signed integer range between -2^imm4u and + * 2^imm4u-1, and writes the limited results to Rd. For example, if imm4u is 3, the 32-bit input values should be saturated + * between 7 and -8. If saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.H[x]; + * if (src > (2^imm4u)-1) { + * src = (2^imm4u)-1; + * OV = 1; + * } else if (src < -2^imm4u) { + * src = -2^imm4u; + * OV = 1; + * } + * Rd.H[x] = src + * x=3...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +#define __RV_DSCLIP16(a, b) \ + ({ \ + unsigned long long result; \ + unsigned long long __a = (unsigned long long)(a); \ + __ASM volatile("dsclip16 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for DSCLIP16 ===== */ + +/* ===== Inline Function Start for DSCLIP32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSCLIP32 (32-bit Signed Saturation and Clip) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSCLIP32 Rd, Rs1, imm5u[4:0] + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Limit the 32-bit signed integer elements of a register into a signed range simultaneously. + * + * **Description**:\n + * This instruction limits the 32-bit signed integer elements stored in Rs1 into a signed integer range between -2^imm5u and + * 2^imm5u-1, and writes the limited results to Rd. For example, if imm5u is 3, the 32-bit input values should be saturated + * between 7 and -8. If saturation is performed, set OV bit to 1. + * + * **Operations**:\n + * ~~~ + * src = Rs1.W[x]; + * if (src > (2^imm5u)-1) { + * src = (2^imm5u)-1; + * OV = 1; + * } else if (src < -2^imm5u) { + * src = -2^imm5u; + * OV = 1; + * } + * Rd.W[x] = src + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +#define __RV_DSCLIP32(a, b) \ + ({ \ + unsigned long long result; \ + unsigned long long __a = (unsigned long long)(a); \ + __ASM volatile("dsclip32 %0, %1, %2" : "=r"(result) : "r"(__a), "K"(b)); \ + result; \ + }) +/* ===== Inline Function End for DSCLIP32 ===== */ + +/* ===== Inline Function Start for DRSUB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DRSUB32 (32-bit Signed Halving Subtraction) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DRSUB32 Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do 32-bit signed integer element subtractions simultaneously. The results are halved to avoid overflow or saturation. + * + * **Description**:\n + * This instruction subtracts the 32-bit signed integer elements in Rs2 from the 32-bit signed integer elements in Rs1. The + * results are first arithmetically right-shifted by 1 bit and then written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[x] = (Rs1.W[x] - Rs2.W[x]) s>> 1; + * x=1...0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DRSUB32(unsigned long long a, unsigned long long b) +{ + unsigned long long result; + __ASM volatile("drsub32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DRSUB32 ===== */ + +/* ===== Inline Function Start for DPACK32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DPACK32 (SIMD Pack Two 32-bit Data To 64-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DPACK32 Rd, Rs1, Rs2 + * # Rd is even/odd pair of register + * ~~~ + * + * **Purpose**:\n + * Pack two 32-bit datas which from two registers into a 64-bit data. + * + * **Description**:\n + * This instruction moves 32-bit Rs1 to Rd.W[1] and moves 32-bit Rs2 to Rd.W[0]. + * + * **Operations**:\n + * ~~~ + * Rd = CONCAT(Rs1.W , Rs2.W); + * ~~~ + * + * \param [in] a signed long type of value stored in a + * \param [in] b signed long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DPACK32(signed long a, signed long b) +{ + unsigned long long result; + __ASM volatile("dpack32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DPACK32 ===== */ + +/* ===== Inline Function Start for DSUNPKD810 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUNPKD810 (Signed Unpacking Bytes 1 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUNPKD810 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 1 and byte 0 of 32-bit chunks in a register into two 16-bit signed halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DSUNPKD810` instruction, it unpacks byte 1 and byte 0 of 32-bit chunks in Rs1 into two 16-bit signed halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[1]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUNPKD810(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dsunpkd810 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DSUNPKD810 ===== */ + +/* ===== Inline Function Start for DSUNPKD820 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUNPKD820 (Signed Unpacking Bytes 2 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUNPKD820 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 2 and byte 0 of 32-bit chunks in a register into two 16-bit signed halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DSUNPKD820` instruction, it unpacks byte 2 and byte 0 of 32-bit chunks in Rs1 into two 16-bit signed halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[2]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUNPKD820(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dsunpkd820 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DSUNPKD820 ===== */ + +/* ===== Inline Function Start for DSUNPKD830 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUNPKD830 (Signed Unpacking Bytes 3 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUNPKD830 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 0 of 32-bit chunks in a register into two 16-bit signed halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DSUNPKD830` instruction, it unpacks byte 3 and byte 0 of 32-bit chunks in Rs1 into two 16-bit signed halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUNPKD830(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dsunpkd830 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DSUNPKD830 ===== */ + +/* ===== Inline Function Start for DSUNPKD831 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUNPKD831 (Signed Unpacking Bytes 3 & 1) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUNPKD831 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 1 of 32-bit chunks in a register into two 16-bit signed halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DSUNPKD831` instruction, it unpacks byte 3 and byte 1 of 32-bit chunks in Rs1 into two 16-bit signed halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[1]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUNPKD831(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dsunpkd831 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DSUNPKD831 ===== */ + +/* ===== Inline Function Start for DSUNPKD832 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DSUNPKD832 (Signed Unpacking Bytes 3 & 2) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSUNPKD832 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 2 of 32-bit chunks in a register into two 16-bit signed halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DSUNPKD832` instruction, it unpacks byte 3 and byte 2 of 32-bit chunks in Rs1 into two 16-bit signed halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[2]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSUNPKD832(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dsunpkd832 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DSUNPKD832 ===== */ + +/* ===== Inline Function Start for DZUNPKD810 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DZUNPKD810 (UnSigned Unpacking Bytes 1 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DZUNPKD810 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 1 and byte 0 of 32-bit chunks in a register into two 16-bit unsigned halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DZUNPKD810` instruction, it unpacks byte 1 and byte 0 of 32-bit chunks in Rs1 into two 16-bit unsigned halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[1]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DZUNPKD810(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dzunpkd810 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DZUNPKD810 ===== */ + +/* ===== Inline Function Start for DZUNPKD820 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DZUNPKD820 (UnSigned Unpacking Bytes 2 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DZUNPKD820 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 2 and byte 0 of 32-bit chunks in a register into two 16-bit unsigned halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DZUNPKD820` instruction, it unpacks byte 2 and byte 0 of 32-bit chunks in Rs1 into two 16-bit unsigned halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[2]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DZUNPKD820(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dzunpkd820 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DZUNPKD820 ===== */ + +/* ===== Inline Function Start for DZUNPKD830 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DZUNPKD830 (UnSigned Unpacking Bytes 3 & 0) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DZUNPKD830 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 0 of 32-bit chunks in a register into two 16-bit unsigned halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DZUNPKD830` instruction, it unpacks byte 3 and byte 0 of 32-bit chunks in Rs1 into two 16-bit unsigned halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[0]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DZUNPKD830(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dzunpkd830 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DZUNPKD830 ===== */ + +/* ===== Inline Function Start for DZUNPKD831 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DZUNPKD831 (UnSigned Unpacking Bytes 3 & 1) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DZUNPKD831 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 1 of 32-bit chunks in a register into two 16-bit unsigned halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DZUNPKD831` instruction, it unpacks byte 3 and byte 1 of 32-bit chunks in Rs1 into two 16-bit unsigned halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[1]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DZUNPKD831(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dzunpkd831 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DZUNPKD831 ===== */ + +/* ===== Inline Function Start for DZUNPKD832 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N2 + * \brief DZUNPKD832 (UnSigned Unpacking Bytes 3 & 2) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DZUNPKD832 Rd, Rs1 + * # Rd, Rs1 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Unpack byte 3 and byte 2 of 32-bit chunks in a register into two 16-bit unsigned halfwords of 32-bit chunks in a register. + * + * **Description**:\n + * For the `DZUNPKD832` instruction, it unpacks byte 3 and byte 2 of 32-bit chunks in Rs1 into two 16-bit unsigned halfwords + * and writes the results to the top part and the bottom part of 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * Rd.W[m].H[1] = SE16(Rs1.W[m].B[3]) + * Rd.W[m].H[0] = SE16(Rs1.W[m].B[2]) + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DZUNPKD832(unsigned long long a) +{ + unsigned long long result; + __ASM volatile("dzunpkd832 %0, %1" : "=r"(result) : "r"(a)); + return result; +} +/* ===== Inline Function End for DZUNPKD832 ===== */ + +/* ===== Inline Function Start for DKMMAC ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMMAC (64-bit MSW 32x32 Signed Multiply and Saturating Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMMAC Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element signed multiplications and saturating addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and adds the most significant 32-bit multiplication results with the signed 32-bit elements of Rd. If + * the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range + * and the OV bit is set to 1. The results after saturation are written to Rd. The .u form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * res = sat.q31(dop + (aop s* bop)[63:32]); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMMAC(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmmac %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMMAC ===== */ + +/* ===== Inline Function Start for DKMMAC.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMMAC.u (64-bit MSW 32x32 Unsigned Multiply and Saturating Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMMAC.u Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element unsigned multiplications and saturating addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and adds the most significant 32-bit multiplication results with the signed 32-bit elements of Rd. If + * the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range + * and the OV bit is set to 1. The results after saturation are written to Rd. The .u form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * res = sat.q31(dop + RUND(aop u* bop)[63:32]); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMMAC_U(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmmac.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMMAC.u ===== */ + +/* ===== Inline Function Start for DKMMSB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMMSB (64-bit MSW 32x32 Signed Multiply and Saturating Sub) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMMSB Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element signed multiplications and saturating subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and subtracts the most significant 32-bit multiplication results from the signed 32-bit elements of + * Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the + * range and the OV bit is set to 1. The results after saturation are written to Rd. The .u form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * res = sat.q31(dop - (aop s* bop)[63:32]); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMMSB(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmmsb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMMSB ===== */ + +/* ===== Inline Function Start for DKMMSB.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMMSB.u (64-bit MSW 32x32 Unsigned Multiply and Saturating Sub) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMMSB.u Rd, Rs1, Rs2 + * # Rd, Rs1, Rs2 are all even/odd pair of registers + * ~~~ + * + * **Purpose**:\n + * Do MSW 32x32 element unsigned multiplications and saturating subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 + * and subtracts the most significant 32-bit multiplication results from the signed 32-bit elements of + * Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the + * range and the OV bit is set to 1. The results after saturation are written to Rd. The .u form of the + * instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by + * adding a 1 to bit 31 of the results. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * res = sat.q31(dop - (aop u* bop)[63:32]); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMMSB_U(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmmsb.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMMSB.u ===== */ + +/* ===== Inline Function Start for DKMADA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADA (Saturating Signed Multiply Two Halfs and Two Adds) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two 16x16 with 32-bit signed double addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then adds the result to the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[1]; + * mul2 = aop.H[0] s* bop.H[0]; + * res = sat.q31(dop + mul1 + mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMADA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmada %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADA ===== */ + +/* ===== Inline Function Start for DKMAXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMAXDA (Two Cross 16x16 with 32-bit Signed Double Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMAXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross 16x16 with 32-bit signed double addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32-bit + * elements in Rs2 and then adds the result to the result of multiplying the bottom 16-bit content of + * 32-bit elements in Rs1 with the top 16-bit content of 32-bit elements in elements in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[0]; + * mul2 = aop.H[0] s* bop.H[1]; + * res = sat.q31(dop + mul1 + mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMAXDA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmaxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMAXDA ===== */ + +/* ===== Inline Function Start for DKMADS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADS (Two 16x16 with 32-bit Signed Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two 16x16 with 32-bit signed addition and subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of 32-bit elements in Rs1 with + * the bottom 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the top 16-bit content of 32-bit elements in Rs1 with the top 16-bit content of 32-bit + * elements in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[1]; + * mul2 = aop.H[0] s* bop.H[0]; + * res = sat.q31(dop + mul1 - mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMADS(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmads %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADS ===== */ + +/* ===== Inline Function Start for DKMADRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADRS (Two 16x16 with 32-bit Signed Add and Reversed Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADRS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two 16x16 with 32-bit signed addition and revered subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * it multiplies the top 16-bit content of 32-bit elements in Rs1 with the + * top 16-bit content of 32-bit elements in Rs2 and then subtracts the result from the result of + * multiplying the bottom 16-bit content of 32-bit elements in Rs1 with the bottom 16-bit content of 32- + * bit elements in Rs2 + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[1]; + * mul2 = aop.H[0] s* bop.H[0]; + * res = sat.q31(dop - mul1 + mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMADRS(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmadrs %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADRS ===== */ + +/* ===== Inline Function Start for DKMAXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMAXDS (Saturating Signed Crossed Multiply Two Halfs & Subtract & Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMAXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross 16x16 with 32-bit signed addition and subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * Do two signed 16-bit multiplications from 32-bit elements in two registers; and then + * perform a subtraction operation between the two 32-bit results. Then add the subtraction result to + * the corresponding 32-bit elements in a third register. The addition result may be saturated. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[0]; + * mul2 = aop.H[0] s* bop.H[1]; + * res = sat.q31(dop + mul1 - mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMAXDS(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmaxds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMAXDS ===== */ + +/* ===== Inline Function Start for DKMSDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMSDA (Two 16x16 with 32-bit Signed Double Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMSDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two 16x16 with 32-bit signed double subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the bottom 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of + * the 32-bit elements of Rs1 with the top 16-bit content of the 32-bit elements of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[0]; + * mul2 = aop.H[0] s* bop.H[1]; + * res = sat.q31(dop - mul1 - mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMSDA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmsda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMSDA ===== */ + +/* ===== Inline Function Start for DKMSXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMSXDA (Two Cross 16x16 with 32-bit Signed Double Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMSXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross 16x16 with 32-bit signed double subtraction simultaneously. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of the 32-bit elements of Rs1 + * with the top 16-bit content of the 32-bit elements of Rs2 and multiplies the top 16-bit content of the + * 32-bit elements of Rs1 with the bottom 16-bit content of the 32-bit elements of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * mul1 = aop.H[1] s* bop.H[0]; + * mul2 = aop.H[0] s* bop.H[1]; + * res = sat.q31(dop - mul1 - mul2); + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKMSXDA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmsxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMSXDA ===== */ + +/* ===== Inline Function Start for DSMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMAQA (Four Signed 8x8 with 32-bit Signed Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 8x8 with 32-bit signed addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the four signed 8-bit elements of 32-bit chunks of Rs1 with the four + * signed 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the signed + * content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * m0 = aop.B[0] s* bop.B[0]; + * m1 = aop.B[1] s* bop.B[1]; + * m2 = aop.B[2] s* bop.B[2]; + * m3 = aop.B[3] s* bop.B[3]; + * res = dop + m0 + m1 + m2 + m3; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMAQA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMAQA ===== */ + +/* ===== Inline Function Start for DSMAQA.SU ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMAQA.SU (Four Signed 8 x Unsigned 8 with 32-bit Signed Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMAQA.SU Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four Signed 8 x Unsigned 8 with 32-bit unsigned addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the four unsigned 8-bit elements of 32-bit chunks of Rs1 with the four + * signed 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the unsigned + * content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * m0 = aop.B[0] su* bop.B[0]; + * m1 = aop.B[1] su* bop.B[1]; + * m2 = aop.B[2] su* bop.B[2]; + * m3 = aop.B[3] su* bop.B[3]; + * res = dop + m0 + m1 + m2 + m3; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DSMAQA_SU(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmaqa.su %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMAQA.SU ===== */ + +/* ===== Inline Function Start for DUMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DUMAQA (Four Unsigned 8x8 with 32-bit Unsigned Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DUMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four unsigned 8x8 with 32-bit unsigned addition simultaneously. The results are written into Rd. + * + * **Description**:\n + * This instruction multiplies the four unsigned 8-bit elements of 32-bit chunks of Rs1 with the four + * unsigned 8-bit elements of 32-bit chunks of Rs2 and then adds the four results together with the + * unsigned content of the corresponding 32-bit chunks of Rd. The final results are written back to the + * corresponding 32-bit chunks in Rd. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; op3t = Rd.W[x+1] // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; op3b = Rd.W[x] // bottom + * + * for ((aop,bop,dop,res) in [(op1t,op2t,op3t,rest), (op1b,op2b,op3b,resb)]) { + * m0 = aop.B[0] su* bop.B[0]; + * m1 = aop.B[1] su* bop.B[1]; + * m2 = aop.B[2] su* bop.B[2]; + * m3 = aop.B[3] su* bop.B[3]; + * res = dop + m0 + m1 + m2 + m3; + * } + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DUMAQA(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dumaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DUMAQA ===== */ + +/* ===== Inline Function Start for DKMDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMDA32 (Two Signed 32x32 with 64-bit Saturation Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 add the signed multiplication results with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * For the `KMDA32` instruction, it multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the top 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * t0 = op1b s* op2b; + * t1 = op1t s* op2t; + * Rd = concat(rest, resb); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMDA32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dkmda32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKMDA32 ===== */ + +/* ===== Inline Function Start for DKMXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMXDA32 (Two Cross Signed 32x32 with 64-bit Saturation Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and add the signed multiplication results with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the bottom 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * t01 = op1b s* op2t; + * t10 = op1t s* op2b; + * Rd = sat.q63(t01 + t10); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMXDA32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dkmxda32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DKMXDA32 ===== */ + +/* ===== Inline Function Start for DKMADA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADA32 (Two Signed 32x32 with 64-bit Saturation Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add the signed multiplication results and a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then adds the result to the result of multiplying the top 32-bit element of Rs1 + * with the top 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * t01 = op1b s* op2b; + * t10 = op1t s* op2t; + * Rd = sat.q63(t01 + t10); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMADA32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmada32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADA32 ===== */ + +/* ===== Inline Function Start for DKMAXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMAXDA32 (Two Cross Signed 32x32 with 64-bit Saturation Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMAXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and add the signed multiplication results and a third register with Q63 saturation. The + * results are written into Rd. + * + * **Description**:\n + * It multiplies the top 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then adds the result to the result of multiplying the bottom 32-bit element in Rs1 + * with the top 32-bit element in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * t01 = op1b s* op2t; + * t10 = op1t s* op2b; + * Rd = sat.q63(Rd + t01 + t10); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMAXDA32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmaxda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMAXDA32 ===== */ + +/* ===== Inline Function Start for DKMADS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADS32 (Two Signed 32x32 with 64-bit Saturation Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add the top signed multiplication results and subtraction bottom signed multiplication results + * and add a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 32-bit element in Rs1 with the bottom 32-bit + * element in Rs2 and then subtracts the result to the result of multiplying the top 32-bit element in Rs1 + * with the top 32-bit element in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t0 = op1b s* op2b; + * t1 = op1t s* op2t; + * Rd = sat.q63(Rd - t0 + t1); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMADS32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmads32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADS32 ===== */ + +/* ===== Inline Function Start for DKMADRS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMADRS32 (Two Signed 32x32 with 64-bit Saturation Revered Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMADRS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add the signed multiplication results and a third register with Q63 saturation. The results + * are written into Rd.Do two signed 32x32 and subtraction the top signed multiplication results and add bottom signed + * multiplication results and add a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element in Rs1 with the bottom 32-bit element in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * t0 = op1b s* op2b; + * t1 = op1t s* op2t; + * Rd = sat.q63(Rd + t0 - t1); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMADRS32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmadrs32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMADRS32 ===== */ + +/* ===== Inline Function Start for DKMAXDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMAXDS32 (Two Cross Signed 32x32 with 64-bit Saturation Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMAXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add the top signed multiplication results and subtraction bottom signed multiplication results + * and add a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element in Rs1 with the top 32-bit + * element in Rs2 and then subtracts the result from the result of multiplying the top 32-bit element in + * Rs1 with the bottom 32-bit element in Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t01 = op1b s* op2t; + * t10 = op1t s* op2b; + * Rd = sat.q63(Rd - t01 + t10); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMAXDS32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmaxds32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMAXDS32 ===== */ + +/* ===== Inline Function Start for DKMSDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMSDA32 (Two Signed 32x32 with 64-bit Saturation Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMSDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and subtraction the top signed multiplication results and subtraction bottom signed multiplication + * results and add a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the top 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t0 = op1b s* op2b; + * t1 = op1t s* op2t; + * Rd = sat.q63(Rd - t0 - t1); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMSDA32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmsda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMSDA32 ===== */ + +/* ===== Inline Function Start for DKMSXDA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMSXDA32 (Two Cross Signed 32x32 with 64-bit Saturation Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DKMSXDA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and subtraction the top signed multiplication results and subtraction bottom signed multiplication + * results and add a third register with Q63 saturation. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and multiplies the top 32-bit element of Rs1 with the bottom 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t0 = op1b s* op2t; + * t1 = op1t s* op2b; + * Rd = sat.q63(Rd - t0 - t1); + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMSXDA32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmsxda32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMSXDA32 ===== */ + +/* ===== Inline Function Start for DSMDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMDS32 (Two Signed 32x32 with 64-bit Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add the top signed multiplication results and subtraction bottom signed multiplication. The + * results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the bottom 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the top 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t0 = op1b s* op2t; + * t1 = op1t s* op2b; + * Rd = t1 - t0; + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMDS32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmds32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMDS32 ===== */ + +/* ===== Inline Function Start for DSMDRS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMDRS32 (Two Signed 32x32 with 64-bit Revered Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMDRS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and subtraction the top signed multiplication results and add bottom signed multiplication. The results are written into Rd + * + * **Description**:\n + * It multiplies the top 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the bottom 32-bit + * element of Rs1 with the bottom 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t0 = op1b s* op2b; + * t1 = op1t s* op2t; + * Rd = t1 - t0; + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMDRS32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmdrs32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMDRS32 ===== */ + +/* ===== Inline Function Start for DSMXDS32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMXDS32 (Two Cross Signed 32x32 with 64-bit Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMXDS32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and add the top signed multiplication results and subtraction bottom signed multiplication. + * The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 32-bit element of Rs1 with the top 32-bit + * element of Rs2 and then subtracts the result from the result of multiplying the top 32-bit element of + * Rs1 with the bottom 32-bit element of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * t01 = op1b s* op2t; + * t10 = op1t s* op2b; + * Rd = t1 - t0; + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMXDS32(unsigned long long a, unsigned long long b) +{ + long long result; + __ASM volatile("dsmxds32 %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMXDS32 ===== */ + +/* ===== Inline Function Start for DSMALDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALDA (Four Signed 16x16 with 64-bit Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMALDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 16x16 and add signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the top 16-bit content of Rs1 with + * the top 16-bit content of Rs2 with unlimited precision + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[0] s* op2b.H[0]; + * m1 = op1b.H[1] s* op2b.H[1]; + * m2 = op1t.H[0] s* op2t.H[0]; + * m3 = op1t.H[1] s* op2t.H[1]; + * + * Rd = Rd + m0 + m1 + m2 + m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALDA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALDA ===== */ + +/* ===== Inline Function Start for DSMALXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALXDA (Four Signed 16x16 with 64-bit Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMALXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four cross signed 16x16 and add signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then adds the result to the result of multiplying the bottom 16-bit content of Rs1 + * with the top 16-bit content of Rs2 with unlimited precision. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[0] s* op2b.H[1]; + * m1 = op1b.H[1] s* op2b.H[0]; + * m2 = op1t.H[0] s* op2t.H[1]; + * m3 = op1t.H[1] s* op2t.H[0]; + * + * Rd = Rd + m0 + m1 + m2 + m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALXDA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALXDA ===== */ + +/* ===== Inline Function Start for DSMALDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALDS (Four Signed 16x16 with 64-bit Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMALDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 16x16 and add and subtraction signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the top 16-bit content of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[1] s* op2b.H[1]; + * m1 = op1b.H[0] s* op2b.H[0]; + * m2 = op1t.H[1] s* op2t.H[1]; + * m3 = op1t.H[0] s* op2t.H[0]; + * + * Rd = Rd + m0 - m1 + m2 - m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALDS(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALDS ===== */ + +/* ===== Inline Function Start for DSMALDRS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALDRS (Four Signed 16x16 with 64-bit Add and Revered Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMALDRS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16x16 and add and revered subtraction signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 16-bit content of Rs1 with the top 16-bit content + * of Rs2 and then subtracts the result from the result of multiplying the bottom 16-bit content of Rs1 + * with the bottom 16-bit content of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[0] s* op2b.H[0]; + * m1 = op1b.H[1] s* op2b.H[1]; + * m2 = op1t.H[0] s* op2t.H[0]; + * m3 = op1t.H[1] s* op2t.H[1]; + * + * Rd = Rd + m0 - m1 + m2 - m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALDRS(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmaldrs %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALDRS ===== */ + +/* ===== Inline Function Start for DSMALXDS ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALXDS (Four Cross Signed 16x16 with 64-bit Add and Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMALXDS Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four cross signed 16x16 and add and subtraction signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of Rs1 with the top 16-bit + * content of Rs2 and then subtracts the result from the result of multiplying the top 16-bit content of + * Rs1 with the bottom 16-bit content of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[1] s* op2b.H[0]; + * m1 = op1b.H[0] s* op2b.H[1]; + * m2 = op1t.H[1] s* op2t.H[0]; + * m3 = op1t.H[0] s* op2t.H[1]; + * + * Rd = Rd + m0 - m1 + m2 - m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALXDS(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalxds %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALXDS ===== */ + +/* ===== Inline Function Start for DSMSLDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMSLDA (Four Signed 16x16 with 64-bit Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMSLDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 16x16 and subtraction signed multiplication results and add a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit + * content Rs2 and multiplies the top 16-bit content of Rs1 with the top 16-bit content of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[0] s* op2b.H[0]; + * m1 = op1b.H[1] s* op2b.H[1]; + * m2 = op1t.H[0] s* op2t.H[0]; + * m3 = op1t.H[1] s* op2t.H[1]; + * + * Rd = Rd - m0 - m1 - m2 - m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMSLDA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmslda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMSLDA ===== */ + +/* ===== Inline Function Start for DSMSLXDA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMSLXDA (Four Cross Signed 16x16 with 64-bit Sub) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMSLXDA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do four signed 16x16 and subtraction signed multiplication results and add a third register. The results are written into Rd. + * + * **Description**:\n + * It multiplies the top 16-bit content of Rs1 with the bottom 16-bit + * content of Rs2 and multiplies the bottom 16-bit content of Rs1 with the top 16-bit content of Rs2. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.H[0] s* op2b.H[1]; + * m1 = op1b.H[1] s* op2b.H[0]; + * m2 = op1t.H[0] s* op2t.H[1]; + * m3 = op1t.H[1] s* op2t.H[0]; + * + * Rd = Rd - m0 - m1 - m2 - m3; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMSLXDA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmslxda %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMSLXDA ===== */ + +/* ===== Inline Function Start for DDSMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DDSMAQA (Eight Signed 8x8 with 64-bit Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DDSMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do eight signed 8x8 and add signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * Do eight signed 8-bit multiplications from eight 8-bit chunks of two registers; and then adds + * the eight 16-bit results and the content of 64-bit chunks of a third register. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.B[0] s* op2b.B[0]; + * m1 = op1b.B[1] s* op2b.B[1]; + * m2 = op1b.B[2] s* op2b.B[2]; + * m3 = op1b.B[3] s* op2b.B[3]; + * m4 = op1t.B[0] s* op2t.B[0]; + * m5 = op1t.B[1] s* op2t.B[1]; + * m6 = op1t.B[2] s* op2t.B[2]; + * m7 = op1t.B[3] s* op2t.B[3]; + * + * s0 = m0 + m1 + m2 + m3; + * s1 = m4 + m5 + m6 + m7; + * Rd = Rd + s0 + s1; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DDSMAQA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("ddsmaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DDSMAQA ===== */ + +/* ===== Inline Function Start for DDSMAQA.SU ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DDSMAQA.SU (Eight Signed 8 x Unsigned 8 with 64-bit Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DDSMAQA.SU Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do eight signed 8 x unsigned 8 and add signed multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * Do eight signed 8 x unsigned 8 and add signed multiplication results and a third register; and then adds + * the eight 16-bit results and the content of 64-bit chunks of a third register. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.B[0] su* op2b.B[0]; + * m1 = op1b.B[1] su* op2b.B[1]; + * m2 = op1b.B[2] su* op2b.B[2]; + * m3 = op1b.B[3] su* op2b.B[3]; + * m4 = op1t.B[0] su* op2t.B[0]; + * m5 = op1t.B[1] su* op2t.B[1]; + * m6 = op1t.B[2] su* op2t.B[2]; + * m7 = op1t.B[3] su* op2t.B[3]; + * + * s0 = m0 + m1 + m2 + m3; + * s1 = m4 + m5 + m6 + m7; + * Rd = Rd + s0 + s1; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DDSMAQA_SU(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("ddsmaqa.su %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DDSMAQA.SU ===== */ + +/* ===== Inline Function Start for DDUMAQA ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DDUMAQA (Eight Unsigned 8x8 with 64-bit Unsigned Add) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DDUMAQA Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do eight unsigned 8x8 and add unsigned multiplication results and a third register. The results are written into Rd. + * + * **Description**:\n + * Do eight unsigned 8x8 and add unsigned multiplication results and a third register; and then adds + * the eight 16-bit results and the content of 64-bit chunks of a third register. + * + * **Operations**:\n + * ~~~ + * op1t = Rs1.W[x+1]; op2t = Rs2.W[x+1]; // top + * op1b = Rs1.W[x]; op2b = Rs2.W[x]; // bottom + * + * m0 = op1b.B[0] u* op2b.B[0]; + * m1 = op1b.B[1] u* op2b.B[1]; + * m2 = op1b.B[2] u* op2b.B[2]; + * m3 = op1b.B[3] u* op2b.B[3]; + * m4 = op1t.B[0] u* op2t.B[0]; + * m5 = op1t.B[1] u* op2t.B[1]; + * m6 = op1t.B[2] u* op2t.B[2]; + * m7 = op1t.B[3] u* op2t.B[3]; + * + * s0 = m0 + m1 + m2 + m3; + * s1 = m4 + m5 + m6 + m7; + * Rd = Rd + s0 + s1; + * x=0 + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DDUMAQA(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("ddumaqa %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DDUMAQA ===== */ + +/* ===== Inline Function Start for DSMA32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMA32.u (64-bit SIMD 32-bit Signed Multiply Addition With Rounding and Clip) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and add signed multiplication results with Rounding, then right shift 32-bit and clip q63 to q31. + * The result is written to Rd. + * + * **Description**:\n + * For the `DSMA32.u` instruction, multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with the top 32-bit Q31 + * content of 64-bit chunks in Rs2. At the same time, multiply the bottom 32-bit Q31 content of 64-bit chunks in Rs1 with + * the bottom 32-bit Q31 content of 64-bit chunks in Rs2. + * Then, do the addtion for the results above and perform the addtional rounding operations, and then move the data to the right + * by 32-bit, and clip the 64-bit data into 32-bit.The result is written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd = (q31_t)((Rs1.W[x] s* Rs2.W[x] + Rs1.W[x + 1] s* Rs2.W[x + 1] + 0x80000000LL) s>> 32); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMA32_U(unsigned long long a, unsigned long long b) +{ + long result; + __ASM volatile("dsma32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMA32.u ===== */ + +/* ===== Inline Function Start for DSMXS32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMXS32.u (64-bit SIMD 32-bit Signed Multiply Cross Subtraction With Rounding and Clip) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMXS32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and sub signed multiplication results with Rounding, then right shift 32-bit and clip q63 to + * q31. The result is written to Rd. + * + * **Description**:\n + * For the `DSMXS32.u` instruction, multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with the bottom 32-bit + * Q31 content of 64-bit chunks in Rs2. At the same time, multiply the bottom 32-bit Q31 content of 64-bit chunks in Rs1 + * with the top 32-bit Q31 content of 64-bit chunks in Rs2. + * Then, do the subtraction for the results above and perform the addtional rounding operations, and then move the data to the right by + * 32-bit, and clip the 64-bit data into 32-bit.The result is written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd = (q31_t)((Rs1.W[x + 1] s* Rs2.W[x] - Rs1.W[x] s* Rs2.W[x + 1] + 0x80000000LL) s>> 32); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMXS32_U(unsigned long long a, unsigned long long b) +{ + long result; + __ASM volatile("dsmxs32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMXS32.u ===== */ + +/* ===== Inline Function Start for DSMXA32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMXA32.u (64-bit SIMD 32-bit Signed Cross Multiply Addition with Rounding and Clip) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMXA32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and add signed multiplication results with Rounding, then right shift 32-bit and clip q63 to + * q31. The result is written to Rd. + * + * **Description**:\n + * For the `DSMXA32.u` instruction,multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with the bottom 32-bit Q31 + * content of 64-bit chunks in Rs2. At the same time, multiply the bottom 32-bit Q31 content of 64-bit chunks in Rs1 with + * the top 32-bit Q31 content of 64-bit chunks in Rs2. + * Then, do the addtion for the results above and perform the addtional rounding operations, and then move the data to the right + * by 32-bit, and clip the 64-bit data into 32-bit.The result is written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd = (q31_t)((Rs1.W[x + 1] s* Rs2.W[x] + Rs1.W[x] s* Rs2.W[x + 1] + 0x80000000LL) s>> 32); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMXA32_U(unsigned long long a, unsigned long long b) +{ + long result; + __ASM volatile("dsmxa32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMXA32.u ===== */ + +/* ===== Inline Function Start for DSMS32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMS32.u (64-bit SIMD 32-bit Signed Multiply Subtraction with Rounding and Clip) + * \details + * **Type**: DSP + * + * **Syntax**:\n + * ~~~ + * DSMS32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 32x32 and sub signed multiplication results with Rounding, then right shift 32-bit and clip q63 to q31. The + * result is written to Rd. + * + * **Description**:\n + * For the `DSMS32.u` instruction, multiply the bottom 32-bit Q31 content of 64-bit chunks in Rs1 with the bottom 32-bit + * Q31 content of 64-bit chunks in Rs2. At the same time, multiply the top 32-bit Q31 content of 64-bit chunks in Rs1 with + * the top 32-bit Q31 content of 64-bit chunks in Rs2. + * Then, do the subtraction for the results above and perform the addtional rounding operations, and then move the data to the right by + * 32-bit, and clip the 64-bit data into 32-bit.The result is written to Rd. + * + * **Operations**:\n + * ~~~ + * Rd = (q31_t)((Rs1.W[x] s* Rs2.W[x] - Rs1.W[x + 1] s* Rs2.W[x + 1] + 0x80000000LL) s>> 32); + * x=0 + * ~~~ + * + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMS32_U(unsigned long long a, unsigned long long b) +{ + long result; + __ASM volatile("dsms32.u %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); + return result; +} +/* ===== Inline Function End for DSMS32.u ===== */ + +/* ===== Inline Function Start for DSMADA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMADA16 (Signed Multiply Two Halfs and Two Adds 32-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMADA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications of two 32-bit registers; and then adds the 32-bit results and the 32-bit value of an + * even/odd pair of registers together. + * * DSMADA16: rt pair+ top*top + bottom*bottom + * + * **Description**:\n + * This instruction multiplies the per 16-bit content of the 32-bit elements of Rs1 with the corresponding 16-bit content of + * the 32-bit elements of Rs2. The result is added to the 32-bit value of an even/odd pair of registers specified by Rd(4,1). + * The 32-bit addition result is written back to the register-pair. The 16-bit values of Rs1 and Rs2, and the 32-bit value of the + * register-pair are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[0]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[1]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[0]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[1]); + * Rd.W = Rd.W + SE32(Mres0[0][31:0]) + SE32(Mres1[0][31:0]) + SE32(Mres0[1][31:0]) + SE32(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMADA16(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmada16 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return (long)t; +} +/* ===== Inline Function End for DSMADA16 ===== */ + +/* ===== Inline Function Start for DSMAXDA16 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMAXDA16 (Signed Crossed Multiply Two Halfs and Two Adds 32-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMAXDA16 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two signed 16-bit multiplications of two 32-bit registers; and then adds the 32-bit results and the 32-bit value of an + * even/odd pair of registers together. + * * DSMAXDA: rt pair+ top*bottom + bottom*top (all 32-bit elements) + * + * **Description**:\n + * This instruction crossly multiplies the top 16-bit content of the 32-bit elements of Rs1 with the bottom 16-bit content of the 32-bit + * elements of Rs2 and then adds the result to the result of multiplying the bottom 16-bit content of the 32-bit elements of + * Rs1 with the top 16-bit content of the 32-bit elements of Rs2 with unlimited precision. The result is added to the 64-bit + * value of an even/odd pair of registers specified by Rd(4,1).The 64-bit addition result is clipped to 32-bit result. + * + * **Operations**:\n + * ~~~ + * Mres0[0][31:0] = (Rs1.W[0].H[0] * Rs2.W[0].H[1]); + * Mres1[0][31:0] = (Rs1.W[0].H[1] * Rs2.W[0].H[0]); + * Mres0[1][31:0] = (Rs1.W[1].H[0] * Rs2.W[1].H[1]); + * Mres1[1][31:0] = (Rs1.W[1].H[1] * Rs2.W[1].H[0]); + * Rd.W = Rd.W + SE32(Mres0[0][31:0]) + SE32(Mres1[0][31:0]) + SE32(Mres0[1][31:0]) + SE32(Mres1[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DSMAXDA16(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmaxda16 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return (long)t; +} +/* ===== Inline Function End for DSMAXDA16 ===== */ + +/* ===== Inline Function Start for DKSMS32.u ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKSMS32.u (Two Signed Multiply Shift-clip and Saturation with Rounding) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKSMS32.u Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Computes saturated multiplication of two pairs of q31 type with shifted rounding. + * + * **Description**:\n + * Compute the multiplication of Rs1 and Rs2 of type q31_t, intercept [47:16] for the resulting 64-bit product + * to get the 32-bit number, then add 1 to it to do rounding, and finally saturate the result after rounding. + * + * **Operations**:\n + * ~~~ + * Mres[x][63:0] = Rs1.W[x] s* Rs2.W[x]; + * Round[x][32:0] = Mres[x][47:15] + 1; + * Rd.W[x] = sat.31(Rd.W[x] + Round[x][32:1]); + * x=1...0 + * ~~~ + * + * \param [in] t unsigned long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE unsigned long long __RV_DKSMS32_U(unsigned long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dksms32.u %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKSMS32.u ===== */ + +/* ===== Inline Function Start for DMADA32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DMADA32 ((Two Cross Signed 32x32 with 64-bit Add and Clip to 32-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DMADA32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Do two cross signed 32x32 and add the signed multiplication results to q63, then clip the q63 result to q31 , the final results + * are written into Rd. + * + * **Description**:\n + * For the `DMADA32` instruction, it multiplies the top 32-bit element in Rs1 with the bottom 32-bit element in Rs2 and + * then adds the result to the result of multiplying the bottom 32-bit element in Rs1 with the top 32-bit element in Rs2, then + * clip the q63 result to q31. + * + * **Operations**:\n + * ~~~ + * res = (q31_t)((((q63_t) Rd.w[0] << 32) + (q63_t)Rs1.w[0] s* Rs2.w[1] + (q63_t)Rs1.w[1] s* Rs2.w[0]) s>> 32); + * rd = res; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long type + */ +__STATIC_FORCEINLINE long __RV_DMADA32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dmada32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return (long)t; +} +/* ===== Inline Function End for DMADA32 ===== */ + +/* ===== Inline Function Start for DSMALBB ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALBB (Signed Multiply Bottom Halfs & Add 64-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMALBB Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit content of the corresponding 32-bit + * elements of another register and add the results with a 64-bit value of an even/odd pair of registers. The addition result + * is written back to the register-pair. + * * DSMALBB: rt pair + bottom*bottom (all 32-bit elements) + * + * **Description**:\n + * For the `DSMALBB` instruction, it multiplies the bottom 16-bit content of Rs1 with the bottom 16-bit content of Rs2.The + * multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written back to Rd. + * + * **Operations**:\n + * ~~~ + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[0]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[0]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALBB(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalbb %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALBB ===== */ + +/* ===== Inline Function Start for DSMALBT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALBT (Signed Multiply Bottom Half & Top Half & Add 64-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMALBT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit content of the corresponding 32-bit + * elements of another register and add the results with a 64-bit value of an even/odd pair of registers. The addition result + * is written back to the register-pair. + * * DSMALBT: rt pair + bottom*top (all 32-bit elements) + * + * **Description**:\n + * For the `DSMALBT` instruction, it multiplies the bottom 16-bit content of the 32-bit elements of Rs1 with the top 16-bit + * content of the 32-bit elements of Rs2. + * The multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written back to Rd. The + * 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed integers + * + * **Operations**:\n + * ~~~ + * Mres[0][31:0] = Rs1.W[0].H[0] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[0] * Rs2.W[1].H[1]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALBT(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmalbt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALBT ===== */ + +/* ===== Inline Function Start for DSMALTT ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DSMALTT (Signed Multiply Top Half & Add 64-bit) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DSMALTT Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 16-bit content of the 32-bit elements of a register with the 16-bit content of the corresponding 32-bit + * elements of another register and add the results with a 64-bit value of an even/odd pair of registers. The addition result + * is written back to the register-pair. + * * DSMALTT: DSMALTT rt pair + top*top (all 32-bit elements) + * + * **Description**:\n + * For the `DSMALTT` instruction, it multiplies the top 16-bit content of the 32-bit elements of Rs1 with the top 16-bit + * content of the 32-bit elements of Rs2. + * The multiplication results are added with the 64-bit value of Rd. The 64-bit addition result is written back to Rd. The + * 16-bit values of Rs1 and Rs2, and the 64-bit value of Rd are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * Mres[0][31:0] = Rs1.W[0].H[1] * Rs2.W[0].H[1]; + * Mres[1][31:0] = Rs1.W[1].H[1] * Rs2.W[1].H[1]; + * Rd = Rd + SE64(Mres[0][31:0]) + SE64(Mres[1][31:0]); + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DSMALTT(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dsmaltt %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DSMALTT ===== */ + +/* ===== Inline Function Start for DKMABB32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMABB32 (Saturating Signed Multiply Bottom Words & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMABB32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register and add the result to the content + * of 64-bit data in the third register. The addition result may besaturated and is written to the third register. + * * DKMABB32: rd + bottom*bottom + * + * **Description**:\n + * For the `DKMABB32` instruction, it multiplies the bottom 32-bit element in Rs1 with the bottom 32-bit element in Rs2 + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond the Q63 number range + * (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The result after saturation is written to Rd. + * The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[0] * Rs2.W[0]); + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMABB32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmabb32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMABB32 ===== */ + +/* ===== Inline Function Start for DKMABT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMABT32 (Saturating Signed Multiply Bottom & Top Words & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMABT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register and add the result to the content + * of 64-bit data in the third register. The addition result may be saturated and is written to the third register. + * * DKMABT32: rd + bottom*top + * + * **Description**:\n + * For the `DKMABT32` instruction, it multiplies the bottom 32-bit element in Rs1 with the top 32-bit element in Rs2 + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond the Q63 number range + * (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The result after saturation is written to Rd. + * The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[0] * Rs2.W[1]); + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMABT32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmabt32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMABT32 ===== */ + +/* ===== Inline Function Start for DKMATT32 ===== */ +/** + * \ingroup NMSIS_Core_DSP_Intrinsic_NUCLEI_N3 + * \brief DKMATT32 (Saturating Signed Multiply Bottom & Top Words & Add) + * \details + * **Type**: SIMD + * + * **Syntax**:\n + * ~~~ + * DKMATT32 Rd, Rs1, Rs2 + * ~~~ + * + * **Purpose**:\n + * Multiply the signed 32-bit element in a register with the 32-bit element in another register and add the result to the content + * of 64-bit data in the third register. The addition result may be saturated and is written to the third register. + * * DKMATT32: rd + top*top + * + * **Description**:\n + * For the `DKMATT32` instruction, it multiplies the top 32-bit element in Rs1 with the top 32-bit element in Rs2 + * The multiplication result is added to the content of 64-bit data in Rd. If the addition result is beyond the Q63 number range + * (-2^63 <= Q63 <= 2^63-1), it is saturated to the range and the OV bit is set to 1. The result after saturation is written to Rd. + * The 32-bit contents of Rs1 and Rs2 are treated as signed integers. + * + * **Operations**:\n + * ~~~ + * res = Rd + (Rs1.W[1] * Rs2.W[1]); + * if (res > (2^63)-1) { + * res = (2^63)-1; + * OV = 1; + * } else if (res < -2^63) { + * res = -2^63; + * OV = 1; + * } + * Rd = res; + * ~~~ + * + * \param [in] t long long type of value stored in t + * \param [in] a unsigned long long type of value stored in a + * \param [in] b unsigned long long type of value stored in b + * \return value stored in unsigned long long type + */ +__STATIC_FORCEINLINE long long __RV_DKMATT32(long long t, unsigned long long a, unsigned long long b) +{ + __ASM volatile("dkmatt32 %0, %1, %2" : "+r"(t) : "r"(a), "r"(b)); + return t; +} +/* ===== Inline Function End for DKMATT32 ===== */ +#endif /* __RISCV_XLEN == 32 */ + +#elif defined (__ICCRISCV__) + +#if __riscv_xlen == 32 +#include "iar_nds32_intrinsic.h" +#elif __riscv_xlen == 64 +#include "iar_nds64_intrinsic.h" +#else +#error "Unexpected RISC-V XLEN size." +#endif /* __riscv_xlen == 32 */ + +#pragma language=save +#pragma language=extended + +// Redefine those compatible instruction name supplied by IAR +#define __RV_CLROV __nds__clrov +#define __RV_RDOV __nds__rdov +#define __RV_ADD8 __nds__add8 +#define __RV_SUB8 __nds__sub8 +#define __RV_ADD16 __nds__add16 +#define __RV_SUB16 __nds__sub16 +#define __RV_ADD64 __nds__add64 +#define __RV_SUB64 __nds__sub64 +#define __RV_RADD8 __nds__radd8 +#define __RV_RSUB8 __nds__rsub8 +#define __RV_RADD16 __nds__radd16 +#define __RV_RSUB16 __nds__rsub16 +#define __RV_RADD64 __nds__radd64 +#define __RV_RSUB64 __nds__rsub64 +#define __RV_RADDW __nds__raddw +#define __RV_RSUBW __nds__rsubw +#define __RV_URADD8 __nds__uradd8 +#define __RV_URSUB8 __nds__ursub8 +#define __RV_URADD16 __nds__uradd16 +#define __RV_URSUB16 __nds__ursub16 +#define __RV_URADD64 __nds__uradd64 +#define __RV_URSUB64 __nds__ursub64 +#define __RV_URADDW __nds__uraddw +#define __RV_URSUBW __nds__ursubw +#define __RV_KADD8 __nds__kadd8 +#define __RV_KSUB8 __nds__ksub8 +#define __RV_KADD16 __nds__kadd16 +#define __RV_KSUB16 __nds__ksub16 +#define __RV_KADD64 __nds__kadd64 +#define __RV_KSUB64 __nds__ksub64 +#define __RV_KADDH __nds__kaddh +#define __RV_KSUBH __nds__ksubh +#define __RV_KADDW __nds__kaddw +#define __RV_KSUBW __nds__ksubw +#define __RV_UKADD8 __nds__ukadd8 +#define __RV_UKSUB8 __nds__uksub8 +#define __RV_UKADD16 __nds__ukadd16 +#define __RV_UKSUB16 __nds__uksub16 +#define __RV_UKADD64 __nds__ukadd64 +#define __RV_UKSUB64 __nds__uksub64 +#define __RV_UKADDH __nds__ukaddh +#define __RV_UKSUBH __nds__uksubh +#define __RV_UKADDW __nds__ukaddw +#define __RV_UKSUBW __nds__uksubw +#define __RV_CRAS16 __nds__cras16 +#define __RV_CRSA16 __nds__crsa16 +#define __RV_RCRAS16 __nds__rcras16 +#define __RV_RCRSA16 __nds__rcrsa16 +#define __RV_URCRAS16 __nds__urcras16 +#define __RV_URCRSA16 __nds__urcrsa16 +#define __RV_KCRAS16 __nds__kcras16 +#define __RV_KCRSA16 __nds__kcrsa16 +#define __RV_UKCRAS16 __nds__ukcras16 +#define __RV_UKCRSA16 __nds__ukcrsa16 +#define __RV_SRA8 __nds__sra8 +#define __RV_SRAI8 __nds__sra8 +#define __RV_SRA16 __nds__sra16 +#define __RV_SRAI16 __nds__sra16 +#define __RV_SRL8 __nds__srl8 +#define __RV_SRL16 __nds__srl16 +#define __RV_SLL8 __nds__sll8 +#define __RV_SLL16 __nds__sll16 +#define __RV_SRA_U __nds__sra_u +#define __RV_SRA8_U __nds__sra8_u +#define __RV_SRA16_U __nds__sra16_u +#define __RV_SRL8_U __nds__srl8_u +#define __RV_SRL16_U __nds__srl16_u +#define __RV_KSLL8 __nds__ksll8 +#define __RV_KSLL16 __nds__ksll16 +#define __RV_KSLLW __nds__ksllw +#define __RV_KSLRA8 __nds__kslra8 +#define __RV_KSLRA8_U __nds__kslra8_u +#define __RV_KSLRA16 __nds__kslra16 +#define __RV_KSLRA16_U __nds__kslra16_u +#define __RV_KSLRAW __nds__kslraw +#define __RV_KSLRAW_U __nds__kslraw_u +#define __RV_CMPEQ8 __nds__cmpeq8 +#define __RV_CMPEQ16 __nds__cmpeq16 +#define __RV_SCMPLE8 __nds__scmple8 +#define __RV_SCMPLE16 __nds__scmple16 +#define __RV_SCMPLT8 __nds__scmplt8 +#define __RV_SCMPLT16 __nds__scmplt16 +#define __RV_UCMPLE8 __nds__ucmple8 +#define __RV_UCMPLE16 __nds__ucmple16 +#define __RV_UCMPLT8 __nds__ucmplt8 +#define __RV_UCMPLT16 __nds__ucmplt16 +#define __RV_SMUL8 __nds__smul8 +#define __RV_UMUL8 __nds__umul8 +#define __RV_SMUL16 __nds__smul16 +#define __RV_UMUL16 __nds__umul16 +#define __RV_SMULX8 __nds__smulx8 +#define __RV_UMULX8 __nds__umulx8 +#define __RV_SMULX16 __nds__smulx16 +#define __RV_UMULX16 __nds__umulx16 +#define __RV_KHM8 __nds__khm8 +#define __RV_KHMX8 __nds__khmx8 +#define __RV_KHM16 __nds__khm16 +#define __RV_KHMX16 __nds__khmx16 +#define __RV_MULR64 __nds__mulr64 +#define __RV_MULSR64 __nds__mulsr64 +#define __RV_SMMUL __nds__smmul +#define __RV_SMMUL_U __nds__smmul_u +#define __RV_WEXT __nds__wext +#define __RV_SUNPKD810 __nds__sunpkd810 +#define __RV_SUNPKD820 __nds__sunpkd820 +#define __RV_SUNPKD830 __nds__sunpkd830 +#define __RV_SUNPKD831 __nds__sunpkd831 +#define __RV_SUNPKD832 __nds__sunpkd832 +#define __RV_ZUNPKD810 __nds__zunpkd810 +#define __RV_ZUNPKD820 __nds__zunpkd820 +#define __RV_ZUNPKD830 __nds__zunpkd830 +#define __RV_ZUNPKD831 __nds__zunpkd831 +#define __RV_ZUNPKD832 __nds__zunpkd832 +#define __RV_PKBB16 __nds__pkbb16 +#define __RV_PKBT16 __nds__pkbt16 +#define __RV_PKTT16 __nds__pktt16 +#define __RV_PKTB16 __nds__pktb16 +#define __RV_KMMAC __nds__kmmac +#define __RV_KMMAC_U __nds__kmmac_u +#define __RV_KMMSB __nds__kmmsb +#define __RV_KMMSB_U __nds__kmmsb_u +#define __RV_KWMMUL __nds__kwmmul +#define __RV_KWMMUL_U __nds__kwmmul_u +#define __RV_SMMWB __nds__smmwb +#define __RV_SMMWB_U __nds__smmwb_u +#define __RV_SMMWT __nds__smmwt +#define __RV_SMMWT_U __nds__smmwt_u +#define __RV_KMMAWB __nds__kmmawb +#define __RV_KMMAWB_U __nds__kmmawb_u +#define __RV_KMMAWT __nds__kmmawt +#define __RV_KMMAWT_U __nds__kmmawt_u +#define __RV_KMMWB2 __nds__kmmwb2 +#define __RV_KMMWB2_U __nds__kmmwb2_u +#define __RV_KMMWT2 __nds__kmmwt2 +#define __RV_KMMWT2_U __nds__kmmwt2_u +#define __RV_KMMAWB2 __nds__kmmawb2 +#define __RV_KMMAWB2_U __nds__kmmawb2_u +#define __RV_KMMAWT2 __nds__kmmawt2 +#define __RV_KMMAWT2_U __nds__kmmawt2_u +#define __RV_SMBB16 __nds__smbb16 +#define __RV_SMBT16 __nds__smbt16 +#define __RV_SMTT16 __nds__smtt16 +#define __RV_KMDA __nds__kmda +#define __RV_KMXDA __nds__kmxda +#define __RV_SMDS __nds__smds +#define __RV_SMDRS __nds__smdrs +#define __RV_SMXDS __nds__smxds +#define __RV_KMABB __nds__kmabb +#define __RV_KMABT __nds__kmabt +#define __RV_KMATT __nds__kmatt +#define __RV_KMADA __nds__kmada +#define __RV_KMAXDA __nds__kmaxda +#define __RV_KMADS __nds__kmads +#define __RV_KMADRS __nds__kmadrs +#define __RV_KMAXDS __nds__kmaxds +#define __RV_KMSDA __nds__kmsda +#define __RV_KMSXDA __nds__kmsxda +#define __RV_SMAL __nds__smal +#define __RV_SMAQA __nds__smaqa +#define __RV_UMAQA __nds__umaqa +#define __RV_SMAQA_SU __nds__smaqa_su +#define __RV_SMAR64 __nds__smar64 +#define __RV_SMSR64 __nds__smsr64 +#define __RV_UMAR64 __nds__umar64 +#define __RV_UMSR64 __nds__umsr64 +#define __RV_KMAR64 __nds__kmar64 +#define __RV_KMSR64 __nds__kmsr64 +#define __RV_UKMAR64 __nds__ukmar64 +#define __RV_UKMSR64 __nds__ukmsr64 +#define __RV_SMALBB __nds__smalbb +#define __RV_SMALBT __nds__smalbt +#define __RV_SMALTT __nds__smaltt +#define __RV_SMALDA __nds__smalda +#define __RV_SMALXDA __nds__smalxda +#define __RV_SMALDS __nds__smalds +#define __RV_SMALDRS __nds__smaldrs +#define __RV_SMALXDS __nds__smalxds +#define __RV_SMSLDA __nds__smslda +#define __RV_SMSLXDA __nds__smslxda +#define __RV_MINW __nds__minw +#define __RV_MAXW __nds__maxw +#define __RV_SMIN8 __nds__smin8 +#define __RV_SMAX8 __nds__smax8 +#define __RV_SMIN16 __nds__smin16 +#define __RV_SMAX16 __nds__smax16 +#define __RV_UMIN8 __nds__umin8 +#define __RV_UMAX8 __nds__umax8 +#define __RV_UMIN16 __nds__umin16 +#define __RV_UMAX16 __nds__umax16 +#define __RV_KABS8 __nds__kabs8 +#define __RV_KABS16 __nds__kabs16 +#define __RV_KABSW __nds__kabsw +#define __RV_SCLIP8 __nds__sclip8 +#define __RV_SCLIP16 __nds__sclip16 +#define __RV_SCLIP32 __nds__sclip32 +#define __RV_UCLIP8 __nds__uclip8 +#define __RV_UCLIP16 __nds__uclip16 +#define __RV_UCLIP32 __nds__uclip32 +#define __RV_CLO8 __nds__clo8 +#define __RV_CLO16 __nds__clo16 +#define __RV_CLO32 __nds__clo32 +#define __RV_CLZ8 __nds__clz8 +#define __RV_CLZ16 __nds__clz16 +#define __RV_CLZ32 __nds__clz32 +#define __RV_CLRS8 __nds__clrs8 +#define __RV_CLRS16 __nds__clrs16 +#define __RV_CLRS32 __nds__clrs32 +#define __RV_SWAP8 __nds__swap8 +#define __RV_SWAP16 __nds__swap16 +#define __RV_KHMBB __nds__khmbb +#define __RV_KHMBT __nds__khmbt +#define __RV_KHMTT __nds__khmtt +#define __RV_KDMBB __nds__kdmbb +#define __RV_KDMBT __nds__kdmbt +#define __RV_KDMTT __nds__kdmtt +#define __RV_KDMABB __nds__kdmabb +#define __RV_KDMABT __nds__kdmabt +#define __RV_KDMATT __nds__kdmatt +#define __RV_MADDR32 __nds__maddr32 +#define __RV_MSUBR32 __nds__msubr32 +#define __RV_PBSAD __nds__pbsad +#define __RV_PBSADA __nds__pbsada +#define __RV_AVE __nds__ave +#define __RV_BITREV __nds__bitrev +#define __RV_INSB __nds__insb + +#if (__riscv_xlen == 64) +#define __RV_ADD32 __nds__add32 +#define __RV_SUB32 __nds__sub32 +#define __RV_RADD32 __nds__radd32 +#define __RV_RSUB32 __nds__rsub32 +#define __RV_URADD32 __nds__uradd32 +#define __RV_URSUB32 __nds__ursub32 +#define __RV_KADD32 __nds__kadd32 +#define __RV_KSUB32 __nds__ksub32 +#define __RV_UKADD32 __nds__ukadd32 +#define __RV_UKSUB32 __nds__uksub32 +#define __RV_CRAS32 __nds__cras32 +#define __RV_CRSA32 __nds__crsa32 +#define __RV_RCRAS32 __nds__rcras32 +#define __RV_RCRSA32 __nds__rcrsa32 +#define __RV_URCRAS32 __nds__urcras32 +#define __RV_URCRSA32 __nds__urcrsa32 +#define __RV_KCRAS32 __nds__kcras32 +#define __RV_KCRSA32 __nds__kcrsa32 +#define __RV_UKCRAS32 __nds__ukcras32 +#define __RV_UKCRSA32 __nds__ukcrsa32 +#define __RV_SRA32 __nds__sra32 +#define __RV_SRAI32 __nds__sra32 +#define __RV_SRL32 __nds__srl32 +#define __RV_SLL32 __nds__sll32 +#define __RV_SLLI32 __nds__sll32 +#define __RV_SRAW_U __nds__sraw_u +#define __RV_SRA32_U __nds__sra32_u +#define __RV_SRL32_U __nds__srl32_u +#define __RV_KSLL32 __nds__ksll32 +#define __RV_KSLRA32 __nds__kslra32 +#define __RV_KSLRA32_U __nds__kslra32_u +#define __RV_SMBB32 __nds__smbb32 +#define __RV_SMBT32 __nds__smbt32 +#define __RV_SMTT32 __nds__smtt32 +#define __RV_PKBB32 __nds__pkbb32 +#define __RV_PKBT32 __nds__pkbt32 +#define __RV_PKTT32 __nds__pktt32 +#define __RV_PKTB32 __nds__pktb32 +#define __RV_SMIN32 __nds__smin32 +#define __RV_SMAX32 __nds__smax32 +#define __RV_UMIN32 __nds__umin32 +#define __RV_UMAX32 __nds__umax32 +#define __RV_KABS32 __nds__kabs32 +#define __RV_KHMBB16 __nds__khmbb16 +#define __RV_KHMBT16 __nds__khmbt16 +#define __RV_KHMTT16 __nds__khmtt16 +#define __RV_KDMBB16 __nds__kdmbb16 +#define __RV_KDMBT16 __nds__kdmbt16 +#define __RV_KDMTT16 __nds__kdmtt16 +#define __RV_KDMABB16 __nds__kdmabb16 +#define __RV_KDMABT16 __nds__kdmabt16 +#define __RV_KDMATT16 __nds__kdmatt16 +#define __RV_KMABB32 __nds__kmabb32 +#define __RV_KMABT32 __nds__kmabt32 +#define __RV_KMATT32 __nds__kmatt32 +#define __RV_KMDA32 __nds__kmda32 +#define __RV_KMXDA32 __nds__kmxda32 +#define __RV_KMADA32 __nds__kmada32 +#define __RV_KMAXDA32 __nds__kmaxda32 +#define __RV_KMADS32 __nds__kmads32 +#define __RV_KMADRS32 __nds__kmadrs32 +#define __RV_KMAXDS32 __nds__kmaxds32 +#define __RV_KMSDA32 __nds__kmsda32 +#define __RV_KMSXDA32 __nds__kmsxda32 +#define __RV_SMDS32 __nds__smds32 +#define __RV_SMDRS32 __nds__smdrs32 +#define __RV_SMXDS32 __nds__smxds32 +#endif /* __riscv_xlen == 64 */ + +// For now, the P-extention version of IAR IDE is 0.5.0, but Nuclei's supports 0.5.4 +// so Nuclei supplies a workround to add custom instructions of those not natively +// supported by the IAR Assembler. Note that __RV_BPICK remains to be implemented in future. +// And we only implement Xxldsp Nuclei custom instruction set, bpick not implemented, expdxx +// implemented in c, not via .insn variant + +#pragma inline=forced_no_body +unsigned long __RV_STAS16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x7A, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_RSTAS16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x5A, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_KSTAS16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x62, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_URSTAS16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x6A, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_UKSTAS16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x72, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_STSA16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x7B, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_RSTSA16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x5B, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_KSTSA16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x63, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_URSTSA16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x6B, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_UKSTSA16(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x73, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +// #pragma inline=forced_no_body +// unsigned long __RV_BPICK(unsigned long a, unsigned long b, unsigned long c) { + // TODO: remains to be done +// } + +// RV64 only +#pragma inline=forced_no_body +unsigned long __RV_STAS32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x78, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_RSTAS32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x58, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_KSTAS32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x60, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_URSTAS32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x68, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_UKSTAS32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x70, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_STSA32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x79, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_RSTSA32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x59, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_KSTSA32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x61, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_URSTSA32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x69, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_UKSTSA32(unsigned long a, unsigned long b) { + unsigned long r; + __asm(".insn r 0x7F, 0x2, 0x71, %0,%1,%2":"=r"(r) : "r"(a), "r"(b) ); + return r; +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD80(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)(a & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD81(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 8) & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD82(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 16) & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD83(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 24) & 0xff)); +} + +#if __RISCV_XLEN == 64 +// RV64 only +#pragma inline=forced_no_body +unsigned long __RV_EXPD84(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 32) & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD85(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 40) & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD86(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 48) & 0xff)); +} + +#pragma inline=forced_no_body +unsigned long __RV_EXPD87(unsigned long a) +{ + return __EXPD_BYTE((uint8_t)((a >> 56) & 0xff)); +} +#endif +#pragma language=restore + +#else + #error Unknown compiler +#endif /* __ICCRISCV__ */ + + +/* XXXXX ARM Compatiable SIMD API XXXXX */ +/** \brief Q setting quad 8-bit saturating addition. */ +#define __QADD8(x, y) __RV_KADD8(x, y) +/** \brief Q setting quad 8-bit saturating subtract. */ +#define __QSUB8(x, y) __RV_KSUB8((x), (y)) +/** \brief Q setting dual 16-bit saturating addition. */ +#define __QADD16(x, y) __RV_KADD16((x), (y)) +/** \brief Dual 16-bit signed addition with halved results. */ +#define __SHADD16(x, y) __RV_RADD16((x), (y)) +/** \brief Q setting dual 16-bit saturating subtract. */ +#define __QSUB16(x, y) __RV_KSUB16((x), (y)) +/** \brief Dual 16-bit signed subtraction with halved results. */ +#define __SHSUB16(x, y) __RV_RSUB16((x), (y)) +/** \brief Q setting dual 16-bit add and subtract with exchange. */ +#define __QASX(x, y) __RV_KCRAS16((x), (y)) +/** \brief Dual 16-bit signed addition and subtraction with halved results.*/ +#define __SHASX(x, y) __RV_RCRAS16((x), (y)) +/** \brief Q setting dual 16-bit subtract and add with exchange. */ +#define __QSAX(x, y) __RV_KCRSA16((x), (y)) +/** \brief Dual 16-bit signed subtraction and addition with halved results.*/ +#define __SHSAX(x, y) __RV_RCRSA16((x), (y)) +/** \brief Dual 16-bit signed multiply with exchange returning difference. */ +#define __SMUSDX(x, y) __RV_SMXDS((y), (x)) +/** \brief Q setting sum of dual 16-bit signed multiply with exchange. */ +__STATIC_FORCEINLINE long __SMUADX (unsigned long op1, unsigned long op2) +{ + return __RV_KMXDA(op1, op2); +} +/** \brief Q setting saturating add. */ +#define __QADD(x, y) __RV_KADDW((x), (y)) +/** \brief Q setting saturating subtract. */ +#define __QSUB(x, y) __RV_KSUBW((x), (y)) +/** \brief Q setting dual 16-bit signed multiply with single 32-bit accumulator. */ +__STATIC_FORCEINLINE long __SMLAD(unsigned long op1, unsigned long op2, long acc) +{ + return __RV_KMADA(acc, op1, op2); +} +/** \brief Q setting pre-exchanged dual 16-bit signed multiply with single 32-bit accumulator. */ +__STATIC_FORCEINLINE long __SMLADX(unsigned long op1, unsigned long op2, long acc) +{ + return __RV_KMAXDA(acc, op1, op2); +} +/** \brief Q setting dual 16-bit signed multiply with exchange subtract with 32-bit accumulate. */ +__STATIC_FORCEINLINE long __SMLSDX(unsigned long op1, unsigned long op2, long acc) +{ + return (acc - __RV_SMXDS(op1, op2)); +} +/** \brief Dual 16-bit signed multiply with single 64-bit accumulator. */ +__STATIC_FORCEINLINE long long __SMLALD(unsigned long op1, unsigned long op2, long long acc) +{ + return __RV_SMALDA(acc, op1, op2); +} +/** \brief Dual 16-bit signed multiply with exchange with single 64-bit accumulator. */ +__STATIC_FORCEINLINE long long __SMLALDX(unsigned long op1, unsigned long op2, long long acc) +{ + return __RV_SMALXDA(acc, op1, op2); +} +/** \brief Q setting sum of dual 16-bit signed multiply. */ +__STATIC_FORCEINLINE long __SMUAD(unsigned long op1, unsigned long op2) +{ + return __RV_KMDA(op1, op2); +} +/** \brief Dual 16-bit signed multiply returning difference. */ +__STATIC_FORCEINLINE long __SMUSD(unsigned long op1, unsigned long op2) +{ + return __RV_SMDRS(op1, op2); +} +/** \brief Dual extract 8-bits and sign extend each to 16-bits. */ +#define __SXTB16(x) __RV_SUNPKD820(x) +/** \brief Dual extracted 8-bit to 16-bit signed addition. TODO Need test */ +__STATIC_FORCEINLINE unsigned long __SXTAB16(unsigned long op1, unsigned long op2) +{ + return __RV_ADD16(op1, __RV_SUNPKD820(op2)); +} +#define __SXTAB16_RORn(ARG1, ARG2, ROTATE) __SXTAB16(ARG1, __ROR(ARG2, ROTATE)) + +/** \brief 32-bit signed multiply with 32-bit truncated accumulator. */ +__STATIC_FORCEINLINE long __SMMLA(long op1, long op2, long acc) +{ + long mul; + mul = __RV_SMMUL(op1, op2); + return (acc + mul); +} +#define __DKHM8 __RV_DKHM8 +#define __DKHM16 __RV_DKHM16 +#define __DKSUB16 __RV_DKSUB16 +#define __SMAQA __RV_SMAQA +#define __MULSR64 __RV_MULSR64 +#define __DQADD8 __RV_DKADD8 +#define __DQSUB8 __RV_DKSUB8 +#define __DKADD16 __RV_DKADD16 +#define __PKBB16 __RV_PKBB16 +#define __DKSLRA16 __RV_DKSLRA16 +#define __DKSLRA8 __RV_DKSLRA8 +#define __KABSW __RV_KABSW +#define __DKABS8 __RV_DKABS8 +#define __DKABS16 __RV_DKABS16 +#define __SMALDA __RV_SMALDA +#define __SMSLDA __RV_SMSLDA +#define __SMALBB __RV_SMALBB +#define __SUB64 __RV_SUB64 +#define __ADD64 __RV_ADD64 +#define __SMBB16 __RV_SMBB16 +#define __SMBT16 __RV_SMBT16 +#define __SMTT16 __RV_SMTT16 +#define __EXPD80 __RV_EXPD80 +#define __SMAX8 __RV_SMAX8 +#define __SMAX16 __RV_SMAX16 +#define __PKTT16 __RV_PKTT16 +#define __KADD16 __RV_KADD16 +#define __SADD16 __RV_ADD16 +#define __SSUB8 __RV_KSUB8 +#define __SADD8 __RV_KADD8 +#define __USAT16 __RV_UCLIP16 +#define __SMALTT __RV_SMALTT + +/** \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16] of val2 levitated with the val3. */ +#define __PKHBT(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_PKTB16(ARG2, ARG1) : \ + (ARG3 == 16) ? __RV_PKBB16(ARG2, ARG1) : \ + (((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL))) + +/** \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0] of val2 right-shifted with the val3. */ +#define __PKHTB(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_PKTB16(ARG1, ARG2) : \ + (ARG3 == 16) ? __RV_PKTT16(ARG1, ARG2) : \ + (((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL))) + +#if __RISCV_XLEN == 64 +/** \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16] of val2 levitated with the val3, + and also combines the [47:32] of val1 with bits[63:48] of val2 with the val3, finally pack the two new 32-bits to 64-bit. */ +#define __PKHBT64(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_PKTB16(ARG2, ARG1) : \ + (ARG3 == 16) ? __RV_PKBB16(ARG2, ARG1) : \ + ((int64_t)((((uint32_t)((uint64_t)ARG1 >> 32)) & 0x0000FFFFUL) | \ + ((((uint32_t)((uint64_t)ARG2 >> 32)) << (ARG3)) & 0xFFFF0000UL)) << 32) | \ + ((int64_t)(((((uint32_t)(ARG1))) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)) & 0xFFFFFFFFUL)) + +/** \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0] of val2 right-shifted with the val3, + and also combines bits [63:48] of val1 with bits [47:32] of val2 with the val3, finally pack the two new 32bits to 64bits. */ +#define __PKHTB64(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_PKTB16(ARG1, ARG2) : \ + (ARG3 == 16) ? __RV_PKTT16(ARG1, ARG2) : \ + ((uint64_t)(((uint32_t)((uint64_t)ARG1 >> 32) & 0xFFFF0000UL) | \ + ((((uint32_t)((uint64_t)ARG2 >> 32)) >> (ARG3)) & 0x0000FFFFUL)) << 32) | \ + ((uint64_t)(((uint32_t)(ARG1) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)) & 0xFFFFFFFFUL)) +#else +/** \brief Halfword packing instruction. Combines bits[15:0] of val1 with bits[31:16] of val2 levitated with the val3, + and also combines the [47:32] of val1 with bits[63:48] of val2 with the val3, finally pack the two new 32-bits to 64-bit. */ +#define __PKHBT64(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_DPKTB16(ARG2, ARG1) : \ + (ARG3 == 16) ? __RV_DPKBB16(ARG2, ARG1) : \ + ((int64_t)((((uint32_t)((uint64_t)ARG1 >> 32)) & 0x0000FFFFUL) | \ + ((((uint32_t)((uint64_t)ARG2 >> 32)) << (ARG3)) & 0xFFFF0000UL)) << 32) | \ + ((int64_t)(((((uint32_t)(ARG1))) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL)) & 0xFFFFFFFFUL)) + +/** \brief Halfword packing instruction. Combines bits[31:16] of val1 with bits[15:0] of val2 right-shifted with the val3, + and also combines bits [63:48] of val1 with bits [47:32] of val2 with the val3, finally pack the two new 32bits to 64bits. */ +#define __PKHTB64(ARG1, ARG2, ARG3) ((ARG3 == 0) ? __RV_DPKTB16(ARG1, ARG2) : \ + (ARG3 == 16) ? __RV_DPKTT16(ARG1, ARG2) : \ + ((uint64_t)(((uint32_t)((uint64_t)ARG1 >> 32) & 0xFFFF0000UL) | \ + ((((uint32_t)((uint64_t)ARG2 >> 32)) >> (ARG3)) & 0x0000FFFFUL)) << 32) | \ + ((uint64_t)(((uint32_t)(ARG1) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL)) & 0xFFFFFFFFUL)) +#endif /* __RISCV_XLEN == 64 */ + +/** first rotate then extract. This is more suitable for arm compiler for it can rotate and extract in one command*/ +#define __SXTB16_RORn(ARG1, ARG2) __RV_SUNPKD820(__ROR(ARG1, ARG2)) + +#endif /* defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_FEATURE_DSP__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_eclic.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_eclic.h new file mode 100644 index 0000000..c898caf --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_eclic.h @@ -0,0 +1,1374 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_ECLIC__ +#define __CORE_FEATURE_ECLIC__ +/*! + * @file core_feature_eclic.h + * @brief ECLIC feature API header file for Nuclei N/NX Core + */ +/* + * ECLIC Feature Configuration Macro: + * 1. __ECLIC_PRESENT: Define whether Enhanced Core Local Interrupt Controller (ECLIC) Unit is present or not + * * 0: Not present + * * 1: Present + * 2. __ECLIC_BASEADDR: Base address of the ECLIC unit. + * 3. __ECLIC_INTCTLBITS: Optional, if defined, it should set to the value of ECLIC_GetInfoCtlbits(), define the number of hardware bits are actually implemented in the clicintctl registers. + * Valid number is 1 - 8. + * 4. __ECLIC_INTNUM: Define the external interrupt number of ECLIC Unit + * 5. __TEE_PRESENT: Define whether TEE feature present, if present, ECLIC will present with S-Mode ECLIC feature + * * 0: Not present + * * 1: Present + * + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) +/** + * \defgroup NMSIS_Core_ECLIC_Registers Register Define and Type Definitions Of ECLIC + * \ingroup NMSIS_Core_Registers + * \brief Type definitions and defines for eclic registers. + * + * @{ + */ + +/** + * \brief Union type to access CLICFG configure register. + */ +typedef union +{ + struct { + __IM uint8_t _reserved0:1; + __IOM uint8_t nlbits:4; /*!< bit: 1..4 specified the bit-width of level and priority in the register clicintctl[i] */ + __IM uint8_t nmbits:2; /*!< bit: 5..6 ties to 1 if supervisor-level interrupt supported, or else it's reserved */ + __IM uint8_t _reserved1:1; + } b; /*!< Structure used for bit access */ + uint8_t w; /*!< Type used for byte access */ +} CLICCFG_Type; + +/** + * \brief Union type to access CLICINFO information register. + */ +typedef union { + struct { + __IM uint32_t numint:13; /*!< bit: 0..12 number of maximum interrupt inputs supported */ + __IM uint32_t version:8; /*!< bit: 13..20 20:17 for architecture version,16:13 for implementation version */ + __IM uint32_t intctlbits:4; /*!< bit: 21..24 specifies how many hardware bits are actually implemented in the clicintctl registers */ + __IM uint32_t _reserved0:7; /*!< bit: 25..31 Reserved */ + } b; /*!< Structure used for bit access */ + __IM uint32_t w; /*!< Type used for word access */ +} CLICINFO_Type; + +/** + * \brief Access to the machine mode register structure of INTIP, INTIE, INTATTR, INTCTL. + */ +typedef struct { + __IOM uint8_t INTIP; /*!< Offset: 0x000 (R/W) Interrupt set pending register */ + __IOM uint8_t INTIE; /*!< Offset: 0x001 (R/W) Interrupt set enable register */ + __IOM uint8_t INTATTR; /*!< Offset: 0x002 (R/W) Interrupt set attributes register */ + __IOM uint8_t INTCTRL; /*!< Offset: 0x003 (R/W) Interrupt configure register */ +} CLIC_CTRL_Type; + +/** + * \brief Access to the structure of ECLIC Memory Map, which is compatible with TEE. + */ +typedef struct { + __IOM uint8_t CFG; /*!< Offset: 0x000 (R/W) CLIC configuration register */ + __IM uint8_t RESERVED0[3]; + __IM uint32_t INFO; /*!< Offset: 0x004 (R/ ) CLIC information register */ + __IM uint8_t RESERVED1; +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) + __IOM uint8_t STH; /*!< Offset: 0x009 (R/W ) CLIC supervisor mode interrupt-level threshold */ +#else + __IM uint8_t RESERVED2; +#endif + __IM uint8_t RESERVED3; + __IOM uint8_t MTH; /*!< Offset: 0x00B(R/W) CLIC machine mode interrupt-level threshold */ + uint32_t RESERVED4[1021]; +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) + CLIC_CTRL_Type CTRL[1024]; /*!< Offset: 0x1000 (R/W) CLIC machine mode register structure for INTIP, INTIE, INTATTR, INTCTL */ + __IM uint32_t RESERVED5[2]; + __IM uint8_t RESERVED6; + __IOM uint8_t SSTH; /*!< Offset: 0x2009 (R) CLIC supervisor mode threshold register, which is a mirror to mintthresh.sth */ + __IM uint8_t RESERVED7; + __IM uint8_t RESERVED8; + __IM uint32_t RESERVED9[1021]; + CLIC_CTRL_Type SCTRL[1024]; /*!< Offset: 0x3000 (R/W) CLIC supervisor mode register structure for INTIP, INTIE, INTATTR, INTCTL */ +#else + CLIC_CTRL_Type CTRL[4096]; /*!< Offset: 0x1000 (R/W) CLIC machine mode register structure for INTIP, INTIE, INTATTR, INTCTL */ +#endif +} CLIC_Type; + +#define CLIC_CLICCFG_NLBIT_Pos 1U /*!< CLIC CLICCFG: NLBIT Position */ +#define CLIC_CLICCFG_NLBIT_Msk (0xFUL << CLIC_CLICCFG_NLBIT_Pos) /*!< CLIC CLICCFG: NLBIT Mask */ + +#define CLIC_CLICINFO_CTLBIT_Pos 21U /*!< CLIC INTINFO: CLICINTCTLBITS Position */ +#define CLIC_CLICINFO_CTLBIT_Msk (0xFUL << CLIC_CLICINFO_CTLBIT_Pos) /*!< CLIC INTINFO: CLICINTCTLBITS Mask */ + +#define CLIC_CLICINFO_VER_Pos 13U /*!< CLIC CLICINFO: VERSION Position */ +#define CLIC_CLICINFO_VER_Msk (0xFFUL << CLIC_CLICINFO_VER_Pos) /*!< CLIC CLICINFO: VERSION Mask */ + +#define CLIC_CLICINFO_NUM_Pos 0U /*!< CLIC CLICINFO: NUM Position */ +#define CLIC_CLICINFO_NUM_Msk (0x1FFFUL << CLIC_CLICINFO_NUM_Pos) /*!< CLIC CLICINFO: NUM Mask */ + +#define CLIC_INTIP_IP_Pos 0U /*!< CLIC INTIP: IP Position */ +#define CLIC_INTIP_IP_Msk (0x1UL << CLIC_INTIP_IP_Pos) /*!< CLIC INTIP: IP Mask */ + +#define CLIC_INTIE_IE_Pos 0U /*!< CLIC INTIE: IE Position */ +#define CLIC_INTIE_IE_Msk (0x1UL << CLIC_INTIE_IE_Pos) /*!< CLIC INTIE: IE Mask */ + +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) +#define CLIC_INTATTR_MODE_Pos 6U /*!< CLIC INTATTA: Mode Position */ +#define CLIC_INTATTR_MODE_Msk (0x3U << CLIC_INTATTR_MODE_Pos) /*!< CLIC INTATTA: Mode Mask */ +#endif + +#define CLIC_INTATTR_TRIG_Pos 1U /*!< CLIC INTATTR: TRIG Position */ +#define CLIC_INTATTR_TRIG_Msk (0x3UL << CLIC_INTATTR_TRIG_Pos) /*!< CLIC INTATTR: TRIG Mask */ + +#define CLIC_INTATTR_SHV_Pos 0U /*!< CLIC INTATTR: SHV Position */ +#define CLIC_INTATTR_SHV_Msk (0x1UL << CLIC_INTATTR_SHV_Pos) /*!< CLIC INTATTR: SHV Mask */ + +#define ECLIC_MAX_NLBITS 8U /*!< Max nlbit of the CLICINTCTLBITS */ +#define ECLIC_MODE_MTVEC_Msk 3U /*!< ECLIC Mode mask for MTVT CSR Register */ + +#define ECLIC_NON_VECTOR_INTERRUPT 0x0 /*!< Non-Vector Interrupt Mode of ECLIC */ +#define ECLIC_VECTOR_INTERRUPT 0x1 /*!< Vector Interrupt Mode of ECLIC */ + +/**\brief ECLIC Trigger Enum for different Trigger Type */ +typedef enum ECLIC_TRIGGER { + ECLIC_LEVEL_TRIGGER = 0x0, /*!< Level Triggerred, trig[0] = 0 */ + ECLIC_POSTIVE_EDGE_TRIGGER = 0x1, /*!< Postive/Rising Edge Triggered, trig[0] = 1, trig[1] = 0 */ + ECLIC_NEGTIVE_EDGE_TRIGGER = 0x3, /*!< Negtive/Falling Edge Triggered, trig[0] = 1, trig[1] = 1 */ + ECLIC_MAX_TRIGGER = 0x3 /*!< MAX Supported Trigger Mode */ +} ECLIC_TRIGGER_Type; + +#ifndef __ECLIC_BASEADDR +/* Base address of ECLIC(__ECLIC_BASEADDR) should be defined in */ +#error "__ECLIC_BASEADDR is not defined, please check!" +#endif + +#ifndef __ECLIC_INTCTLBITS +/* Define __ECLIC_INTCTLBITS to get via ECLIC->INFO if not defined */ +#define __ECLIC_INTCTLBITS (__ECLIC_GetInfoCtlbits()) +#endif + +/* ECLIC Memory mapping of Device */ +#define ECLIC_BASE __ECLIC_BASEADDR /*!< ECLIC Base Address */ +#define ECLIC ((CLIC_Type *) ECLIC_BASE) /*!< CLIC configuration struct */ + +/** @} */ /* end of group NMSIS_Core_ECLIC_Registers */ + +/* ########################## ECLIC functions #################################### */ +/** + * \defgroup NMSIS_Core_IntExc Interrupts and Exceptions + * \brief Functions that manage interrupts and exceptions via the ECLIC. + * + * @{ + */ + +/** + * \brief Definition of IRQn numbers + * \details + * The core interrupt enumeration names for IRQn values are defined in the file .h. + * - Interrupt ID(IRQn) from 0 to 18 are reserved for core internal interrupts. + * - Interrupt ID(IRQn) start from 19 represent device-specific external interrupts. + * - The first device-specific interrupt has the IRQn value 19. + * + * The table below describes the core interrupt names and their availability in various Nuclei Cores. + */ +/* The following enum IRQn definition in this file + * is only used for doxygen documentation generation, + * The .h is the real file to define it by vendor + */ +#if defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__) +typedef enum IRQn { + /* ========= Nuclei N/NX Core Specific Interrupt Numbers =========== */ + /* Core Internal Interrupt IRQn definitions */ + Reserved0_IRQn = 0, /*!< Internal reserved */ + Reserved1_IRQn = 1, /*!< Internal reserved */ + Reserved2_IRQn = 2, /*!< Internal reserved */ + SysTimerSW_IRQn = 3, /*!< System Timer SW interrupt */ + Reserved3_IRQn = 4, /*!< Internal reserved */ + Reserved4_IRQn = 5, /*!< Internal reserved */ + Reserved5_IRQn = 6, /*!< Internal reserved */ + SysTimer_IRQn = 7, /*!< System Timer Interrupt */ + Reserved6_IRQn = 8, /*!< Internal reserved */ + Reserved7_IRQn = 9, /*!< Internal reserved */ + Reserved8_IRQn = 10, /*!< Internal reserved */ + Reserved9_IRQn = 11, /*!< Internal reserved */ + Reserved10_IRQn = 12, /*!< Internal reserved */ + Reserved11_IRQn = 13, /*!< Internal reserved */ + Reserved12_IRQn = 14, /*!< Internal reserved */ + Reserved13_IRQn = 15, /*!< Internal reserved */ + Reserved14_IRQn = 16, /*!< Internal reserved */ + Reserved15_IRQn = 17, /*!< Internal reserved */ + Reserved16_IRQn = 18, /*!< Internal reserved */ + + /* ========= Device Specific Interrupt Numbers =================== */ + /* ToDo: add here your device specific external interrupt numbers. + * 19~max(NUM_INTERRUPT, 1023) is reserved number for user. + * Maxmum interrupt supported could get from clicinfo.NUM_INTERRUPT. + * According the interrupt handlers defined in startup_Device.S + * eg.: Interrupt for Timer#1 eclic_tim1_handler -> TIM1_IRQn */ + FirstDeviceSpecificInterrupt_IRQn = 19, /*!< First Device Specific Interrupt */ + SOC_INT_MAX, /*!< Number of total interrupts */ +} IRQn_Type; +#endif /* __ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__ */ + +#ifdef NMSIS_ECLIC_VIRTUAL + #ifndef NMSIS_ECLIC_VIRTUAL_HEADER_FILE + #define NMSIS_ECLIC_VIRTUAL_HEADER_FILE "nmsis_eclic_virtual.h" + #endif + #include NMSIS_ECLIC_VIRTUAL_HEADER_FILE +#else + #define ECLIC_SetCfgNlbits __ECLIC_SetCfgNlbits + #define ECLIC_GetCfgNlbits __ECLIC_GetCfgNlbits + #define ECLIC_GetInfoVer __ECLIC_GetInfoVer + #define ECLIC_GetInfoCtlbits __ECLIC_GetInfoCtlbits + #define ECLIC_GetInfoNum __ECLIC_GetInfoNum + #define ECLIC_SetMth __ECLIC_SetMth + #define ECLIC_GetMth __ECLIC_GetMth + #define ECLIC_EnableIRQ __ECLIC_EnableIRQ + #define ECLIC_GetEnableIRQ __ECLIC_GetEnableIRQ + #define ECLIC_DisableIRQ __ECLIC_DisableIRQ + #define ECLIC_SetPendingIRQ __ECLIC_SetPendingIRQ + #define ECLIC_GetPendingIRQ __ECLIC_GetPendingIRQ + #define ECLIC_ClearPendingIRQ __ECLIC_ClearPendingIRQ + #define ECLIC_SetTrigIRQ __ECLIC_SetTrigIRQ + #define ECLIC_GetTrigIRQ __ECLIC_GetTrigIRQ + #define ECLIC_SetShvIRQ __ECLIC_SetShvIRQ + #define ECLIC_GetShvIRQ __ECLIC_GetShvIRQ + #define ECLIC_SetCtrlIRQ __ECLIC_SetCtrlIRQ + #define ECLIC_GetCtrlIRQ __ECLIC_GetCtrlIRQ + #define ECLIC_SetLevelIRQ __ECLIC_SetLevelIRQ + #define ECLIC_GetLevelIRQ __ECLIC_GetLevelIRQ + #define ECLIC_SetPriorityIRQ __ECLIC_SetPriorityIRQ + #define ECLIC_GetPriorityIRQ __ECLIC_GetPriorityIRQ + + /* For TEE */ +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) + #define ECLIC_SetModeIRQ __ECLIC_SetModeIRQ + #define ECLIC_SetSth __ECLIC_SetSth + #define ECLIC_GetSth __ECLIC_GetSth + #define ECLIC_SetTrigIRQ_S __ECLIC_SetTrigIRQ_S + #define ECLIC_GetTrigIRQ_S __ECLIC_GetTrigIRQ_S + #define ECLIC_SetShvIRQ_S __ECLIC_SetShvIRQ_S + #define ECLIC_GetShvIRQ_S __ECLIC_GetShvIRQ_S + #define ECLIC_SetCtrlIRQ_S __ECLIC_SetCtrlIRQ_S + #define ECLIC_GetCtrlIRQ_S __ECLIC_GetCtrlIRQ_S + #define ECLIC_SetLevelIRQ_S __ECLIC_SetLevelIRQ_S + #define ECLIC_GetLevelIRQ_S __ECLIC_GetLevelIRQ_S + #define ECLIC_SetPriorityIRQ_S __ECLIC_SetPriorityIRQ_S + #define ECLIC_GetPriorityIRQ_S __ECLIC_GetPriorityIRQ_S + #define ECLIC_EnableIRQ_S __ECLIC_EnableIRQ_S + #define ECLIC_GetEnableIRQ_S __ECLIC_GetEnableIRQ_S + #define ECLIC_DisableIRQ_S __ECLIC_DisableIRQ_S + +#endif +#endif /* NMSIS_ECLIC_VIRTUAL */ + +#ifdef NMSIS_VECTAB_VIRTUAL + #ifndef NMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define NMSIS_VECTAB_VIRTUAL_HEADER_FILE "nmsis_vectab_virtual.h" + #endif + #include NMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define ECLIC_SetVector __ECLIC_SetVector + #define ECLIC_GetVector __ECLIC_GetVector + +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) + #define ECLIC_SetVector_S __ECLIC_SetVector_S + #define ECLIC_GetVector_S __ECLIC_GetVector_S +#endif +#endif /* (NMSIS_VECTAB_VIRTUAL) */ + +/** + * \brief Set nlbits value + * \details + * This function set the nlbits value of CLICCFG register. + * \param [in] nlbits nlbits value + * \remarks + * - nlbits is used to set the width of level in the CLICINTCTL[i]. + * \sa + * - \ref ECLIC_GetCfgNlbits + */ +__STATIC_FORCEINLINE void __ECLIC_SetCfgNlbits(uint32_t nlbits) +{ + ECLIC->CFG &= ~CLIC_CLICCFG_NLBIT_Msk; + ECLIC->CFG |= (uint8_t)((nlbits <CFG & CLIC_CLICCFG_NLBIT_Msk) >> CLIC_CLICCFG_NLBIT_Pos)); +} + +/** + * \brief Get the ECLIC version number + * \details + * This function gets the hardware version information from CLICINFO register. + * \return hardware version number in CLICINFO register. + * \remarks + * - This function gets harware version information from CLICINFO register. + * - Bit 20:17 for architecture version, bit 16:13 for implementation version. + * \sa + * - \ref ECLIC_GetInfoNum +*/ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoVer(void) +{ + return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_VER_Msk) >> CLIC_CLICINFO_VER_Pos)); +} + +/** + * \brief Get CLICINTCTLBITS + * \details + * This function gets CLICINTCTLBITS from CLICINFO register. + * \return CLICINTCTLBITS from CLICINFO register. + * \remarks + * - In the CLICINTCTL[i] registers, with 2 <= CLICINTCTLBITS <= 8. + * - The implemented bits are kept left-justified in the most-significant bits of each 8-bit + * CLICINTCTL[I] register, with the lower unimplemented bits treated as hardwired to 1. + * \sa + * - \ref ECLIC_GetInfoNum + */ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoCtlbits(void) +{ + return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_CTLBIT_Msk) >> CLIC_CLICINFO_CTLBIT_Pos)); +} + +/** + * \brief Get number of maximum interrupt inputs supported + * \details + * This function gets number of maximum interrupt inputs supported from CLICINFO register. + * \return number of maximum interrupt inputs supported from CLICINFO register. + * \remarks + * - This function gets number of maximum interrupt inputs supported from CLICINFO register. + * - The num_interrupt field specifies the actual number of maximum interrupt inputs supported in this implementation. + * \sa + * - \ref ECLIC_GetInfoCtlbits + */ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoNum(void) +{ + return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_NUM_Msk) >> CLIC_CLICINFO_NUM_Pos)); +} + +/** + * \brief Set Machine Mode Interrupt Level Threshold + * \details + * This function sets machine mode interrupt level threshold. + * \param [in] mth Interrupt Level Threshold. + * \sa + * - \ref ECLIC_GetMth + */ +__STATIC_FORCEINLINE void __ECLIC_SetMth(uint8_t mth) +{ + ECLIC->MTH = mth; +} + +/** + * \brief Get Machine Mode Interrupt Level Threshold + * \details + * This function gets machine mode interrupt level threshold. + * \return Interrupt Level Threshold. + * \sa + * - \ref ECLIC_SetMth + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetMth(void) +{ + return (ECLIC->MTH); +} + + +/** + * \brief Enable a specific interrupt + * \details + * This function enables the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_DisableIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_EnableIRQ(IRQn_Type IRQn) +{ + ECLIC->CTRL[IRQn].INTIE |= CLIC_INTIE_IE_Msk; +} + +/** + * \brief Get a specific interrupt enable status + * \details + * This function returns the interrupt enable status for the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \returns + * - 0 Interrupt is not enabled + * - 1 Interrupt is pending + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_EnableIRQ + * - \ref ECLIC_DisableIRQ + */ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetEnableIRQ(IRQn_Type IRQn) +{ + return ((uint32_t) (ECLIC->CTRL[IRQn].INTIE) & CLIC_INTIE_IE_Msk); +} + +/** + * \brief Disable a specific interrupt + * \details + * This function disables the specific interrupt \em IRQn. + * \param [in] IRQn Number of the external interrupt to disable + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_EnableIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_DisableIRQ(IRQn_Type IRQn) +{ + ECLIC->CTRL[IRQn].INTIE &= ~CLIC_INTIE_IE_Msk; +} + +/** + * \brief Get the pending specific interrupt + * \details + * This function returns the pending status of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \returns + * - 0 Interrupt is not pending + * - 1 Interrupt is pending + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetPendingIRQ + * - \ref ECLIC_ClearPendingIRQ + */ +__STATIC_FORCEINLINE int32_t __ECLIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return ((uint32_t)(ECLIC->CTRL[IRQn].INTIP) & CLIC_INTIP_IP_Msk); +} + +/** + * \brief Set a specific interrupt to pending + * \details + * This function sets the pending bit for the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_GetPendingIRQ + * - \ref ECLIC_ClearPendingIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetPendingIRQ(IRQn_Type IRQn) +{ + ECLIC->CTRL[IRQn].INTIP |= CLIC_INTIP_IP_Msk; +} + +/** + * \brief Clear a specific interrupt from pending + * \details + * This function removes the pending state of the specific interrupt \em IRQn. + * \em IRQn cannot be a negative number. + * \param [in] IRQn Interrupt number + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetPendingIRQ + * - \ref ECLIC_GetPendingIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + ECLIC->CTRL[IRQn].INTIP &= ~CLIC_INTIP_IP_Msk; +} + +/** + * \brief Set trigger mode and polarity for a specific interrupt + * \details + * This function set trigger mode and polarity of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] trig + * - 00 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 01 positive edge trigger, \ref ECLIC_POSTIVE_EDGE_TRIGGER + * - 02 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 03 negative edge trigger, \ref ECLIC_NEGTIVE_EDGE_TRIGGER + * \remarks + * - IRQn must not be negative. + * + * \sa + * - \ref ECLIC_GetTrigIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetTrigIRQ(IRQn_Type IRQn, uint32_t trig) +{ + ECLIC->CTRL[IRQn].INTATTR &= ~CLIC_INTATTR_TRIG_Msk; + ECLIC->CTRL[IRQn].INTATTR |= (uint8_t)(trig << CLIC_INTATTR_TRIG_Pos); +} + +/** + * \brief Get trigger mode and polarity for a specific interrupt + * \details + * This function get trigger mode and polarity of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return + * - 00 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 01 positive edge trigger, \ref ECLIC_POSTIVE_EDGE_TRIGGER + * - 02 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 03 negative edge trigger, \ref ECLIC_NEGTIVE_EDGE_TRIGGER + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetTrigIRQ + */ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetTrigIRQ(IRQn_Type IRQn) +{ + return ((uint32_t)(((ECLIC->CTRL[IRQn].INTATTR) & CLIC_INTATTR_TRIG_Msk) >> CLIC_INTATTR_TRIG_Pos)); +} + +/** + * \brief Set interrupt working mode for a specific interrupt + * \details + * This function set selective hardware vector or non-vector working mode of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] shv + * - 0 non-vector mode, \ref ECLIC_NON_VECTOR_INTERRUPT + * - 1 vector mode, \ref ECLIC_VECTOR_INTERRUPT + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_GetShvIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetShvIRQ(IRQn_Type IRQn, uint32_t shv) +{ + ECLIC->CTRL[IRQn].INTATTR &= ~CLIC_INTATTR_SHV_Msk; + ECLIC->CTRL[IRQn].INTATTR |= (uint8_t)(shv << CLIC_INTATTR_SHV_Pos); +} + +/** + * \brief Get interrupt working mode for a specific interrupt + * \details + * This function get selective hardware vector or non-vector working mode of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return shv + * - 0 non-vector mode, \ref ECLIC_NON_VECTOR_INTERRUPT + * - 1 vector mode, \ref ECLIC_VECTOR_INTERRUPT + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetShvIRQ + */ +__STATIC_FORCEINLINE uint32_t __ECLIC_GetShvIRQ(IRQn_Type IRQn) +{ + return ((uint32_t)(((ECLIC->CTRL[IRQn].INTATTR) & CLIC_INTATTR_SHV_Msk) >> CLIC_INTATTR_SHV_Pos)); +} + +/** + * \brief Modify ECLIC Interrupt Input Control Register for a specific interrupt + * \details + * This function modify ECLIC Interrupt Input Control(CLICINTCTL[i]) register of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] intctrl Set value for CLICINTCTL[i] register + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_GetCtrlIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetCtrlIRQ(IRQn_Type IRQn, uint8_t intctrl) +{ + ECLIC->CTRL[IRQn].INTCTRL = intctrl; +} + +/** + * \brief Get ECLIC Interrupt Input Control Register value for a specific interrupt + * \details + * This function modify ECLIC Interrupt Input Control register of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return value of ECLIC Interrupt Input Control register + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetCtrlIRQ + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetCtrlIRQ(IRQn_Type IRQn) +{ + return (ECLIC->CTRL[IRQn].INTCTRL); +} + +/** + * \brief Set ECLIC Interrupt level of a specific interrupt + * \details + * This function set interrupt level of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] lvl_abs Interrupt level + * \remarks + * - IRQn must not be negative. + * - If lvl_abs to be set is larger than the max level allowed, it will be force to be max level. + * - When you set level value you need use clciinfo.nlbits to get the width of level. + * Then we could know the maximum of level. CLICINTCTLBITS is how many total bits are + * present in the CLICINTCTL register. + * \sa + * - \ref ECLIC_GetLevelIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetLevelIRQ(IRQn_Type IRQn, uint8_t lvl_abs) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + + if (nlbits == 0) { + return; + } + + if (nlbits > intctlbits) { + nlbits = intctlbits; + } + uint8_t maxlvl = ((1 << nlbits) - 1); + if (lvl_abs > maxlvl) { + lvl_abs = maxlvl; + } + uint8_t lvl = lvl_abs << (ECLIC_MAX_NLBITS - nlbits); + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn); + cur_ctrl = cur_ctrl << nlbits; + cur_ctrl = cur_ctrl >> nlbits; + __ECLIC_SetCtrlIRQ(IRQn, (cur_ctrl | lvl)); +} + +/** + * \brief Get ECLIC Interrupt level of a specific interrupt + * \details + * This function get interrupt level of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt level + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetLevelIRQ + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetLevelIRQ(IRQn_Type IRQn) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + + if (nlbits == 0) { + return 0; + } + + if (nlbits > intctlbits) { + nlbits = intctlbits; + } + uint8_t intctrl = __ECLIC_GetCtrlIRQ(IRQn); + uint8_t lvl_abs = intctrl >> (ECLIC_MAX_NLBITS - nlbits); + return lvl_abs; +} + +/** + * \brief Get ECLIC Interrupt priority of a specific interrupt + * \details + * This function get interrupt priority of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] pri Interrupt priority + * \remarks + * - IRQn must not be negative. + * - If pri to be set is larger than the max priority allowed, it will be force to be max priority. + * - Priority width is CLICINTCTLBITS minus clciinfo.nlbits if clciinfo.nlbits + * is less than CLICINTCTLBITS. Otherwise priority width is 0. + * \sa + * - \ref ECLIC_GetPriorityIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_SetPriorityIRQ(IRQn_Type IRQn, uint8_t pri) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + if (nlbits < intctlbits) { + uint8_t maxpri = ((1 << (intctlbits - nlbits)) - 1); + if (pri > maxpri) { + pri = maxpri; + } + pri = pri << (ECLIC_MAX_NLBITS - intctlbits); + uint8_t mask = ((uint8_t)(-1)) >> intctlbits; + pri = pri | mask; + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn); + cur_ctrl = cur_ctrl >> (ECLIC_MAX_NLBITS - nlbits); + cur_ctrl = cur_ctrl << (ECLIC_MAX_NLBITS - nlbits); + __ECLIC_SetCtrlIRQ(IRQn, (cur_ctrl | pri)); + } +} + +/** + * \brief Get ECLIC Interrupt priority of a specific interrupt + * \details + * This function get interrupt priority of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt priority + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetPriorityIRQ + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetPriorityIRQ(IRQn_Type IRQn) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + if (nlbits < intctlbits) { + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn); + uint8_t pri = cur_ctrl << nlbits; + pri = pri >> nlbits; + pri = pri >> (ECLIC_MAX_NLBITS - intctlbits); + return pri; + } else { + return 0; + } +} + +/** + * \brief Set Interrupt Vector of a specific interrupt + * \details + * This function set interrupt handler address of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] vector Interrupt handler address + * \remarks + * - IRQn must not be negative. + * - You can set the \ref CSR_CSR_MTVT to set interrupt vector table entry address. + * - If your vector table is placed in readonly section, the vector for IRQn will not be modified. + * For this case, you need to use the correct irq handler name defined in your vector table as + * your irq handler function name. + * - This function will only work correctly when the vector table is placed in an read-write enabled section. + * \sa + * - \ref ECLIC_GetVector + */ +__STATIC_FORCEINLINE void __ECLIC_SetVector(IRQn_Type IRQn, rv_csr_t vector) +{ + volatile unsigned long vec_base; + vec_base = ((unsigned long)__RV_CSR_READ(CSR_MTVT)); + vec_base += ((unsigned long)IRQn) * sizeof(unsigned long); + (* (unsigned long *) vec_base) = vector; +#if (defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1)) +#if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1)) + MFlushDCacheLine((unsigned long)vec_base); +#endif +#endif +#if (defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1)) +#if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1)) + MInvalICacheLine((unsigned long)vec_base); +#else + __FENCE_I(); +#endif +#endif +} + +/** + * \brief Get Interrupt Vector of a specific interrupt + * \details + * This function get interrupt handler address of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt handler address + * \remarks + * - IRQn must not be negative. + * - You can read \ref CSR_CSR_MTVT to get interrupt vector table entry address. + * \sa + * - \ref ECLIC_SetVector + */ +__STATIC_FORCEINLINE rv_csr_t __ECLIC_GetVector(IRQn_Type IRQn) +{ +#if __RISCV_XLEN == 32 + return (*(uint32_t *)(__RV_CSR_READ(CSR_MTVT) + IRQn * 4)); +#elif __RISCV_XLEN == 64 + return (*(uint64_t *)(__RV_CSR_READ(CSR_MTVT) + IRQn * 8)); +#else // TODO Need cover for XLEN=128 case in future + return (*(uint64_t *)(__RV_CSR_READ(CSR_MTVT) + IRQn * 8)); +#endif +} + +#if defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) +/** + * \brief Set privilege mode of a specific interrupt + * \details + * This function set in which privilege mode the interrupts \em IRQn should be taken. + * \param [in] IRQn Interrupt number + * \param [in] mode Privilege mode + * \remarks + * - IRQn must not be negative. + * - mode must be 1(Supervisor Mode) or 3(Machine Mode), other values are ignored. + * - M-mode can R/W this field, but S-mode can only read.And ECLIC with TEE does not + * reply on CSR mideleg to delegate interrupts. + * - Mode of S-mode ECLIC region's clicintattr can be omitted to set, which is mirror to M-mode ECLIC region's. + * Only the low 6 bits of clicintattr [i] can be written via the S-mode memory region. + */ +__STATIC_FORCEINLINE void __ECLIC_SetModeIRQ(IRQn_Type IRQn, uint32_t mode) +{ + /* + * only 1 or 3 can be assigned to mode in one step.the default value of mode is 3, + * which can't be clear to 0 firstly, then OR it to 1 + */ + ECLIC->CTRL[IRQn].INTATTR = (uint8_t)(mode << CLIC_INTATTR_MODE_Pos) + \ + (ECLIC->SCTRL[IRQn].INTATTR & (~CLIC_INTATTR_MODE_Msk)); +} + +/** + * \brief Set supervisor-mode Interrupt Level Threshold in supervisor mode + * \details + * This function sets supervisor-mode interrupt level threshold. + * \param [in] sth Interrupt Level Threshold. + * \remarks + * - S-mode ECLIC region sintthresh'sth is a mirror to M-mode ECLIC region's mintthresh.sth, + * and will be updated synchronously, here operate on mintthresh.sth. + * \sa + * - \ref ECLIC_GetSth + */ +__STATIC_FORCEINLINE void __ECLIC_SetSth(uint8_t sth) +{ + ECLIC->STH = sth; +} + +/** + * \brief Get supervisor-mode Interrupt Level Threshold in supervisor mode + * \details + * This function gets supervisor mode interrupt level threshold. + * \return Interrupt Level Threshold. + * \remarks + * - S-mode ECLIC region sintthresh'sth is a mirror to M-mode ECLIC region's mintthresh.sth, + * and will be updated synchronously, here operate on mintthresh.sth. + * \sa + * - \ref ECLIC_SetSth + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetSth(void) +{ + return (ECLIC->STH); +} + +/** + * \brief Set trigger mode and polarity for a specific interrupt in supervisor mode + * \details + * This function set trigger mode and polarity of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] trig + * - 00 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 01 positive edge trigger, \ref ECLIC_POSTIVE_EDGE_TRIGGER + * - 02 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 03 negative edge trigger, \ref ECLIC_NEGTIVE_EDGE_TRIGGER + * \remarks + * - IRQn must not be negative. + * + * \sa + * - \ref ECLIC_GetTrigIRQ_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetTrigIRQ_S(IRQn_Type IRQn, uint32_t trig) +{ + ECLIC->SCTRL[IRQn].INTATTR &= ~CLIC_INTATTR_TRIG_Msk; + ECLIC->SCTRL[IRQn].INTATTR |= (uint8_t)(trig << CLIC_INTATTR_TRIG_Pos); +} + +/** + * \brief Get trigger mode and polarity for a specific interrupt in supervisor mode + * \details + * This function get trigger mode and polarity of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return + * - 00 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 01 positive edge trigger, \ref ECLIC_POSTIVE_EDGE_TRIGGER + * - 02 level trigger, \ref ECLIC_LEVEL_TRIGGER + * - 03 negative edge trigger, \ref ECLIC_NEGTIVE_EDGE_TRIGGER + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetTrigIRQ_S + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetTrigIRQ_S(IRQn_Type IRQn) +{ + return ((uint8_t)(((ECLIC->SCTRL[IRQn].INTATTR) & CLIC_INTATTR_TRIG_Msk) >> CLIC_INTATTR_TRIG_Pos)); +} + + +/** + * \brief Set interrupt working mode for a specific interrupt in supervisor mode + * \details + * This function set selective hardware vector or non-vector working mode of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] shv + * - 0 non-vector mode, \ref ECLIC_NON_VECTOR_INTERRUPT + * - 1 vector mode, \ref ECLIC_VECTOR_INTERRUPT + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_GetShvIRQ_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetShvIRQ_S(IRQn_Type IRQn, uint32_t shv) +{ + ECLIC->SCTRL[IRQn].INTATTR &= ~CLIC_INTATTR_SHV_Msk; + ECLIC->SCTRL[IRQn].INTATTR |= (uint8_t)(shv << CLIC_INTATTR_SHV_Pos); +} + +/** + * \brief Get interrupt working mode for a specific interrupt in supervisor mode + * \details + * This function get selective hardware vector or non-vector working mode of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return shv + * - 0 non-vector mode, \ref ECLIC_NON_VECTOR_INTERRUPT + * - 1 vector mode, \ref ECLIC_VECTOR_INTERRUPT + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SMODE_SetShvIRQ + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetShvIRQ_S(IRQn_Type IRQn) +{ + return ((uint8_t)(((ECLIC->SCTRL[IRQn].INTATTR) & CLIC_INTATTR_SHV_Msk) >> CLIC_INTATTR_SHV_Pos)); +} + +/** + * \brief Modify ECLIC Interrupt Input Control Register for a specific interrupt in supervisor mode + * \details + * This function modify ECLIC Interrupt Input Control(CLICINTCTL[i]) register of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] intctrl Set value for CLICINTCTL[i] register + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_GetCtrlIRQ_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetCtrlIRQ_S(IRQn_Type IRQn, uint8_t intctrl) +{ + ECLIC->SCTRL[IRQn].INTCTRL = intctrl; +} + +/** + * \brief Get ECLIC Interrupt Input Control Register value for a specific interrupt in supervisor mode + * \details + * This function modify ECLIC Interrupt Input Control register of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return value of ECLIC Interrupt Input Control register + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetCtrlIRQ_S + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetCtrlIRQ_S(IRQn_Type IRQn) +{ + return (ECLIC->SCTRL[IRQn].INTCTRL); +} + +/** + * \brief Set ECLIC Interrupt level of a specific interrupt in supervisor mode + * \details + * This function set interrupt level of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] lvl_abs Interrupt level + * \remarks + * - IRQn must not be negative. + * - If lvl_abs to be set is larger than the max level allowed, it will be force to be max level. + * - When you set level value you need use clciinfo.nlbits to get the width of level. + * Then we could know the maximum of level. CLICINTCTLBITS is how many total bits are + * present in the CLICINTCTL register. + * \sa + * - \ref ECLIC_GetLevelIRQ_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetLevelIRQ_S(IRQn_Type IRQn, uint8_t lvl_abs) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + + if (nlbits == 0) { + return; + } + + if (nlbits > intctlbits) { + nlbits = intctlbits; + } + uint8_t maxlvl = ((1 << nlbits) - 1); + if (lvl_abs > maxlvl) { + lvl_abs = maxlvl; + } + uint8_t lvl = lvl_abs << (ECLIC_MAX_NLBITS - nlbits); + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ_S(IRQn); + cur_ctrl = cur_ctrl << nlbits; + cur_ctrl = cur_ctrl >> nlbits; + __ECLIC_SetCtrlIRQ_S(IRQn, (cur_ctrl | lvl)); +} + + +/** + * \brief Get ECLIC Interrupt level of a specific interrupt + * \details + * This function get interrupt level of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt level + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetLevelIRQ_S + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetLevelIRQ_S(IRQn_Type IRQn) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + + if (nlbits == 0) { + return 0; + } + + if (nlbits > intctlbits) { + nlbits = intctlbits; + } + uint8_t intctrl = __ECLIC_GetCtrlIRQ_S(IRQn); + uint8_t lvl_abs = intctrl >> (ECLIC_MAX_NLBITS - nlbits); + return lvl_abs; +} + +/** + * \brief Set ECLIC Interrupt priority of a specific interrupt in supervisor mode + * \details + * This function get interrupt priority of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] pri Interrupt priority + * \remarks + * - IRQn must not be negative. + * - If pri to be set is larger than the max priority allowed, it will be force to be max priority. + * - Priority width is CLICINTCTLBITS minus clciinfo.nlbits if clciinfo.nlbits + * is less than CLICINTCTLBITS. Otherwise priority width is 0. + * \sa + * - \ref ECLIC_GetPriorityIRQ_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetPriorityIRQ_S(IRQn_Type IRQn, uint8_t pri) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + if (nlbits < intctlbits) { + uint8_t maxpri = ((1 << (intctlbits - nlbits)) - 1); + if (pri > maxpri) { + pri = maxpri; + } + pri = pri << (ECLIC_MAX_NLBITS - intctlbits); + uint8_t mask = ((uint8_t)(-1)) >> intctlbits; + pri = pri | mask; + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ_S(IRQn); + cur_ctrl = cur_ctrl >> (ECLIC_MAX_NLBITS - nlbits); + cur_ctrl = cur_ctrl << (ECLIC_MAX_NLBITS - nlbits); + __ECLIC_SetCtrlIRQ_S(IRQn, (cur_ctrl | pri)); + } +} + +/** + * \brief Get ECLIC Interrupt priority of a specific interrupt in supervisor mode + * \details + * This function get interrupt priority of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt priority + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_SetPriorityIRQ_S + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetPriorityIRQ_S(IRQn_Type IRQn) +{ + uint8_t nlbits = __ECLIC_GetCfgNlbits(); + uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS; + if (nlbits < intctlbits) { + uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ_S(IRQn); + uint8_t pri = cur_ctrl << nlbits; + pri = pri >> nlbits; + pri = pri >> (ECLIC_MAX_NLBITS - intctlbits); + return pri; + } else { + return 0; + } +} + +/** + * \brief Enable a specific interrupt in supervisor mode + * \details + * This function enables the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_DisableIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_EnableIRQ_S(IRQn_Type IRQn) +{ + ECLIC->SCTRL[IRQn].INTIE |= CLIC_INTIE_IE_Msk; +} + +/** + * \brief Get a specific interrupt enable status in supervisor mode + * \details + * This function returns the interrupt enable status for the specific interrupt \em IRQn in S MODE. + * \param [in] IRQn Interrupt number + * \returns + * - 0 Interrupt is not masked + * - 1 Interrupt is enabled + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_EnableIRQ_S + * - \ref ECLIC_DisableIRQ_S + */ +__STATIC_FORCEINLINE uint8_t __ECLIC_GetEnableIRQ_S(IRQn_Type IRQn) +{ + return ((uint8_t) (ECLIC->SCTRL[IRQn].INTIE) & CLIC_INTIE_IE_Msk); +} + +/** + * \brief Disable a specific interrupt in supervisor mode + * \details + * This function disables the specific interrupt \em IRQn. + * \param [in] IRQn Number of the external interrupt to disable + * \remarks + * - IRQn must not be negative. + * \sa + * - \ref ECLIC_EnableIRQ + */ +__STATIC_FORCEINLINE void __ECLIC_DisableIRQ_S(IRQn_Type IRQn) +{ + ECLIC->SCTRL[IRQn].INTIE &= ~CLIC_INTIE_IE_Msk; +} + +/** + * \brief Set Interrupt Vector of a specific interrupt in supervisor mode + * \details + * This function set interrupt handler address of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \param [in] vector Interrupt handler address + * \remarks + * - IRQn must not be negative. + * - You can set the \ref CSR_CSR_MTVT to set interrupt vector table entry address. + * - If your vector table is placed in readonly section, the vector for IRQn will not be modified. + * For this case, you need to use the correct irq handler name defined in your vector table as + * your irq handler function name. + * - This function will only work correctly when the vector table is placed in an read-write enabled section. + * \sa + * - \ref ECLIC_GetVector_S + */ +__STATIC_FORCEINLINE void __ECLIC_SetVector_S(IRQn_Type IRQn, rv_csr_t vector) +{ + volatile unsigned long vec_base; + vec_base = ((unsigned long)__RV_CSR_READ(CSR_STVT)); + vec_base += ((unsigned long)IRQn) * sizeof(unsigned long); + (* (unsigned long *) vec_base) = vector; +#if (defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1)) +#if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1)) + SFlushDCacheLine((unsigned long)vec_base); +#endif +#endif +#if (defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1)) +#if (defined(__CCM_PRESENT) && (__CCM_PRESENT == 1)) + SInvalICacheLine((unsigned long)vec_base); +#else + __FENCE_I(); +#endif +#endif +} + +/** + * \brief Get Interrupt Vector of a specific interrupt in supervisor mode + * \details + * This function get interrupt handler address of the specific interrupt \em IRQn. + * \param [in] IRQn Interrupt number + * \return Interrupt handler address + * \remarks + * - IRQn must not be negative. + * - You can read \ref CSR_CSR_MTVT to get interrupt vector table entry address. + * \sa + * - \ref ECLIC_SMODE_SetVector + */ +__STATIC_FORCEINLINE rv_csr_t __ECLIC_GetVector_S(IRQn_Type IRQn) +{ +#if __RISCV_XLEN == 32 + return (*(uint32_t *)(__RV_CSR_READ(CSR_STVT) + IRQn * 4)); +#elif __RISCV_XLEN == 64 + return (*(uint64_t *)(__RV_CSR_READ(CSR_STVT) + IRQn * 8)); +#else // TODO Need cover for XLEN=128 case in future + return (*(uint64_t *)(__RV_CSR_READ(CSR_STVT) + IRQn * 8)); +#endif +} + +#endif /* defined(__TEE_PRESENT) && (__TEE_PRESENT == 1) */ + +/** + * \brief Set Exception entry address + * \details + * This function set exception handler address to 'CSR_MTVEC'. + * \param [in] addr Exception handler address + * \remarks + * - This function use to set exception handler address to 'CSR_MTVEC'. + * Address need to be aligned to 64 bytes. + * \sa + * - \ref __get_exc_entry + */ +__STATIC_FORCEINLINE void __set_exc_entry(rv_csr_t addr) +{ + addr &= (rv_csr_t)(~0x3F); + addr |= ECLIC_MODE_MTVEC_Msk; + __RV_CSR_WRITE(CSR_MTVEC, addr); +} + +/** + * \brief Get Exception entry address + * \details + * This function get exception handler address from 'CSR_MTVEC'. + * \return Exception handler address + * \remarks + * - This function use to get exception handler address from 'CSR_MTVEC'. + * Address need to be aligned to 64 bytes. + * \sa + * - \ref __set_exc_entry + */ +__STATIC_FORCEINLINE rv_csr_t __get_exc_entry(void) +{ + unsigned long addr = __RV_CSR_READ(CSR_MTVEC); + return (addr & ~ECLIC_MODE_MTVEC_Msk); +} + +/** + * \brief Set Non-vector interrupt entry address + * \details + * This function set Non-vector interrupt address. + * \param [in] addr Non-vector interrupt entry address + * \remarks + * - This function use to set non-vector interrupt entry address to 'CSR_MTVT2' if + * - CSR_MTVT2 bit0 is 1. If 'CSR_MTVT2' bit0 is 0 then set address to 'CSR_MTVEC' + * \sa + * - \ref __get_nonvec_entry + */ +__STATIC_FORCEINLINE void __set_nonvec_entry(rv_csr_t addr) +{ + if (__RV_CSR_READ(CSR_MTVT2) & 0x1) { + __RV_CSR_WRITE(CSR_MTVT2, addr | 0x01); + } else { + addr &= (rv_csr_t)(~0x3F); + addr |= ECLIC_MODE_MTVEC_Msk; + __RV_CSR_WRITE(CSR_MTVEC, addr); + } +} + +/** + * \brief Get Non-vector interrupt entry address + * \details + * This function get Non-vector interrupt address. + * \return Non-vector interrupt handler address + * \remarks + * - This function use to get non-vector interrupt entry address from 'CSR_MTVT2' if + * - CSR_MTVT2 bit0 is 1. If 'CSR_MTVT2' bit0 is 0 then get address from 'CSR_MTVEC'. + * \sa + * - \ref __set_nonvec_entry + */ +__STATIC_FORCEINLINE rv_csr_t __get_nonvec_entry(void) +{ + if (__RV_CSR_READ(CSR_MTVT2) & 0x1) { + return __RV_CSR_READ(CSR_MTVT2) & (~(rv_csr_t)(0x1)); + } else { + rv_csr_t addr = __RV_CSR_READ(CSR_MTVEC); + return (addr & ~ECLIC_MODE_MTVEC_Msk); + } +} + +/** + * \brief Get NMI interrupt entry from 'CSR_MNVEC' + * \details + * This function get NMI interrupt address from 'CSR_MNVEC'. + * \return NMI interrupt handler address + * \remarks + * - This function use to get NMI interrupt handler address from 'CSR_MNVEC'. If CSR_MMISC_CTL[9] = 1 'CSR_MNVEC' + * - will be equal as mtvec. If CSR_MMISC_CTL[9] = 0 'CSR_MNVEC' will be equal as reset vector. + * - NMI entry is defined via \ref CSR_MMISC_CTL, writing to \ref CSR_MNVEC will be ignored. + */ +__STATIC_FORCEINLINE rv_csr_t __get_nmi_entry(void) +{ + return __RV_CSR_READ(CSR_MNVEC); +} + +/** + * \brief Save necessary CSRs into variables for vector interrupt nesting + * \details + * This macro is used to declare variables which are used for saving + * CSRs(MCAUSE, MEPC, MSUB), and it will read these CSR content into + * these variables, it need to be used in a vector-interrupt if nesting + * is required. + * \remarks + * - Interrupt will be enabled after this macro is called + * - It need to be used together with \ref RESTORE_IRQ_CSR_CONTEXT + * - Don't use variable names __mcause, __mpec, __msubm in your ISR code + * - If you want to enable interrupt nesting feature for vector interrupt, + * you can do it like this: + * \code + * // __INTERRUPT attribute will generates function entry and exit sequences suitable + * // for use in an interrupt handler when this attribute is present + * __INTERRUPT void eclic_mtip_handler(void) + * { + * // Must call this to save CSRs + * SAVE_IRQ_CSR_CONTEXT(); + * // !!!Interrupt is enabled here!!! + * // !!!Higher priority interrupt could nest it!!! + * + * // put you own interrupt handling code here + * + * // Must call this to restore CSRs + * RESTORE_IRQ_CSR_CONTEXT(); + * } + * \endcode + */ +#define SAVE_IRQ_CSR_CONTEXT() \ + rv_csr_t __mcause = __RV_CSR_READ(CSR_MCAUSE); \ + rv_csr_t __mepc = __RV_CSR_READ(CSR_MEPC); \ + rv_csr_t __msubm = __RV_CSR_READ(CSR_MSUBM); \ + __enable_irq(); + +/*! Save necessary CSRs into variables for vector interrupt nesting in supervisor mode */ +#define SAVE_IRQ_CSR_CONTEXT_S() \ + rv_csr_t __scause = __RV_CSR_READ(CSR_SCAUSE); \ + rv_csr_t __sepc = __RV_CSR_READ(CSR_SEPC); \ + __enable_irq_s(); + + +/** + * \brief Restore necessary CSRs from variables for vector interrupt nesting + * \details + * This macro is used restore CSRs(MCAUSE, MEPC, MSUB) from pre-defined variables + * in \ref SAVE_IRQ_CSR_CONTEXT macro. + * \remarks + * - Interrupt will be disabled after this macro is called + * - It need to be used together with \ref SAVE_IRQ_CSR_CONTEXT + */ +#define RESTORE_IRQ_CSR_CONTEXT() \ + __disable_irq(); \ + __RV_CSR_WRITE(CSR_MSUBM, __msubm); \ + __RV_CSR_WRITE(CSR_MEPC, __mepc); \ + __RV_CSR_WRITE(CSR_MCAUSE, __mcause); + +/*! Restore necessary CSRs from variables for vector interrupt nesting in supervisor mode */ +#define RESTORE_IRQ_CSR_CONTEXT_S() \ + __disable_irq_s(); \ + __RV_CSR_WRITE(CSR_SEPC, __sepc); \ + __RV_CSR_WRITE(CSR_SCAUSE, __scause); +/** @} */ /* End of Doxygen Group NMSIS_Core_IntExc */ + +#endif /* defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_ECLIC__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_fpu.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_fpu.h new file mode 100644 index 0000000..1c56293 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_fpu.h @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_FPU_H__ +#define __CORE_FEATURE_FPU_H__ +/*! + * @file core_feature_fpu.h + * @brief FPU feature API header file for Nuclei N/NX Core + */ +/* + * FPU Feature Configuration Macro: + * 1. __FPU_PRESENT: Define whether Floating Point Unit(FPU) is present or not + * * 0: Not present + * * 1: Single precision FPU present, __RISCV_FLEN == 32 + * * 2: Double precision FPU present, __RISCV_FLEN == 64 + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +/* ===== FPU Operations ===== */ +/** + * \defgroup NMSIS_Core_FPU_Functions FPU Functions + * \ingroup NMSIS_Core + * \brief Functions that related to the RISC-V FPU (F and D extension). + * \details + * + * Nuclei provided floating point unit by RISC-V F and D extension. + * * `F extension` adds single-precision floating-point computational + * instructions compliant with the IEEE 754-2008 arithmetic standard, __RISCV_FLEN = 32. + * The F extension adds 32 floating-point registers, f0-f31, each 32 bits wide, + * and a floating-point control and status register fcsr, which contains the + * operating mode and exception status of the floating-point unit. + * * `D extension` adds double-precision floating-point computational instructions + * compliant with the IEEE 754-2008 arithmetic standard. + * The D extension widens the 32 floating-point registers, f0-f31, to 64 bits, __RISCV_FLEN = 64 + * @{ + */ +#if defined(__FPU_PRESENT) && (__FPU_PRESENT > 0) + +#if __FPU_PRESENT == 1 + /** \brief Refer to the width of the floating point register in bits(either 32 or 64) */ + #define __RISCV_FLEN 32 +#elif __FPU_PRESENT == 2 + #define __RISCV_FLEN 64 +#else + #define __RISCV_FLEN __riscv_flen +#endif /* __FPU_PRESENT == 1 */ + +/** \brief Get FCSR CSR Register */ +#define __get_FCSR() __RV_CSR_READ(CSR_FCSR) +/** \brief Set FCSR CSR Register with val */ +#define __set_FCSR(val) __RV_CSR_WRITE(CSR_FCSR, (val)) +/** \brief Get FRM CSR Register */ +#define __get_FRM() __RV_CSR_READ(CSR_FRM) +/** \brief Set FRM CSR Register with val */ +#define __set_FRM(val) __RV_CSR_WRITE(CSR_FRM, (val)) +/** \brief Get FFLAGS CSR Register */ +#define __get_FFLAGS() __RV_CSR_READ(CSR_FFLAGS) +/** \brief Set FFLAGS CSR Register with val */ +#define __set_FFLAGS(val) __RV_CSR_WRITE(CSR_FFLAGS, (val)) + +/** \brief Enable FPU Unit, and set state to initial */ +#define __enable_FPU() { __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_FS); \ + __RV_CSR_SET(CSR_MSTATUS, MSTATUS_FS_INITIAL); \ + } +/** + * \brief Disable FPU Unit + * \details + * * We can save power by disable FPU Unit. + * * When FPU Unit is disabled, any access to FPU related CSR registers + * and FPU instructions will cause illegal Instuction Exception. + * */ +#define __disable_FPU() __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_FS) + + +/** + * \brief Load a single-precision value from memory into float point register freg using flw instruction + * \details The FLW instruction loads a single-precision floating point value from memory + * address (addr + ofs) into floating point register freg(f0-f31) + * \param [in] freg The floating point register, eg. FREG(0), f0 + * \param [in] addr The memory base address, 4 byte aligned required + * \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value + * \remarks + * * FLW and FSW operations need to make sure the address is 4 bytes aligned, + * otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned) + * * FLW and FSW do not modify the bits being transferred; in particular, the payloads of non-canonical + * NaNs are preserved + * + */ +#define __RV_FLW(freg, addr, ofs) \ + ({ \ + rv_csr_t __addr = (rv_csr_t)(addr); \ + __ASM volatile("flw " STRINGIFY(freg) ", %0(%1) " \ + : : "I"(ofs), "r"(__addr) \ + : "memory"); \ + }) + +/** + * \brief Store a single-precision value from float point freg into memory using fsw instruction + * \details The FSW instruction stores a single-precision value from floating point register to memory + * \param [in] freg The floating point register(f0-f31), eg. FREG(0), f0 + * \param [in] addr The memory base address, 4 byte aligned required + * \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value + * \remarks + * * FLW and FSW operations need to make sure the address is 4 bytes aligned, + * otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned) + * * FLW and FSW do not modify the bits being transferred; in particular, the payloads of non-canonical + * NaNs are preserved + * + */ +#define __RV_FSW(freg, addr, ofs) \ + ({ \ + rv_csr_t __addr = (rv_csr_t)(addr); \ + __ASM volatile("fsw " STRINGIFY(freg) ", %0(%1) " \ + : : "I"(ofs), "r"(__addr) \ + : "memory"); \ + }) + +/** + * \brief Load a double-precision value from memory into float point register freg using fld instruction + * \details The FLD instruction loads a double-precision floating point value from memory + * address (addr + ofs) into floating point register freg(f0-f31) + * \param [in] freg The floating point register, eg. FREG(0), f0 + * \param [in] addr The memory base address, 8 byte aligned required + * \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value + * \attention + * * Function only available for double precision floating point unit, FLEN = 64 + * \remarks + * * FLD and FSD operations need to make sure the address is 8 bytes aligned, + * otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned) + * * FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical + * NaNs are preserved. + */ +#define __RV_FLD(freg, addr, ofs) \ + ({ \ + rv_csr_t __addr = (rv_csr_t)(addr); \ + __ASM volatile("fld " STRINGIFY(freg) ", %0(%1) " \ + : : "I"(ofs), "r"(__addr) \ + : "memory"); \ + }) + +/** + * \brief Store a double-precision value from float point freg into memory using fsd instruction + * \details The FSD instruction stores double-precision value from floating point register to memory + * \param [in] freg The floating point register(f0-f31), eg. FREG(0), f0 + * \param [in] addr The memory base address, 8 byte aligned required + * \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value + * \attention + * * Function only available for double precision floating point unit, FLEN = 64 + * \remarks + * * FLD and FSD operations need to make sure the address is 8 bytes aligned, + * otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned) + * * FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical + * NaNs are preserved. + * + */ +#define __RV_FSD(freg, addr, ofs) \ + ({ \ + rv_csr_t __addr = (rv_csr_t)(addr); \ + __ASM volatile("fsd " STRINGIFY(freg) ", %0(%1) " \ + : : "I"(ofs), "r"(__addr) \ + : "memory"); \ + }) + +/** + * \def __RV_FLOAD + * \brief Load a float point value from memory into float point register freg using flw/fld instruction + * \details + * * For Single-Precison Floating-Point Mode(__FPU_PRESENT == 1, __RISCV_FLEN == 32): + * It will call \ref __RV_FLW to load a single-precision floating point value from memory to floating point register + * * For Double-Precison Floating-Point Mode(__FPU_PRESENT == 2, __RISCV_FLEN == 64): + * It will call \ref __RV_FLD to load a double-precision floating point value from memory to floating point register + * + * \attention + * Function behaviour is different for __FPU_PRESENT = 1 or 2, please see the real function this macro represent + */ +/** + * \def __RV_FSTORE + * \brief Store a float value from float point freg into memory using fsw/fsd instruction + * \details + * * For Single-Precison Floating-Point Mode(__FPU_PRESENT == 1, __RISCV_FLEN == 32): + * It will call \ref __RV_FSW to store floating point register into memory + * * For Double-Precison Floating-Point Mode(__FPU_PRESENT == 2, __RISCV_FLEN == 64): + * It will call \ref __RV_FSD to store floating point register into memory + * + * \attention + * Function behaviour is different for __FPU_PRESENT = 1 or 2, please see the real function this macro represent + */ +#if __FPU_PRESENT == 1 +#define __RV_FLOAD __RV_FLW +#define __RV_FSTORE __RV_FSW +/** \brief Type of FPU register, depends on the FLEN defined in RISC-V */ +typedef uint32_t rv_fpu_t; +#elif __FPU_PRESENT == 2 +#define __RV_FLOAD __RV_FLD +#define __RV_FSTORE __RV_FSD +/** \brief Type of FPU register, depends on the FLEN defined in RISC-V */ +typedef uint64_t rv_fpu_t; +#endif /* __FPU_PRESENT == 2 */ + +/** + * \brief Save FPU context into variables for interrupt nesting + * \details + * This macro is used to declare variables which are used for saving + * FPU context, and it will store the nessary fpu registers into + * these variables, it need to be used in a interrupt when in this + * interrupt fpu registers are used. + * \remarks + * - It need to be used together with \ref RESTORE_FPU_CONTEXT + * - Don't use variable names __fpu_context in your ISR code + * - If you isr code will use fpu registers, and this interrupt is nested. + * Then you can do it like this: + * \code + * void eclic_mtip_handler(void) + * { + * // !!!Interrupt is enabled here!!! + * // !!!Higher priority interrupt could nest it!!! + * + * // Necessary only when you need to use fpu registers + * // in this isr handler functions + * SAVE_FPU_CONTEXT(); + * + * // put you own interrupt handling code here + * + * // pair of SAVE_FPU_CONTEXT() + * RESTORE_FPU_CONTEXT(); + * } + * \endcode + */ +#define SAVE_FPU_CONTEXT() \ + rv_fpu_t __fpu_context[20]; \ + __RV_FSTORE(FREG(0), __fpu_context, 0 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(1), __fpu_context, 1 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(2), __fpu_context, 2 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(3), __fpu_context, 3 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(4), __fpu_context, 4 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(5), __fpu_context, 5 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(6), __fpu_context, 6 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(7), __fpu_context, 7 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(10), __fpu_context, 8 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(11), __fpu_context, 9 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(12), __fpu_context, 10 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(13), __fpu_context, 11 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(14), __fpu_context, 12 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(15), __fpu_context, 13 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(16), __fpu_context, 14 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(17), __fpu_context, 15 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(28), __fpu_context, 16 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(29), __fpu_context, 17 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(30), __fpu_context, 18 << LOG_FPREGBYTES); \ + __RV_FSTORE(FREG(31), __fpu_context, 19 << LOG_FPREGBYTES); + +/** + * \brief Restore necessary fpu registers from variables for interrupt nesting + * \details + * This macro is used restore necessary fpu registers from pre-defined variables + * in \ref SAVE_FPU_CONTEXT macro. + * \remarks + * - It need to be used together with \ref SAVE_FPU_CONTEXT + */ +#define RESTORE_FPU_CONTEXT() \ + __RV_FLOAD(FREG(0), __fpu_context, 0 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(1), __fpu_context, 1 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(2), __fpu_context, 2 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(3), __fpu_context, 3 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(4), __fpu_context, 4 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(5), __fpu_context, 5 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(6), __fpu_context, 6 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(7), __fpu_context, 7 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(10), __fpu_context, 8 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(11), __fpu_context, 9 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(12), __fpu_context, 10 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(13), __fpu_context, 11 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(14), __fpu_context, 12 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(15), __fpu_context, 13 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(16), __fpu_context, 14 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(17), __fpu_context, 15 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(28), __fpu_context, 16 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(29), __fpu_context, 17 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(30), __fpu_context, 18 << LOG_FPREGBYTES); \ + __RV_FLOAD(FREG(31), __fpu_context, 19 << LOG_FPREGBYTES); +#else +#define SAVE_FPU_CONTEXT() +#define RESTORE_FPU_CONTEXT() +#endif /* __FPU_PRESENT > 0 */ +/** @} */ /* End of Doxygen Group NMSIS_Core_FPU_Functions */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_FPU_H__ */ \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_plic.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_plic.h new file mode 100644 index 0000000..64c5f14 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_plic.h @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_PLIC__ +#define __CORE_FEATURE_PLIC__ +/*! + * @file core_feature_plic.h + * @brief PLIC feature API header file for RISC-V Core + */ +/* + * PLIC Feature Configuration Macro: + * 1. __PLIC_PRESENT: Define whether Platform Level Interrupt Controller (PLIC) Unit is present or not + * * 0: Not present + * * 1: Present + * 2. __PLIC_BASEADDR: Base address of the PLIC unit. + * 3. __PLIC_INTNUM : Define the external interrupt number of PLIC Unit + * + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1) +/** + * \defgroup NMSIS_Core_PLIC_Registers Register Define and Type Definitions Of PLIC + * \ingroup NMSIS_Core_Registers + * \brief Type definitions and defines for plic registers. + * + * @{ + */ + +/* 32 bits per source */ +#define PLIC_PRIORITY_OFFSET _AC(0x0000,UL) /*!< PLIC Priority register offset */ +#define PLIC_PRIORITY_SHIFT_PER_SOURCE 2 /*!< PLIC Priority register offset shift per source */ +/* 1 bit per source (1 address) */ +#define PLIC_PENDING_OFFSET _AC(0x1000,UL) /*!< PLIC Pending register offset */ +#define PLIC_PENDING_SHIFT_PER_SOURCE 0 /*!< PLIC Pending register offset shift per source */ + +/* 0x80 per context */ +#define PLIC_ENABLE_OFFSET _AC(0x2000,UL) /*!< PLIC Enable register offset */ +#define PLIC_ENABLE_SHIFT_PER_CONTEXT 7 /*!< PLIC Enable register offset shift per context */ + +#define PLIC_THRESHOLD_OFFSET _AC(0x200000,UL) /*!< PLIC Threshold register offset */ +#define PLIC_CLAIM_OFFSET _AC(0x200004,UL) /*!< PLIC Claim register offset */ +#define PLIC_THRESHOLD_SHIFT_PER_CONTEXT 12 /*!< PLIC Threshold register offset shift per context */ +#define PLIC_CLAIM_SHIFT_PER_CONTEXT 12 /*!< PLIC Claim register offset shift per context */ + +#ifndef __PLIC_BASEADDR +/* Base address of PLIC(__PLIC_BASEADDR) should be defined in */ +#error "__PLIC_BASEADDR is not defined, please check!" +#endif + +/* PLIC Memory mapping of Device */ +#define PLIC_BASE __PLIC_BASEADDR /*!< PLIC Base Address */ + +/** + * PLIC_GetHartID() is used to get plic hartid which might not be the same as cpu hart id, + * for example, cpu hartid may be 1, but plic hartid may be 0, then plic hartid offset is 1. + * If defined __PLIC_HARTID, it will use __PLIC_HARTID as plic hartid, + * otherwise, it will use __get_hart_index(). + * The cpu hartid is get by using __get_hart_id function + */ +#ifndef __PLIC_HARTID +#define PLIC_GetHartID() (__get_hart_index()) +#else +#define PLIC_GetHartID() (__PLIC_HARTID) +#endif + +#define PLIC_GetHartMContextID() (PLIC_GetHartID() << 1) +// TODO SMODE HARTID need to handle, maybe use a predefined variable of hartid +#define PLIC_GetHartSContextID() ((PLIC_GetHartID() << 1) + 1) + +#define PLIC_PRIORITY_REGADDR(source) ((PLIC_BASE) + (PLIC_PRIORITY_OFFSET) + ((source) << PLIC_PRIORITY_SHIFT_PER_SOURCE)) +#define PLIC_PENDING_REGADDR(source) ((PLIC_BASE) + (PLIC_PENDING_OFFSET) + (((source) >> 5) * 4)) +#define PLIC_ENABLE_REGADDR(ctxid, source) ((PLIC_BASE) + (PLIC_ENABLE_OFFSET) + ((ctxid) << PLIC_ENABLE_SHIFT_PER_CONTEXT) + ((source) >> 5) * 4) +#define PLIC_THRESHOLD_REGADDR(ctxid) ((PLIC_BASE) + (PLIC_THRESHOLD_OFFSET) + ((ctxid) << PLIC_THRESHOLD_SHIFT_PER_CONTEXT)) +#define PLIC_CLAIM_REGADDR(ctxid) ((PLIC_BASE) + (PLIC_CLAIM_OFFSET) + ((ctxid) << PLIC_CLAIM_SHIFT_PER_CONTEXT)) +#define PLIC_COMPLETE_REGADDR(ctxid) (PLIC_CLAIM_REGADDR(ctxid)) + + +/** @} */ /* end of group NMSIS_Core_PLIC_Registers */ + +/* ########################## PLIC functions #################################### */ +/** + * \defgroup NMSIS_Core_IntPlic PLIC Interrupt + * \brief Functions that manage interrupts via the PLIC. + * + * @{ + */ + +/** + * \brief Set priority threshold value of plic for selected context + * \details + * This function set priority threshold value of plic for selected context. + * \param [in] ctxid selected context id + * \param [in] thresh threshold value + * \remarks + * \sa + * - \ref PLIC_GetContextThreshold + */ +__STATIC_FORCEINLINE void PLIC_SetContextThreshold(uint32_t ctxid, uint32_t thresh) +{ + volatile uint32_t *thresh_reg = (uint32_t *)PLIC_THRESHOLD_REGADDR(ctxid); + + *thresh_reg = thresh; +} + +/** + * \brief Get priority threshold value of plic for selected context + * \details + * This function get priority threshold value of plic for selected context. + * \param [in] ctxid selected context id + * \return priority threshold value for selected context + * \remarks + * \sa + * - \ref PLIC_SetContextThreshold + */ +__STATIC_FORCEINLINE uint32_t PLIC_GetContextThreshold(uint32_t ctxid) +{ + volatile uint32_t *thresh_reg = (uint32_t *)PLIC_THRESHOLD_REGADDR(ctxid); + + return (*thresh_reg); +} + +/** + * \brief Enable interrupt of selected source plic for selected context + * \details + * This function enable interrupt of selected source plic for selected context. + * \param [in] ctxid selected context id + * \param [in] source interrupt source + * \remarks + * \sa + * - \ref PLIC_DisableContextInterrupt + */ +__STATIC_FORCEINLINE void PLIC_EnableContextInterrupt(uint32_t ctxid, uint32_t source) +{ + volatile uint32_t *enable_reg = (uint32_t *)PLIC_ENABLE_REGADDR(ctxid, source); + + uint32_t current = *enable_reg; + current = current | (1 << (source & 0x1F)); + *enable_reg = current; +} + +/** + * \brief Disable interrupt of selected source plic for selected context + * \details + * This function disable interrupt of selected source plic for selected context + * \param [in] ctxid selected context id + * \param [in] source interrupt source + * \remarks + * \sa + * - \ref PLIC_EnableContextInterrupt + */ +__STATIC_FORCEINLINE void PLIC_DisableContextInterrupt(uint32_t ctxid, uint32_t source) +{ + volatile uint32_t *enable_reg = (uint32_t *)PLIC_ENABLE_REGADDR(ctxid, source); + + uint32_t current = *enable_reg; + current = current & (~(1 << (source & 0x1F))); + *enable_reg = current; +} + +/** + * \brief Get interrupt enable status of selected source plic for selected context + * \details + * This function get interrupt enable of selected source plic for selected context. + * \param [in] ctxid selected context id + * \param [in] source interrupt source + * \return enable status for selected interrupt source for selected context + * \remarks + * \sa + * - \ref PLIC_EnableContextInterrupt + * - \ref PLIC_DisableContextInterrupt + */ +__STATIC_FORCEINLINE uint32_t PLIC_GetContextInterruptEnable(uint32_t ctxid, uint32_t source) +{ + volatile uint32_t *enable_reg = (uint32_t *)PLIC_ENABLE_REGADDR(ctxid, source); + + uint32_t current = *enable_reg; + current = (current >> (source & 0x1F)) & 0x1; + return current; +} + +/** + * \brief Set interrupt pending of selected source plic + * \details + * This function set interrupt pending of selected source plic. + * \param [in] source interrupt source + * \remarks + * \sa + * - \ref PLIC_GetInterruptPending + * - \ref PLIC_CLearInterruptPending + */ +__STATIC_FORCEINLINE void PLIC_SetInterruptPending(uint32_t source) +{ + volatile uint32_t *pending_reg = (uint32_t *)PLIC_PENDING_REGADDR(source); + + uint32_t current = *pending_reg; + current = current | (1 << (source & 0x1F)); + *pending_reg = current; +} + +/** + * \brief Clear interrupt pending of selected source plic + * \details + * This function clear interrupt pending of selected source plic + * \param [in] source interrupt source + * \remarks + * \sa + * - \ref PLIC_SetInterruptPending + * - \ref PLIC_GetInterruptPending + */ +__STATIC_FORCEINLINE void PLIC_ClearInterruptPending(uint32_t source) +{ + volatile uint32_t *pending_reg = (uint32_t *)PLIC_PENDING_REGADDR(source); + + uint32_t current = *pending_reg; + current = current & (~(1 << (source & 0x1F))); + *pending_reg = current; +} + +/** + * \brief Get interrupt pending status of selected source plic + * \details + * This function get interrupt pending of selected source plic + * \param [in] source interrupt source + * \return interrupt pending status for selected interrupt source + * \remarks + * \sa + * - \ref PLIC_SetInterruptPending + * - \ref PLIC_ClearInterruptPending + */ +__STATIC_FORCEINLINE uint32_t PLIC_GetInterruptPending(uint32_t source) +{ + volatile uint32_t *pending_reg = (uint32_t *)PLIC_PENDING_REGADDR(source); + + uint32_t current = *pending_reg; + current = (current >> (source & 0x1F)) & 0x1; + return current; +} + +/** + * \brief Set interrupt priority for selected source plic + * \details + * This function set interrupt priority for selected source plic. + * \param [in] source interrupt source + * \param [in] priority interrupt priority + * \remarks + * \sa + * - \ref PLIC_GetPriority + */ +__STATIC_FORCEINLINE void PLIC_SetPriority(uint32_t source, uint32_t priority) +{ + volatile uint32_t *priority_reg = (uint32_t *)PLIC_PRIORITY_REGADDR(source); + + *priority_reg = priority; +} + +/** + * \brief Get interrupt priority for selected source plic + * \details + * This function get interrupt priority for selected source plic. + * \param [in] source interrupt source + * \param [in] priority interrupt priority + * \remarks + * \sa + * - \ref PLIC_SetPriority + */ +__STATIC_FORCEINLINE uint32_t PLIC_GetPriority(uint32_t source) +{ + volatile uint32_t *priority_reg = (uint32_t *)PLIC_PRIORITY_REGADDR(source); + + return (*priority_reg); +} + +/** + * \brief Claim interrupt for plic for selected context + * \details + * This function claim interrupt for plic for selected context. + * \param [in] ctxid selected context id + * \return the ID of the highest priority pending interrupt or + * zero if there is no pending interrupt + * \remarks + * A successful claim will also atomically clear the corresponding pending bit + * on the interrupt source. The PLIC can perform a claim at any time and the + * claim operation is not affected by the setting of the priority threshold register. + * \sa + * - \ref PLIC_CompleteContextInterrupt + */ +__STATIC_FORCEINLINE uint32_t PLIC_ClaimContextInterrupt(uint32_t ctxid) +{ + volatile uint32_t *claim_reg = (uint32_t *)PLIC_CLAIM_REGADDR(ctxid); + + return (*claim_reg); +} + +/** + * \brief Complete interrupt for plic for selected context + * \details + * This function complete interrupt for plic for selected context. + * \param [in] ctxid selected context id + * \return the ID of the highest priority pending interrupt or + * zero if there is no pending interrupt + * \remarks + * The PLIC signals it has completed executing an interrupt handler by writing + * the interrupt ID it received from the claim to the claim/complete register. + * The PLIC does not check whether the completion ID is the same as the last + * claim ID for that context. + * If the completion ID does not match an interrupt source that is currently + * enabled for the context, the completion is silently ignored. + * \sa + * - \ref PLIC_ClaimContextInterrupt + */ +__STATIC_FORCEINLINE void PLIC_CompleteContextInterrupt(uint32_t ctxid, uint32_t source) +{ + volatile uint32_t *complete_reg = (uint32_t *)PLIC_COMPLETE_REGADDR(ctxid); + + *complete_reg = source; +} + +/** + * \brief Perform init for plic for selected context + * \details + * This function perform initialization steps for plic for selected context. + * \param [in] ctxid selected context id + * \param [in] num_sources plic interrupt source count number + * \param [in] enable plic interrupt enable or not + * \param [in] thresh plic interrupt threshold + * \remarks + * * Disable all interrupts + * * Set priority threshold to value specified by thresh + */ +__STATIC_FORCEINLINE void PLIC_Context_Init(uint32_t ctxid, uint32_t num_sources, uint32_t enable, uint32_t thresh) +{ + uint32_t i; + + for (i = 0; i < num_sources; i ++) { + if (enable) { + PLIC_EnableContextInterrupt(ctxid, i); + } else { + PLIC_DisableContextInterrupt(ctxid, i); + } + } + PLIC_SetContextThreshold(ctxid, thresh); +} + +#define PLIC_Init(num_sources, enable, thresh) PLIC_Context_Init(PLIC_GetHartMContextID(), (num_sources), (enable), (thresh)) +#define PLIC_Init_S(num_sources, enable, thresh) PLIC_Context_Init(PLIC_GetHartSContextID(), (num_sources), (enable), (thresh)) + +#define PLIC_ClaimInterrupt() PLIC_ClaimContextInterrupt(PLIC_GetHartMContextID()) +#define PLIC_ClaimInterrupt_S() PLIC_ClaimContextInterrupt(PLIC_GetHartSContextID()) + +#define PLIC_CompleteInterrupt(source) PLIC_CompleteContextInterrupt(PLIC_GetHartMContextID(), (source)) +#define PLIC_CompleteInterrupt_S(source) PLIC_CompleteContextInterrupt(PLIC_GetHartSContextID(), (source)) + +#define PLIC_GetInterruptEnable(source) PLIC_GetContextInterruptEnable(PLIC_GetHartMContextID(), (source)) +#define PLIC_GetInterruptEnable_S(source) PLIC_GetContextInterruptEnable(PLIC_GetHartSContextID(), (source)) + +#define PLIC_EnableInterrupt(source) PLIC_EnableContextInterrupt(PLIC_GetHartMContextID(), (source)) +#define PLIC_EnableInterrupt_S(source) PLIC_EnableContextInterrupt(PLIC_GetHartSContextID(), (source)) + +#define PLIC_DisableInterrupt(source) PLIC_DisableContextInterrupt(PLIC_GetHartMContextID(), (source)) +#define PLIC_DisableInterrupt_S(source) PLIC_DisableContextInterrupt(PLIC_GetHartSContextID(), (source)) + +#define PLIC_SetThreshold(source, thresh) PLIC_SetContextThreshold(PLIC_GetHartMContextID(), (source), (thresh)) +#define PLIC_SetThreshold_S(source, thresh) PLIC_SetContextThreshold(PLIC_GetHartSContextID(), (source), (thresh)) + +#define PLIC_GetThreshold(source) PLIC_GetContextThreshold(PLIC_GetHartMContextID(), (source)) +#define PLIC_GetThreshold_S(source) PLIC_GetContextThreshold(PLIC_GetHartSContextID(), (source)) + +/** + * \brief Set Trap entry address + * \details + * This function set trap entry address to 'CSR_MTVEC'. + * \param [in] addr trap entry address + * \remarks + * - This function use to set trap entry address to 'CSR_MTVEC'. + * \sa + * - \ref __get_trap_entry + */ +__STATIC_FORCEINLINE void __set_trap_entry(rv_csr_t addr) +{ + addr &= (rv_csr_t)(~0x7); + __RV_CSR_WRITE(CSR_MTVEC, addr); +} + +/** + * \brief Get trap entry address + * \details + * This function get trap entry address from 'CSR_MTVEC'. + * \return trap entry address + * \remarks + * - This function use to get trap entry address from 'CSR_MTVEC'. + * \sa + * - \ref __set_trap_entry + */ +__STATIC_FORCEINLINE rv_csr_t __get_trap_entry(void) +{ + unsigned long addr = __RV_CSR_READ(CSR_MTVEC); + return (addr); +} + +/** @} */ /* End of Doxygen Group NMSIS_Core_IntExc */ + +#endif /* defined(__PLIC_PRESENT) && (__PLIC_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /** __CORE_FEATURE_PLIC__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_pmp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_pmp.h new file mode 100644 index 0000000..9fd7ec7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_pmp.h @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_PMP_H__ +#define __CORE_FEATURE_PMP_H__ +/*! + * @file core_feature_pmp.h + * @brief PMP feature API header file for Nuclei N/NX Core + */ +/* + * PMP Feature Configuration Macro: + * 1. __PMP_PRESENT: Define whether Physical Memory Protection(PMP) is present or not + * * 0: Not present + * * 1: Present + * 2. __PMP_ENTRY_NUM: Define the number of PMP entries, only 8 or 16 is configurable. + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "core_feature_base.h" +#include "core_compatiable.h" + +#if defined(__PMP_PRESENT) && (__PMP_PRESENT == 1) +/* ===== PMP Operations ===== */ +/** + * \defgroup NMSIS_Core_PMP_Functions PMP Functions + * \ingroup NMSIS_Core + * \brief Functions that related to the RISCV Phyiscal Memory Protection. + * \details + * Optional physical memory protection (PMP) unit provides per-hart machine-mode + * control registers to allow physical memory access privileges (read, write, execute) + * to be specified for each physical memory region. + * + * The PMP can supports region access control settings as small as four bytes. + * + * @{ + */ +#ifndef __PMP_ENTRY_NUM +/* numbers of PMP entries(__PMP_ENTRY_NUM) should be defined in */ +#error "__PMP_ENTRY_NUM is not defined, please check!" +#endif + +typedef struct PMP_CONFIG { + /** + * set locking bit, addressing mode, read, write, and instruction execution permissions, + * see \ref PMP_L, \ref PMP_R, \ref PMP_W, \ref PMP_X, .etc in + */ + unsigned int protection; + /** + * Size of memory region as power of 2, it has to be minimum 2 and maxium \ref __RISCV_XLEN according to the + * hard-wired granularity 2^N bytes, if N = 12, then order has to be at least 12; if not, the order read out + * is N though you configure less than N. + */ + unsigned long order; + /** + * Base address of memory region + * It must be 2^order aligned address + */ + unsigned long base_addr; +} pmp_config; + +/** + * \brief Get PMPCFGx Register by csr index + * \details Return the content of the PMPCFGx Register. + * \param [in] csr_idx PMPCFG CSR index(0-3) + * \return PMPCFGx Register value + * \remark + * - For RV64, only csr_idx = 0 and csr_idx = 2 is allowed. + * pmpcfg0 and pmpcfg2 hold the configurations + * for the 16 PMP entries, pmpcfg1 and pmpcfg3 are illegal + * - For RV32, pmpcfg0–pmpcfg3, hold the configurations + * pmp0cfg–pmp15cfg for the 16 PMP entries + */ +__STATIC_INLINE rv_csr_t __get_PMPCFGx(uint32_t csr_idx) +{ + switch (csr_idx) { + case 0: return __RV_CSR_READ(CSR_PMPCFG0); + case 1: return __RV_CSR_READ(CSR_PMPCFG1); + case 2: return __RV_CSR_READ(CSR_PMPCFG2); + case 3: return __RV_CSR_READ(CSR_PMPCFG3); + default: return 0; + } +} + +/** + * \brief Set PMPCFGx by csr index + * \details Write the given value to the PMPCFGx Register. + * \param [in] csr_idx PMPCFG CSR index(0-3) + * \param [in] pmpcfg PMPCFGx Register value to set + * \remark + * - For RV64, only csr_idx = 0 and csr_idx = 2 is allowed. + * pmpcfg0 and pmpcfg2 hold the configurations + * for the 16 PMP entries, pmpcfg1 and pmpcfg3 are illegal + * - For RV32, pmpcfg0–pmpcfg3, hold the configurations + * pmp0cfg–pmp15cfg for the 16 PMP entries + */ +__STATIC_INLINE void __set_PMPCFGx(uint32_t csr_idx, rv_csr_t pmpcfg) +{ + switch (csr_idx) { + case 0: __RV_CSR_WRITE(CSR_PMPCFG0, pmpcfg); break; + case 1: __RV_CSR_WRITE(CSR_PMPCFG1, pmpcfg); break; + case 2: __RV_CSR_WRITE(CSR_PMPCFG2, pmpcfg); break; + case 3: __RV_CSR_WRITE(CSR_PMPCFG3, pmpcfg); break; + default: return; + } +} + +/** + * \brief Get 8bit PMPxCFG Register by PMP entry index + * \details Return the content of the PMPxCFG Register. + * \param [in] entry_idx PMP region index(0-15) + * \return PMPxCFG Register value + */ +__STATIC_INLINE uint8_t __get_PMPxCFG(uint32_t entry_idx) +{ + rv_csr_t pmpcfgx = 0; + uint8_t csr_cfg_num = 0; + uint16_t csr_idx = 0; + uint16_t cfg_shift = 0; + + if (entry_idx >= __PMP_ENTRY_NUM) return 0; + +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + /* For RV64, pmpcfg0 and pmpcfg2 each hold 8 PMP entries, align by 2 */ + csr_idx = (entry_idx >> 2) & ~1; +#else + // TODO Add RV128 Handling + return 0; +#endif + pmpcfgx = __get_PMPCFGx(csr_idx); + /* + * first get specific pmpxcfg's order in one CSR composed of csr_cfg_num pmpxcfgs, + * then get pmpxcfg's bit position in one CSR by left shift 3(each pmpxcfg size is one byte) + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + + /* read specific pmpxcfg register value */ + return (uint8_t)(__RV_EXTRACT_FIELD(pmpcfgx, 0xFF << cfg_shift)); +} + +/** + * \brief Set 8bit PMPxCFG by pmp entry index + * \details Set the given pmpxcfg value to the PMPxCFG Register. + * \param [in] entry_idx PMPx region index(0-15) + * \param [in] pmpxcfg PMPxCFG register value to set + * \remark + * - For RV32, 4 pmpxcfgs are densely packed into one CSR in order + * For RV64, 8 pmpxcfgs are densely packed into one CSR in order + */ +__STATIC_INLINE void __set_PMPxCFG(uint32_t entry_idx, uint8_t pmpxcfg) +{ + rv_csr_t pmpcfgx = 0; + uint8_t csr_cfg_num = 0; + uint16_t csr_idx = 0; + uint16_t cfg_shift = 0; + if (entry_idx >= __PMP_ENTRY_NUM) return; + +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + /* For RV64, pmpcfg0 and pmpcfg2 each hold 8 PMP entries, align by 2 */ + csr_idx = (entry_idx >> 2) & ~1; +#else + // TODO Add RV128 Handling + return; +#endif + /* read specific pmpcfgx register value */ + pmpcfgx = __get_PMPCFGx(csr_idx); + /* + * first get specific pmpxcfg's order in one CSR composed of csr_cfg_num pmpxcfgs, + * then get pmpxcfg's bit position in one CSR by left shift 3(each pmpxcfg size is one byte) + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + + pmpcfgx = __RV_INSERT_FIELD(pmpcfgx, 0xFFUL << cfg_shift, pmpxcfg); + __set_PMPCFGx(csr_idx, pmpcfgx); +} + +/** + * \brief Get PMPADDRx Register by CSR index + * \details Return the content of the PMPADDRx Register. + * \param [in] csr_idx PMP region CSR index(0-15) + * \return PMPADDRx Register value + */ +__STATIC_INLINE rv_csr_t __get_PMPADDRx(uint32_t csr_idx) +{ + switch (csr_idx) { + case 0: return __RV_CSR_READ(CSR_PMPADDR0); + case 1: return __RV_CSR_READ(CSR_PMPADDR1); + case 2: return __RV_CSR_READ(CSR_PMPADDR2); + case 3: return __RV_CSR_READ(CSR_PMPADDR3); + case 4: return __RV_CSR_READ(CSR_PMPADDR4); + case 5: return __RV_CSR_READ(CSR_PMPADDR5); + case 6: return __RV_CSR_READ(CSR_PMPADDR6); + case 7: return __RV_CSR_READ(CSR_PMPADDR7); + case 8: return __RV_CSR_READ(CSR_PMPADDR8); + case 9: return __RV_CSR_READ(CSR_PMPADDR9); + case 10: return __RV_CSR_READ(CSR_PMPADDR10); + case 11: return __RV_CSR_READ(CSR_PMPADDR11); + case 12: return __RV_CSR_READ(CSR_PMPADDR12); + case 13: return __RV_CSR_READ(CSR_PMPADDR13); + case 14: return __RV_CSR_READ(CSR_PMPADDR14); + case 15: return __RV_CSR_READ(CSR_PMPADDR15); + default: return 0; + } +} + +/** + * \brief Set PMPADDRx by CSR index + * \details Write the given value to the PMPADDRx Register. + * \param [in] csr_idx PMP region CSR index(0-15) + * \param [in] pmpaddr PMPADDRx Register value to set + */ +__STATIC_INLINE void __set_PMPADDRx(uint32_t csr_idx, rv_csr_t pmpaddr) +{ + switch (csr_idx) { + case 0: __RV_CSR_WRITE(CSR_PMPADDR0, pmpaddr); break; + case 1: __RV_CSR_WRITE(CSR_PMPADDR1, pmpaddr); break; + case 2: __RV_CSR_WRITE(CSR_PMPADDR2, pmpaddr); break; + case 3: __RV_CSR_WRITE(CSR_PMPADDR3, pmpaddr); break; + case 4: __RV_CSR_WRITE(CSR_PMPADDR4, pmpaddr); break; + case 5: __RV_CSR_WRITE(CSR_PMPADDR5, pmpaddr); break; + case 6: __RV_CSR_WRITE(CSR_PMPADDR6, pmpaddr); break; + case 7: __RV_CSR_WRITE(CSR_PMPADDR7, pmpaddr); break; + case 8: __RV_CSR_WRITE(CSR_PMPADDR8, pmpaddr); break; + case 9: __RV_CSR_WRITE(CSR_PMPADDR9, pmpaddr); break; + case 10: __RV_CSR_WRITE(CSR_PMPADDR10, pmpaddr); break; + case 11: __RV_CSR_WRITE(CSR_PMPADDR11, pmpaddr); break; + case 12: __RV_CSR_WRITE(CSR_PMPADDR12, pmpaddr); break; + case 13: __RV_CSR_WRITE(CSR_PMPADDR13, pmpaddr); break; + case 14: __RV_CSR_WRITE(CSR_PMPADDR14, pmpaddr); break; + case 15: __RV_CSR_WRITE(CSR_PMPADDR15, pmpaddr); break; + default: return; + } +} + +/** + * \brief Set PMP entry by entry idx + * \details Write the given value to the PMPxCFG Register and PMPADDRx. + * \param [in] entry_idx PMP entry index(0-15) + * \param [in] pmp_cfg structure of L, X, W, R field of PMP configuration register, memory region base address + * and size of memory region as power of 2 + * \remark + * - If the size of memory region is 2^12(4KB) range, pmp_cfg->order makes 12, and the like. + * - Suppose the size of memory region is 2^X bytes range, if X >=3, the NA4 mode is not selectable, NAPOT is selected. + * - TOR of A field in PMP configuration register is not considered here. + */ +__STATIC_INLINE void __set_PMPENTRYx(uint32_t entry_idx, const pmp_config *pmp_cfg) +{ + unsigned int cfg_shift, cfg_csr_idx, addr_csr_idx = 0; + unsigned long cfgmask, addrmask = 0; + unsigned long pmpcfg, pmpaddr = 0; + unsigned long protection, csr_cfg_num = 0; + /* check parameters */ + if (entry_idx >= __PMP_ENTRY_NUM || pmp_cfg->order > __RISCV_XLEN || pmp_cfg->order < PMP_SHIFT) return; + + /* calculate PMP register and offset */ +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + cfg_csr_idx = (entry_idx >> 2); +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + cfg_csr_idx = ((entry_idx >> 2)) & ~1; +#else + // TODO Add RV128 Handling + return; +#endif + /* + * first get specific pmpxcfg's order in one CSR composed of csr_cfg_num pmpxcfgs, + * then get pmpxcfg's bit position in one CSR by left shift 3, each pmpxcfg size is one byte + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + addr_csr_idx = entry_idx; + + /* encode PMP config */ + protection = (unsigned long)pmp_cfg->protection; + protection |= (PMP_SHIFT == pmp_cfg->order) ? PMP_A_NA4 : PMP_A_NAPOT; + cfgmask = ~(0xFFUL << cfg_shift); + pmpcfg = (__get_PMPCFGx(cfg_csr_idx) & cfgmask); + pmpcfg |= ((protection << cfg_shift) & ~cfgmask); + + /* encode PMP address */ + if (PMP_SHIFT == pmp_cfg->order) { /* NA4 */ + pmpaddr = (pmp_cfg->base_addr >> PMP_SHIFT); + } else { /* NAPOT */ + addrmask = (1UL << (pmp_cfg->order - PMP_SHIFT)) - 1; + pmpaddr = ((pmp_cfg->base_addr >> PMP_SHIFT) & ~addrmask); + pmpaddr |= (addrmask >> 1); + } + /* + * write csrs, update the address first, in case the entry is locked that + * we won't be able to modify it after we set the config csr. + */ + __set_PMPADDRx(addr_csr_idx, pmpaddr); + __set_PMPCFGx(cfg_csr_idx, pmpcfg); +} + +/** + * \brief Get PMP entry by entry idx + * \details Write the given value to the PMPxCFG Register and PMPADDRx. + * \param [in] entry_idx PMP entry index(0-15) + * \param [out] pmp_cfg structure of L, X, W, R, A field of PMP configuration register, memory region base + * address and size of memory region as power of 2 + * \return -1 failure, else 0 success + * \remark + * - If the size of memory region is 2^12(4KB) range, pmp_cfg->order makes 12, and the like. + * - TOR of A field in PMP configuration register is not considered here. + */ +__STATIC_INLINE int __get_PMPENTRYx(unsigned int entry_idx, pmp_config *pmp_cfg) +{ + unsigned int cfg_shift, cfg_csr_idx, addr_csr_idx = 0; + unsigned long cfgmask, pmpcfg, prot = 0; + unsigned long t1, addr, pmpaddr, len = 0; + uint8_t csr_cfg_num = 0; + /* check parameters */ + if (entry_idx >= __PMP_ENTRY_NUM || !pmp_cfg) return -1; + + /* calculate PMP register and offset */ +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + cfg_csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + cfg_csr_idx = (entry_idx>> 2) & ~1; +#else +// TODO Add RV128 Handling + return -1; +#endif + + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + addr_csr_idx = entry_idx; + + /* decode PMP config */ + cfgmask = (0xFFUL << cfg_shift); + pmpcfg = (__get_PMPCFGx(cfg_csr_idx) & cfgmask); + prot = pmpcfg >> cfg_shift; + + /* decode PMP address */ + pmpaddr = __get_PMPADDRx(addr_csr_idx); + if (PMP_A_NAPOT == (prot & PMP_A)) { + t1 = __CTZ(~pmpaddr); + addr = (pmpaddr & ~((1UL << t1) - 1)) << PMP_SHIFT; + len = (t1 + PMP_SHIFT + 1); + } else { + addr = pmpaddr << PMP_SHIFT; + len = PMP_SHIFT; + } + + /* return details */ + pmp_cfg->protection = prot; + pmp_cfg->base_addr = addr; + pmp_cfg->order = len; + + return 0; +} + +/** @} */ /* End of Doxygen Group NMSIS_Core_PMP_Functions */ +#endif /* defined(__PMP_PRESENT) && (__PMP_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_PMP_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_spmp.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_spmp.h new file mode 100644 index 0000000..a722e50 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_spmp.h @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_SPMP_H__ +#define __CORE_FEATURE_SPMP_H__ +/*! + * @file core_feature_spmp.h + * @brief sPMP(has upgraded to S-mode Memory Protection Unit, renamed as SMPU) feature API header file for Nuclei N/NX Core + */ +/* + * sPMP Feature Configuration Macro: + * 1. __SPMP_PRESENT: Define whether sPMP is present or not + * __SMPU_PRESENT: Define whether SMPU is present or not + * * 0: Not present + * * 1: Present + * 2. __SPMP_ENTRY_NUM: Define the number of sPMP entries, only 8 or 16 is configurable + * __SMPU_ENTRY_NUM: Define the number of SMPU entries, only 8 or 16 is configurable + * __SMPU_ENTRY_NUM is the same as __SPMP_ENTRY_NUM + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "core_feature_base.h" +#include "core_compatiable.h" + +#if defined(__SPMP_PRESENT) && (__SPMP_PRESENT == 1) + +/* ===== sPMP Operations ===== */ +/** + * \defgroup NMSIS_Core_SPMP_Functions sPMP Functions + * \ingroup NMSIS_Core + * \brief Functions that related to the RISCV supervisor-mode Phyiscal Memory Protection. + * \details + * Optional superviosr physical memory protection (sPMP) unit provides per-hart supervisor-mode + * control registers to allow physical memory access privileges (read, write, execute) + * to be specified for each physical memory region. The sPMP values are checked after the physical + * address to be accessed pass PMP checks described in the RISC-V privileged spec. + * + * Like PMP, the sPMP can supports region access control settings as small as four bytes. + * + * @{ + */ +#ifndef __SPMP_ENTRY_NUM +/* Number of __SPMP_ENTRY_NUM entries should be defined in */ +#error "__SPMP_ENTRY_NUM is not defined, please check!" +#endif + +typedef struct SPMP_CONFIG { + /** + * Set permissions using macros \ref SMPU_S/\ref SMPU_R/\ref SMPU_W/\ref SMPU_X of SMPU; + * \ref SPMP_L/\ref SPMP_U/\ref SPMP_R/\ref SPMP_W/\ref SPMP_X of sPMP, + * see details in riscv spec of SMPU/sPMP + */ + unsigned int protection; + /** + * Size of memory region as power of 2, it has to be minimum 2 and maxium \ref __RISCV_XLEN according to the + * hardwired granularity 2^N bytes, if N = 12, then order has to be at least 12; if not, the order read out + * is N though you configure less than N. + */ + unsigned long order; + /** + * Base address of memory region + * It must be 2^order aligned address + */ + unsigned long base_addr; +} spmp_config; + +/** + * \brief Get sPMPCFGx Register by csr index + * \details Return the content of the sPMPCFGx Register. + * \param [in] csr_idx sPMPCFG CSR index(0-3) + * \return sPMPCFGx Register value + * \remark + * - For RV64, only csr_idx = 0 and csr_idx = 2 is allowed. + * spmpcfg0 and spmpcfg2 hold the configurations + * for the 16 sPMP entries, spmpcfg1 and spmpcfg3 are illegal + * - For RV32, spmpcfg0–spmpcfg3, hold the configurations + * spmp0cfg–spmp15cfg for the 16 sPMP entries + */ +__STATIC_INLINE rv_csr_t __get_sPMPCFGx(uint32_t csr_idx) +{ + switch (csr_idx) { + case 0: return __RV_CSR_READ(CSR_SPMPCFG0); + case 1: return __RV_CSR_READ(CSR_SPMPCFG1); + case 2: return __RV_CSR_READ(CSR_SPMPCFG2); + case 3: return __RV_CSR_READ(CSR_SPMPCFG3); + default: return 0; + } +} + +/** + * \brief Set sPMPCFGx by csr index + * \details Write the given value to the sPMPCFGx Register. + * \param [in] csr_idx sPMPCFG CSR index(0-3) + * \param [in] spmpcfg sPMPCFGx Register value to set + * \remark + * - For RV64, only csr_idx = 0 and csr_idx = 2 is allowed. + * spmpcfg0 and spmpcfg2 hold the configurations + * for the 16 sPMP entries, spmpcfg1 and spmpcfg3 are illegal + * - For RV32, spmpcfg0–spmpcfg3, hold the configurations + * spmp0cfg–spmp15cfg for the 16 sPMP entries + */ +__STATIC_INLINE void __set_sPMPCFGx(uint32_t csr_idx, rv_csr_t spmpcfg) +{ + switch (csr_idx) { + case 0: __RV_CSR_WRITE(CSR_SPMPCFG0, spmpcfg); break; + case 1: __RV_CSR_WRITE(CSR_SPMPCFG1, spmpcfg); break; + case 2: __RV_CSR_WRITE(CSR_SPMPCFG2, spmpcfg); break; + case 3: __RV_CSR_WRITE(CSR_SPMPCFG3, spmpcfg); break; + default: return; + } +} + +/** + * \brief Get 8bit sPMPxCFG Register by sPMP entry index + * \details Return the content of the sPMPxCFG Register. + * \param [in] entry_idx sPMP region index(0-15) + * \return sPMPxCFG Register value + */ +__STATIC_INLINE uint8_t __get_sPMPxCFG(uint32_t entry_idx) +{ + rv_csr_t spmpcfgx = 0; + uint8_t csr_cfg_num = 0; + uint16_t csr_idx = 0; + uint16_t cfg_shift = 0; + + if (entry_idx >= __SPMP_ENTRY_NUM) return 0; + +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + /* For RV64, spmpcfg0 and spmpcfg2 each hold 8 sPMP entries, align by 2 */ + csr_idx = (entry_idx >> 2) & ~1; +#else + // TODO Add RV128 Handling + return 0; +#endif + spmpcfgx = __get_sPMPCFGx(csr_idx); + /* + * first get specific spmpxcfg's order in one CSR composed of csr_cfg_num spmpxcfgs, + * then get spmpxcfg's bit position in one CSR by left shift 3(each spmpxcfg size is one byte) + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + + /* read specific spmpxcfg register value */ + return (uint8_t)(__RV_EXTRACT_FIELD(spmpcfgx, 0xFF << cfg_shift)); +} + +/** + * \brief Set 8bit sPMPxCFG by spmp entry index + * \details Set the given spmpxcfg value to the sPMPxCFG Register. + * \param [in] entry_idx sPMPx region index(0-15) + * \param [in] spmpxcfg sPMPxCFG register value to set + * \remark + * - For RV32, 4 spmpxcfgs are densely packed into one CSR in order + * For RV64, 8 spmpxcfgs are densely packed into one CSR in order + */ +__STATIC_INLINE void __set_sPMPxCFG(uint32_t entry_idx, uint8_t spmpxcfg) +{ + rv_csr_t spmpcfgx = 0; + uint8_t csr_cfg_num = 0; + uint16_t csr_idx = 0; + uint16_t cfg_shift = 0; + if (entry_idx >= __SPMP_ENTRY_NUM) return; + +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + /* For RV64, spmpcfg0 and spmpcfg2 each hold 8 sPMP entries, align by 2 */ + csr_idx = (entry_idx >> 2) & ~1; +#else + // TODO Add RV128 Handling + return; +#endif + /* read specific spmpcfgx register value */ + spmpcfgx = __get_sPMPCFGx(csr_idx); + /* + * first get specific spmpxcfg's order in one CSR composed of csr_cfg_num spmpxcfgs, + * then get spmpxcfg's bit position in one CSR by left shift 3(each spmpxcfg size is one byte) + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + + spmpcfgx = __RV_INSERT_FIELD(spmpcfgx, 0xFFUL << cfg_shift, spmpxcfg); + __set_sPMPCFGx(csr_idx, spmpcfgx); +} + +/** + * \brief Get sPMPADDRx Register by CSR index + * \details Return the content of the sPMPADDRx Register. + * \param [in] csr_idx sPMP region CSR index(0-15) + * \return sPMPADDRx Register value + */ +__STATIC_INLINE rv_csr_t __get_sPMPADDRx(uint32_t csr_idx) +{ + switch (csr_idx) { + case 0: return __RV_CSR_READ(CSR_SPMPADDR0); + case 1: return __RV_CSR_READ(CSR_SPMPADDR1); + case 2: return __RV_CSR_READ(CSR_SPMPADDR2); + case 3: return __RV_CSR_READ(CSR_SPMPADDR3); + case 4: return __RV_CSR_READ(CSR_SPMPADDR4); + case 5: return __RV_CSR_READ(CSR_SPMPADDR5); + case 6: return __RV_CSR_READ(CSR_SPMPADDR6); + case 7: return __RV_CSR_READ(CSR_SPMPADDR7); + case 8: return __RV_CSR_READ(CSR_SPMPADDR8); + case 9: return __RV_CSR_READ(CSR_SPMPADDR9); + case 10: return __RV_CSR_READ(CSR_SPMPADDR10); + case 11: return __RV_CSR_READ(CSR_SPMPADDR11); + case 12: return __RV_CSR_READ(CSR_SPMPADDR12); + case 13: return __RV_CSR_READ(CSR_SPMPADDR13); + case 14: return __RV_CSR_READ(CSR_SPMPADDR14); + case 15: return __RV_CSR_READ(CSR_SPMPADDR15); + default: return 0; + } +} + +/** + * \brief Set sPMPADDRx by CSR index + * \details Write the given value to the sPMPADDRx Register. + * \param [in] csr_idx sPMP region CSR index(0-15) + * \param [in] spmpaddr sPMPADDRx Register value to set + */ +__STATIC_INLINE void __set_sPMPADDRx(uint32_t csr_idx, rv_csr_t spmpaddr) +{ + switch (csr_idx) { + case 0: __RV_CSR_WRITE(CSR_SPMPADDR0, spmpaddr); break; + case 1: __RV_CSR_WRITE(CSR_SPMPADDR1, spmpaddr); break; + case 2: __RV_CSR_WRITE(CSR_SPMPADDR2, spmpaddr); break; + case 3: __RV_CSR_WRITE(CSR_SPMPADDR3, spmpaddr); break; + case 4: __RV_CSR_WRITE(CSR_SPMPADDR4, spmpaddr); break; + case 5: __RV_CSR_WRITE(CSR_SPMPADDR5, spmpaddr); break; + case 6: __RV_CSR_WRITE(CSR_SPMPADDR6, spmpaddr); break; + case 7: __RV_CSR_WRITE(CSR_SPMPADDR7, spmpaddr); break; + case 8: __RV_CSR_WRITE(CSR_SPMPADDR8, spmpaddr); break; + case 9: __RV_CSR_WRITE(CSR_SPMPADDR9, spmpaddr); break; + case 10: __RV_CSR_WRITE(CSR_SPMPADDR10, spmpaddr); break; + case 11: __RV_CSR_WRITE(CSR_SPMPADDR11, spmpaddr); break; + case 12: __RV_CSR_WRITE(CSR_SPMPADDR12, spmpaddr); break; + case 13: __RV_CSR_WRITE(CSR_SPMPADDR13, spmpaddr); break; + case 14: __RV_CSR_WRITE(CSR_SPMPADDR14, spmpaddr); break; + case 15: __RV_CSR_WRITE(CSR_SPMPADDR15, spmpaddr); break; + default: return; + } +} + +/** + * \brief Set sPMP entry by entry idx + * \details Write the given value to the sPMPxCFG Register and sPMPADDRx. + * \param [in] entry_idx sPMP entry index(0-15) + * \param [in] spmp_cfg structure of L,U,X,W,R field of sPMP configuration register, memory region base address + * and size of memory region as power of 2 + * \remark + * - If the size of memory region is 2^12(4KB) range, spmp_cfg->order makes 12, and the like. + * - Suppose the size of memory region is 2^X bytes range, if X >=3, the NA4 mode is not selectable, NAPOT is selected. + * - TOR of A field in sPMP configuration register is not considered here. + */ +__STATIC_INLINE void __set_sPMPENTRYx(uint32_t entry_idx, const spmp_config *spmp_cfg) +{ + unsigned int cfg_shift, cfg_csr_idx, addr_csr_idx = 0; + unsigned long cfgmask, addrmask = 0; + unsigned long spmpcfg, spmpaddr = 0; + unsigned long protection, csr_cfg_num = 0; + /* check parameters */ + if (entry_idx >= __SPMP_ENTRY_NUM || spmp_cfg->order > __RISCV_XLEN || spmp_cfg->order < SPMP_SHIFT) return; + + /* calculate sPMP register and offset */ +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + cfg_csr_idx = (entry_idx >> 2); +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + cfg_csr_idx = ((entry_idx >> 2)) & ~1; +#else + // TODO Add RV128 Handling + return; +#endif + /* + * first get specific spmpxcfg's order in one CSR composed of csr_cfg_num spmpxcfgs, + * then get spmpxcfg's bit position in one CSR by left shift 3, each spmpxcfg size is one byte + */ + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + addr_csr_idx = entry_idx; + + /* encode sPMP config */ + protection = (unsigned long)spmp_cfg->protection; + protection |= (SPMP_SHIFT == spmp_cfg->order) ? SPMP_A_NA4 : SPMP_A_NAPOT; + cfgmask = ~(0xFFUL << cfg_shift); + spmpcfg = (__get_sPMPCFGx(cfg_csr_idx) & cfgmask); + spmpcfg |= ((protection << cfg_shift) & ~cfgmask); + + /* encode sPMP address */ + if (SPMP_SHIFT == spmp_cfg->order) { /* NA4 */ + spmpaddr = (spmp_cfg->base_addr >> SPMP_SHIFT); + } else { /* NAPOT */ + addrmask = (1UL << (spmp_cfg->order - SPMP_SHIFT)) - 1; + spmpaddr = ((spmp_cfg->base_addr >> SPMP_SHIFT) & ~addrmask); + spmpaddr |= (addrmask >> 1); + } + /* + * write csrs, update the address first, in case the entry is locked that + * we won't be able to modify it after we set the config csr. + */ + __set_sPMPADDRx(addr_csr_idx, spmpaddr); + __set_sPMPCFGx(cfg_csr_idx, spmpcfg); +} + +/** + * \brief Get sPMP entry by entry idx + * \details Write the given value to the sPMPxCFG Register and sPMPADDRx. + * \param [in] entry_idx sPMP entry index(0-15) + * \param [out] spmp_cfg structure of L, U, X, W, R, A field of sPMP configuration register, memory region base + * address and size of memory region as power of 2 + * \return -1 failure, else 0 success + * \remark + * - If the size of memory region is 2^12(4KB) range, spmp_cfg->order makes 12, and the like. + * - TOR of A field in PMP configuration register is not considered here. + */ +__STATIC_INLINE int __get_sPMPENTRYx(unsigned int entry_idx, spmp_config *spmp_cfg) +{ + unsigned int cfg_shift, cfg_csr_idx, addr_csr_idx = 0; + unsigned long cfgmask, spmpcfg, prot = 0; + unsigned long t1, addr, spmpaddr, len = 0; + uint8_t csr_cfg_num = 0; + /* check parameters */ + if (entry_idx >= __SPMP_ENTRY_NUM || !spmp_cfg) return -1; + + /* calculate sPMP register and offset */ +#if __RISCV_XLEN == 32 + csr_cfg_num = 4; + cfg_csr_idx = entry_idx >> 2; +#elif __RISCV_XLEN == 64 + csr_cfg_num = 8; + cfg_csr_idx = (entry_idx >> 2) & ~1; +#else +// TODO Add RV128 Handling + return -1; +#endif + + cfg_shift = (entry_idx & (csr_cfg_num - 1)) << 3; + addr_csr_idx = entry_idx; + + /* decode sPMP config */ + cfgmask = (0xFFUL << cfg_shift); + spmpcfg = (__get_sPMPCFGx(cfg_csr_idx) & cfgmask); + prot = spmpcfg >> cfg_shift; + + /* decode sPMP address */ + spmpaddr = __get_sPMPADDRx(addr_csr_idx); + if (SPMP_A_NAPOT == (prot & SPMP_A)) { + t1 = __CTZ(~spmpaddr); + addr = (spmpaddr & ~((1UL << t1) - 1)) << SPMP_SHIFT; + len = (t1 + SPMP_SHIFT + 1); + } else { + addr = spmpaddr << SPMP_SHIFT; + len = SPMP_SHIFT; + } + + /* return details */ + spmp_cfg->protection = prot; + spmp_cfg->base_addr = addr; + spmp_cfg->order = len; + + return 0; +} + +#if defined(__SMPU_PRESENT) && (__SMPU_PRESENT == 1) +/** + * sPMP has upgraded to S-mode Memory Protection Unit, renamed as SMPU, but still share the apis with sPMP's + */ +typedef spmp_config smpu_config; +#define __get_SMPUCFGx __get_sPMPCFGx +#define __set_SMPUCFGx __set_sPMPCFGx +#define __get_SMPUxCFG __get_sPMPxCFG +#define __set_SMPUxCFG __set_sPMPxCFG +#define __get_SMPUADDRx __get_sPMPADDRx +#define __set_SMPUADDRx __set_sPMPADDRx +#define __set_SMPUENTRYx __set_sPMPENTRYx +#define __get_SMPUENTRYx __get_sPMPENTRYx + +/** + * \brief Set SMPU each entry's on/off status + * \details Write the given value to the SMPUSWITCHx Register. + * \param [in] val activate each entry(max to 64) or not + * \remark + * - Each bit of this register holds on/off status of the corresponding SMPU entry respectively. + * - An SMPU entry is activated only when both corresponding bits in smpuswitch and + * A field of smpuicfg are set. (i.e., smpuswitch[i] & smpu[i]cfg.A). + */ +__STATIC_INLINE void __set_SMPUSWITCHx(uint64_t val) +{ +#if __RISCV_XLEN == 32 + __RV_CSR_WRITE(CSR_SMPUSWITCH0, (uint32_t)val); + __RV_CSR_WRITE(CSR_SMPUSWITCH1, (uint32_t)(val >> 32)); +#elif __RISCV_XLEN == 64 + __RV_CSR_WRITE(CSR_SMPUSWITCH0, val); +#else + // TODO Add RV128 Handling +#endif +} + +/** + * \brief Get SMPU each entry's on/off status + * \details Get the value of the SMPUSWITCHx Register. + * \remark + * - Each bit of this register holds on/off status of the corresponding SMPU entry respectively. + * - An SMPU entry is activated only when both corresponding bits in smpuswitch and + * A field of smpuicfg are set. (i.e., smpuswitch[i] & smpu[i]cfg.A). + */ +__STATIC_INLINE uint64_t __get_SMPUSWITCHx(void) +{ +#if __RISCV_XLEN == 32 + uint32_t lo, hi = 0; + lo = __RV_CSR_READ(CSR_SMPUSWITCH0); + hi = __RV_CSR_READ(CSR_SMPUSWITCH1); + return (uint64_t)((((uint64_t)hi) << 32) | lo); +#elif __RISCV_XLEN == 64 + return (uint64_t)__RV_CSR_READ(CSR_SMPUSWITCH0); +#else + // TODO Add RV128 Handling +#endif +} + +#endif + +/** @} */ /* End of Doxygen Group NMSIS_Core_SPMP_Functions */ +#endif /* defined(__SPMP_PRESENT) && (__SPMP_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_SPMP_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_timer.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_timer.h new file mode 100644 index 0000000..f1b03f7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_timer.h @@ -0,0 +1,683 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_TIMER_H__ +#define __CORE_FEATURE_TIMER_H__ +/*! + * @file core_feature_timer.h + * @brief System Timer feature API header file for Nuclei N/NX Core + */ +/* + * System Timer Feature Configuration Macro: + * 1. __SYSTIMER_PRESENT: Must, Define whether Private System Timer is present or not. + * * 0: Not present + * * 1: Present + * 2. __SYSTIMER_BASEADDR: Must, Define the base address of the System Timer. + * 3. __SYSTIMER_HARTID: Optional, Define the system timer hart index of the cpu, important for case when cpu hartid and cpu hart index are different, only set it if your cpu is single core. + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1) +/** + * \defgroup NMSIS_Core_SysTimer_Registers Register Define and Type Definitions Of System Timer + * \ingroup NMSIS_Core_Registers + * \brief Type definitions and defines for system timer registers. + * + * @{ + */ +/** + * \brief Structure type to access the System Timer (SysTimer). + * \details + * Structure definition to access the system timer(SysTimer). + * \remarks + * - MSFTRST register is introduced in Nuclei N Core version 1.3(\ref __NUCLEI_N_REV >= 0x0103) + * - MSTOP register is renamed to MTIMECTL register in Nuclei N Core version 1.4(\ref __NUCLEI_N_REV >= 0x0104) + * - CMPCLREN and CLKSRC bit in MTIMECTL register is introduced in Nuclei N Core version 1.4(\ref __NUCLEI_N_REV >= 0x0104) + */ +typedef struct { + __IOM uint64_t MTIMER; /*!< Offset: 0x000 (R/W) System Timer current value 64bits Register */ + __IOM uint64_t MTIMERCMP; /*!< Offset: 0x008 (R/W) System Timer compare Value 64bits Register */ + __IOM uint32_t RESERVED0[0x3F8]; /*!< Offset: 0x010 - 0xFEC Reserved */ + __IOM uint32_t MSFTRST; /*!< Offset: 0xFF0 (R/W) System Timer Software Core Reset Register */ + __IOM uint32_t RESERVED1; /*!< Offset: 0xFF4 Reserved */ + __IOM uint32_t MTIMECTL; /*!< Offset: 0xFF8 (R/W) System Timer Control Register, previously MSTOP register */ + __IOM uint32_t MSIP; /*!< Offset: 0xFFC (R/W) System Timer SW interrupt Register */ +} SysTimer_Type; + +/* Timer Control / Status Register Definitions */ +#define SysTimer_MTIMECTL_TIMESTOP_Pos 0U /*!< SysTick Timer MTIMECTL: TIMESTOP bit Position */ +#define SysTimer_MTIMECTL_TIMESTOP_Msk (1UL << SysTimer_MTIMECTL_TIMESTOP_Pos) /*!< SysTick Timer MTIMECTL: TIMESTOP Mask */ +#define SysTimer_MTIMECTL_CMPCLREN_Pos 1U /*!< SysTick Timer MTIMECTL: CMPCLREN bit Position */ +#define SysTimer_MTIMECTL_CMPCLREN_Msk (1UL << SysTimer_MTIMECTL_CMPCLREN_Pos) /*!< SysTick Timer MTIMECTL: CMPCLREN Mask */ +#define SysTimer_MTIMECTL_CLKSRC_Pos 2U /*!< SysTick Timer MTIMECTL: CLKSRC bit Position */ +#define SysTimer_MTIMECTL_CLKSRC_Msk (1UL << SysTimer_MTIMECTL_CLKSRC_Pos) /*!< SysTick Timer MTIMECTL: CLKSRC Mask */ + +#define SysTimer_MSIP_MSIP_Pos 0U /*!< SysTick Timer MSIP: MSIP bit Position */ +#define SysTimer_MSIP_MSIP_Msk (1UL << SysTimer_MSIP_MSIP_Pos) /*!< SysTick Timer MSIP: MSIP Mask */ + +#define SysTimer_MTIMER_Msk (0xFFFFFFFFFFFFFFFFULL) /*!< SysTick Timer MTIMER value Mask */ +#define SysTimer_MTIMERCMP_Msk (0xFFFFFFFFFFFFFFFFULL) /*!< SysTick Timer MTIMERCMP value Mask */ +#define SysTimer_MTIMECTL_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MTIMECTL/MSTOP value Mask */ +#define SysTimer_MSIP_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MSIP value Mask */ +#define SysTimer_MSFTRST_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MSFTRST value Mask */ + +#define SysTimer_MSFRST_KEY (0x80000A5FUL) /*!< SysTick Timer Software Reset Request Key */ + +#define SysTimer_CLINT_MSIP_OFS (0x1000UL) /*!< Software interrupt register offset of clint mode in SysTick Timer */ +#define SysTimer_CLINT_MTIMECMP_OFS (0x5000UL) /*!< MTIMECMP register offset of clint mode in SysTick Timer */ +#define SysTimer_CLINT_MTIME_OFS (0xCFF8UL) /*!< MTIME register offset of clint mode in SysTick Timer */ + +#ifndef __SYSTIMER_BASEADDR +/* Base address of SYSTIMER(__SYSTIMER_BASEADDR) should be defined in */ +#error "__SYSTIMER_BASEADDR is not defined, please check!" +#endif +/* System Timer Memory mapping of Device */ +#define SysTimer_BASE __SYSTIMER_BASEADDR /*!< SysTick Base Address */ +#define SysTimer ((SysTimer_Type *) SysTimer_BASE) /*!< SysTick configuration struct */ + +/* System Timer Clint register base */ +#define SysTimer_CLINT_MSIP_BASE(hartid) (unsigned long)((SysTimer_BASE) + (SysTimer_CLINT_MSIP_OFS) + ((hartid) << 2)) +#define SysTimer_CLINT_MTIMECMP_BASE(hartid) (unsigned long)((SysTimer_BASE) + (SysTimer_CLINT_MTIMECMP_OFS) + ((hartid) << 3)) +#define SysTimer_CLINT_MTIME_BASE (unsigned long)((SysTimer_BASE) + (SysTimer_CLINT_MTIME_OFS)) + +/** @} */ /* end of group NMSIS_Core_SysTimer_Registers */ + +/* ################################## SysTimer function ############################################ */ +/** + * \defgroup NMSIS_Core_SysTimer SysTimer Functions + * \brief Functions that configure the Core System Timer. + * @{ + */ + +/** + * SysTimer_GetHartID() is used to get timer hartid which might not be the same as cpu hart id, + * for example, cpu hartid may be 1, but timer hartid may be 0, then timer hartid offset is 1. + * If defined __SYSTIMER_HARTID, it will use __SYSTIMER_HARTID as timer hartid, + * otherwise, it will use __get_hart_index(). + * The cpu hartid is get by using __get_hart_id function + */ +#ifndef __SYSTIMER_HARTID +#define SysTimer_GetHartID() (__get_hart_index()) +#else +#define SysTimer_GetHartID() (__SYSTIMER_HARTID) +#endif + +/** + * \brief Set system timer load value + * \details + * This function set the system timer load value in MTIMER register. + * \param [in] value value to set system timer MTIMER register. + * \remarks + * - Load value is 64bits wide. + * - \ref SysTimer_GetLoadValue + */ +__STATIC_FORCEINLINE void SysTimer_SetLoadValue(uint64_t value) +{ +#if __RISCV_XLEN == 32 + uint8_t *addr; + addr = (uint8_t *)(&(SysTimer->MTIMER)); + __SW(addr, 0); // prevent carry + __SW(addr + 4, (uint32_t)(value >> 32)); + __SW(addr, (uint32_t)(value)); +#else + SysTimer->MTIMER = value; +#endif +} + +/** + * \brief Get system timer load value + * \details + * This function get the system timer current value in MTIMER register. + * \return current value(64bit) of system timer MTIMER register. + * \remarks + * - Load value is 64bits wide. + * - \ref SysTimer_SetLoadValue + */ +__STATIC_FORCEINLINE uint64_t SysTimer_GetLoadValue(void) +{ +#if __RISCV_XLEN == 32 + volatile uint32_t high0, low, high; + uint64_t full; + uint8_t *addr; + + addr = (uint8_t *)(&(SysTimer->MTIMER)); + + high0 = __LW(addr + 4); + low = __LW(addr); + high = __LW(addr + 4); + if (high0 != high) { + low = __LW(addr); + } + full = (((uint64_t)high) << 32) | low; + return full; +#else + return SysTimer->MTIMER; +#endif +} + +/** + * \brief Set system timer compare value by hartid + * \details + * This function set the system Timer compare value in MTIMERCMP register. + * \param [in] value compare value to set system timer MTIMERCMP register. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \remarks + * - Compare value is 64bits wide. + * - If compare value is larger than current value timer interrupt generate. + * - Modify the load value or compare value less to clear the interrupt. + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_GetHartCompareValue + */ +__STATIC_FORCEINLINE void SysTimer_SetHartCompareValue(uint64_t value, unsigned long hartid) +{ + if (hartid == 0) { +#if __RISCV_XLEN == 32 + uint8_t *addr; + addr = (uint8_t *)(&(SysTimer->MTIMERCMP)); + __SW(addr, -1U); // prevent load > timecmp + __SW(addr + 4, (uint32_t)(value >> 32)); + __SW(addr, (uint32_t)(value)); +#else + SysTimer->MTIMERCMP = value; +#endif + } else { + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MTIMECMP_BASE(hartid)); +#if __RISCV_XLEN == 32 + __SW(addr, -1U); // prevent load > timecmp + __SW(addr + 4, (uint32_t)(value >> 32)); + __SW(addr, (uint32_t)value); +#else + __SD(addr, value); +#endif + } +} + +/** + * \brief Set system timer compare value in machine mode + * \details + * This function set the system Timer compare value in MTIMERCMP register. + * \param [in] value compare value to set system timer MTIMERCMP register. + * \remarks + * - Compare value is 64bits wide. + * - If compare value is larger than current value timer interrupt generate. + * - Modify the load value or compare value less to clear the interrupt. + * - __get_hart_id function can only be accessed in machine mode, or else exception will occur. + * - \ref SysTimer_GetCompareValue + */ +__STATIC_FORCEINLINE void SysTimer_SetCompareValue(uint64_t value) +{ + unsigned long hartid = SysTimer_GetHartID(); + SysTimer_SetHartCompareValue(value, hartid); +} + +/** + * \brief Get system timer compare value by hartid + * \details + * This function get the system timer compare value in MTIMERCMP register. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \return compare value of system timer MTIMERCMP register. + * \remarks + * - Compare value is 64bits wide. + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_SetHartCompareValue + */ +__STATIC_FORCEINLINE uint64_t SysTimer_GetHartCompareValue(unsigned long hartid) +{ + if (hartid == 0) { + return SysTimer->MTIMERCMP; + } else { + uint64_t full; + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MTIMECMP_BASE(hartid)); +#if __RISCV_XLEN == 32 + // MTIMECMP didn't increase + uint32_t high, low; + + high = __LW(addr + 4); + low = __LW(addr); + full = (((uint64_t)high) << 32) | low; +#else + full = __LD(addr); +#endif + return full; + } +} + +/** + * \brief Get system timer compare value in machine mode + * \details + * This function get the system timer compare value in MTIMERCMP register. + * \return compare value of system timer MTIMERCMP register. + * \remarks + * - Compare value is 64bits wide. + * - \ref SysTimer_SetCompareValue + */ +__STATIC_FORCEINLINE uint64_t SysTimer_GetCompareValue(void) +{ + unsigned long hartid = SysTimer_GetHartID(); + return SysTimer_GetHartCompareValue(hartid); +} + +/** + * \brief Enable system timer counter running + * \details + * Enable system timer counter running by clear + * TIMESTOP bit in MTIMECTL register. + */ +__STATIC_FORCEINLINE void SysTimer_Start(void) +{ + SysTimer->MTIMECTL &= ~(SysTimer_MTIMECTL_TIMESTOP_Msk); +} + +/** + * \brief Stop system timer counter running + * \details + * Stop system timer counter running by set + * TIMESTOP bit in MTIMECTL register. + */ +__STATIC_FORCEINLINE void SysTimer_Stop(void) +{ + SysTimer->MTIMECTL |= SysTimer_MTIMECTL_TIMESTOP_Msk; +} + +/** + * \brief Set system timer control value + * \details + * This function set the system timer MTIMECTL register value. + * \param [in] mctl value to set MTIMECTL register + * \remarks + * - Bit TIMESTOP is used to start and stop timer. + * Clear TIMESTOP bit to 0 to start timer, otherwise to stop timer. + * - Bit CMPCLREN is used to enable auto MTIMER clear to zero when MTIMER >= MTIMERCMP. + * Clear CMPCLREN bit to 0 to stop auto clear MTIMER feature, otherwise to enable it. + * - Bit CLKSRC is used to select timer clock source. + * Clear CLKSRC bit to 0 to use *mtime_toggle_a*, otherwise use *core_clk_aon* + * - \ref SysTimer_GetControlValue + */ +__STATIC_FORCEINLINE void SysTimer_SetControlValue(uint32_t mctl) +{ + SysTimer->MTIMECTL = (mctl & SysTimer_MTIMECTL_Msk); +} + +/** + * \brief Get system timer control value + * \details + * This function get the system timer MTIMECTL register value. + * \return MTIMECTL register value + * \remarks + * - \ref SysTimer_SetControlValue + */ +__STATIC_FORCEINLINE uint32_t SysTimer_GetControlValue(void) +{ + return (SysTimer->MTIMECTL & SysTimer_MTIMECTL_Msk); +} + +/** + * \brief Trigger or set software interrupt via system timer by hartid + * \details + * This function set the system timer MSIP bit in MSIP register. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \remarks + * - Set system timer MSIP bit and generate a SW interrupt. + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_ClearHartSWIRQ + * - \ref SysTimer_GetHartMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_SetHartSWIRQ(unsigned long hartid) +{ + if (hartid == 0) { + SysTimer->MSIP |= SysTimer_MSIP_MSIP_Msk; + } else { + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + __SW(addr, SysTimer_MSIP_MSIP_Msk); + } +} + +/** + * \brief Trigger or set software interrupt via system timer in machine mode + * \details + * This function set the system timer MSIP bit in MSIP register. + * \remarks + * - Set system timer MSIP bit and generate a SW interrupt. + * - \ref SysTimer_ClearSWIRQ + * - \ref SysTimer_GetMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_SetSWIRQ(void) +{ + unsigned long hartid = SysTimer_GetHartID(); + SysTimer_SetHartSWIRQ(hartid); +} + +/** + * \brief Clear system timer software interrupt pending request by hartid + * \details + * This function clear the system timer MSIP bit in MSIP register. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \remarks + * - Clear system timer MSIP bit in MSIP register to clear the software interrupt pending. + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_SetHartSWIRQ + * - \ref SysTimer_GetHartMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_ClearHartSWIRQ(unsigned long hartid) +{ + if (hartid == 0) { + SysTimer->MSIP &= ~SysTimer_MSIP_MSIP_Msk; + } else { + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + __SW(addr, 0); + } +} + +/** + * \brief Clear system timer software interrupt pending request in machine mode + * \details + * This function clear the system timer MSIP bit in MSIP register. + * \remarks + * - Clear system timer MSIP bit in MSIP register to clear the software interrupt pending. + * - \ref SysTimer_SetSWIRQ + * - \ref SysTimer_GetMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_ClearSWIRQ(void) +{ + unsigned long hartid = SysTimer_GetHartID(); + SysTimer_ClearHartSWIRQ(hartid); +} + +/** + * \brief Get system timer MSIP register value by hartid + * \details + * This function get the system timer MSIP register value. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \return Value of Timer MSIP register. + * \remarks + * - Bit0 is SW interrupt flag. + * Bit0 is 1 then SW interrupt set. Bit0 is 0 then SW interrupt clear. + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_SetHartSWIRQ + * - \ref SysTimer_ClearHartSWIRQ + * - \ref SysTimer_SetHartMsipValue + */ +__STATIC_FORCEINLINE uint32_t SysTimer_GetHartMsipValue(unsigned long hartid) +{ + if (hartid == 0) { + return (uint32_t)(SysTimer->MSIP & SysTimer_MSIP_Msk); + } else { + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + return __LW(addr); + } +} + +/** + * \brief Get system timer MSIP register value in machine mode + * \details + * This function get the system timer MSIP register value. + * \return Value of Timer MSIP register. + * \remarks + * - Bit0 is SW interrupt flag. + * Bit0 is 1 then SW interrupt set. Bit0 is 0 then SW interrupt clear. + * - \ref SysTimer_SetSWIRQ + * - \ref SysTimer_ClearSWIRQ + * - \ref SysTimer_SetMsipValue + */ +__STATIC_FORCEINLINE uint32_t SysTimer_GetMsipValue(void) +{ + unsigned long hartid = SysTimer_GetHartID(); + return SysTimer_GetHartMsipValue(hartid); +} + +/** + * \brief Set system timer MSIP register value by hartid + * \details + * This function set the system timer MSIP register value. + * \param [in] msip value to set MSIP register + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \remarks + * - In S-mode, hartid can't be get using __get_hart_id function, so this api suits S-mode particularly. + * - \ref SysTimer_GetHartMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_SetHartMsipValue(uint32_t msip, unsigned long hartid) +{ + if (hartid == 0) { + SysTimer->MSIP = (msip & SysTimer_MSIP_Msk); + } else { + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + __SW(addr, msip); + } +} + +/** + * \brief Set system timer MSIP register value in machine mode + * \details + * This function set the system timer MSIP register value. + * \param [in] msip value to set MSIP register + * - \ref SysTimer_GetMsipValue + */ +__STATIC_FORCEINLINE void SysTimer_SetMsipValue(uint32_t msip) +{ + unsigned long hartid = SysTimer_GetHartID(); + SysTimer_SetHartMsipValue(msip, hartid); +} + +/** + * \brief Do software reset request + * \details + * This function will do software reset request through MTIMER + * - Software need to write \ref SysTimer_MSFRST_KEY to generate software reset request + * - The software request flag can be cleared by reset operation to clear + * \remarks + * - The software reset is sent to SoC, SoC need to generate reset signal and send back to Core + * - This function will not return, it will do while(1) to wait the Core reset happened + */ +__STATIC_FORCEINLINE void SysTimer_SoftwareReset(void) +{ + SysTimer->MSFTRST = SysTimer_MSFRST_KEY; + // will reset cpu, never return + while (1); +} + +/** + * \brief send ipi to target hart using Systimer Clint + * \details + * This function send ipi using clint timer. + * \param [in] hart target hart + */ +__STATIC_FORCEINLINE void SysTimer_SendIPI(unsigned long hartid) +{ + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + __SW(addr, 1); +} + +/** + * \brief clear ipi to target hart using Systimer Clint + * \details + * This function clear ipi using Systimer clint timer. + * \param [in] hart target hart + */ +__STATIC_FORCEINLINE void SysTimer_ClearIPI(unsigned long hartid) +{ + uint8_t *addr = (uint8_t *)(SysTimer_CLINT_MSIP_BASE(hartid)); + __SW(addr, 0); +} + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) && defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) +/** + * \brief System Tick Configuration + * \details Initializes the System Timer and its non-vector interrupt, and starts the System Tick Timer. + * + * In our default implementation, the timer counter will be set to zero, and it will start a timer compare non-vector interrupt + * when it matchs the ticks user set, during the timer interrupt user should reload the system tick using \ref SysTick_Reload function + * or similar function written by user, so it can produce period timer interrupt. + * \param [in] ticks Number of ticks between two interrupts. + * \return 0 Function succeeded. + * \return 1 Function failed. + * \remarks + * - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, + * but we assume that the CMPCLREN bit is set to 0, so MTIMER register will not be + * auto cleared to 0 when MTIMER >= MTIMERCMP. + * - When the variable \ref __Vendor_SysTickConfig is set to 1, then the + * function \ref SysTick_Config is not included. + * - In this case, the file .h must contain a vendor-specific implementation + * of this function. + * - If user need this function to start a period timer interrupt, then in timer interrupt handler + * routine code, user should call \ref SysTick_Reload with ticks to reload the timer. + * - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0 + * \sa + * - \ref SysTimer_SetCompareValue; SysTimer_SetLoadValue + */ +__STATIC_INLINE uint32_t SysTick_Config(uint64_t ticks) +{ + uint64_t loadticks = SysTimer_GetLoadValue(); + SysTimer_SetCompareValue(ticks + loadticks); + ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT); + ECLIC_SetLevelIRQ(SysTimer_IRQn, 0); + ECLIC_EnableIRQ(SysTimer_IRQn); + return (0UL); +} + +/** + * \brief System Tick Configuration By hartid + * \details Initializes the System Timer and its non-vector interrupt, and starts the System Tick Timer. + * + * In our default implementation, the timer counter will be set to zero, and it will start a timer compare non-vector interrupt + * when it matchs the ticks user set, during the timer interrupt user should reload the system tick using \ref SysTick_Reload function + * or similar function written by user, so it can produce period timer interrupt. + * \param [in] ticks Number of ticks between two interrupts. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \return 0 Function succeeded. + * \return 1 Function failed. + * \remarks + * - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, + * but we assume that the CMPCLREN bit is set to 0, so MTIMER register will not be + * auto cleared to 0 when MTIMER >= MTIMERCMP. + * - When the variable \ref __Vendor_SysTickConfig is set to 1, then the + * function \ref SysTick_Config is not included. + * - In this case, the file .h must contain a vendor-specific implementation + * of this function. + * - If user need this function to start a period timer interrupt, then in timer interrupt handler + * routine code, user should call \ref SysTick_Reload with ticks to reload the timer. + * - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0 + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * \sa + * - \ref SysTimer_SetCompareValue; SysTimer_SetLoadValue + */ +__STATIC_INLINE uint32_t SysTick_HartConfig(uint64_t ticks, unsigned long hartid) +{ + uint64_t loadticks = SysTimer_GetLoadValue(); + SysTimer_SetHartCompareValue(ticks + loadticks, hartid); + ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT); + ECLIC_SetLevelIRQ(SysTimer_IRQn, 0); + ECLIC_EnableIRQ(SysTimer_IRQn); + return (0UL); +} + +/** + * \brief System Tick Reload + * \details Reload the System Timer Tick when the MTIMECMP reached TIME value + * + * \param [in] ticks Number of ticks between two interrupts. + * \return 0 Function succeeded. + * \return 1 Function failed. + * \remarks + * - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, + * but for this \ref SysTick_Config function, we assume this CMPCLREN bit is set to 0, + * so in interrupt handler function, user still need to set the MTIMERCMP or MTIMER to reload + * the system tick, if vendor want to use this timer's auto clear feature, they can define + * \ref __Vendor_SysTickConfig to 1, and implement \ref SysTick_Config and \ref SysTick_Reload functions. + * - When the variable \ref __Vendor_SysTickConfig is set to 1, then the + * function \ref SysTick_Reload is not included. + * - In this case, the file .h must contain a vendor-specific implementation + * of this function. + * - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0 + * - Since the MTIMERCMP value might overflow, if overflowed, MTIMER will be set to 0, and MTIMERCMP set to ticks + * \sa + * - \ref SysTimer_SetCompareValue + * - \ref SysTimer_SetLoadValue + */ +__STATIC_FORCEINLINE uint32_t SysTick_Reload(uint64_t ticks) +{ + uint64_t cur_ticks = SysTimer_GetLoadValue(); + uint64_t reload_ticks = ticks + cur_ticks; + + if (__USUALLY(reload_ticks > cur_ticks)) { + SysTimer_SetCompareValue(reload_ticks); + } else { + /* When added the ticks value, then the MTIMERCMP < TIMER, + * which means the MTIMERCMP is overflowed, + * so we need to reset the counter to zero */ + SysTimer_SetLoadValue(0); + SysTimer_SetCompareValue(ticks); + } + + return (0UL); +} + +/** + * \brief System Tick Reload + * \details Reload the System Timer Tick when the MTIMECMP reached TIME value + * + * \param [in] ticks Number of ticks between two interrupts. + * \param [in] hartid hart ID, one hart is required to have a known hart ID of 0, other harts ID can be in 1~1023. + * \return 0 Function succeeded. + * \return 1 Function failed. + * \remarks + * - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced, + * but for this \ref SysTick_Config function, we assume this CMPCLREN bit is set to 0, + * so in interrupt handler function, user still need to set the MTIMERCMP or MTIMER to reload + * the system tick, if vendor want to use this timer's auto clear feature, they can define + * \ref __Vendor_SysTickConfig to 1, and implement \ref SysTick_Config and \ref SysTick_Reload functions. + * - When the variable \ref __Vendor_SysTickConfig is set to 1, then the + * function \ref SysTick_Reload is not included. + * - In this case, the file .h must contain a vendor-specific implementation + * of this function. + * - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0 + * - Since the MTIMERCMP value might overflow, if overflowed, MTIMER will be set to 0, and MTIMERCMP set to ticks + * - In S-mode, hartid can't be get by using __get_hart_id function, so this api suits S-mode particularly. + * \sa + * - \ref SysTimer_SetCompareValue + * - \ref SysTimer_SetLoadValue + */ +__STATIC_FORCEINLINE uint32_t SysTick_HartReload(uint64_t ticks, unsigned long hartid) +{ + uint64_t cur_ticks = SysTimer_GetLoadValue(); + uint64_t reload_ticks = ticks + cur_ticks; + + if (__USUALLY(reload_ticks > cur_ticks)) { + SysTimer_SetHartCompareValue(reload_ticks, hartid); + } else { + /* When added the ticks value, then the MTIMERCMP < TIMER, + * which means the MTIMERCMP is overflowed, + * so we need to reset the counter to zero */ + SysTimer_SetLoadValue(0); + SysTimer_SetHartCompareValue(ticks, hartid); + } + + return (0UL); +} + +#endif /* defined(__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) */ +/** @} */ /* End of Doxygen Group NMSIS_Core_SysTimer */ + +#endif /* defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif +#endif /* __CORE_FEATURE_TIMER_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_vector.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_vector.h new file mode 100644 index 0000000..c95a8bb --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/core_feature_vector.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __CORE_FEATURE_VECTOR__ +#define __CORE_FEATURE_VECTOR__ + +/*! + * @file core_feature_vector.h + * @brief Vector feature API header file for Nuclei N/NX Core + */ +/* + * Vector Feature Configuration Macro: + * 1. __VECTOR_PRESENT: Define whether Vector Unit is present or not + * * 0: Not present + * * 1: Present + */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" + +#if defined(__VECTOR_PRESENT) && (__VECTOR_PRESENT == 1) + +/* ########################### CPU Vector Intrinsic Functions ########################### */ +/** + * \defgroup NMSIS_Core_Vector_Intrinsic Intrinsic Functions for Vector Instructions + * \ingroup NMSIS_Core + * \brief Functions that generate RISC-V Vector instructions. + * \details + * + * RISC-V Vector Intrinsic APIs are provided directly through compiler generated intrinsic function. + * + * This intrinsic function support by compiler: + * + * For Nuclei RISC-V GCC 10.2, it is an very old and not ratified version(no longer supported). + * + * - API header file can be found in lib/gcc/riscv-nuclei-elf//include/riscv_vector.h + * + * For Nuclei RISC-V GCC 13/Clang 17, the intrinsic API supported is v0.12 version, see + * https://github.com/riscv-non-isa/rvv-intrinsic-doc/releases/tag/v0.12.0 + * + * @{ + */ + +#if defined(__INC_INTRINSIC_API) && (__INC_INTRINSIC_API == 1) +#include +#endif + +/** + * \brief Enable Vector Unit + * \details + * Set vector context status bits to enable vector unit, + * and set state to initial + */ +__STATIC_FORCEINLINE void __enable_vector(void) +{ + __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_VS); + __RV_CSR_SET(CSR_MSTATUS, MSTATUS_VS_INITIAL); +} + +/** + * \brief Disable Vector Unit + * \details + * Clear vector context status bits to disable vector unit + */ +__STATIC_FORCEINLINE void __disable_vector(void) +{ + __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_VS); +} + +/** @} */ /* End of Doxygen Group NMSIS_Core_Vector_Intrinsic */ +#endif /* defined(__VECTOR_PRESENT) && (__VECTOR_PRESENT == 1) */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_FEATURE_VECTOR__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_bench.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_bench.h new file mode 100644 index 0000000..10dcb57 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_bench.h @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __NMSIS_BENCH__ +#define __NMSIS_BENCH__ + +/*! + * @file nmsis_bench.h + * @brief benchmark and helper related API for Nuclei N/NX Core + */ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "core_feature_base.h" +#include + +/** + * \defgroup NMSIS_Core_Bench_Helpers NMSIS Bench and Test Related Helper Functions + * \ingroup NMSIS_Core + * \brief Functions that used to do benchmark and test suite. + * \details + * + * NMSIS benchmark and test related helper functions are provided to help do benchmark + * and test case pass/fail assertion. + * + * If you want to do calculate cpu cycle cost of a process, you can use BENCH_xxx macros + * defined in this. + * + * In a single c source code file, you should include `nmsis_bench.h`, and then you should place `BENCH_DECLARE_VAR();` + * before call other BENCH_xxx macros. If you want to start to do benchmark, you should only call `BENCH_INIT();` + * once in your source code, and then place `BENCH_START(proc_name);` and `BENCH_END(proc_name)` before + * and after the process you want to measure. You can refer to `/application/baremetal/demo_dsp` + * for how to use it. + * + * If you want to disable the benchmark calculation, you can place `#define DISABLE_NMSIS_BENCH` + * before include `nmsis_bench.h` + * + * If in your c test source code, you can add `NMSIS_TEST_PASS();` and `NMSIS_TEST_FAIL();` to mark c test + * is pass or fail. + * + * @{ + */ + +/** + * \brief Prepare benchmark environment + * \details + * Prepare benchmark required environment, such as turn on necessary units + * like vpu, cycle, instret counters, hpm counters + */ +__STATIC_FORCEINLINE void __prepare_bench_env(void) +{ +#ifdef __riscv_vector + __RV_CSR_SET(CSR_MSTATUS, MSTATUS_VS); +#endif + __enable_all_counter(); +} + +#ifndef READ_CYCLE +/** Read run cycle of cpu */ +#define READ_CYCLE __get_rv_cycle +#endif + +#ifndef DISABLE_NMSIS_BENCH + +/** Declare benchmark required variables, need to be placed above all BENCH_xxx macros in each c source code if BENCH_xxx used */ +#define BENCH_DECLARE_VAR() static volatile uint64_t _bc_sttcyc, _bc_endcyc, _bc_usecyc, _bc_sumcyc, _bc_lpcnt, _bc_ercd; + +/** Initialize benchmark environment, need to called in before other BENCH_xxx macros are called */ +#define BENCH_INIT() printf("Benchmark initialized\n"); \ + __prepare_bench_env(); \ + _bc_ercd = 0; _bc_sumcyc = 0; + +/** Reset benchmark sum cycle and use cycle for proc */ +#define BENCH_RESET(proc) _bc_sumcyc = 0; _bc_usecyc = 0; _bc_lpcnt = 0; _bc_ercd = 0; + +/** Start to do benchmark for proc, and record start cycle, and reset error code */ +#define BENCH_START(proc) _bc_ercd = 0; \ + _bc_sttcyc = READ_CYCLE(); + +/** Sample a benchmark for proc, and record this start -> sample cost cycle, and accumulate it to sum cycle */ +#define BENCH_SAMPLE(proc) _bc_endcyc = READ_CYCLE(); \ + _bc_usecyc = _bc_endcyc - _bc_sttcyc; \ + _bc_sumcyc += _bc_usecyc; _bc_lpcnt += 1; + +/** Mark end of benchmark for proc, and calc used cycle, and print it */ +#define BENCH_END(proc) BENCH_SAMPLE(proc); \ + printf("CSV, %s, %lu\n", #proc, (unsigned long)_bc_usecyc); + +/** Mark stop of benchmark, start -> sample -> sample -> stop, and print the sum cycle of a proc */ +#define BENCH_STOP(proc) printf("CSV, %s, %lu\n", #proc, (unsigned long)_bc_sumcyc); + +/** Show statistics of benchmark, format: STAT, proc, loopcnt, sumcyc */ +#define BENCH_STAT(proc) printf("STAT, %s, %lu, %lu\n", #proc, (unsigned long)_bc_lpcnt, (unsigned long)_bc_sumcyc); + +/** Get benchmark use cycle */ +#define BENCH_GET_USECYC() (_bc_usecyc) + +/** Get benchmark sum cycle */ +#define BENCH_GET_SUMCYC() (_bc_sumcyc) + +/** Get benchmark loop count */ +#define BENCH_GET_LPCNT() (_bc_lpcnt) + +/** Mark benchmark for proc is errored */ +#define BENCH_ERROR(proc) _bc_ercd = 1; +/** Show the status of the benchmark */ +#define BENCH_STATUS(proc) if (_bc_ercd) { \ + printf("ERROR, %s\n", #proc); \ + } else { \ + printf("SUCCESS, %s\n", #proc); \ + } +#else +#define BENCH_DECLARE_VAR() static volatile uint64_t _bc_ercd, _bc_lpcnt; +#define BENCH_INIT() _bc_ercd = 0; __prepare_bench_env(); +#define BENCH_RESET(proc) +#define BENCH_START(proc) _bc_ercd = 0; +#define BENCH_SAMPLE(proc) _bc_lpcnt += 1; +#define BENCH_END(proc) +#define BENCH_STOP(proc) +#define BENCH_STAT(proc) +#define BENCH_GET_USECYC() (0) +#define BENCH_GET_SUMCYC() (0) +#define BENCH_GET_LPCNT() (_bc_lpcnt) +#define BENCH_ERROR(proc) _bc_ercd = 1; +#define BENCH_STATUS(proc) if (_bc_ercd) { \ + printf("ERROR, %s\n", #proc); \ + } else { \ + printf("SUCCESS, %s\n", #proc); \ + } + +#endif + +// High performance monitor bench helpers +#ifndef DISABLE_NMSIS_HPM + +/* Events type select */ +#define EVENT_SEL_INSTRUCTION_COMMIT 0 +#define EVENT_SEL_MEMORY_ACCESS 1 + +/* Instruction commit events idx define*/ +#define EVENT_INSTRUCTION_COMMIT_CYCLE_COUNT 1 +#define EVENT_INSTRUCTION_COMMIT_RETIRED_COUNT 2 +/* Integer load instruction (includes LR) */ +#define EVENT_INSTRUCTION_COMMIT_INTEGER_LOAD 3 +/* Integer store instruction (includes SC) */ +#define EVENT_INSTRUCTION_COMMIT_INTEGER_STORE 4 +/* Atomic memory operation (do not include LR and SC) */ +#define EVENT_INSTRUCTION_COMMIT_ATOMIC_MEMORY_OPERATION 5 +/* System instruction */ +#define EVENT_INSTRUCTION_COMMIT_SYSTEM 6 +/* Integer computational instruction (excluding multiplication/division/remainder) */ +#define EVENT_INSTRUCTION_COMMIT_INTEGER_COMPUTATIONAL 7 +#define EVENT_INSTRUCTION_COMMIT_CONDITIONAL_BRANCH 8 +#define EVENT_INSTRUCTION_COMMIT_TAKEN_CONDITIONAL_BRANCH 9 +#define EVENT_INSTRUCTION_COMMIT_JAL 10 +#define EVENT_INSTRUCTION_COMMIT_JALR 11 +#define EVENT_INSTRUCTION_COMMIT_RETURN 12 +/* Control transfer instruction (CBR+JAL+JALR) */ +#define EVENT_INSTRUCTION_COMMIT_CONTROL_TRANSFER 13 +/* 14 Reseved */ +#define EVENT_INSTRUCTION_COMMIT_INTEGER_MULTIPLICATION 15 +/* Integer division/remainder instruction */ +#define EVENT_INSTRUCTION_COMMIT_INTEGER_DIVISION_REMAINDER 16 +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_LOAD 17 +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_STORE 18 +/* Floating-point addition/subtraction */ +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_ADDITION_SUBTRACTION 19 +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_MULTIPLICATION 20 +/* Floating-point fused multiply-add (FMADD, FMSUB, FNMSUB, FNMADD) */ +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_FUSED_MULTIPLY_ADD_SUB 21 +#define EVENT_INSTRUCTION_COMMIT_FLOATING_POINT_DIVISION_OR_SQUARE_ROOT 22 +#define EVENT_INSTRUCTION_COMMIT_OTHER_FLOATING_POINT_INSTRUCTION 23 +#define EVENT_INSTRUCTION_COMMIT_CONDITIONAL_BRANCH_PREDICTION_FAIL 24 +#define EVENT_INSTRUCTION_COMMIT_JAL_PREDICTION_FAIL 25 +#define EVENT_INSTRUCTION_COMMIT_JALR_PREDICTION_FAIL 26 + +/* Memory access events idx define*/ +#define EVENT_MEMORY_ACCESS_ICACHE_MISS 1 +#define EVENT_MEMORY_ACCESS_DCACHE_MISS 2 +#define EVENT_MEMORY_ACCESS_ITLB_MISS 3 +#define EVENT_MEMORY_ACCESS_DTLB_MISS 4 +#define EVENT_MEMORY_ACCESS_MAIN_DTLB_MISS 5 + +/* Enable the corresponding performance monitor counter increment for events in Machine/Supervisor/User Mode */ +#define MSU_EVENT_ENABLE 0x0F +#define MEVENT_EN 0x08 +#define SEVENT_EN 0x02 +#define UEVENT_EN 0x01 + +/** Declare high performance monitor counter idx benchmark required variables, need to be placed above all HPM_xxx macros in each c source code if HPM_xxx used */ +#define HPM_DECLARE_VAR(idx) static volatile uint64_t __hpm_sttcyc##idx, __hpm_endcyc##idx, __hpm_usecyc##idx, __hpm_sumcyc##idx, __hpm_lpcnt##idx, __hpm_val##idx; + +#define HPM_SEL_ENABLE(ena) (ena << 28) +#define HPM_SEL_EVENT(sel, idx) ((sel) | (idx << 4)) + +/** Construct a event variable to be set(sel -> event_sel, idx -> event_idx, ena -> m/s/u_enable) */ +#define HPM_EVENT(sel, idx, ena) (HPM_SEL_ENABLE(ena) | HPM_SEL_EVENT(sel, idx)) + +/** Initialize high performance monitor environment, need to called in before other HPM_xxx macros are called */ +#define HPM_INIT() printf("High performance monitor initialized\n"); \ + __prepare_bench_env(); + +/** Reset high performance benchmark for proc using counter which index is idx */ +#define HPM_RESET(idx, proc, event) __hpm_sumcyc##idx = 0; __hpm_lpcnt##idx = 0; + +/** Start to do high performance benchmark for proc, and record start hpm counter */ +#define HPM_START(idx, proc, event) \ + __hpm_val##idx = (event); \ + __set_hpm_event(idx, __hpm_val##idx); \ + __set_hpm_counter(idx, 0); \ + __hpm_sttcyc##idx = __get_hpm_counter(idx); + +/** Do high performance benchmark sample for proc, and sum it into sum counter */ +#define HPM_SAMPLE(idx, proc, event) \ + __hpm_endcyc##idx = __get_hpm_counter(idx); \ + __hpm_usecyc##idx = __hpm_endcyc##idx - __hpm_sttcyc##idx; \ + __hpm_sumcyc##idx += __hpm_usecyc##idx; \ + __hpm_lpcnt##idx += 1; + +/** Mark end of high performance benchmark for proc, and calc used hpm counter value */ +#define HPM_END(idx, proc, event) \ + HPM_SAMPLE(idx, proc, event); \ + printf("HPM%d:0x%x, %s, %lu\n", idx, event, #proc, (unsigned long)__hpm_usecyc##idx); + +/** Mark stop of hpm benchmark, start -> sample -> sample -> stop, and print the sum cycle of a proc */ +#define HPM_STOP(idx, proc, event) \ + printf("HPM%d:0x%x, %s, %lu\n", idx, event, #proc, (unsigned long)__hpm_sumcyc##idx); + +/** Show statistics of hpm benchmark, format: STATHPM#idx:event, proc, loopcnt, sumcyc */ +#define HPM_STAT(idx, proc, event) \ + printf("STATHPM%d:0x%x, %s, %lu, %lu\n", idx, event, #proc, (unsigned long)__hpm_lpcnt##idx, (unsigned long)__hpm_sumcyc##idx); + +/** Get hpm benchmark use cycle for counter idx */ +#define HPM_GET_USECYC(idx) (__hpm_usecyc##idx) + +/** Get hpm benchmark sum cycle for counter idx */ +#define HPM_GET_SUMCYC(idx) (__hpm_sumcyc##idx) + +/** Get hpm benchmark loop count for counter idx */ +#define HPM_GET_LPCNT(idx) (__hpm_lpcnt##idx) + +#else +#define HPM_DECLARE_VAR(idx) +#define HPM_EVENT(sel, idx, ena) +#define HPM_INIT() +#define HPM_RESET(idx, proc, event) +#define HPM_START(idx, proc, event) +#define HPM_SAMPLE(idx, proc, event) +#define HPM_END(idx, proc, event) +#define HPM_STOP(idx, proc, event) +#define HPM_STAT(idx, proc, event) +#define HPM_GET_USECYC(idx) (0) +#define HPM_GET_SUMCYC(idx) (0) +#define HPM_GET_LPCNT(idx) (1) +#endif + +// NMSIS Helpers +#ifndef DISABLE_NMSIS_HELPER +/** Mark test or application passed */ +#define NMSIS_TEST_PASS() printf("\nNMSIS_TEST_PASS\n"); +/** Mark test or application failed */ +#define NMSIS_TEST_FAIL() printf("\nNMSIS_TEST_FAIL\n"); +#else +#define NMSIS_TEST_PASS() +#define NMSIS_TEST_FAIL() +#endif + +/** @} */ /* End of Doxygen Group NMSIS_Core_Bench_Helpers */ +#ifdef __cplusplus +} +#endif +#endif /* __NMSIS_BENCH__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_compiler.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_compiler.h new file mode 100644 index 0000000..eb2b582 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_compiler.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __NMSIS_COMPILER_H +#define __NMSIS_COMPILER_H + +#include + +/*! + * @file nmsis_compiler.h + * @brief NMSIS compiler generic header file + */ +#if defined ( __GNUC__ ) + /* GNU GCC Compiler */ + #include "nmsis_gcc.h" +#elif defined ( __ICCRISCV__ ) + /* IAR Compiler */ + #include "nmsis_iar.h" +#else + #error Unknown compiler. +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + * \defgroup NMSIS_Core_PeriphAccess Peripheral Access + * \brief Naming conventions and optional features for accessing peripherals. + * + * The section below describes the naming conventions, requirements, and optional features + * for accessing device specific peripherals. + * Most of the rules also apply to the core peripherals. + * + * The **Device Header File ** contains typically these definition + * and also includes the core specific header files. + * + * @{ + */ +/** \brief Defines 'read only' permissions */ +#ifdef __cplusplus + #define __I volatile +#else + #define __I volatile const +#endif +/** \brief Defines 'write only' permissions */ +#define __O volatile +/** \brief Defines 'read / write' permissions */ +#define __IO volatile + +/* following defines should be used for structure members */ +/** \brief Defines 'read only' structure member permissions */ +#define __IM volatile const +/** \brief Defines 'write only' structure member permissions */ +#define __OM volatile +/** \brief Defines 'read/write' structure member permissions */ +#define __IOM volatile + +/** + * \brief Mask and shift a bit field value for use in a register bit range. + * \details The macro \ref _VAL2FLD uses the #define's _Pos and _Msk of the related bit + * field to shift bit-field values for assigning to a register. + * + * **Example**: + * \code + * ECLIC->CFG = _VAL2FLD(CLIC_CLICCFG_NLBIT, 3); + * \endcode + * \param[in] field Name of the register bit field. + * \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + * \return Masked and shifted value. + */ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + * \brief Mask and shift a register value to extract a bit filed value. + * \details The macro \ref _FLD2VAL uses the #define's _Pos and _Msk of the related bit + * field to extract the value of a bit field from a register. + * + * **Example**: + * \code + * nlbits = _FLD2VAL(CLIC_CLICCFG_NLBIT, ECLIC->CFG); + * \endcode + * \param[in] field Name of the register bit field. + * \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + * \return Masked and shifted bit field value. + */ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/** @} */ /* end of group NMSIS_Core_PeriphAccess */ + + +#endif /* __NMSIS_COMPILER_H */ + diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_core.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_core.h new file mode 100644 index 0000000..6346d12 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_core.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * -- Adaptable modifications made for Nuclei Processors. -- + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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. + */ +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#include "nmsis_version.h" + +/** + * \ingroup NMSIS_Core_VersionControl + * @{ + */ +/* The following macro __NUCLEI_N_REV/__NUCLEI_NX_REV/ + * __NUCLEI_CPU_REV/__NUCLEI_CPU_SERIES definition in this file + * is only used for doxygen documentation generation, + * The .h is the real file to define it by vendor + */ +#if defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__) +/** + * \brief Nuclei N class core revision number + * \details + * Reversion number format: [15:8] revision number, [7:0] patch number + * \attention + * Deprecated, this define is exclusive with \ref __NUCLEI_NX_REV + */ +#define __NUCLEI_N_REV (0x0309) +/** + * \brief Nuclei NX class core revision number + * \details + * Reversion number format: [15:8] revision number, [7:0] patch number + * \attention + * Deprecated, this define is exclusive with \ref __NUCLEI_N_REV + */ +#define __NUCLEI_NX_REV (0x0207) +/** + * \brief Nuclei CPU core revision number + * \details + * Nuclei RISC-V CPU Revision Number vX.Y.Z, eg. v3.10.1 + * \attention + * This define is exclusive with \ref __NUCLEI_CPU_SERIES + */ +#define __NUCLEI_CPU_REV (0x030A01) +/** + * \brief Nuclei CPU core series + * \details + * Nuclei RISC-V CPU Series Number, eg, 0x200, 0x300, 0x600, 0x900 + * for 200, 300, 600, 900 series. + * \attention + * This define is used together with \ref __NUCLEI_CPU_REV + */ +#define __NUCLEI_CPU_SERIES (0x0200) +#endif /* __ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__ */ +/** @} */ /* End of Group NMSIS_Core_VersionControl */ + +#include "nmsis_compiler.h" /* NMSIS compiler specific defines */ + +/* === Include Nuclei Core Related Headers === */ +/* Include core base feature header file */ +#include "core_feature_base.h" + +/* Include core fpu feature header file */ +#include "core_feature_fpu.h" +/* Include core dsp feature header file */ +#include "core_feature_dsp.h" +/* Include core vector feature header file */ +#include "core_feature_vector.h" +/* Include core bitmanip feature header file */ +#include "core_feature_bitmanip.h" +/* Include core pmp feature header file */ +#include "core_feature_pmp.h" +/* Include core spmp feature header file */ + #include "core_feature_spmp.h" +/* Include core cache feature header file */ +#include "core_feature_cache.h" +/* Include core cidu feature header file */ + #include "core_feature_cidu.h" + +/* Include compatiable functions header file */ +#include "core_compatiable.h" + +#ifndef __NMSIS_GENERIC +/* Include core eclic feature header file */ +#include "core_feature_eclic.h" +/* Include core plic feature header file */ +#include "core_feature_plic.h" +/* Include core systimer feature header file */ +#include "core_feature_timer.h" +#endif + +#ifdef __cplusplus +} +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_gcc.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_gcc.h new file mode 100644 index 0000000..100019d --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_gcc.h @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __NMSIS_GCC_H__ +#define __NMSIS_GCC_H__ +/*! + * @file nmsis_gcc.h + * @brief NMSIS compiler GCC header file + */ +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#include "riscv_encoding.h" + +/* ######################### Startup and Lowlevel Init ######################## */ +/** + * \defgroup NMSIS_Core_CompilerControl Compiler Control + * \ingroup NMSIS_Core + * \brief Compiler agnostic \#define symbols for generic c/c++ source code + * \details + * + * The NMSIS-Core provides the header file nmsis_compiler.h with consistent \#define symbols for generate C or C++ source files that should be compiler agnostic. + * Each NMSIS compliant compiler should support the functionality described in this section. + * + * The header file nmsis_compiler.h is also included by each Device Header File so that these definitions are available. + * @{ + */ + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* NMSIS compiler specific defines */ +/** \brief Pass information from the compiler to the assembler. */ +#ifndef __ASM + #define __ASM __asm +#endif + +/** \brief Recommend that function should be inlined by the compiler. */ +#ifndef __INLINE + #define __INLINE inline +#endif + +/** \brief Define a static function that may be inlined by the compiler. */ +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +/** \brief Define a static function that should be always inlined by the compiler. */ +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif + +/** \brief Inform the compiler that a function does not return. */ +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif + +/** \brief Inform that a variable shall be retained in executable image. */ +#ifndef __USED + #define __USED __attribute__((used)) +#endif + +/** \brief restrict pointer qualifier to enable additional optimizations. */ +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif + +/** \brief specified the vector size of the variable, measured in bytes */ +#ifndef __VECTOR_SIZE + #define __VECTOR_SIZE(x) __attribute__((vector_size(x))) +#endif + +/** \brief Request smallest possible alignment. */ +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif + +/** \brief Request smallest possible alignment for a structure. */ +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif + +/** \brief Request smallest possible alignment for a union. */ +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif + +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + /** \brief Packed struct for unaligned uint16_t write access */ + __PACKED_STRUCT T_UINT16_WRITE { + uint16_t v; + }; + #pragma GCC diagnostic pop + /** \brief Pointer for unaligned write of a uint16_t variable. */ + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif + +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + /** \brief Packed struct for unaligned uint16_t read access */ + __PACKED_STRUCT T_UINT16_READ { + uint16_t v; + }; + #pragma GCC diagnostic pop + /** \brief Pointer for unaligned read of a uint16_t variable. */ + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + /** \brief Packed struct for unaligned uint32_t write access */ + __PACKED_STRUCT T_UINT32_WRITE { + uint32_t v; + }; + #pragma GCC diagnostic pop + /** \brief Pointer for unaligned write of a uint32_t variable. */ + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif + +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + /** \brief Packed struct for unaligned uint32_t read access */ + __PACKED_STRUCT T_UINT32_READ { + uint32_t v; + }; + #pragma GCC diagnostic pop + /** \brief Pointer for unaligned read of a uint32_t variable. */ + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif + +/** \brief Minimum `x` bytes alignment for a variable. */ +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif + +/** \brief restrict pointer qualifier to enable additional optimizations. */ +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/** \brief Barrier to prevent compiler from reordering instructions. */ +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/** \brief provide the compiler with branch prediction information, the branch is usually true */ +#ifndef __USUALLY + #define __USUALLY(exp) __builtin_expect((exp), 1) +#endif + +/** \brief provide the compiler with branch prediction information, the branch is rarely true */ +#ifndef __RARELY + #define __RARELY(exp) __builtin_expect((exp), 0) +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */ +#ifndef __INTERRUPT + #define __INTERRUPT __attribute__((interrupt)) +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */ +#ifndef __MACHINE_INTERRUPT + #define __MACHINE_INTERRUPT __attribute__ ((interrupt ("machine"))) +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Supervisor Mode. */ +#ifndef __SUPERVISOR_INTERRUPT + #define __SUPERVISOR_INTERRUPT __attribute__ ((interrupt ("supervisor"))) +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in User Mode. */ +#ifndef __USER_INTERRUPT + #define __USER_INTERRUPT __attribute__ ((interrupt ("user"))) +#endif + +/** @} */ /* End of Doxygen Group NMSIS_Core_CompilerControl */ + +#ifdef __cplusplus +} +#endif +#endif /* __NMSIS_GCC_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_iar.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_iar.h new file mode 100644 index 0000000..8c5ffc0 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_iar.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __NMSIS_IAR_H__ +#define __NMSIS_IAR_H__ +/*! + * @file nmsis_iar.h + * @brief NMSIS compiler IAR header file + */ +#include + +#ifdef __cplusplus + extern "C" { +#endif + +#include "riscv_encoding.h" + +/* ######################### Startup and Lowlevel Init ######################## */ +/** + * \defgroup NMSIS_Core_CompilerControl Compiler Control + * \ingroup NMSIS_Core + * \brief Compiler agnostic \#define symbols for generic c/c++ source code + * \details + * + * The NMSIS-Core provides the header file nmsis_compiler.h with consistent \#define symbols for generate C or C++ source files that should be compiler agnostic. + * Each NMSIS compliant compiler should support the functionality described in this section. + * + * The header file nmsis_compiler.h is also included by each Device Header File so that these definitions are available. + * @{ + */ + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* NMSIS compiler specific defines */ +/** \brief Pass information from the compiler to the assembler. */ +#ifndef __ASM + #define __ASM __asm +#endif + +/** \brief Recommend that function should be inlined by the compiler. */ +#ifndef __INLINE + #define __INLINE inline +#endif + +/** \brief Define a static function that may be inlined by the compiler. */ +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +/** \brief Define a static function that should be always inlined by the compiler. */ +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif + +/** \brief Inform the compiler that a function does not return. */ +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif + +/** \brief Inform that a variable shall be retained in executable image. */ +#ifndef __USED + #define __USED __attribute__((used)) +#endif + +/** \brief restrict pointer qualifier to enable additional optimizations. */ +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif + +/** \brief specified the vector size of the variable, measured in bytes, not supported in IAR */ +#ifndef __VECTOR_SIZE + #define __VECTOR_SIZE(x) +#endif + +/** \brief Request smallest possible alignment. */ +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif + +/** \brief Request smallest possible alignment for a structure. */ +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif + +/** \brief Request smallest possible alignment for a union. */ +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif + +#ifndef __UNALIGNED_UINT16_WRITE + #pragma language=save + #pragma language=extended + /** \brief Packed struct for unaligned uint16_t write access */ + __PACKED_STRUCT T_UINT16_WRITE { + uint16_t v; + }; + #pragma language=restore + /** \brief Pointer for unaligned write of a uint16_t variable. */ + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif + +#ifndef __UNALIGNED_UINT16_READ + #pragma language=save + #pragma language=extended + /** \brief Packed struct for unaligned uint16_t read access */ + __PACKED_STRUCT T_UINT16_READ { + uint16_t v; + }; + #pragma language=restore + /** \brief Pointer for unaligned read of a uint16_t variable. */ + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE + #pragma language=save + #pragma language=extended + /** \brief Packed struct for unaligned uint32_t write access */ + __PACKED_STRUCT T_UINT32_WRITE { + uint32_t v; + }; + #pragma language=restore + /** \brief Pointer for unaligned write of a uint32_t variable. */ + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif + +#ifndef __UNALIGNED_UINT32_READ + #pragma language=save + #pragma language=extended + /** \brief Packed struct for unaligned uint32_t read access */ + __PACKED_STRUCT T_UINT32_READ { + uint32_t v; + }; + #pragma language=restore + /** \brief Pointer for unaligned read of a uint32_t variable. */ + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif + +/** \brief Minimum `x` bytes alignment for a variable. */ +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif + +/** \brief restrict pointer qualifier to enable additional optimizations. */ +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/** \brief Barrier to prevent compiler from reordering instructions. */ +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/** \brief provide the compiler with branch prediction information, the branch is usually true */ +#ifndef __USUALLY + #define __USUALLY(exp) (exp) +#endif + +/** \brief provide the compiler with branch prediction information, the branch is rarely true */ +#ifndef __RARELY + #define __RARELY(exp) (exp) +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */ +#ifndef __INTERRUPT + #define __INTERRUPT __machine __interrupt +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Machine Mode. */ +#ifndef __MACHINE_INTERRUPT + #define __MACHINE_INTERRUPT __machine __interrupt +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in Supervisor Mode. */ +#ifndef __SUPERVISOR_INTERRUPT + #define __SUPERVISOR_INTERRUPT __supervisor __interrupt +#endif + +/** \brief Use this attribute to indicate that the specified function is an interrupt handler run in User Mode. */ +#ifndef __USER_INTERRUPT + #define __USER_INTERRUPT __user __interrupt +#endif + +/** @} */ /* End of Doxygen Group NMSIS_Core_CompilerControl */ + +#ifdef __cplusplus +} +#endif +#endif /* __NMSIS_GCC_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_version.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_version.h new file mode 100644 index 0000000..7c2f5b4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/nmsis_version.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __NMSIS_VERSION_H +#define __NMSIS_VERSION_H + +/** + * \defgroup NMSIS_Core_VersionControl Version Control + * \ingroup NMSIS_Core + * \brief Version \#define symbols for NMSIS release specific C/C++ source code + * \details + * + * We followed the [semantic versioning 2.0.0](https://semver.org/) to control NMSIS version. + * The version format is **MAJOR.MINOR.PATCH**, increment the: + * 1. MAJOR version when you make incompatible API changes, + * 2. MINOR version when you add functionality in a backwards compatible manner, and + * 3. PATCH version when you make backwards compatible bug fixes. + * + * The header file `nmsis_version.h` is included by each core header so that these definitions are available. + * + * **Example Usage for NMSIS Version Check**: + * \code + * #if defined(__NMSIS_VERSION) && (__NMSIS_VERSION >= 0x00010105) + * #warning "Yes, we have NMSIS 1.1.5 or later" + * #else + * #error "We need NMSIS 1.1.5 or later!" + * #endif + * \endcode + * + * @{ + */ + +/*! + * \file nmsis_version.h + * \brief NMSIS Version definitions + **/ + +/** + * \brief Represent the NMSIS major version + * \details + * The NMSIS major version can be used to + * differentiate between NMSIS major releases. + * */ +#define __NMSIS_VERSION_MAJOR (1U) + +/** + * \brief Represent the NMSIS minor version + * \details + * The NMSIS minor version can be used to + * query a NMSIS release update including new features. + * + **/ +#define __NMSIS_VERSION_MINOR (3U) + +/** + * \brief Represent the NMSIS patch version + * \details + * The NMSIS patch version can be used to + * show bug fixes in this package. + **/ +#define __NMSIS_VERSION_PATCH (1U) +/** + * \brief Represent the NMSIS Version + * \details + * NMSIS Version format: **MAJOR.MINOR.PATCH** + * * MAJOR: \ref __NMSIS_VERSION_MAJOR, stored in `bits [31:16]` of \ref __NMSIS_VERSION + * * MINOR: \ref __NMSIS_VERSION_MINOR, stored in `bits [15:8]` of \ref __NMSIS_VERSION + * * PATCH: \ref __NMSIS_VERSION_PATCH, stored in `bits [7:0]` of \ref __NMSIS_VERSION + **/ +#define __NMSIS_VERSION ((__NMSIS_VERSION_MAJOR << 16U) | (__NMSIS_VERSION_MINOR << 8) | __NMSIS_VERSION_PATCH) + +/** @} */ /* End of Doxygen Group NMSIS_Core_VersionControl */ +#endif diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_bits.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_bits.h new file mode 100644 index 0000000..75550e7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_bits.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __RISCV_BITS_H__ +#define __RISCV_BITS_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +#if __riscv_xlen == 64 +# define SLL32 sllw +# define STORE sd +# define LOAD ld +# define LWU lwu +# define LOG_REGBYTES 3 +#else +# define SLL32 sll +# define STORE sw +# define LOAD lw +# define LWU lw +# define LOG_REGBYTES 2 +#endif /* __riscv_xlen */ + +#define REGBYTES (1 << LOG_REGBYTES) + +#if defined(__riscv_flen) +#if __riscv_flen == 64 +# define FPSTORE fsd +# define FPLOAD fld +# define LOG_FPREGBYTES 3 +#else +# define FPSTORE fsw +# define FPLOAD flw +# define LOG_FPREGBYTES 2 +#endif /* __riscv_flen == 64 */ +#define FPREGBYTES (1 << LOG_FPREGBYTES) +#endif /* __riscv_flen */ + +#ifdef __GNUC__ +#define __rv_likely(x) __builtin_expect((x), 1) +#define __rv_unlikely(x) __builtin_expect((x), 0) +#else +#define __rv_likely(x) (x) +#define __rv_unlikely(x) (x) +#endif + +#define __RV_ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b)) +#define __RV_ROUNDDOWN(a, b) ((a)/(b)*(b)) + +#define __RV_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define __RV_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define __RV_CLAMP(a, lo, hi) __RV_MIN(__RV_MAX(a, lo), hi) + +#define __RV_EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1))) +#define __RV_INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1)))) + +#ifdef __ASSEMBLY__ +#define _AC(X,Y) X +#define _AT(T,X) X +#else +#define __AC(X,Y) (X##Y) +#define _AC(X,Y) __AC(X,Y) +#define _AT(T,X) ((T)(X)) +#endif /* __ASSEMBLY__ */ + +#define _UL(x) (_AC(x, UL)) +#define _ULL(x) (_AC(x, ULL)) + +#define _BITUL(x) (_UL(1) << (x)) +#define _BITULL(x) (_ULL(1) << (x)) + +#define UL(x) (_UL(x)) +#define ULL(x) (_ULL(x)) + +#define STR(x) XSTR(x) +#define XSTR(x) #x +#define __STR(s) #s +#define STRINGIFY(s) __STR(s) + +#ifdef __cplusplus +} +#endif + +#endif /* __RISCV_BITS_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_encoding.h b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_encoding.h new file mode 100644 index 0000000..72fba8f --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/NMSIS/Core/Include/riscv_encoding.h @@ -0,0 +1,1104 @@ +/* + * Copyright (c) 2019 Nuclei Limited. All rights reserved. + * + * 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 + * + * 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 __RISCV_ENCODING_H__ +#define __RISCV_ENCODING_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "riscv_bits.h" + +/** + * \defgroup NMSIS_Core_CSR_Encoding Core CSR Encodings + * \ingroup NMSIS_Core + * \brief NMSIS Core CSR Encodings + * \details + * + * The following macros are used for CSR encodings + * @{ + */ +/* === Standard CSR bit mask === */ +#define MSTATUS_UIE 0x00000001 +#define MSTATUS_SIE 0x00000002 +#define MSTATUS_HIE 0x00000004 +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_UPIE 0x00000010 +#define MSTATUS_SPIE 0x00000020 +#define MSTATUS_UBE 0x00000040 +#define MSTATUS_MPIE 0x00000080 +#define MSTATUS_SPP 0x00000100 +#define MSTATUS_VS 0x00000600 +#define MSTATUS_MPP 0x00001800 +#define MSTATUS_FS 0x00006000 +#define MSTATUS_XS 0x00018000 +#define MSTATUS_MPRV 0x00020000 +#define MSTATUS_SUM 0x00040000 +#define MSTATUS_MXR 0x00080000 +#define MSTATUS_TVM 0x00100000 +#define MSTATUS_TW 0x00200000 +#define MSTATUS_TSR 0x00400000 +#define MSTATUS32_SD 0x80000000 +#define MSTATUS_UXL 0x0000000300000000 +#define MSTATUS_SXL 0x0000000C00000000 +#define MSTATUS_SBE 0x0000001000000000 +#define MSTATUS_MBE 0x0000002000000000 +#define MSTATUS_GVA 0x0000004000000000 +#define MSTATUS_MPV 0x0000008000000000 +#define MSTATUS64_SD 0x8000000000000000 + +#define MSTATUS_FS_INITIAL 0x00002000 +#define MSTATUS_FS_CLEAN 0x00004000 +#define MSTATUS_FS_DIRTY 0x00006000 + +#define MSTATUS_VS_INITIAL 0x00000200 +#define MSTATUS_VS_CLEAN 0x00000400 +#define MSTATUS_VS_DIRTY 0x00000600 + +#define MSTATUSH_SBE 0x00000010 +#define MSTATUSH_MBE 0x00000020 +#define MSTATUSH_GVA 0x00000040 +#define MSTATUSH_MPV 0x00000080 + +#define SSTATUS_UIE 0x00000001 +#define SSTATUS_SIE 0x00000002 +#define SSTATUS_UPIE 0x00000010 +#define SSTATUS_SPIE 0x00000020 +#define SSTATUS_UBE 0x00000040 +#define SSTATUS_SPP 0x00000100 +#define SSTATUS_VS 0x00000600 +#define SSTATUS_FS 0x00006000 +#define SSTATUS_XS 0x00018000 +#define SSTATUS_SUM 0x00040000 +#define SSTATUS_MXR 0x00080000 +#define SSTATUS32_SD 0x80000000 +#define SSTATUS_UXL 0x0000000300000000 +#define SSTATUS64_SD 0x8000000000000000 + +#define USTATUS_UIE 0x00000001 +#define USTATUS_UPIE 0x00000010 + +#define DCSR_XDEBUGVER (3U<<30) +#define DCSR_NDRESET (1<<29) +#define DCSR_FULLRESET (1<<28) +#define DCSR_EBREAKM (1<<15) +#define DCSR_EBREAKH (1<<14) +#define DCSR_EBREAKS (1<<13) +#define DCSR_EBREAKU (1<<12) +#define DCSR_STOPCYCLE (1<<10) +#define DCSR_STOPTIME (1<<9) +#define DCSR_CAUSE (7<<6) +#define DCSR_DEBUGINT (1<<5) +#define DCSR_HALT (1<<3) +#define DCSR_STEP (1<<2) +#define DCSR_PRV (3<<0) + +#define DCSR_CAUSE_NONE 0 +#define DCSR_CAUSE_SWBP 1 +#define DCSR_CAUSE_HWBP 2 +#define DCSR_CAUSE_DEBUGINT 3 +#define DCSR_CAUSE_STEP 4 +#define DCSR_CAUSE_HALT 5 + +#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4)) +#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5)) +#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11)) + +#define MCONTROL_SELECT (1<<19) +#define MCONTROL_TIMING (1<<18) +#define MCONTROL_ACTION (0x3f<<12) +#define MCONTROL_CHAIN (1<<11) +#define MCONTROL_MATCH (0xf<<7) +#define MCONTROL_M (1<<6) +#define MCONTROL_H (1<<5) +#define MCONTROL_S (1<<4) +#define MCONTROL_U (1<<3) +#define MCONTROL_EXECUTE (1<<2) +#define MCONTROL_STORE (1<<1) +#define MCONTROL_LOAD (1<<0) + +#define MCONTROL_TYPE_NONE 0 +#define MCONTROL_TYPE_MATCH 2 + +#define MCONTROL_ACTION_DEBUG_EXCEPTION 0 +#define MCONTROL_ACTION_DEBUG_MODE 1 +#define MCONTROL_ACTION_TRACE_START 2 +#define MCONTROL_ACTION_TRACE_STOP 3 +#define MCONTROL_ACTION_TRACE_EMIT 4 + +#define MCONTROL_MATCH_EQUAL 0 +#define MCONTROL_MATCH_NAPOT 1 +#define MCONTROL_MATCH_GE 2 +#define MCONTROL_MATCH_LT 3 +#define MCONTROL_MATCH_MASK_LOW 4 +#define MCONTROL_MATCH_MASK_HIGH 5 + +#define MIP_SSIP (1 << IRQ_S_SOFT) +#define MIP_HSIP (1 << IRQ_H_SOFT) +#define MIP_MSIP (1 << IRQ_M_SOFT) +#define MIP_STIP (1 << IRQ_S_TIMER) +#define MIP_HTIP (1 << IRQ_H_TIMER) +#define MIP_MTIP (1 << IRQ_M_TIMER) +#define MIP_SEIP (1 << IRQ_S_EXT) +#define MIP_HEIP (1 << IRQ_H_EXT) +#define MIP_MEIP (1 << IRQ_M_EXT) + +#define MIE_SSIE MIP_SSIP +#define MIE_HSIE MIP_HSIP +#define MIE_MSIE MIP_MSIP +#define MIE_STIE MIP_STIP +#define MIE_HTIE MIP_HTIP +#define MIE_MTIE MIP_MTIP +#define MIE_SEIE MIP_SEIP +#define MIE_HEIE MIP_HEIP +#define MIE_MEIE MIP_MEIP + +#define SIP_SSIP MIP_SSIP +#define SIP_STIP MIP_STIP +#define SIP_SEIP MIP_SEIP + +#define SIE_SSIE MIP_SSIP +#define SIE_STIE MIP_STIP +#define SIE_SEIE MIP_SEIP + +#define MCAUSE_INTR (1ULL << (__riscv_xlen - 1)) +#define MCAUSE_CAUSE 0x00000FFFUL +#define SCAUSE_INTR MCAUSE_INTR +#define SCAUSE_CAUSE 0x000003FFUL + +#define MENVCFG_CBIE_EN (0x11 << 4) +#define MENVCFG_CBIE_FLUSH (0x01 << 4) +#define MENVCFG_CBIE_INVAL (0x11 << 4) +#define MENVCFG_CBCFE (0x1 << 6) +#define MENVCFG_CBZE (0x1 << 7) +#define SENVCFG_CBIE_EN (0x11 << 4) +#define SENVCFG_CBIE_FLUSH (0x01 << 4) +#define SENVCFG_CBIE_INVAL (0x11 << 4) +#define SENVCFG_CBCFE (0x1 << 6) +#define SENVCFG_CBZE (0x1 << 7) + +/* === P-ext CSR bit mask === */ + +#define UCODE_OV (0x1) + +/* === Nuclei custom CSR bit mask === */ +#define CSR_MCACHE_CTL_IE 0x00000001 +#define CSR_MCACHE_CTL_DE 0x00010000 + +#define WFE_WFE (0x1) +#define TXEVT_TXEVT (0x1) +#define SLEEPVALUE_SLEEPVALUE (0x1) + +#define MCOUNTINHIBIT_IR (1<<2) +#define MCOUNTINHIBIT_CY (1<<0) + +#define MILM_CTL_ILM_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10) +#define MILM_CTL_ILM_ECC_CHK_EN (1<<4) +#define MILM_CTL_ILM_RWECC (1<<3) +#define MILM_CTL_ILM_ECC_INJ_EN (1<<3) +#define MILM_CTL_ILM_ECC_EXCP_EN (1<<2) +#define MILM_CTL_ILM_ECC_EN (1<<1) +#define MILM_CTL_ILM_EN (1<<0) + +#define MDLM_CTL_DLM_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10) +#define MDLM_CTL_DLM_ECC_CHK_EN (1<<4) +#define MDLM_CTL_DLM_RWECC (1<<3) +#define MDLM_CTL_DLM_ECC_INJ_EN (1<<3) +#define MDLM_CTL_DLM_ECC_EXCP_EN (1<<2) +#define MDLM_CTL_DLM_ECC_EN (1<<1) +#define MDLM_CTL_DLM_EN (1<<0) + +#define MSUBM_PTYP (0x3<<8) +#define MSUBM_TYP (0x3<<6) + +#define MDCAUSE_MDCAUSE (0x7) + +#define MMISC_CTL_LDSPEC_ENABLE (1<<12) +#define MMISC_CTL_SIJUMP_ENABLE (1<<11) +#define MMISC_CTL_IMRETURN_ENABLE (1<<10) +#define MMISC_CTL_NMI_CAUSE_FFF (1<<9) +#define MMISC_CTL_CODE_BUS_ERR (1<<8) +#define MMISC_CTL_MISALIGN (1<<6) +#define MMISC_CTL_ZC (1<<7) +#define MMISC_CTL_BPU (1<<3) + +#define MCACHE_CTL_IC_EN (1<<0) +#define MCACHE_CTL_IC_SCPD_MOD (1<<1) +#define MCACHE_CTL_IC_ECC_EN (1<<2) +#define MCACHE_CTL_IC_ECC_EXCP_EN (1<<3) +#define MCACHE_CTL_IC_TRAM_ECC_INJ_EN (1<<4) +#define MCACHE_CTL_IC_RWTECC (1<<4) +#define MCACHE_CTL_IC_RWDECC (1<<5) +#define MCACHE_CTL_IC_DRAM_ECC_INJ_EN (1<<5) +#define MCACHE_CTL_IC_PF_EN (1<<6) +#define MCACHE_CTL_IC_CANCEL_EN (1<<7) +#define MCACHE_CTL_IC_ECC_CHK_EN (1<<8) +#define MCACHE_CTL_DC_EN (1<<16) +#define MCACHE_CTL_DC_ECC_EN (1<<17) +#define MCACHE_CTL_DC_ECC_EXCP_EN (1<<18) +#define MCACHE_CTL_DC_TRAM_ECC_INJ_EN (1<<19) +#define MCACHE_CTL_DC_RWTECC (1<<19) +#define MCACHE_CTL_DC_RWDECC (1<<20) +#define MCACHE_CTL_DC_DRAM_ECC_INJ_EN (1<<20) +#define MCACHE_CTL_DC_ECC_CHK_EN (1<<21) + +#define MTVT2_MTVT2EN (1<<0) +#define MTVT2_COMMON_CODE_ENTRY (((1ULL<<((__riscv_xlen)-2))-1)<<2) + +#define MCFG_INFO_TEE (1<<0) +#define MCFG_INFO_ECC (1<<1) +#define MCFG_INFO_CLIC (1<<2) +#define MCFG_INFO_PLIC (1<<3) +#define MCFG_INFO_FIO (1<<4) +#define MCFG_INFO_PPI (1<<5) +#define MCFG_INFO_NICE (1<<6) +#define MCFG_INFO_ILM (1<<7) +#define MCFG_INFO_DLM (1<<8) +#define MCFG_INFO_ICACHE (1<<9) +#define MCFG_INFO_DCACHE (1<<10) +#define MCFG_INFO_SMP (1<<11) +#define MCFG_INFO_DSP_N1 (1<<12) +#define MCFG_INFO_DSP_N2 (1<<13) +#define MCFG_INFO_DSP_N3 (1<<14) +#define MCFG_INFO_IREGION_EXIST (1<<16) +#define MCFG_INFO_VP (0x3<<17) + +#define MICFG_IC_SET (0xF<<0) +#define MICFG_IC_WAY (0x7<<4) +#define MICFG_IC_LSIZE (0x7<<7) +#define MICFG_IC_ECC (0x1<<10) +#define MICFG_ILM_SIZE (0x1F<<16) +#define MICFG_ILM_XONLY (0x1<<21) +#define MICFG_ILM_ECC (0x1<<22) + +#define MDCFG_DC_SET (0xF<<0) +#define MDCFG_DC_WAY (0x7<<4) +#define MDCFG_DC_LSIZE (0x7<<7) +#define MDCFG_DC_ECC (0x1<<10) +#define MDCFG_DLM_SIZE (0x1F<<16) +#define MDCFG_DLM_ECC (0x1<<21) + +#define MIRGB_INFO_IRG_BASE_ADDR_BOFS (10) +#define MIRGB_INFO_IREGION_SIZE_BOFS (1) + +#define MPPICFG_INFO_PPI_SIZE (0x1F<<1) +#define MPPICFG_INFO_PPI_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10) + +#define MFIOCFG_INFO_FIO_SIZE (0x1F<<1) +#define MFIOCFG_INFO_FIO_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10) + +#define MECC_LOCK_ECC_LOCK (0x1) + +#define MECC_CODE_CODE (0x1FF) +#define MECC_CODE_RAMID (0x1F<<16) +#define MECC_CODE_SRAMID (0x1F<<24) + +#define CCM_SUEN_SUEN (0x1<<0) +#define CCM_DATA_DATA (0x7<<0) +#define CCM_COMMAND_COMMAND (0x1F<<0) + +/* IREGION Offsets */ +#define IREGION_IINFO_OFS (0x0) +#define IREGION_DEBUG_OFS (0x10000) +#define IREGION_ECLIC_OFS (0x20000) +#define IREGION_TIMER_OFS (0x30000) +#define IREGION_SMP_OFS (0x40000) +#define IREGION_IDU_OFS (0x50000) +#define IREGION_PL2_OFS (0x60000) +#define IREGION_DPREFETCH_OFS (0x70000) +#define IREGION_PLIC_OFS (0x4000000) + +/* === Stack protect === */ +#define MSTACK_CTRL_MODE (0x1<<2) +#define MSTACK_CTRL_UDF_EN (0x1<<1) +#define MSTACK_CTRL_OVF_TRACK_EN (0x1) + +#define SIP_SSIP MIP_SSIP +#define SIP_STIP MIP_STIP + +#define PRV_U 0 +#define PRV_S 1 +#define PRV_H 2 +#define PRV_M 3 + +#define VM_MBARE 0 +#define VM_MBB 1 +#define VM_MBBID 2 +#define VM_SV32 8 +#define VM_SV39 9 +#define VM_SV48 10 + +#define SATP32_MODE 0x80000000 +#define SATP32_ASID 0x7FC00000 +#define SATP32_PPN 0x003FFFFF +#define SATP64_MODE 0xF000000000000000 +#define SATP64_ASID 0x0FFFF00000000000 +#define SATP64_PPN 0x00000FFFFFFFFFFF + +#define SATP_MODE_OFF 0 +#define SATP_MODE_SV32 1 +#define SATP_MODE_SV39 8 +#define SATP_MODE_SV48 9 +#define SATP_MODE_SV57 10 +#define SATP_MODE_SV64 11 + +#define IRQ_S_SOFT 1 +#define IRQ_H_SOFT 2 +#define IRQ_M_SOFT 3 +#define IRQ_S_TIMER 5 +#define IRQ_H_TIMER 6 +#define IRQ_M_TIMER 7 +#define IRQ_S_EXT 9 +#define IRQ_H_EXT 10 +#define IRQ_M_EXT 11 +#define IRQ_COP 12 +#define IRQ_HOST 13 + + +/* === FPU FRM Rounding Mode === */ +/** FPU Round to Nearest, ties to Even*/ +#define FRM_RNDMODE_RNE 0x0 +/** FPU Round Towards Zero */ +#define FRM_RNDMODE_RTZ 0x1 +/** FPU Round Down (towards -inf) */ +#define FRM_RNDMODE_RDN 0x2 +/** FPU Round Up (towards +inf) */ +#define FRM_RNDMODE_RUP 0x3 +/** FPU Round to nearest, ties to Max Magnitude */ +#define FRM_RNDMODE_RMM 0x4 +/** + * In instruction's rm, selects dynamic rounding mode. + * In Rounding Mode register, Invalid */ +#define FRM_RNDMODE_DYN 0x7 + +/* === FPU FFLAGS Accrued Exceptions === */ +/** FPU Inexact */ +#define FFLAGS_AE_NX (1<<0) +/** FPU Underflow */ +#define FFLAGS_AE_UF (1<<1) +/** FPU Overflow */ +#define FFLAGS_AE_OF (1<<2) +/** FPU Divide by Zero */ +#define FFLAGS_AE_DZ (1<<3) +/** FPU Invalid Operation */ +#define FFLAGS_AE_NV (1<<4) + +/** Floating Point Register f0-f31, eg. f0 -> FREG(0) */ +#define FREG(idx) f##idx + + +/* === PMP CFG Bits === */ +#define PMP_R 0x01 +#define PMP_W 0x02 +#define PMP_X 0x04 +#define PMP_A 0x18 +#define PMP_A_TOR 0x08 +#define PMP_A_NA4 0x10 +#define PMP_A_NAPOT 0x18 +#define PMP_L 0x80 + +#define PMP_SHIFT 2 +#define PMP_COUNT 16 + +/* === sPMP CFG Bits === */ +#define SPMP_R PMP_R +#define SPMP_W PMP_W +#define SPMP_X PMP_X +#define SPMP_A PMP_A +#define SPMP_A_TOR PMP_A_TOR +#define SPMP_A_NA4 PMP_A_NA4 +#define SPMP_A_NAPOT PMP_A_NAPOT +#define SPMP_U 0x40 +#define SPMP_L PMP_L + +#define SPMP_SHIFT PMP_SHIFT +#define SPMP_COUNT 16 + +/* === SMPU CFG Bits === */ +#define SMPU_R SPMP_R +#define SMPU_W SPMP_W +#define SMPU_X SPMP_X +#define SMPU_A SPMP_A +#define SMPU_A_TOR SPMP_A_TOR +#define SMPU_A_NA4 SPMP_A_NA4 +#define SMPU_A_NAPOT SPMP_A_NAPOT +#define SMPU_S 0x80 + +#define SMPU_SHIFT PMP_SHIFT + +// page table entry (PTE) fields +#define PTE_V 0x001 // Valid +#define PTE_R 0x002 // Read +#define PTE_W 0x004 // Write +#define PTE_X 0x008 // Execute +#define PTE_U 0x010 // User +#define PTE_G 0x020 // Global +#define PTE_A 0x040 // Accessed +#define PTE_D 0x080 // Dirty +#define PTE_SOFT 0x300 // Reserved for Software + +#define PTE_PPN_SHIFT 10 + +#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V) + +#ifdef __riscv + +#ifdef __riscv64 +# define MSTATUS_SD MSTATUS64_SD +# define SSTATUS_SD SSTATUS64_SD +# define RISCV_PGLEVEL_BITS 9 +#else +# define MSTATUS_SD MSTATUS32_SD +# define SSTATUS_SD SSTATUS32_SD +# define RISCV_PGLEVEL_BITS 10 +#endif /* __riscv64 */ + +#define RISCV_PGSHIFT 12 +#define RISCV_PGSIZE (1 << RISCV_PGSHIFT) + +#endif /* __riscv */ + +/** + * \defgroup NMSIS_Core_CSR_Registers Core CSR Registers + * \ingroup NMSIS_Core + * \brief NMSIS Core CSR Register Definitions + * \details + * + * The following macros are used for CSR Register Defintions. + * @{ + */ +/* === Standard RISC-V CSR Registers === */ +#define CSR_USTATUS 0x0 +#define CSR_FFLAGS 0x1 +#define CSR_FRM 0x2 +#define CSR_FCSR 0x3 +#define CSR_VSTART 0x8 +#define CSR_VXSAT 0x9 +#define CSR_VXRM 0xa +#define CSR_VCSR 0xf +#define CSR_SEED 0x15 +#define CSR_JVT 0x17 +#define CSR_CYCLE 0xc00 +#define CSR_TIME 0xc01 +#define CSR_INSTRET 0xc02 +#define CSR_HPMCOUNTER3 0xc03 +#define CSR_HPMCOUNTER4 0xc04 +#define CSR_HPMCOUNTER5 0xc05 +#define CSR_HPMCOUNTER6 0xc06 +#define CSR_HPMCOUNTER7 0xc07 +#define CSR_HPMCOUNTER8 0xc08 +#define CSR_HPMCOUNTER9 0xc09 +#define CSR_HPMCOUNTER10 0xc0a +#define CSR_HPMCOUNTER11 0xc0b +#define CSR_HPMCOUNTER12 0xc0c +#define CSR_HPMCOUNTER13 0xc0d +#define CSR_HPMCOUNTER14 0xc0e +#define CSR_HPMCOUNTER15 0xc0f +#define CSR_HPMCOUNTER16 0xc10 +#define CSR_HPMCOUNTER17 0xc11 +#define CSR_HPMCOUNTER18 0xc12 +#define CSR_HPMCOUNTER19 0xc13 +#define CSR_HPMCOUNTER20 0xc14 +#define CSR_HPMCOUNTER21 0xc15 +#define CSR_HPMCOUNTER22 0xc16 +#define CSR_HPMCOUNTER23 0xc17 +#define CSR_HPMCOUNTER24 0xc18 +#define CSR_HPMCOUNTER25 0xc19 +#define CSR_HPMCOUNTER26 0xc1a +#define CSR_HPMCOUNTER27 0xc1b +#define CSR_HPMCOUNTER28 0xc1c +#define CSR_HPMCOUNTER29 0xc1d +#define CSR_HPMCOUNTER30 0xc1e +#define CSR_HPMCOUNTER31 0xc1f +#define CSR_VL 0xc20 +#define CSR_VTYPE 0xc21 +#define CSR_VLENB 0xc22 +#define CSR_SSTATUS 0x100 +#define CSR_SEDELEG 0x102 +#define CSR_SIDELEG 0x103 +#define CSR_SIE 0x104 +#define CSR_STVEC 0x105 +#define CSR_STVT 0x107 +#define CSR_SCOUNTEREN 0x106 +#define CSR_SENVCFG 0x10a +#define CSR_SSTATEEN0 0x10c +#define CSR_SSTATEEN1 0x10d +#define CSR_SSTATEEN2 0x10e +#define CSR_SSTATEEN3 0x10f +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SCAUSE 0x142 +#define CSR_STVAL 0x143 +#define CSR_SIP 0x144 +#define CSR_STIMECMP 0x14d +#define CSR_SATP 0x180 +#define CSR_SCONTEXT 0x5a8 +#define CSR_VSSTATUS 0x200 +#define CSR_VSIE 0x204 +#define CSR_VSTVEC 0x205 +#define CSR_VSSCRATCH 0x240 +#define CSR_VSEPC 0x241 +#define CSR_VSCAUSE 0x242 +#define CSR_VSTVAL 0x243 +#define CSR_VSIP 0x244 +#define CSR_VSTIMECMP 0x24d +#define CSR_VSATP 0x280 +#define CSR_HSTATUS 0x600 +#define CSR_HEDELEG 0x602 +#define CSR_HIDELEG 0x603 +#define CSR_HIE 0x604 +#define CSR_HTIMEDELTA 0x605 +#define CSR_HCOUNTEREN 0x606 +#define CSR_HGEIE 0x607 +#define CSR_HENVCFG 0x60a +#define CSR_HSTATEEN0 0x60c +#define CSR_HSTATEEN1 0x60d +#define CSR_HSTATEEN2 0x60e +#define CSR_HSTATEEN3 0x60f +#define CSR_HTVAL 0x643 +#define CSR_HIP 0x644 +#define CSR_HVIP 0x645 +#define CSR_HTINST 0x64a +#define CSR_HGATP 0x680 +#define CSR_HCONTEXT 0x6a8 +#define CSR_HGEIP 0xe12 +#define CSR_SCOUNTOVF 0xda0 +#define CSR_UTVT 0x7 +#define CSR_UNXTI 0x45 +#define CSR_UINTSTATUS 0x46 +#define CSR_USCRATCHCSW 0x48 +#define CSR_USCRATCHCSWL 0x49 +#define CSR_STVT 0x107 +#define CSR_SNXTI 0x145 +#define CSR_SINTSTATUS 0x146 +#define CSR_SSCRATCHCSW 0x148 +#define CSR_SSCRATCHCSWL 0x149 +#define CSR_MTVT 0x307 +#define CSR_MNXTI 0x345 +#define CSR_MINTSTATUS 0x346 +#define CSR_MSCRATCHCSW 0x348 +#define CSR_MSCRATCHCSWL 0x349 +#define CSR_MSTATUS 0x300 +#define CSR_MISA 0x301 +#define CSR_MEDELEG 0x302 +#define CSR_MIDELEG 0x303 +#define CSR_MIE 0x304 +#define CSR_MTVEC 0x305 +#define CSR_MCOUNTEREN 0x306 +#define CSR_MENVCFG 0x30a +#define CSR_MSTATEEN0 0x30c +#define CSR_MSTATEEN1 0x30d +#define CSR_MSTATEEN2 0x30e +#define CSR_MSTATEEN3 0x30f +#define CSR_MCOUNTINHIBIT 0x320 +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MTVAL 0x343 +#define CSR_MBADADDR 0x343 +#define CSR_MIP 0x344 +#define CSR_MTINST 0x34a +#define CSR_MTVAL2 0x34b +#define CSR_PMPCFG0 0x3a0 +#define CSR_PMPCFG1 0x3a1 +#define CSR_PMPCFG2 0x3a2 +#define CSR_PMPCFG3 0x3a3 +#define CSR_PMPCFG4 0x3a4 +#define CSR_PMPCFG5 0x3a5 +#define CSR_PMPCFG6 0x3a6 +#define CSR_PMPCFG7 0x3a7 +#define CSR_PMPCFG8 0x3a8 +#define CSR_PMPCFG9 0x3a9 +#define CSR_PMPCFG10 0x3aa +#define CSR_PMPCFG11 0x3ab +#define CSR_PMPCFG12 0x3ac +#define CSR_PMPCFG13 0x3ad +#define CSR_PMPCFG14 0x3ae +#define CSR_PMPCFG15 0x3af +#define CSR_PMPADDR0 0x3b0 +#define CSR_PMPADDR1 0x3b1 +#define CSR_PMPADDR2 0x3b2 +#define CSR_PMPADDR3 0x3b3 +#define CSR_PMPADDR4 0x3b4 +#define CSR_PMPADDR5 0x3b5 +#define CSR_PMPADDR6 0x3b6 +#define CSR_PMPADDR7 0x3b7 +#define CSR_PMPADDR8 0x3b8 +#define CSR_PMPADDR9 0x3b9 +#define CSR_PMPADDR10 0x3ba +#define CSR_PMPADDR11 0x3bb +#define CSR_PMPADDR12 0x3bc +#define CSR_PMPADDR13 0x3bd +#define CSR_PMPADDR14 0x3be +#define CSR_PMPADDR15 0x3bf +#define CSR_PMPADDR16 0x3c0 +#define CSR_PMPADDR17 0x3c1 +#define CSR_PMPADDR18 0x3c2 +#define CSR_PMPADDR19 0x3c3 +#define CSR_PMPADDR20 0x3c4 +#define CSR_PMPADDR21 0x3c5 +#define CSR_PMPADDR22 0x3c6 +#define CSR_PMPADDR23 0x3c7 +#define CSR_PMPADDR24 0x3c8 +#define CSR_PMPADDR25 0x3c9 +#define CSR_PMPADDR26 0x3ca +#define CSR_PMPADDR27 0x3cb +#define CSR_PMPADDR28 0x3cc +#define CSR_PMPADDR29 0x3cd +#define CSR_PMPADDR30 0x3ce +#define CSR_PMPADDR31 0x3cf +#define CSR_PMPADDR32 0x3d0 +#define CSR_PMPADDR33 0x3d1 +#define CSR_PMPADDR34 0x3d2 +#define CSR_PMPADDR35 0x3d3 +#define CSR_PMPADDR36 0x3d4 +#define CSR_PMPADDR37 0x3d5 +#define CSR_PMPADDR38 0x3d6 +#define CSR_PMPADDR39 0x3d7 +#define CSR_PMPADDR40 0x3d8 +#define CSR_PMPADDR41 0x3d9 +#define CSR_PMPADDR42 0x3da +#define CSR_PMPADDR43 0x3db +#define CSR_PMPADDR44 0x3dc +#define CSR_PMPADDR45 0x3dd +#define CSR_PMPADDR46 0x3de +#define CSR_PMPADDR47 0x3df +#define CSR_PMPADDR48 0x3e0 +#define CSR_PMPADDR49 0x3e1 +#define CSR_PMPADDR50 0x3e2 +#define CSR_PMPADDR51 0x3e3 +#define CSR_PMPADDR52 0x3e4 +#define CSR_PMPADDR53 0x3e5 +#define CSR_PMPADDR54 0x3e6 +#define CSR_PMPADDR55 0x3e7 +#define CSR_PMPADDR56 0x3e8 +#define CSR_PMPADDR57 0x3e9 +#define CSR_PMPADDR58 0x3ea +#define CSR_PMPADDR59 0x3eb +#define CSR_PMPADDR60 0x3ec +#define CSR_PMPADDR61 0x3ed +#define CSR_PMPADDR62 0x3ee +#define CSR_PMPADDR63 0x3ef +#define CSR_MSECCFG 0x747 +#define CSR_TSELECT 0x7a0 +#define CSR_TDATA1 0x7a1 +#define CSR_TDATA2 0x7a2 +#define CSR_TDATA3 0x7a3 +#define CSR_TINFO 0x7a4 +#define CSR_TCONTROL 0x7a5 +#define CSR_MCONTEXT 0x7a8 +#define CSR_MSCONTEXT 0x7aa +#define CSR_DCSR 0x7b0 +#define CSR_DPC 0x7b1 +#define CSR_DSCRATCH0 0x7b2 +#define CSR_DSCRATCH1 0x7b3 +#define CSR_MCYCLE 0xb00 +#define CSR_MINSTRET 0xb02 +#define CSR_MHPMCOUNTER3 0xb03 +#define CSR_MHPMCOUNTER4 0xb04 +#define CSR_MHPMCOUNTER5 0xb05 +#define CSR_MHPMCOUNTER6 0xb06 +#define CSR_MHPMCOUNTER7 0xb07 +#define CSR_MHPMCOUNTER8 0xb08 +#define CSR_MHPMCOUNTER9 0xb09 +#define CSR_MHPMCOUNTER10 0xb0a +#define CSR_MHPMCOUNTER11 0xb0b +#define CSR_MHPMCOUNTER12 0xb0c +#define CSR_MHPMCOUNTER13 0xb0d +#define CSR_MHPMCOUNTER14 0xb0e +#define CSR_MHPMCOUNTER15 0xb0f +#define CSR_MHPMCOUNTER16 0xb10 +#define CSR_MHPMCOUNTER17 0xb11 +#define CSR_MHPMCOUNTER18 0xb12 +#define CSR_MHPMCOUNTER19 0xb13 +#define CSR_MHPMCOUNTER20 0xb14 +#define CSR_MHPMCOUNTER21 0xb15 +#define CSR_MHPMCOUNTER22 0xb16 +#define CSR_MHPMCOUNTER23 0xb17 +#define CSR_MHPMCOUNTER24 0xb18 +#define CSR_MHPMCOUNTER25 0xb19 +#define CSR_MHPMCOUNTER26 0xb1a +#define CSR_MHPMCOUNTER27 0xb1b +#define CSR_MHPMCOUNTER28 0xb1c +#define CSR_MHPMCOUNTER29 0xb1d +#define CSR_MHPMCOUNTER30 0xb1e +#define CSR_MHPMCOUNTER31 0xb1f +#define CSR_MHPMEVENT3 0x323 +#define CSR_MHPMEVENT4 0x324 +#define CSR_MHPMEVENT5 0x325 +#define CSR_MHPMEVENT6 0x326 +#define CSR_MHPMEVENT7 0x327 +#define CSR_MHPMEVENT8 0x328 +#define CSR_MHPMEVENT9 0x329 +#define CSR_MHPMEVENT10 0x32a +#define CSR_MHPMEVENT11 0x32b +#define CSR_MHPMEVENT12 0x32c +#define CSR_MHPMEVENT13 0x32d +#define CSR_MHPMEVENT14 0x32e +#define CSR_MHPMEVENT15 0x32f +#define CSR_MHPMEVENT16 0x330 +#define CSR_MHPMEVENT17 0x331 +#define CSR_MHPMEVENT18 0x332 +#define CSR_MHPMEVENT19 0x333 +#define CSR_MHPMEVENT20 0x334 +#define CSR_MHPMEVENT21 0x335 +#define CSR_MHPMEVENT22 0x336 +#define CSR_MHPMEVENT23 0x337 +#define CSR_MHPMEVENT24 0x338 +#define CSR_MHPMEVENT25 0x339 +#define CSR_MHPMEVENT26 0x33a +#define CSR_MHPMEVENT27 0x33b +#define CSR_MHPMEVENT28 0x33c +#define CSR_MHPMEVENT29 0x33d +#define CSR_MHPMEVENT30 0x33e +#define CSR_MHPMEVENT31 0x33f +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MHARTID 0xf14 +#define CSR_MCONFIGPTR 0xf15 +#define CSR_STIMECMPH 0x15d +#define CSR_VSTIMECMPH 0x25d +#define CSR_HTIMEDELTAH 0x615 +#define CSR_HENVCFGH 0x61a +#define CSR_HSTATEEN0H 0x61c +#define CSR_HSTATEEN1H 0x61d +#define CSR_HSTATEEN2H 0x61e +#define CSR_HSTATEEN3H 0x61f +#define CSR_CYCLEH 0xc80 +#define CSR_TIMEH 0xc81 +#define CSR_INSTRETH 0xc82 +#define CSR_HPMCOUNTER3H 0xc83 +#define CSR_HPMCOUNTER4H 0xc84 +#define CSR_HPMCOUNTER5H 0xc85 +#define CSR_HPMCOUNTER6H 0xc86 +#define CSR_HPMCOUNTER7H 0xc87 +#define CSR_HPMCOUNTER8H 0xc88 +#define CSR_HPMCOUNTER9H 0xc89 +#define CSR_HPMCOUNTER10H 0xc8a +#define CSR_HPMCOUNTER11H 0xc8b +#define CSR_HPMCOUNTER12H 0xc8c +#define CSR_HPMCOUNTER13H 0xc8d +#define CSR_HPMCOUNTER14H 0xc8e +#define CSR_HPMCOUNTER15H 0xc8f +#define CSR_HPMCOUNTER16H 0xc90 +#define CSR_HPMCOUNTER17H 0xc91 +#define CSR_HPMCOUNTER18H 0xc92 +#define CSR_HPMCOUNTER19H 0xc93 +#define CSR_HPMCOUNTER20H 0xc94 +#define CSR_HPMCOUNTER21H 0xc95 +#define CSR_HPMCOUNTER22H 0xc96 +#define CSR_HPMCOUNTER23H 0xc97 +#define CSR_HPMCOUNTER24H 0xc98 +#define CSR_HPMCOUNTER25H 0xc99 +#define CSR_HPMCOUNTER26H 0xc9a +#define CSR_HPMCOUNTER27H 0xc9b +#define CSR_HPMCOUNTER28H 0xc9c +#define CSR_HPMCOUNTER29H 0xc9d +#define CSR_HPMCOUNTER30H 0xc9e +#define CSR_HPMCOUNTER31H 0xc9f +#define CSR_MSTATUSH 0x310 +#define CSR_MENVCFGH 0x31a +#define CSR_MSTATEEN0H 0x31c +#define CSR_MSTATEEN1H 0x31d +#define CSR_MSTATEEN2H 0x31e +#define CSR_MSTATEEN3H 0x31f +#define CSR_MHPMEVENT3H 0x723 +#define CSR_MHPMEVENT4H 0x724 +#define CSR_MHPMEVENT5H 0x725 +#define CSR_MHPMEVENT6H 0x726 +#define CSR_MHPMEVENT7H 0x727 +#define CSR_MHPMEVENT8H 0x728 +#define CSR_MHPMEVENT9H 0x729 +#define CSR_MHPMEVENT10H 0x72a +#define CSR_MHPMEVENT11H 0x72b +#define CSR_MHPMEVENT12H 0x72c +#define CSR_MHPMEVENT13H 0x72d +#define CSR_MHPMEVENT14H 0x72e +#define CSR_MHPMEVENT15H 0x72f +#define CSR_MHPMEVENT16H 0x730 +#define CSR_MHPMEVENT17H 0x731 +#define CSR_MHPMEVENT18H 0x732 +#define CSR_MHPMEVENT19H 0x733 +#define CSR_MHPMEVENT20H 0x734 +#define CSR_MHPMEVENT21H 0x735 +#define CSR_MHPMEVENT22H 0x736 +#define CSR_MHPMEVENT23H 0x737 +#define CSR_MHPMEVENT24H 0x738 +#define CSR_MHPMEVENT25H 0x739 +#define CSR_MHPMEVENT26H 0x73a +#define CSR_MHPMEVENT27H 0x73b +#define CSR_MHPMEVENT28H 0x73c +#define CSR_MHPMEVENT29H 0x73d +#define CSR_MHPMEVENT30H 0x73e +#define CSR_MHPMEVENT31H 0x73f +#define CSR_MSECCFGH 0x757 +#define CSR_MCYCLEH 0xb80 +#define CSR_MINSTRETH 0xb82 +#define CSR_MHPMCOUNTER3H 0xb83 +#define CSR_MHPMCOUNTER4H 0xb84 +#define CSR_MHPMCOUNTER5H 0xb85 +#define CSR_MHPMCOUNTER6H 0xb86 +#define CSR_MHPMCOUNTER7H 0xb87 +#define CSR_MHPMCOUNTER8H 0xb88 +#define CSR_MHPMCOUNTER9H 0xb89 +#define CSR_MHPMCOUNTER10H 0xb8a +#define CSR_MHPMCOUNTER11H 0xb8b +#define CSR_MHPMCOUNTER12H 0xb8c +#define CSR_MHPMCOUNTER13H 0xb8d +#define CSR_MHPMCOUNTER14H 0xb8e +#define CSR_MHPMCOUNTER15H 0xb8f +#define CSR_MHPMCOUNTER16H 0xb90 +#define CSR_MHPMCOUNTER17H 0xb91 +#define CSR_MHPMCOUNTER18H 0xb92 +#define CSR_MHPMCOUNTER19H 0xb93 +#define CSR_MHPMCOUNTER20H 0xb94 +#define CSR_MHPMCOUNTER21H 0xb95 +#define CSR_MHPMCOUNTER22H 0xb96 +#define CSR_MHPMCOUNTER23H 0xb97 +#define CSR_MHPMCOUNTER24H 0xb98 +#define CSR_MHPMCOUNTER25H 0xb99 +#define CSR_MHPMCOUNTER26H 0xb9a +#define CSR_MHPMCOUNTER27H 0xb9b +#define CSR_MHPMCOUNTER28H 0xb9c +#define CSR_MHPMCOUNTER29H 0xb9d +#define CSR_MHPMCOUNTER30H 0xb9e +#define CSR_MHPMCOUNTER31H 0xb9f + +/* === TEE CSR Registers === */ +#define CSR_SPMPCFG0 0x1A0 +#define CSR_SPMPCFG1 0x1A1 +#define CSR_SPMPCFG2 0x1A2 +#define CSR_SPMPCFG3 0x1A3 +#define CSR_SPMPADDR0 0x1B0 +#define CSR_SPMPADDR1 0x1B1 +#define CSR_SPMPADDR2 0x1B2 +#define CSR_SPMPADDR3 0x1B3 +#define CSR_SPMPADDR4 0x1B4 +#define CSR_SPMPADDR5 0x1B5 +#define CSR_SPMPADDR6 0x1B6 +#define CSR_SPMPADDR7 0x1B7 +#define CSR_SPMPADDR8 0x1B8 +#define CSR_SPMPADDR9 0x1B9 +#define CSR_SPMPADDR10 0x1BA +#define CSR_SPMPADDR11 0x1BB +#define CSR_SPMPADDR12 0x1BC +#define CSR_SPMPADDR13 0x1BD +#define CSR_SPMPADDR14 0x1BE +#define CSR_SPMPADDR15 0x1BF + +#define CSR_SMPUCFG0 0x1A0 +#define CSR_SMPUCFG1 0x1A1 +#define CSR_SMPUCFG2 0x1A2 +#define CSR_SMPUCFG3 0x1A3 +#define CSR_SMPUADDR0 0x1B0 +#define CSR_SMPUADDR1 0x1B1 +#define CSR_SMPUADDR2 0x1B2 +#define CSR_SMPUADDR3 0x1B3 +#define CSR_SMPUADDR4 0x1B4 +#define CSR_SMPUADDR5 0x1B5 +#define CSR_SMPUADDR6 0x1B6 +#define CSR_SMPUADDR7 0x1B7 +#define CSR_SMPUADDR8 0x1B8 +#define CSR_SMPUADDR9 0x1B9 +#define CSR_SMPUADDR10 0x1BA +#define CSR_SMPUADDR11 0x1BB +#define CSR_SMPUADDR12 0x1BC +#define CSR_SMPUADDR13 0x1BD +#define CSR_SMPUADDR14 0x1BE +#define CSR_SMPUADDR15 0x1BF + +#define CSR_SMPUSWITCH0 0x170 +#define CSR_SMPUSWITCH1 0x171 + +/* === CLIC CSR Registers === */ +#define CSR_MTVT 0x307 +#define CSR_MNXTI 0x345 +#define CSR_MINTSTATUS 0x346 +#define CSR_MSCRATCHCSW 0x348 +#define CSR_MSCRATCHCSWL 0x349 +#define CSR_MCLICBASE 0x350 + +/* === P-Extension Registers === */ +#define CSR_UCODE 0x801 + +/* === Nuclei custom CSR Registers === */ +//#define CSR_MCOUNTINHIBIT 0x320 +#define CSR_MILM_CTL 0x7C0 +#define CSR_MDLM_CTL 0x7C1 +#define CSR_MECC_CODE 0x7C2 +#define CSR_MNVEC 0x7C3 +#define CSR_MSUBM 0x7C4 +#define CSR_MDCAUSE 0x7C9 +#define CSR_MCACHE_CTL 0x7CA +#define CSR_MMISC_CTL 0x7D0 +#define CSR_MSAVESTATUS 0x7D6 +#define CSR_MSAVEEPC1 0x7D7 +#define CSR_MSAVECAUSE1 0x7D8 +#define CSR_MSAVEEPC2 0x7D9 +#define CSR_MSAVECAUSE2 0x7DA +#define CSR_MSAVEDCAUSE1 0x7DB +#define CSR_MSAVEDCAUSE2 0x7DC +#define CSR_MTLB_CTL 0x7DD +#define CSR_MECC_LOCK 0x7DE +#define CSR_MFP16MODE 0x7E2 +/* mfp16mode is renamed to mmisc_ctl1 */ +#define CSR_MMISC_CTL1 0x7E2 +#define CSR_LSTEPFORC 0x7E9 +#define CSR_PUSHMSUBM 0x7EB +#define CSR_MTVT2 0x7EC +#define CSR_JALMNXTI 0x7ED +#define CSR_PUSHMCAUSE 0x7EE +#define CSR_PUSHMEPC 0x7EF +#define CSR_MPPICFG_INFO 0x7F0 +#define CSR_MFIOCFG_INFO 0x7F1 + +/* === NCDEV === */ +#define CSR_MDEVB 0x7F3 +#define CSR_MDEVM 0x7F4 +#define CSR_MNOCB 0x7F5 +#define CSR_MNOCM 0x7F6 +#define CSR_MMACRO_DEV_EN 0xBC8 +#define CSR_MMACRO_NOC_EN 0xBC9 +#define CSR_MMACRO_CA_EN 0xBCA +#define CSR_MATTRI0_BASE 0x7F3 +#define CSR_MATTRI0_MASK 0x7F4 +#define CSR_MATTRI1_BASE 0x7F5 +#define CSR_MATTRI1_MASK 0x7F6 +#define CSR_MATTRI2_BASE 0x7F9 +#define CSR_MATTRI2_MASK 0x7FA +#define CSR_MATTRI3_BASE 0x7FB +#define CSR_MATTRI3_MASK 0x7FC +#define CSR_MATTRI4_BASE 0x7FD +#define CSR_MATTRI4_MASK 0x7FE +#define CSR_MATTRI5_BASE 0xBE0 +#define CSR_MATTRI5_MASK 0xBE1 +#define CSR_MATTRI6_BASE 0xBE2 +#define CSR_MATTRI6_MASK 0xBE3 +#define CSR_MATTRI7_BASE 0xBE4 +#define CSR_MATTRI7_MASK 0xBE5 +#define CSR_SATTRI0_BASE 0x5F0 +#define CSR_SATTRI0_MASK 0x5F1 +#define CSR_SATTRI1_BASE 0x5F2 +#define CSR_SATTRI1_MASK 0x5F3 +#define CSR_SATTRI2_BASE 0x5F4 +#define CSR_SATTRI2_MASK 0x5F5 +#define CSR_SATTRI3_BASE 0x5F6 +#define CSR_SATTRI3_MASK 0x5F7 +#define CSR_SATTRI4_BASE 0x5F8 +#define CSR_SATTRI4_MASK 0x5F9 +#define CSR_SATTRI5_BASE 0x5FA +#define CSR_SATTRI5_MASK 0x5FB +#define CSR_SATTRI6_BASE 0x5FC +#define CSR_SATTRI6_MASK 0x5FD +#define CSR_SATTRI7_BASE 0x5FE +#define CSR_SATTRI7_MASK 0x5FF + +/* === IREGION === */ +#define CSR_MSMPCFG_INFO 0x7F7 +#define CSR_MIRGB_INFO 0x7F7 + +#define CSR_SLEEPVALUE 0x811 +#define CSR_TXEVT 0x812 +#define CSR_WFE 0x810 +#define CSR_JALSNXTI 0x947 +#define CSR_STVT2 0x948 +#define CSR_PUSHSCAUSE 0x949 +#define CSR_PUSHSEPC 0x94A +#define CSR_SDCAUSE 0x9C0 +#define CSR_MICFG_INFO 0xFC0 +#define CSR_MDCFG_INFO 0xFC1 +#define CSR_MCFG_INFO 0xFC2 +#define CSR_MTLBCFG_INFO 0xFC3 + +/* === ECC === */ +#define CSR_MECC_CTL 0xBC0 +#define CSR_MECC_STATUS 0xBC4 + +/* === STL === */ +#define CSR_SAFETY_CRC_CTL 0x813 +#define CSR_SAFETY_STL_STATUS 0x814 + +/* === Stack protect === */ +#define CSR_MSTACK_CTRL 0x7C6 +#define CSR_MSTACK_BOUND 0x7C7 +#define CSR_MSTACK_BASE 0x7C8 + +/* === Nuclei CCM Registers === */ +#define CSR_CCM_MBEGINADDR 0x7CB +#define CSR_CCM_MCOMMAND 0x7CC +#define CSR_CCM_MDATA 0x7CD +#define CSR_CCM_SUEN 0x7CE +#define CSR_CCM_SBEGINADDR 0x5CB +#define CSR_CCM_SCOMMAND 0x5CC +#define CSR_CCM_SDATA 0x5CD +#define CSR_CCM_UBEGINADDR 0x4CB +#define CSR_CCM_UCOMMAND 0x4CC +#define CSR_CCM_UDATA 0x4CD +#define CSR_CCM_FPIPE 0x4CF + +/** @} */ /** End of Doxygen Group NMSIS_Core_CSR_Registers **/ + +/* Exception Code in MCAUSE CSR */ +#define CAUSE_MISALIGNED_FETCH 0x0 +#define CAUSE_FAULT_FETCH 0x1 +#define CAUSE_ILLEGAL_INSTRUCTION 0x2 +#define CAUSE_BREAKPOINT 0x3 +#define CAUSE_MISALIGNED_LOAD 0x4 +#define CAUSE_FAULT_LOAD 0x5 +#define CAUSE_MISALIGNED_STORE 0x6 +#define CAUSE_FAULT_STORE 0x7 +#define CAUSE_USER_ECALL 0x8 +#define CAUSE_SUPERVISOR_ECALL 0x9 +#define CAUSE_HYPERVISOR_ECALL 0xa +#define CAUSE_MACHINE_ECALL 0xb +#define CAUSE_FETCH_PAGE_FAULT 0xc +#define CAUSE_LOAD_PAGE_FAULT 0xd +#define CAUSE_STORE_PAGE_FAULT 0xf + +/* Delegatable Exception Code Mask in MCAUSE CSR*/ +#define MISALIGNED_FETCH (1 << CAUSE_MISALIGNED_FETCH) +#define FAULT_FETCH (1 << CAUSE_FAULT_FETCH) +#define ILLEGAL_INSTRUCTION (1 << CAUSE_ILLEGAL_INSTRUCTION) +#define BREAKPOINT (1 << CAUSE_BREAKPOINT) +#define MISALIGNED_LOAD (1 << CAUSE_MISALIGNED_LOAD) +#define FAULT_LOAD (1 << CAUSE_FAULT_LOAD) +#define MISALIGNED_STORE (1 << CAUSE_MISALIGNED_STORE) +#define FAULT_STORE (1 << CAUSE_FAULT_STORE) +#define USER_ECALL (1 << CAUSE_USER_ECALL) +#define FETCH_PAGE_FAULT (1 << CAUSE_FETCH_PAGE_FAULT) +#define LOAD_PAGE_FAULT (1 << CAUSE_LOAD_PAGE_FAULT) +#define STORE_PAGE_FAULT (1 << CAUSE_STORE_PAGE_FAULT) + +/* Exception Subcode in MDCAUSE CSR */ +#define DCAUSE_FAULT_FETCH_PMP 0x1 +#define DCAUSE_FAULT_FETCH_INST 0x2 + +#define DCAUSE_FAULT_LOAD_PMP 0x1 +#define DCAUSE_FAULT_LOAD_INST 0x2 +#define DCAUSE_FAULT_LOAD_NICE 0x3 + +#define DCAUSE_FAULT_STORE_PMP 0x1 +#define DCAUSE_FAULT_STORE_INST 0x2 + +/** @} */ /** End of Doxygen Group NMSIS_Core_CSR_Encoding **/ + +#ifdef __cplusplus +} +#endif +#endif /* __RISCV_ENCODING_H__ */ diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/component.mk b/pec930_sdk-v1.0.1/Drivers/PEC930/component.mk new file mode 100644 index 0000000..f1aa5e1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/component.mk @@ -0,0 +1,92 @@ +# +# component Makefile +# + + +#======================================= +# Configurations +#======================================= + +# +# Drivers of MCU +# + +SOC_CPU_NAME = n203e + +#======================================= +# system +#======================================= +ifeq ("$(SOC)","pec930") + C_DEFS += -DCONFIG_USE_PEC930 +else +$(error "Unknown SoC !!!") +endif + +# +# cpu +# +C_DEFS += -DCONFIG_CPU_N203E -DCONFIG_HAS_BPU + +CPU_FLAGS = -mabi=ilp32e -mcmodel=medlow +CPU_FLAGS += -march=rv32emc_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + + +# +# Source +# +ASM_SOURCES := \ + $(srctree)/Drivers/PEC930/Device/src/Startup/startup.S \ + $(srctree)/Drivers/PEC930/Device/src/Startup/trap.S + +C_SOURCES += \ + $(srctree)/Drivers/PEC930/Device/src/interrupt.c \ + $(srctree)/Drivers/PEC930/Device/src/syscalls.c \ + $(srctree)/Drivers/PEC930/Device/src/system_dev.c + +C_INCLUDES += \ + -I$(srctree)/Drivers/PEC930/Device/inc \ + -I$(srctree)/Drivers/PEC930/NMSIS/Core/Include \ + -I$(srctree)/Drivers/PEC930/ + + + +#======================================= +# peripheral hal driver +#======================================= +C_SOURCES += \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_adc.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_amisc.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_comp.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_opamp.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_crc.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_dsp.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_flash.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_gpio.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_i2c.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_lptim.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_pwr.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_spi.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_syscfg.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_tim.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_uart.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_wdg.c \ + $(srctree)/Drivers/PEC930/HAL_Lib/src/hal_device.c + +C_INCLUDES += \ + -I$(srctree)/Drivers/PEC930/HAL_Lib/inc + +#======================================= +# BSP +#======================================= +C_SOURCES += $(srctree)/Drivers/PEC930/BSP/StarterKit/starterkit.c + +C_INCLUDES += \ + -I$(srctree)/Drivers/PEC930/BSP/StarterKit + +#======================================= +# Flags +#======================================= +CFLAGS += $(CPU_FLAGS) +CXXFLAGS += +LDFLAGS += $(CPU_FLAGS) +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Drivers/PEC930/gcc_flashxip.ld b/pec930_sdk-v1.0.1/Drivers/PEC930/gcc_flashxip.ld new file mode 100644 index 0000000..5641231 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/PEC930/gcc_flashxip.ld @@ -0,0 +1,267 @@ +/****************************************************************************** + * @file gcc_flashxip.ld + * @brief GNU Linker Script for RISC-V device in FlashXIP Download Mode + * @date 10. March 2022 + ******************************************************************************/ + +/*********** Use Configuration Wizard in Context Menu *************************/ + +OUTPUT_ARCH( "riscv" ) + +/********************* Stack / neap Configuration **************************** + * Stack / Heap Configuration + * Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> + * Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> + * + */ +__STACK_SIZE = 0x00000200; +__HEAP_SIZE = 0x00000000; +/**************************** end of configuration section ********************/ + +ENTRY(_start) + +/* Define base address and length of flash and sram */ +MEMORY +{ + flash (rxa!w) : ORIGIN = 0x00000000, LENGTH = 0x8000 + sram (wxa!r) : ORIGIN = 0x20000000, LENGTH = 0x1000 + ovly (wxa!r) : ORIGIN = 0x20000C00, LENGTH = 0x400 +} + +REGION_ALIAS("ROM", flash) +REGION_ALIAS("RAM", sram) + +SECTIONS +{ + /* To provide symbol __STACK_SIZE, __HEAP_SIZE */ + PROVIDE(__STACK_SIZE = 512); + PROVIDE(__HEAP_SIZE = 256); + __TOT_STACK_SIZE = __STACK_SIZE; + + .init : + { + __exec_base_start = .; + /* vector table locate at ROM */ + *(.text.vtable) + KEEP (*(SORT_NONE(.text.init))) + . = ALIGN(4); + } >flash AT>flash + + . = ALIGN(4); + __fastcode_lma_start = .; + + .fastcode : ALIGN(4) + { + /* fast code, execute code at SRAM */ + __fastcode_vma_start = ALIGN(4); + PROVIDE( __fastcode_start = . ); + + *(.fastcode) + + __fastcode_vma_end = .; + PROVIDE( __fastcode_end = . ); + } >sram AT>flash + + /* Code section located at flash */ + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + . = ALIGN(8); + PROVIDE( __jvt_base$ = . ); + *(.text.tbljal .text.tbljal.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + /* readonly data placed in flash */ + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + /* below sections are used for rt-thread */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + } >flash AT>flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + * the constructors, so we make sure it is + * first. Because this is a wildcard, it + * doesn't matter if the user does not + * actually link against crtbegin.o; the + * linker won't look for a file to match a + * wildcard. The wildcard also means that it + * doesn't matter which directory crtbegin.o + * is in. + */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + * the crtend.o file until after the sorted ctors. + * The .ctor section from the crtend file contains the + * end of ctors marker and it must be last + */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash + + PROVIDE( _text_lma = LOADADDR(.text) ); + PROVIDE( _text = ADDR(.text) ); + PROVIDE (_etext = .); + PROVIDE (__etext = .); + PROVIDE (etext = .); + + .data : ALIGN(8) + { + KEEP(*(.data.ctest*)) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata*) + *(.gnu.linkonce.s.*) + /* Fix undefined symbol: __eh_frame_start/__eh_frame_hdr_start/__eh_frame_end/__eh_frame_hdr_end */ + PROVIDE_HIDDEN (__eh_frame_hdr_start = .); + *(.eh_frame_hdr) + PROVIDE_HIDDEN (__eh_frame_hdr_end = .); + PROVIDE_HIDDEN (__eh_frame_start = .); + *(.eh_frame) + PROVIDE_HIDDEN (__eh_frame_end = .); + . = ALIGN(8); + + /* table real-usage */ + . = ALIGN(256); + KEEP (*(.mintvec)) + . = ALIGN(64); + KEEP (*(.mexcptrap)) + } >sram AT>flash + + .tdata : ALIGN(8) + { + PROVIDE( __tls_base = . ); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >sram AT>flash + + PROVIDE( _data_lma = LOADADDR(.data) ); + PROVIDE( _data = ADDR(.data) ); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + + __end_lma__ = LOADADDR(.tdata); + + .tbss (NOLOAD) : ALIGN(8) + { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + PROVIDE( __tls_end = . ); + } >sram AT>sram + + .tbss_space (NOLOAD) : ALIGN(8) + { + . = . + SIZEOF(.tbss); + } >sram AT>sram + + .bss (NOLOAD) : ALIGN(8) + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >sram AT>sram + + . = ALIGN(4); + __ovly_vma_start = ORIGIN(ovly); + OVERLAY : NOCROSSREFS + { + .ovly1 { *(.ovly1.text .ovly1.data) } + .ovly2 { *(.ovly2.text .ovly2.data) } + } >ovly AT>flash + + PROVIDE( _end = . ); + PROVIDE( end = . ); + + /** + * 1. heap need to be align at 16 bytes + * 2. __heap_start and __heap_end symbol need to be defined + * 3. reserved at least __HEAP_SIZE space for heap + */ + .heap (NOLOAD) : ALIGN(16) + { + . = ALIGN(16); + PROVIDE( __heap_start = . ); + . += __HEAP_SIZE; + . = ALIGN(16); + PROVIDE( __heap_limit = . ); + } >sram AT>sram + + .stack ORIGIN(sram) + LENGTH(sram) - __TOT_STACK_SIZE (NOLOAD) : + { + . = ALIGN(16); + PROVIDE( _heap_end = . ); + PROVIDE( __heap_end = . ); + PROVIDE( __StackLimit = . ); + PROVIDE( __StackBottom = . ); + . += __TOT_STACK_SIZE; + . = ALIGN(16); + PROVIDE( __StackTop = . ); + PROVIDE( _sp = . ); + } >sram AT>sram +} diff --git a/pec930_sdk-v1.0.1/Drivers/drivers.mk b/pec930_sdk-v1.0.1/Drivers/drivers.mk new file mode 100644 index 0000000..54e9be7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Drivers/drivers.mk @@ -0,0 +1,22 @@ +# +# component Makefile +# + +ifeq (,$(filter $(MAKECMDGOALS),clean help)) + +ifeq ("$(SOC_DRIVER)","") +$(error "Unknown SoC !!!") +else + include $(srctree)/Drivers/$(SOC_DRIVER)/component.mk +endif + +C_INCLUDES += + + +endif # ifeq (,$(filter $(MAKECMDGOALS),clean help)) + + +CFLAGS += +CXXFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.cproject b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.project b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/Project.nuproject b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/component.mk b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/component.mk new file mode 100644 index 0000000..fde693b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += -DCONFIG_HAS_SYSLOG_FLOAT +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/isr.h b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/main.h b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/readme.md b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/readme.md new file mode 100644 index 0000000..a8e8ab7 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/readme.md @@ -0,0 +1,374 @@ +adc_conv_mode +--- + +This is an example of ADC conversion mode. + ++ This ADC supports 4 modes + > + Single conversion mode + > + Continuous mode + > + Scan mode + > + Discontinuous mode + ++ The target ADC channels + + ``` + // in main.c + #define CONFIG_TARGET_1_ADC_CHANNEL ADC_Channel_03 + #define CONFIG_TARGET_ADC_MULTI_CHANNELS (ADC_Channel_02 | ADC_Channel_03 | ADC_Channel_09) + ``` + ++ User pull low of the specific key to trigger ADC work + + ``` + // in main.c + #define CONFIG_GPIO_INPUT_PORTx GPIOA + #define CONFIG_GPIO_INPUT_PINx GPIO_Pin_02 + ``` + +## Single conversion mode + +Software trigger ADC to sample a channel once +> The target ADC channel is defined at `CONFIG_TARGET_1_ADC_CHANNEL` + ++ Configure to single conversion mode + + ``` + // in main.c + #define CONFIG_TARGET_ADC_MODE_SIGNAL 1 + #define CONFIG_TARGET_ADC_MODE_CONTINOUS 0 + #define CONFIG_TARGET_ADC_MODE_SCAN 0 + #define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 0 + ``` + ++ Operation flow + + - Step 1. Connect the AIN-Channel (`CONFIG_TARGET_1_ADC_CHANNEL`) with an external device (e.g. power support) which provide difference voltage + - Step 2. Set a specific voltage to external device (e.g. power support) + - Step 3. Press button to trigger ADC start + - Step 4. Get the ADC conversion value from log message + - Step 5. Calculate the measured voltage + + ``` + the measured voltage = ADC_Value * ((AVDD - AVSS) / 4095) + ``` + + - Step 6. repeat `Step 2 ~ Step 5` + +## Continuous mode + +In this mode, ADC will always sequentially sample the specific channels after a trigger-event + ++ Configure to continuous mode + + ``` + // in main.c + #define CONFIG_TARGET_ADC_MODE_SIGNAL 0 + #define CONFIG_TARGET_ADC_MODE_CONTINOUS 1 + #define CONFIG_TARGET_ADC_MODE_SCAN 0 + #define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 0 + ``` + ++ Operation flow + + - Step 1. Connect the AIN-Channel (`CONFIG_TARGET_1_ADC_CHANNEL`) with an external device (e.g. power support) which provide difference voltage + - Step 2. Set a specific voltage to the external device (e.g. power support) + - Step 3. Press button to trigger ADC start + - Step 4. Run-time change voltage from the external device (e.g. power support) + - Step 5. Get the ADC conversion value from log message + > It will auto-log `CONFIG_REPEAT_TIMES` times with a trigger-event + > ``` + > // at main.c + > #define CONFIG_REPEAT_TIMES 10 + > ``` + +## Scan mode + +In Scan mode, ACD will sequentially sample the specific channels **once** after a trigger-event + ++ Configure to Scan mode + + ``` + // in main.c + #define CONFIG_TARGET_ADC_MODE_SIGNAL 0 + #define CONFIG_TARGET_ADC_MODE_CONTINOUS 0 + #define CONFIG_TARGET_ADC_MODE_SCAN 1 + #define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 0 + ``` + ++ Operation flow + + - Step 1. Connect the AIN-Channels (`CONFIG_TARGET_ADC_MULTI_CHANNELS`) with an external device (e.g. power support) which provide difference voltages + - Step 2. Set specific voltages to the external device (e.g. power support) with multi-channels + - Step 3. Press button to trigger ADC start + - Step 4. Run-time change voltages of multi-channels of the external device (e.g. power support) + - Step 5. Get the ADC conversion values from log message + > It will auto-trigger the sample-event `CONFIG_REPEAT_TIMES` times + > ``` + > // at main.c + > #define CONFIG_REPEAT_TIMES 10 + > ``` + +## Discontinuous mode + +It will group the selected AIN-Channels and sequentially trigger a sub-group of the selected AIN-Channels with a trigger-event +> An example as below +> ``` +> Selected AIN 4,5,7,9 +> Sub-Group 1: AIN 4, 5, 7 +> Sub-Group 2: AIN 9 +> the 1st trigger-evern => Execute Sub-Group 1 +> the 2nd trigger-evern => Execute Sub-Group 2 +> ``` + + ++ Configure to Discontinuous mode + + ``` + // in main.c + #define CONFIG_TARGET_ADC_MODE_SIGNAL 0 + #define CONFIG_TARGET_ADC_MODE_CONTINOUS 0 + #define CONFIG_TARGET_ADC_MODE_SCAN 0 + #define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 1 + ``` + ++ Operation flow + + - Step 1. Connect the AIN-Channels (`CONFIG_TARGET_ADC_MULTI_CHANNELS`) with an external device (e.g. power support) which provide difference voltages + - Step 2. Set specific voltages to the external device (e.g. power support) with multi-channels + - Step 3. Press button to trigger ADC start + - Step 4. Run-time change voltages of multi-channels of the external device (e.g. power support) + - Step 5. Get the ADC conversion values from log message + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Single conversion mode + + ``` + Oct 2 2025 16:19:41 + ADC run Single conversion mode + Button = PA2 + wait key event (voltage level low)... + ADC Single Conversion + Trigger ADC + ch-03 ADC Value: 3395, voltage: 2.735898 + + ... + ``` + ++ Continuous mode + + ``` + Oct 2 2025 15:02:37 + ADC run Continuous conversion mode + Button = PA2 + wait key event (voltage level low)... + ADC Continuous mode + + Trigger ADC <--- trigger ADC + => Change External Voltage + ch-09 ADC Value: 2327, voltage: 1.875238 + ch-03 ADC Value: 3274, voltage: 2.638388 + ch-02 ADC Value: 1342, voltage: 1.081465 + => Change External Voltage + ch-09 ADC Value: 2331, voltage: 1.878461 + ch-03 ADC Value: 3276, voltage: 2.640000 + ch-02 ADC Value: 1349, voltage: 1.087106 + => Change External Voltage + ch-09 ADC Value: 2341, voltage: 1.886520 + ch-03 ADC Value: 3152, voltage: 2.540073 <--- change AIN3 voltage + ch-02 ADC Value: 1352, voltage: 1.089524 + => Change External Voltage + ch-09 ADC Value: 2336, voltage: 1.882491 + ch-03 ADC Value: 3159, voltage: 2.545714 + ch-02 ADC Value: 1351, voltage: 1.088718 + => Change External Voltage + ch-09 ADC Value: 2333, voltage: 1.880073 + ch-03 ADC Value: 3028, voltage: 2.440146 + ch-02 ADC Value: 1341, voltage: 1.080659 + => Change External Voltage + ch-09 ADC Value: 2336, voltage: 1.882491 + ch-03 ADC Value: 2906, voltage: 2.341831 <--- change AIN3 voltage + ch-02 ADC Value: 1343, voltage: 1.082271 + => Change External Voltage + ch-09 ADC Value: 2345, voltage: 1.889744 + ch-03 ADC Value: 2902, voltage: 2.338608 + ch-02 ADC Value: 1347, voltage: 1.085495 + => Change External Voltage + ch-09 ADC Value: 2332, voltage: 1.879267 + ch-03 ADC Value: 2904, voltage: 2.340220 + ch-02 ADC Value: 1717, voltage: 1.383663 <--- change AIN2 voltage + => Change External Voltage + ch-09 ADC Value: 2338, voltage: 1.884103 + ch-03 ADC Value: 2902, voltage: 2.338608 + ch-02 ADC Value: 2090, voltage: 1.684249 + => Change External Voltage + ch-09 ADC Value: 2340, voltage: 1.885714 + ch-03 ADC Value: 2910, voltage: 2.345055 + ch-02 ADC Value: 2575, voltage: 2.075092 <--- change AIN2 voltage + => Change External Voltage + ch-09 ADC Value: 2328, voltage: 1.876044 + ch-03 ADC Value: 2905, voltage: 2.341026 + ch-02 ADC Value: 2585, voltage: 2.083150 + => Change External Voltage + ch-09 ADC Value: 2082, voltage: 1.677802 <--- change AIN9 voltage + ch-03 ADC Value: 2907, voltage: 2.342637 + ch-02 ADC Value: 2582, voltage: 2.080733 + => Change External Voltage + ch-09 ADC Value: 1956, voltage: 1.576264 + ch-03 ADC Value: 2905, voltage: 2.341026 + ch-02 ADC Value: 2582, voltage: 2.080733 + => Change External Voltage + ch-09 ADC Value: 2457, voltage: 1.980000 + ch-03 ADC Value: 2905, voltage: 2.341026 + ch-02 ADC Value: 2583, voltage: 2.081538 + => Change External Voltage + ch-09 ADC Value: 2833, voltage: 2.283004 <--- change AIN9 voltage + ch-03 ADC Value: 2904, voltage: 2.340220 + ch-02 ADC Value: 2589, voltage: 2.086374 + ... + ``` + ++ Scan mode + + ``` + Oct 2 2025 15:44:15 + ADC run Scan conversion mode + Button = PA2 + wait key event (voltage level low)... + ADC Scan mode + + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 2215, voltage: 1.784982 + ch-03 ADC Value: 2902, voltage: 2.338608 + ch-02 ADC Value: 2581, voltage: 2.079927 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 2214, voltage: 1.784176 + ch-03 ADC Value: 2903, voltage: 2.339414 + ch-02 ADC Value: 2578, voltage: 2.077509 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 2081, voltage: 1.676996 + ch-03 ADC Value: 2902, voltage: 2.338608 + ch-02 ADC Value: 2587, voltage: 2.084762 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1961, voltage: 1.580293 <--- change AIN9 voltage + ch-03 ADC Value: 2906, voltage: 2.341831 + ch-02 ADC Value: 2581, voltage: 2.079927 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1843, voltage: 1.485201 + ch-03 ADC Value: 2907, voltage: 2.342637 + ch-02 ADC Value: 2573, voltage: 2.073480 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1843, voltage: 1.485201 <--- change AIN9 voltage + ch-03 ADC Value: 2901, voltage: 2.337802 + ch-02 ADC Value: 2586, voltage: 2.083956 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1848, voltage: 1.489231 + ch-03 ADC Value: 2901, voltage: 2.337802 + ch-02 ADC Value: 2830, voltage: 2.280586 <--- change AIN2 voltage + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1852, voltage: 1.492454 + ch-03 ADC Value: 2906, voltage: 2.341831 + ch-02 ADC Value: 2697, voltage: 2.173407 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1847, voltage: 1.488425 + ch-03 ADC Value: 2902, voltage: 2.338608 + ch-02 ADC Value: 2453, voltage: 1.976776 <--- change AIN2 voltage + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1846, voltage: 1.487619 + ch-03 ADC Value: 2903, voltage: 2.339414 + ch-02 ADC Value: 2344, voltage: 1.888938 <--- change AIN2 voltage + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1851, voltage: 1.491648 + ch-03 ADC Value: 2905, voltage: 2.341026 + ch-02 ADC Value: 2459, voltage: 1.981612 <--- change AIN2 voltage + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1854, voltage: 1.494066 + ch-03 ADC Value: 2893, voltage: 2.331355 + ch-02 ADC Value: 2466, voltage: 1.987253 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1848, voltage: 1.489231 + ch-03 ADC Value: 3148, voltage: 2.536850 <--- change AIN3 voltage + ch-02 ADC Value: 2464, voltage: 1.985641 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1849, voltage: 1.490037 + ch-03 ADC Value: 2782, voltage: 2.241905 + ch-02 ADC Value: 2460, voltage: 1.982418 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1850, voltage: 1.490842 + ch-03 ADC Value: 2413, voltage: 1.944542 <--- change AIN3 voltage + ch-02 ADC Value: 2458, voltage: 1.980806 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1848, voltage: 1.489231 + ch-03 ADC Value: 2412, voltage: 1.943736 + ch-02 ADC Value: 2458, voltage: 1.980806 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1850, voltage: 1.490842 + ch-03 ADC Value: 2679, voltage: 2.158901 <--- change AIN3 voltage + ch-02 ADC Value: 2466, voltage: 1.987253 + => Change External Voltage + Trigger ADC + ch-09 ADC Value: 1850, voltage: 1.490842 + ch-03 ADC Value: 3023, voltage: 2.436117 + ch-02 ADC Value: 2460, voltage: 1.982418 + => Change External Voltage + Trigger ADC <--- trigger ADC + ch-09 ADC Value: 1854, voltage: 1.494066 + ch-03 ADC Value: 3397, voltage: 2.737509 <--- change AIN3 voltage + ch-02 ADC Value: 2464, voltage: 1.985641 + + ... + ``` + ++ Discontinuous mode + > Sub-Group 1: AIN 2
    + > Sub-Group 2: AIN 3
    + > Sub-Group 3: AIN 9
    + + ``` + Oct 2 2025 16:13:42 + ADC run Discontinuous conversion mode + Button = PA2 + wait key event (voltage level low)... + ADC Discontinuous mode + => Change External Voltage + + ## trigger 00-th + Trigger ADC <--- trigger ADC Sub-Group 1 (AIN 2) + ch-09 ADC Value: 0, voltage: 0.000000 + ch-03 ADC Value: 0, voltage: 0.000000 + ch-02 ADC Value: 2453, voltage: 1.976776 + + ## trigger 01-th + Trigger ADC <--- trigger ADC Sub-Group 2 (AIN 3) + ch-09 ADC Value: 0, voltage: 0.000000 + ch-03 ADC Value: 3399, voltage: 2.739121 + ch-02 ADC Value: 2453, voltage: 1.976776 + + ## trigger 02-th + Trigger ADC <--- trigger ADC Sub-Group 3 (AIN 9) + ch-09 ADC Value: 1843, voltage: 1.485201 + ch-03 ADC Value: 3399, voltage: 2.739121 + ch-02 ADC Value: 2453, voltage: 1.976776 + + ... + ``` diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/isr.c b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/main.c b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/main.c new file mode 100644 index 0000000..731c5a4 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_conv_mode/src/main.c @@ -0,0 +1,356 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_TARGET_ADC_MODE_SIGNAL 0 +#define CONFIG_TARGET_ADC_MODE_CONTINOUS 1 +#define CONFIG_TARGET_ADC_MODE_SCAN 0 +#define CONFIG_TARGET_ADC_MODE_DISCONTINOUS 0 + +#define CONFIG_REPEAT_TIMES 10 + +/* Input Key I/O definitions */ +#define CONFIG_GPIO_INPUT_PORTx GPIOA +#define CONFIG_GPIO_INPUT_PINx GPIO_Pin_02 +#define CONFIG_GPIO_IRQ GPIOA_IRQn // GPIOB_IRQn + +#define CONFIG_TARGET_1_ADC_CHANNEL ADC_Channel_03 // ADC_Channel_AVSS +#define CONFIG_TARGET_ADC_MULTI_CHANNELS (ADC_Channel_02 | ADC_Channel_03 | ADC_Channel_09) // (ADC_Channel_AVSS | ADC_Channel_AMISC) +#define CONFIG_TARGET_ADC_SUB_CHANNEL ADC_SubChannel_VBuf_1_5 +//============================================================================= +// Macro Definition +//============================================================================= +#define _ADC_Convert_Voltage(__ADC_12b_value__) \ + ((__ADC_12b_value__) * 3.3f / 4095.0f) +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static bool g_hasPullLow = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + if( GPIO_GetITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx) ) + { + GPIO_ClearITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + g_hasPullLow = true; + } + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +__INTERRUPT void ADC0_Handler(void) +{ + return; +} + +__USED static int +_ADC_Conv_Single(ADC_ChannelsTypeDef channel) +{ + int rval = 0; + uint16_t value = 0; + ADC_InitTypeDef init = {0}; + int index = 31ul - HAL_CLZ(channel); + + log_color(SLOG_CYAN, "ADC Single Conversion\n"); + + /* Configure ADC */ + ADC_StructInit(&init); + + init.SelChannels = channel; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + + /* Start ADC conversion */ + msg("Trigger ADC\n"); + ADC_Start(ADC0); + + /* Wait ADC idle */ + while( ADC_IsIdle(ADC0) == 0 ); + + /* Get ADC conversion value */ + value = ADC_GetChannelConvValue(ADC0, channel); + msg(" ch-%02d ADC Value: %d, voltage: %f\n", + index, value, _ADC_Convert_Voltage(value)); + + ADC_DeInit(ADC0); + return rval; +} + +__USED static int +_ADC_Conv_Continuous(ADC_ChannelsTypeDef channels) +{ + int rval = 0; + uint16_t value = 0; + ADC_InitTypeDef init = {0}; + + log_color(SLOG_CYAN, "ADC Continuous mode\n"); + + /* Configure ADC */ + ADC_StructInit(&init); + + init.SelChannels = channels; + init.Mode = ADC_Mode_Continuous; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + + /* Start ADC conversion once */ + msg("Trigger ADC \n"); + ADC_Start(ADC0); + sys_delay(3); + + for(int i = 0; i < CONFIG_REPEAT_TIMES; i++) + { + uint32_t chnnls_set = 0; + + /** + * User modify the AIN channel voltage + */ + log_color(SLOG_GREEN, "=> Change External Voltage\n"); + sys_delay(1000); + + chnnls_set = (uint32_t)channels; + + while( chnnls_set ) + { + int index = 31ul - HAL_CLZ(chnnls_set); + + chnnls_set &= ~(0x1ul << index); + + /* Get ADC conversion value */ + value = ADC_GetChannelConvValue(ADC0, 0x1ul << index); + msg(" ch-%02d ADC Value: %d, voltage: %f\n", + index, value, _ADC_Convert_Voltage(value)); + } + + } + + ADC_DeInit(ADC0); + return rval; +} + +__USED static int +_ADC_Conv_Scan(ADC_ChannelsTypeDef channels) +{ + int rval = 0; + uint32_t chnnls_set = 0; + ADC_InitTypeDef init = {0}; + + log_color(SLOG_CYAN, "ADC Scan mode\n"); + + /* Configure ADC */ + ADC_StructInit(&init); + + init.SelChannels = channels; + init.Mode = ADC_Mode_Scan; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + + for(int i = 0; i < CONFIG_REPEAT_TIMES; i++) + { + /** + * User modify the AIN channel voltage + */ + log_color(SLOG_GREEN, "=> Change External Voltage\n"); + sys_delay(1000); + + /* Start ADC conversion every time */ + msg("Trigger ADC \n"); + ADC_Start(ADC0); + + + /* Wait ADC idle */ + while( ADC_IsIdle(ADC0) == 0 ); + + chnnls_set = (uint32_t)channels; + + while( chnnls_set ) + { + uint16_t value = 0; + int index = 31ul - HAL_CLZ(chnnls_set); + + chnnls_set &= ~(0x1ul << index); + + /* Get ADC conversion value */ + value = ADC_ITGetConvValue(ADC0, 0x1ul << index); + msg(" ch-%02d ADC Value: %d, voltage: %f\n", + index, value, _ADC_Convert_Voltage(value)); + } + } + + ADC_DeInit(ADC0); + return rval; +} + +__USED static int +_ADC_Conv_Discontinuous(ADC_ChannelsTypeDef channels) +{ + int rval = 0; + int chnnl_num = 0; + uint32_t chnnls_set = 0; + int subset_ch_cnt = 1; + int trigger_cnt = 0; + ADC_InitTypeDef init = {0}; + + log_color(SLOG_CYAN, "ADC Discontinuous mode\n"); + + chnnl_num = HAL_PopCount((uint32_t)channels); + + /* Configure ADC */ + ADC_StructInit(&init); + + init.SelChannels = channels; + init.Mode = ADC_Mode_Discontinuous; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + + /* Set the subset channel number */ + ADC_DiscMode_SetGroupSubsetNum(ADC0, subset_ch_cnt); + + trigger_cnt = (chnnl_num + (subset_ch_cnt - 1)) / subset_ch_cnt; + + for(int i = 0; i < CONFIG_REPEAT_TIMES; i++) + { + /** + * User modify the AIN channel voltage + */ + log_color(SLOG_GREEN, "=> Change External Voltage\n"); + sys_delay(1000); + + for(int j = 0; j < trigger_cnt; j++) + { + msg("\n ## trigger %02d-th\n", j); + + /* Start ADC conversion */ + msg(" Trigger ADC \n"); + ADC_Start(ADC0); + + /* Wait ADC idle */ + while( ADC_IsIdle(ADC0) == 0 ); + + chnnls_set = (uint32_t)channels; + + while( chnnls_set ) + { + uint16_t value = 0; + int index = 31ul - HAL_CLZ(chnnls_set); + + chnnls_set &= ~(0x1ul << index); + + /* Get ADC conversion value */ + value = ADC_ITGetConvValue(ADC0, 0x1ul << index); + msg(" ch-%02d ADC Value: %d, voltage: %f\n", + index, value, _ADC_Convert_Voltage(value)); + } + } + } + + ADC_DeInit(ADC0); + return rval; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + int rval = 0; + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nADC run %s conversion mode\n", __DATE__, __TIME__, + #if (CONFIG_TARGET_ADC_MODE_CONTINOUS) + "Continuous" + #elif (CONFIG_TARGET_ADC_MODE_SCAN) + "Scan" + #elif (CONFIG_TARGET_ADC_MODE_DISCONTINOUS) + "Discontinuous" + #else + "Single" + #endif + ); + + msg(" Button = P%s%d\n", + (CONFIG_GPIO_INPUT_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_GPIO_INPUT_PINx)); + + do { + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_GPIO_INPUT_PINx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN ; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Level; + GPIO_InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_GPIO_INPUT_PORTx , &GPIO_InitStruct); + + GPIO_ITEnable(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + } while(0); + + sys_register_IRQ(CONFIG_GPIO_IRQ, GPIOx_Handler, &irq_attr); + sys_register_IRQ(ADC0_IRQn, ADC0_Handler, &irq_attr); + + msg("wait key event (voltage level low)...\n"); + + while(1) + { + if( g_hasPullLow == true ) + { + g_hasPullLow = false; + + #if (CONFIG_TARGET_ADC_MODE_CONTINOUS) + rval = _ADC_Conv_Continuous(CONFIG_TARGET_ADC_MULTI_CHANNELS); + if( rval ) break; + + #elif (CONFIG_TARGET_ADC_MODE_SCAN) + rval = _ADC_Conv_Scan(CONFIG_TARGET_ADC_MULTI_CHANNELS); + if( rval ) break; + + #elif (CONFIG_TARGET_ADC_MODE_DISCONTINOUS) + rval = _ADC_Conv_Discontinuous(CONFIG_TARGET_ADC_MULTI_CHANNELS); + if( rval ) break; + + #else + rval = _ADC_Conv_Single(CONFIG_TARGET_1_ADC_CHANNEL); + if( rval ) break; + #endif + + msg("wait key event (voltage level low)...\n"); + } + + sys_delay(500); + } + + if( rval ) err("Fail ! (err_code= %d)\n"); + + while(1); + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.cproject b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.project b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/Project.nuproject b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/component.mk b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/isr.h b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/main.h b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/readme.md b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/readme.md new file mode 100644 index 0000000..b69ffcd --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/readme.md @@ -0,0 +1,78 @@ +adc_single_conv_interrupt +--- + +This example is a single channel conversion of ADC with interrupt + ++ Configure the target ADC channel (AINx) + + ``` + // in main.c + #if 1 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_08 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_02 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_09 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_03 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_10 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_04 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_11 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_05 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_12 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_06 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_13 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_07 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_06 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_08 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_07 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_09 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_14 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_10 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_15 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_11 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOB + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_00 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_12 + #elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOB + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_01 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_13 + #elif 0 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_14 + #else + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_15 + #endif + ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +Sep 30 2025 10:02:19 +ADC single channel (AIN-2) conversion with interrupt + 1-th ADC Single Conv Value = 0x920 (2336) + 2-th ADC Single Conv Value = 0x9F7 (2551) + 3-th ADC Single Conv Value = 0xB49 (2889) + 4-th ADC Single Conv Value = 0xB2F (2863) + 5-th ADC Single Conv Value = 0xB62 (2914) + ... +``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/isr.c b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/main.c b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/main.c new file mode 100644 index 0000000..a7a3a7c --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_single_conv/src/main.c @@ -0,0 +1,240 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +#define CONFIG_USE_ADC_INTERRUPT 1 + +#if 1 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_08 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_02 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_09 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_03 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_10 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_04 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_11 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_05 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_12 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_06 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_13 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_07 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_06 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_08 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_07 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_09 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_14 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_10 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_15 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_11 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOB + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_00 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_12 +#elif 0 + #define CONFIG_ADC_IO_SRC_PORT GPIOB + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_01 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_13 +#elif 0 + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_14 +#else + #define CONFIG_TARGGET_ADC_CHANNEL ADC_Channel_15 +#endif + + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint16_t g_ConvValue = 0; +static bool g_IsDone = false; +static ADC_SubChannelTypeDef g_a15_sub_chnnl = ADC_SubChannel_NONE; + +static ADC_SubChannelTypeDef g_sub_channels[] = +{ + ADC_SubChannel_TEMP, + ADC_SubChannel_DAC0, + ADC_SubChannel_DAC1, + ADC_SubChannel_VBuf_1_5, + ADC_SubChannel_VDDL, + ADC_SubChannel_VSS, + ADC_SubChannel_VDD, +}; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void ADC0_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + g_ConvValue = ADC_ITGetConvValue(ADC0, CONFIG_TARGGET_ADC_CHANNEL); + + g_IsDone = true; + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +#if defined(CONFIG_ADC_IO_SRC_PORT) && defined(CONFIG_ADC_IO_SRC_PIN) +static void _Config_AIN_IO(void) +{ + GPIO_InitTypeDef gpio_init = {0}; + + if( CONFIG_TARGGET_ADC_CHANNEL == ADC_Channel_13 ) + { + SYSCFG_SetRstPin2NormalIO(true); + } + + gpio_init.GPIO_Pin = CONFIG_ADC_IO_SRC_PIN; + gpio_init.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(CONFIG_ADC_IO_SRC_PORT, &gpio_init); + return; +} +#else + #define _Config_AIN_IO() +#endif /* CONFIG_ADC_IO_SRC_PORT */ +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + #if 1 + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + #else + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv4; + #endif + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nADC single channel (AIN-%d) conversion with interrupt\n", + __DATE__, __TIME__, (31ul - HAL_CLZ(CONFIG_TARGGET_ADC_CHANNEL))); + + _Config_AIN_IO(); + + { /* Configure ADC */ + ADC_InitTypeDef init = {0}; + + ADC_StructInit(&init); + + if( init.SelChannels == ADC_Channel_15 ) + { + ADC_SelSubChannel(g_a15_sub_chnnl); + + init.ClkPrescaler = ADC_ClkDiv_32; + } + + init.SelChannels = CONFIG_TARGGET_ADC_CHANNEL; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + + if( init.SelChannels == ADC_Channel_15 ) + { + ADC_SetSampleCycles(ADC0, 0x1F); + } + + #if defined(CONFIG_USE_ADC_INTERRUPT) && (CONFIG_USE_ADC_INTERRUPT) + { + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(ADC0_IRQn, ADC0_Handler, &irq_attr); + ADC_ITConfig(ADC0, ADC_IT_CONV_DONE); + } + #endif + } + + g_IsDone = false; + ADC_Start(ADC0); + + sys_delay(100); + + while(1) + { + static int cnt = 0; + + #if defined(CONFIG_USE_ADC_INTERRUPT) && (CONFIG_USE_ADC_INTERRUPT) + if( g_IsDone == false ) + continue; + + g_IsDone = false; + #else /* CONFIG_USE_ADC_INTERRUPT */ + g_ConvValue = ADC_GetChannelConvValue(ADC0, CONFIG_TARGGET_ADC_CHANNEL); + #endif /* CONFIG_USE_ADC_INTERRUPT */ + + cnt++; + + msg(" %d-th ADC Single Conv Value(12-bits) = 0x%02X (%d)\n", + cnt, g_ConvValue, g_ConvValue); + + if( CONFIG_TARGGET_ADC_CHANNEL == ADC_Channel_15 ) + { + log_color(SLOG_GREEN, "\n\nSet internal signal: %s\n", + (g_a15_sub_chnnl == ADC_SubChannel_TEMP ) ? "Temperature" : + (g_a15_sub_chnnl == ADC_SubChannel_DAC0 ) ? "DAC 0" : + (g_a15_sub_chnnl == ADC_SubChannel_DAC1 ) ? "DAC 1" : + (g_a15_sub_chnnl == ADC_SubChannel_VBuf_1_5 ) ? "V1.5" : + (g_a15_sub_chnnl == ADC_SubChannel_VDDL ) ? "VDDL" : + (g_a15_sub_chnnl == ADC_SubChannel_VSS ) ? "VSS" : + (g_a15_sub_chnnl == ADC_SubChannel_VDD ) ? "VDD" : + "None"); + + ADC_SelSubChannel(g_a15_sub_chnnl); + + g_a15_sub_chnnl = g_sub_channels[cnt % (sizeof(g_sub_channels)/sizeof(g_sub_channels[0]))]; + } + + ADC_Start(ADC0); + sys_delay(1000); + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.cproject b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.project b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/Project.nuproject b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/component.mk b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/isr.h b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/main.h b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/readme.md b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/readme.md new file mode 100644 index 0000000..2d9b6bd --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/readme.md @@ -0,0 +1,108 @@ +adc_trigger_src_io +--- + +This is an example to select the source (I/O) to trigger ADC start +> It uses the specific pin to trigge ADC + ++ Select the ADC converison channel + + ``` + // in main.c + #define CONFIG_ADC_IO_SRC_PORT GPIOA + #define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_09 + #define CONFIG_TARGGET_ADC_1_CHANNEL ADC_Channel_03 + ``` + ++ Select the specific pin to trigger ADC + > It supports PB1 (nRST) or PB2 (JTCK) + >> PB1/PB2 MUST be changed to normal I/O mode + + ``` + // in main.c + #define CONFIG_ADC_EXT_TRIG_SRC ADC_ExtTrigSource_PB1 + ``` + ++ Select the trigger mode of the specific pin + > It supports rising or falling trigger mode + + ``` + // in main.c + #define CONFIG_ADC_EXT_TRIG_MODE ADC_ExtTrigMode_PinRising + ``` + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Link PB1 to button + + - Trigger ADC when free button + + ``` + Oct 7 2025 15:46:32 + ADC Trigger single conversion (AIN-3) from external source (Pin: PB1 Rising) + Button = PA2 + Press Button to setup I/O trigger ... + PB1 (nRST) => I/O + 1-th ADC Single Conv Value = 0x77C (1916) <--- Trigger ADC when free button + 2-th ADC Single Conv Value = 0x778 (1912) + 3-th ADC Single Conv Value = 0x77A (1914) + 4-th ADC Single Conv Value = 0x77E (1918) + 5-th ADC Single Conv Value = 0x77F (1919) + ``` + + - Trigger ADC when press button + + ``` + Oct 7 2025 15:59:09 + ADC Trigger single conversion (AIN-3) from external source (Pin: PB1 Falling) + Button = PA2 + Press Button to setup I/O trigger ... + PB1 (nRST) => I/O + 1-th ADC Single Conv Value = 0x775 (1909) <--- Trigger ADC when press button + 2-th ADC Single Conv Value = 0x789 (1929) + 3-th ADC Single Conv Value = 0x78A (1930) + 4-th ADC Single Conv Value = 0x777 (1911) + ``` + ++ Link PB2 to button + + - Trigger ADC when free button + + ``` + Oct 7 2025 16:18:35 + ADC Trigger single conversion (AIN-3) from external source (Pin: PB2 Rising) + Button = PA2 + Press Button to setup I/O trigger ... + 1-th ADC Single Conv Value = 0x7DF (2015) <--- Link ICE handshaking + 2-th ADC Single Conv Value = 0x722 (1826) + 3-th ADC Single Conv Value = 0x6E8 (1768) + 4-th ADC Single Conv Value = 0x752 (1874) + 5-th ADC Single Conv Value = 0x748 (1864) + 6-th ADC Single Conv Value = 0x675 (1653) + PB2 (JTCK) => I/O <--- disable ICE + 7-th ADC Single Conv Value = 0x789 (1929) <--- free button + 8-th ADC Single Conv Value = 0x7E5 (2021) + ... + ``` + + - Trigger ADC when press button + + ``` + Oct 3 2025 16:22:41 + ADC Trigger single conversion (AIN-3) from external source (Pin: PB2 Falling) + Button = PA2 + Press Button to setup I/O trigger ... + ... + 31-th ADC Single Conv Value = 0x78A (1930) <--- Link ICE handshaking + 32-th ADC Single Conv Value = 0x77B (1915) + 33-th ADC Single Conv Value = 0x7A8 (1960) + 34-th ADC Single Conv Value = 0x792 (1938) + 35-th ADC Single Conv Value = 0x777 (1911) <--- Link ICE handshaking + PB2 (JTCK) => I/O <--- disable ICE + 36-th ADC Single Conv Value = 0x7EC (2028) <--- press button + 37-th ADC Single Conv Value = 0x777 (1911) + 38-th ADC Single Conv Value = 0x78E (1934) + 39-th ADC Single Conv Value = 0x792 (1938) + ``` diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/isr.c b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/main.c b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/main.c new file mode 100644 index 0000000..3389d1d --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/adc/adc_trigger_src_io/src/main.c @@ -0,0 +1,223 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +#define CONFIG_ADC_IO_SRC_PORT GPIOA +#define CONFIG_ADC_IO_SRC_PIN GPIO_Pin_09 +#define CONFIG_TARGGET_ADC_1_CHANNEL ADC_Channel_03 + +/** + * I/O triggr is PB1 or PB2 + * + ADC_ExtTrigSource_PB1 + * + ADC_ExtTrigSource_PB2 + */ +#define CONFIG_ADC_EXT_TRIG_SRC ADC_ExtTrigSource_PB1 + +/** + * Trigger edge + * + ADC_ExtTrigMode_PinRising + * + ADC_ExtTrigMode_PinFaling + */ +#define CONFIG_ADC_EXT_TRIG_MODE ADC_ExtTrigMode_PinFaling + +/* Input Key I/O definitions */ +#define CONFIG_GPIO_INPUT_PORTx GPIOA +#define CONFIG_GPIO_INPUT_PINx GPIO_Pin_02 +#define CONFIG_GPIO_IRQ GPIOA_IRQn // GPIOB_IRQn +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint16_t g_ConvValue = 0; +static bool g_IsDone = false; +static bool g_hasPullLow = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + if( GPIO_GetITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx) ) + { + GPIO_ClearITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + g_hasPullLow = true; + } + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +__INTERRUPT void ADC0_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + g_ConvValue = ADC_ITGetConvValue(ADC0, CONFIG_TARGGET_ADC_1_CHANNEL); + + g_IsDone = true; + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +static void _Config_ButtonIO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + msg(" Button = P%s%d\n", + (CONFIG_GPIO_INPUT_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_GPIO_INPUT_PINx)); + + GPIO_InitStruct.GPIO_Pin = CONFIG_GPIO_INPUT_PINx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN ; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Level; + GPIO_InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_GPIO_INPUT_PORTx , &GPIO_InitStruct); + + GPIO_ITEnable(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + return; +} + +static void _Config_AIN_IO(void) +{ + GPIO_InitTypeDef gpio_init = {0}; + + gpio_init.GPIO_Pin = CONFIG_ADC_IO_SRC_PIN; + gpio_init.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(CONFIG_ADC_IO_SRC_PORT, &gpio_init); + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + REG_WRITE(SYSCFG->PRSTEN1, 0xFFFFFFFFul); + REG_WRITE(SYSCFG->PRSTEN, 0xFFFFFFFFul); + REG_WRITE(SYSCFG->PRSTEN1, 0x0ul); + REG_WRITE(SYSCFG->PRSTEN, 0x0ul); + + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nADC Trigger single conversion (AIN-%d) from external source (Pin: %s %s)\n", + __DATE__, __TIME__, + (31ul - HAL_CLZ(CONFIG_TARGGET_ADC_1_CHANNEL)), + (CONFIG_ADC_EXT_TRIG_SRC == ADC_ExtTrigSource_PB1) ? "PB1" : + (CONFIG_ADC_EXT_TRIG_SRC == ADC_ExtTrigSource_PB2) ? "PB2" : + "N/A", + (CONFIG_ADC_EXT_TRIG_MODE == ADC_ExtTrigMode_PinRising) ? "Rising" : "Falling" + ); + + _Config_ButtonIO(); + _Config_AIN_IO(); + + g_hasPullLow = false; + + { /* Configure ADC */ + ADC_InitTypeDef init = {0}; + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(ADC0_IRQn, ADC0_Handler, &irq_attr); + sys_register_IRQ(CONFIG_GPIO_IRQ, GPIOx_Handler, &irq_attr); + + ADC_StructInit(&init); + + init.SelChannels = CONFIG_TARGGET_ADC_1_CHANNEL; + init.IsSoftTrig = false; + ADC_Init(ADC0, &init); + + ADC_ExtTrigConfig(ADC0, CONFIG_ADC_EXT_TRIG_SRC, CONFIG_ADC_EXT_TRIG_MODE); + ADC_ITConfig(ADC0, ADC_IT_CONV_DONE); + } + + g_IsDone = false; + + /* User makes External-Pin Rising/Falling to trigger ADC start */ + msg("Press Button to setup I/O trigger ...\n"); + + while(1) + { + static int cnt = 0; + + if( g_hasPullLow == true ) + { + static int is_io_mode = false; + GPIO_InitTypeDef gpio_init = {0}; + + g_hasPullLow = false; + + if( CONFIG_ADC_EXT_TRIG_SRC == ADC_ExtTrigSource_PB1 ) + { + SYSCFG_SetRstPin2NormalIO(true); + + gpio_init.GPIO_Pin = GPIO_Pin_01; + msg(" PB1 (nRST) => I/O\n"); + } + else if( CONFIG_ADC_EXT_TRIG_SRC == ADC_ExtTrigSource_PB2 ) + { + SYSCFG_SetICEPin2NormalIO(true); + + gpio_init.GPIO_Pin = GPIO_Pin_02; + msg(" PB2 (JTCK) => I/O\n"); + } + + if( is_io_mode == false ) + { + gpio_init.GPIO_Mode = GPIO_Mode_IN; + gpio_init.GPIO_PuPd = GPIO_PuPd_UP; + gpio_init.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIOB , &gpio_init); + + is_io_mode = true; + } + } + + if( g_IsDone == false ) + continue; + + cnt++; + + msg(" %d-th ADC Single Conv Value = 0x%02X (%d)\n", + cnt, g_ConvValue, g_ConvValue); + + g_IsDone = false; + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.cproject b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.project b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/Project.nuproject b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/component.mk b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/isr.h b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/main.h b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/readme.md b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/readme.md new file mode 100644 index 0000000..e9ae499 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/readme.md @@ -0,0 +1,174 @@ +comp_src_io +--- + +This example is used to run comparator with sources from I/O + ++ VinP (Input-plus type of the Comparator) support 4 I/O sources + > I/O 0 ~ 4 type + + - PEC930 + > + I/O 0: PA8 + > + I/O 1: PA11 + > + I/O 2: PA14 + > + I/O 3: PA15 + ++ VinM (Input-minus type of the Comparator) only support 1 I/O source + > + COMP_0: PA6 + > + COMP_1: PA12 + +### Use interrupt/polling mode + +```c +// at main.c +/** + * + Use polling mode when CONIFG_USE_COMP_INTERRUPT = 0 + * + Use interrupt mode when CONIFG_USE_COMP_INTERRUPT = 1 + */ +#define CONIFG_USE_COMP_INTERRUPT 0 +``` + +### Select the target COMP module + +```c +// at main.c +/** + * Use COMP0 or COMP1 + * ps. Use the COMP0 when unmark + * Use the COMP1 when mark + */ +#define CONFIG_USE_COMP0 +``` + +### Select the target I/O type of VinP + +```c +// at main.c +/** + * Select the target I/O type of VinP + * + Use I/O 0 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 0 + * + Use I/O 1 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 1 + * + Use I/O 2 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 2 + * + Use I/O 3 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 3 + */ +#define CONIFG_TERGET_COMP_VinP_IO_IDX 0 +``` + +### Select the interrupt types + +> + COMP triggers the rising event when `VinP > VinM` +> + COMP triggers the falling event when `VinP < VinM` + +``` +// at main.c +/** + * Configure status flags of COMP + * + COMP_IE_Falling + * + COMP_IE_Rising + */ +#define CONFIG_COMP_WATCH_STATE (COMP_IE_Rising | COMP_IE_Falling) +``` + + +## Operation flow + ++ Step 1. Connect the I/O of VinP (`CONIFG_TERGET_COMP_VinP_IO_IDX`) and VinM with an external device (e.g. power support) which provide difference voltage ++ Step 2. Respectively, set the specific voltage to external device (e.g. power support) to link the I/O of VinP and VinM ++ Step 3. Modify the VinP voltage of external device (e.g. power support) ++ Step 4. Observe the message has match the relation of VinP and VinM or not + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Polling mode + > modify VinP voltage with external device + + ``` + Dec 19 2025 16:19:55 + COMP0 compares the voltage from I/O + COMP Vin+ = PA8 + COMP Vin- = PA6 + The target status (Rising/Falling) of COMP + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + ``` + ++ Interrupt mode + > modify VinP voltage with external device + + - Rising and Falling events + + ``` + Dec 19 2025 15:27:53 + COMP0 compares the voltage from I/O + COMP Vin+ = PA8 + COMP Vin- = PA6 + The target status (Rising/Falling) of COMP + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + ``` + + - Rising event + + ``` + Dec 19 2025 16:16:33 + COMP0 compares the voltage from I/O + COMP Vin+ = PA8 + COMP Vin- = PA6 + The target status (Rising/-) of COMP + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + + @COMP Event + Get (Rising edge) Vin+ > Vin- + ``` + + - Falling event + + ``` + Dec 19 2025 16:18:40 + COMP0 compares the voltage from I/O + COMP Vin+ = PA8 + COMP Vin- = PA6 + The target status (-/Falling) of COMP + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + + @COMP Event + Get (Falling edge) Vin+ < Vin- + ``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/isr.c b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/main.c b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/main.c new file mode 100644 index 0000000..89fc825 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/comp/comp_src_io/src/main.c @@ -0,0 +1,251 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * + Use polling mode when CONIFG_USE_COMP_INTERRUPT = 0 + * + Use interrupt mode when CONIFG_USE_COMP_INTERRUPT = 1 + */ +#define CONIFG_USE_COMP_INTERRUPT 0 + +/** + * Use COMP0 or COMP1 + * ps. Use the COMP0 when unmark + * Use the COMP1 when mark + */ +#define CONFIG_USE_COMP0 + +/** + * Select the target I/O type of VinP + * + Use I/O 0 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 0 + * + Use I/O 1 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 1 + * + Use I/O 2 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 2 + * + Use I/O 3 as VinP if CONIFG_TERGET_COMP_VinP_IO_IDX is 3 + */ +#define CONIFG_TERGET_COMP_VinP_IO_IDX 0 + + +#if defined(CONFIG_USE_COMP0) + #define COMPx COMP0 + #define COMPx_IRQn COMP0_IRQn + + #define CONFIG_COMP_VinM_PORTx GPIOA + #define CONFIG_COMP_VinM_PINx GPIO_Pin_06 + +#else + #define COMPx COMP1 + #define COMPx_IRQn COMP1_IRQn + + #define CONFIG_COMP_VinM_PORTx GPIOA + #define CONFIG_COMP_VinM_PINx GPIO_Pin_12 + +#endif + +#if (CONIFG_TERGET_COMP_VinP_IO_IDX == 0) + #define CONFIG_COMP_VinP_IO_PORTx GPIOA + #define CONFIG_COMP_VinP_IO_PINx GPIO_Pin_08 +#elif (CONIFG_TERGET_COMP_VinP_IO_IDX == 1) + #define CONFIG_COMP_VinP_IO_PORTx GPIOA + #define CONFIG_COMP_VinP_IO_PINx GPIO_Pin_11 +#elif (CONIFG_TERGET_COMP_VinP_IO_IDX == 2) + #define CONFIG_COMP_VinP_IO_PORTx GPIOA + #define CONFIG_COMP_VinP_IO_PINx GPIO_Pin_14 +#elif (CONIFG_TERGET_COMP_VinP_IO_IDX == 3) + #define CONFIG_COMP_VinP_IO_PORTx GPIOA + #define CONFIG_COMP_VinP_IO_PINx GPIO_Pin_15 +#else + #error "Wrong VinP I/O index !" +#endif + +#if defined(CONIFG_USE_COMP_INTERRUPT) && (CONIFG_USE_COMP_INTERRUPT) + /** + * Configure status flags of COMP + * + COMP_IE_Falling + * + COMP_IE_Rising + */ + #define CONFIG_COMP_WATCH_STATE (COMP_IE_Rising | COMP_IE_Falling) +#endif + +typedef enum comp_event +{ + COMP_EVENT_NONE = 0, + COMP_EVENT_VinP_GT_VinM = (0x1ul << 0), + COMP_EVENT_VinP_LT_VinM = (0x1ul << 1), + COMP_EVENT_BOTH = (COMP_EVENT_VinP_GT_VinM | COMP_EVENT_VinP_LT_VinM), +} comp_event_t; +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static comp_event_t g_comp_event = COMP_EVENT_NONE; +static int g_prev_state = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void COMPx_Handler(void) +{ + uint32_t flags = 0; + uint32_t it_en_flags = 0; + + SAVE_IRQ_CSR_CONTEXT(); + + it_en_flags = COMP_GetITFlags(COMPx); + flags = COMP_GetFlagStatus(COMPx, COMP_IE_ALL); + + COMP_ClearFlag(COMPx, flags); + + if( (flags & COMP_IE_Rising) & it_en_flags ) + g_comp_event |= COMP_EVENT_VinP_GT_VinM; + + if( (flags & COMP_IE_Falling) & it_en_flags ) + g_comp_event |= COMP_EVENT_VinP_LT_VinM; + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + + +static void _Config_IO(void) +{ + GPIO_InitTypeDef gpio_init = {0}; + + msg(" COMP Vin+ = P%s%d\n", + (CONFIG_COMP_VinP_IO_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_COMP_VinP_IO_PINx)); + + msg(" COMP Vin- = P%s%d\n", + (CONFIG_COMP_VinM_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_COMP_VinM_PINx)); + + // Vin- + gpio_init.GPIO_Pin = CONFIG_COMP_VinM_PINx; + gpio_init.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_Init(CONFIG_COMP_VinM_PORTx, &gpio_init); + + // Vin+ + gpio_init.GPIO_Pin = CONFIG_COMP_VinP_IO_PINx; + GPIO_Init(CONFIG_COMP_VinP_IO_PORTx, &gpio_init); + + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = { .ClkSource = SYSCFG_ClkSrc_HSI, }; + + #if 0 + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv2; + #endif + + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nCOMP%d compares the voltage from I/O\n", + __DATE__, __TIME__, + (COMPx == COMP0) ? 0 : 1); + + g_comp_event = COMP_EVENT_NONE; + + _Config_IO(); + + { /* Initialize COMP */ + COMP_InitTypeDef init = {0}; + + COMP_StructInit(&init); + + init.InputPlus = (CONIFG_TERGET_COMP_VinP_IO_IDX == 0) ? COMP_VinP_IO0 : + (CONIFG_TERGET_COMP_VinP_IO_IDX == 1) ? COMP_VinP_IO1 : + (CONIFG_TERGET_COMP_VinP_IO_IDX == 2) ? COMP_VinP_IO2 : + COMP_VinP_IO3; + init.InputMinus = COMP_VinM_IO; + init.InputHysteresis = COMP_Hysteresis_Enable; + init.FilterFreq = COMP_Filter_Sample_4; + init.OutputPolarity = COMP_OutPolarity_Normal; + init.OutputSel = COMP_Vout_IO; // COMP_Vout_None; + COMP_Init(COMPx, &init); + } + +#if defined(CONIFG_USE_COMP_INTERRUPT) && (CONIFG_USE_COMP_INTERRUPT) + { /* Configure Interrupt */ + COMP_IETypeDef flags = 0; + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(COMPx_IRQn, COMPx_Handler, &irq_attr); + + flags = CONFIG_COMP_WATCH_STATE; + msg(" The target status (%s/%s) of COMP\n", + (flags & COMP_IE_Rising) ? "Rising" : "-", + (flags & COMP_IE_Falling) ? "Falling" : "-"); + + COMP_ITConfig(COMPx, flags); + } +#endif + + COMP_Enable(COMPx); + COMP_ClearFlag(COMPx, COMP_IE_ALL); + + while(1) + { + #if defined(CONIFG_USE_COMP_INTERRUPT) && (CONIFG_USE_COMP_INTERRUPT) + if( g_comp_event == COMP_EVENT_NONE ) + continue; + + msg("\n @COMP Event\n"); + if( g_comp_event & COMP_EVENT_VinP_GT_VinM ) + { + HAL_ClearBits(g_comp_event, COMP_EVENT_VinP_GT_VinM); + msg(" Get (Rising edge) Vin+ > Vin- \n"); + } + + if( g_comp_event & COMP_EVENT_VinP_LT_VinM ) + { + HAL_ClearBits(g_comp_event, COMP_EVENT_VinP_LT_VinM); + msg(" Get (Falling edge) Vin+ < Vin- \n"); + } + #else + int rt_state = 0; + + rt_state = COMP_GetOutputLevel(COMPx); + + if( rt_state == g_prev_state ) + continue; + + g_prev_state = rt_state; + msg(" COMP Vin+ %s Vin- \n", rt_state ? ">" : "<"); + #endif + + sys_delay(1000); + } +} diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.cproject b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.project b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/Project.nuproject b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/component.mk b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/isr.h b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/main.h b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/readme.md b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/readme.md new file mode 100644 index 0000000..ceabdac --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/readme.md @@ -0,0 +1,89 @@ +crc_calculate +--- + +This example is used to calculate CRC 16/32. + ++ Use CRC16 + + ```c + // at main.c + #define CONFIG_USE_CRC16 1 + ``` + ++ Use CRC32 + + ```c + // at main.c + #define CONFIG_USE_CRC16 0 + ``` + +# Log + +Use serial port with baudrate 115200 8bit, no parity check.
    +User can receive log infomation from `PA00(Uart TXD)` of DUT. + ++ CRC16 + + ``` + 11:50:46 + This example to calculates CRC16. + + data:200001C8 | A1 98 EE 82 A5 4B 5D 90 - 11 30 AC F5 2F 54 EB 64 + data:200001D8 | 02 CC 74 C5 85 14 E8 FA - B3 66 8D CB 9E 16 6C 0A + data:200001E8 | FB 03 7B 69 BC 8E 36 D3 - 32 F5 3A D5 D1 7D 05 20 + data:200001F8 | 29 8D 79 F9 65 18 06 B4 - 99 79 47 73 90 AD 16 B4 + data:20000208 | E0 70 C9 A7 7B 69 5B 46 - 12 E2 56 B1 62 2D 1A 52 + data:20000218 | 4C 3C 14 95 82 0E 16 E5 - 98 E3 87 0F 55 61 A5 80 + data:20000228 | 56 77 D1 30 B4 CD BB A0 - 33 FD BD B1 DD 7F 04 9A + data:20000238 | 41 0E 03 CA FA 31 C7 E9 - 9D B1 41 0C 00 CD B6 14 + + Expected CRC16: 0x00006679 + + data-stream: + crc= 0x00006679 + CRC verify OK~~ + + byte by byte: + crc= 0x00006679 + CRC verify OK~~ + + two-part accumulation: + crc= 0x00004546 (addr: 0x200001C8 ~ 0x20000207) + crc= 0x00006679 (accumulate to 0x20000247) + CRC verify OK~~ + + CRC done~~ + ``` + ++ CRC32 + + ``` + 11:52:08 + This example to calculates CRC32. + + data:200001C8 | A6 98 9F 82 5A 48 5A AF - 6F BE B1 0A CB 54 63 64 + data:200001D8 | 92 C0 54 1A C5 54 6E 77 - D0 A1 72 37 9E 2D 6C CA + data:200001E8 | FA 8E 65 AA 67 38 31 D1 - 43 DE C5 3D D7 2D 6C 80 + data:200001F8 | 6A CE C0 4B 80 50 96 A8 - BD 86 46 73 8D A2 F1 57 + data:20000208 | 57 80 D0 47 D9 A9 38 CB - E5 2A C6 A2 43 39 42 3F + data:20000218 | 72 3F 8C AA 3B 8C F5 CF - 60 1F F1 3A D3 51 CE EA + data:20000228 | 36 0E 17 58 56 9D 5B 0F - F8 51 92 23 7E 74 77 34 + data:20000238 | 9C BB 68 FE 93 15 89 E9 - E3 B1 59 0F B9 F5 54 E6 + + Expected CRC32: 0xAF32ACDE + + data-stream: + crc= 0xAF32ACDE + CRC verify OK~~ + + byte by byte: + crc= 0xAF32ACDE + CRC verify OK~~ + + two-part accumulation: + crc= 0x55325724 (addr: 0x200001C8 ~ 0x20000207) + crc= 0xAF32ACDE (accumulate to 0x20000247) + CRC verify OK~~ + + CRC done~~ + ``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/isr.c b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/main.c b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/main.c new file mode 100644 index 0000000..5bfd00b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/crc/crc_calculate/src/main.c @@ -0,0 +1,194 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author CT + * @version 0.1 + * @date 2024/10/28 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include + +#include +#include + +/* #include "gdb_peri.h" */ + +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_CRC16 1 + +#if (CONFIG_USE_CRC16) + #define CONFIG_USE_CRC_WIDTH CRC_Width_CRC16 +#else + #define CONFIG_USE_CRC_WIDTH CRC_Width_CRC32 +#endif + +#define CONFIG_DATA_SIZE 128 +#define CONFIG_HALF_PART_SIZE (CONFIG_DATA_SIZE >> 1) + +/** + * Data offset for word/hword/byte align + * + '0': word + * + '2': half-word + * + '1': byte + */ +#define CONFIG_DATA_OFFSET 0 + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint8_t g_data[CONFIG_DATA_SIZE] = {0}; +//============================================================================= +// Private Function Definition +//============================================================================= +static __used uint16_t _Calc_crc16(uint8_t *c, int n, uint16_t crc16) +{ +#define CRC16POLY1 0x1021U +#define CRC16POLY2 0x8408U /* left-right reversal */ + + for(int i = 0; i < n; i++) + { + crc16 ^= c[i]; + for(int j = 0; j < 8; j++) + { + if (crc16 & 0x1) + crc16 = (crc16 >> 1) ^ CRC16POLY2; + else + crc16 >>= 1; + } + } + return crc16 ^ 0xFFFFU; +} + +static __used uint32_t _Calc_crc32(uint8_t *c, int n, uint32_t crc32) +{ +#define CRC32POLY1 0x04C11DB7U +#define CRC32POLY2 0xEDB88320U /* left-right reversal */ + + for(int i = 0; i < n; i++) + { + crc32 ^= c[i]; + for(int j = 0; j < 8; j++) + { + if (crc32 & 0x1) + crc32 = (crc32 >> 1) ^ CRC32POLY2; + else + crc32 >>= 1; + } + } + return crc32 ^ 0xFFFFFFFFU; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + uint32_t expected_crc_value = 0; + uint32_t crc_value = 0; + + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s\nThis example to calculates %s.\n", + __TIME__, + #if (CONFIG_USE_CRC16) + "CRC16" + #else + "CRC32" + #endif + ); + + /** + * Prepare the data stream + */ + /* HAL_SRand(sys_get_tick()); */ + for(int i = 0; i < sizeof(g_data); i++) + { + g_data[i] = HAL_Rand() & 0xFF; + } + + syslog_dump_mem("data:", (uint32_t*)&g_data, sizeof(g_data), false); + +#if (CONFIG_USE_CRC16) + expected_crc_value = _Calc_crc16((uint8_t*)&g_data[CONFIG_DATA_OFFSET], + sizeof(g_data) - CONFIG_DATA_OFFSET, (uint16_t)CRC_START_CODE); + msg("Expected CRC16: 0x%08X\n", (int)expected_crc_value); +#else + expected_crc_value = _Calc_crc32((uint8_t*)&g_data[CONFIG_DATA_OFFSET], + sizeof(g_data) - CONFIG_DATA_OFFSET, (uint32_t)CRC_START_CODE); + msg("Expected CRC32: 0x%08X\n", (int)expected_crc_value); +#endif + + CRC_Init(); + + msg("\n data-stream:\n"); + crc_value = CRC_CalcBlockCRC((uint8_t*)&g_data[CONFIG_DATA_OFFSET], + sizeof(g_data) - CONFIG_DATA_OFFSET, CONFIG_USE_CRC_WIDTH); + msg(" crc= 0x%08X\n", (int)crc_value); + if( CRC_VerifyFlag(expected_crc_value) == 0 ) + err(" CRC verify fail !\n"); + else + msg(" CRC verify OK~~\n"); + + + msg("\n byte by byte:\n"); + CRC_Init(); + + for(int i = CONFIG_DATA_OFFSET; i < sizeof(g_data); i++) + CRC_CalcCRC((uint8_t*)&g_data[i], CONFIG_USE_CRC_WIDTH); + + msg(" crc= 0x%08X\n", (int)CRC_GetCRC()); + if( CRC_VerifyFlag(expected_crc_value) == 0 ) + err(" CRC verify fail !\n"); + else + msg(" CRC verify OK~~\n"); + + + msg("\n two-part accumulation:\n"); + CRC_Init(); + + crc_value = CRC_CalcBlockCRC((uint8_t*)&g_data[CONFIG_DATA_OFFSET], + CONFIG_HALF_PART_SIZE - CONFIG_DATA_OFFSET, CONFIG_USE_CRC_WIDTH); + msg(" crc= 0x%08X (addr: 0x%08X ~ 0x%08X)\n", + (int)crc_value, (int)&g_data[CONFIG_DATA_OFFSET], (int)&g_data[CONFIG_HALF_PART_SIZE-1]); + + crc_value = CRC_CalcBlockCRC((uint8_t*)&g_data[CONFIG_HALF_PART_SIZE], CONFIG_HALF_PART_SIZE, CONFIG_USE_CRC_WIDTH); + msg(" crc= 0x%08X (accumulate to 0x%08X)\n", (int)crc_value, (int)&g_data[CONFIG_DATA_SIZE] - 1); + if( CRC_VerifyFlag(expected_crc_value) == 0 ) + err(" CRC verify fail !\n"); + else + msg(" CRC verify OK~~\n"); + + msg("\nCRC done~~\n"); + + while(1) + { + __NOP(); + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/.cproject b/pec930_sdk-v1.0.1/Examples/dac/dac_base/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/.project b/pec930_sdk-v1.0.1/Examples/dac/dac_base/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/Project.nuproject b/pec930_sdk-v1.0.1/Examples/dac/dac_base/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/component.mk b/pec930_sdk-v1.0.1/Examples/dac/dac_base/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/isr.h b/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/main.h b/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/readme.md b/pec930_sdk-v1.0.1/Examples/dac/dac_base/readme.md new file mode 100644 index 0000000..39f4b87 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/readme.md @@ -0,0 +1,62 @@ +dac_base +--- + +This example is used to demo the usage of DAC +> It is a `10-bits DAC` + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ DAC0 + - Measure DAC outupt (PA8) + > + `step= 0`, PA8 Output= 1 mV + > + `step= 128`, PA8 Output= 407 mV + > + `step= 256`, PA8 Output= 815 mV + > + `step= 384`, PA8 Output= 1219 mV + > + `step= 512`, PA8 Output= 1627 mV + > + `step= 640`, PA8 Output= 2017 mV + > + `step= 768`, PA8 Output= 2413 mV + > + `step= 896`, PA8 Output= 2825 mV + > + `step= 1023`, PA8 Output= 3231 mV + + ``` + Oct 1 2025 16:42:52 + Run DAC-0 and output to PA8 <--- If VDD = 3300 + DAC step= 0, Expect Output= 0 mV + DAC step= 128, Expect Output= 412 mV + DAC step= 256, Expect Output= 825 mV + DAC step= 384, Expect Output= 1237 mV + DAC step= 512, Expect Output= 1650 mV + DAC step= 640, Expect Output= 2062 mV + DAC step= 768, Expect Output= 2475 mV + DAC step= 896, Expect Output= 2887 mV + DAC step= 1023, Expect Output= 3296 mV + ``` + ++ DAC1 + - Measure DAC outupt (PA8) + > + `step= 0`, PA8 Output= 1 mV + > + `step= 128`, PA8 Output= 408 mV + > + `step= 256`, PA8 Output= 815 mV + > + `step= 384`, PA8 Output= 1218 mV + > + `step= 512`, PA8 Output= 1628 mV + > + `step= 640`, PA8 Output= 2018 mV + > + `step= 768`, PA8 Output= 2413 mV + > + `step= 896`, PA8 Output= 2825 mV + > + `step= 1023`, PA8 Output= 3231 mV + + ``` + Oct 1 2025 16:50:50 + Run DAC-1 and output to PA8 <--- If VDD = 3300 + DAC step= 0, Expect Output= 0 mV + DAC step= 128, Expect Output= 412 mV + DAC step= 256, Expect Output= 825 mV + DAC step= 384, Expect Output= 1237 mV + DAC step= 512, Expect Output= 1650 mV + DAC step= 640, Expect Output= 2062 mV + DAC step= 768, Expect Output= 2475 mV + DAC step= 896, Expect Output= 2887 mV + DAC step= 1023, Expect Output= 3296 mV + ``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/isr.c b/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/main.c b/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/main.c new file mode 100644 index 0000000..00b66d1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dac/dac_base/src/main.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_DAC0 0 + +/** + * The reference mVoltage of ADC on board + */ +#define CONFIG_ADC_REF_mVOLTAGE 3300 // 5000 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + #if 1 + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + #else + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv2; + #endif + + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nRun DAC-%d and output to PA8\n", + __DATE__, __TIME__, (CONFIG_USE_DAC0) ? 0 : 1); + + AMISC_Init(); + + for(int dac_step = 0; dac_step <= (0x1ul << 10); dac_step += ((0x1ul << 10) >> 3)) + { + dac_step = (dac_step == (0x1ul << 10)) ? (0x1ul << 10) -1 : dac_step; + + #if defined(CONFIG_USE_DAC0) && (CONFIG_USE_DAC0) + AMISC_OutInternalSignalToIO(AMISC_InternalSrc_DAC0, true); + + AMISC_DAC0_Config(dac_step); + AMISC_DAC0_Enable(); + #else + AMISC_OutInternalSignalToIO(AMISC_InternalSrc_DAC1, true); + + AMISC_DAC1_Config(dac_step); + AMISC_DAC1_Enable(); + #endif + + msg(" DAC step= %d, Expect Output= %d mV\n", + dac_step, (dac_step * CONFIG_ADC_REF_mVOLTAGE) >> 10); + + sys_delay(1000); + } + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.cproject b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.project b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/Project.nuproject b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/component.mk b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/isr.h b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/main.h b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/readme.md b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/readme.md new file mode 100644 index 0000000..dc80123 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/readme.md @@ -0,0 +1,81 @@ +dsp_divide +--- + +This example is a demo project to calculate divide with DSP +> Support `signed 32-bits` input + ++ the remainder + > + In math theory, the remainder should be `>= 0` + > + In computer implementation, the remainder may be sign + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +14:09:45 +This is a demo project to calculat divide with DSP +Calculate -696395606/254485144: + DSP: -2...187425318 + SW : -2...187425318 +Calculate 960610547/194190880: + DSP: 4...183847027 + SW : 4...183847027 +Calculate 53174450/-1858707637: + DSP: 0...53174450 + SW : 0...53174450 +Calculate -2037599628/552396449: + DSP: -3...380410281 + SW : -3...380410281 +Calculate 1207792136/-457186971: + DSP: -2...293418194 + SW : -2...293418194 +Calculate -624636222/1570295625: + DSP: 0...624636222 + SW : 0...624636222 +Calculate -1198278299/-885072939: + DSP: 1...313205360 + SW : 1...313205360 +Calculate 407759637/1611478605: + DSP: 0...407759637 + SW : 0...407759637 +Calculate 967964410/-1150596243: + DSP: 0...967964410 + SW : 0...967964410 +Calculate -674502209/610867640: + DSP: -1...63634569 + SW : -1...63634569 +Calculate -388411390/-1696873075: + DSP: 0...388411390 + SW : 0...388411390 +Calculate 261576971/-1546613682: + DSP: 0...261576971 + SW : 0...261576971 +Calculate -2004069415/1563427714: + DSP: -1...440641701 + SW : -1...440641701 +Calculate -439982405/-2110095024: + DSP: 0...439982405 + SW : 0...439982405 +Calculate 576556116/-1770983411: + DSP: 0...576556116 + SW : 0...576556116 +Calculate -1910913220/-453320577: + DSP: 4...97630912 + SW : 4...97630912 +Calculate 1229840007/2045052399: + DSP: 0...1229840007 + SW : 0...1229840007 +Calculate 227256829/1222470193: + DSP: 0...227256829 + SW : 0...227256829 +Calculate 600388003/1510945259: + DSP: 0...600388003 + SW : 0...600388003 +Calculate -839901652/-1917673492: + DSP: 0...839901652 + SW : 0...839901652 +done~~~ + +``` + diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/isr.c b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/main.c b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/main.c new file mode 100644 index 0000000..27cc276 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_divide/src/main.c @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include +#include +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s\nThis is a demo project to calculat divide with DSP\n", __TIME__); + + __HAL_SYSCFG_DSP_CLK_ENABLE(); + + for(int cnt = 0; cnt < 20; cnt++) + { + int numerator = 0, denominator = 0; + int Quotient = 0, Remainder = 0; + + numerator = HAL_Rand(); + denominator = HAL_Rand(); + + DSP_Div32(numerator, denominator, &Quotient, &Remainder); + + msg("Calculate %d/%d:\n", numerator, denominator); + msg(" DSP: %d...%d\n", Quotient, Remainder); + msg(" SW : %d...%d\n", (numerator/denominator), (numerator%denominator)); + } + + msg("done~~~\n"); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.cproject b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.project b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/Project.nuproject b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/component.mk b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/isr.h b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/main.h b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/readme.md b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/readme.md new file mode 100644 index 0000000..52e734b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/readme.md @@ -0,0 +1,77 @@ +dsp_sqrt +--- + +This example is a demo project to calculate sqrt with DSP +> Support to input `unsigned 64-bits` values + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +13:49:12 +This is a demo project to calculat square root with DSP +square root of 1285064488: + DSP: 35847 + SW : 35847 +square root of 2029536100: + DSP: 45050 + SW : 45050 +square root of 3986797496: + DSP: 63141 + SW : 63141 +square root of 243657094: + DSP: 15609 + SW : 15609 +square root of 3954601218: + DSP: 62885 + SW : 62885 +square root of 3274404210: + DSP: 57222 + SW : 57222 +square root of 2272361996: + DSP: 47669 + SW : 47669 +square root of 1348358280: + DSP: 36719 + SW : 36719 +square root of 2143185402: + DSP: 46294 + SW : 46294 +square root of 1611702454: + DSP: 40146 + SW : 40146 +square root of 2651961574: + DSP: 51497 + SW : 51497 +square root of 2217312272: + DSP: 47088 + SW : 47088 +square root of 2377225393: + DSP: 48756 + SW : 48756 +square root of 3369961082: + DSP: 58051 + SW : 58051 +square root of 3553778770: + DSP: 59613 + SW : 59613 +square root of 3301112800: + DSP: 57455 + SW : 57455 +square root of 4229335839: + DSP: 65033 + SW : 65033 +square root of 2794502198: + DSP: 52863 + SW : 52863 +square root of 2327378881: + DSP: 48242 + SW : 48242 +square root of 584525248: + DSP: 24176 + SW : 24176 +done~~~ + + +``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/isr.c b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/main.c b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/main.c new file mode 100644 index 0000000..b841255 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/dsp/dsp_sqrt/src/main.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include +#include +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s\nThis is a demo project to calculat square root with DSP\n", __TIME__); + + __HAL_SYSCFG_DSP_CLK_ENABLE(); + + for(int cnt = 0; cnt < 20; cnt++) + { + DSP_SqrtParamTypeDef param = {0}; + + param.value64 = HAL_Rand() * HAL_Rand(); + + msg("square root of %lu:\n", param.value64); + msg(" DSP: %u\n", DSP_Sqrt32(¶m)); + msg(" SW : %u\n", (uint32_t)sqrt((double)param.value64)); + } + + msg("done~~~\n"); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.cproject b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.project b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/Project.nuproject b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/component.mk b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/isr.h b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/main.h b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/main.h new file mode 100644 index 0000000..bd118fa --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/inc/main.h @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * + 10KB: 0x2800 + */ +#define FLASH_PROG_ADDR_START (13ul << 10) +#define FLASH_PROG_ADDR_END sizeof(EFLASH_MEM_Type) +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/readme.md b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/readme.md new file mode 100644 index 0000000..5ae68bd --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/readme.md @@ -0,0 +1,60 @@ +flash_prog_erase +--- + +This example is a demo project to P/E (Program/Erase) main-area of eFlash. +> The execute-bin will occupy front area of eFlash, + as the result P/E the other area of eFlash + +There are 3-case in this example +> + word data +> + half-word data +> + byte data + +The execute-flow of every case: + ++ Erase eFalsh (secotr by sector) and verify word-data is `0xFFFFFFFF` or not + > If the word-data is NOT `0xFFFFFFFF`, it will stop procedure and log error message + ++ Program **word/hword/byte-data** to eFlash and verify the result value of eFlash + > If the data is NOT match, it will stop procedure and log error message + +It also supports fix/random pattern + ++ Fix pattern is `0x5A5A5A5Aul` ++ Random pattern + > User should modify `CONFIG_USE_RAND_DATA` as below + > ``` + > // at main.c + > /** + > * Use random data as pattern + > */ + > #define CONFIG_USE_RAND_DATA 1 + > ``` + +If user wants to get more detail message, unmark `CONFIG_MORE_MESSAGE` definition + +```c +// at main.c +/** + * Get more log message + */ +#define CONFIG_MORE_MESSAGE +``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + +``` +Oct 13 2025 14:12:47 +This is eFlash Erase/Program/Read (0x00003400 ~ 0x00008000) example +## P/E with word value + done~ +## P/E with half-word value + done~ +## P/E with byte value + done~ +## P/E with data stream (32-bits valule and 4-aling length) + done~ +done ~~~~~~ +``` diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/isr.c b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/main.c b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/main.c new file mode 100644 index 0000000..59db641 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/flash/flash_prog_erase/src/main.c @@ -0,0 +1,365 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#include +#include +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Get more log message + */ +// #define CONFIG_MORE_MESSAGE + +/** + * Use random data as pattern + */ +#define CONFIG_USE_RAND_DATA 0 + +#define CONFIG_PATTERN_BYTE_1 0x5Au +#define CONFIG_PATTERN_BYTE_2 0xA5u +#define CONFIG_PATTERN_HWORD_1 0x5A5Au +#define CONFIG_PATTERN_HWORD_2 0xA5A5u +#define CONFIG_PATTERN_WORD_1 0x5A5A5A5Aul +#define CONFIG_PATTERN_WORD_2 0xA5A5A5A5ul +//============================================================================= +// Macro Definition +//============================================================================= +#if !defined(CONFIG_MORE_MESSAGE) +#undef dbg +#define dbg(str, ...) +#endif +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint32_t g_buf[512 >> 2] = {0}; +//============================================================================= +// Private Function Definition +//============================================================================= +static int +_Run_Flash_Erase(void) +{ + int rval = 0; + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + uint32_t *pCur = 0; + + /* Erase eFlash (sector by sector) */ + rval = FLASH_ErasePage(addr); + if( rval ) break; + + /* Verify value after erase */ + pCur = (uint32_t*)addr; + + for(int i = 0; i < (FLASH_1_PAGE_SIZE >> 2); i++) + { + if( pCur[i] != 0xFFFFFFFFul ) + { + rval = -__LINE__; + err(" ! erase fail (addr: 0x%08X, data: 0x%08X)\n", &pCur[i], pCur[i]); + /* break; */ + } + + dbg("addr(x%08X)= x%08X, pattern= x%08X\n", &pCur[i], pCur[i], 0xFFFFFFFF); + } + } + + return rval; +} + +static int +_Run_Flash_ProgWord(uint32_t pattern) +{ + int rval = 0; + + do { + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Program value to eFlash */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint32_t)) + { + rval = FLASH_ProgWord(addr + i, pattern); + if( rval ) break; + } + + if( rval ) break; + } + + if( rval ) break; + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Verify value after program */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint32_t)) + { + dbg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint32_t*)(addr + i), pattern); + + if( *(uint32_t*)(addr + i) != pattern ) + { + rval = -__LINE__; + err(" ! prog fail (addr: 0x%08X, value: 0x%08X)\n", addr + i, *(uint32_t*)(addr + i)); + break; + } + } + + if( rval ) break; + } + } while(0); + + return rval; +} + + +static int +_Run_Flash_ProgHWord(uint16_t pattern) +{ + int rval = 0; + + do { + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Program value to eFlash */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint16_t)) + { + rval = FLASH_ProgHWord(addr + i, pattern); + if( rval ) break; + } + + if( rval ) break; + } + + if( rval ) break; + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Verify value after program */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint16_t)) + { + dbg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint16_t*)(addr + i), pattern); + + if( *(uint16_t*)(addr + i) != pattern ) + { + rval = -__LINE__; + err(" ! prog fail (addr: 0x%08X, value: 0x%04X)\n", addr + i, *(uint16_t*)(addr + i)); + break; + } + } + + if( rval ) break; + } + } while(0); + + return rval; +} + +static int +_Run_Flash_ProgByte(uint8_t pattern) +{ + int rval = 0; + + do { + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Program value to eFlash */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint8_t)) + { + rval = FLASH_ProgByte(addr + i, pattern); + if( rval ) break; + } + + if( rval ) break; + } + + if( rval ) break; + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Verify value after program */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(uint8_t)) + { + dbg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint8_t*)(addr + i), pattern); + + if( *(uint8_t*)(addr + i) != pattern ) + { + rval = -__LINE__; + err(" ! prog fail (addr: 0x%08X, value: 0x%02X)\n", addr + i, *(uint8_t*)(addr + i)); + break; + } + } + + if( rval ) break; + } + } while(0); + + return rval; +} + +static int +_Run_Flash_ProgData(uint32_t pattern) +{ + int rval = 0; + + do { + uint32_t patt_act = pattern; + + for(int j = 0; j < (sizeof(g_buf) >> 2); j++) + { + g_buf[j] = patt_act; + } + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Program value to eFlash */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(g_buf)) + { + rval = FLASH_ProgData(addr + i, (uint32_t*)&g_buf, sizeof(g_buf)); + if( rval ) break; + } + + if( rval ) break; + } + + if( rval ) break; + + + for(uint32_t addr = FLASH_PROG_ADDR_START; + addr < FLASH_PROG_ADDR_END; + addr += FLASH_1_PAGE_SIZE) + { + /* Verify value after program */ + for(int i = 0; i < FLASH_1_PAGE_SIZE; i += sizeof(g_buf)) + { + dbg("addr(x%08X)= x%08X, pattern= x%08X\n", addr + i, *(uint32_t*)(addr + i), patt_act); + + if( memcmp((void*)(addr + i), (void*)&g_buf, sizeof(g_buf)) ) + { + rval = -__LINE__; + err(" ! prog fail (addr: 0x%08X, value: 0x%08X)\n", addr + i, *(uint32_t*)(addr + i)); + break; + } + } + + if( rval ) break; + } + } while(0); + return rval; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + int rval = 0; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nThis is eFlash Erase/Program/Read (0x%08x ~ 0x%08x) example\n", + __DATE__, __TIME__, FLASH_PROG_ADDR_START, FLASH_PROG_ADDR_END); + + do { + uint32_t patt_value = 0; + + log_color(SLOG_GREEN, "## P/E with word value\n"); + + rval = _Run_Flash_Erase(); + if( rval ) break; + + patt_value = (CONFIG_USE_RAND_DATA) + ? (HAL_Rand() << 16 | HAL_Rand()) + : CONFIG_PATTERN_WORD_1; + + rval = _Run_Flash_ProgWord(patt_value); + if( rval ) break; + + msg(" done~\n"); + + log_color(SLOG_GREEN, "## P/E with half-word value\n"); + + rval = _Run_Flash_Erase(); + if( rval ) break; + + patt_value = (CONFIG_USE_RAND_DATA) + ? (HAL_Rand() & 0xFFFFul) + : CONFIG_PATTERN_HWORD_1; + + rval = _Run_Flash_ProgHWord(patt_value); + if( rval ) break; + + msg(" done~\n"); + + log_color(SLOG_GREEN, "## P/E with byte value\n"); + + rval = _Run_Flash_Erase(); + if( rval ) break; + + patt_value = (CONFIG_USE_RAND_DATA) + ? ((HAL_Rand() & 0xFF00ul) >> 8) + : CONFIG_PATTERN_BYTE_1; + + rval = _Run_Flash_ProgByte(patt_value); + if( rval ) break; + + msg(" done~\n"); + + log_color(SLOG_GREEN, "## P/E with data stream (32-bits valule and 4-aling length)\n"); + + rval = _Run_Flash_Erase(); + if( rval ) break; + + patt_value = (CONFIG_USE_RAND_DATA) + ? (HAL_Rand() << 16 | HAL_Rand()) + : CONFIG_PATTERN_WORD_1; + + rval = _Run_Flash_ProgData(patt_value); + if( rval ) break; + + msg(" done~\n"); + } while(0); + + if(rval) err("!!! fail %d\n", rval); + else msg("done ~~~~~~\n"); + + while(1) + { + __NOP(); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.cproject b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.project b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/Project.nuproject b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/component.mk b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/isr.h b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/main.h b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/readme.md b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/readme.md new file mode 100644 index 0000000..5dd58ac --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/readme.md @@ -0,0 +1,54 @@ + +## GPIO Interrupt + +> This example is used to trig gpio interrupt. + ++ Select GPIO Port + + ``` + // in main.c + /** + * Select Interrupt pin + */ + #define GPIO_INPUT_PORTx GPIOB + #define GPIO_INPUT_PINx GPIO_Pin_00 + #define CONFIG_GPIO_IRQ GPIOB_IRQn + ``` + ++ Select GPIO interrupt trigger mode + + ``` + // in main.c + /** + * Select Interrupt source + */ + #define GPIO_INTERRUPT_TRIGGER GPIO_Trigger_Level + #define GPIO_INTERRUPT_POLARITY GPIO_Polarity_Low_Fall + ``` + + +## Note-Log + +Use serial port with baudrate 115200 8bit, no parity check. + ++ Select UART log pin + + ``` + // in syslog.c + #define CONFIG_LOG_DEVICE_TX_IO_PORTx GPIOA + #define CONFIG_LOG_DEVICE_TX_IO_PINx GPIO_Pin_15 + #define CONFIG_LOG_DEVICE_TX_IO_AF GPIO_AF_1 + ``` + ++ If you want to use `PB1` as an interrupt, set IO to normal IO.(RST pin by default) + + ``` + SYSCFG_SetRstPin2NormalIO(true); // set RST IO to normal IO + ``` + ++ If you want to use `PB[2:5]` as an interrupt, set IO to normal IO, and Restore IO to JTAG IO at the end.(JTAG pin by default) + + ``` + SYSCFG_SetICEPin2NormalIO(true); // set JTAG IO to normal IO + SYSCFG_SetICEPin2NormalIO(false); // set normal IO to JTAG IO + ``` diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/isr.c b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/main.c b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/main.c new file mode 100644 index 0000000..d304dd5 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_interrupt/src/main.c @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Select Interrupt pin + */ +#define GPIO_INPUT_PORTx GPIOB +#define GPIO_INPUT_PINx GPIO_Pin_00 +#define CONFIG_GPIO_IRQ GPIOB_IRQn + +/** + * Select Interrupt source + */ +#define GPIO_INTERRUPT_TRIGGER GPIO_Trigger_Level +#define GPIO_INTERRUPT_POLARITY GPIO_Polarity_Low_Fall +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint32_t g_interrupt_cnt = 0; +static bool g_hasPullLow = false; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); // Save CSRs + + if( GPIO_GetITFlag(GPIO_INPUT_PORTx, GPIO_INPUT_PINx) ) + { + /* Enter interrupt trigger */ + GPIO_ClearITFlag(GPIO_INPUT_PORTx, GPIO_INPUT_PINx); + + g_hasPullLow = true; // Mark interrupt triggered + g_interrupt_cnt++; + } + + RESTORE_IRQ_CSR_CONTEXT(); // Restore CSRs + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nThis is a demo project of GPIO interrput\n", __DATE__, __TIME__); + + /* Configure trig interrupt pin and set interrupt source */ + GPIO_InitTypeDef InitStruct = {0}; + InitStruct.GPIO_Pin = GPIO_INPUT_PINx; + InitStruct.GPIO_Mode = GPIO_Mode_IN ; + InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; + InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_INTERRUPT_TRIGGER; + InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_INTERRUPT_POLARITY; + InitStruct.GPIO_PuPd = (InitStruct.GPIO_ITInit.GPIO_Polarity == GPIO_Polarity_High_Rise) + ? GPIO_PuPd_DOWN : GPIO_PuPd_UP; + GPIO_Init(GPIO_INPUT_PORTx , &InitStruct); + + { /* Configure the interrupt function of GPIO */ + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_GPIO_IRQ, GPIOx_Handler, &irq_attr); + + GPIO_ITConfig(GPIO_INPUT_PORTx, GPIO_INPUT_PINx, &InitStruct.GPIO_ITInit); + GPIO_ITEnable(GPIO_INPUT_PORTx, GPIO_INPUT_PINx); + } + + while(1) + { + /* Interrupt triggered behavior */ + if( g_hasPullLow == true ) + { + msg("Interrupt times is %d\n", g_interrupt_cnt); + g_hasPullLow = false; + } + + sys_delay(30); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.cproject b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.project b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/Project.nuproject b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/component.mk b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/isr.h b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/main.h b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/readme.md b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/readme.md new file mode 100644 index 0000000..0df6687 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/readme.md @@ -0,0 +1,31 @@ + +## GPIO toggle + +The example is used to toggle gpio. + ++ Select GPIO Portx + + ``` + // at main.c + /** + * Select toggle pin + */ + #define GPIO_PORTx GPIOA + #define GPIO_Pinx GPIO_Pin_00 + ``` + +Note: +--- + ++ If you want to toggle `PB1`, set IO to normal IO.(RST pin by default) + + ``` + SYSCFG_SetRstPin2NormalIO(true); // set RST IO to normal IO + ``` + ++ If you want to toggle `PB[2:5]`, set IO to normal IO, and Restore IO to JTAG IO at the end.(JTAG pin by default) + + ``` + SYSCFG_SetICEPin2NormalIO(true); // set JTAG IO to normal IO + SYSCFG_SetICEPin2NormalIO(false); // set normal IO to JTAG IO + ``` diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/isr.c b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/main.c b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/main.c new file mode 100644 index 0000000..60d6691 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/gpio/gpio_toggle/src/main.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +#include +#include +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Select toggle pin + */ +#define GPIO_PORTx GPIOA +#define GPIO_Pinx GPIO_Pin_00 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s\nThis is a demo project to toggle gpio\n", __TIME__); + + /* Configure toggle pin */ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = GPIO_Pinx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIO_PORTx , &GPIO_InitStruct); + + while(1) + { + /* pin toggle */ + GPIO_TogglePin(GPIO_PORTx, GPIO_Pinx); + + /* delay 10ms */ + sys_delay(10); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.cproject b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.project b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/Project.nuproject b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/component.mk b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/isr.h b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/main.h b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/readme.md b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/readme.md new file mode 100644 index 0000000..e1f8a63 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/readme.md @@ -0,0 +1,79 @@ + +## I2C_master_transceiver + +> This example is used to transceive data with STM32 I2C-Master + +### steps +> IIC master: `DUT` IIC slave: `STM32` +1. `DUT` ==> `STM32`(Transmit data action) +2. `STM32` save the data +3. `DUT` ==> `STM32`(Receive data action) +4. `STM32` send the saved data +5. `DUT` save the read data +6. `DUT` compare the Transmitted data with the Received data, + if consistent, proceed to the next loop, and inconsistent, enter `while(1)` loop + +### Configuration + ++ select transmit mode + + ``` + //in main.c + /** + * if defined, transfer data using interrupt mode + * if not, transfer data using polling mode + */ + #define CONFIG_USE_I2C_INTERRUPT + ``` + ++ Select IIC DIV Clock + + ``` + //in main.c + #define IIC_DIV_CLOCK I2C_CLK_Div60 // I2C clock division + ``` + ++ Select IIC pin + + ``` + //in main.c + /** + * Select I2C SCL and SDA pin + */ + #define IIC_SCL_PORT GPIOA + #define IIC_SCL_PIN GPIO_Pin_00 + #define IIC_SCL_AF GPIO_AF_4 + #define IIC_SDA_PORT GPIOA + #define IIC_SDA_PIN GPIO_Pin_01 + #define IIC_SDA_AF GPIO_AF_4 + ``` + + > SCL_PIN: `PA00` `PA01` `PB02` `PB01` `PB03` `PA15` + > + > SDA_PIN: `PA01` `PA00` `PB01` `PB02` `PB05` `PB00` + + +--- +Note: + ++ Select UART log pin + + ``` + // in syslog.c + #define CONFIG_LOG_DEVICE_TX_IO_PORTx GPIOA + #define CONFIG_LOG_DEVICE_TX_IO_PINx GPIO_Pin_15 + #define CONFIG_LOG_DEVICE_TX_IO_AF GPIO_AF_1 + ``` + ++ If you want to use `PB1` as an I2C pin, set IO to normal IO.(RST pin by default) + + ``` + SYSCFG_SetRstPin2NormalIO(true); // set RST IO to normal IO + ``` + ++ If you want to use `PB[2:5]` as an I2C pin, set IO to normal IO, and Restore IO to JTAG IO at the end.(JTAG pin by default) + + ``` + SYSCFG_SetICEPin2NormalIO(true); // set JTAG IO to normal IO + SYSCFG_SetICEPin2NormalIO(false); // set normal IO to JTAG IO + ``` diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/isr.c b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/main.c b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/main.c new file mode 100644 index 0000000..a0fa29d --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_mster_transceiver/src/main.c @@ -0,0 +1,219 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#include +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * if defined, transfer data using interrupt mode + * if not, transfer data using polling mode + */ +#define CONFIG_USE_I2C_INTERRUPT + +#define CONFIG_REMOTE_I2C_ADDR 0xB0 // slave address +#define CONFIG_DATA_BUF_LEN 64 // transmit data of length + +#define IIC_DIV_CLOCK I2C_CLK_Div60 // I2C clock division + +/** + * Select I2C SCL and SDA pin + */ +#define IIC_SCL_PORT GPIOA +#define IIC_SCL_PIN GPIO_Pin_00 +#define IIC_SCL_AF GPIO_AF_4 +#define IIC_SDA_PORT GPIOA +#define IIC_SDA_PIN GPIO_Pin_01 +#define IIC_SDA_AF GPIO_AF_4 + +#define I2Cx I2C0 +#define I2Cx_IRQn I2C0_IRQn + +#if defined(CONFIG_USE_I2C_INTERRUPT) + #define CONFIG_XFER_MODE "Interrupt" +#else + #define CONFIG_XFER_MODE "Polling" +#endif + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint8_t g_tx_buf[CONFIG_DATA_BUF_LEN] = {0}; +static uint8_t g_rx_buf[CONFIG_DATA_BUF_LEN] = {0}; + +static I2C_IT_HandleTypeDef g_hI2CIT = {0}; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void I2Cx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + I2C_Master_IRQHandler(&g_hI2CIT); + + RESTORE_IRQ_CSR_CONTEXT(); + + return; +} + +/** + * Configure the pin of I2C + */ +static void _Config_IO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + GPIO_InitStruct.GPIO_Pin = IIC_SCL_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = IIC_SCL_AF; + GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; + GPIO_Init(IIC_SCL_PORT, &GPIO_InitStruct); + + GPIO_InitStruct.GPIO_Pin = IIC_SDA_PIN; + GPIO_InitStruct.GPIO_AF_Mode = IIC_SDA_AF; + GPIO_Init(IIC_SDA_PORT, &GPIO_InitStruct); + + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + I2C_ErrTypeDef rval = I2C_Err_OK; + int data_base = 0x50; + + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv4; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nI2C-Maseter (%s). The Target Slave-Address is 0x%02X\n", + __DATE__, __TIME__, CONFIG_XFER_MODE, (CONFIG_REMOTE_I2C_ADDR >> 1)); + + /* Configure the pin of I2C */ + _Config_IO(); + + { /* Configure the parameters of I2C */ + I2C_InitTypeDef init = {0}; + + I2C_StructInit(&init); + + init.Mode = I2C_Mode_MASTER; + init.ClockDiv = IIC_DIV_CLOCK; + init.BroadAck = I2C_BroadAck_Enable; + rval = I2C_Init(I2Cx, &init); + if( rval != I2C_Err_OK ) + { + err("I2C init fail !\n"); + } + } + +#if defined(CONFIG_USE_I2C_INTERRUPT) + { /* Setup Interrupt */ + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(I2Cx_IRQn, I2Cx_Handler, &irq_attr); + + g_hI2CIT.pHI2C = I2Cx; + } +#endif + + do { + sys_delay(500); + + /* prepare data */ + data_base++; + for(int i = 0; i < sizeof(g_tx_buf); i++) + { + g_tx_buf[i] = (data_base + i) & 0xFF; + } + + log_color(SLOG_GREEN, " @ Start Transmitting...\n"); + syslog_dump_mem("tx: ", (uint32_t*)&g_tx_buf, sizeof(g_tx_buf), 0); + + /* IIC Master transmit and receive data */ + #if defined(CONFIG_USE_I2C_INTERRUPT) + rval = I2C_Master_Transmit_IT(&g_hI2CIT, CONFIG_REMOTE_I2C_ADDR, (uint8_t*)&g_tx_buf, (uint16_t)sizeof(g_tx_buf)); + if( rval != I2C_Err_OK ) + { + err("I2C master TX fail !\n"); + break; + } + + while( g_hI2CIT.XferMode != I2C_XferMode_Idle ) + __NOP(); + + rval = I2C_Master_Receive_IT(&g_hI2CIT, CONFIG_REMOTE_I2C_ADDR, (uint8_t*)&g_rx_buf, (uint16_t)sizeof(g_rx_buf)); + if( rval != I2C_Err_OK ) + { + err("I2C master RX fail !\n"); + break; + } + + while( g_hI2CIT.XferMode != I2C_XferMode_Idle ) + __NOP(); + + #else + uint16_t length = 0; + + rval = I2C_Master_Transmit(I2Cx, CONFIG_REMOTE_I2C_ADDR, (uint8_t*)&g_tx_buf, (uint16_t)sizeof(g_tx_buf)); + if( rval != I2C_Err_OK ) + { + err("I2C master TX fail !\n"); + break; + } + + length = sizeof(g_rx_buf); + memset((void*)&g_rx_buf, 0xAA, sizeof(g_rx_buf)); + + rval = I2C_Master_Receive(I2Cx, CONFIG_REMOTE_I2C_ADDR, (uint8_t*)&g_rx_buf, &length, 1000); + if( rval != I2C_Err_OK ) + { + err("I2C master RX fail !\n"); + break; + } + #endif + + /* comparative data */ + syslog_dump_mem("rx: ", (uint32_t*)&g_rx_buf, sizeof(g_rx_buf), 0); + + if( !memcmp(g_tx_buf, g_rx_buf, sizeof(g_tx_buf)) ) + msg("done~~ \n\n"); + else + { + err("Data is NOT match !\n"); + break; + } + + } while(1); + + + while(1); + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.cproject b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.project b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/Project.nuproject b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/component.mk b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/isr.h b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/main.h b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/readme.md b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/readme.md new file mode 100644 index 0000000..543c13f --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/readme.md @@ -0,0 +1,67 @@ + +## i2c_slave_transceiver +> This example is used to transceive data with I2C-Slave + + +### steps +> IIC master: `STM32` IIC slave: `DUT` +1. `STM32` ==> `DUT`(Transmit data action) +2. `DUT` save the data +3. `STM32` ==> `DUT`(Receive data action) +4. `DUT` send data( is consistent with the transmitted data) +5. `DUT` compare the save send with the send data, if consistent, proceed to the next loop, and inconsistent, enter `while(1)` loop + +### Configuration + ++ select transmit mode + + ``` + //in main.c + /** + * if defined, transfer data using interrupt mode + * if not, transfer data using polling mode + */ + #define CONFIG_USE_I2C_INTERRUPT + ``` + ++ Select IIC pin + + ``` + //in main.c + /** + * Select I2C SCL and SDA pin + */ + #define IIC_SCL_PORT GPIOA + #define IIC_SCL_PIN GPIO_Pin_00 + #define IIC_SCL_AF GPIO_AF_4 + #define IIC_SDA_PORT GPIOA + #define IIC_SDA_PIN GPIO_Pin_01 + #define IIC_SDA_AF GPIO_AF_4 + ``` + + > SCL_PIN: `PA00` `PA01` `PB02` `PB01` `PB03` `PA15` + > + > SDA_PIN: `PA01` `PA00` `PB01` `PB02` `PB05` `PB00` + + ++ Select UART log pin + + ``` + // in syslog.c + #define CONFIG_LOG_DEVICE_TX_IO_PORTx GPIOA + #define CONFIG_LOG_DEVICE_TX_IO_PINx GPIO_Pin_15 + #define CONFIG_LOG_DEVICE_TX_IO_AF GPIO_AF_1 + ``` + ++ If you want to use `PB1` as an I2C pin, set IO to normal IO.(RST pin by default) + + ``` + SYSCFG_SetRstPin2NormalIO(true); // set RST IO to normal IO + ``` + ++ If you want to use `PB[2:5]` as an I2C pin, set IO to normal IO, and Restore IO to JTAG IO at the end. (JTAG pin by default) + + ``` + SYSCFG_SetICEPin2NormalIO(true); // set JTAG IO to normal IO + SYSCFG_SetICEPin2NormalIO(false); // set normal IO to JTAG IO + ``` diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/isr.c b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/main.c b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/main.c new file mode 100644 index 0000000..18ca019 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/i2c/i2c_slave_transceiver/src/main.c @@ -0,0 +1,211 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#include +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * if defined, transfer data using interrupt mode + * if not, transfer data using polling mode + */ +#define CONFIG_USE_I2C_INTERRUPT + +#define CONFIG_REMOTE_I2C_ADDR 0xAA // slave address +#define CONFIG_DATA_BUF_LEN 64 // transmit data of length + +/** + * Select I2C SCL and SDA pin + */ +#define IIC_SCL_PORT GPIOA +#define IIC_SCL_PIN GPIO_Pin_00 +#define IIC_SCL_AF GPIO_AF_4 +#define IIC_SDA_PORT GPIOA +#define IIC_SDA_PIN GPIO_Pin_01 +#define IIC_SDA_AF GPIO_AF_4 + +#define I2Cx I2C0 +#define I2Cx_IRQn I2C0_IRQn + +#if defined(CONFIG_USE_I2C_INTERRUPT) + #define CONFIG_XFER_MODE "Interrupt" +#else + #define CONFIG_XFER_MODE "Polling" +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint8_t g_tx_buf[CONFIG_DATA_BUF_LEN] = {0}; +static uint8_t g_rx_buf[CONFIG_DATA_BUF_LEN] = {0}; + +static I2C_IT_HandleTypeDef g_hI2CIT = {0}; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void I2Cx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + I2C_Slave_IRQHandler(&g_hI2CIT); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + + +/** + * Configure the pin of I2C + */ +static void _Config_IO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = IIC_SCL_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = IIC_SCL_AF; + GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; + GPIO_Init(IIC_SCL_PORT, &GPIO_InitStruct); + + GPIO_InitStruct.GPIO_Pin = IIC_SDA_PIN; + GPIO_InitStruct.GPIO_AF_Mode = IIC_SDA_AF; + GPIO_Init(IIC_SDA_PORT, &GPIO_InitStruct); + + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + I2C_ErrTypeDef rval = I2C_Err_OK; + int data_base = 0x50; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_FreqDiv; + SysClkInit.SysClk_Div = SYSCFG_SysClkDiv8; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nI2C-Slave (%s). The local Slave-Address is 0x%02X\n", + __DATE__, __TIME__, CONFIG_XFER_MODE, (CONFIG_REMOTE_I2C_ADDR >> 1)); + + /* Configure the pin of I2C */ + _Config_IO(); + + /* Configure the parameters of I2C */ + I2C_InitTypeDef init = {0}; + I2C_StructInit(&init); + init.Mode = I2C_Mode_SLAVE; + init.OwnAddress = CONFIG_REMOTE_I2C_ADDR >> 1; +// init.ClockDiv = I2C_CLK_Div960; + rval = I2C_Init(I2Cx, &init); + if( rval != I2C_Err_OK ) + { + err("I2C init fail !\n"); + } + + +#if defined(CONFIG_USE_I2C_INTERRUPT) + { /* Setup Interrupt */ + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(I2Cx_IRQn, I2Cx_Handler, &irq_attr); + + g_hI2CIT.pHI2C = I2Cx; + } +#endif + + do { + /* prepare data */ + data_base++; + for(int i = 0; i < sizeof(g_tx_buf); i++) + { + g_tx_buf[i] = (data_base + i) & 0xFF; + } + + log_color(SLOG_GREEN, " @ Start Transmitting...\n"); + syslog_dump_mem("tx: ", (uint32_t*)&g_tx_buf, sizeof(g_tx_buf), 0); + + /* IIC slave receive and transmit data */ + #if defined(CONFIG_USE_I2C_INTERRUPT) + rval = I2C_Slave_Receive_IT(&g_hI2CIT, (uint8_t*)&g_rx_buf, (uint16_t)sizeof(g_rx_buf)); + if( rval != I2C_Err_OK ) + { + err("I2C master TX fail !\n"); + break; + } + + while( g_hI2CIT.XferMode != I2C_XferMode_Idle ) + __NOP(); + + rval = I2C_Slave_Transmit_IT(&g_hI2CIT, (uint8_t*)&g_tx_buf, (uint16_t)sizeof(g_tx_buf)); + if( rval != I2C_Err_OK ) + { + err("I2C master RX fail !\n"); + break; + } + + while( g_hI2CIT.XferMode != I2C_XferMode_Idle ) + __NOP(); + + #else + uint16_t length = 0; + + length = sizeof(g_rx_buf); + + memset((void*)&g_rx_buf, 0xAA, sizeof(g_rx_buf)); + + rval = I2C_Slave_Receive(I2Cx, (uint8_t*)&g_rx_buf, &length, I2C_BLOCKING); + if( rval != I2C_Err_OK ) + { + err("I2C slave RX fail !\n"); + break; + } + + rval = I2C_Slave_Transmit(I2Cx, (uint8_t*)&g_tx_buf, (uint16_t)sizeof(g_tx_buf), I2C_BLOCKING); + if( rval != I2C_Err_OK ) + { + err("I2C slave TX fail !\n"); + break; + } + #endif + + /* comparative data */ + syslog_dump_mem("rx: ", (uint32_t*)&g_rx_buf, sizeof(g_rx_buf), 0); + + if( !memcmp(g_tx_buf, g_rx_buf, sizeof(g_tx_buf)) ) + msg("done~~ \n\n"); + else + { + err("Data is NOT match !\n"); + break; + } + + } while(1); + + + while(1); + return 0; + } diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.cproject b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.project b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/Project.nuproject b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/component.mk b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/isr.h b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/main.h b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/readme.md b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/readme.md new file mode 100644 index 0000000..7908a3b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/readme.md @@ -0,0 +1,17 @@ +LPTIM count +--- + +This example is used to run LPTIM count function. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Set the count value to your desired value. ++ Run the example \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/isr.c b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/main.c b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/main.c new file mode 100644 index 0000000..7c8e3dd --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_count/src/main.c @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +// #define CONFIG_USE_LPTIM +#define CONFIG_USE_TIM0 +// #define CONFIG_USE_TIM1 + +#if defined(CONFIG_USE_LPTIM) + #define LPTIMx LPTIM + #define CONFIG_PERI_NAME "LpTim" +#elif defined(CONFIG_USE_TIM0) + #define LPTIMx TIM0 + #define CONFIG_PERI_NAME "Tim0" +#elif defined(CONFIG_USE_TIM1) + #define LPTIMx TIM1 + #define CONFIG_PERI_NAME "Tim1" +#endif + +/* Use PA2 to toggle */ +#define CONFIG_TOGGLE_PORT GPIOA +#define CONFIG_TOGGLE_PIN GPIO_Pin_02 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + uint32_t set_matchvalue = 0; + LPTIM_InitTypeDef Init = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("This is a demo project to set %s count\n", + CONFIG_PERI_NAME); + + {// configure I/O to toggle + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_TOGGLE_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_Init(CONFIG_TOGGLE_PORT, &GPIO_InitStruct); + } + + set_matchvalue = 0xFFF0; + + Init.LPTIM_Prescaler = 0x3; + Init.LPTIM_ClockSource = LPTIM_CLK_Src_SysClk; + Init.LPTIM_MatchMode = LPTIM_MatchMode_Reset; + Init.LPTIM_MatchValue = set_matchvalue; + LPTIM_Init(LPTIMx, &Init); + + LPTIM_Enable(LPTIMx); + + while(1) + { + if( LPTIM_GetFlagStatus(LPTIMx, LPTIM_Flag_Match0) ) + { + LPTIM_ClearFlag(LPTIMx, LPTIM_Flag_Match0); + + msg("cnt= x%04X\n", LPTIM_GetCounter(LPTIMx)); + + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + } + + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.cproject b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.project b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/Project.nuproject b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/component.mk b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/isr.h b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/main.h b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/readme.md b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/readme.md new file mode 100644 index 0000000..851ee0d --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/readme.md @@ -0,0 +1,17 @@ +LPTIM match and interrupt +--- + +This example is used to run LPTIM match and interrupt function. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Set the match model and interrupt ++ Run the example \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/isr.c b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/main.c b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/main.c new file mode 100644 index 0000000..e6100f3 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lptim/lptim_match_Interrupt/src/main.c @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +#define CONFIG_USE_LPTIM +// #define CONFIG_USE_TIM0 +// #define CONFIG_USE_TIM1 + +#if defined(CONFIG_USE_LPTIM) + #define LPTIMx LPTIM + #define CONFIG_IRQ_ID LPTIM_IRQn + #define CONFIG_PERI_NAME "LpTim" +#elif defined(CONFIG_USE_TIM0) + #define LPTIMx TIM0 + #define CONFIG_IRQ_ID TIM0_IRQn + #define CONFIG_PERI_NAME "Tim0" +#elif defined(CONFIG_USE_TIM1) + #define LPTIMx TIM1 + #define CONFIG_IRQ_ID TIM1_IRQn + #define CONFIG_PERI_NAME "Tim1" +#endif + +/* Use PA2 to toggle */ +#define CONFIG_TOGGLE_PORT GPIOA +#define CONFIG_TOGGLE_PIN GPIO_Pin_02 +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void LPTIMx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + if( LPTIM_GetFlagStatus(LPTIMx, LPTIM_Flag_Match0) ) + { + LPTIM_ClearFlag(LPTIMx, LPTIM_Flag_Match0); + + GPIO_TogglePin(CONFIG_TOGGLE_PORT, CONFIG_TOGGLE_PIN); + } + + RESTORE_IRQ_CSR_CONTEXT(); + return; + +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + LPTIM_InitTypeDef Init = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("This is a demo project to set %s match model and interrupt\n", + CONFIG_PERI_NAME); + + + {// configure I/O to toggle + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.GPIO_Pin = CONFIG_TOGGLE_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_Init(CONFIG_TOGGLE_PORT, &GPIO_InitStruct); + } + + + Init.LPTIM_Prescaler = 0x0; + Init.LPTIM_ClockSource = LPTIM_CLK_Src_SysClk; + Init.LPTIM_MatchMode = LPTIM_MatchMode_IRQ | LPTIM_MatchMode_Reset; + Init.LPTIM_MatchValue = 2400; + LPTIM_Init(LPTIMx, &Init); + + /* Regiser ISR MUST be after init method */ + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(CONFIG_IRQ_ID, LPTIMx_Handler, &irq_attr); + sys_enable_girq(); + + LPTIM_ITConfig(LPTIMx, true); + + LPTIM_Enable(LPTIMx); + + + while(1) + { + __NOP(); + } + + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.cproject b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.project b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/Project.nuproject b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/component.mk b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/isr.h b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/main.h b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/readme.md b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/readme.md new file mode 100644 index 0000000..e6ca230 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/readme.md @@ -0,0 +1,21 @@ +## LVD & LVR + +> This example is used to run lvd/lvr function. + ++ Select Test Items + ``` + // in main.c + /** + * Enable LVD and Select LVD Voltage + */ + #define LVD_TEST_EN + #define LVD_VOL_SET AMISC_LVDVoltage_4_3V + + /** + * Enable LVR and Select LVR Voltage + */ + //#define LVR_TEST_EN + //#define LVR_VOL_SET AMISC_LVRVoltage_3_7V + ``` + +> Run Code,and adjust VDD, then observe the waveform with an oscilloscope \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/isr.c b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/main.c b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/main.c new file mode 100644 index 0000000..c4d4011 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/lvd_lvr/lvd_lvr/src/main.c @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * Enable LVD and Select LVD Voltage + */ +#define LVD_TEST_EN +#define LVD_VOL_SET AMISC_LVDVoltage_4_3V + +/** + * Enable LVR and Select LVR Voltage + */ +//#define LVR_TEST_EN +//#define LVR_VOL_SET AMISC_LVRVoltage_3_7V +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + GPIO_InitTypeDef GPIO_InitStruct = {0}; + AMISC_LVDRInitTypeDef LVD_LVR_InitStruct = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + /* Enable AMISC Module and enable vbuf */ + AMISC_Init(); + AMISC_Vbuf_Enable(); + + /* Enable and Configure the parameters of LVD/LVR */ +#if defined(LVD_TEST_EN) + AMISC_LVD_Enable(); + LVD_LVR_InitStruct.LVD_Voltage = LVD_VOL_SET; +#endif + +#if defined(LVR_TEST_EN) + AMISC_LVR_Enable(); + LVD_LVR_InitStruct.LVR_Voltage = LVR_VOL_SET; +#endif + + AMISC_LVD_LVR_Config(&LVD_LVR_InitStruct); + + info("%s %s\nThis is a demo project of LVD/LVR test\n", __DATE__, __TIME__); + + /* Configure GPIO, pin is used to display the status of LVD/LVR */ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_00 | GPIO_Pin_03; + GPIO_InitStruct.GPIO_Pin = GPIO_PIN_All; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_Init(GPIOA , &GPIO_InitStruct); + + while(1) + { +#if defined(LVR_TEST_EN) + /* Observe LVR action through pin */ + GPIO_TogglePin(GPIOA, GPIO_Pin_00); +#endif + +#if defined(LVD_TEST_EN) + /* VDD < LVD: pin out low; VDD > LVD:pin out high */ + GPIO_WriteBit(GPIOA, GPIO_Pin_03, (AMISC_LVD_GetFlagStatus() ? GPIO_PIN_HIGH : GPIO_PIN_LOW)); +#endif + sys_delay(1); + + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.cproject b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.project b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/Project.nuproject b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/component.mk b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/isr.h b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/main.h b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/readme.md b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/readme.md new file mode 100644 index 0000000..060fc01 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/readme.md @@ -0,0 +1,114 @@ +pga_src_internal +--- + +This example is used to demo the PGA module which uses internal signals as input/output +> Only PGA0 supports internal source + ++ Configure the amplifier gain + + ```c + // at main.c + /** + * The amplify gain, @ref OPAMP_PGAGainTypeDef + * ps. OPAMP_PGAGain_1 ~ OPAMP_PGAGain_16 + */ + #define CONFIG_AMP_GAIN OPAMP_PGAGain_1 + ``` + ++ Configure the reference mVoltage of ADC to convert the sampled value to mVoltage + + ```c + // at main.c + /** + * The reference mVoltage of ADC on board + */ + #define CONFIG_ADC_REF_mVOLTAGE 3300 + ``` + + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Internal signal + > + Temperature: Analog signal output to PA8 (0.686 V) + > + DAC0 : Analog signal output to PA8 (1.627 V) + > + DAC1 : Analog signal output to PA8 (1.659 V) + > + VBuf 1.5v : Analog signal output to PA8 (1.511 V) + > + VDDL : Analog signal output to PA8 (1.521 V) + > + VSS : Analog signal output to PA8 (0.002 V) + > + VDD : Analog signal output to PA8 (3.288 V) + + ``` + Oct 1 2025 15:48:50 + Run PGA-0 (Programmable Gain Amplifier) internal source + The gain 1 + VinP= Internal signal + VinM= GND + Vout= ADC AIN0 + + Set internal signal: Temperature + ADC samples the PGA Vout= 0x00000353 (685 mV) + + Set internal signal: DAC 0 + ADC samples the PGA Vout= 0x000007D7 (1616 mV) + + Set internal signal: DAC 1 + ADC samples the PGA Vout= 0x000007F0 (1637 mV) + + Set internal signal: VBuf 1.5 + ADC samples the PGA Vout= 0x0000074C (1504 mV) + + Set internal signal: VDDL + ADC samples the PGA Vout= 0x00000757 (1513 mV) + + Set internal signal: VSS + ADC samples the PGA Vout= 0x00000006 (4 mV) + + Set internal signal: VDD + ADC samples the PGA Vout= 0x00000FEF (3286 mV) + + Set internal signal: Temperature + ADC samples the PGA Vout= 0x0000034F (682 mV) + + Set internal signal: DAC 0 + ADC samples the PGA Vout= 0x000007CE (1609 mV) + + Set internal signal: DAC 1 + ADC samples the PGA Vout= 0x00000822 (1677 mV) + + Set internal signal: VBuf 1.5 + ADC samples the PGA Vout= 0x0000074F (1507 mV) + + Set internal signal: VDDL + ADC samples the PGA Vout= 0x0000074C (1504 mV) + + Set internal signal: VSS + ADC samples the PGA Vout= 0x00000004 (3 mV) + + Set internal signal: VDD + ADC samples the PGA Vout= 0x00000FED (3284 mV) + + Set internal signal: Temperature + ADC samples the PGA Vout= 0x0000034F (682 mV) + + Set internal signal: DAC 0 + ADC samples the PGA Vout= 0x000007E2 (1625 mV) + + Set internal signal: DAC 1 + ADC samples the PGA Vout= 0x000007F2 (1638 mV) + + Set internal signal: VBuf 1.5 + ADC samples the PGA Vout= 0x00000747 (1500 mV) + + Set internal signal: VDDL + ADC samples the PGA Vout= 0x00000755 (1512 mV) + + Set internal signal: VSS + ADC samples the PGA Vout= 0x00000008 (6 mV) + + Set internal signal: VDD + ADC samples the PGA Vout= 0x00000FF6 (3291 mV) + + ... + ``` diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/isr.c b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/main.c b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/main.c new file mode 100644 index 0000000..0026678 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_internal/src/main.c @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +/** + * The reference mVoltage of ADC on board + */ +#define CONFIG_ADC_REF_mVOLTAGE 3300 // 5000 + +/** + * The amplify gain, @ref OPAMP_PGAGainTypeDef + * ps. OPAMP_PGAGain_1 ~ OPAMP_PGAGain_16 + */ +#define CONFIG_AMP_GAIN OPAMP_PGAGain_1 + + +#define OPAMPx OPAMP0 +#define CONFIG_ADC_TARGET_CHANNEL ADC_Channel_OPA0_O + + +typedef enum internal_src +{ + INTERNAL_SRC_TEMPERATURE, + INTERNAL_SRC_DAC0, + INTERNAL_SRC_DAC1, + INTERNAL_SRC_VBUF_1P5V, + INTERNAL_SRC_VDDL, + INTERNAL_SRC_VSS, + INTERNAL_SRC_VDD, + +} internal_src_t; +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +static AMISC_InternalSrcTypeDef g_VinP_Src = AMISC_InternalSrc_NONE; +static AMISC_InternalSrcTypeDef g_InternalSrc[] = +{ + AMISC_InternalSrc_TEMP, + AMISC_InternalSrc_DAC0, + AMISC_InternalSrc_DAC1, + AMISC_InternalSrc_VBuf_1P5V, + AMISC_InternalSrc_VDDL, + AMISC_InternalSrc_VSS, + AMISC_InternalSrc_VDD, +}; + + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nRun PGA-%d (Programmable Gain Amplifier) internal source\n", + __DATE__, __TIME__, (OPAMPx == OPAMP0) ? 0 : 1); + + msg(" The gain %d\n", + (CONFIG_AMP_GAIN == OPAMP_PGAGain_2 ) ? 2 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_3 ) ? 3 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_4 ) ? 4 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_5 ) ? 5 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_6 ) ? 6 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_7 ) ? 7 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_8 ) ? 8 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_9 ) ? 9 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_10) ? 10 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_11) ? 11 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_12) ? 12 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_13) ? 13 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_14) ? 14 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_15) ? 15 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_16) ? 16 : + 1); + + msg(" VinP= Internal signal\n"); + msg(" VinM= GND\n"); + msg(" Vout= ADC AIN%d\n", 31ul - HAL_CLZ(CONFIG_ADC_TARGET_CHANNEL)); + + { /* Configure ADC */ + ADC_InitTypeDef init = {0}; + + ADC_StructInit(&init); + + init.SelChannels = CONFIG_ADC_TARGET_CHANNEL; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + } + + while(1) + { + static int cnt = 0; + OPAMP_InitTypeDef init = {0}; + uint32_t ConvValue = 0; + + /* Configure OPAMP module */ + init.OPAMP_VinP = OPAMP_VinP_Internal; + init.OPAMP_VinM = OPAMP_VinM_GND; + init.OPAMP_Vout = OPAMP_Vout_None; + init.OPAMP_Gain = CONFIG_AMP_GAIN; + + if( init.OPAMP_VinP == OPAMP_VinP_Internal ) + { + uint16_t dac_step = 512; // 0 ~ 1023 (10-bits) + + g_VinP_Src = g_InternalSrc[cnt % (sizeof(g_InternalSrc)/sizeof(g_InternalSrc[0]))]; + + log_color(SLOG_GREEN, "\nSet internal signal: %s\n", + (g_VinP_Src == AMISC_InternalSrc_TEMP ) ? "Temperature" : + (g_VinP_Src == AMISC_InternalSrc_DAC0 ) ? "DAC 0" : + (g_VinP_Src == AMISC_InternalSrc_DAC1 ) ? "DAC 1" : + (g_VinP_Src == AMISC_InternalSrc_VBuf_1P5V) ? "VBuf 1.5" : + (g_VinP_Src == AMISC_InternalSrc_VDDL ) ? "VDDL" : + (g_VinP_Src == AMISC_InternalSrc_VSS ) ? "VSS" : + (g_VinP_Src == AMISC_InternalSrc_VDD ) ? "VDD" : + "None"); + + /* Select internal source as VinP */ + AMISC_Sel_PGA_VinP_Src(g_VinP_Src); + AMISC_OutInternalSignalToIO(g_VinP_Src, true); + + if( g_VinP_Src == AMISC_InternalSrc_DAC0 ) + { + AMISC_DAC0_Config(dac_step); + AMISC_DAC0_Enable(); + } + else if( g_VinP_Src == AMISC_InternalSrc_DAC1 ) + { + AMISC_DAC1_Config(dac_step + 10); + AMISC_DAC1_Enable(); + } + } + + OPAMP_Init(OPAMPx, &init); + + OPAMP_Enable(OPAMPx); + + sys_busy_wait(60*1000); + + ADC_Start(ADC0); + + ConvValue = ADC_GetChannelConvValue(ADC0, CONFIG_ADC_TARGET_CHANNEL); + + msg(" ADC samples the PGA Vout= 0x%08X (%d mV)\n", + ConvValue, ((ConvValue * CONFIG_ADC_REF_mVOLTAGE) >> 12)); + + cnt++; + + sys_delay(1000); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.cproject b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.project b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/Project.nuproject b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/component.mk b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/isr.h b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/main.h b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/readme.md b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/readme.md new file mode 100644 index 0000000..fb8e142 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/readme.md @@ -0,0 +1,108 @@ +pga_src_io +--- + +This example is used to demo the PGA module which uses GPIO Pins as input/output + ++ Select PGA0 or PGA1 + + ```c + // at main.c + /** + * Select the terget OPAMP module + * + unmark CONFIG_USE_OPAMP_0 => OPAMP0 + * + mark CONFIG_USE_OPAMP_0 => OPAMP1 + */ + #define CONFIG_USE_OPAMP_0 + ``` + ++ Configure the amplifier gain + + ```c + // at main.c + /** + * The amplify gain, @ref OPAMP_PGAGainTypeDef + * ps. OPAMP_PGAGain_1 ~ OPAMP_PGAGain_16 + */ + #define CONFIG_AMP_GAIN OPAMP_PGAGain_1 + ``` + ++ Configure the reference mVoltage of ADC to convert the sampled value to mVoltage + + ```c + // at main.c + /** + * The reference mVoltage of ADC on board + */ + #define CONFIG_ADC_REF_mVOLTAGE 3300 + ``` + ++ Configure VinM to use internal ground + + ``` + // at main.c + #define CONFIG_SET_OPAMP_VINM_GND 1 + ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Use OPAmp0 and PA8 links to VDD/VSS + + ``` + Oct 1 2025 14:25:16 + Run PGA-0 (Programmable Gain Amplifier) + The gain 1 + VinP= PA8 + VinM= GND + Vout= ADC AIN0 <--- Vout directly links to AIN0 + ADC samples the PGA Vout= 0x08E6 (1835 mV) + ADC samples the PGA Vout= 0x080D (1660 mV) + ADC samples the PGA Vout= 0x061F (1262 mV) + ADC samples the PGA Vout= 0x0590 (1147 mV) + ADC samples the PGA Vout= 0x0E02 (2889 mV) + ADC samples the PGA Vout= 0x0FFB (3295 mV) <--- link VinP to VDD + ADC samples the PGA Vout= 0x0FFB (3295 mV) + ADC samples the PGA Vout= 0x0FFB (3295 mV) + ADC samples the PGA Vout= 0x0FFA (3295 mV) + ADC samples the PGA Vout= 0x0BB2 (2412 mV) + ADC samples the PGA Vout= 0x0003 (2 mV) <--- link VinP to VSS + ADC samples the PGA Vout= 0x0001 (0 mV) + ADC samples the PGA Vout= 0x0002 (1 mV) + ADC samples the PGA Vout= 0x0003 (2 mV) + ``` + ++ Use OPAmp0 and PA8 links to VDD/VSS + > ADC samples AIN9 (PA7) + >> There is an impedance between Vout and AIN9(PA7). + As this result, the ADC sample value is difference with `Vout = AIN0` case + + ``` + Oct 1 2025 14:30:09 + Run PGA-0 (Programmable Gain Amplifier) + The gain 1 + VinP= PA8 + VinM= GND + Vout= PA7 <--- Vout to PA7 + ADC samples the PGA Vout= 0x0110 (219 mV) + ADC samples the PGA Vout= 0x0056 (69 mV) <--- link VinP to VSS + ADC samples the PGA Vout= 0x0058 (70 mV) + ADC samples the PGA Vout= 0x0059 (71 mV) + ADC samples the PGA Vout= 0x0062 (78 mV) + ADC samples the PGA Vout= 0x002B (34 mV) + ADC samples the PGA Vout= 0x0038 (45 mV) + ADC samples the PGA Vout= 0x0057 (70 mV) + ADC samples the PGA Vout= 0x0064 (80 mV) + ADC samples the PGA Vout= 0x0029 (33 mV) + ADC samples the PGA Vout= 0x0031 (39 mV) + ADC samples the PGA Vout= 0x0590 (1147 mV) + ADC samples the PGA Vout= 0x0ADB (2238 mV) + ADC samples the PGA Vout= 0x0B38 (2313 mV) + ADC samples the PGA Vout= 0x0ECA (3050 mV) + ADC samples the PGA Vout= 0x0F2F (3131 mV) <--- link VinP to VDD + ADC samples the PGA Vout= 0x0F58 (3164 mV) + ADC samples the PGA Vout= 0x0F68 (3177 mV) + ADC samples the PGA Vout= 0x0F43 (3147 mV) + ADC samples the PGA Vout= 0x0F35 (3136 mV) + ... + ``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/isr.c b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/main.c b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/main.c new file mode 100644 index 0000000..563a752 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pga/pga_src_io/src/main.c @@ -0,0 +1,220 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_SET_OPAMP_VINM_GND 1 + +/** + * The reference mVoltage of ADC on board + */ +#define CONFIG_ADC_REF_mVOLTAGE 3300 // 5000 + +/** + * Select the terget OPAMP module + * + unmark CONFIG_USE_OPAMP_0 => OPAMP0 + * + mark CONFIG_USE_OPAMP_0 => OPAMP1 + */ +#define CONFIG_USE_OPAMP_0 + +/** + * The amplify gain, @ref OPAMP_PGAGainTypeDef + * ps. OPAMP_PGAGain_1 ~ OPAMP_PGAGain_16 + */ +#define CONFIG_AMP_GAIN OPAMP_PGAGain_1 + + +#if defined(CONFIG_USE_OPAMP_0) + #define OPAMPx OPAMP0 + + #define CONFIG_OPAMPx_VinP_IO_PORT GPIOA + #define CONFIG_OPAMPx_VinP_IO_PIN GPIO_Pin_08 + + #define CONFIG_OPAMPx_VinM_IO_PORT GPIOA + #define CONFIG_OPAMPx_VinM_IO_PIN GPIO_Pin_09 + + #define CONFIG_OPAMPx_Vout_IO_PORT GPIOA + #define CONFIG_OPAMPx_Vout_IO_PIN GPIO_Pin_07 + + #define CONFIG_ADC_TARGET_CHANNEL ADC_Channel_OPA0_O + // #define CONFIG_ADC_TARGET_CHANNEL ADC_Channel_09 +#else + #define OPAMPx OPAMP1 + + #define CONFIG_OPAMPx_VinP_IO_PORT GPIOA + #define CONFIG_OPAMPx_VinP_IO_PIN GPIO_Pin_11 + + #define CONFIG_OPAMPx_VinM_IO_PORT GPIOA + #define CONFIG_OPAMPx_VinM_IO_PIN GPIO_Pin_10 + + #define CONFIG_OPAMPx_Vout_IO_PORT GPIOA + #define CONFIG_OPAMPx_Vout_IO_PIN GPIO_Pin_13 + + #define CONFIG_ADC_TARGET_CHANNEL ADC_Channel_OPA1_O + // #define CONFIG_ADC_TARGET_CHANNEL ADC_Channel_07 +#endif +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +static void +_Log_IO_Msg(char *pPrefix, GPIO_Type *pHGpio, GPIO_PinTypeDef pin) +{ + int pin_idx = 0; + + pin_idx = 31 - HAL_CLZ(pin); + msg("%s P%s%d\n", pPrefix, + (pHGpio == GPIOB) ? "B" : "A", + pin_idx); + return; +} + +static int +_Config_PGA_IO(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + // VinP + GPIO_InitStruct.GPIO_Pin = CONFIG_OPAMPx_VinP_IO_PIN; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_ANAL; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(CONFIG_OPAMPx_VinP_IO_PORT , &GPIO_InitStruct); + + // VinM + GPIO_InitStruct.GPIO_Pin = CONFIG_OPAMPx_VinM_IO_PIN; + GPIO_Init(CONFIG_OPAMPx_VinM_IO_PORT , &GPIO_InitStruct); + + // Vout + if( CONFIG_ADC_TARGET_CHANNEL != ADC_Channel_OPA0_O && + CONFIG_ADC_TARGET_CHANNEL != ADC_Channel_OPA1_O ) + { + GPIO_InitStruct.GPIO_Pin = CONFIG_OPAMPx_Vout_IO_PIN; + GPIO_Init(CONFIG_OPAMPx_Vout_IO_PORT , &GPIO_InitStruct); + } + return 0; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nRun PGA-%d (Programmable Gain Amplifier)\n", + __DATE__, __TIME__, (OPAMPx == OPAMP0) ? 0 : 1); + + msg(" The gain %d\n", + (CONFIG_AMP_GAIN == OPAMP_PGAGain_2 ) ? 2 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_3 ) ? 3 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_4 ) ? 4 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_5 ) ? 5 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_6 ) ? 6 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_7 ) ? 7 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_8 ) ? 8 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_9 ) ? 9 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_10) ? 10 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_11) ? 11 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_12) ? 12 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_13) ? 13 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_14) ? 14 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_15) ? 15 : + (CONFIG_AMP_GAIN == OPAMP_PGAGain_16) ? 16 : + 1); + + _Log_IO_Msg(" VinP=", CONFIG_OPAMPx_VinP_IO_PORT, CONFIG_OPAMPx_VinP_IO_PIN); + + #if defined(CONFIG_SET_OPAMP_VINM_GND) && (CONFIG_SET_OPAMP_VINM_GND) + msg(" VinM= GND\n"); + #else + _Log_IO_Msg(" VinM=", CONFIG_OPAMPx_VinM_IO_PORT, CONFIG_OPAMPx_VinM_IO_PIN); + #endif + + if( CONFIG_ADC_TARGET_CHANNEL == ADC_Channel_OPA0_O || + CONFIG_ADC_TARGET_CHANNEL == ADC_Channel_OPA1_O ) + msg(" Vout= ADC AIN%d\n", 31ul - HAL_CLZ(CONFIG_ADC_TARGET_CHANNEL)); + else + _Log_IO_Msg(" Vout=", CONFIG_OPAMPx_Vout_IO_PORT, CONFIG_OPAMPx_Vout_IO_PIN); + + _Config_PGA_IO(); + + { /* Configure ADC */ + ADC_InitTypeDef init = {0}; + + ADC_StructInit(&init); + + init.SelChannels = CONFIG_ADC_TARGET_CHANNEL; + init.IsSoftTrig = true; + ADC_Init(ADC0, &init); + } + + { /* Configure OPAMP module */ + OPAMP_InitTypeDef init = {0}; + + init.OPAMP_Gain = CONFIG_AMP_GAIN; + init.OPAMP_VinP = OPAMP_VinP_IO; + + #if defined(CONFIG_SET_OPAMP_VINM_GND) && (CONFIG_SET_OPAMP_VINM_GND) + init.OPAMP_VinM = OPAMP_VinM_GND; + #else + init.OPAMP_VinM = OPAMP_VinM_IO; + #endif + + if( CONFIG_ADC_TARGET_CHANNEL == ADC_Channel_OPA0_O || + CONFIG_ADC_TARGET_CHANNEL == ADC_Channel_OPA1_O ) + init.OPAMP_Vout = OPAMP_Vout_None; + else + init.OPAMP_Vout = OPAMP_Vout_IO; + + OPAMP_Init(OPAMPx, &init); + + OPAMP_Enable(OPAMPx); + } + + while(1) + { + uint32_t ConvValue = 0ul; + + ADC_Start(ADC0); + + ConvValue = ADC_GetChannelConvValue(ADC0, CONFIG_ADC_TARGET_CHANNEL); + + msg("ADC samples the PGA Vout= 0x%04X (%d mV)\n", + ConvValue, ((ConvValue * CONFIG_ADC_REF_mVOLTAGE) >> 12)); + + sys_delay(1000); + } + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.cproject b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.project b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/Project.nuproject b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/component.mk b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/isr.h b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/main.h b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/readme.md b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/readme.md new file mode 100644 index 0000000..8379eee --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/readme.md @@ -0,0 +1,210 @@ +pwr_sleep_mode +--- + +This example is used to enter power mode and wake-up system +> + In normal mode, it will toggle I/O to notify user +> + Use Button to enter/leave power-mode function + +When measure the electric current, user should remove all external device links +> External device e.g. ICE, log message device (UART), LA (Logic Analyzer), ...etc. + ++ Sleep/Deepsleep mode + + - Sleep mode + + ``` + // at main.c (Use sleep mode) + #define CONFIG_USE_SLEEP_MODE 1 + ``` + - Deep-Sleep mode + + ``` + // at main.c (Use deep-sleep mode) + #define CONFIG_USE_SLEEP_MODE 0 + ``` + ++ The I/O selection of Button + + ```c + // at main.c + /* Input Key I/O definitions */ + #define CONFIG_GPIO_INPUT_PORTx GPIOA + #define CONFIG_GPIO_INPUT_PINx GPIO_Pin_03 + #define CONFIG_GPIO_INPUT_IRQ GPIOA_IRQn + ``` + ++ The toggled I/O selection + + ```c + // at main.c + /* Toggle I/O when normal App executing */ + #define CONFIG_IO_TOGGLE_PORTx GPIOA + #define CONFIG_IO_TOGGLE_PINx GPIO_Pin_02 + ``` + ++ Wake-up modules selection + > + The I/O wake-up case will provide the `minimum current` when deep-sleep mode + > + The LpTIM/WDG cases will provide the `lower current` when deep-sleep mode + + > In `void (*CallbaskPreSleepTypeDef)(PWR_ModeTypeDef, PWR_WakeupTypeDef*)` + >> User uses `PWR_WakeupTypeDef` to focus on the selected wake-up type (The un-selected types will be disable) + >> ```c + >> // at _Pre_Proc() + >> ... + >> *pWakeup_type = PWR_Wakeup_IO_PORT_A | PWR_Wakeup_IO_PORT_B; + >> or + >> *pWakeup_type = PWR_Wakeup_LpTIM; + >> or + >> *pWakeup_type = PWR_Wakeup_WDG; + >> ... + >> ``` + + - I/O wake-up + + ``` + // at main.c + /** + * The target module to wake-up system + * + I/O wake-up case is ultra-low power in DeepSleep mode + * + LpTIM/WDG wake-up cases are low power in DeepSleep mode + */ + #define CONFIG_USE_IO_WAKEUP 1 + #define CONFIG_USE_LPTIN_WAKEUP 0 + #define CONFIG_USE_WDG_WAKEUP 0 + ``` + + - LpTIM wake-up + + ``` + // at main.c + /** + * The target module to wake-up system + * + I/O wake-up case is ultra-low power in DeepSleep mode + * + LpTIM/WDG wake-up cases are low power in DeepSleep mode + */ + #define CONFIG_USE_IO_WAKEUP 0 + #define CONFIG_USE_LPTIN_WAKEUP 1 + #define CONFIG_USE_WDG_WAKEUP 0 + ``` + + - WDG wake-up + + ``` + // at main.c + /** + * The target module to wake-up system + * + I/O wake-up case is ultra-low power in DeepSleep mode + * + LpTIM/WDG wake-up cases are low power in DeepSleep mode + */ + #define CONFIG_USE_IO_WAKEUP 0 + #define CONFIG_USE_LPTIN_WAKEUP 0 + #define CONFIG_USE_WDG_WAKEUP 1 + ``` + +## Log + +Use serial port with baudrate 115200, 8bit, no parity check. + ++ Sleep mode + + - I/O wake-up + + ``` + [2025-11-21 16:54:01.215] Nov 19 2025 16:53:58 + [2025-11-21 16:54:01.215] This is an example of Power-Mode (Sleep) and wake-up with I/O + [2025-11-21 16:54:01.220] Button = PA3 + [2025-11-21 16:54:01.224] Output I/O = PA2 + [2025-11-21 16:54:05.020] -> enter sleep + [2025-11-21 16:54:05.020] _Pre_Proc <--- manually trigger to enter sleep mode + [2025-11-21 16:54:06.462] Output I/O = PA2 <--- manually trigger to leave sleep mode + [2025-11-21 16:54:06.462] _Post_Proc + [2025-11-21 16:54:06.464] @ Entered None ISR <--- Never enter ISR + [2025-11-21 16:54:06.464] <- wake-up + [2025-11-21 16:54:06.466] + ``` + + - LpTIM wake-up + > Configure 5 sec wake-up with LpTIM + + ``` + [2026-01-13 16:47:15.315] Nov 19 2025 16:47:12 + [2026-01-13 16:47:15.315] This is an example of Power-Mode (Sleep) and wake-up with LpTIM + [2026-01-13 16:47:15.321] Button = PA3 + [2026-01-13 16:47:15.324] Output I/O = PA2 + [2026-01-13 16:47:19.546] -> enter sleep + [2026-01-13 16:47:19.546] _Pre_Proc <--- enter sleep mode + [2026-01-13 16:48:26.635] Output I/O = PA2 <--- wake-up with LpTIM (duration 67 sec !!!) + [2026-01-13 16:48:26.635] _Post_Proc + [2026-01-13 16:48:26.637] @ Entered None ISR <--- Never enter ISR + [2026-01-13 16:48:26.637] <- wake-up + [2026-01-13 16:48:26.639] + ``` + + - WDG wake-up + > Configure 1 sec wake-up with WatchDog + + ``` + [2025-11-21 16:36:30.876] Nov 19 2025 16:35:58 + [2025-11-21 16:36:30.876] This is an example of Power-Mode (Sleep) and wake-up with WatchDog + [2025-11-21 16:36:30.881] Button = PA3 + [2025-11-21 16:36:30.881] Output I/O = PA2 + [2025-11-21 16:36:34.050] -> enter sleep + [2025-11-21 16:36:34.050] _Pre_Proc <--- enter sleep mode + [2025-11-21 16:36:35.098] Output I/O = PA2 <--- wake-up with WDG (duration 1 sec) + [2025-11-21 16:36:35.098] _Post_Proc + [2025-11-21 16:36:35.101] @ Entered None ISR <--- Never enter ISR + [2025-11-21 16:36:35.101] <- wake-up + [2025-11-21 16:36:35.102] + ``` + ++ Deepsleep + + - I/O wake-up + + ``` + [2025-11-21 16:44:10.823] Nov 19 2025 16:44:07 + [2025-11-21 16:44:10.823] This is an example of Power-Mode (DeepSleep) and wake-up with I/O + [2025-11-21 16:44:10.828] Button = PA3 + [2025-11-21 16:44:10.838] Output I/O = PA2 + [2025-11-21 16:44:13.727] -> enter deepsleep + [2025-11-21 16:44:13.727] _Pre_Proc <--- manually trigger to enter deepsleep mode + [2025-11-21 16:44:16.085] Output I/O = PA2 <--- manually trigger to leave deepsleep mode + [2025-11-21 16:44:16.085] _Post_Proc + [2025-11-21 16:44:16.085] @ Entered None ISR <--- Never enter ISR + [2025-11-21 16:44:16.085] <- wake-up + [2025-11-21 16:44:16.085] + ``` + + - LpTIM wake-up + > Configure 5 sec wake-up with LpTIM + + ``` + [2026-01-13 16:40:38.170] Nov 19 2025 16:40:34 + [2026-01-13 16:40:38.170] This is an example of Power-Mode (DeepSleep) and wake-up with LpTIM + [2026-01-13 16:40:38.179] Button = PA3 + [2026-01-13 16:40:38.179] Output I/O = PA2 + [2026-01-13 16:40:41.607] -> enter deepsleep + [2026-01-13 16:40:41.607] _Pre_Proc <--- enter deepsleep mode + [2026-01-13 16:40:46.789] Output I/O = PA2 <--- wake-up with LpTIM (duration 5 sec) + [2026-01-13 16:40:46.789] _Post_Proc + [2026-01-13 16:40:46.791] @ Entered None ISR <--- Never enter ISR + [2026-01-13 16:40:46.792] <- wake-up + [2026-01-13 16:40:46.793] + ``` + + - WDG wake-up + > Configure 1 sec wake-up with WatchDog + + ``` + [2025-11-21 16:38:56.627] Nov 19 2025 16:38:53 + [2025-11-21 16:38:56.627] This is an example of Power-Mode (DeepSleep) and wake-up with WatchDog + [2025-11-21 16:38:56.635] Button = PA3 + [2025-11-21 16:38:56.635] Output I/O = PA2 + [2025-11-21 16:38:59.874] -> enter deepsleep + [2025-11-21 16:38:59.874] _Pre_Proc <--- enter deepsleep mode + [2025-11-21 16:39:00.911] Output I/O = PA2 <--- wake-up with WDG (duration 1 sec) + [2025-11-21 16:39:00.911] _Post_Proc + [2025-11-21 16:39:00.914] @ Entered None ISR <--- Never enter ISR + [2025-11-21 16:39:00.914] <- wake-up + [2025-11-21 16:39:00.914] + ``` diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/isr.c b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/main.c b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/main.c new file mode 100644 index 0000000..e34e703 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/pwr/pwr_sleep_mode/src/main.c @@ -0,0 +1,310 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= +#define CONFIG_USE_SLEEP_MODE 0 + +/** + * The target module to wake-up system + * + I/O wake-up case is ultra-low power in DeepSleep mode + * + LpTIM/WDG wake-up cases are low power in DeepSleep mode + */ +#define CONFIG_USE_IO_WAKEUP 1 +#define CONFIG_USE_LPTIM_WAKEUP 0 +#define CONFIG_USE_WDG_WAKEUP 0 + +/* Toggle I/O when normal App executing */ +#define CONFIG_IO_TOGGLE_PORTx GPIOA +#define CONFIG_IO_TOGGLE_PINx GPIO_Pin_02 + +/* Input Key I/O definitions (Wake-up Key when I/O wakup case) */ +#define CONFIG_GPIO_INPUT_PORTx GPIOA +#define CONFIG_GPIO_INPUT_PINx GPIO_Pin_03 +#define CONFIG_GPIO_INPUT_IRQn GPIOA_IRQn + + +typedef enum isr_tag +{ + ISR_TAG_NONE = 0, + ISR_TAG_LPTIM = 0x123, + ISR_TAG_WDG = 0x456, + ISR_TAG_IO = 0x789, +} isr_tag_t; +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static bool g_has_key_event = false; +static isr_tag_t g_enter_isr_tag = ISR_TAG_NONE; +//============================================================================= +// Private Function Definition +//============================================================================= +__INTERRUPT void GPIOx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + if( GPIO_GetITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx) ) + { + GPIO_ClearITFlag(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + g_has_key_event = true; + } + + g_enter_isr_tag = ISR_TAG_IO; + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +static void _Config_ButtonIO(bool has_log) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + if( has_log ) + { + msg(" Button = P%s%d\n", + (CONFIG_GPIO_INPUT_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_GPIO_INPUT_PINx)); + } + + GPIO_InitStruct.GPIO_Pin = CONFIG_GPIO_INPUT_PINx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN ; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStruct.GPIO_ITInit.GPIO_Trigger = GPIO_Trigger_Level; + GPIO_InitStruct.GPIO_ITInit.GPIO_Polarity = GPIO_Polarity_Low_Fall; + GPIO_Init(CONFIG_GPIO_INPUT_PORTx , &GPIO_InitStruct); + + GPIO_ITEnable(CONFIG_GPIO_INPUT_PORTx, CONFIG_GPIO_INPUT_PINx); + + sys_irq_attr_t irq_attr = { .disable_vector = false, }; + + irq_attr.trig_mode = SYS_IRQ_TRIGGER_LEVEL; + irq_attr.level = SYS_IRQ_LEVEL_L; + irq_attr.priority = SYS_IRQ_PRIORITY_MIDDEN; + sys_register_IRQ(CONFIG_GPIO_INPUT_IRQn, GPIOx_Handler, &irq_attr); + return; +} + +static void _Config_ToggleOutput(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + msg(" Output I/O = P%s%d\n", + (CONFIG_IO_TOGGLE_PORTx == GPIOA) ? "A" : "B", + 31ul - HAL_CLZ(CONFIG_IO_TOGGLE_PINx)); + + GPIO_InitStruct.GPIO_Pin = CONFIG_IO_TOGGLE_PINx; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; + GPIO_Init(CONFIG_IO_TOGGLE_PORTx, &GPIO_InitStruct); + return; +} + +static void +_Pre_Proc(PWR_ModeTypeDef pwr_mode, PWR_WakeupTypeDef *pWakeup_type) +{ + msg(" %s\n", __func__); + + { /* User terminates proprietary modules */ + sys_disable_systick(); + syslog_deinit(); + } + + { /* Configure wake-up module */ + #if (CONFIG_USE_IO_WAKEUP) + *pWakeup_type = (CONFIG_GPIO_INPUT_PORTx == GPIOA) + ? PWR_Wakeup_IO_PORT_A : PWR_Wakeup_IO_PORT_B; + + #elif (CONFIG_USE_LPTIM_WAKEUP) + + // Configure LpTim to wake-up system + LPTIM_InitTypeDef InitStruct = {0}; + int g_wakeup_sec = 5; + + SYSCFG_SetLSIAlwaysOn(true); + + *pWakeup_type = PWR_Wakeup_LpTIM; + + InitStruct.LPTIM_Prescaler = 32 - 1; + InitStruct.LPTIM_ClockSource = LPTIM_CLK_Src_LSI; + InitStruct.LPTIM_MatchMode = LPTIM_MatchMode_IRQ; + InitStruct.LPTIM_MatchValue = (g_wakeup_sec * SYS_LIRC_VALUE) / (InitStruct.LPTIM_Prescaler + 1); + LPTIM_Init(LPTIM, &InitStruct); + LPTIM_Enable(LPTIM); + + #elif (CONFIG_USE_WDG_WAKEUP) + + // Configure WDG to wake-up system + WDG_InitTypeDef init = {0}; + uint32_t g_wakeup_msec = 5000; + + SYSCFG_SetLSIAlwaysOn(true); + + *pWakeup_type = PWR_Wakeup_WDG; + + init.Counter = WDG_MSec2Counter(g_wakeup_msec); + init.ResetMode = WDG_Reset_Disable; + WDG_Init(&init); + + WDG_Enable(); + + #else + #error "No wake-up configuration !" + #endif + } + + g_enter_isr_tag = ISR_TAG_NONE; + + /* Reset Pin Configuration if necessary */ + + /* Disable ICE I/O */ + SYSCFG_SetICEPin2NormalIO(true); + + { /* Configure I/O for Power-Saving mode */ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_PWR_Saving; + GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; + GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; + + GPIO_InitStruct.GPIO_Pin = GPIO_PIN_All; + if( GPIOA == CONFIG_GPIO_INPUT_PORTx ) + { + HAL_ClearBits(GPIO_InitStruct.GPIO_Pin, CONFIG_GPIO_INPUT_PINx); + } + + GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.GPIO_Pin = GPIO_PIN_All; + if( GPIOB == CONFIG_GPIO_INPUT_PORTx ) + { + HAL_ClearBits(GPIO_InitStruct.GPIO_Pin, CONFIG_GPIO_INPUT_PINx); + } + GPIO_Init(GPIOB, &GPIO_InitStruct); + } + + return; +} + +static void +_Post_Proc(PWR_ModeTypeDef pwr_mode) +{ + { /* Recover wake-up module */ + SYSCFG_SetLSIAlwaysOn(false); + + __HAL_SYSCFG_RESET_GPIOA(); + __HAL_SYSCFG_RESET_GPIOB(); + + #if (CONFIG_USE_LPTIM_WAKEUP) + LPTIM_DeInit(LPTIM); + #elif (CONFIG_USE_WDG_WAKEUP) + WDG_DeInit(); + #endif + } + + /* Enable ICE I/O */ + SYSCFG_SetICEPin2NormalIO(false); + + { /* User re-initializes proprietary modules */ + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + msg(" %s\n", __func__); + msg(" @ Entered %s ISR\n", + (g_enter_isr_tag == ISR_TAG_WDG) ? "WDG" : + (g_enter_isr_tag == ISR_TAG_LPTIM) ? "LpTim" : + (g_enter_isr_tag == ISR_TAG_IO) ? "I/O" : + "None"); + + _Config_ButtonIO(false); + _Config_ToggleOutput(); + + g_has_key_event = false; + } + + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + HAL_DeviceInit(); + + { /* Configure system clock */ + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + } + + sys_config_systick(SYS_TICK_1_MS); + + syslog_init(); + + info("%s %s\nThis is an example of Power-Mode (%s) and wake-up with %s\n", + __DATE__, __TIME__, + #if (CONFIG_USE_SLEEP_MODE) + "Sleep", + #else + "DeepSleep", + #endif + #if (CONFIG_USE_IO_WAKEUP) + "I/O" + #elif (CONFIG_USE_LPTIM_WAKEUP) + "LpTIM" + #elif (CONFIG_USE_WDG_WAKEUP) + "WatchDog" + #endif + ); + + _Config_ButtonIO(true); + _Config_ToggleOutput(); + + g_has_key_event = false; + + while(1) + { + if( g_has_key_event == true ) + { + g_has_key_event = false; + + #if (CONFIG_USE_SLEEP_MODE) + msg("-> enter sleep\n"); + PWR_EnterSleepMode(_Pre_Proc, _Post_Proc); + #else + msg("-> enter deepsleep\n"); + PWR_EnterDeepSleepMode(_Pre_Proc, _Post_Proc); + #endif + + msg("<- wake-up \n\n"); + } + + GPIO_TogglePin(CONFIG_IO_TOGGLE_PORTx, CONFIG_IO_TOGGLE_PINx); + + sys_busy_wait(100); + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/.cproject b/pec930_sdk-v1.0.1/Examples/spi/spi_master/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/.project b/pec930_sdk-v1.0.1/Examples/spi/spi_master/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/Project.nuproject b/pec930_sdk-v1.0.1/Examples/spi/spi_master/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/component.mk b/pec930_sdk-v1.0.1/Examples/spi/spi_master/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/isr.h b/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/main.h b/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/readme.md b/pec930_sdk-v1.0.1/Examples/spi/spi_master/readme.md new file mode 100644 index 0000000..c3f0f1b --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/readme.md @@ -0,0 +1,22 @@ +spi send and receive data +--- + +This example is used to run spi send and receive function. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Sets the data to be transferred ++ Run the example + +* spi_clk -- p02 +* spi_do -- p03 +* spi_di -- p04 +* spi_cs -- p05 \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/isr.c b/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/main.c b/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/main.c new file mode 100644 index 0000000..372bdc8 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master/src/main.c @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void SPI_PinConfg(SPI_Type *spi, uint32_t io_sel) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(io_sel == 0) + { + /*----------------------------------- + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 + * ---------------------------------*/ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 |GPIO_Pin_04|GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + } + +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + uint32_t tx_data[10] = {0}; + uint32_t rx_data[10] = {0}; + + SPI_InitTypeDef SPI_InitStruct = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + sys_config_systick(SYS_TICK_1_MS); + + /* set tx data */ + for(int i=0; i<10; i++) + { + tx_data[i] = 0xA1A2A3A4; + } + + /* configure GPIO Pin mux of SPI */ + SPI_PinConfg(SPI0, 0); + + /* configure SPI */ + SPI_DeInit(SPI0); + SPI_InitStruct.SPI_Mode = SPI_Mode_Master; + SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStruct.SPI_CPHA = SPI_CPHA_Effective; + SPI_InitStruct.SPI_TxDataSize = SPI_TxDataSize_8b; + SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudratePrescaler_256; + SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_Init(SPI0, &SPI_InitStruct); + + /* Enable SPI */ + SPI_Enable(SPI0); + + /* SPI Master Send data */ + for(int i=0; i<10; i++) + { + SPI_SendData(SPI0, tx_data[i]); + while(SPI_GetFlagStatus(SPI0, SPI_RXNEP_Flag) == 0); + rx_data[i] = SPI_ReceiveData(SPI0); + } + + while(1) + { + __NOP(); + } + + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.cproject b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.project b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/Project.nuproject b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/component.mk b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/isr.h b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/main.h b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/readme.md b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/readme.md new file mode 100644 index 0000000..90b1f7e --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/readme.md @@ -0,0 +1,33 @@ +spi send and receive data by interrupt +--- + +This example is used to run spi send and receive function by interrupt. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Sets the data to be transferred ++ Run the example + +* spi_clk -- p02 +* spi_do -- p03 +* spi_di -- p04 +* spi_cs -- p05 + ++ select transmit mode + + ``` + //in main.c + /** + * Select only send Data, and send/receive Data + */ + #define TRANSMISSION_METHOD_TRANSMIT // only send data + //#define TRANSMISSION_METHOD_RECEIVE // send and receive data + ``` \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/isr.c b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/main.c b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/main.c new file mode 100644 index 0000000..c37db7a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_master_IT/src/main.c @@ -0,0 +1,177 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +#define TRANSMISSION_METHOD_TRANSMIT // send data +//#define TRANSMISSION_METHOD_RECEIVE // receive data +#define FRAME_LENGTH 64 // Length of one frame of data +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint32_t g_tx_buf[FRAME_LENGTH] = {0}; +static uint32_t g_rx_buf[FRAME_LENGTH] = {0}; +uint16_t tx_cnt = 0; +uint16_t rx_cnt = 0; +uint16_t data_base = 0; +bool frame_flag = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +void SPI_PinConfg(SPI_Type *spi, uint32_t io_sel) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(io_sel == 0) + { + /*----------------------------------- + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 + * ---------------------------------*/ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 |GPIO_Pin_04|GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIO_InitStruct); + + } + +} + +void SPI_Master_IRQHandler(void) +{ +#if defined(TRANSMISSION_METHOD_TRANSMIT) + // send data and interrupt handler + if(SPI_GetFlagStatus(SPI0,SPI_TXNFUL_Flag) == 1 && frame_flag == 0) + { + // send data + SPI_SendData(SPI0, g_tx_buf[tx_cnt++]); + if(tx_cnt >= FRAME_LENGTH) + { + // Data transmission completed, and close SPI + tx_cnt = 0; + SPI_SetInterruptDisable(SPI0, SPI_STA_TXNFUL_Msk); + SPI_Disable(SPI0); + frame_flag = 1; + } + } + +#elif defined(TRANSMISSION_METHOD_RECEIVE) + + // receive data and interrupt handler + if(SPI_GetFlagStatus(SPI0,SPI_TXNFUL_Flag) == 1 && frame_flag == 0) + { + // Send data and read data + SPI_SendData(SPI0, g_tx_buf[tx_cnt++]); + while(SPI_GetFlagStatus(SPI0, SPI_RXNEP_Flag) == 0); + // The selected transmission word size is 8 bits + // and the received data requires forced conversion (uint8_t) + g_rx_buf[rx_cnt++] = (uint8_t)SPI_ReceiveData(SPI0); // need + if(tx_cnt >= FRAME_LENGTH) + { + // Data received completed, and close SPI + tx_cnt = 0; + rx_cnt = 0; + SPI_SetInterruptDisable(SPI0, SPI_STA_TXNFUL_Msk); + SPI_Disable(SPI0); + frame_flag = 1; + } + } +#endif +} + +__INTERRUPT void SPIx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); // Save CSRs + + SPI_Master_IRQHandler(); + + RESTORE_IRQ_CSR_CONTEXT(); // Restore CSRs + return; +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SPI_InitTypeDef SPI_InitStruct = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + sys_config_systick(SYS_TICK_1_MS); + + /* configure GPIO Pin mux of SPI */ + SPI_PinConfg(SPI0, 0); + + /* configure SPI */ + SPI_DeInit(SPI0); + SPI_InitStruct.SPI_Mode = SPI_Mode_Master; + SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStruct.SPI_CPHA = SPI_CPHA_Effective; + SPI_InitStruct.SPI_TxDataSize = SPI_TxDataSize_8b; + SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudratePrescaler_256; + SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_Init(SPI0, &SPI_InitStruct); + + /* Enable SPI */ + SPI_Enable(SPI0); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(SPI0_IRQn, SPIx_Handler, &irq_attr); + sys_enable_girq(); + + /* initial data */ + data_base++; + for(uint32_t i = 0; i < FRAME_LENGTH; i++) + { + g_tx_buf[i] = data_base+i; + g_rx_buf[i] = 0xA55A; + } + + // enable Interrupt TXNFUL + SPI_SetInterrupt(SPI0, SPI_STA_TXNFUL_Msk); + + while(1) + { + // a frame data send finished + if(frame_flag == 1) + { + data_base++; + // and initial array + for(uint32_t i = 0; i < FRAME_LENGTH; i++) + { + g_tx_buf[i] = data_base+i; + g_rx_buf[i] = 0xA55A; + } + // enter the next data transmission + frame_flag = 0; + SPI_Enable(SPI0); + SPI_SetInterrupt(SPI0, SPI_STA_TXNFUL_Msk); + } + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.cproject b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.project b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/Project.nuproject b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/component.mk b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/isr.h b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/main.h b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/readme.md b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/readme.md new file mode 100644 index 0000000..45c2ffb --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/readme.md @@ -0,0 +1,21 @@ +spi slave mode +--- + +This example is used to run the function of spi to transmit data in slave mode. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Run the example + + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/isr.c b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/main.c b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/main.c new file mode 100644 index 0000000..dde6401 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave/src/main.c @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= +void SPI_PinConfg(SPI_Type *spi, uint32_t io_sel) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + if(io_sel == 0) + { + /*----------------------------------- + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 + * ---------------------------------*/ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 |GPIO_Pin_04|GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIO_InitStruct); + } + +} +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + uint32_t tx_data[10] = {0}; + uint32_t rx_data[10] = {0}; + + SPI_InitTypeDef SPI_InitStruct = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* set tx data */ + for(int i=0; i<10; i++) + { + tx_data[i] = 0xB1A1 + i*0x101; + } + + /* configure GPIO Pin mux of SPI */ + SPI_PinConfg(SPI0, 0); + + /* configure SPI */ + SPI_DeInit(SPI0); + SPI_InitStruct.SPI_Mode = SPI_Mode_Slave; + SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStruct.SPI_CPHA = SPI_CPHA_Effective; + SPI_InitStruct.SPI_TxDataSize = SPI_TxDataSize_16b; + SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudratePrescaler_4; + SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_Init(SPI0, &SPI_InitStruct); + + /* Enable SPI */ + SPI_Enable(SPI0); + + while(1) + { + for(int i=0; i<10; i++) + { + /* SPI Slave Send data */ + SPI_SendData(SPI0, tx_data[i]); + while(SPI_GetFlagStatus(SPI0, SPI_STA_RXNEP_Msk) == 0); + rx_data[i] = SPI_ReceiveData(SPI0); + } + } + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.cproject b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.project b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/Project.nuproject b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/component.mk b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/component.mk new file mode 100644 index 0000000..bc41314 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/component.mk @@ -0,0 +1,16 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/isr.h b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/isr.h new file mode 100644 index 0000000..cd15d53 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/isr.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + +#ifndef __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ +#define __isr_H_wuraIpBA_lTJm_HvJw_sNDo_uEd5JnucTReY__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/main.h b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/main.h new file mode 100644 index 0000000..d0b4252 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/inc/main.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.h + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + +#ifndef __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ +#define __main_H_wxBnwdPw_lq7D_H4I5_sHPp_uXof15pFLp4V__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "hal_device.h" +#include "syslog.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/readme.md b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/readme.md new file mode 100644 index 0000000..6f742ea --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/readme.md @@ -0,0 +1,21 @@ +spi slave Interrupt mode +--- + +This example is used to run the function of spi to transmit data in slave mode from interrupt. + +## Hardware and Software environment + ++ This example runs on PEC930 devices. + +## How to use it ? + +### In order to make the program work, you must do the following: + ++ Open your preferred toolchain ++ Rebuild all files and load your image into target memory ++ Run the example + + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/isr.c b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/isr.c new file mode 100644 index 0000000..58136cc --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/isr.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file isr.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/09/16 + * @license + * @description + */ + + +#include "isr.h" + +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= + +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= + +//============================================================================= +// Private Function Definition +//============================================================================= + +//============================================================================= +// Public Function Definition +//============================================================================= + diff --git a/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/main.c b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/main.c new file mode 100644 index 0000000..9dc3128 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/spi/spi_slave_IT/src/main.c @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2024 Wei-Lun Hsu. All Rights Reserved. + */ +/** @file main.c + * + * @author Wei-Lun Hsu + * @version 0.1 + * @date 2024/08/29 + * @license + * @description + */ + + +#include "main.h" +#include "isr.h" +//============================================================================= +// Constant Definition +//============================================================================= + +//============================================================================= +// Macro Definition +//============================================================================= +#define FRAME_LENGTH 64 // Length of one frame of data +//============================================================================= +// Structure Definition +//============================================================================= + +//============================================================================= +// Global Data Definition +//============================================================================= +static uint32_t g_tx_buf[FRAME_LENGTH] = {0}; +static uint32_t g_rx_buf[FRAME_LENGTH] = {0}; +uint16_t tx_cnt = 0; +uint16_t rx_cnt = 0; +uint16_t data_base = 0; +bool frame_flag = 0; +//============================================================================= +// Private Function Definition +//============================================================================= +void SPI_PinConfg(SPI_Type *spi, uint32_t io_sel) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + if(io_sel == 0) + { + /*----------------------------------- + * spi_clk -- p02 + * spi_do -- p03 + * spi_di -- p04 + * spi_cs -- p05 + * ---------------------------------*/ + GPIO_InitStruct.GPIO_Pin = GPIO_Pin_02 | GPIO_Pin_03 |GPIO_Pin_04|GPIO_Pin_05; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStruct.GPIO_AF_Mode = GPIO_AF_1; + GPIO_Init(GPIOA, &GPIO_InitStruct); + } + +} + +void SPI_Slave_IRQHandler(void) +{ + // send data and interrupt handler + if(SPI_GetFlagStatus(SPI0,SPI_STA_RXNEP_Msk) == 1 && frame_flag == 0) + { + // send data + SPI_SendData(SPI0, g_tx_buf[tx_cnt++]); + // The selected transmission word size is 8 bits + // and the received data requires forced conversion (uint8_t) + g_rx_buf[rx_cnt++] = (uint8_t)SPI_ReceiveData(SPI0); + if(tx_cnt >= FRAME_LENGTH) + { + // Read the last data + while(SPI_GetFlagStatus(SPI0, SPI_RXNEP_Flag) == 0); + g_rx_buf[rx_cnt++] = (uint8_t)SPI_ReceiveData(SPI0); + tx_cnt = 0; + rx_cnt = 0; + // Data transmission completed, and close SPI + SPI_SetInterruptDisable(SPI0, SPI_STA_RXNEP_Msk); + SPI_Disable(SPI0); + frame_flag = 1; + } + } + +} + +__INTERRUPT void SPIx_Handler(void) +{ + SAVE_IRQ_CSR_CONTEXT(); + + SPI_Slave_IRQHandler(); + + RESTORE_IRQ_CSR_CONTEXT(); + return; +} + +//============================================================================= +// Public Function Definition +//============================================================================= +int main(void) +{ + SPI_InitTypeDef SPI_InitStruct = {0}; + SYSCFG_ClkInitTypeDef SysClkInit = {0}; + + /* Configure system clock */ + SysClkInit.ClkSource = SYSCFG_ClkSrc_HSI; + SYSCFG_SysClkConfig(&SysClkInit); + + /* configure GPIO Pin mux of SPI */ + SPI_PinConfg(SPI0, 0); + + /* configure SPI */ + SPI_DeInit(SPI0); + SPI_InitStruct.SPI_Mode = SPI_Mode_Slave; + SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStruct.SPI_CPHA = SPI_CPHA_Effective; + SPI_InitStruct.SPI_TxDataSize = SPI_TxDataSize_8b; + SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudratePrescaler_4; + SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_Init(SPI0, &SPI_InitStruct); + + /* Enable SPI */ + SPI_Enable(SPI0); + + sys_irq_attr_t irq_attr = { .trig_mode = SYS_IRQ_TRIGGER_LEVEL, }; + sys_register_IRQ(SPI0_IRQn, SPIx_Handler, &irq_attr); + sys_enable_girq(); + + /* initial data */ + data_base++; + for(uint32_t i = 0; i < FRAME_LENGTH; i++) + { + g_tx_buf[i] = data_base+i; + g_rx_buf[i] = 0xA55A; + } + + SPI_SendData(SPI0, g_tx_buf[tx_cnt++]); + + SPI_SetInterrupt(SPI0, SPI_STA_RXNEP_Msk); // enable Interrupt TXNFUL + + while(1) + { + // a frame data send finished + if(frame_flag == 1) + { + data_base++; + // and initial array + for(uint32_t i = 0; i < FRAME_LENGTH; i++) + { + g_tx_buf[i] = data_base+i; + g_rx_buf[i] = 0xA55A; + } + // enter the next data transmission + frame_flag = 0; + SPI_Enable(SPI0); + SPI_SendData(SPI0, g_tx_buf[tx_cnt++]); + SPI_SetInterrupt(SPI0, SPI_STA_RXNEP_Msk); + } + } + + + return 0; +} diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.cproject b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.cproject new file mode 100644 index 0000000..5778a16 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.project b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.project new file mode 100644 index 0000000..c61dca1 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/.project @@ -0,0 +1,54 @@ + + + Project + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + Common + 2 + PARENT-3-PROJECT_LOC/Common + + + Drivers + 2 + PARENT-3-PROJECT_LOC/Drivers + + + Profiles + 2 + PARENT-3-PROJECT_LOC/Tools/scripts/Profiles + + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-*.nuproject + + + + diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/Project.nuproject b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/Project.nuproject new file mode 100644 index 0000000..c2ca38a --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/Project.nuproject @@ -0,0 +1,25 @@ +SDK_CONFIG: + Debug: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32ema_zba_zbb_zbs_zca_zcb_zcmp_zcmt_zicond + toolchain: gnu + extra_cflags: + extra_ldflags: + Release: + core: N203E + extra_asmflags: + archext: + extra_cxxflags: + cmodel: medlow + extra_commonflags: + abi: ilp32e + arch: rv32emac_zba_zbb_zbs + toolchain: gnu + extra_cflags: + extra_ldflags: diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/component.mk b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/component.mk new file mode 100644 index 0000000..e5e2310 --- /dev/null +++ b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/component.mk @@ -0,0 +1,17 @@ +# +# component Makefile +# + + +C_SOURCES += \ + $(srctree)/$(PROJ)/src/isr.c \ + $(srctree)/$(PROJ)/src/main.c + +C_INCLUDES += -I$(srctree)/$(PROJ)/inc + +LIBS += -L$(srctree)/Drivers/PEC930 -lSysDev_PEC930 + +LIBS += +CFLAGS += +LDFLAGS += +LIBDIR += diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_SW_unlock_ICE_time_slot_resp.jpg b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_SW_unlock_ICE_time_slot_resp.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1ec58cd32c750200dd7c19870ae4e39bdc8a1a4b GIT binary patch literal 34721 zcmeFZ1z1(z);_wCR2l(kkPwtox`GmF6nOR?uJcBcXw|7%isCV zcaQu|eQ}?A@AKU4v)nNEWbHNQnsbbIyyG3~Zt89Ug!N8TLKFn|00e>q{(H<=0&k2pi?WhX>E#;V3~5u;Jjb z;qKZ%K8L5GP`xf`#*-U9pl1DK?fLK#{u2U1BAREkbkAR~v2$>8ar3-+ zD@OioQh7nhb-R@c@yHn$Fsj!#a{&Mz*n zevJzb1pk*|0ssGHVE4v_4UFpn0s=e&@~?5hJ#YXHcx(j3r>~H3gk_O+tR7Rcd`7{2 z9iCd!{E&)O?f~zT_3$HnYPLn1!(T)DV`Tr{z&!t3Bm2*R{a@pPg3#dMfSU)84H5*M zU(uy`Jo^90!Ch9cJ*irmYn-`pWjbVhj%q$KXCjTtOQ0L`R1q2UNrvZ)opy##=ME&q zhW`!Ivl9Ank!qx)?cj(Ds;i{9uLL_&fdtJy)4}EVz<$^aP{db_QiXqv5-A8r5 z109^b9dQRTw5T7okn5qB|f;;{W6mE2F7$mrXn0g0VShIkM`#3pDH?LQv#TQc^9*ES-N#<0nB!sJXs@ ziExsF0{dqt&zmHp7~W;4W7|BXSKc?ASrr;V->>5pCvAp8UW}w*Kz5T}-hoo^eeXbC zv5lAbp_PuUFb`F77>2uMpS=~ny< zN8lII&~6(wc;O3sll1rwRGgoDC1R(62*Q;W`O{(T{Gnl~z)-Ygobd#mP`jZjWQjde z`Rhw1nI;l7>;!UoC4t`ub3l6&IfxFKdNFwi5@EE(g&Vvr>mWaQFmwkxu;IJ|Q4XIC z5F2yQ8!tk_Q zWpykwnwpWR$@{4jlDmBKbg1ci!l#maKB*<}Ahw1v=HeU&XPGi}b(qOO6Ln^>f)l(I zF|k+3>=07u|9k-hi=4n&pd?oV%n8-Z%~n;F23sJuR1_?KC@d|{^QvW|@Orr8957qx zJ_vh9R(1!{&cnPVcK8Q3@bBH!f7E6JySF3N??AqdE8I(i*N-~yKpBb^Lo#q8xH8C3 zavg1CsxSNv-EiO8Iw2@=n$<&!y!DkkSR<2PVOZUP7`#7qFZ63GUkuEuAxoH=Go0w- zFb|ZmMHH{xG_t1Igr2%bZH~zx<1J}nXl*?fCJipVq)+)dweFlFL5<}%Nw{IpN%c82 z^OO39>gEqKv1?A{_O%$qJT+AfHTt&0eMIW{cVEq>dm=-ud6aShs{rwF<+jTJ!)zxO zbwb~kmV~^a3)>IQWU5(6(C4NwJnqyH!3D{R0Bi03vbTXf{bh!}+<|uJX<^|SO2R^j zxUzpb0NeCga3#qR3~N?wym}5!DTFj7A4&7E|C)cTTim}+4egRLyRxfNipiCGs6Zxq z2B%eDm=q36EMGzPc}U7_$EFHVj8DZNws4V248GO0=4>k%Jvbqf9;@;w*7sX)6ymq= z4$D{l&ZM|-os`>TPY*@?o$ON8jTLL(=4LLI zHOKS=%`(R;5-hu`N&Aw_7lT%Golj2-Jp({=X@5D^cL4j4x-EG2sQ3;vTxB<;BxraC zqQO)FOu$E9Sa4mT=l|HypfcH@- z3~P=V=3X&)LpFa0I^6nYuORo@1Q*dq?m+9?!18O}-M<5o{Tjyl9q4{@`n|vVb*^X2 zt(CGDbst6*_tmcX&Ys9u!)6->E>@~Ot`D3a5jbIU^PlgdyL zo^(T2Gb?YG5BHV+&8hk~ub=td0W3LPU0q$(tsuMlt%P1}L)>aW>ZcS!4L?v_0-7Cr z?qBx(uf6}jalm;w5GRux;~;zr%>4P>)be5UD7?UhV0gh+I#X6SxH3*QIB<4G+M1jX z?(y3UcLB?rV9k^V0d)V~QRC=NapAs(vhJ}}+Dhpw@mRE8U!RJ?lX3-nzBb@^5D5T5 zp^JB*YowVw&_+e!d&Q?i5}7XXvKikwVwwDxNniX_JR~V?&qJsglT-E^-WyO*oyii% zwmPP=v~)S4m}qn7A6iRX@V9e_V^?yV6sc$U-sVm1r2gPzvCFPNl<1(0WN*Q1L{WKt zONvj@^Uvs3x^Af94{}|3??6-?Re-IVA-^SbP|-Pz$deDxBl?(o-#2TJc<>5H6^fKT65YL>uL+pA4V+J~XS)Jh+aE@Y zC`FUV85qmW5Z*h74f+`9HdBzNq+sj?tey@M7J9MmT4l@=6Fa<(+bK6{ zi(j#3073XrPutcT=bm)tP@BKA=)F5Kkb+r@@Jh_}{Au^Lt? z>|WA_dGNgQbFtvU`_98W7%A{=%W8m+G7E(T)fJke-_|x-49#HQuok5S(9iNM6hc~? zNG;k^g1o+G{}D$3ZsRx9QVtiLgf_l=QaNOL^Oo`C@mJ-E(c2ev{&ygSNQ)){>IX7m zyytliN$5{h4gF1{FFI<+0v3bR>OG!@@VV{B-)h=)YMD-$hc5App0~OaMYyC*Iz;x; zjC~Kl497n+2X*r5eh_Ss8uj%*9YhmZGIA9)T1dRF80D1}m7{S#lIRnXDwaoj}X0c5894)j>{w$box zCGXijt-uG$5I$XpepnHI?Q+Ev0m|s(MYlnJ1{({$INtfzFydYaUG>&WOE*yr`WG(2 zkk(qwm_q5Lho`&}29+Uu(5-pAmcE|&@N^N1JT5M71OpEiNEy4*SU#H?`xsSm#YFr1 z^x9}ozEytKYxmJQ-BiBspX5|=V@CJNiFz(e<3D$v^dMy?+NSBfbhn~inRVWs zMJC*r#0ZWHUsrBCBNgjP~kEBCIZ?fcWUh?39()-sR_Ag(U94nL#u_O5B)6|#LM9Fkge4It~ zn11h7jnpATRfJn|F}P#Rx`nMt*zX-#5WryQS|&kB_ZpL-UDVp%18zAEv};uOVZHO^ zl&WS0EXoCOHzB&0<{RDKHlHWgG>Tb1s-7M43%5M!x03?}4sQBZ*|W-;)40bvvEikK z4;9hAcw(TOQ4AsV{~ZW;9~Ke{&`gAUPLp&Fb4#;6Y(?O$yo~5t#Fp6MeA#`{FING< zhiUME(s8=Ch*y)^;bE> zFqo4Pge+SJg}xt0p*S?Vy-gj9|1i3<+sl@x&)YX?R_=kZqTwHz;Mz%HBZOB^wOl6! zks5A?_9EV%ro=ykiZ6t>cu{urH_r^(H0=irjo#>IY&le(4Y?J#j|J1@m#KD>I6O+H zPJanH9IRf^Q`GSNQbEs8-+b1xHvMc^+h{#pLR)#JTquPq`J2}OSNdvs=bP>ye3yc9_Fg9uMc)tWCxg-o>oTB?R~1Qu85$^ zc&jm3@l895RIH@KN*;PKBT|!Or00?+@w6N~jkua0_6d=KP(Yh&{X`(D7p#d~V*%Pw zbsO(9Vgo2uD5#KC&O=a3$?;d;4j%AVn?59O1Qoz}EDlVNimFOp~4=`TL+{cCwOu6UEy8 zkeJNPi5QzXwL!~%JIA3H3{p4?X2IRmeY_YxrS+_ff&GH&u;GT1;)++$Z%?`!k~ZgJ zzm^%iN6`A}T21>i#MVM^C3WNH*`r3l4px2zx&4!{7KF#QYn|bQ-hsq-^WvW+uT@x*vilJKRNjvaBMc0Wyx?8O(0p3J&mU)$1nh7$>V?H<@Cge8AV zlyT2iAr+;)Vrb7OE#PzjD=mNy^skO0z5|OJKN$HhBi;xLR6XH2)_5R@WvoduaNZWRaYt5#X26P|5+#eRV%xS7#{HF%kEfxVV3b;aCQ1DY*k};uVnp4wl9=@soF-Xi_&GF{M;hk41|I zkC%tBQbK1^%}QTXa#Eo!m!u#Z?0;!24o-Wl!60{Z%K^Z3;*nA(cY6kp3GGp!90Sx4Pp^EH}Jjs#|hQ zJ*v;(Wtg6Os~)ll$2duSL~o)MP$@GzXFhDls%!k6BgV${fs<7av5}yQ73l@Z1KtD~ zWO9RRUfju+T8Xro-6KBn4 zs(x}WXUY!?kO#j2i?3FXu9lYhrv-^*WytqrzQg2DPi%X>m1^xI5EYZ@*sFf1`4TNzF{}_tT+W+5HlD1#09GsFlXt_P|Z>Wh8P*7a516fRZIRV zcp<_tM_xH1!868*#x-LrYN=pm^M#nJ(+RQ8;TSc9JB->YCfzfx=`9NibJx z9I-|oN##g4rNGEK#XhLeh0JNWJk5javi^x(4*&Rk_V;$CR4ev)LW+v#xK?WKX%rNg zr28E71IZgkgA`YjLeHeJww$Yy>vo5Q$)n1M`5JE4`PLyR9lR5n|2(cyVzgR{-DRp* zqzQQDE9Uc@;t|Fs>RUDA^$0bPE-5&-@bz}f`6Ll6-CD2e8t-=Z>p)$|Aqi>(N(Z-{ zaL@_urqDx-+$AYp*}Bn_?vokWER@Ci+UhE&FI7nF_6kDV6+-&m)Jaw$tg1hVCJNbI zT&9>8LeRyeYrtw5{{F9FdqHy(F5a@L0H%hKb+5rx->Cou{DD zOX+r~Ca6~IdTkV;C*Jm#D_X0)D}7hOErXW!8Xk*hr^DrAJj9PkR~21uX+s% zNNAVAz=;q^yh|qx3DiZAB#fszD0UbUi(jCx&8EE2@S~9#c;pg;6WWwty6bTQ|l^YJ-!*z0c_1R(&Q*1+)^s4LwkX+3$7R=9jZo`0BEb^)ynda^rTOlcL2zd@4p<`So*2`5DTYbmQigjG4Z@9?Fu*!458z zfQzU7+zv9?fN>7n^#+QY&TpVj1yz-!CGVi(@I+5z}~6~>FQr9x_&4I@Rj!C?cX2>8!dMrEL*5o=MpME8^v?}{NtEG zijG4%^3XWQ3$vd$LGyTkWBQtWC1xYnot+WaUzwrd)oj5A_o^9(%~X1E6>}i%o-6Ea zRhxO;sSm#9CIx_^)@vt#UHpR?{l$*{vjfRIHn#zmnm@y4lGbu)_SNgW+4H$Igi!p3 zUSwELR7|F)6;Zs4Y9v?L*k8vfcQ!w$1GZ|ejD3#c!&NMZ^7+Q(6l5dz`p3|>{>9wK zJJY?JoM>-pVKto3sCIi?Fe-*-x{lRE7{cl?HVD(KQJ+#pQRA@iSc>NY1Vr3Msc2X0 zizZM0T!49vHPU=o*KiR1Ic>h5G2sW{Bw~|;M{%uqVk}2O2%(0%P6C!F{p;n$qU6O} zT}jx)%xz{NN734Cynv>LR&U3i`yQvB-KNGaF5EIyx^)+<9@tjN6OzvE6X>)=ALyU2 zIfP#mBwm;wf%7O&+g{Ki{E}K zVf^?GROAUV0IlP^VrV@uU?2W7cY7bW|L5-r3wkGMu?(M-lQ;%Q-zB&VAty*263YtU zRE+2Eq$KUDjuZ8YelE=`v-;@t0WxL4)j1D8UpRFU-v;FjEbm8d4>z{%%%k=h+5do% zsuyIgXJ_qVOLYet_e#6?aIAU(&NQ|^m(X9rL^Jt7>4f|B@!MUG*1`!<`HPT>I^D(4 z$J+wTqwM?m{h1wc@5C8)*+zDVB#Cl_E2dlF(Eb4s`lJ0R9k&Ja2{=A+aHN<;X;JcS{9jlf^ ze0|H&t&aw1>+46dLZIUBSaQM-MAgV0NY*!4Bh^pWTN@v1sn0ojs+?p@>Q6A7;#P`< z&FoZ)ioCvd(DR{Au)oQyzpz_Emu_`uuc)sbRlL?pB3wLD>9hI@wJ)JhUhELHnS{>- z*>TL%JMrmcZw`{ppsPuPH z!wL?WTLn!+5Ne0Zw*&KjmX#Pqt+yF@gkkckAMq-}%JlOgEpM{6pi&jVgVVcAW*Gr{ zn+ta!<%42vMa}`fh?hcJbnq$PC(nnBE9Erio+wjwoQY3&AuMyreBfR=Bc%PT@_V|n z{9Zf&M3tGVg{ffD@x(SI{3EoC5-vNP9WlHP=x;VFW(jfp#J{neV)P`KO1|16a)+nB z@7!WT8~@8Yx3fL?3t!dv)+@{qrjc`nvAuFPrhS=2!-&ZpYjr$Ig5`ll7PxQ%UZ)P{ zGm@!VxjgA;-gud~FMHjE8lAzm)vX+@*_t>t3*j`Cm|GB@5(j|SBzBwb<;8(-!U>}tBK$$6^{a{z&r16sc zwCEaf3bHX%yVmpxtWcQFnc4U{BjRo2L8wXc3HNsL`5M58hHn7Z;i7N{N*x6Fs74O0 zn@|lzyuDZ;(!ZgCX5V5suisvl0vQ=+zE_O~8+u<0J@LEmF zz05El2NE^EM-U*}f5guHSKIMaVe~aS838?;X6D3j21fP$UVLFSgj@rxO zb@WcX8>PiaMc%VznIyp{#!!=}zocS1d6y&Rl#(+Ft`sZ&ea5l-f*kf169Y2E1h6S0 zjCN7?8XTuPo5|(hxkTH>KioNGw0C;_rT&M?QuBaF10rUsy z=9^HdoAbEnI)u!3DnA*pwRInvEk-75#ffHZLXHHtwa!rgk|67j{<;0)w()g#$;hw> z-igoC`@~|!|7~|heZJBTwFu8xRU@m&AzPR+YObvSOu{fQ+)$e%U}_F(D;mNWgBy_r zuIS!s5?mx37u>L!6x{Cz7J0MxL=99*@+wW36=^h%KCOx)@YyS=6V(d2=_Kbb+gG9= zG`H1IgFTjFhP_DCZ(P!Fy1oNF8-0G=YY}rR`ZKEFzHhil{Xlx6W^)bKkcMEdV`+GH_+Jid(wO$|jO))^4uFYxgLj}7 z{_l{X^+L$ccxISbIt+VP9_Gt$1G|}q9PtC2Nl6e$VV&jPf!-w5+=1Lp8!yR1FT^UO zuSiY@uaETslXC($^xvH8|L3nsS#{FSoUOp1r33wi%b}G8f1A(Tq$`;CZOx;pxxRD{ zn@-S47UZ`n%5N-_NW0jVt{$_y&g&8lckPfoL;$1UK=szRhP2lcr#D`OSi_ANJI^QP zckJp~m$Dg}mSD+=ho-0Ne7(k^$85R-9Z@*iz?$uUUOhKS%7%9wQC=O+4=!x>JH31( zLK%9c4TrIOyM%QIs^rRZM@TsoZd}IsfjfB%B;)PLuQ>M7hIDNw_&)RnrJl0sQ|nq@(-e1|u3%p% z)BVNRIImd7wG7A0Qw*+=XKS*} znSQJDorc`dPoL*!R&+nB(V{xfO9ptBJlHl0U%5JJ^*v~zJ8R9AtOXbN33R^7!5E1+|Q#H%~o)JL%Hza9)u?>cE#bdttqP~4i+<6Y54fXNd^2wMsd)1Wi*J@C8wXdDj zT?fU2zF#4)KH3!lXO@SxL_jw2`W?UVx_wG)Ea;~xf{ zgZ1#n?s)m3rN4*|h_FAQrOUwK>cqAA^*^+#BuOMXlZOIZWBK*uEF1txNd7F zsUiR3;f|*Ss0e_e1A{8o_$8mnEuUlGu{aI%30KydD`@c$*uWCO$6O{941SXdn2?LXFB@bx@L{}MJ~2N#)2y|?j7h~(qC*XgG1_C`b} zGh;~IBTQ~?mw0bSv3VE`!nH%Y@fO*WvGrj-Gc@~mlROC}>^bwXUm5G^C;4>7ua>i1 zCUp#pHhDbN*pt%DxM~fR?Zq+9r0bEZ_jm$A_S!q3b^i(Jpb2O? ztvJ5Jok-G(7aT1h%k;fP`wi|3VzTPl27VFcl0y#P-1$IyQq_UAmCiN4rC8;tCT@c5 zX7X<-=&Jv&VsoY5(tViL_oQaU@nly_4oefyx^75}Dqk-|$nYcbWVZ9RNmgdow8^avY6!vJ1uX zi=Jc-)?;11u`37vQ~oy}4s`dbLfp*9GZO1dUsp}{dE^XAO)Za9**2nXs*22LssLnf5ZP!{xc51yrv-ZZ@5KpCCgUVvC;v_kxXa)Z~8Z<7m9wL|S;mVAA(d7~uek z#~BS|Er2)XD#jGK$j^lSVT%1M*~*T+?`%y>CKyWwP%L~~dlLc4Gfl_O=STEeha=lHoq3dQ$eC?8nWA4PqnEw{ zf=)S>fO$gPaD3Ab(pZYn9cB_M;WM+a*HZ{%Q#LsN#ok?c`NPbD z)%GPP)(iWQ)!hjeT-LI6WCxO?k29*W8zNOrw!ngagm8{ z0CzMc2Y8Rl!mJvzC$Kj# zdcYoJK(0j0H0{B#y<1t!S-1YN&1HU;VLcrSrer7j&goda%102;?q!@o#UJN*1eubP zzNM@wcqq_%TVl3m3LCoS`|-j3JgQcZm2CQ`>_XA~_nt+Mfr*7kU+oz)#*P8t^wj5{ zu}=T_nR@bP00|2ntlxU>HlD~$s@!k*tLNniwBzr{TcXPhPh>nr2%r&c%9=n1ocd>8 z@{X8$b}ug)qI0d7dM1_R07ZtLogTYpbnHWzdv9L-9xbi(Y8=v!p1g1&Wdt}g@lSYz z7cPJTl>wNqd|acq*f>5LX1DPgvBZ2TAwOY>PAI zT?b0}y!tQSMWbO-+|JieW)2IHL9#C7y8tP`NH}yS&?M^k9!zG-EtvI_(2>RZz<{D4@coZT@R?`6TaZdQXN3OI@6~j%>}}deow3_9b~6eQB~83eVc@?U*6kIG}|(xA{O;j zu2W}zBLh;A#G?f8wJ7#JwI7nR-hip`uUzoUU#d%xghilmg)4JD4RKoM8|hp`f5cA& z;4*ybsVxk>+TgYDpb#O%K>XQP#r!9#T42gQP0*xPuc%^KTIhpMza;@6uOqF?* z`Ba~ZSG|xJ90}n`*1l`bX>G?9ec3;CF_P5|Idd}2Dq|oLMX>K#O)-gpQFS2bs~0Rvd{uThZ42==GK_uh~4O*F)E4UE5pC%#o?F zL!wG(_5*y1GK|Tg&enqvu#FwVQn#PqQ(u$smkG;#RMbbjR;pA@n#9<>kCnR)>RE(} z8^#JqUUj|P#))ooLI{l{u~L)DQmITgb01pUf-4-Iz^0|>N zn(tq%3x21DUp0{)tBOLQ|FYaj`K5IyH`Mx7hgjB!+x45T{KT+k0O4J6j1;OlI=m~B zVyCE>sx`j@m14dMjj6^n&ra}kUd#OrFang=uk>%Bn#dpEE&#~JJ_qFdYD)5dvXDi* z>~|ms_nc~Tfwc*T!=zaIl9H-G>3aW_o%|6sJaRwLn_yM|PW^@vD`*1&jHn#^PF+=9 z{Ru$aALRTZ?w{Vnh}FE;&JM6Dw&=bsATNDY_P04{_^|SEK1&$U1QSy^D%Yu>f&S>O zqTO>oSDkPBO|(fFwz(8z^#;&n-{tr><&wOCX3+99{r>zq>7H~*AM58Z;%yC$zn^4N zqFsPoV(|fDMeRBZKm$B+zhT*s9KlWM`JPl7bkO4aMSzN~o@B5vjeqE2PQ_;y!3FWw zgUsK_i7hiuIhXC*Pjl%X@t=UrGsx@Fuq7iey2KV`{$IjQ{96&jNALx0O=$$ZT4!0p zvff6(syO#XlPBhzoewB{Lx}fd2dUed+>M{iehi#5p_hJ}8-wKIORLK_oH=_f#cYjF z98G=#u0wi>^chXEOo(z&OiAGhhkdJM_lh2NvaY7PA^yQG(?+$q?a^i~Qw{h#Apw6w z`NZO{{LTAc`J29RQZV3|aesMcpw_`g*+GEqU>I0{lo#<59C_LE3_;AxQzYGH<&WzK zn_S(9=L^&?Lf?$vNH40nv8s#~8ECu{GukbT5Jf%X4UfQ$3<@8tE+T&T!K8s>@-)}l zq;GEnSagy9h8SY4VkX$=BKuv*2(xw-roMv}wFB0^#5?}l9BQoIw%{&78D|+}$$M^j zyt-a4IwG^mkC9j+(eGol*iSP6c^H_2Sf{uY`Mqs4F%Cn07+tYb)Mgz+#RH7WXKW+5 znbQE7M-GMOGy>W9ioxO6RAQ#Aujf2IFq*H0aZL;ldJvSG}YUHzB^E#D2x&n zQ#qAO7k0c$+N7g_SZ{$|E-S%0u<=<{3B(#Ea0mr;Z#O;o;nx*$KREv-!EgO}L~>|& z>ka5XM(9;R8~-XY{C7U57nC0=ceCh$O^oDQ+$3B=z*Q3VhJ+mee~gjjS^gKjx-{|~ zXec)oCs2gbovtnlF%$UCi3!mTXJH!9?%;z#f^cF4 z>?l4GEX+j(bGFNsL;J*BI<2y19Xt4h;~x@?(~ehfe`bPZkbe^&|2fH`Ta2d*ik{KWC zg%|s2+lh3Iui6tF6j%0STECk2WtXhnftbF=i6-+WWfw`ml!>X@=Hue-K{cXUA6*O1 zQ}y6mhhg&*wyKZ9JTc~l@kahA;=8}fOpI$k#HXuO{D{ehDmM*iq*r)KDaU8vf-O? zsR(3@jg93zk;YKB#2SMr(`=`>-O4by*}xJOo6v777)B4OzPLIV7j4#Z)v0JV{wRN} zHzPrU!zH7qJYCJ}wC6~As7eG0Do^}yHV?(DD1wG(R78VSs6rMM^u8K^$hgl*f&zMr z527;-GaUt{)Mu!n4Co|B&lymO?fq~OY>u&j1;UxsUh*8 z{!4OMDLj#P@68m~LioPI2z{d;&pJ{avcIZuh?@Kh)_!tf&gSQCKf|fVK6AaQP*n{6qs+5eJH1LeYTgDP?+U*f|6dHqY zeK-*O8?yDl{JmcC_wq$BP^AN)x!=3=gtoiWL|@C4YhfA-=m%{hWNaO2mjqJ-l%D9O z|C2&)MUB_NdKcPAAk^i7YN6I~Uicbhf#+E2^?yx*2N_)8jyBE#Rz_&qE!)&5LA4Z_{ zDd96zJDudQ1zYr!T<;trOe8)P=^GofuM-BiLP7YQ8QtAf4O^9jv}Z!k>62X{#hPa?%^BGh!7+-XOr^5Y(3BI}|9qyC+^6W1&6J00 zmH47(V6*$OeSAg;bVg6SeuU>70O}v5omh@4Y0xA4|(BEZv2{_M@Ksy`tZM3Ll`fORw(GDEy1_Grz8fP&K8mIJ|mp-Z_`j%Z|lup*j6&woV9js6XrqK2}6sz0zi5xJ6F0KIn%;{!buj(11 zxHTGM;(J3ntidTc%EWl^ie@04nmOqX^rC6`w7`V!L18k@O>}AnJs9i~l+bBrIr@y( zwa*Xot^z0^Q6kTDjBLC55vrd%a{&=owqRVY4%VBXLBkt+iHzT7h&)mEXypd*@RZ2D zf;&&l?m%hL^*f!9<-UAc9IK{2f3f-F>7m;=tmNTvxgmZ`Ad38V@j5t9+9p9m-XAb) zq3s~6$WNG9j#=j9`V2-m2ZpdNO#EIjNGhDe~;bjWM^f5{LmcDWGCnIq=`pwgaqF*i9v-c zdx5&i*?F;6GYL^hvh_rj#A6(9&phP!#}!dukGlqVKN7MP*oaNqk-m8y(z5qc&NkXb zt!5scq~|kd-gg1vkLtPb;bBhg8V3XZRvBvZ{ce0VTRh&Q8gqQ_UL#S^y&dHJ_)%z( zmT+H)KryZ}sDi5kJcB%}Nz8j4Z)qAMtWJh#`Yd<}omqBld4#M< zWlITcYi<}`KcicL-4tq!qen}q-{CYs2N!1;3@KmrV}pD`R*GviYp;)ulBJevF$?F-zjwdmR)>{1UEuJtRFmyk7^%JQL^kTNbPH zr<6*Wtjl0TRDBzk!tGHqpG88a+Y<&Q@es1zfzZJj7tXzMJkBac>YeQMg(Dg-y;I+( z%1{xjN5FGP!v}!Ihi@#>wqx+arW=Nyln|Qf#Z8EhSRyG?y#$3}QcYdS7yWG|LR50b zh1^w3Z?k1LV~H6CWehK2@k*2KCD-~I_d1E9_wNpo=Z|MhEEWg?QKHiAmvkVM;xz%} z{`aa50$;)&4tv9%YOa!8OiG5)n-bYAFowXfsA;?V9_2lO06I)1Sc@EFleAy*SxWde z2h>=UnZJJ2cMv2xoC|O^f-eI0VWJj~0K)v8^et6Q5i>f(40F3?T5TbG_LsndHu`tc zQq%2_>dXto-1)Zvon8Q-Q>m@ckFmI;GoKz1L2PKfAPg~vmRvMwXvQq+6* zJ+Z$WjAFT6JtsxsAM=_o-}qZ1=#QTZrGHCKgY)k0{=m zKc^!0oo4hAE20Q(xlh=Phh)S|I!D!Z^q4Y<)Zw@vz7k^+TcjZO{`fnyvmME3w)FAZ z-CJ5W6R2F;`lE8s|Wz%gGO;U>iZ27%cuV5h4&kL-SM^L4vp zIz&#m>S!tlD)?+X2n^rBds3P+Vs7?zpfiIex0#-b?zdd+{CEd64;L4^d=wao$#&4J za)M*uh1Y)Ljmz@h?a$MsIsWY@9rI7dPv)FSMdx-^rKH=VIq^OAw7n_qZWo%G<~F2p z;eKYfNn>z)hU8cD4bN;I<#Sr~nr|{N_2In{6=eXd;Crf@OD)Skk!y@* z9q1PH7>8q=VF3$SYsdl5-|b*qW8#FIKp@>NyE)&{Q_|pVm7x(O{;K_hwg(cOw0K(T z7Y<8Bk1?^;w;pd|sc*&E;tz`kX_$V{Zy1h( z%)VyDzTnoNR~e9p`AUtK$AgKJ%b@Br5_of?&9IV1?WTN-1Se|k&wxf(_+!z2%BX2Z zT`g0wSny7GS=hr4%ajD0?j08C2c^Fw*L#mBNkNa7?A3TZ!JEhHSID?RDDla1t92@b zKKS0QW^O~x+k6Z$63*Tv63w>!Njqid6ub9xsEHBf>ori|cZgBJ>3c#>qLI0mn>%N8 zr7@q%Ge}c3wNm}!?W@kj7Cm^%m-fd&r#svwwwa2_3=SNr><{PS9vkn|`Z1hREKuW@ zHOZ4iQnfX~$YgIetNzwZC{&Ns%aaGPU1RRvvOZRxlj?|~kPhGNq(2LaydJ<1R_kuAG& zSrO-Tl)o+aR(hOkY-9X`K!RC=ddz~oL11a`Ep@Jq3+PeCafQN*Q2jwUaAhH+L+c2> z5}*hRe z^-%?@HP@8+_NDb{rjJ*@jZ5a~NFzJ~=)U|0+BOcNv53sLc`pLQAEP?_)$2oDfypfu z|2@9o`{bdPB)o{KqYGFp8Dk*?ybt;j-)v**3}`O!^dE1vYd3~$D;nPJtqs|Z6$DNRR8L|f;@ zm}*lj`2n@gh1~t5MBXQ*>0II8eLG;R_bArhp}9F+?fjp8x(JilGjB3D5}#DbOG zN@~aRCqXrf67xZa@+FCEd9Rk}e9vlvAAAt0_vqn7V+pOPKCnOR zpdah;L3oKk))DQ&4SBeY@BC#_rg@ndf+dcpX8H+Bhr|$0 zGhX*L^h139#rE5(akgv8jVJGa*oAE2MZIyV^rCo4#YJs63#`ZAQ;i;&7s7nxcc9l< zzIPzc4ah~D;3C2SP<3kF=)yc{Xys0pq?V!`<*%@opiIE7I>@On%h9#LLLwDE;QSm9dqj)(*BF!8{)P z-ubcg%JWG9lA)8(#}|sr?}2)O=kapkM3P{I;DFnZm4ztKGKJL+eM*d!gk7(OOjq;n zZdTR95R~w=PY_HxcY~a5tt0Y->|1X@i#|dhcUWvkz1^%4LzDi8el4TzZ?h2e$%ipF z9=nY@^jUz6&XgUH6#usGjUGf-EI-cL=BbQ(`ZAD_`e$H`+1#@H@$Eu&k4Hm@L>Eaw z+;L|uS+bQC`dAg!PJ|fVST~qT1fD1F*&4_L)5o#A7 zg(z(-Ogmg?uC?ePmtU-xQRybH}nzy|acKN9C zW-g*Ebkyhxg8NEm`wi{r)Y`PClq#t{RlbW@h>RL^CrrCgYI7$j^R^w%oRemX0qa{c z(b_6!daJz2MRCYQKNpwp)N};Rmmex9{a}W5RC%vdnF;Vt?F|#8`!WV`ys83epHqj7 z4=X)QxllZAh5m@sjzA40U~{yc)|k!zoW}6x#eyfsUM#_R;g7#Od+9z}_^0?G<9za} zy-xHy1JlHuxS%5eWen|MSZK>V{IE415*N+s9M#g*XR#;J`aob4TMQq0k>LN7ciw?; zHR`$_AxO07odl_RCqzrMh!UOAd+$AZMDJpVE{HlK${01eA$pI_AbPJs**;0_DYDDNq)@X&0ax`lrtCwP!bC zqv&MbyHy4wZ6b@B11aS)xG-gud=n{xE$Z0|tnqvb(D`b38#XswA9851ZZHQ?wt#XV zFJp0>^`L-4=gG`jN6Ls7X1+6fu(BMQqwDqI&$scIapFj7n9%52rWCv5J$PoUjz2%R z6CyThnj~&3tA6acvvkhnS7StIuJci1!QDBk4WG+;Ozb8H2z@|_RALKcd)N;0WQ8xL z^ELC*>hK4rYC#0;Y_~t`$8+9zNSXezmpnByRbaKIsX&;y#4?3HJY#yw*csFc9A zot*CT>ax-yGMuNQ`27%h`ZG=z!n!kdvOKW;gwU#DM7<}nG7G0MQKCFJT< z#{f%^-_SAwqS-ea8b#sz%4rRlN&co-Bfp|pGy8W{+TY}K05+&`2@B{(8tU=`%0|P# ziLojDI`OA2TWakuA+7({@p;urDCdPMBV1w#t_^;If@Py>)daz4}`U19-97JlGQ?$nh#psxH?C3pSi`1hH!_X{<=?Lqq{t2vFt#wKXSg|+wJNv?PXK}cyj;Y zB3tUVKT7nS`(N=E%D$Udyg@b&n_F`Pcas>qtGY!t(tdlkQsuKD`m3^QNLOkFh%W&Y z@7I!wz%xikz7%4^Yx-`Tw!5S7#5aXaC@VkPmNF3+=*n zC!A&*4y43)JY;<269x=`&`2d7sDU0(fbc;;!|gYx1arc!=tU?U4e)`{MO=n!Z!pIU z)$^l#7^TaHSuezMdHCG+raFc!_92hLNr)q2xdYbp+>C<@^*EJQb*R88$8M0SaqXb0 zt#@{I7zlJX2NaVy(mswj2HBwUYX!eSEjd)L%4<)UIC_}eHKJ4@68DgZzI^JU`!be; zGaxcUHSHkaUQYfgQZht!%w=qtH%c3Y%{oLHu%#@pXbE<}lxCZFyI12u+mDrbJpd|& z5I+96%ryALiYgJ3U@@+7@)9hTPrYPwO;PNL>?YQ|4~TR&+xHn93wOoVX>amj_dja7 zU%N`y6WoulR%|&} z0JOQgTfuqOY-R36l9sqRQW#bkM zfK30=sOU@7>qilKPiZIHxDzvmG))#uw`ZQxcV~?L z9J)1*rsnEx-419xCm3#w>XHN4KD{A9s!9Kbf+<}IJ+sjW6O+pLL0`Y=$E=)t!8`E+@BrUdS~0;K_cl8k?+ilC`BpVF)m+f3`OA4OCP1 zeP0Sta=APj<)fvdpzw0l*ypS6kphPdEc69X=3WIHYSQ`?p{meDoa?z2vi*uP?;-R_ zwCl?xXbJhJ;Yj6LvR(1QoLB`rm%3!)nB&|ijon_VkkAsBsT_M@s?=)G*D1N0bip4W zD}f0=+%Y%_nug-Yoe`*H+YP5sS&Evfc&x?m??}OW?b<+OVNMD`5rk|TM0?;Dvv56d ziQ}>EP*>){W?&Pi-6*(9KU!)xqQywjsDV>G&#_FYY9y?bOO5zaAEoQt%MrmSQ)fF7 zMbCs?-sneRL&rT3Xd}HigKs&DouuKJqvjsv0&e+SBBLyw*mM_+^=WubYw|BL_5fyM zG*m&3TmwIw&N}f(Ui#?>oBA1c{Zr$@_givPwl@z&L~G|;!^powFuV*7wB0T_%H%8{ zC|Wbw7Bt5EkexWKvM!uu8r1V2}~WJa@^hO{D-gg|-Vr z@6rHnYqT5QhE;Ao-eT(40`<+Z{u@{(b|%B(bGz=Ox0SP^yll$ zMTt-^b8cGVW@rhy+uf)ptfN_+Hi_r_R=y~o^u$=pH=0k+G+O$-<$HYY z3_QuzWc6P?mOL)@gMUxxkJu8?PhHxfJ~pSWI_mJ~mD3T8Veb!yK-jB}W+-o9l?%`F#EY ziII3eyB*}E!(WA<*k?0LV%xij$NUx>+l_P($8cjP`*re&T(fm7@aPw>$v888=nj2W zkV^U-=>(#fnl_+Y0bWbP|7Ma}eV$r4+~H;VzO!XkS7cu!rh==>hU5}$>VT*B7mcqr zkx$6E(NxdG_v~X&@3ikb%r3rWPb!wpcS``<=pV$udiU@yFEfw+ElJ(L{Uu5LW5W8! zNsPy9@yv?rUo<>qCgXCliD5-RgBg5^v{Ql2c5oSi*x2V%V?k} zCzD|x69@p>_XB)D`#$-S*RQp4U)b937_ST{U6Ne770bSVINz)j-VydGw%6zGeqlam zo^)!IxiI&Qj<@j~6VTZXq5vTnR ziVm*f=9Gp{kV(AE&^Mm~og%0v{qiIUMc3nPPth^_pA%vE9@!l@#wQp5cbkW}4_cWmxQVrxQ(PmR7pjULqsyzBP`nAavZ` zue2%8db8K;-Ho_ zQmyq)#firvm(&~!>vrS-rsA<#(OF_}gjsEn8(Hm_`g7q)Pqk>?x1EZU?lvy>6P5U# z&{nOTh8OlHtYijsEK%+3+PmldH3>--m=tQqb##xe25P0X!pkdu=y zC~h0?56${S#XtAYq9afS_1`O5^A#x@f!U01nZc_XHC_pYnM8(36#A-ZmYbp(R^wv{ z2rFTMB^~)Q1nd3q^sFG-m|1bWK?n#xR}sb1&AI>w>W8uJpf8;mt|*8o<@abQ9|`7G z!H?yxWs;FQ5KAUWZ1LsffXr(daYm)X6N=G(_L?+Hzq+_9mN|>haO5W*IC#x z;=_nk@zEcCPNSRm7vIuzwk=*SwEkZ9y@9uFZa3~z8qa>&H#0^Tqy1fSxA_ncn-!2- z@1qT`@-+^R&<$?tcdnTqtCFfjAKa{^UCk96P!Or`9C4u+{&#B-x`$}pW zZYHLSZtS4Gj@H!ocwUWg0eanD@6e*wq1F=v%0Hpv>F^Y@k2}rZc^wT#-&&i2AT51; zgwyMWTHWBY8-F>?WW>aP&QShFNs8~FUyxTqlw{+KEzaH1)7jn8?_M15OpRIaD>;Z* zZZEMEX`IyNrePrV3S%sRye;{2w}4dnihDOwP(%j$GoRZau8YA;@iI#ZT8Ll9(H*?R!AG{SoZfjJuQ^%g8(3_*b)spXdJ} zoY*=`8imK)nxdC38sw^;GBosnHXhYeXeyQ)*(cBm!}WPM60W52*kL#l{MEFVVbX&4 ziI=SLqlCGVIN}Q{)-0WvQ=*R-fcx_bZIS`0H3r*0dVm!K=R2qE^bg7yW=_sYz4HZ=L51<4ct_(?1Mk-~z;NklhcSG)7VgV88E zOJ)mey<8fWcWWdX>39wspP9z-5w>Qnj0(et*1Hsb!?HnlGFR&~%BGpK5qs)?gTXfh zSCDYtmRXd)cK8S=bI}MuH;?*=bFa3bL>IV#dUR!62N3j=?)(5z7SywfPO{a@`Yq{- z+dCGr#8DSp-ZldmmJ(AYYBqLKlt^Q-8w+zc{0ynZ@6OkP<@l>2PQapL&rO_1j@pdr zH_!Lvh3ShYEn~9RX77M)@m@=X+MG-`6ZRQL>z<2&VsA)@A$2r3X8FfgcJ&f{Ooc5A zPBS(5j`4U5^4?w#FGTL$D$MYLh$KS=T)tjVoI!E>kJ>|y(5xkRi?CEj(X~c zbzQ-+U$He7zvV;>k=a5nLR-l&HYtZ$7W!sp`C(+1KxZFTBX0~r5F8wr-wfRtnAOzm zqA9esHD0!8>pmry8#`)XSli~slPxg>Kht^MGi3WEuOgtrTzJU~h^u^=^SKoxIkk|Jz9^|I zDt2bO1=q))rQ976c5~h<(TR%BPJMX_p^T74MabvAd*Pg9DRGLA5+4XpIJw`-FM89p zbf$9WG~K{Fyl+FUv2sMA7&D1Cw~k-pfSF71PUr)P4Dlj8?$bDtq=kOs-kdL;itaFFRVc!In@kJK_gtTIpZgiEaf8)g;IXOc^0m7x=CdYN zmvJUv_Aux(8?M(mM!r%jdVtPlk8j~lu709oaZIEGepEsPFDHv+pSkJSL|ZnL&K8i< zUv#gKFVXZ~Rx-28?!#E){NBjD$w~`gt;Dlk-^840SNGvx+Avi)Mv;LT z2mZy<=L1yu(Yz`}QI9&UuwJ_!yB;V~oPX(8V3r6671N~}-_*`kSMRJcCTliQx=k?^ zw79$&E##=S>HXyWT0$>xaDuTl%Y2v~j;q9cTC5CBY1 zQ(|R1hkc-4^It5J|09eID><0#KfnbPYo*mM576^+%`=PY5b}nlyOyzZCm#Xp1 zWtb0^F}6Cfh@#O1klJSz=w^RRlmF!SCLfiNrk<5MGb3kX4H$yq({ksh6YaJiRqbjy zBV&Q7VPLKa;hLs4M)cWuxLSJhy@K$pv@Lq$DgnB*ct5JyEPRVqjY(q4dR_*fR6(D6 z3!%Ucm+^Z`Z9X-MhGVtVo^;k0dGX`{Gw3`D;wDT^xq(vB3O7jal7Lin$z&!dOf_#w z!yku(4xZ3Am0S7YZ+Y_<$hzjwt-9|VGcUck)w%pWk-PPw27Rs`3`!Z- z-{TL(FLO7hMw(J-v(`K8P?$~L=q5ydqu8>@BH$eoA=6t6kwEwnc~07ec#ZS9%^9JE zml>(ex!-4PMwZeq?_&!u@BX{%O-6vJy2bWo zynrgxe42^Zxcz@|`@nC52Vit_{@+O_dT+38sc2S}y8?3{$gGyJkQW1w;kT{seA>M& zEj`Atl~HeQTz4XH-8xrMFNN}8f~o5PUQ=X@gCw~6V}>H>+FAIUb73-mCBc57Tn|c* zGpV_}r@zjv+M1^}NVdM)0r&*z=QrkSn5bro5NQr)XWM>4!~HCB(%+JiMhy=q?NVI} zJwn>~$uby5Sd1RO6_d7r^u%0-*tna?q%8$Lrg0G1$Qbbdtmc0^^46@D3BBvtm!`+5FM^4!Vv>5$IO=N}nEyG7>ffApe~O|y`uh^JKgWKJi%Wuj!+rr# z`ZppSun_5g%imNcENBa}x}+F#6^bEW-{4(-%TL7Op!EiKl_DV3$uVI=cjmXzpq{06 z-UG?zDdqWu=~8p!SI({llJ<*uHgdKO4Ar9M<&@4u0xO#r7tv{#w1p5i?HOd)5gzA- zVF|EF016`vA_GUr92BEp#zY$3Mbh>!6y|Rc?%F)JC2F zgVPZ*3bS-ZjW57v9;|Ljl>?cX;(uh3g}D*XSdjCVfu&vf?j>~wFF;Mfo+f>KCGBpU zolVV4hp=#9I97z1jDn?nX5Z@=LzYt#1upoNui{IZD=#=bfEy+m>vb5F$+K}5j84x3(~ zIVvWN&!8G&+!M}V1i!Ev5(h{m2lUCOi*|0uGyt}VbKJ$z`tIPUjby!(ry~0#u~FlR zY#-Wj@q8c}#w{;GoeFRM-Go(ywveUZ$J*L+ok5@X`YHN5=5EphG_N$2L(AU3k9-t~ zwk3x1Ul#qD%Qj{lD32SwEtC^l4rIYKl&|M<-Z+pM0hV(82Tu*AHK`43a3Y$jGOej5 zn#P-G4UNO1{q#&hlF_bZ8 zZd*u%ex4HK)s1bQ4~--FBKLt%8AtYY5T=tT?jRAvEI=6aMXfAaTF^Mt_-{ImC)~eZ zgsT_j&mLb9XVl(Aj#d&EuJa}BS|KJ~M@y7jN-gdP#XqGqcve=uL3D`p0(~hO-=AqU zWrC=8IXhG{<8&_vuVkiTVNoJ&7URasuYezak0Jgnma})u8f(e8!faewOeXZ$lkOmu z>k}Qf--I-n|EdC6afOQ5dduZ%T2Fqec_hMQ9^M893v3U4PhJRlZyJKo9vKj!o?5F? z;FY)69x455a4;S995v02p-RtUm$mRxNH`*Q9T6j~A{x^~88t!z4?CBmQ8-a*YzwotUz1d-tM_%|61;L@ zUDeDVmld@aav*)_GQC|ED(QpSMH{ugk&NKNunfIBRbej@Uic7_Gky2MUs9!`A6prV z&P6lwM)*CFCH?Z6#3|5i2|Y|2lx7SySQ8f}XL=2Ws~<$u>+ANfczG^|S^NNT zQ*3JF3CR!J!P#$}en1VkX}^h-Ru0A9BASQ;fB;+3n_a|dvC>bYv1pw)Dbu0<-@_+= zhmZcAh5RK*=T%@I(9F1!%&3+4(yxwD`M}fMA5TQj-VIYc9-TCK0P-%p{c`xd{}T{t zYjleoF-ZbEJQ6UW{WWt>UPuU!^?9$tgvq$-7aeE?F>Ll?sTCjqHXObsXo&(hS+gbh zV7@7_^3pw;>?qfTFCp+(Q^T_@wccs4A(wA2ovb>x%-@wNt+dYzd8n&7+PKFGZYEyQFVm5$1?;NmhIaSIFn?Wp>?f`x1KOIxXfK)ypG)deF|`eYI@`>IVcs$u2s6d zliyH%{%m*#yOnHzhyxTwDuzRKe3V7-pt5W(|-G2a#@823-@s zZQ>&G7HwI(D*Kq7rkf=RwQawJ;{xXS1ex8wC4pDg;*=oaY24Jw+9xIX3g_G`)hDCW zl|QU;feAurWj7NuaXHpJ{<%*$n`|-7fN-3l!QFy|8l5q_U3sW7)s}8nh82+*?+Lr% zbYq4kijm-hCdyy9%YKB3D@tMYv~xp5wMyU0`_g{DuhNx2i+k+rbn&NNMw;lyg;6T!P|)`^XrQ}o;x1C=Wf71J!@=je{7NCx4VS|s zsZuG=YRf-C%-HIDEw`4s!tE3|ytXM8qhp#7BIaSZZjYgPqj4YEh1C(mGcnvwo9>pF zgnRX*o%ajrS-k|5Zrlbb>fl#`FdaZ$UF{%%i}u^z(SK*v|Jgb9#*c`R&D@Gwbql5@ zS1n3@kaM8w>(|lJjOG&ZAdAM&lXrdrc2G1cBXr00V$jAGmjTI)m>I|!V=>sZdwc<_y-o5e*E`CcGa|Lld!8->K25~|-=x~y`|ByY*(JHCx8cOKFmi^#TOjnJ0 z{Fg`MbPkU|p9{M%=I5Qq^2de2$43JzyH$C{o){@bQ`6;&v3@Q)9}}^LMg0NRBY=ul zh+1S--;p11)s=e=hkqQq8!gbI!Lmc19F*;#O7O1f`462Sej7)y!P+b&^z-V)eWyp}!U z%c!HXp@&mDU|3f-eB@DzTSbVZfM`UC-ISwGu(s>M#lnJuyj)3}^V^?@e4QL*ae+#0 zXw+1vOr5imVwA~}3HL5ljiNKA9c04pixTrBEPQbl*kaGEg&eMRe+WfRULV+?q-;Ve zJ4gDeqD>C!nWFT=$;m!pjoVkwu%X7ahnB-}Qo-%Ywvj=$u?rtROH15Xp)qP8Ye9kQ zu-WdxA!D+)xWyk{&k+g1i2RNR()?Eg!M}d~Al)83vI(arZMXJhvK!a7&8sV$uKMIV zVy-5PYj=NGpcmxDOWLP>YU&cD(6`>NJ)-8MjG~^ZVN>6DI>2$&tK@;z+KgQEfRJDeAUoTy<;5{OcM5ELtZt40Vmj9bRU+Iov4j zuPL@l9fLd_JaNALoWMvz^%gaSsEd11@1oEb7wa&XZRHfWPFJ#ojj8$*;nba*6aq&4 zeBw$ZxJzf(EYKBYci(zFJI>I97WP`2KQ zN&I9(+S9B(+~CA%7#e+B?yaXBYqK@h`t<#jvdntBPqur5vvHY7vM&tCSbM_o+0e zx1haH(i-PezQYI9*|uVNYuTMCqRv}ec-0@LNk9a?%uXgf)esN?qf^W)+^*Z`y?q@*nybfS>H&wblttXu-yE{C6@*h}5y_~sQMaYYp- zxTc{UG98}nSbN>bMQme)*4s!Gdqa|iPr&;7JmW~v^5@$%=I52 zqNEoiM- zIzv5R2TIAh+8)6|9!qde+x=%R-*(!hC8WI$2oxFz12%=XfH08FeE85bRi~=q(~zfC ze}I)iTgaO9Ssn7QL9Yi^o`^A$B7m+W#FtRUl^MMCRCDA=qr9t9t|P{VMO^pGGu_@m zsjpp2qq^)(Ll(!7V>dnK@x@96NE*{N{0){se?pos@7SOi2`}C~yyrXeHSd-*hPUN= z#IezmJN6dJ9~(U#ra_h4d6Sy6cGU%*9gl5V5fm`(C4b3{x)tV+`{sEfZS(CD7$h9@ zwZxm$*qDdgr|QhpcqCP2jwf91#XxeZz{~yEws~W$4_G7{F_;t2hvo5Rmf=(SRoS#X zFH#p0a|mOz3a>wpyw!9h@?~{33twTbsnGmuLw+c4vYk0Z);z6V!IbMdE+rLLW)pTx zAeY!;c+H1Xp%+8S&nm6oNDrfitCBFV7rAap(|df2N*K<+_H%c50^PNWC^zl(l*CF! zL;OsKI3CZ82XBj(!-?{7#UE&tTE*34I1N z$LIkX#IO0gHp)c9{E(?80o{~td_ I`!Vr<0P{XFBme*a literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_dut_resp.png b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_dut_resp.png new file mode 100644 index 0000000000000000000000000000000000000000..ee5d0a3e58932b7ee3b08383d06a791fc0236cc9 GIT binary patch literal 52737 zcmZ^~2UJsA*EWg;Q4u^xMN~wrAV^VZ0zyQkNS7+1L`6Wl0trospn#%)iV&$0sUalv z76<`R5Re*32q6iG5R%Y42}y1|-~XQP{l~pGV=x$d?Y+vLYt1>IIiI;-TUi*1?LV-ly2NQ*adeZLP*0&9Hou!C8m$oDEmuP-uO)x%!WNv(O!QlMv z+uwKo@R<|_>Bl-KzS{pPVQMY;dGo!$436mBixyHjZL)W;0A^LW@7>LC%i0BM1b-z< zrz&D&p3ulFu`*?< zT(RRnO+tY`H_#33Vwt;iBwe0Wi2d9C&Mhi*uEu}l`s){vCq^f zCDx*xj=Y&_Q0t%7^h`>+Hv3l(ybdm|wRu|ez~JvYht4dWr`64Vr}!F z|4btUa&vp3fp$XrWokZd-QLn>&*a$wfhC27vbfuvQnLpSa>aFKFH4v6d81W9@q{wR zshHcl?p`}NQ0;{WUg%~eA#7w>fZkBt@=B#h{n_`gs3FWowYo23eO@xr(*K!eTuoiw zdnFDG#Cg_@5Am!bhDV+?n7c9%7m z;Hcpd$VXu=?)sT^(h=3|iPA_sjh~~@DxC>s>d+=)00BDlpCB&)J9g^)XR-rNUx$tf zyAn`QHiz4j@mD%dqTZh~DygWbFlU<8x|^7oI6wCstwx~NdJDw@I%AA?wT{*VFv{wv z1O-P|hws?P2s&j0<4^7~O!k);yK|5^q^UNuuEXmS)A_0@P|5%K9s8pAxyp@W??z1%j)`oI$C`p8EBou$v$0F?Olq%AGK5b(tSHI7cX79 zgx}s;NtH}|Jjc|m4&rD?E;8grnfLC?s=AA=2cJKg^mw$|3uXP+%pKum+4`mV%K4G` zdd{hhQKe!x4tG9co~2ftl7t@lcaP3ef!w%~^;yEtbXAIK@XcJSAWbh9b16;#+44)Z z6>c3KE@0i{3`m__hfnN|XF z2u{kR(DNrDYuMUn26ara5mm5--qLQObfz%am!EvxrcmM%D5NzfsbAt>^Kt8~F5aV~ z7F9y6ayn<2G&FNJ&$&ET$2DqeO1$x5)zNE|2d&xCI*`XKf}etdJVZb5o?;)oF+|v< z!kzUHl^5pnfU`9e(ww)IuFbE9zP1P@lb!2)2@g9kZdKds|JO{yX6;GvVtG{$`S%}P zp=yC=2=$hk+KC_~x56Gp2SuEf;H(d@*Q78<#u)HNO(}Smq#h=0kf9fmB&tl(_?=;U zpZ?AsQ4}p50kJUm^UM5faayNI&XpvLX_P@G%qe{0C;!P&>?2m6#kXN>MH55I> z!l3dzXU(#%4Zuyje0^>0>{2y-tw|$KPiQ>M2gq&QTlBDQU-zsWCt}v5wh`zmPsY8) zLS2EHmy`uOiT>;x<2n1+$iLpq&(>jXpjIg}^;L)6y?dXxx1YgqVJp+(yL8+-lE9Nk z`w?iw(@A%?4rG4tCn=-8-OnXA&k+5c>W(C=&ib#dVG?tg8Q(4JS*=n?-$AH;uq)!xvBo0`7j zv$G@{_kU*=`u%Be@X(*;>zm^*{?%5Y8yPPS>fKJ(T`yjrB~8*-6Tg1FnJO+-*bp=w zI%yE)4{3`(7}Pf1(hK4(Oa6P%g--W$%HeMDx9Nc3RWfy6(2tGLwsUasqGYK5aW34k zS;M506LCG!*>dn_ga7OB7UxE5Ohse@i%;DP#3gCZhXU#X=15ql$@Y(1Hl)1lHh9mUgD*^BGe6vD)AV)h*QV=G#l{LZ!^Q_A+{|+cIlM%`zq7oP zI`sOs_xbeMx<{;;i^72lKAh8+5i@VNb- z`$7$8-<#EZx)a{UGpS8VvOZn3Q>T#zF8IG@c#8XOag`L%Nf@}h|7FwfLS=R<>VM_> zybO)DfJLtE*4{eAEY!yAQo)Gq5l?WUmv1h)lwIIOI-J7 zA0s07$xoSXf5Kb&f6xniP{;S*)je0kafVvM=hNkaf1HVDYoYAy>=60+-{8#jN5zvZ z7F(r=e^Avh_tO7%5~9sh8rRTVBUUUuXQ)*~W|m&N{#8`v@l;o;_RQxOYCZ%-KwZQk z=CyLwqGy;tEA)-MVRR~d=8QCSdx>}CdCo8Ao$NjIL;af9V9%Rd8+NaX^ zq>sSMD@f_wQNb=&i(g;70jR5y1U(zLVB_pux=Z}pXY!7m-kmy}o^(dsgAJ8_;ndVr z-m&M@@&DfeRo)xdKM-g*;mA+T;o;%%?WGPdXRglYdxC^xx2LJSk&*n3`y&65$mdzew8$=*OwzG1FffR+aQZ((VoIy4 zhh%p3OJ$kfp#6Wo&O$-mCx*D_Ow*+FLjRfglYAuEWhnJJ<7YQDj}&E3Zkh}KMNCG_PI|dN z*Z1cf#t{+^?(zKK*_ys=v5yN639PS@=Q;<{-%cqTXKRvr+Y-8J!;IA7uUk&1hH=Xo zQd1Tv@iL=JlJVZo{6QU2BGJ+Qn}Z6@5y@`biO;Jc7v5v zOU!I2bJwB|_Ff1vuRNi14fkCC!b*6`6c#=QOq~n)z%d^hW}UqJ>QN*-WSP=~qdvld z-cJFi?9!$*kIn2Wo{-nH~vxr08Qx`gkj zin1aL{}N|#WgM7Ml_5_z*V;xaz1~s@+q?8sRqCH_YL>bjzyG*G#XKYwure3lEH>BC z(Zz2xDeJ+SEgW|TSkx9~-^%f&KZvKxUOwjD5H*qvBTi#v4)@TlybX~)eHZyzK45f> zcJ}txdc3G3YuBEXq~pYMN!v>`0kX zwhcU<;pR*(y}cgwNma|)!)KZ3mA9|ZD= zz}^AKXk+ZvJ;O%RcKub}VsSp;6BUSUqO|l9P)_cxSvk9dcdnV=6_`P{r0e}+VeR7D z4`fykB4@b)_+tRM2&ylZUTMjA`ILA5^6%0iw}VLoHop<38xwmQ zX6X*K3(s5b<0&+CC1U3K+a(n%X*fvGu*zv;rvLJ64ZvuNS3T$_+tBzR>*MK+U+NU?m7p_ zI-1dEzV^b*9Lsbaduwj6wbD^~_kWb9?Qx(KJ8VQi8)=lvoO6!7D$Tnd8vD>Wj>v`Q z(bY7Ys$?yFC!Pn5kM?Fv7rtOgUM{ZLp!PvfOlH6rWoP&I?T63Zr4@C^$(7As6XLWi1B=%wCw@#JpyLPMFe@B8k>rWX-xP&BoU+t}VAtxCwQLQIOCTJ2>L=I>; zHow`TZJEIN?@#$O7Y0Lmd)B)6dXqr=jJ4}#ks`bIWWEi`$I>j)iBfpx#z(nGQg-rV z^MPE)-m-DF@Bs}}Ux6s#oD3@LR;~&zJbDjQ zD+5iY;$@RXjy!zaz3!lt?xNe1(|DuX)h8^Cbd9}FXw;n&yqo@pt3LXvlH`asGD7^! zgomNie+E_hMP@;7VAgxz6aF0G*k>Z&`U%rI_cLiWUQJ;KRiuiz+l{>>G^oX@B|>JV zP?4A>4y8SE4#0$?zSM~Kt22~5*rpz$**}l$4U_jecgdl4?8&!r&x5yo{4*NH%{E$U z?89=N%H^NJq&+;S@XS2ONjLwpu1e^;2VF6$VUN$mC9L;~@t++FiP4*CzDx?*=WokA zVye4{KebJr2%Dkrc;QsbG8)|)d?qeD+OVz$>xNiBY-KLrtJa0h?wIQ#ezd0>JM=dA z(j88d!}c6Fnw@3ZL+cyO5pjfC+SxLRntB(z{k9T^1_YMosKC-}{PgEgH4Jh<_SvMJ0desXmqsv!3$=_aDw=p$^lqT|2O zM~-g9$GtG`zN9*~Qn?$e*ze~`QDp?Nv!nh`vPA{D_2$1YY~kb0+rzU!no4x`qpJvY zAA&+z=v#OSCBj0h_fOI$gvxpMUytYd_qFSZ&EC6FR9I+8uJv=cYF+wRktXQCp@N(K zK$)X7?&tsN;AWw-w)+nlwzakW7id0@x)MMYpvtKvo%zKMq2PAl=CS{z8)go_zWrsZ z(B|@NiPaB(n}U(hYbV!>fU6-~AvVb4J{{dSzbxn?dn&o{j3C_k@ij`(Rx=#5EVaI= z#jz^AS0KDSF7({_D|n~SA`@B0cH^{1apvf84VBWedoi2_li(9qO2_BmS9Eia`lvl5%BHIpQ574)Q)=~TFPJI{C5&E&iSx!iZ5q`qzb;n^~ z#lu(uteK++yIeat$SNxf-gpu&HNs%cU522>YJ6ZOhGzY|cx79~vKC4xQ=w5`BEWly zU2|!*E67y+!Pl4en#r8TsQah)#%OB%Jn(yj(}0W7u@89CT&+1<^0TFP*TL)K$vbA= z)&SKZgoY|XEc-mS^osJZ?8DKgn-V25&}z8UD@HslnMkj3>Tqo^P2OtoGdqbEM4~p` zeP4jt{4Eq_0M110gX(^ef(Vr-uXTdIsQRJLF-CEPPqKxcN9GmnNG&Y1z2V;e)-lS0 zXpr{+yJSe)4Pl4tnEe%c{EA10xE3=zVQT8q5UT%8oy(FTwuY&$yRk``+XG=EqfWyL zM1tR9LpIhqM1mjv!L-J1^1$$1=YiSltNphGn7G%M)=Ux0Bxfpvn#W8vXM&;HQ^Az+ zWp3~-R)f&xVI zOjik^U2ydix~#TJ0e?xU_Db&J`WVk}BC4;>WgNnUHv0dpeOsVWZy|I;xk~B_A~TO- z+1fMI+%H2O2n-_TxEy|ZYe7ckj*hxnVyKx81gE-`4WGoZ#s z*3b2PU_vvvPZv{U%7C$dkEOB4DrwpUc9ipjRO9GrP)yMD&jEK+NoL8kjQ4upoI+1M z{w;FvywEYVUrY56O~dNQ)}oro39!j;SU5a^Dw+2-_-AYEVC5W}T3KwN zdo8Wzttpj1F9T&)NP5=_V>w*_?w-cuA*q#0>iiF!>g^cKV8ik; zdE$&a^pwy6`^c#58H;6}C9W{|)77Vcj^}SMceDQ0*$(cAln>~yV-@IrOr|d>iR&U+ zpP8DbyjVC&#F5WPT2*iwA#EYxzzkVwXzlczrcKwS!ReCxgt)~1D;=kDbvfK3h=#wH? z7?&e;W2PSl@V<&x^1sUn9XMTMerB#ys;p;W>y7vHv(p^VjmD2f2j^8NTfRM3Sv z(2&09N&YmDz_`v`oV7-6P8!B4uMNs%u5MMu7cjMhKSt@*nsfkp1v=n5?yzH!v}@Pu zvO4DTRuw6;DdP18DSJMc@`QX=No(?|(pnJa*ShFz%m=@8{2FP6I^;fFn`yf$jS-b!A`V1F%?@PbFoc#90r6Ud7_6E)25vG`Nx&83)+?#l;N)`66>hXO$ zb#(X5KdLo;WuJwFE4h|_hwD1WLm?GWka@M(oMu6Hn=C`)vITCi~SjO!et3 zT$gOAxGuV1I`GFC3}?O(EJ%X-bbXZfOB1bTU%18}GRSE5em(EMAW7=Jv|3o`Bbz+A zz_lD zL|ov#S#6~;ec;cWp^Vd&hsR3Iar@YVrhTlgOSs&Uk`ntZF|jpv>p`?2QrYe{4|$ds z9P1jkouWOL&3m+UU7Gvm`&{iP12^|r5Q_}uO9;o$)S&L@R+iiqqdrt^za9K-wKz^P zwi>C20O&cCvA;Y8rkq?Do)ZCCOBdH58+f74W$~V@p%-1jgIPPF{yqy%R>l3BVWY#x z*3y<5-!Sw4IYpCcgZ!Jg?&bYQqUc)*&f5`^O?U4ie)aKgy{;)UNfh&DZ@44`I2HA8 zPfF;q$orwo@!0)~BO0S(jMY9dH!@8kT@#(><3Av&xBVb;)3a|T9UgfPR6lhzlFvDa z+;)>>y%J0IF(1M_JkT)yvyH}YKD7?p;wkxTYXhe>iC#+Jn}`+*WSA?D-Pru)U<8Xp zQtg}ZtaXJoe`(BVFa<5uojW4V1m>4*&jql_H07ZO@h&s|zoG7T!{5b!L?Y_z>rLg! zl_cvscV3IOC<3dEVW6l6AFso^A7ef!H*Y?qgwP_{%P?H2N+iQnd0{3mnGgWwI0=$q zjIp4;;W#m=QANqeyhr6S_v@5^UsSho)j?2_Cii-z2Df8uJFsWbXvh82m2W~GoX`Eb zmh8Q0L#%GTl6FBl=zg?EvOFP=CSCM9#E7xt_Csy;tjm+0V(6bgzlD!ZV6aPijb*@kTg}Z7x&>}RLkSpY z7*wZ)!j}42EH(b92qsx8HI-!3l^}}_1of&HzKgs-P;4`nYy_}k{G4EeGf|1+;*z= zWupg|_+B`C(&yaTg38OKg3s*)P2;{+%CLMh+PWWk<;Hv50_Xy{qA?g!TJL+6e!;O`60YQjtl6gdD)Q;;H zsetlq#*!P-a7|88b7vin3hlZ2=JP?7yrWoG_9mx zA_~)Nm;vgy(A0qhp!!gs9SM1)tMg}4i<$?#m2=}DOi|CN- zdxMy$WbTw{A*@X60(jTlTg~9;2))r~seR?i%jE4ozX#orVaM@inpvv9Za^_!6rediZr*Fop3wYM2h){Y2@9UYo0SIaomVI zA$7tzyT&wNpq8bVvLExZDX6U3emI#{Fy{czYws$O(EEkmk6k!>A(P)#91$bcr~jk~ zNq6#ivm54-UBK7n|0NxG<cR0IkAI0fnagNs_@sTOHg&^O^kyt}E*QMErEyAJw+NI^tTns6YDnvIWJ=JJQB&OJca=)zOeK<* zxBMsZd>G>*iBpcj0Ex~)iL9=k9AuRbQ8|*0hZ8abni;(XzTLtZfHPwUajO2_6chTo z=r#_sg8y#X^wTapZ^}VR=)lGG*e?h~XXK)|N-wcIF7ZUrMu+Y8@a-XJ{7hCByE-pHZWsM~E^kxOO9M@1(4 z`G2Twr${DEyX%ttN7RETk49GpuJQ&)bwwT^lr!B7gYZ_Rn6{{a$Vl0r0s;ixBZN0ave?D=}DgI-r{>Fv;sfsZ8VrVTTP+r2s2W& zdRrA-*8ak0ycO8vU*9@=H19P2tQmLwykAtqeSk*(dnlV$ZMQBWdUT|7#TxVVdcY{} zQ>&@4m{SI8{^nYgRvC|t3XgQkgJ)6-b)OnYh5UoZjIn@}`M9!z`Mu_!3Kkh4+d!^~ z9e=f|#C5HN^a_g#1X#}+ z-7#!7z2g$>l-<>L67^dX8|-0B=a=>lb4P05>G2uW+c@D-6xYVWTlCDh)S89Vq#%N=Qe_^g5?{$f-@Z6&}=wyDh2cTyVkpfRF&T1qxsr zb1~z?`|Elf(SpUS8ht+y3=_)=$#aBZP6Jq2A zRtY9ZpM0FYDovFFD+OcFwA!}N6_)_N+;@ia>u8aQcPBoaap4%dcsCc-UO~WhN#oP8 zH}51OqIxdLK)S*9kyf}Gg^Q@DTL;m_8=lp}<9-VZ@UepTHD!&Gm5Z*yujRk zQMR2&I)AHCqidR6$FkMpWKb&6Y1?U2Tx|{ZR7PFfV1@RaAn!GaVqu%!Q88;im?-Y~ zSPeAsaENZv3rijQ2?jq`R5lckzAo=z9T|zWM>{hxIuU}T<=9fyBNsS#fzKv_5b5W?} zhNldH@Owb-qTE}>!9_~y2@VYZkx$5@7P%QGbA6I;)@fjtRt4{*W5+AAl^H+{rfH}0 zaVIFB(q+zTLW^!H7o$lT(Z#Rd#hW5$P!WIV-mjnPv+|) zR;u>7u;Zyds0q@d$r~|nEUpP+6 zCD(yT_;vGzRXNo)8YF+GT<7h5~*x6)ae%TnPC}g|PgigDgw=1gBD7nmZ z>L7XTgGtKpd^b@Os6jp0n{i%=wL1a)7 z)a|bp;xMzgVSG-mcz#``#GkciVQep={Bw&iz*{# z({$x>(AMQvRxK$Em3BQAiNyXGI|-M}z9IlEJ5U@c?@CS^IS(yVuPgSz+;l=IPt zQA2da_eHI%>aGphjAA3|{4oq!?phfXte@gLRdqr1qn@B*B7AcqzUF@GPU*1U@7df1 zXql6L!*|_~j^1eB?t&tfXA`3AUy``ujEobKzL>dMa`0rLCX*Vm0PY)WSo|ug?mbkj z(JefC0OD!K{9TDY28>!ICD$R3vJW3$5xRf5Lgn(h1Bn2eS|6=v%AU&2mg530ESqo- zae80M^!=%7)9@V`rwa+KYX}m^&&|r3*(FlVyva#hfvAq)a>0A279?-4W{0JQ{|-WN zZjvkV3`M zD(<$C2ALm2Jjg5bZhauvkojmh0>a!Hkn>*oox-*Do8$l5P*<`?ZGU|jq8d6mYJy!| zrMbY=7*|1_yo-CwOsxO6%=7x0xT!^8TKN#s zYZgN4@zbHr8dhf`Yn6^(ys|Rg6V%p%0kgI%4j4T%fe$8PmhM1D(@QrZnSbd9KxlpIn z>6%*~F^tV9qSVVPDGk#B{4mMu7=e9iV$B_eS|kYPn+4tPP;M8x{E-AZ;G^IL%GdCx z76KPcjV}&71@%N2T>P@NGX00qiP|IZ9pl~QN6Z$`LkLb}&hPS7@?Ep{fL}%{Z@4(oI_FOaWEWkMg+K3#a9lK(Y z`&9L#b58jDD?g*ivxr~aywW&_Q+5xR4vuLE>!+hD(FL;&7xeFUSVu%>CrW9u-Jb-j*b|1)7szk-0$JK(7)R z!x39B%MTkngWZk5Ztx1B1a7mSNG|D=1zw9~F$dsH0-PnIC{J5?EJp!B!n&#KviSD&AC{+8Zv+K5Ls%y+IWv>6I7eC1K+c8TUr=o3_7Lute4`aP&ME`us&8Nm{oi>fi-_4owavWl#Ht zo<@K2T9MG>n(j}1Yx^rbB6XXnM12jKQkm+!WVLy0AuFpAeh7-Y+u4J3sm+#KDwK`w z-K;#DLN8`Ucs9}(g6r0ju}4{ik=hG;XLo}i?Sa(#Q%ZazHE^fnmH5UR zytA^ff6DV(?i29O6Ds00$>x1IucgEhhnrzXNmOw9vzFFip5NQZ}jaf7(-n#mB6dDbtsZ&v8W(e;8t%mC->KzTQRR*Vhur>dz5S{e40+Sn6(D_Dzt0ow`YA>3!9i0XrI6!78jN2`iXA=JyFd z=w0-S;iHcAN?8^)&1igFS(&M{xI6|RADn$O1UCb68*8rC!u3MewJ>b%x#}5A&*(GS zhWeGV+6MJ^jADV`6;y5pw$1Ocx+$|=@^vb{VF?3zc6Y$MOta3S3f<3SG4t;pR-1hR zvJWP-qMaZ1T=L%L5>p=+2kp49aNc_8V9QA5geA`^w*oE@THAnJi^D8&s}&hx<4SP+?l^DR0%6469fg6M@d+_afS%r{&}06;RAOX@U5 ztP~#~zRr@pd;Mmf9>*s3;Z}(YTSWaj=3efTdw-iASMt8u5owhHe)Tnl{+P_)j^BTx z#MY{R{kUT`NkDdrGXKx!3QBhW@P6BqGW;ih*xm6eoCo5yk)7_=kvS?~)g-QwPrS%| z@D*kBv`t(nP>8rsNJ#tWZr6l3%fTp-?0(t%Ha1w(vc!l?jb0s_D)?q|p}OzmVPHr8 zPL(pBt(A>BsS&R--e?8|n2y6uD{g-#P*!jm$B^EFXM$}7Hdr9;<^V{e`%j%dhtO7X z%~JQ9BP(e&p0oF)TRGI;%+Hy1q326(p9j6xC1>tZM#oxQ8)II7ii)?`w49O-%FqCX zSDG|wuZZpkrZUW)G>_Ki*Nt9DkCqm_F4(+?`GyX$Ip5&uY!PKtzi=ISVQisbYP=^|RWvqOzPd*`P5Y96&j|BMBd~8ICu>d_^q(3;8PBlZqU6! z{rg4PY$;YvM4vw@WARjKK$GeBHbVt$P0~MVQ+Yo@`2OMb0B@c`~rNk=8%ReO#XSXC_1+^6G^(_{jN)YFe zCqkItg6f07HbvSE1vMK@##=$veMdoeb?}58FshBg+qUiZXgBxVT%pfY7Knm}m!+Dt zNYn7#OpkmOn#0vPJS~Z%Jn#(n(k=Q^_0^#1d||NS>8fW9X?2Ob{GYhn8%j9yH)+*P z1bhAL-ZYWRr~ls+be`#YY=J!;)MRnSR8XPR*ej1O%Agk&5!{pii-7JKii_+GhwJt* z^jrp+FZ$?uc`ub$-9=7pO6rf`zV>Z{P4ll!OD-4qVgy1D4g`Rz3Pg5 z?D{&vsCRYaHfOf>>DhGOl&|kUnLPYkDRctXbxH9(?0rpEK~l97^jgW+n4LY;XJro1 ziX%)%ZcFn+ec0*6LAy>O9NhM+jYb;NF4PioYo%8UC0+2zK3v`JB~L#XIWggOBwO2Z zNz?VQQ|+5l(R#G<;p&+)?~SvIZlr-?>R2)MN|ydauqNt*$H$_mtR5BO0o34!M!bo0 zND55#)|6}X7R>o`EYg4Qd(S`$4BYdbx*aR|h_6p_OD8j?#_DV{^lV(_ZRgiToy(^W zL`3?90$j^R@&&FWf}CX3hG)(bWRoWZ}(Z*b4~ zh1;aq7g`p{E$~+>ld)FF)X9gyzkb5i%r2p`^Ycw7SKIC=xdXud?*Ml$StP2{HH*xs z^zy+Nmgm^{><}k*qE@nSA$gy+3RZD%aFKO*69yY5$X2KfU%m3lNYp^+)(yC;944iS z?=(zy{D*^N+g-CCk2H~!cpZ1-jX^3LPUn4~?A$LL8~Z|GiY{4Cgh_VWD4tky4M{m0 z_MMkAbE9%<4>-IeIZffNn*I9^6$z4W?IZKg`)F~>Zh5Uay@`1l(vzgA9!{K>-T3+L zp6k!y@#UsRD=24}0D$~0`ZBn2t!p0T9ll~9aS~k8bg=O4{RADy?IrO|y5Z@-dIwn1 zJR%}22mVx_#T9U@weE$OH;_m0yLa z8q{Ss<(jumGBI&0`gPcquAN9K9 zQRnCQ$mP@x3#8wEgdWb!$r7Xg`s-DIX4}g{sQQZ~3oaNu7#j3b-aS0nIrSzEY1(56 zyIZ>^FvHsq(-qQuhZ^A<)6!};I}OaW*P+POd+hrCt8F$J!2^+~M)gmNoLk!S4?7}V zdxpe%;Hm3jq0!W9lY4ral(?!xyivABPtzH)=ToB<%!=ayp%=H{AUVuA0Xw`;5Yv^1 zNF;qKiTQP9{{@!dGqOu366H_U#wQugqDw*EPoC(f+)nvrZtm?}>R@vgk^gYCWh z+XvFti7~l!OhaEnG%3WTz)$%TD%;)YaYXRVAWbub(_KX5aR0}lPv64DXv@{@!%Bai zA#KLlH&<6v&?BY1<*k4q&CJXXXZ#Y)iRh8r!$$E)Sq*~9oHVi>rSNzZF_Fl!C2SUc z@lSQ#G7s=T2>_Mg8<5W4M#1+~fVv=vtD3pa4Pj5H6L^DbG9l-`(W}cZW6!C|&lx^3 zijiv1op6)bT1_5a?ZVYeYC2q;9=5Y}&VukDy{<2^kpxT&=0R1ilFaT`R~sKXHHB6H z2q*epii`?!HofVM2VP^{x#RV%>cm>zuL5Y|k+nOVjLY+$#DVO&1u% zrgtY}PNYE6b(rS~B!m^gzr-RvW_AK-gOQQs-G_w&O>oWvCB2H4&n~q1lg(-N)ITZ8 z{Ps{dVM=1=bDrgJv=NqUy5MaQwiUZeo5bqs-muO|q+eoUU0Eh5(+>!##xip)qjTaq zw`lxLUicd8a5bgTwa~hIvm_uHf3TMVnoQO8w=|SQQyS~XD9R+G0a7`f_3PqNrR1I<_ zJSp#Mm_Vg9Vt8wir?ciG!RGnt14jRFQOZuEOe5N|k7UDzs?0JQED3?82=?2bWGm#+ ztm(!cZErnwAc)g_3kdZ!8baJM|mpPV!9g=Jgda(!7jZY zYAes|?yzgPP?E4j-F&0YexI;bj2qJx5q2N6)=|9Z53g`gaxRhD?wi2}7)R=P1{7~r zqO}UJebq_RVTCw^R7_ZqGCq?|G5jpm@_7hE+~?Ed247KjasJ|Vb-K=k%D1QuBU%69 zQg84pSh2!dUk8e%;=cY3QvihznI<>1^ljgglt0uXwbRpmr<68AP?X1 zK6b^#$;7j9eiZYx@8k$F=CrXOp9;sT3s_QKtt;ci(ATgAlYo5SKKJ5&vxWHag!{s^ zv+jd-)MP8-p^KcdUd3(CEi+KQ4S8Qv{-2EnYi5O{eq! zM$QvPzROqz_c4dsipb|VgA)b!!+l=NQxDz!{&MxIer4sFHa`Ki-w}hhPZnOOm8}jm zvlY$gZnwQ6i|#^cMp&%^`LXA>wh>(QDC1#!v@8V z9ags$y(R#^oQ0D0QyFv6!k(XmO06JjiRRGq-%*XT?>$s8ya)S*c9}q(PsSwDBq9g497H>=u(45ancIT8}Hhq-1Dd$ycm1wmY~dPY7YfODqd?m1jKw9FbDCCvn?7QDIa|A3rhrPyGnu)ZE?nBd*0$$x4N-O@I94hmuJfzaQd zyI&?6BXe|b#l~X+n*t~bs&!TzC@ulHe%Z|NOUT}mKx{v`uuV5}3`ux>+xbqJ^B~7J zaB|++xIV0Na3G<1Lv_F1$wKybz}>Z#gP4BH<_+vM?t?j(yLNWN+uD1XLfoRQgxOOs zM^E1Nk}JmNz#L}Gp=wer-UD{Yg}}tX(Q-89Dtl6V=PgR4M(Q~1dA)E}2zN1~TePOrty2k96?GQV3- zuih|&s1l?wL`g_%#*mLUXhqDqtX%j-p?{OpRB}#{9Dn^>Bu5T9EGJ-P_1G_p?3Q|J z*!>4{z<65IyuB`uDC2`O>Kzzb3&BkJy4YJztLg&%|BC1&*FHIKnOBGV!sz4KPHngr zH$e5ws{#O~c;1q5kL$DAOmsaRhus3$kZRpsBg3eb>lu~AgR?#Y9jRBBd8=~+20O!UO}xpYTCeT3G8;`d&5 zp_=boZ)n)-5?*97$07>`FT3ZO1MLMT3WH1ib?Ov_qowiL;X=W^=%M4Y6Ge55CQX&@ zQ}>?kNRGuQpum0Grpk+fY0PHDM4wX8SIDF2L37CvRbzZQKHxF=>yJ}=s#oKN4%$Sl zTL9~P{hL|#XsnP;9IR|W%(RHr+0DL+}G0L4pN(Kr<6Zvv$a1t{6jLpnw0H% z$r*>8Qu$0tQD0eG2}rUZ94uN1-bic&4`@K6!UNs0AJZ4CttBb;Ma!z(@ZJNAZTN5l zju7SRWDMsA19`NJQRRg@xCfqaBubArOWKpJbfBtpb1WF{C4lwdbrNNuiM+6)w{?^m zGv3!gsUq5Mxjf$4GCo8nzMjt)FOzrt5YO5zH0y%E1#eh?&54~5Q|jXc^zu6DA002l zE{J0pm&i0+*E-W{8#oXMAEjXd){lViU!HeDAsLq&TsZDGl)mAD*)h9^& zqSq??dw7kp+~Yvx-|i`PR%&L1#O%2njq+J=IJ`tr6bU%dV-uzSI>E%S z8Oedz$*t5(<|FL@Yu9k!nl&fbVHsE4;slArjIQ#QH9vYmjg{|05J6AGav-v`DJhLr z-AjNYl!&{8j*Zp-1C-2S&lQ$D9=Sbb&?bON7f*B(W7;f&i3d0;i=%In*>1aFVB#an zHT5urAnh$Ek(*DJf%t{?stjbzy$}TH7e8v6sG{7T>(bghUGy5Bzh~|2>H=2&KeW9C zR8(6VH;#b{h^T}L5(Zrg0+IuwQVyL%3rK^+(5--ibV*A$3=IQAh=4GJbc0HF3=9q5 z=34jO_kGv;|G%}qSuT&xnZ3{1``ORlPyU{jg{5>$bo-?K?IiP9730H28KafaO4b1$ znHPusf*Llc@h?o$L_%tg>LKbu5D<9X2N*GHy9ig2ctwp1>-&_Og@t9Q!rP8qy{s@v z1irOpF*KKn*E+E(-k83U@%gn{mdA1jw0nljul69AyubEazaCoca+4Py84bSJ?JS#2 zf~D$`*#*^m%{4sd88587-$c%|$Ib?&v1nBfQk$9|?5vY>nS?`d>#8?enJtVA!>hh4 zDSmN0?U95&y4rZeUIf7$8r+b zQZA_KWFTylldm|lsWTypYYCQKZ!Hi6?WCPMPq1|NJJ2`GWPzoXoSd9wJADLL+o(lV zRh~JUq}{LyQWBBdE(jwNhZS!a(=KqEf(&I?xkWs%Z*PqRtYa<2?G+)x1YUL0mq+nV z3y_&HGBC`^BN`VF21{|JI=OwMQ&olw4wGH)KKSE4&t2pqpuydZFNB{RE5P-P)46^Y zp1aa!zG4DwjA}2>3;X}FGJ15@ybOd`=0kE36R&T_KrHk7bJZpd zftw8XB+o+6Gu|r{58wByUn2`5EaObj!=bSXm)%O=1Nm3N-N@&dGyMG~8TWyq4c1h0 zZLqL5w>%QpvSv4(+j4x#g2_Hg)3P~`GUsr6VnWkKB@Z^;Ie!cS-*xJ*g|SxXVOT2k z+--Z+Jeph2dB)M@G*C1h@}X|zmuh^Hf4UgcvB0J5i)*{YE37QU`JqQnw)yhlytY&% zOIPv}|AQ>DrOo#a7<*k7d5)VMbFKgilC`l5Wx@gQS^ZAZto;0bkcCp}ylqiydptlih40)M zv-wrpDY&_bHTY`vHtU<`4OmszvS%-a9F8kGS=95H>w#)QPB1m-s4tSPqo!^d>^1+P z1G_+r=s7OJmE^_bP;;g1)9sF0&SkTG_cOCsm`6>A9wwXqSOG<_^f>wclaF%8 zYWFE8Zc>WN^LV_flg@4o6pXz?hBoCvocXYtdfwhlK(Ioufd;oe=0mjv^=jT`XDN*; z@maVR$ypmOl5kTZ&v;Zu&Z($28t7g{3z;omD_pTjKN3ySW@_nJ^7MBCGD79b;5;Py zROseBwh1bR>BhwjGh0p$*(%$YO&3L+0U1Hp??t-ne?9J-h=X9qvX2SrW}FHxE7p z>Nt<6UmH&TjoMMC)zz0j2r`7y@9Q<~D9iQoB`9kW&zy#dN358pKkI7w{Cj z?A=p%F@$aE!32->$Uv4)95FvX&QDa%@TZ6c+2M^9yX;!GM{{QMIn3NsC^O(Nh?I!Z zvY*+AMjKG@ME88oFDmLjN#j~|ndLYC)n1qa_>+Ag{Wic~p>mmKUi#}@SFJK@N>+*s zt@@GX1uJIL&zz`+O^641r^6L~r(fZv`#NJ4$G@)tF~QkFE=J` zL*EorH$Tk}kO+!E5}5F{gUQ6>&1U2ZrH1KWgg7%;WPm;>OyJ-6eCM!`bH)*)w%&XdmxB-us@r}8`60K7ll)YgVd;@9dq)i!C*-jh9kh7q`;(;2RL;48 zqyihCQ;t+6uYJE-P1G&0C;n6?m*C{J{_4cTbFM3lbHy8eAE74_PxB$H!;7DevrhCU zJyU{&hRArj0fH&pmqaT@;b;6rFj5oGF0yp6J=4(9S zgSQDIDxUGv=%{_YIii-${ZzrrMb3E%yf!lxw~9=`qFl&KG4l|aT5nEVYnH$N#v@)Y zy5}zfIDB6(sZ-s%M4<1c>S!?N{$rrm-y}E~4x{c7Ea>mODC#j>vc>g`uV(=0*8rk%@T~&@;uPH0c;l_M$pF95WYkI}sx%>i=65#h zb+47a-6Rakom0(C96K5%+jQXENwg8v7o@xwoe%-xQ%=H+^gmD>K{Y#@yj12h`px^Bwm}!Zqis>qjA@i09VQFyYBh+ zl^VtJ5WX^v0vFb-MD-ceEOW`u16uRv(?PaN&8ZVYdyeg82diy8_!Rb@9~$}clmtbk zG&NI{b2EE;vp9jH3EdfFvbDg2>?Ix9>l{mIDvD-uT#zAm9pKR%e+Q7CRK+cY;(KE| z#g%;BRY%76p--~QOu9?`Nldcsr;&F?oH(``osc>0oOYK4d!4slwcHq(pGOB_=~J5v z1fC_L+7rLrK(5TA)9f(Vfhe+L7#b7bbL6WxNNEHQ=Q}b;nLx4ZHGrV^S>PyABRv z(fhLjG6rgqlU>XxUaE;}13@+YjgwZBZH;?y#3ZFN4QLTki=HXSC11N*hJu5&8|>=Wyhl(ViE^AE?8_S*84KfuR34abuvp6$n9DvjQE zSF=BO5z{Z^R+653#Ev?49`{Y3b`{%;$zdl@pZJ)Dl#g1B<3?8}VG?=8a*h`di zHB7FbI-H93hB?g{PF;f1xer0|4iSNq4x0fMR6&QeZM$6se1cSzOVk};TH7bC@W9un90n3QANmjXqu<%g8BV#fkiEO0BeTu&Acyn#QYUK6MxRmr1hF{v3)*CzN_S7 z|M>QOhpS_C{PF>@QKzBa!0G*C!{8ex#l_aTLPKR(~>mR@vHcr_(3-5`?6Cpn_dO$ z8OBFd=3gBj&TU!$j`2vqa<4#YOLfK#8#R3}*D$r(lTSs|5#%O49%#JkaQ7rWNlrhB4Zk6I*%Nk86#H<+XeY4Cf?XWLd^3|5c zb@iIvxL9wvoSG1Er*TpuYGILLGXpY~JD{zdwd#H>2@ns*;sC%Rq_@a`eXi5}=oPx$ zpz3xA&oh%}Op2vws0`#mYPq|7jNKc4^U*KqtPqXjkqGD~NzI`ZBTK>gmW^kY{XG<~ z1Q3{0n#ZFyPAeOXPIKe4Tb_&VImWfTN-Bb@?NX?@T*tSNi4W@iR4Hilp$V!CUyGgM zql1Zwu9%<$&D0R&qb@ntmySQ|K5fZUX#hfOm-c)0rKtt`eJJxAz*2kiY<;>D%VDfA{5Z?&Cu2Y zd$)gea^P^*fHMd!`w-%j8W90Y$IX5pALBC6sn9GK?V^~N=vq)?-*wt`8B+{j-Dd0d za%OS&cB@z#BR46GZ^PWW88`=!qx$E%3}97urTHkVBtZ32fb0(im6#3rGqJFAKe?uv z4jg#p8Y)xfZb~NMqy;!7Syd5r z=U(-QXm<&!NcWIa=IEh1>jU%pQi7abrLFekx|hup&HF@=nam$u`wS&lNwnRqs?C`_ z%ng6F8PR*uwS4Q{jDg$!+Q{a8&3yZ+)5_b;C3{OO)8~urf|_Atp*8G9%d`12yf=f` z=4ZerQ?^D37Hd!aI-)Z@D~Ep&GK3XuPO(Qi3Vho7Ym4&g%pn?E3ngP4n}D1%E?RaD z6kD~$INaQfaJD@)5Of5Z&UM+V|M)hy#vnW0%55|8QsDVo2-eerifF{};Al>42&-MS z@4F~gyEwD{bq{Ql52-{FT$@Ytd*t^Sq1PhK?;`@6%gjf>CPwk4bI=N-o@?e-7AW|l zd8>=gxvc{=>szu@lDZ@(AlkSxRtl@M_HGI=g?ny~bEB6Yk!dO$Z3Q=&DZ^wpsk)foS0~! zY5Pz)$pJ-o{7wIfNjcJbEW}(edhfa5SYJAG8BH>`YFLRR#ChQKwYs8B$T(59*l~sd zl6F;dZ-{Ar(3|?1dfC>|?pIvut?^sibCpx)QAFL&wnLtgmXj(>yAk&Dt+TM!7i^e} zfdQk|62BRjRo3Kz;&AFE#{G4ps#TVi_d@ZkL6cqky{MD5J&}c)v^qKyzj|`C$c*t) z93?MAXjPajvQ~WSLRlI9Cbh|rwbwIpyWX46ZkcJ-p@cO` z=+_U&VjIB^!Mk*EEZaE^+e)=+*dcBPB_(NK0xRYGUy<>EKzF@FK2|iw1_oOcFIFo2 zdLLEvaYH5BI-1az%-LBLANic1`^}Y{h{wUnn3mHoVAy}L_>wYhl2=?|jjJJd~k z@2D^jF_`loaP&PB>X;tFSO7i zHL)n<1h6F(7s=0S9@&q%C|{=3SPZCDP)UDM2(g_+!%FmPgd)hyOk4QHqmB<>;QB-M z%+dS77B0K^l(DT}T*^O8yK3ZABUc^m_x9RS_OJ)Eu-+HZy-xWrqeaHD*6VZ8&7wRD z(>k*|)3DVM9koC)%gq@Fja`9RG3~{US*4ky-FX&3pZ?g%`YmwWA36-y)Jh_A4cxFN z@>W;ueZwn%xT+Bq%hPid-zS)n+@>%0%q zND|WwZc@#Ow`bUAwPGVZYqy@J{Q*Mlwl(N<(I4`|hr~ z)|WR?Zb?x3qf|$yHa%@6vw>I(B=d=Ga>uB!=jLEEzkU91xEUk8f&AWvDd#)o$mgQk zLp3N^L2ZqE%2Vj34btKyD|<{K^BHn4XN(^2F#2ivgieDyv> z*_qi^cr>^5kj&UY{;>Mud^S+G@>dW^-$8D{oxupvhg6l`lOgKh(h&H>Lobx#A;g-X z`A+#uf&X&3=sj5o401qr1=w5CBV}qjhTbOu;5vrAna@E0II1qtm?yg9T;ldp~uqBWM&HU#vI(+eP%71HgjXJ+XEezRb=t{^Ca(5%a(pnb-q= z^28BVg>45>#(ZIK2z&Z*ql`Lxdk*5r^b+@DBnR}}SK$NWu%N=u8z)mQ$Ug_U`~m<4 zo~^RJ@OujE2MaH}d}e)SR?Om?!xUNIf4M{^y%Yd@=V4*O9R#Pt5O1*f-Gi(ZJl}?u zgZZF@Mw6zSIjrZkveK)2_p^)^Q)1Spb}g#emjkxWdd4I62g07w@jtVZEt=kbFzw{3 zIYd7uA!>eXCEyhGkP0PrGiaPPP^?n{X@+qQJ^8}bk%i@-H&?HM6X)$@SJkKWInD15 zn{2;sSME4@2A=hdPDnkv=tpMmsHkwXr4^B{mHV>YBEa#;+Fg1Atcm;WtabpV+xV3o z>S%8^y1*^h0l5Xq=#{$*i<-$bI6#L`(9*Iv zbJ02?f_W5?>@_*2z+4@cQJwrT@dWxEe0+Sevzfrpk>rCnAa2!91IVXkPTec0-teO+ zD;Z20>j=Jl^TlxNrqA*dEX`jnaC{>1h_^vV41l7o{CdfQj7VV3gTm*Jk%VTJRjud~ zwW)R)hh{s$U^Pt|K{`K-`%44|ovMs8US1dJ$YoI#GnAOhPs8eUKkN$?vy#F2_qhCI ztgtDWQflEA7UF0287_MW!TGK90bLFZQl3sz4C6!o2cGtxhiY(x{GP+*9dQ}D>*uDS z_Y$<|ie1Ej-Bg{X$p}h`S0ZUd;23 zL;XEUnpqIdy=t?Ou6Q`ni?en<45#@~z-aq}G@@PO7nh#Jazpi+-mPbRiT-6;heT*P z-Js~CLj|^Na3`2owr!=eM`fWLhZdj%TCSq)Kh5ht0E6sboxKCj8`_dmU}Se^F#y2) zY@I&yKZt=y*xcjK<}7yMp2zTIXP_KKH4O~X{=N`&gb~7GGOs8_bZ9TUPn9v0Or%E4 z)1;wC({+%j17TSir}%n@y$7&AkjFYW5=2g$k+^EP`8w~}J`x4%27 z`!k*?64)Zn@-Lc#U)&R3dl!Gp#}F(K(C)7$b+RQqiG>RHaaL-%xVf1$;(PNSuWm~j z`uIwveni~fm4loYm0NrFUl)k~V^<9WXGz=ogzdSyCN(#UW5-)qseZ*i4LYdZy9lGK{Y2r~Z2 z&swX&8H1@VSui418?vX$J3Od9bmQeHHM=Kshf6nt$I{qwaS!#HMQD$i6@ZY*Y%ltW z9v+Amd^vPGI*c6Bs=Vl{W#yjj!c5&)P(AIoCFkDV5?OBlx;nfhM4w}5!Beqb)ZyYT z<5Wg);v+Zw|8M`;=c~=mZY6Y{{Cp>9vss>uU27?*G_r=Z(r6#MjC5bTc96wVW1D_S z0A8u3$^ez==<4_~QPPu0ySzG0nS-<+`w-y1U7UMhSe9kICqK=O(wNk)l_+q19tJ6H zlrVsN$&^buU@XzCj}2QHh_gx4W`(Ha2swq;9KM6FYuZ$*A6&G_%&#~mi|2X*bH<3l z$K`|E7S+3XYLfI&R@d$#_Z7$7(P|b6Q7N$_1P|f2fq#M^-{-xTQdbcG?to8&L1|e2&6>+@x`}T#4ccVLN@w#20`{PFD z$US4r>J}-R2VA>^lwZ?~wM`W3N4vW5GAfOwY~0jlA|xbx0{eO~p~Ji70RUeN_z=d~nl@BtqvzLoV7ZD5#??`!gBH~5-v={L3ydFB9HCl|#JPu+5Mhqx-Rn>3Z-k+3r4m#oB;7->0vPjn5|-i_7R?-|W=(dYI<}fowyQ47$gkXe?#Jiyy2K6+ zg2c6JM5;8JVPvDmiih+yd0dukijCO{5s8JDO5k&(AhZSArBa4Y^-a`ArBlee+w|^f( z!aN3L>Bc*sNMU418rH+dRkg=qCG*TN>KjX1gYp*b+b98Mp2Gr@wMA=8Px`CZWeK}j zi9A?WTeM9+i-k41lGU+a6o$1fpBtSq951m*;-pWhdXUq(ATbbUkFEr0?e9uEjJ5g~ zAS$!z=29xE#|rU2kzX1jhTVrWdk&1EDzSRX>W3|kNJB5?qc(oCx05T z@vYUJQIgk4j`d%9yE_Ey+mzX>^->~_R>^I+#NQU%B>N|N!GmqM!YTzDTb@WoRVGRw zJ~pAtXWE-$a-q*z%7Cc<>^wwFFcQAIx#|1O^g+#YB(P7-u)a$A6?TDxqoaf8-FKZ) z$=oc?1Vfj}XX%HX>KtS?9%@1?JWAvHrb)l}DNLr%I3qri3xye5?aS{57*cC_++*2k z8DbmU#wsE;o}7hZi)+ST(-wdpcBoE4v5HFcWlVZ= zd~Wsn@0t>II9KFdZNsrsPzBABXV7oAxxDeiFFZNib#68_wVz*cFX(GPb0c-jN_3qA z=-Lv}8ogtyX^YBx3vH#=&k@FQi}HiVfG2;8l3#SRYgDGaDq+cc@f_Lb!fi{1iZ9NP zAUjVgXKnSbMR#toSK5m>I#v=|%TKF?DOzEWGrIZY7e+EH1?HNVnXHc;X0u5nBA5y? z*D|b$W+ndOw~-%vKK6tGR}rp%?VLAfYwEFEmsT5oUGB?b@9c?z+7v*O5TkNTg+vxP ztUq_pE%jsBo=C=RP!uS86jJ>NLSIh$DYfO!Bc}yVU)#neIlhX*Pl-Lx;i=Ns0yT5) zNb{+w=Y(b#X^q^QqMZ!L9xl-c;Nm}s3vX?eak!%b#cj%ZuP zxJ(tT9&S=@i;ZrlhzGeHStNN{tc{Bgtgv?vlWdE(nTE^ych%R)0uuQ|c6BYCWUx-+ zuXsqga&1;84w~}(KIOztjNpqYap>0gHNCL>@Mrl37boMUF)_u?%Sa^YKf;BMDE5}f zIlg6j5(?KU5|&sQ0(b~?&)$D%RgEw6U966a{2(owDI&FDZ`|F>I9zNPMB03rSUJr3 zxGA)c>76Bfbsq8kNQ1G~Hg3aLW-a4ya_Us7EJJSc{pmc|JV`T81;w{BBIf3KAj^*H z`NxN2S{2Y+T-+JXm~zvd%n*=DHy>uPa&PTPC?S){@R#f@>H5rhd@;=7)xSx!yjeO^ zir#uzh6}I5W#yjdJZgy~BdqMOXj3-cUmAW3gjh?xx)jFA_T0-2nWcdzCP z=&*MCT^%8{S`AZt*^|H;0ir;D3ZgW#uW#R>E3-p!@i1ApNx3xd;S=OroG zwZ(}-lL6Rlgi*l4#vKrUM>2-E<)4ZlQ?{39m-_PP-V*|`9n2re&RSM$-Dq_pRjNxr zej}8N&HcmM=E>}Wf`N)5&dsWB7<-0XEqmU2x*?Kcn~<>I@4OLfGTk(No_|d*?`38- zn_Zv3z1L%WF|P9dx3t4T3iMY9nM0_RZj-Is47Wyb0Lxf^h1FyUqs*SYR=ifLzbQb_ zVS^~B^eZV|??Z$N@R$)9oO6pdN>1Os`DQ9=ukw#hz{@~lfoFEMlj43$up%T|d`r(y z34#}X6jxtOI~wXg}frkPAk=MYC#=oYz(R{F56E>u9r%PvbRK+Elg;Q7^Z z;n{?vTa*I!HOY;*c?(09%F$0Rq6glo?Vs#S-+b=)kQ!q*<-HriZ^RjVZ=V&ZvmR6Y zf4L(>2(G5s2MTP6166PRd*hL+DJdx_Q@mXXgf`$=`ndgDRaL@C%$6s+K)!@c8B(Cw zRWIwvZtJZHOf%!_cm5xD9ZcbvDg9uwZZ9ly9EutYiT>-uV2cXdr@ ziK3dw*>_ua;;ZZ6-{j!GWRpAAeV-E9x0{{v`90%9jm35qx-+Moc+6P*j5pRtwh{=A zm(zO$HwMm>E^)64#)x0~%pt}qprxW|8x6^5gu5RESRA6Yx$+paR|Tfex=zJ)?%Kdc zQ9Jg?Wh{SRZ}^8c8fMIa&vW4a#U|F;G@QCJC^C_itMSdJ^5$R*ymI`PWnqrUxvEjR zzfM{r;nKlp3cl~Cg35VYnF&Fe&M|?p0HRMEhKV+T9sGx)76M}ht2;Sv`>_*7{fI~L zu2}bl*J09_*%DRji9Fu>G6?nY8ye`Da0|3?D(%sT{Qx*pp`c2|O(`!X75NS~kR&rWdeU5&}DFw=ju zxPA}Wy=MUWNBaGZ&Gi?(TJKhqlnYBdEjp+ZW;vrDwk+_sFqnHwM|OsJ+UK6%_>l9b ze{1QoNc{AI1mlxum=(pJ|HI*De8wg^z*_|!U;M-&4B{YvRZ5z=N#JyrF}~E=Sh55f z&8mM6c7rC?Z1&XegIoAg5&w{giEe$cLuB|3@f$`49!pEmtEnLT?k78Y#D(Rhc@@rg zAh{^ObeJs(UQNaM-M-G_8?06zFSNw?7H3^6j^-cf=l2{BdEK3F1Y`NYV_oHpKq^jXRDAhkyG&%)UJ2S74H2W7 z{}oT3mz?~F990XUg|d!M`vlNBw(@@?jG)5C#7e6iE(!Dr-uu5|tf1UAPJxJ^iG`Dr zQ5zf96gt5KbIql;BQ{$$X9GY_t4%vE!R7c>SRBL2mwrdc{>90{~(*Zx}i|Khn)>-k*u z;{SNk3AePI(Cj%F$-kGt+z%@M2lfAdweY+Zt(b`vw;~AFPt_l-9TOBrn~fInawQ}s z71k3HzfHAU8C+=M1diiBx42aLv#BwqRH zSuv8xFTcM{i%+4*GYRD}=c&YSODm2ig!tu6q{+&kDQn9NNwFPHR)|3h94v)7xh|Wi z(0zwebGVK)#t71#t}EDNFGOcE%zJ zyE)Pt9b@=y!jrp#32^R);SIzOESlPz?sqt~Ui`?xTz0L(`o&i9@vINFh6cg;8rXpZ ze{nc4_8%G{RE^!dnWG5U_tr1!H| z1qAn^TZFM^JeQje{nF82fyaOhG|jIkOZ~Xb!a^mY%9O>FCiIs{J(6zaKE~`r{_HhC zNeCDr^&6N@#xo>aXjM4B)J(2bc;hOewp|$HW@oSdKBX?= zgrtuF^#!a4QKe6%MmXp0m}V6hv&F=$J^tQz^mjEgWCHOd>2Zo_{TGs`@nO>SS)5ns zCPBGAo-`0WJ(Mc0CnX#9i@HE17H^7}K(r(Vn~;kRYoX08F0xfEHVmr`bd$3d=;l27 ze&hEkcZwk{Qz6&N8B;9At>mpV@Hoos`cAG@hmYVDR4Mc5!BH98g%o4W%jACsc#5{b z*q31Kdew~@3;R!mo}QVESGqffgU1K2^j)&Net|w#@k_~AqKPi;=m@I1di31&DJEu> z3f(8T%~cu7iptsl@;3G7opbu0nG(3sEN@YJXm_G_vW>b+y-v;!goZvU(XOitzZODH zob^>d-6$F64OK@)Yn{?QaV>z_DsNt#)+FALj!xx=|6n|iB)#vS@PNw<&V}G~+BAy7 zISH0eYV7zT>>od#@=FZ`EHL!^B%GSeGyaxeo%HH2;o-#keujUtIcVT7qb<%%go>6G zfX4ZkGsejBoZU&*k{3S?OaPcWEIuow{W{J+%Yi%?;|RVUt!SFsVm@Tir7$%%S7ZvG znU*t#U;WbGw7k!9{$#8s(we%{d<1c+M4Sr2iEK7}nlsizP0&4uHJBI2yg?5-ZE+61 z%NW*~cno&QZAcIbQKbJI?n|;tG0w5Z}8OtR^N) z7mJM~&_@&K=kPO(XlaghjXUj!=AA?^IAMnj595{`554~sGySYfHYzR??O0!ecbbCx zqWrzF=*_)nFEr~bTFO@1syFA&yqttzshH z29lHAb+`$tf`%(O2_Di4B8bnvESlbm`pZ7^I~@ndT2}i!Gsi2&d6CFAIPNsZ8J3~e zv?x4)`_^TPaB-q+YSmB2Zm=#xhfY5{r0kXW?QF#H5J^S}OV9{j=+=_`6iK*YKB%Qh zXR{mFnlWJ7JrE+)X0XqfsrPFu2hJ}KRgYBE*SEN0UcJQ8_1E-z;&Dy8XV3SDXaU!) z@?q!$fo9I^Y7CaA@kd3<|C~1sN{=n0y@uu#?r*H2x{VigWIF)gQCcy zmHOR+7PS$w3{xAdLluSVFCUWfA*vtWP6E{*zCdGXIzb&Po(I6MXkp}7UxDYv8yTeq zVkLf`KprA1sbSI^&BH~)fw-D1MtYNE6?mr~iqz5TI4aW_MTd>!(_grN3o@ym-pio= zqYCH*t5>{CqIh9ispm-cAsPhv(@Dq8oqjN%=b+^{P0I5iQbk_Adz6D-@MYMze6tIH zxVCGcx$wH?k0s6HRC30tP|YekV^s;`9I}V=nz?E;hTW+Wuo9yXo`?mLcApm6M}2*z zM-EKeaW)+i0Xt@~OS}U06@~qLCrfgY>;MmGDMhrQZ@TrWV@Oxrdp2~!_RK{KiL^kQ z&(z8EHQ&-K)1Lm2m_2Si|M)3!Ur*4!S59nKkFk8htqRgVJlB>m20EBT|sVBUXRGa3zhj!OrD^=<_dME;yhFICwr}8il&ShGs6nSI-A>*J57rz35CZ;VG%}rv)%@GU}DIQjrWd z@R{{lEpN+l`A{f0DmShAErZxDo5c&KrGUk!U4)X;aYG+~&6o9YqfSbRrb;M`a?Fnv zrQONw;rhipI5=ZvhMfs)^qZ^%9;zVWm$iSd(dQ)l3=|a`5;*Qxw}f}13#~52e-od`4oQf{fsuA=`&c1>8!?`Qg=8-k9*Ubg3}8JXd(76HB#D#3j-)~1U&W8C9#`UuUD!u(%0(ny!iVYM?kjcn8W4EMY>LF=QaPB=DwI? z5eNBnn?wND^W`U>{=FuoG6Agq>{x0xG>m&7mvkO+%{I#3b+LzmwA1eO(?$o5N0WsVd2vG8Z?4_%7Ax|aYieIY_&TBrvqX=c17rZ)jQJDcotk%*jv z8W^5)I`nS(
    =gD!H~Tr#auMCWIEc(5B!@&X7v(Hp=IImZFuMiE=<+R1skBk0VFz zeiIM5>ZsfyHEzpLz)QD3&rYPB4`dAHYJ)$+9{U?C1I> zt{7re^QiDSZHl*_Dh@p?^`%=D2}OD^A;yEZanZ5~OWK1?h1Vr5DoUn{j#q4Le4llYXhB(N`M1LXZg$wFn` zegn1iPS+J1Sdso)E$3w}9`iiCYIlvgPe|3`%ffd_lt+8t0)uU{F%wzD4lmE;;JzEiT#x()D!W^>eggWS`c{7{@bZ^`K0ji7i8879teGoGFtW zG`bwR)n($tOO&5jhW*YU2y&c&_NVfrCOX0ATRo>F`+E{3JF8JwUfYJAuk+DYVQ zw-mfjNhO^wOkz9kLxIaQGuxG~#$bPXbNe4M0SHhVH|&g41Nr|1cB*SlK9JoO8Gt?R zrc`C8lD5I}Uay|Iwhub!#naE!Y#C47%KWmkx6mW7bR#QgIGNJ2CN+DjpfbPLi$TN& zQAhFC;m*1pZ29#gD^R;)?Px2#`xTpR#IuBykRBp=k$Hy3=i_!gaeJVs|HajQ3 z8>Fl3<{uLhRp$C#n5qA4K}KKYlKMx07NRV@)!1Tu^XMFXtWtz;n%pdgjF|U|EcZHVPEe)kDWW%_6 z2bj7ptAte>JQ}x?PRNiezNGT)-s(ecCB{+NyvKS0$%Jq}o<7GBb5`fvkus+O7p6>N ztX3Nk^77z|{Yb;}H=-=_f&@ebKa2hc8LkWt@#i{o5$LGiYY2rayvS40cu7wpH;B|M zj%4k6AL_Rw694{c7pMpl{u$%r*r@fSF?*;Os;(lCwm=xcCVbW3M@gPfKE*f6XlLzP zD?6JU3q+>y<>#D{1iQ(;#EVsRQewB06hF{@BfR>Sj*II-HmK;yZ@SEg29) zzC6S?zDE~ny1CS#_`oH%S9N-NfU&@;{5v6+yuv6tXG@Zcfhx$^)Kbw(E-M?mw9efO zV@NwKm67O%Jdr9+3f4eDbe|4=>Gm&Mb)Ar59-O6OG9h*{Kpo%%mj&WVyrUTAw0R^q zfP!%psJ=b83J_43_5~0)MA^d#`I8EA0**y9?GxIdkYIPJagP$8 zbvT-cF?p{kH9N;tNxKv*@hT;4?Frp%^IR49m__4c!1%c*r2dT$ob;p9p@~_QHnUkS z9cIw?0wTD$a!PsH`F%taxuu|i2uy&e@ zG2B!dO=z54esv;i`BFJ$5-gl$wfEt}{tP9>!QuU0d$d@qsG+gsMJ}?pG|Of!Lg<_z z&2cs4qn!8BE^p!KYomD6L<*@dUq?MP>B$LNY_C1mP_jg2t7>_sL!&?763iH5b8nE} zw=VI+_ZxG{^?nD>Qr4~#dz+3_BuEl}_DwZ`fCV1@JOr_EyU`@qQnortj*t+VZMoS* zyv4-y&bV!kL#b`NQ+@SRjF7qC24(}btd<|KeKuV9#V3p;X=`T`{?jUh0l`E2J~Pef1qu*k+Y~^N zq1)h7NygO#8&TyYh*7Qk+<)V25DP*+Oc*X02%4j=Q_GkZ>ppLk36wiZi`d+5r|M24P01(!7Yi{p~F_(=*1EoG)*#+|juAGytAW&oX?Hqh(4G?4A93^>>I%)(Qvo9YNLIo)bWGLFa5# zC0@XL$Jcai5apIVO8I4r7Inkatf%WfeBNPMU!@tYsC;Io*v8gZ@7lnJXrmU26AyC< z$c7GVu`wK&bHu>TL-OyS+vCE+jm;hz=ID}G5guki2 z4Ohv1dGwMN<1^2CtyeAmB|}oteFFgZ6Nyhi0FpwySb$QOuQlKeW0^rZ=457m87$OO zQdFF3?d|KURFswd5E`mWE>sP`n-iYPSvG#FP@$WG?W`bQ1(na6`V0!#FVGMI6Y;--hfm0U#kP{{ zVtcedCb5rHjca_`8v#x zE>-_CtoCu*<5ApLGrnk0(iD+jCQ)U#+*L*yTWT;#*BAx@1XyIZq@D5Dn;r7rQ8~rNv<857PTd_ zt~COdj0H4mbde+9JH#;atb-RoH)j5&>ep#qK6|VC)fM;skqO&oO8dE1<^siegs$XW zR-G#$A8*m7IO0F?*C2>7a`XJS+lW6)IIx$o+Ld3fCC9=pQ_MVLyiqdG#KdHkr@@k` z$7%p#K{W48FI&1-okX<57MF&Kn{lmXIui?kn60tDT%Oq4+N!}jl8!`@_pN62B`h%Y zDXQeON|nN$6$cbEeA1sb66?~&eq>{KU@>~VeZn#!P-y0%icBueOhSs@$XcL%wdks2 zr*n)tk=o0avYh)jR9J3yZDw&k$Z#pU?RbBAe66To$Th=RS+?59HhaI)D2ap_ixp8E z_a9JS9AKmhti%cHIX;>MO`WgQd7#i|$*N%GmXNN}*8e^vh4k%oR$-0wy8cI8 zJ`iyNQpVcf-*3P*W69)jJ8;-Opd|Qy)-w{67a1^!p+(z>T=yR3bWI+&dqA7!RgEwe znVNaRQW2`y<|RGO;rBEb^Y963cPoH!#kEMc;ar}2xpadskv*$dB&&M*HEowJT$k^+ z3dZ$cCEs7&qMaPBf%}@il^^K+pi4Y!vT$ovvB)Ch>ejeh=187VwQ@@nIW2J(+w`OL z*KE~mk1Q=|H3;ZO=yC?Sb;SICTYj({1PSi}W(JHJl<6FE`11Wz0+d+!6EiW$cGPE> zIsKs3pOK0p-zZnsG;!b8WB`?UP>lei?|p4GiNgPAl3Ab}CNDy{=(Y?@IMyQZ%OmAg z)u3jyY)?AWW|GWh2t>gV)Tu_9kv%JdTaH(&#g)0;z)6L4 zjkQ}EOw!~pGn&P=4{Mf+5ssT$iNpu@1{=vfB$qQb&H{NjS)!MCKjHe1yI`Q(&!|o7 z^+rgc{gpH!xDlZ(Zx(OogX6w2d3X4*KL@t|@r)$dMf*JXbH`mjUre=YNXF}OncFR| zK{|Un0Ili9g})=fzJAoc|B~U4uf9&}Y6*)Y07=;zHZ7P3@}+g>z#+{XK z(~!6QNwV)-R@`<>8(wR@GmOI0df(A)XDRqH^;SVY&oqYoJ6nZr{T0(Kn^wk*3S~aB z%t9J}xcZB+B9P6Co;DvUY6Lc&xnclw5Ty;uPJ4-yrQ%&9aa=^(Yt|0gsiNam@Alz; zE*+J73@6;m-iVwi)vK~w&E9Brm^M$K*8e|cU1wC2X}5J$1`H~U6s3zw6A%jsgeFZy z1f=&aolpcq4JcLVf`leD(tAnhL_mnrTj(Ludyy6(1n$fIz8Rf+f3X&8C3(y9oO7PN z_u1!CollA+tWLYsc>Vl+;80%hG>Wk_rkbREFU?_lCE;o0jpDINE3eLAqv~ zXg;BUM?32sa_v2RjXS4I{vtsfz+oNz8459@MXhDfl>M&0KV$_Wcin#&x&#C zNty48ZVTFHX1z?a|06Dfu6}W4NKnXTakW>E%l0e_a4IJ*1;}BMLZIN-lJKg2#M7m( zG^%d=_KZwSMukZ(v+cDmlnc5i8@PI45*?r37Dk_%teG=K#l04;2^>%x%D;EoJM+Ke zdt=_rVDXkAWfLX9@Va+utO-_#S|8n5sQ~lq-TYSPFLv-F(CA5f!1GN{j3T43l|w;^ zoci~g>J8^-mX-)X*wKs9{ddq}Z{xi^B#162KrC#5mzlQ;hp4GGcCwg+CIb4*7b7MF znrf+AQ^BNc_y8r@o|jjR8#DM59-ay6W^O^_NEb z>P#yw`IpR%vd3!3AbdAz#O*P$?(tSTFJAV9>?b?G_UjyKGumFf3?++N6B?^o_3q}? zdHM23T|ni0QT)JP3e3}Wnw52YWX(5yuFP^p>_H6;SJO`FY5BDTOEn)j;RS9ty1J?U0fa?^(9qMd_HClL6aP;UV^ZgW-nyn})I zMC$X$y#oL?q-A8Z-Z54oUH1JvSQ{fv&hojXMMk(c2jb&EisOpVu~p1pftC!`EpF;) zOgjt7KX2TdhR)N4`E9ty_-`zc-lKvgq#qp0k26}m zPWed}CjI2BUt(w+X^(StDgMcxi-e-_T`oH^9n{cEY?QL8MPlah`zaY(S2$k zRb6{7icAkk%A4mO)4wc#CCy@AOmk5+VBSHjsDaFsj|^8r=57EA5Tn0w358p^WE|a1 z1+RYn7{6foXK+z`j6^SH8{(BB4DgQCYi*#4mBpbYZ){*1;S03+oXt1M9-$-|7CA72p z1+!KdC5%V@=T5)GJTPmK1G@C0z$@JTeDnJgP6Uj8CDSSVPcWs3A%NiN18(C!s0cD< zzOoNJ$l;$M?`__;0Q$rorO(IH>iyj7Qw`EgY5GM0Ei&CH!m4Cs@>ARS!(jR^<-?+J zoXW3zv7&P^vVwL)+yFOLpAki-QbeXwCQ12PH=LDn>Ec`3&dNjWgz`-HB&$R1_7J#r zbE>I0#l~n=Ipk6ZyhxI=?*`=!Jr4)^$#O{Ly;;8AmCB4kfal1_*T}WQ)wz4`VRdk? zhZ!*jDRxY&d)rE#nmQvH??ch5*%s|eNHMy6eC8_{a!3~uBcXvYz~@SlYymC}y*C%9 zTDLcWy3+n8${lH)40s$KUkWt&CBp!1&heZ{p#KI4n*+!ig@(?H(O)e8(g}DIx_$ji zVd;dpIRYf#9|4T?zGYHhJ^U3|BfWwtKUV!v@hg|%uzXJY(YCGCUt@3|n=I;@(;mf8 z{8D7^GBah7ZpPOY81SwpAGvb^7KG<{p`Z9X0lML4o&`|mNv8vUWmDKL+64eB{v4OY zJB#MD45YGm24-Ol46y+?n?ZWb@|%(FjaJeu2E(ZQswz!+dHIrvdB|jq+L;Gkxa$8B zf8`dTDS(;FcFJQ&Uy4(Sw#yi;vgn2^NXJR50-B<^*?66)FxxXQRyh*nvs(Q|r_3oL z(!i)4C3J)B+rOxQKGhU z3Ub<`WRT;L@dg12`lTZv?UbD2ryARB)NvlHr#cb|O)m(O$+azS9&};vK!@Lij+WB| zBDfnUMz7T~ypkP7zT!_9ExfaE%ccB$BF?7KKJgBm z#lNK#=eh!33SB!&Kc3@~9I6EncgV@{;mIe#ux`UnzHR)7VkaG&;hN7fgTL?hitHSO zVyqr~PCBgMja>702J27Lyf(C7mn1V+I4(ZOf&?>VzLuZRizOGWQ;}A(0Sh}2vnMCL z%6%U1*|C4V#IAY(n+69<6flCY(jaHS5^HQZK+dtGO&I0kvv#!9s$S1OC&)}1+Bzr> zmp|v(!H>HLqXNbJEfu}Kp%I_wrk)uJh2M5Xcg=K>=m}9OM&$!dyV(L`zyNRvFtXDc z7W{FldSg(D;vbD-B1fkFo!zXPv){SWKQU{#T_c8l3X{(cV-a!wl3Z_6@%F9csS%?| z>VT~QX8XQ8KHKYXK7sVwz2KdiY1W(hZejeVqOAUHTd>Y-X7C%XbvIsz0r9QA2V@WG zw54BAI1N?1nFyD_QgbCIWidkZ0XK!Z5u$R9``8v=u=SbWLSli3W;vqZw$@|Y@3rdL z4saxY$9DGA0zY$k^T{7f{ySuaY~$8yUSAry2$C}u{!RtsE~nPQQ=SOe&v26}fQM?) zQOJM(+;#s}z&{DY>V3<50Czl`+5~!ak^-(GxwW6ERR|7yKnvg>|6J<}M{g~5v!z*M z?Z#4zLG&K5@$xhCyH(nVr4%9dvi<>UKS_`DnONHucSFIF6{hu2m*9IK1KMH1RWB`N z3RA)Ks<xcU-P!nDOEOr6g!Lf^##psH7iJ@bft&wm zq)h200Cf$pp{7Haa`>onIEH<-6pISt!t@N0KVd$~YTc&(>G8Z5BnA7;A#l!Nyzm^l z8*yLGEHV$IAgxH@K1A$b9wGkVRwmVg+yxVQcyxFrfAl}JA0H6~S#dJDn;;P@$ts2G z1`oC_Wk$BUHI-t3CT*tFhM zox3`)8X>2$UfTX4uB%D$L_XemrSdkHF|gD88db#H~P zXo;oQXG@tYTTNN`J~grg2-*o9{!T14K*B7KW^ zjh#N$&MJr0sZ1)5F0?|U>bwQ0cSr?bY=F9CgcGkM!2a9Y2|6bqHmw3L0AYNeAkaC{ z&tY(ROM5O3`>0J9uEf1PDt(@gQVk7?N8*BWh59Xii6%slx*Yq{pT_zNeCTLBr2bxG ziN?DudKo4uh5Fe*xPI|Mp~EgD^(k-ZmrG``-0##hC=jl6D@)*DupP*E$SqZdITZoJ zDJ(8a+JSSdUsB&mMnCrZ77}v3#$zT;^xom~?9s-Ux6Owe5kvaq_%d!N8lef@e1YdG zm}^$1Cmx~?yPb|!@&Lg48@U+x=|7Ej=ceM%2iup_w(GWvypSy4DuP zf9n*MY9&?(XmZ>Agq!SJ(M%?trC>QAna86LolzGF}+TI-v9@FUkC7;*CD?S(ikiGn6Ikw?(2 z7?XD8&e}*e#vPbN)<&V9W{IzmOmlQgmr7Ducx{#FuCA?R$78|_nD(Z_@???|+ysmO3o&bXnEkE?VlOhE3$h(C;(H{(X4 z;r!e1+}2YhC;3-M=2gCd!x2e?(p3n*_gv$8W1`Z zTWdn!3$`wZQO|$^h3y1TX4NTplm8ZxpJWELe56J_gNgv=wAa@$9C!~}bGIr7{S{u% zfjg&;Q7zFYCnvsokA$NauuTCUoDG#{*#$3UKC3~a+@;o)DBOnZ?`eI@vn{&ug?p*r zg-phWu(79v4t}D5C#sdw%cPo9(4J>SQqScb9?}Sxbg*>dl|7$Iq?b@iM^U*L?!?Qh zjCUl2gm*PQaz*nGQ@Ry1ZJeo4pa8Zx3Wz=IQ-q!N-|CnCzPXF^ksUn}1Vgd)szJ^R z@weDkM4Gnm+||Qe&z+;Y3lhIp%}}CImYLn{d*fq{_lxuurYD7G^ql#m>#2O!$N- zu|d8xAu)cnH)DQ8kUrp^nq^E0rCIC|^)7Jp+)*7TxWhh$KU4`4e;ygN9fnUdzWF7P z(#v=vo!P^YU}!#K=&H<`Nc-?l82!^`xfnfNV?MO@1p81QltNM_@mc_LYTAF0*kg9tFT0ww}Dnm_YYT?gGC*!OfJ#Lq~hv5i1(lNW)OpG zheBUIRVGd+a(})w;Y~FyY(;)$j>(?)&^|h2!=WxsM43yueFS%mD z?x6PVtU55LeVq-6aE5iZz5#aCX1(G&5$gboOfE5PTySdu>8&CW7j!>cq;wy9CqnO& zKshH^SiE|nU)^b(J{4hog&6yEqp`*qlM~9!SPxL&u$UaDb>CAWKE1)C^!JR*qnmhH z@YCAXLWEmM%hh1!mBo5!$3YEV`&*{5Yr!=Ib|9)~Hq(?0>Qczbl+J=x`6KKNMuLnj z3Vw*L?`rKQ;fY2*t^|Yq$t5V8;IiLziug)+vr66#5KI%yEM+4W!KJs7khHT{lY`GB zhAdv~y%994(VEmMooFM#ti#q)bta=MY1n=)HT8P{lLrZfHGdt7x#eu3W;~xYE1Mc+ z^!mpe9I1nMzf@Ji5=|UX@-u8!qA>j$$`Ks%bYfZ@Qh3A>!7Fm5hPkn{T*Db$K6sCh(CL2S3UwiXk05?MYdSFwLwoT>VTgI`GdWqlYQ4>&k z_?UJz0Rfp<+aEEmq^$3(c8|^P%;Skrv&pP z>J=M0A5q?9g46Y)}b;L%!RU4u*&2wOWop=cJ`smz5-ggELs+VsqS6;NSsWhj{B z@Lh+;%@26&>g zE3(cA`j)u+B|u~X+Yt$ygb~|XfKBxv?$EB}FrfTo<{`fE+d`OCMP{GHE8x zH=X0NR2_t8DB({l6$XpuuB3q$gVuRVYFc!ZaGtY~Ct_mY;ony&8G8hEFlDYgct0CP zTsv(#$ikhB7ec2qFW?ZH_m=-;$y~|NE>sQ?0m%*Ve(HA-g76++dK-Ckn+%++x@f1O zwGt5-d1y@~{XT$|zca_4?hAK~TD*#Gh%#`1Xmyd09UXR}Y7S3cxN4>(QhHD{eTZE( zWEpw%d=7;Wq;i{N*_o2CdgthNat3hlW}nI9*fy3v8O!`r=zQVR1q#_yR8)b&P)Ls` zW`j-70qwd!hVmmRtPNmS*TS%9Gd$R$7$UiY*gstms7{xAbc%$r7R+@f*&5IZt&0J>e&MjbBU)3iA2L=WoLK7H#HSF_LTVCAvlxee^uS635Y75!L26 z@hAP^Z67ffAM>dUiHG729?^U#u0M&K7ih?Cf^4rci~K-)(X=F+v!P@)US@5{{qcSu zTWHI=&IWe-hS#wG>i`eE1zAv_wsZ~tf|5PVJNVJ~u!{r&B^yH%RY--wz8WP-cC*Oj zQm^FcXlx;jr(-`Z@>lRJ9}wmj9}B0eg12id08s9KYZqW1h|`F%PceQ|=(o&uE%=%| z=(bD^4LxOe#n)R}>AH4Ub~3R;VQaq5)(o1)rp0q6 zmreCQIg~8=_HoHg_C23%5>JidxORC|s*uP=sVzz$UbT91%pK0JNH^qG=;PLq-}eHX?fQbW% z_@TJogbCBaWm>sCMv}~_(_0YyKKT;fAxVET)FMOYy7BG*0GIc5iVVvu>fMhY1IGWj zj^&9*j~Eyjey+dDjhXHd+uYTbt`S zZS=ee1t_<}YXnM!J@ zbzf~KoPTF}uu}lNM%d#EyZ{?k&x>>83s(Y8g;As-SlVUqbn@k!vRIh{w*qjJp5 z@E@J}v)U_n;G7`n!0i)kb=vYPVK8`w_}$bRFw0x%n|-Q~P9P-<9ec5rF5>*f3rC8U zH~uS`at)OHdh4EEjfapl$Z4SI^Q~K?*W*L^+@5Vt!BlV+O%%L|; z!q3okCFxk)*8BpDbYjE;uIhzuPT5nc7}@jsue!pA_mi*$y&*(~~*;y`X=GR@gxq1dtpVi3qz=$TU|C6LOA0SMnGvz6S&OihI7xs9;}QCbLid?hlVRx2eJR%*)qX@I!pgF8YGq#{jFl}w z?ruhT5o*s6FvxWS3Y(Uu9<`;cn+jNiWQCECA9s9vb3K)RGGOH_GG`Pz2W_uj+Qfv4 z+D=HMuT~C8VGiU@)^^|}70>W@Rs>-t1IM-$c~?Vi^x-PgJum`pk?=3f>gF8dYE?1)w)O53foD;Dm!)w z)Uh^x>m#e~6Sc0nR4jyPLcfWl)aPll6%P8eKbVJ22}-(yKu1hMMYR9fURJ3dTm z^#w}>31%)gIP>wX=4@WY+9AK=v+S#IYc+%zPWl9;6W>$|y@?QQQb>Hf4G^>>4hvX< zMK@Aw{0~IsMlPDwiwsl#4$y*xG^bzBMhcIwSK}S2BzF5gW;BQ1RJ60LpHH~HD!`$= zUd3mOn);~6%-9?F@hhp6Hihb$Tco!ZE@-{chj3K(YO29YBOsAFFE8t<8{b8Ka7k@A zaivu#^E%6*7yFP}c4PrGEFRn@X~=f>^==X4h_LsW#J~q&G>;!dhIVjv7sj;v({S_F z*K)1>7?nO{x?XfbMPI$TLH0s-*u}LjVNfv{0CIgpLKnxf6O30DsoY)&`u`hHGBpE& znq*B(*OlO#vYIZ}QuOWe1HwLAw9a>BHTf0t5#Q;JSCA~O`1@tYhTa6d_Zm!#iPs;ugktPoupWh@&Mz_oGZt!;X3l(&!4f_3@0E2VrdnhxbO0M)4{?t$r zZIe=RxrCx-UebU1zD>u&u3Y#8@sIOi3nB2@9p(LmUq z_UpwV%vHTcT-BZRlX$=6!_AE)MmERK9R31YCriYKAa&Xen-|hyEp(~5&hi#*eVh^V zy)n_jWp^T$$7g_4O1bmwr|+dja!Pu>Em9PV7-s?`Zp#p?Gm-ro3$~pA7hfvGCi~SQ z+g7D)T?!rb42sPbrj$R`;?wFxD|}hoSU`PMbE(NPX)`3BOTSX*W}vF?42_@SW90O- z8TxY4!5hxb));QcVL|F4_FL9-?11Ge-)nNJbum-h+y@L4hflb8^!ieTi`WM1u*hb6O9D&B?DaJDcU?z z)n_~1Zav?lemlHmm`W?Fh^-5X0ljvRorP{FX%9er*@O7X&tKI_`^?gL4Q8Kf8#oW& z<5Ff4**V`C0@p=gtMmcq=@`9yb!1fbM%~xva6O*a33aaWu69XP*Nr`!@ji#!^KqHs z-ehc`S1kk9*IMYv9*$onw$Zn@9Iwbyj^x=I?$&&IcG}zZ{oYq_ z+vsCP(AtRWFr=Io89oz zbW}_H;m+d3K(-R;fq$tZM|explaaZ%icNC*iChk$rrf)BAfu|%oYmdSM@`WIEHG6C zd|kimyB<1{RqFMH0RYt36@)rZf)(v#b0K9X!QtKGp?r2Ky2G~mLr{Vhe)<0aaOKp*D`v z&XPn1&kr39By07YM6^-D4F(*?J&SGEtIRlH1{ifE_eiunhMW^PLeoVC!~ruJ4>mXQ z?4BxB^6OW93+0}!mC26OzmZ}qw#z>HGhWb9>f$3=Sy>d&M0SR~ujS{aRREk0F1>I^ z#y#e4=#X2ZK82ZE&**3(5)4VHUJ^8L+1NA~8g+6(n5orUxez8~H+Ux9LGP}bl=={@ zD@ToCd)V*RbSxUHzr(3n)G^=EkH4pn)-I;mpD|`QAU#SZ#!$4 zz;B?ru8S-mDX{kMspxovWTcUtTsAhh&3EWV6_|INhzXHMq(g#T>{s%;EB46b(#bKT zeFEFyfaTGN^3RiL(N?I&Q;51AY9$ko0=rq#BEJ> zZ1}`;(@Mu2^e2TKl%!np^+*|Q#W{M`UBJh=mlNe7CfLvSm8#apgRdJeRl_`KSo}7Y zH<7=sxh=`VDMFJq0D1S$RYRxf#pPI(D!+y@y5vHJZFPm7L!^Z&)yK=;MjM*zX;!q$ z;p~ug@!hE@@vxW=^Z^NP-@g6sEZeL|p|{)3qBWFPAwK~i#dv@?f)vcD9c0DGy$$y^ zGSDp6hG|8?4Ky^~?E>v>WBcn9qzZcgnN4j-@Ro>fVU|$U^((%yV&h|O-m6M`0#OI5B7CX_eumBfe;f{Y0wxCa=YH=*i)s$GdjHK^hGnF@%`98;Tqv5q- zId>0dq25_yAJ&mL#{!Vp0mvqCQm6EX zf^@`rX8z3_P-?1}$C2d}?RlPew$(EhfXWHK9e)h)-07)i3TE${haG&-ctI>a{Aip2;L?)t*#?AAyi+!&br2_ z^yQ0r|7Dr)QV?K19gCJzd>lw5(Y_7uG)0BVD;rBhNnq zrh&UL(%04^FQzOU9xqC5Ccp;8;*2RFQ{R`C@;3AT!8CrrK2ys!f3=n(>ebJL@lMgN zyu0f(!zZM%I>c``QaqGYMuz=LuepLM+`R3W=1z~Xv=>T#{8)|fM?@RQS`!xb0oK+79ER!?a@23mv|cmGkJTNrtsCBs z=iBM{&|P?E|21Az`*761!qX<7qZq})$X039I9;lP14_#(Hv=vge)oy_Sd%nmI)UjF zVUR&fqs$wc^C^A8Dc#>m)LVJM_qlv!f$9X=If22N}5lxN$eW zW6pKy6HsMSS%6D+Xy=yd&W0=Y^~JE!z$_G+RbtyqbnegY<46V@x-j!ePCIvhU*|D> zgTwq&8!R_cefAAUvA&;Uy{#Tbh~TsHlI!Ot`m>=yrAkYHajzNE!$zy>siCFBt@H8Br zI;#=|uyl&6(4>_*0LJ+zK-=v zo%$vD4|yO4A8QvkLckyDIroL0Y2f3g=FiBSUJ1e{DzAm#D(xvQka*a15K6Y@krshD z7@S|Ab1huUWp@9zt3`20d|aIt4a@`MU}jj^9KTBP@L2nZ^_$YJTy9PEw&)TFUdUbj z^S)Uz6S#iV)@i!7^9#*$KDoagr=cyT$B>G9~d zb>{U2UX!MuN$zT64AyeU8WV{uEVymp-r$=$#0 z@c#6k@~6D*Y_s7KJyF}ytQspyhc5bbzo>4p&DRrUW|8sm)0}!qR8;-bW)+xuS2EJ2 zTEeUw+Nxh1vK%LF>+N}n>?7Xf>E^Tb;Bz5p&qu=@m`brlQw|4*U`5u3F0plC2r1+W zYKCx9dBxwR(I> zlq$#gJO9aZfI! zsK&BvCa025A21p3sijo^1n~+OEVi=8Z@a~QOIGGjAKt=>TUb~?m-^W8(UH+(&4J{k zrtyhV#}ll3(3!D}9{Pc?Y@eDI<$WGwg;8zSYKwr+A@KtHmtD_%Y_b0o=I zjp2tx)h-s+?yS;#(5_VRZ^wf-4(l_cXnjZ<$HJ;G|F#T;Dz<`%9JW=Vqskq$+y95} z6ciwP$wD}Z|JxIHmgvV`(ZzI>Y>qC|sE#dt^;KHcXDoKqTYZzA`c--0`-O{I z6t;daf7tnHh3203xBr{P zzZlAuxvt3^yu8em6Z+Rfjc0$AT$&wRysMqZ{lkTvD>|1$Yx`?SsV?R@J@4-Kj$xj7 zqY-PhNoz&J@-7x(m<}eA_xSts@;0^f>^jS}*@WYh{PT%J{uj8k&c)5)j}*na8}z>k z(iQ8DN}B$izT2RY8db zdN~3d^fK==ZfL$M=?8FbX%*e%7da*=OIQ7)=x?^Q1jVd&fF zJe0@OJ(Sf;>PWF-OB-tUh@!VW{5~IkYH;0IVi3}Zty%xNi_RM?k3E%)y6Xnk9HLc!zZ|*82M>cVcG3Jx^`ERsXg<9V>lf`ofn^BTK9KFRiCntF0Ttv{M~8$ zhN?<@NX@X{=%`!m22Id9^%iZlHDiix{cq=nHztqxQ{XC>9HQoQ1Cos?-R02V6twx; z9t)SzPQ16^`Ok>tb6xU{6|@t(mS46`e)RtMT29OK_ZG%X&k9RfMdOZtZlsOn_*75q zuiHf@u}!&^Lj2dPI(rXlaL0*a(9Im%*^2KQIKNUNm(^#&Jl=j9r?P|c5MV=(v8FWi zAh&va=14UEL}X{p?HH@h`NBG4Pma$ze2}e5*?wevd;&T???D%Mfn~}({iK=Gzy}N8 zpokiW7djMA*?U&&sD_(bc@seHDBp3vvV5OZ`xL(|+Z4a$?-9T76U4SFv0dICG8kB2 zN3>#-BDziN1u9JbW!-79kI-VPK%TrC8&6@YEHoZ}bsg5q22%*-RUNV_QEAqE)JO~$ zIH?*7G^w89Jv|h@SK-l#RmmZ!{^A;aAlP|m=e(7a=PUiZ+4kxee^OMBa@DsQlz`%S zq#hFc8#MwhIaK&KiQ-r%k2kbb*^c_|P8`adY*)Q9rm(NNmNs%>GyT`q62?o&A#rf> ziHGY<_ZTGr}0$^g*)i+ zSmVUzL!$SCp?=*a&G8qTeme`~-S^O|qY3I_@28}GA!!Qo*xM5j;8i(b=M5a{&!_O~ zj6uZeJAG_x%S!!kpDrjR6g)lt>2cX(vcbd1u@KZ5qQn@)o~Ah4X%=+ zO%fce2cGC!maHq%ytN2xNMmC` zV(o|B2>)4$Z)(kaeH;EEkRZ4^WW5mf+qZX4oAK-ZMQEVdA&H&p%y_2%w053(s-OT< z{dR1dCKIaWpGe^6xMcxJhS-Vc2D&pST1`-!j9 zAodkz(hWyW_xr~RM%4ym9Wdkn{y%13jre?-cO#ultO=5SH@;{$o(HkNq%)~2GLrsi z(0#DoSw`kb+@0kI!bU`C`Cn`EK}TS6_`GR?1sdO+Ncs@M0H)rT<0AuD~m zb=)|4jp=VX35z{){}kO=adVT64ORCjpu1#n-}xDo6*ii7vYoIV0MveCKi5_D6t$!> zl?zXr`$ZdQQ|>x%?-!boQUJ*=|6@r>Ny`ST-FS7=9)3Mk>R1QetM2f3?C4^*zt_~2 zcGBrIakZMX)T%mRnc(n^iaEHlgqX?kJ^-Oc9450eX_}*|Q*h?n&K|w0vnH6rPb8xK z`=D!{%_l3R8)fC?<8ucK-KU*^RanA4)#;Z1v53+?KBD&%KDn10S)JNMuXzr!`W-#2 z_jLF09q?G6G1uxzE**=mR|sIiH?=fDdv5Pn&w(+P-fb$(32Q5brzw#UpUmr_jSi~ccSEATy&ozzsDtobuACTz(z~zHw1iZb~<>)*5L+Cj=kb>pB_nLvf<5w_7bu2<(H;lh3m{MUa z+5TjbUO=)8;NuZq7iC;xI0?SdxE$!ENK4|5+Ie@XaFKejM13N!W4CaUSJ}8^F?P1)^AW{)3?9o z)izwDXR$g`x*2ui9T^pMCRyZ-in{zAFih{Q#D}pQA2piLiEYxs&09<9{!e)oNa%Ra7b=|a zTbli%2t=p<6QRy(1M(%ZzrPpw`A@HYz2|c(*M1%F&v9L9Du0C8icF=!2>(5p>w054 zepIi?x0c_yp{Abv$=R$4p8()jOc%fYeKs<^=PebOdWGrnfiw9Rv(s&X(-|MQ`QNji zGRV&iZ*awvyQB<}lJ#YNZbwxQzQyMvr#QwbmS2%f!rc3b`eo%Dwm6_A%K15^oAGG6 zpYls_lL-Z|0Qc1Fvk6a+Ul+UkZut+z2jV>Y^6W7@A)?JMEEFtqViYXee7dV5J%H<9 zxY1PZI&<*%P^*PoP31ey(4yvV{TD?ZMJnEqO7>ypp#=|2id1Yxvi!e0x;1)e${WJp z*5v5`j#Rx~lKTC{PPZUoxBPau$DP4N*?Sj%d!r1aoB`(4JyyGXV-oTB9&-6m6cS|{J+hNzN%%9Fw|?GME)jKy5u*l%Unl{ zJjT9#d*(rrwfk;uy8p;Jw6YWN{_REOQ71F2zIlD?ZRdv){y!DlLJ-2Wv<9_?+M%q~ zuM{zadXF6-Q-hV@x?Y5h4c7neE8)+!@ybgptAD88u4zZ7A^KIjeQqN z_BA{6P0#y0bI&~A<9+z&J&y1Fj6WR5ecyB4*L7aMiiO$8t#0stcH zAAsorlmT*5GIBCfa&j_q3JP*c2t5QsMFnA^rK6^2VPa)vVLEVtjZ=V|jh&C5*GS32oVJZ1%wi^9|GAg#CCv9XxAUidw_uwI6;;`LUafq zW*{PAAi`7t9KWVYLWKPQe|*RRVp1|95(-M}T_t*eh=hcQgnS92>diy|f=1<1%5 z7K%^ezvg&LK=P%OSt51>*58N!bL`*${~7{& zM}Pr)ix?myA;Z0zh?s$dlvm;+<9<^nnD>V-vzTsxngsh40|^752yCSzk!d1Gq!02* zmWXAq+1WswV$G|^#vX4JP6?dL{n~OdrP(02)fyg2w8lwYRsT&Tj;tr|1C8NE@%P>b zVpJrR*{ZhIf30!X_SDWHnC(cFz|{#E11y_0XV_ zvMztt3&j9S**Q&!I+B}_5FMWHi+RGr8qXBHdG@E2R-aa+hd#LZ?E=@hVY~xz(PUwt zZrHRf5<5>-^Bmb2=lqI7!yBbfemiLUQkjn83cp-8nkmvUohJxJahhn9IRD;{lEwY} zo9nJ^h{5=<2HA8|7s_NEa=YUS;WrQ1-I`lRrD(r339CyHmk%3aH&naCB`_+*Q#`;a zH{IcW_+^2(&fIiz(bB9if=pQ~rnDZFFYvMF!N^UXdUHlrHw7Zzs`ikij5BJa)|B$} zbaG5hk5&Xna%jdc8T$wwkr&@2tyT2s`-xc09hp8?qo4P=dOAPmeB~Vtk*9^@8Uc28 z0$1FkpEvtV+;bW(FBD^*x26WQu!@mJZg}i=w4trWgMxiEBe1AC{-d)l#L7V^UNzlEVU(@( zPCQ&Upx2uM%VCli1`6B}CRD4UpYBAlTzQ00vew3|Sva)#fDpQ@asK>B z?}KMX8y*u@5tDjJ+3A5#k_!FW(Yh25Z#Pnk7gV2D$Qw{gL)Ax~xSMY8UJ4<@ZX-}{ z;UGC-_wYvk*V`Ncl3l;~anZh4b<9f=7Wo2)vH8&6Cut(HUH#(vzsnWbG?s)h;Dt(#%CSQ-htwJ{Nc^Vab?q(6;frvE5to1HDK1Ldgw9Ln(IJE2oA>=N$TM-vx zMj&)Zb|B--IiRj(;lxfP;n=RDs-7mYlbEJB>EX}v8H{(Xh>|JWKyo6fn;d7GGyJo9E-JySl90e*TQqQTTz>nuvG zYcNbE@9QU559>OwEbtasL%@+~5HLqXO^Ee7S2@~S9COLz6^o?!uE4A&sIvx0&9|iw zmlFMm+mN2t<-gM!_kxPg#)L!G^?O1cHci8NJOuks7}DXMtNEhwwIPSEq(QR(h}@uK zP&TAxC@hYpl#{mGZOd>aYvrUY3vZq)!)3qT+IiiOWIJH>lxXS~43O>IG0*3cwn&FE6Jgk{T!HzC+t7nnR_q%4&Z}D5cv+b!bg4H~pZPuhTOlRq(*|wx>aXF)U zMxbZaR7aO1_w$%E4@nN?3!h$WoJocXiJWiIP~(Z<`Ju*^q)WtCd>=0lCTMWNO`3R{V_jIjQ(`9?`bx=z&9jIy-vUn)|Uoeaq}cb(}4 zm~)iy`VE<47=XRtvU!EaO^d{p8b=yM+PiZHB3>t?E1VPK_tElAt4jZ7GO^$8Btk2>@qP~ z7~G`Us(6r=H}&ghk3;Cl2xdX6KX3b6E;WP?DFlB`!0WE$ zp+c@1OuZGGWuyKSP{(TiMvd|`oH1f%pb&ssc!6~z!pLw-*1oJhU}L0Fc`js#&4Xik zNK9BC26u@yP$NyGIIY@tsAvlW3iCyp<6k0CGmu0v&j)RPZ;Z<`s zhCEeyJy#6}r4ITtL>#TZ5=MVNNkDj@{05-gNCdWUkc9;s_I>Wr46C)V{=>W#QX9u- zDh%M+K1owjxnWeNY43+3&)nJoaUz0O%z^Mhvu{rdn%LcvB4G+~<{s{qZQnUx^+;X_ zm{vUHgR7O{$oB1tkBTM6Yy9nm_@k>JOtA0%v$4Vqq9;jaTT(EwOYN2vux{id@RfLS zMuzKKB_mMV6W>sZ4A;Ne5%HNngE&z_f=x~l@Up7iwww@>vD_sme7Ez8eYiSVJ;Pvo z+UHwBaIMrG(HDnFyJ z$RSL`l_z-JN42}dpQdj$&?h2O@*0#|7r(HsuFM>fq(l%G5KvoG(%0Q%}k zq$qUcc(tly`Hk|Qk+*Trh#Io${taUEe)U7sz1{ePB5ypm&)1CH0uAQ>2W-~ciO77d$OIv^q9N> zSIF@EaQdQD{av28`zX?|0(y!h#r@^#tKh`11z~_%ix{!i8EXma7LF}8nRwQ5|5d{h z!3FCmE#`TS;Uu|%!pm!QrT%hbw6fDITiKBaB^fiLxhNy|z$#gR_HKiaj?S!tVJ6x8 zcDMCgjHNo1QzeqzHos)_J?e9MOle{3GQ!WrBh2%|QzA36m;iuKFAQ+HWa^<|S!1DG z%Go8ZpEWJ>WR(e?ncn6I1dMQTuQM1=TA%++8k(0y%U-geg?$2xLj*ZN+viox$)@km z8Z#TOxa>ccoH$0SC@vqbtXYsv)v4aB26Y7PD9E^KpD=tMR>*cEj#(cyFpK%sZQ3OC#<+&SdlI=q$;4W_bK`6HyeFL$N z1{Iq#*RSf%}6yD7Ed?P$q8k)Z!8fDZ{6AW}hqMGDEgagDOijAP$V9=@)j zjOOq#az5o3<6yS`O=Lot?hvr(Kjb=g`3N}i*N)|@qAdc&aZ@T{2G`<0sk97pYGDAV ztJ#(vypFgGNgvd1(ml+ ziT&a9T`HKnSo-c;!^}``>c%I%_kAnK_&MpmOQQ=22yx~H_YXbyw@}xv0t%*@txx?$ zY#vI5xpY69MSuNfhhTYak%U@DvLozdMS~O9mD?6M>E=Y2!LSf)Iq75S;i{y~@}Oxo z_RFS4RyU})4S2{^tj4e>x|@=uIRA>8RSskhsxk;lXB0FxYnJr{-%04DAG zg90&u78r++#)vVVsn$`f>+4c{rjzZJ1tJfDbD;?AZ-a6UjXusEo-~mt63<7s`ju6>m$N38^4Zii z#g3&Ea~==ktDX)rnbe&~x}tpSS^+Q59FZD@@@kM13XLzR7mX;^mu_`g6*XLW%-u~WX2c!gb$Wt5(Fs)NA0w$RKJ~z4au9BI59d^$5qGH zH8%5iA?H8p`luNOkf6CA4kYste22LT1B~QoMvc4XvF2Gl@uXqD@Yq>-1JxJ4ng_!p zA3+H4mBnD;pTZ$Y=%TRX;6Ao@ov04g_kI@D_NQS(#9_4l3v6SCix;+aW6@uy3)BSS zb9P5^sak{2?lb>JFtyBayG)pC-~mCGoZN93?lDlc%pa8XCcf{JD+ajkE^J2#UE(cJ zT?mC2vQ46sz%D87Rxf_4a+p1A!cI)pW>T+b?h*S(nbOx|nXxvBEl<%WwqaEt;dZ|F zOf+7qKn+;*a%l6d)7=@dS|uK8R_sv9#vaWOdb;jkM2gmISs~UzrbODiQ?n_`KS^$* zaNM0nvcE>q6bj=w{)j#H@cG} zw)I-ZqsM~T!k4yWi}>x_?{7`Bm#-^~>4T9GB3O~R5-7YPV19r=;441rcId4teaEFE zti92OR@Tawua*rw*6L@-`*!`DQ;RX}^Qsua^dWn_h z8}qg&B*e`t$v1JMs#te(|8_Li5W*_ISLV4>3!{japRb162aG(0e=FSR3=9LT9MSX< z$?c0B)f4H0TcxsXpq?51`2*hM?NeYp&+p5wtm%58cdw}Xu*#e|m8ODCXjJ5Q92GoC zjmX^Qf`<4EZH7Cc}`ERipvh2DDY~WCirDcKks!wg_#p=o>liLeWpZ za77MJyDFe+0-nIA!p4b}p@7gGO0^Ex&EOrQc z2k0xcX*%aX;G5Z55SW(kix5&;43K;+N)LMT-T1tkG*=q}LG{0?o5UEV6}K`+$lR@H zE}G15G+Ji0Awvdsw7FTVRprgh^e`>mx0mEP9Yv6HO_;TWKQJTMajOj#!}BYrgySP7Qr zXQusiXte@b*<|DUQSwc34 z2R9|FHh)ylXUuR@j77=Ls3=Ba3+$}^Q*kHu@NzgHl$(f8lf2fq?|qpE#Q43=-NiL&AIsDm>j zAGX}!4qnZSBC+@A3h0TAjT0>P6}i0LchPxZ6NMNMCW9H=QKDDaik$krH$sphXW+-~ z?%$QHdz<>NP3?&JdW6a}np*{NB_t)*z}L1n#-LqgGa?C!*q<_}$i1MM@i9b)IW>uh zqRkZXrP2{a(cX!y$4SznmyvH^?Z%AsO2JyND6=K6DXZag0e|3BBMSI7*+za@=vS zds?fFTr-ANAfE)9^aKMX~ECb4mVZ1*AYRz zvYtI#N*e+qM8SBu56_m21@a){ZA?Be`@e}OEb!-W> z;k*^O-JDh?5<$sAUef#SIczvFHRIe!FPF>%C*lau(y%>BJS<6>dOG@Unq)Etc-O{ai~+jaR7L)#!ZkNx@<~9QD&W61nea@BY-9&+ z2z3BwPH21oaZLS}_!U8pb@%U1IY4`eAfDd=1epuA!`fwBzLk#90S=kDobde^7e2|} om_IrsTENXd0uNaZ?Dn8-YOj^YR?#N%Y@WM8&`B)76fs@@1D?LwX8-^I literal 0 HcmV?d00001 diff --git a/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_1xxKHz.png b/pec930_sdk-v1.0.1/Examples/system/sys_ice_unlock_lib/image/pec930_unlock_ice_waveform_1xxKHz.png new file mode 100644 index 0000000000000000000000000000000000000000..7a8882df62c57bf9eed8670ed065e96d1fecb67e GIT binary patch literal 80500 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 n~)6^&;ceW>?d;muth76|X+rTpA@6 zWuW84WOgqI7yA1QMb}CPs)r~k0Kv!*z7i+FU~`XFdNM0|OH!O|VxQP8P{c1k2JL+x zYDs^X_GS&v(ctV%%pvRlDYZv#S|ka9x4!QTBB*@v$S(+S+jy}(NbFN{>z5Djc|lb3 zgNibHEem?`rUiK@4{8;bcpf)lRSxx$p^cKUZh0@c_@6L=4UIB!Sqi>u#hM8s4VYUA zb!X3?x9t>qbUfmgoX#|B+$(Ux*i;j(%P^K2ED+-F<$7~xQ^>gpgjUqVI%OY**!g}f zIOa1_K=Pel(OnzNiA~HDAIz8k4&|d z4VK2$qX(Y_u(!}BLk}ApVj97~{$@3jGP7(=G}x}lhBwmPBdsu26fjFhl?I||!n=sp zZj}GD3SjWjECF9^1w-I6Fa!6u>`?nZuE%{-4$i9}WC@wtO)UsBG3n#})M0Iz!2q-4 z?=bL)wFV7n4c)c0LenvS#~{`&@GL#N?eiwI5TgSVL?N_|e8=nW8og5+t45)If^!Inh5=QtY4Oi1D^!1J#>-Ztn%(gajX$iohZ|1( z8ivkp0|jdBC4&sdF?JbQn&}xa8GA+FS})*!Gw)k-D$U;7Xk-3`=E=BPDzsArnf92L zuM*)PGR2r037l3yGp3fykxs8p{PJ)Xj{boAxUnncGC!2#4db@`lqD2I-0#Zqj8%o#w_^xm| zx=}OFkW@1AXtxP`{@dBMUR>fbb+I+qiSkwTk0$-UnO0n->&alpE6dk^u>jn@p|(2b zn>45TI566;ULcoJ#Z;Bor)P}iA+d8bOB98Uy<7SweZ>Sgjk-Kax>5k7j6D083a_Xe zLf6t=(_8Fecs}muEyJANb;2^@&hFaUV`PEZ@j#hTW5TAv<)iyS$r+orT%ZuIYym6F zC#IL`^HCK}S!^)DF6&$mrQgpOieu`GL-I-*8pc zNqPnY=}o!|dw>*3qT2j;(-ZPteqh=cFX8HNcB>9|gDu z4Bwc4VeuCp>P3x_=B7hiT>9FUan_2-U{%>r2hbO5=@F;d?vv$H?e*|R!Bp^-36Y~> zG7rHLD)MeA;>Lg@$RGd6qVmdnwuilWbeW~M(J-d8UZfy-MUx<|3X6m5KLcF6>s*GBIzGv zJWi4ed`X)!fVJzj&rNqDWc1DAGIFO@VdD7^aCn_yb^t2h+X9u;{pnd>=u#SWHL#=U zY3uVs)bk5za;w>_sB@FH8jDHE^=LaV)>EP0j&v>sV`2N$P7*6shjAdXchAtQzy~S29TvvK}Ex z->c2Y64t0mN>42drg{tK#^O5H#H2~t9XP{8ezUP;0;-jNndOP})@at8(FW!Z&>nS1 zl@lr!-gGUBJr6yZvZF|#yKEs+i4f*pZ|(#4s+d@KgdnaG5LQH@Rt+E0ni~i``HQlC z0sTdCYkm4|kX8siBWw!d_CBb^doPfCf99&EsV3OEtb!^DIEPZ<&tqE69mty*LSnxA z9Nq;K~u362lVCPyR?s z>W?aa5*JaSv^ztNHMS0YSwp4v!~_%0AY?y%JfuYEDp0CR^{(H1r|Eb{Q_JzO9{0q= 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